/* ══════════════════════════════════════════════════════════════
   ШРИФТИ
   ══════════════════════════════════════════════════════════════
   Три гарнітури, три ролі, і жодна не робить чужу роботу.

   • Playfair Display — ЗАГОЛОВКИ. Високий контраст штриха дає той
     самий «дорогий» тон, що й золото на чорному.
     ⚠️ Цифри вмикаються ЯВНО через `lnum`: типово Playfair малює
     старостильні (мінускульні) — «26» у заголовку виглядало б як
     «2» з хвостом нижче рядка.
   • Bickham Script Three — ТІЛЬКИ ВОРДМАРК. Формальний каліграфічний
     шрифт нечитабельний у тексті за побудовою; у субсет пішло рівно
     дванадцять літер слова «Viktoria Family».
     ⚠️ Його не можна ні капіталити, ні розганяти трекінгом: у
     скрипта літери зв'язані розчерками, і розрив між ними ламає
     саме те, заради чого шрифт узятий.
   • Jost — ТЕКСТ, ІНТЕРФЕЙС І ВСІ ЦИФРИ.

   ⚠️⚠️ ЧОМУ ЦІНИ ЛИШАЮТЬСЯ В JOST, А НЕ ЙДУТЬ У PLAYFAIR.
   Дві причини, обидві перевірені в самому файлі шрифту:
   1. У Playfair Display НЕМАЄ гліфа ₴ (U+20B4). Перевірено по cmap:
      524 гліфи, гривні серед них нема — цифра малювалась би
      Playfair'ом, а значок падав би у фолбек, тобто в іншу
      гарнітуру посеред одного числа.
   2. У Playfair немає фічі `tnum` (є lnum, немає tnum). Прайс
      перемикає три довжини підміною тексту на місці, і саме
      табличні цифри тримають сталу ширину — без них при кожному
      перемиканні стрибала б ширина колонки.
   ══════════════════════════════════════════════════════════════ */
@font-face {
  font-family: 'Playfair Display';
  src: url('/vendor/fonts/playfair-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Playfair Display';
  src: url('/vendor/fonts/playfair-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Bickham Script Three';
  src: url('/vendor/fonts/bickham-mark.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

/* ============================================================
   Viktoria Family — чорне з золотом. Її вибір, не наш.

   ЧОТИРИ ЗАКОНИ, з яких зібрано все інше:

   1. РОЗТЯЖКА — ЦЕ ПРОДУКТ, А НЕ ОЗДОБА.
      Айртач — це перехід від темного кореня до світлого кінця
      без видимої межі. Той самий градієнт веде прайс, кроки
      візиту й планку внизу. Один сенс, одна форма.

   2. БЮДЖЕТ ЗОЛОТА.
      Золото має право стояти тільки на «кінцях»: цифра ціни,
      активний перемикач, планка Instagram, підпис групи.
      Більше НІДЕ. Золото, розлите по сторінці, дешевіє миттєво —
      плаский #C9A24A на чорному читається як казино.

   3. ЩІЛЬНІСТЬ ЧЕРЕЗ ШВИ, А НЕ ЧЕРЕЗ МАЛІ ВІДСТУПИ.
      Клієнтка сказала: «занадто порожньо». Відповідь — полотно:
      короткий проміжок і волосяна лінія, що гасне перед кутами.
      Картки не злипаються в таблицю, але порожнечі між ними немає.

   4. ЖОДНОГО backdrop-filter.
      Найдорожчий ефект під час скролу; у сусідньому проєкті він
      уже морозив рендер. Липкі елементи — суцільний колір.
   ============================================================ */

:root {
  --bg: #121212;
  --surface: #1C1A18;
  --surface-2: #211E1B;
  --fg: #F2EFE9;
  --fg-2: #D6D0C6;
  --muted: #9A9188;
  --line: #2E2A26;
  --gold: #C9A24A;
  --gold-lo: #6B4A22;
  --gold-hi: #EBD69B;

  /* Золото як метал, а не як заливка: п'ять стопів дають
     відблиск, через який колір читається дорогим. */
  --metal: linear-gradient(100deg, #8A6A2E, #C9A24A 28%, #EBD69B 47%, #C9A24A 66%, #9B7A34);
  /* Хребет — та сама розтяжка, згори вниз. */
  --spine: linear-gradient(180deg, var(--line), var(--gold-lo) 34%, var(--gold) 72%, var(--gold-hi));

  /* Це не розширення палітри, а розшивка того кольору,
     який раніше стояв прибитим у правилах. Без цього
     денна тема вимагала б переписати три десятки правил
     замість одного блоку змінних. */
  --on-gold: #17130C;      /* текст НА золотій заливці */
  --map-bg: #0D0D0D;       /* тло полотен і карти */
  /* Аврора: ледь теплі калюжі під контентом. Уночі
     вона ламає мертву чорноту (шаблонність), але не
     чіпає ідентичності «чорне+золото»: альфа ≤ .06. */
  --au-1: rgba(201,162,74,.055);
  --au-2: rgba(124,65,80,.045);
  --au-3: rgba(235,214,155,.035);
  --au-4: rgba(60,45,20,.06);
  /* Заголовки градієнтом. Уночі — айворі, що тоне
     в золото НА КІНЦІ (закон бюджету: золото тільки
     на кінці, а не заливкою). */
  --headline: linear-gradient(96deg, #F2EFE9 0%, #E7D9B0 55%, #C9A24A 100%);
  --map-rgb: 13, 13, 13;   /* те саме числами — для прозорих накладок */
  /* ⚠ Було `--ink: var(--ink)` — оголошення посилалось саме на себе,
     тобто було невалідним, і вночі `background: var(--ink)` у маркерів
     маршруту обчислювався в прозорий. Заміряно в браузері:
     rgba(0,0,0,0). Денна тема перевизначає його на #FFFFFF, тому
     баг був видимий тільки в типовій темі. */
  --ink: #121212;             /* обводка маркерів і кант маршруту */
  /* Скляна колія рейки розділів. Уночі скло — це освітлення зверху:
     плівка світла по верхній кромці й глибока тінь під колією. */
  --rail-bg: linear-gradient(180deg, rgba(255,255,255,.058), rgba(255,255,255,.016) 46%, rgba(255,255,255,.032));
  --rail-line: rgba(242,239,233,.11);
  --rail-shadow: inset 0 1px 0 rgba(255,255,255,.11), 0 10px 28px rgba(0,0,0,.5);
  --rail-hover: rgba(255,255,255,.055);
  --rail-on: rgba(255,255,255,.085);
  --rail-on-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 3px 12px rgba(0,0,0,.42);

  /* ⚠️ СКЛЯНИЙ КАНТ КНОПОК — ОКРЕМИЙ ВІД --rail-*. Рейка світиться
     плівкою на чорному (--rail-bg); тут те саме світло лягає НЕ на
     плоску заливку, а на --metal, тому відблиск і тінь мають бути
     сильнішими, інакше на глянці металу вони губляться. */
  --btn-hi: rgba(255,255,255,.20);
  --btn-bevel: inset 0 1px 0 var(--btn-hi), inset 0 -3px 6px rgba(0,0,0,.32), 0 10px 22px rgba(0,0,0,.3);
  --btn-press: inset 0 2px 5px rgba(0,0,0,.42), inset 0 -1px 0 rgba(255,255,255,.06);
  --font-body: 'Jost', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-script: 'Bickham Script Three', 'Playfair Display', Georgia, serif;
  --ok: #8FBF8A;           /* вільне вікно */
  --warn: #C8794F;         /* помилка в кабінеті */
  --card: linear-gradient(118deg, #17130C, #241B0E 46%, #12100C);
  --card-2: linear-gradient(118deg, #17130C, #221A0E 52%, #14110D);
  --tile-filter: grayscale(.4) sepia(.5) saturate(.85) brightness(.95) contrast(1.08) hue-rotate(-6deg);

  /* Одна шкала тримає м'якість передбачуваною: дрібне поле не сперечається
     з великою карткою, а великі площини не перетворюються на пігулки. */
  --r-s: 10px;
  --r-m: 18px;
  --r-l: 28px;
  --r-xl: 40px;
  --soft-shadow: 0 18px 40px rgba(0,0,0,.35);

  --pad: 18px;
  --dock: 94px;
  --safe: env(safe-area-inset-bottom, 0px);
  --max: 1180px;
  --shot: 0px;            /* колонка під фото в «Роботах»; стане 72px разом зі зйомкою */
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; background: var(--bg); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  /* ⚠ ТЛО НА html, А НЕ ТУТ. Фіксована аврора
     лежить на body::before під контентом; якби body був
     непрозорий, він би її перекрив. Саме це й дає склу
     що заломлювати: blur від рівної заливки = та сама
     рівна заливка, тому раніше скла було не видно. */
  background: transparent;
  color: var(--fg);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 16.5px;
  line-height: 1.6;
  padding-bottom: calc(var(--dock) + var(--safe));
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }
h1, h2 { margin: 0; font-weight: 200; line-height: 1.02; letter-spacing: -.01em; }
ul, ol { margin: 0; padding: 0; list-style: none; }
[id] { scroll-margin-top: 20px; }

/* ---------- Три типографічні константи ----------
   Більше кеглів на сторінці немає. Через це полотно читається
   як кладка, а не як таблиця з різнобоєм. */
.kicker { font-size: 11px; letter-spacing: .26em; text-transform: uppercase; color: var(--muted); margin: 0 0 14px; }
/* ⚠ `lnum` обов'язковий: без нього «26 років» у заголовку виходить
   старостильними цифрами, які пірнають під рядок. */
.h1, .h2, .h1-page {
  font-family: var(--font-display);
  font-feature-settings: 'lnum' 1, 'kern' 1, 'liga' 1;
  font-weight: 400;
}
.h1 { font-size: clamp(38px, 10.5vw, 88px); line-height: 1.08; letter-spacing: 0; margin: 0 0 18px; }
.h2 { font-size: clamp(26px, 6.8vw, 46px); line-height: 1.12; letter-spacing: 0; margin: 0 0 12px; }
/* ⚠ ГРАДІЄНТ У ЗАГОЛОВКАХ — тільки великий тип (≥ 28px).
   Дрібне й кікери НЕ чіпаємо: градієнт у 11px зашумить
   і впаде в контрасті. Фолбек color:var(--fg) — перший
   (найконтрастніший) стоп, якщо background-clip не підтримано. */
.h1, .h2, .h1-page {
  background: var(--headline);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--fg);
}
.lead { color: var(--fg-2); margin: 0 0 12px; max-width: 54ch; line-height: 1.65; }
.sign { color: var(--muted); font-size: 14px; margin: 18px 0 0; }
.sec-lead { color: var(--muted); margin: 0; max-width: 52ch; font-size: 15.5px; line-height: 1.65; }

/* Золото — тільки текстом і тільки там, де дозволено законом №2. */
.gold {
  background: var(--metal);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--gold);
}

/* Риска «не підтверджено». Тонка, зліва, не заважає читати,
   але видно одразу, що рядок наш, а не її. */
.ask { position: relative; }
.ask::before {
  content: ''; position: absolute; left: -10px; top: .35em; bottom: .35em;
  width: 2px; background: var(--gold); opacity: .55; border-radius: 2px;
}

/* ---------- Чернетка ---------- */
.draft {
  position: relative; z-index: 60;
  background: var(--gold); color: var(--on-gold);
  font-size: 13px; line-height: 1.4; font-weight: 400;
  margin: 8px var(--pad) 0; padding: 9px 42px 9px var(--pad);
  border-radius: var(--r-m);
}
.draft button {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; font-size: 22px; line-height: 1; padding: 4px 8px; opacity: .5;
}
.draft.is-off { display: none; }

/* ---------- Шапка ----------
   Розкладку задає розділ «БАГАТОСТОРІНКОВІСТЬ» нижче: там шапка
   у три рядки (логотип+телефон / іменний рядок / рейка). Тут
   лишились тільки типографічні дрібниці. */
/* ⚠ БЕЗ uppercase І БЕЗ ТРЕКІНГУ. У каліграфічного шрифта літери
   зв'язані розчерками: капітель ламає зв'язки, а міжлітерний
   інтервал розриває їх фізично. Розмір більший за колишні 15px —
   скрипт при дрібному кеглі перетворюється на пляму. */
.top-mark {
  font-family: var(--font-script);
  /* ⚠ line-height 1 РІЗАВ РОЗЧЕРК. У каліграфічного шрифта верхній
     виносний елемент «V» виходить далеко за рядок, і при щільному
     інтерліньяжі його зрізає край шапки. Півтора — це не «на око»,
     а рівно та висота, за якої розчерк уміщається. */
  font-size: 32px; line-height: 1.5; letter-spacing: 0; text-transform: none;
  display: inline-block;
}
.top-mark i { font-style: normal; color: var(--gold); margin-left: .18em; }
.top-tel { font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- Герой ---------- */
.hero { padding: 28px var(--pad) 0; max-width: var(--max); margin: 0 auto; }

/* ⚠️⚠️ НИЖНИЙ КРАЙ ПОЛОТНА — ПАТЬОКИ, А НЕ РІВНА ЛІНІЯ.
   Власник сказав про цей модуль дослівно: «четкие прямоугольные
   границы… сделай их неровными, как будто накапало краской».
   Претензія по суті: рівний прямокутник читається як банер,
   вставлений у сторінку, а тут малюється ФАРБА — і в фарби
   немає прямого нижнього краю.

   Зроблено ДВОМА шарами маски, а не одним розтягнутим малюнком:
   • перший шар — суцільна заливка на всю висоту МІНУС смуга
     патьоків; він і тримає тіло кадру;
   • другий — плитка 560×113 із патьоками, покладена по низу
     через repeat-x у ПІКСЕЛЯХ.
   Чому саме плиткою: одна розтягнута на 100 % картинка робить
   на широкому екрані патьоки завширшки з долоню, а на телефоні —
   з нитку. Фіксована плитка тримає однакову краплю скрізь.
   Перекриття в 9 px між шарами обов'язкове: впритул на стику
   лишається волосина напівпрозорих пікселів, і вона видно як
   світла риска через увесь кадр. */
.canvas-wrap {
  position: relative; margin: 0 0 26px;
  border: 0; background: var(--map-bg);
  aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--r-l) 78px var(--r-s) 58px;
}

/* ⚠️⚠️ МАСКА — ТІЛЬКИ НА [data-nopal], ТОБТО ТІЛЬКИ НА ГОЛОВНІЙ.
   На /airtouch/ палітра й назва відтінку — АБСОЛЮТНІ ДІТИ
   цього ж елемента (їх додає canvas.js у wrap), а маска ріже ВСЕ,
   що нижче (висота − 102 px) — разом із кружечками й підписом.
   Тобто «красивіший край» з'їв єдиний орган керування цілої
   сторінки. На головній цього немає: там палітра живе на фото.
   І за сенсом так ж правильно: патьоки — це фарба, що стекла З
   ПОРТРЕТА; де портрета немає, текти нізвідки. */
.canvas-wrap[data-nopal] {
  --drip-band: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='560' height='113' viewBox='0 0 560 113'%3E%3Cg fill='%23000'%3E%3Cpath d='M0 0 H560 V11.2 L534.0 11.6 L523.4 12.1 C509.6 19.9 520.1 76.0 499.5 80.0 C479.0 76.0 489.5 19.9 475.6 13.4 L449.6 11.9 L423.6 9.3 L397.6 7.3 L391.6 7.1 C383.2 11.5 389.6 48.6 377.2 51.2 C364.7 48.6 371.1 11.5 362.7 7.8 L336.7 10.4 L329.3 11.2 C320.3 15.3 327.1 35.8 313.9 37.3 C300.6 35.8 307.4 15.3 298.4 13.9 L272.4 14.3 L246.4 13.2 L234.9 12.6 C221.1 18.4 231.5 73.9 211.1 77.8 C190.6 73.9 201.1 18.4 187.3 12.2 L161.3 14.0 L135.3 15.8 L109.3 16.1 L97.0 15.4 C90.0 17.4 95.3 43.0 84.9 44.8 C74.6 43.0 79.9 17.4 72.9 13.0 L46.9 10.0 L36.0 9.0 C28.7 11.3 34.3 36.7 23.4 38.5 C12.5 36.7 18.1 11.3 10.7 8.0 L0.0 8.2 Z'/%3E%3Cellipse cx='499.5' cy='94.0' rx='3.8' ry='5.0'/%3E%3Cellipse cx='211.1' cy='92.0' rx='3.8' ry='5.0'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(#000, #000), var(--drip-band);
  -webkit-mask-size: 100% calc(100% - 104px), 560px 113px;
  -webkit-mask-position: top left, bottom left;
  -webkit-mask-repeat: no-repeat, repeat-x;
  mask-image: linear-gradient(#000, #000), var(--drip-band);
  mask-size: 100% calc(100% - 104px), 560px 113px;
  mask-position: top left, bottom left;
  mask-repeat: no-repeat, repeat-x;
}
/* ⚠️ НА ШИРОКОМУ ЕКРАНІ КАДР — СМУГА, А НЕ 16:9. При 1440×900
   банер 16:9 займав 624 px із 900, і заголовок разом із чотирма
   цінами йшов за згин: перший екран показував саму лише текстуру
   й жодного слова. Це і є та «порожнеча», з якої все почалось.
   Композицію при цьому НЕ стискаємо — canvas.js обрізає її по
   центру: пасмо йде діагоналлю, і вужча смуга з нього читається
   як банер, а не як зіжмаканий кадр. */
@media (min-width: 900px) {
  /* +50 px до попередніх значень: рівно стільки з'їдає смуга
     патьоків, і без цієї добавки сам кадр став би нижчим. */
  .canvas-wrap { aspect-ratio: auto; height: clamp(340px, 46vh, 490px); }
}
#blow { display: block; width: 100%; height: 100%; }
/* ⚠ Підказка стоїть УГОРІ, а не внизу: внизу ліворуч живе назва
   відтінку, і два написи друкувались один по одному саме на
   першому екрані — тобто рівно тоді, коли це найпомітніше. */
/* ⚠️ Та сама плитка, що й під назвою відтінку, і з тієї ж причини:
   пасмо заходить у верхній лівий кут, і напис по ньому зникав. */
.canvas-note {
  position: absolute; left: 10px; top: 9px; z-index: 2;
  padding: 4px 11px 3px; border-radius: 999px;
  font-size: 12px; color: var(--fg); letter-spacing: .04em;
  background: rgba(10, 10, 10, .62);
  border: 1px solid rgba(242, 239, 233, .14);
  opacity: 0; transition: opacity .6s ease; pointer-events: none;
}
/* ⚠ ЦЕ ЄДИНЕ денне правило для підказки. Нижче у файлі стояв його
   дубль із власним padding і border-radius: 2px, і він мовчки
   перебивав плитку — у дні підказка була не пігулкою, а
   прямокутником. Той самий клас баги, що вже був із шапкою:
   після правок теми старі правила треба ВИДАЛЯТИ, а не лишати. */
[data-theme="day"] .canvas-note {
  color: var(--fg);
  background: rgba(255, 255, 255, .78);
  border-color: rgba(16, 74, 68, .14);
}
.canvas-note.is-on { opacity: 1; }

/* ---------- Вибір відтінку просто в героєві ----------
   Це не палітра «поганяти кольорики»: тут ті самі шість
   відтінків, що в блоці «Відтінки» нижче, з одного джерела.
   Людина крутить справжній колір, який потім побачить у прайсі
   й назве в директі. */
/* ⚠️⚠️ ПАЛІТРА СТОЯЛА НА ЩІЛЬНОМУ ВОЛОССІ. Заміряно сіткою 12×8:
   під нею заповненість 39–52 %, тобто шість кольорових кружечків
   лежали на масі волосся РІВНО ТИХ САМИХ кольорів — найгірший
   можливий фон для елемента, у якого колір і є вся інформація.
   А правий ВЕРХНІЙ кут порожній структурно: клітинки (0, 9–11) —
   нулі і до правки осі, і після. Це не недоробка, а геометрична
   ціна повороту дотичної на 50°, без якого полиск не ляже смугою.
   Заповнити його волоссям нічим — а зайняти осмисленим об'єктом
   можна. Дві задачі закриваються одним переїздом.
   ⚠️ Тільки на десктопі: на телефоні обрізки немає, дірка не
   виникає, а підказка й палітра поруч у 339 px не помістяться. */
.hair-pal {
  position: absolute; right: 10px; bottom: 10px; z-index: 2;
  display: flex; gap: 7px;
}
@media (min-width: 900px) {
  .hair-pal { top: 10px; right: 10px; bottom: auto; }
}
/* ⚠️ КНОПКА — ЦІЛЬ ПІД ПАЛЕЦЬ, КРУЖЕЧОК — ПСЕВДОЕЛЕМЕНТ. Було
   26×26 (на телефоні 22×22) при нормі 44: промах вибирав сусідній
   відтінок, а два сусідні відрізняються по контрасту на 1.04:1 —
   помилку не видно ні на кружечках, ні на полотні. Арифметика:
   6×44 = 264 px, полотно на екрані 320 px = 284 px. Влазить. */
.hair-sw {
  width: 44px; height: 44px; padding: 0; border: 0; background: none;
  display: grid; place-items: center;
  -webkit-tap-highlight-color: transparent;
  transition: transform .16s ease;
}
.hair-sw::before {
  content: ''; width: 26px; height: 26px; border-radius: 50%;
  background: var(--sw);
  border: 1px solid rgba(242,239,233,.22);
  box-shadow: 0 2px 8px rgba(0,0,0,.5);
  transition: box-shadow .16s ease;
}
/* ⚠️⚠️ КІЛЬЦЕ ВИБОРУ БУЛО НЕВИДИМЕ НА ЧОТИРЬОХ ЗРАЗКАХ ІЗ ШЕСТИ.
   Золото #C9A24A проти світлої половини кружечка: Карамель 1.09:1,
   Мідний 1.27, Попелястий блонд 1.38, Холодний беж 1.43 — при
   порозі 3:1 для нетекстових елементів не проходить жоден.
   Лишалось лише збільшення на 16 % — підпорогова різниця.
   Тепер два кільця: темна прокладка кольором тла, за нею золото.
   Проти найсвітлішого зразка прокладка дає 15.6:1. */
.hair-sw.is-on { transform: scale(1.12); }
.hair-sw.is-on::before {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--gold), 0 2px 8px rgba(0,0,0,.5);
}
.hair-sw:active { transform: scale(.94); }

/* ⚠️ ПІДПИС СТОЇТЬ НА ПЛИТЦІ, А НЕ ПРОСТО НА КАДРІ. Волосся тепер
   заповнює нижній лівий кут щільною масою, і сірий текст по ньому
   не читався взагалі — на телефоні назва відтінку зникала в самому
   волоссі. Плитка суцільна, без backdrop-filter: закон №4 дозволяє
   розмиття рівно на чотирьох заміряних елементах, і цей не з них. */
.hair-name {
  position: absolute; left: 10px; bottom: 10px; z-index: 2; margin: 0;
  padding: 5px 11px 4px; border-radius: 999px;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--fg); pointer-events: none;
  background: rgba(10, 10, 10, .62);
  border: 1px solid rgba(242, 239, 233, .14);
}
[data-theme="day"] .hair-name {
  color: var(--fg);
  background: rgba(255, 255, 255, .74);
  border-color: rgba(16, 74, 68, .14);
}

/* Підказка живе, доки до кадру не торкнулись жодного разу. */
.canvas-wrap .canvas-note { transition: opacity .5s ease; }
.canvas-wrap.is-touched .canvas-note { opacity: 0 !important; }

/* ⚠️ НА ВУЗЬКОМУ ЕКРАНІ НАЗВА СТОЇТЬ НАД ПАЛІТРОЮ, А НЕ ПОРУЧ.
   Заміряно на 360 px: «Темний шоколад із підсвіткою» — 272 px,
   палітра ще 190, і назва налазила на кружечки на 130 px. Ставити
   три крапки не можна: обрізана назва відтінку — це те саме, що
   збрехати про колір. Тому вони не сусіди, а два рядки. */
@media (max-width: 700px) {
  /* Ціль лишається 44, зменшується лише видимий кружечок. */
  .hair-sw::before { width: 22px; height: 22px; }
  .hair-pal { gap: 0; right: 1px; bottom: 1px; }
  .hair-name { bottom: 42px; max-width: calc(100% - 20px); }
}

/* Чотири ціни ДО першого свайпу. Головна відповідь на «порожньо»
   і на мовчазне «а скільки це коштує». */
.tiles {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: transparent; border: 0;
  margin: 26px 0 0;
}
.tiles li { background: var(--bg); padding: 15px 14px; border-radius: var(--r-m); }
.tiles b { display: block; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); font-weight: 300; margin-bottom: 5px; }
.tiles span { font-size: 20px; font-variant-numeric: tabular-nums; }


/* ══════════════════════════════════════════════════════════════
   ФОТО Й ВІДЕО НА ВНУТРІШНІХ СТОРІНКАХ
   ══════════════════════════════════════════════════════════════
   Той самий закон, що й у героєві: рамок немає, край гасне.
   Прямокутне фото на цьому сайті виглядає як чужа вставка —
   і саме про це була претензія власника до всієї верстки.
   ══════════════════════════════════════════════════════════════ */
.pg-shot, .pg-reel { margin: 0 auto; padding: 0 var(--pad); max-width: var(--max); }
.pg-shot { margin-top: 34px; }
.pg-reel { margin-top: 44px; }

.pg-shot-in, .pg-reel-in {
  position: relative; margin-inline: auto;
  width: min(100%, 420px);
}
.pg-shot-in {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.pg-shot-in img {
  display: block; width: 100%; height: auto;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 86%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 86%, transparent 100%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

/* ⚠️ ВІДЕО МАСКОЮ НЕ ЧІПАЄМО. Маска на <video> примушує
   композитор перемальовувати кадр на процесорі, і на телефоні
   це видно як ривки в самому ролику. Тому тут край тримає
   м'який радіус — тобто те, що композитор уміє без витрат. */
.pg-reel-in {
  width: min(100%, 340px);
  border-radius: var(--r-xl) var(--r-l) var(--r-xl) var(--r-l);
  overflow: hidden;
  box-shadow: 0 22px 50px rgba(0, 0, 0, .42);
}
.pg-reel-in video { display: block; width: 100%; height: auto; }

.pg-shot figcaption, .pg-reel figcaption {
  margin: 12px auto 0; text-align: center;
  font-size: 12.5px; color: var(--muted); letter-spacing: .04em;
}

/* ⚠️ БУЛО `float: right` — І ЦЕ БУЛА ПОМИЛКА РІВНЯ ВЕРСТКИ.
   Кожен блок сторінки — окрема <section> зі своїм потоком, тому
   обтікати плаваючий портрет НЕМА ЧОМУ: наступний текст починає
   власний контекст і просто йде НИЖЧЕ. Заміряно на /maister/:
   між портретом і першим абзацом лишалась діра на пів екрана.
   Портрет стоїть по центру й меншим — сторінка про людину має
   право починатися з обличчя, але не на весь екран. */
@media (min-width: 900px) {
  .pg-shot.is-side .pg-shot-in { width: min(100%, 340px); }
}

/* Удень згасання треба ШИРШЕ з усіх чотирьох боків.
   Контраст між тлом знімка й м'ятною сторінкою більший, ніж
   уночі, і коротке згасання читається як рамка. */
[data-theme="day"] .pg-shot-in {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 15%, #000 85%, transparent 100%);
}
[data-theme="day"] .pg-shot-in img {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 74%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 74%, transparent 100%);
}
/* Той самий острів, що й у фото героя (.shot-glow): студійний
   чорний фон удень читається випадковою плямою без власного
   теплого підкладення під низом. */
/* ⚠️⚠️ ТА САМА ДІРА, ЩО Й У .shot-glow ГЕРОЯ. .pg-shot-in ніде не
   обрізає вміст (маска керує лише пенлом, не геометрією), тому
   цей острів світла тягнув за собою всю сторінку вшир. Заміряно
   на проді: 128% від ширини .pg-shot-in давало на 390px переповнення
   30px, на 320px — 19px; уночі того самого правила взагалі немає.
   `min(128%, 480px)` не рятує: 480px — це стеля ЗНАЧЕННЯ, а не
   запас понад батьківський бокс, і на мобільних ширинах відсоток
   від вузького .pg-shot-in завжди менший за 480px, тобто стеля не
   спрацьовує ніколи. Правильна межа — це запас, на який світло
   сміє вилізти за .pg-shot-in, не вилізши за ЙОГО Ж батьківський
   .pg-shot (а той має власний `padding: 0 var(--pad)`, тобто
   рівно стільки простору, скільки треба). 108% — те саме безпечне
   число, що вже стоїть у мобільного .shot-glow героя (styles.css:762);
   тут перевірено тим самим виміром: 390px → 0px переповнення. */
[data-theme="day"] .pg-shot-in::before {
  content: ''; position: absolute; left: 50%; top: 2%;
  width: 128%; height: 90%; transform: translateX(-50%);
  background: radial-gradient(52% 46% at 50% 46%, rgba(24, 20, 18, .5), rgba(24, 20, 18, .18) 58%, transparent 76%);
  z-index: -1; pointer-events: none;
}
@media (max-width: 899px) {
  [data-theme="day"] .pg-shot-in::before { width: 108%; }
}
/* Плитка відтінку знята на чорному — удень це темний
   острів на світлому. М'яка тінь робить його карткою,
   а не діркою в сторінці. */
[data-theme="day"] .shade { box-shadow: 0 18px 38px rgba(16, 74, 68, .18); }
[data-theme="day"] .pg-reel-in { box-shadow: 0 20px 44px rgba(16, 74, 68, .16); }

/* ---------- Полотно фактів ---------- */
.facts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: transparent; border: 0;
  margin: 40px 0 0;
}
.facts li { background: var(--bg); padding: 20px var(--pad); }
.facts b { display: block; font-size: 30px; font-weight: 200; line-height: 1.1; margin-bottom: 6px; }
.facts span { font-size: 13.5px; color: var(--muted); line-height: 1.6; display: block; }

/* ---------- Секції ---------- */
.sec { padding: 58px var(--pad); max-width: var(--max); margin: 0 auto; }
.sec-head { position: relative; margin-bottom: 26px; padding-bottom: 18px; }
.sec-head::after {
  content: ''; position: absolute; left: 0; bottom: 0;
  width: min(230px, 72%); height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold) 24%, var(--gold) 76%, transparent);
  opacity: .62; pointer-events: none;
}

/* ---------- Питання ---------- */
.qa { display: grid; gap: 4px; background: transparent; border: 0; }
.qa li { background: var(--bg); padding: 20px 16px; }
.qa .q { font-size: 15px; margin: 0 0 8px; }
.qa .a { font-size: 15.5px; color: var(--fg-2); line-height: 1.65; margin: 0; }

/* Дві кнопки офера в героєві: головна і другорядна поруч.
   На вузькому — одна під одною на всю ширину. */
.hero-cta { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 0; }
.hero-cta .btn { flex: 1 1 auto; text-align: center; }
@media (max-width: 560px) { .hero-cta .btn { flex: 1 1 100%; } }

/* ══════════════════════════════════════════════════════════════
   ГЕРОЙ: СЛОВО ЛІВОРУЧ, ВІКТОРІЯ ПРАВОРУЧ
   ══════════════════════════════════════════════════════════════
   Перший екран раніше починався з абстракції — смуги волосин.
   Красиво, але людина, яка шукає майстра, спершу хоче побачити
   МАЙСТРА. Тепер ліворуч слово, праворуч вона сама, а абстракція
   лишилась нижче — як фарба, що стекла з портрета.

   ⚠️ Фото НЕ в прямокутнику. Знімок зроблено на темному тлі, і
   сайт теж темний, тому край просто розчиняється маскою — рамки
   немає взагалі, і взятись «квадратності» немає звідки.
   ══════════════════════════════════════════════════════════════ */
/* ⚠️⚠️ minmax(0, 1fr), А НЕ ПРОСТО СІТКА. Заміряно на 360 px:
   колонка автоматичної ширини = max-content, а в портрета вона
   похідна від висоти (480 × 0.793 = 381 px). Колонка розтягувалась
   до 381 при екрані 360, і `max-width: 100%` більше нічого не різало:
   100 % від 381 — це 381. Заголовок й текст їхали за край екрана. */
.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: clamp(16px, 3vw, 44px); align-items: center;
}

@media (min-width: 980px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr) minmax(300px, 43%); }
}
/* ⚠️ НА ТЕЛЕФОНІ ФОТО ПІДНІМАЄТЬСЯ НАГОРУ СИЛОЮ CSS, а не
   порядком у розмітці: пошуковик і читалка мусять отримати
   заголовок першим, а око — обличчя. */
@media (max-width: 979px) {
  .hero-copy { order: 2; }
  .hero-shot { order: 1; }
}

/* ⚠️⚠️ КЛАС `.shot` БУВ УЖЕ ЗАЙНЯТИЙ — і це ламало «Роботи».
   `app/home.js` малює першою клітинкою кожного рядка робіт
   `<span class="shot">` — колонку під майбутнє фото шириною
   `--shot: 0px`. Мої правила героя падали і на неї: `order: 1` піднімав
   нульову колонку нагору, і заголовок роботи з'їжджав у щілину
   в нуль пікселів. Префікс обов'язковий. */
.hero-shot { position: relative; margin: 0; min-width: 0; }

/* ⚠️ ЗАГОЛОВОК У ГЕРОЄВІ МЕНШИЙ ЗА ЗАГАЛЬНИЙ .h1.
   На 1440×900 вісімдесят восьмипіксельний заголовок займав
   чотири рядки й зіштовхував обидві кнопки за згин. На
   внутрішніх сторінках цього немає: там фото не забирає півекрана. */
@media (min-width: 980px) {
  .hero-copy .h1 { font-size: clamp(34px, 4.4vw, 62px); margin-bottom: 14px; }
  .hero-copy .lead { max-width: 46ch; }
}

.shot-frame {
  /* ⚠️ ВИСОТА ВЕДЕ, А НЕ ШИРИНА. При width:100% портрет на
     1440×900 виріс до 592 px і зіштовхнув обидві кнопки за згин:
     перший екран показував красу й жодного способу записатись. */
  position: relative;
  height: min(50vh, 470px); width: auto; max-width: 100%;
  margin-inline: auto;
  aspect-ratio: 853 / 1075;
  transform: translateY(var(--par, 0px));
  /* Край гасне по боках. Заміряно по самому знімку:
     волосся лежить у межах 13–89 % ширини кадру, тому 9 %
     згасання з кожного боку — це межа, за якою починається вже
     пасмо, а не тло. Більше — і фарба на кінчиках бліднішає
     разом із краєм, тобто гасне саме те, що ми продаємо. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
/* Друга маска — по вертикалі. Зверху легко (там вінок),
   знизу сильно: саме там фото мусить перейти в планку відтінків
   без жодного різа. */
.shot-stack {
  position: absolute; inset: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 5%, #000 82%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 5%, #000 82%, transparent 100%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

.shot-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 4%;
  display: block;
}
/* Верхній шар мовчить, поки не наливається. */
.shot-b { opacity: 0; }

/* ⚠️⚠️ ПЕРЕХІД МІЖ ВІДТІНКАМИ — ЗАЛИВКА ЗГОРИ, А НЕ CROSSFADE.
   Кадри згенеровані по одному на відтінок, і між ними лишається
   мікрорізниця в рисах. На прямому затуханні вона читається як
   «обличчя попливло» — найгірше, що може статись із портретом
   живої людини на її ж сайті. Заливка з нерівним краєм веде око
   за собою: дивишся на межу фарби, а не на риси.

   Маска вдвічі вища за кадр: у верхній половині суцільна, далі
   патьоки, нижче порожньо. Тому `mask-position: 0 100%` — це
   «фарби ще немає», а `0 0` — «залито повністю». */
.shot-b.is-pour {
  opacity: 1;
  --pour: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='1200' viewBox='0 0 600 1200' preserveAspectRatio='none'%3E%3Cg fill='%23000'%3E%3Cpath d='M0 0 H600 V601.4 L574.0 599.4 L548.0 596.4 L528.8 594.6 C509.1 597.8 524.0 623.4 494.9 625.2 C465.7 623.4 480.6 597.8 460.9 598.6 L434.9 601.8 L408.9 603.1 L397.9 603.0 C388.2 611.5 395.6 690.3 381.2 695.9 C366.8 690.3 374.2 611.5 364.5 601.0 L338.5 599.8 L312.5 600.5 L286.5 602.6 L281.5 603.1 C271.7 610.5 279.1 662.2 264.6 665.9 C250.0 662.2 257.4 610.5 247.6 604.9 L221.6 603.7 L195.6 600.4 L169.6 596.8 L157.0 595.7 C147.3 600.3 154.6 644.1 140.2 647.2 C125.8 644.1 133.2 600.3 123.5 595.5 L97.5 597.6 L71.5 599.7 L45.5 600.1 L38.7 599.9 C29.3 603.5 36.5 641.2 22.5 643.9 C8.5 641.2 15.7 603.5 6.2 598.0 L0.0 597.6 Z'/%3E%3Cellipse cx='381.2' cy='706.3' rx='2.7' ry='3.5'/%3E%3Cellipse cx='264.6' cy='676.5' rx='2.7' ry='3.6'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-image: var(--pour); mask-image: var(--pour);
  -webkit-mask-size: 100% 200%; mask-size: 100% 200%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: 0 100%; mask-position: 0 100%;
}

/* Тепле світло ЗА портретом. Не тінь і не рамка: просто повітря
   навколо, щоб фото не висіло в мертвій чорноті. */
.shot-glow {
  position: absolute; left: 50%; top: 4%;
  width: min(122%, 620px); height: 78%;
  transform: translateX(-50%);
  background: radial-gradient(52% 46% at 50% 44%, rgba(201, 162, 74, .17), rgba(201, 162, 74, .05) 58%, transparent 76%);
  pointer-events: none;
}

/* ---------- планка відтінків ----------
   Плитка з кружечками стоїть ПІД фото, а не на ньому: на самому
   знімку вона лягала б або на вишивку, або на волосся — тобто
   рівно на те, заради чого фото тут стоїть. */
.shot-bar {
  position: relative; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 10px 14px;
  margin: -14px auto 0; width: min(var(--shot-w, 470px), 100%);
  padding: 12px 16px;
  background: var(--surface);
  border-radius: var(--r-l) var(--r-m) var(--r-s) var(--r-m);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .35);
}
.shot-pal { display: flex; gap: 4px; flex: none; }
.shot-sw {
  position: relative; width: 38px; height: 38px;
  border: 0; background: none; padding: 0; cursor: pointer;
  border-radius: 50%;
}
/* ⚠️ Кружечок малює псевдоелемент, а сама кнопка розтягнута до
   38 px: видима ціль у 22 px під палець — це промах у сусідній
   відтінок, якого людина навіть не помітить. */
.shot-sw::before {
  content: ''; position: absolute; inset: 50% auto auto 50%;
  width: 22px; height: 22px; transform: translate(-50%, -50%);
  border-radius: 50%; background: var(--sw);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16);
  transition: transform .2s ease;
}
.shot-sw:hover::before { transform: translate(-50%, -50%) scale(1.12); }
.shot-sw.is-on::before {
  transform: translate(-50%, -50%) scale(1.1);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3), 0 0 0 2px var(--gold);
}
.shot-sw:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.shot-cap { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.shot-name { font-size: 14px; color: var(--fg); letter-spacing: .02em; }
.shot-hint { font-size: 11.5px; color: var(--muted); letter-spacing: .04em; transition: opacity .5s ease; }
.shot-hint.is-off { opacity: 0; }

/* ---------- патьоки з-під планки ----------
   Той самий жест, що й унизу полотна, але тут фарба МАЛЬОВАНА:
   маска показала б пікселі фото (низ спідниці), а показати треба
   обраний КОЛІР. Колір ставить hero-photo.js двома змінними. */
.shot-drip {
  /* ⚠️ ВИСОТА ПІДІГНАНА ПІД viewBox, А НЕ ВЗЯТА З ГОЛОВИ.
     preserveAspectRatio=none розтягує малюнок по обох осях незалежно.
     При 600→470 по ширині (0.78) і 99→74 по висоті (0.75) краплі були
     притиснуті й читались як обрублені стовпчики. 78 px тримає
     обидва масштаби біля 0.78 — форма краплі лишається краплею. */
  display: block; width: min(var(--shot-w, 470px), 100%); height: 78px;
  /* ⚠️⚠️⚠️ ТУТ НЕ МОЖЕ БУТИ `--drip-a: …`. Було — і патьоки
     НІКОЛИ не міняли колір. hero-photo.js кладе змінні на
     батьківський <figure> і розраховує на успадкування, але
     ВЛАСНЕ оголошення на елементі б'є успадковане завжди,
     навіть якщо те прийшло inline зі стилю. Запасне значення
     тепер стоїть у самому var() у hero-photo.js. */
  /* Початок смуги ховається ПІД планку: без цього верх
     SVG — це рівна смуга на всю ширину з квадратними кінцями
     під круглою карткою — найпомітніше в денній темі. */
  margin: -12px auto 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 16%);
  mask-image: linear-gradient(180deg, transparent 0, #000 16%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  opacity: .92;
  pointer-events: none;
}
/* Крапля зривається раз на дев'ять секунд і гасне на
   лету. transform-box: fill-box обов'язковий: без нього початок
   координат — кут viewBox, і крапля від'їжджає не туди. */
@keyframes vf-drop {
  0%, 60% { transform: translateY(0); opacity: 0; }
  64% { opacity: 1; }
  86% { transform: translateY(22px); opacity: .55; }
  96%, 100% { transform: translateY(30px); opacity: 0; }
}
.shot-drip .shot-fall {
  transform-box: fill-box; transform-origin: center;
  animation: vf-drop 9s var(--d, 0s) infinite cubic-bezier(.55, 0, .85, .4);
}
@media (prefers-reduced-motion: reduce) {
  .shot-drip .shot-fall { animation: none; opacity: 0; }
}

/* На вузькому веде ШИРИНА, а не висота: екрана все одно не
   вистачає, щоб показати портрет ціликом і ще залишити місце
   на слово, а обрізати його з боків — це відрізати волосся. */
@media (max-width: 979px) {
  .shot-frame { height: auto; width: min(100%, 400px); }
  /* Сяйво не має права вилізати за екран: `overflow-x: hidden`
     на body його відрізає, але розраховувати на це — значить
     тримати в макеті елемент, що ширший за вікно. */
  .hero-shot .shot-glow { width: min(108%, 420px); }
}
@media (max-width: 420px) {
  .shot-sw { width: 34px; height: 34px; }
  .shot-bar { padding: 10px 12px; gap: 8px 10px; }
}

/* День: фото — темний острів на світлому. Це не помилка, а
   рішення: знімок студійний, на чорному, і «висвітлити» його
   означало б підробити освітлення. Тому даємо йому власне
   м'яке підкладення, щоб острів читався як навмисний. */
/* ⚠️⚠️ У ДЕННІЙ ТЕМІ ФОТО ЗНОВУ СТАЄ ПРЯМОКУТНИКОМ.
   Ночі його немає: тло знімка й тло сторінки — одна чорнота, і
   9 % згасання вистачає. Удень сторінка світла, і той самий
   край читається як темна плита, приклеєна на м'яту. Дві правки,
   обидві тільки в денній:
   1. ширше згасання (16 % замість 9) — край йде в ніщо повільніше;
   2. темна аура ЗА фото — тобто те, в ЩО воно гасне. Без неї
      згасання впирається в контраст 1:12 і все одно малює межу. */
/* ⚠⚠ ГОРИЗОНТАЛЬНА ПРОКРУТКА НА ТЕЛЕФОНІ, ЛИШЕ ВДЕНЬ.
   Мобільне звуження світіння (styles.css:762, `width: min(108%, 420px)`)
   стоїть усередині `@media (max-width: 979px)`, а денне розширення
   до 132% йде окремим, нічим не обмеженим правилом НИЖЧЕ у файлі —
   і на мобільному екрані перебиває вузьке значення тим самим
   каскадом, яким на десктопі мало перебивати нічне. Заміряно на
   проді: 390px/день → сторінка ширша за екран на 36px, 320px/день
   — на 25px; уночі на тих самих ширинах нуль. Виправлення — та сама
   мобільна межа, тільки в денному кольорі: не новий розмір, а
   перелицювання наявного під потрібну тему. */
[data-theme="day"] .hero-shot .shot-glow {
  background: radial-gradient(50% 46% at 50% 46%, rgba(24, 20, 18, .5), rgba(24, 20, 18, .2) 58%, rgba(24, 20, 18, 0) 76%);
  width: min(132%, 660px); height: 88%; top: 1%;
}
@media (max-width: 979px) {
  [data-theme="day"] .hero-shot .shot-glow { width: min(108%, 420px); }
}
[data-theme="day"] .shot-frame {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16%, #000 84%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 16%, #000 84%, transparent 100%);
}
[data-theme="day"] .shot-stack {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 74%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 9%, #000 74%, transparent 100%);
}
[data-theme="day"] .shot-sw::before { box-shadow: inset 0 0 0 1px rgba(16, 74, 68, .18); }
[data-theme="day"] .shot-sw.is-on::before { box-shadow: inset 0 0 0 1px rgba(16, 74, 68, .22), 0 0 0 2px var(--gold); }
[data-theme="day"] .shot-bar { box-shadow: 0 16px 34px rgba(16, 74, 68, .12); }


/* Кнопка під секцією: відступ і власна ширина за вмістом. */
#trust > .btn, #why > .btn, #offer > .btn { display: inline-block; margin-top: 22px; }

/* ---------- Послуги: шість напрямків ----------
   Шість карток у дві колонки дають рівно три ряди без дір, а короткий
   згасаючий шов не перетворює цю щільність на таблицю. Уся картка —
   посилання, тому клікабельна площа велика на тачі. */
.svc {
  display: grid; gap: 4px; background: transparent;
  border: 0; list-style: none; margin: 0; padding: 0;
}
.svc li { background: var(--bg); }
.svc a {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 14px;
  padding: 22px var(--pad) 20px; height: 100%; align-content: start;
  border-radius: inherit;
}
.svc b { font-size: 17px; font-weight: 400; grid-column: 1; }
.svc .svc-p {
  grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap;
  font-size: 24px; font-weight: 200; font-variant-numeric: tabular-nums;
  background: var(--metal); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--gold);
}
.svc .svc-t {
  grid-column: 2; grid-row: 2; text-align: right; font-style: normal;
  font-size: 12.5px; color: var(--muted); white-space: nowrap;
}
.svc p { grid-column: 1 / -1; margin: 8px 0 0; color: var(--fg-2); font-size: 15px; line-height: 1.65; }
.svc .svc-go {
  grid-column: 1 / -1; margin-top: 14px; font-style: normal;
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}
.svc .svc-go::after { content: ' →'; }
@media (hover: hover) and (pointer: fine) {
  .svc a:hover .svc-go { color: var(--gold); }
}
@media (min-width: 760px) { .svc { grid-template-columns: 1fr 1fr; } }

/* ⚠ На вузькому ціна й назва не вміщаються в один рядок: діапазон
   «3 900 – 5 400 ₴» бере ~180 px із 354, і назва ламається на три
   рядки. Зменшити кегль не можна — 24 px це поріг, за яким метал у
   background-clip:text законно тримає 3:1 (нижче потрібно 4.5, а
   найтемніший стоп його не дає). Тому не тиснемо, а розносимо. */
@media (max-width: 560px) {
  .svc a { grid-template-columns: auto 1fr; }
  .svc b { grid-column: 1 / -1; grid-row: 1; }
  .svc .svc-p { grid-column: 1; grid-row: 2; text-align: left; margin-top: 6px; }
  .svc .svc-t {
    grid-column: 2; grid-row: 2; text-align: left; align-self: end;
    margin-left: 12px; padding-bottom: 5px;
  }
}

/* ⚠ НА 320px КАРТКА ВИЛАЗИЛА ЗА ЕКРАН НА 9px. Причина не в тексті:
   ціна й час обидва `white-space: nowrap` і стояли в одному рядку, а
   клітинка ґрід-контейнера типово має `min-width: auto`, тобто не
   може стати вужчою за свій нерозривний вміст — і розсувала всю
   картку. `body{overflow-x:hidden}` це ховав, тому сторінка не
   їздила, зате правий кант картки зрізало.
   Лік із двох частин: дозволити клітинці стискатись і дозволити
   часу переноситись. Кегль ціни чіпати не можна — 24px це поріг
   контрасту для металу. */
@media (max-width: 380px) {
  .svc a, .svc li { min-width: 0; }
  .svc .svc-p { min-width: 0; }
  .svc .svc-t { white-space: normal; margin-left: 10px; }
}

/* ---------- Прайс ---------- */
.airtouch {
  position: relative; overflow: hidden;
  border: 0; border-radius: var(--r-xl); padding: 22px 18px;
  background: var(--card);
  box-shadow: var(--soft-shadow); margin-bottom: 24px;
}
.airtouch h3 { margin: 0 0 4px; font-size: 26px; font-weight: 200; }
.airtouch .meta { font-size: 13px; color: var(--muted); letter-spacing: .1em; text-transform: uppercase; margin: 0 0 12px; }
.airtouch p { margin: 0; font-size: 15.5px; line-height: 1.65; color: var(--fg-2); }
.airtouch .sum { font-size: 26px; font-variant-numeric: tabular-nums; margin-top: 14px; display: block; }

.switch-wrap { position: sticky; top: 0; z-index: 20; background: var(--bg); padding: 12px 0 10px; }
.switch-wrap::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent);
  pointer-events: none;
}
.switch { display: flex; gap: 3px; padding: 3px; background: transparent; border: 0; border-radius: var(--r-m); }
.switch button {
  flex: 1; background: var(--bg); border: 0; padding: 11px 6px;
  border-radius: var(--r-s); font-size: 13.5px; color: var(--muted);
  transition: color .16s, background .16s, box-shadow .16s, transform .16s;
}
.switch button.is-on { background: var(--surface); color: var(--gold); }
.switch-note { font-size: 12px; color: var(--muted); margin: 9px 0 0; }

.price-body { position: relative; padding-left: 16px; }
/* Хребет: та сама розтяжка айртачу, вертикально вздовж усього прайсу.
   Малюється один раз при появі — і більше ніколи не рухається. */
.spine {
  position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--spine); transform: scaleY(0); transform-origin: 50% 0;
  transition: transform .9s cubic-bezier(.22,.61,.36,1);
}
.spine.is-on { transform: scaleY(1); }

.pgroup { margin: 26px 0 0; }
.pgroup > h3 {
  font-size: 11px; letter-spacing: .28em; text-transform: uppercase;
  margin: 0 0 10px; font-weight: 400;
}
.pgroup .note { font-size: 12px; color: var(--muted); letter-spacing: 0; text-transform: none; margin-left: .8em; }

.prow {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 14px;
  position: relative; padding: 12px 0;
  cursor: pointer; transition: transform .09s;
}
.prow:active { transform: scale(.985); }
/* Позиції задані явно. Автопідстановка сітки ставить елемент із
   визначеним рядком раніше за інші, і .p забирала першу колонку —
   ціна опинялась ліворуч від назви. Явні координати знімають
   питання назавжди. */
.prow .n { grid-column: 1; grid-row: 1; font-size: 16px; }
.prow .m { grid-column: 1; grid-row: 2; font-size: 13px; color: var(--muted); }
.prow .p {
  grid-column: 2; grid-row: 1 / span 2; align-self: center; text-align: right;
  /* ⚠⚠ 24px, А НЕ 19px, І ЦЕ ДОСТУПНІСТЬ, А НЕ СМАК. Цифра залита
     градієнтом --metal через background-clip:text, тому її контраст
     визначає НАЙТЕМНІШИЙ стоп. Уночі це #8A6A2E — 3.73:1 на #121212,
     і його стеля навіть на ідеально чорному лише 4.18, тобто підняти
     стоп до 4.5 неможливо, не зруйнувавши метал. Удень дзеркально:
     найсвітліший стоп #B0687A дає 3.65:1.
     При 19px і вазі 300 текст НЕ є великим за WCAG (потрібно 24px, або
     18.66px жирним), тому поріг був 4.5:1 і прайс його не тримав в
     ОБОХ темах — на живому проді. З 24px поріг законно стає 3:1, і
     обидва градієнти проходять цілком, не втрачаючи блиску. */
  font-size: 24px; font-variant-numeric: tabular-nums; white-space: nowrap;
  background: var(--metal); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--gold);
  transition: opacity .17s linear;
}
/* ⚠ ПРАВИЛО: МЕТАЛ ТІЛЬКИ НА ТЕКСТІ ≥24px. Нижче — суцільне золото.
   Градієнт із п'яти стопів на 15-22px не може тримати 4.5:1 у жодній
   темі (див. розрахунок вище), а суцільний --gold тримає з запасом:
   ніч 7.81:1, день 5.29:1. */
.prow .p.free,
.qa .q.gold {
  background: none;
  -webkit-text-fill-color: currentColor;
  color: var(--gold);
}
.prow .p.free { font-size: 15px; }
/* Підміна цін — одна анімація на весь список, а не десять окремих.
   Ширина не стрибає завдяки tabular-nums, тому рефлоу немає. */
.price-body.swap .p { opacity: 0; }

.draft-note {
  border: 1px solid var(--gold); color: var(--gold);
  border-radius: var(--r-s); font-size: 13px; padding: 10px 14px; margin: 0 0 18px;
}
.proof { font-size: 14.5px; line-height: 1.65; color: var(--muted); margin: 22px 0 0; }

/* ---------- Сертифікати ---------- */
.gifts { display: grid; gap: 4px; background: transparent; border: 0; }
.gifts li { background: var(--card-2); padding: 20px 16px; }
.gifts b { display: block; font-size: 28px; font-weight: 200; font-variant-numeric: tabular-nums; margin-bottom: 4px; }
.gifts span { font-size: 13.5px; color: var(--muted); }
.terms { font-size: 14.5px; line-height: 1.65; color: var(--muted); margin: 18px 0 0; }

/* ---------- Кроки візиту ---------- */
.steps { position: relative; padding-left: 34px; }
.steps::before {
  content: ''; position: absolute; left: 9px; top: 8px; bottom: 8px;
  width: 2px; background: var(--spine);
}
.steps li { position: relative; padding: 0 0 24px; border-radius: var(--r-m); }
.steps li::before {
  content: ''; position: absolute; left: -30px; top: 7px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--dot, #4A4038); border: 1px solid var(--bg);
}
.steps .t { font-size: 17px; margin: 0 0 5px; }
.steps .d { font-size: 15px; line-height: 1.65; color: var(--fg-2); margin: 0; }

.guarantee { position: relative; border: 0; border-radius: var(--r-l); padding: 18px 16px; margin-top: 6px; box-shadow: var(--soft-shadow); }
.guarantee-t { font-size: 11px; letter-spacing: .28em; text-transform: uppercase; color: var(--muted); margin: 0 0 12px; }
.guarantee li { position: relative; font-size: 15.5px; padding: 7px 0; }

/* ---------- Роботи ---------- */
.works li {
  display: grid; grid-template-columns: var(--shot) 1fr auto; gap: 0 14px;
  position: relative; align-items: center; padding: 13px 14px;
}
.works .t { font-size: 15.5px; }
.works .r { text-align: right; font-size: 13px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.works .shot { width: var(--shot); }

/* ---------- Рейки ----------
   proximity, не mandatory: на iOS mandatory б'ється з інерцією
   при швидкому флику й рейка «застрягає».
   overscroll-behavior-x: contain — без нього свайп на Android
   перехоплює системний жест «назад». */
.rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 62vw; gap: 10px;
  overflow-x: auto; scroll-snap-type: x proximity; overscroll-behavior-x: contain;
  margin: 0 calc(var(--pad) * -1); padding: 0 var(--pad) 4px;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail > li { scroll-snap-align: start; }
/* Плитка відтінку. Була прямокутником із градієнтом у
   рамці — тобто точно те, про що сказали «слишком
   квадратный». Тепер це пасмо на чорному, край якого
   гасне в тло сторінки: границі плитки просто немає. */
.shade {
  position: relative; aspect-ratio: 4 / 5;
  border: 0; padding: 14px; display: flex; align-items: flex-end;
  border-radius: var(--r-l) var(--r-s) var(--r-l) var(--r-s);
  overflow: hidden;
}
.rail li:nth-child(even) .shade { border-radius: var(--r-s) var(--r-l) var(--r-s) var(--r-l); }
.shade img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
  /* Знімок темний по краях, тому згасання може бути
     коротким: градієнт під ним того ж кольору, і
     стику не видно взагалі. */
  -webkit-mask-image: radial-gradient(78% 74% at 50% 46%, #000 62%, rgba(0,0,0,.6) 84%, rgba(0,0,0,0) 100%);
  mask-image: radial-gradient(78% 74% at 50% 46%, #000 62%, rgba(0,0,0,.6) 84%, rgba(0,0,0,0) 100%);
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
/* ⚠️ ТІНЬ НА ТЕКСТІ НЕ РЯТУЄ, КОЛИ ПІД НИМ СВІТЛИЙ КІНЧИК ПАСМА.
   На «Попелястому блонді» світла прядка якраз лягає в нижній
   лівий кут — той самий, де стоїть підпис — і контраст падає
   нижче читабельного. Замість тіні на кожній літері — суцільна
   темна підкладка під усім нижнім краєм картки, однакова
   незалежно від того, що там на фото. */
.shade::after {
  content: ''; position: absolute; inset: auto 0 0 0; z-index: 1;
  height: 46%; pointer-events: none;
  background: linear-gradient(0deg, rgba(10,9,8,.72) 0%, rgba(10,9,8,.38) 52%, transparent 100%);
}
.shade span {
  position: relative; z-index: 2;
  font-size: 14px; color: #F6F1E6; text-shadow: 0 1px 6px rgba(0,0,0,.6);
}

/* ---------- Відгуки ---------- */
.numbers { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 4px; background: transparent; border: 0; margin-bottom: 22px; }
.numbers li { background: var(--bg); padding: 16px 12px; border-radius: var(--r-m); }
.numbers b { display: block; font-size: 24px; font-weight: 200; margin-bottom: 4px; }
.numbers span { font-size: 12.5px; color: var(--muted); line-height: 1.6; display: block; }
.empty-note { border: 1px solid var(--line); padding: 18px 16px; }
.empty-note p { margin: 0 0 14px; color: var(--fg-2); font-size: 15.5px; }

/* ---------- Салон ---------- */
.salon-facts { display: grid; gap: 4px; background: transparent; border: 0; }
.salon-facts li { background: var(--bg); padding: 16px; border-radius: var(--r-m); }
.salon-facts b { display: block; font-size: 16px; font-weight: 400; margin-bottom: 3px; }
.salon-facts span { font-size: 14px; color: var(--muted); }

/* ---------- Карта ---------- */
.where-grid { display: grid; gap: 22px; }
.map { position: relative; border: 0; border-radius: var(--r-xl); background: var(--map-bg); box-shadow: var(--soft-shadow); overflow: hidden; aspect-ratio: 4 / 3; }
.map svg { display: block; width: 100%; height: 100%; }
.where-text { color: var(--fg-2); margin: 0 0 10px; }
.where-hours { color: var(--muted); font-size: 15px; margin: 0 0 18px; }
.where-btns { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------- Кнопки ---------- */
.btn {
  display: inline-block; padding: 14px 24px; font-size: 15px;
  letter-spacing: .04em; border: 1px solid var(--line); border-radius: 999px;
  color: var(--fg); transition: transform .09s, border-color .16s, color .16s, background-color .16s, box-shadow .16s;
  /* ⚠️ БЕЗ ЦЬОГО РЯДКА `.btn` НА <button> ВИХОДИТЬ БІЛИМ. Доти цей
     клас вішали тільки на посилання, тому браузерне тло кнопки
     ніколи не проступало — і виявилось воно аж на сторінці запису,
     де «Перенести» і «Скасувати» справді кнопки, а не переходи.
     Заливку далі ставить .btn-gold, він оголошений нижче й виграє
     за порядком. */
  background: none;
}
/* ⚠️ НАТИСКАННЯ БУЛО ЛЕДЬ ПОМІТНЕ. scale(.985) на 15-піксельній
   кнопці — це пів пікселя: палець не отримував відповіді взагалі.
   Тепер стиск глибший і додано вивернутий bevel, той самий прийом,
   що вже стоїть у .btn-gold: верхній відблиск гасне, знизу
   з'являється тінь — скло продавлюється, а не блимає.
   ⚠️ Перехід НАЗАД у натиснутий стан швидший (.05s), назовні —
   лишається м'яким: натиск має відчуватись миттєво. */
.btn:active {
  transform: scale(.965);
  box-shadow: var(--btn-press);
  transition-duration: .05s;
}
.btn-ghost { color: var(--fg-2); }
/* ⚠ ХОВЕР ЗАЛИПАЄ НА ТАЧІ. Після тапу браузер лишає :hover доти,
   доки людина не торкнеться іншого місця. Найгірше на .pill: у нього
   і в стану .is-on однаковий золотий кант, тобто просто торкнута
   пігулка виглядає як обрана — на головній рейці навігації.
   Обгортка стоїть ПОЗАДУ КОЖНОГО ПРАВИЛА ОКРЕМО, а не одним блоком у
   кінці файлу: у .pill:hover і .pill.is-on однакова специфічність
   (0,2,0), і переніс ховера нижче зробив би так, що він перебивав би
   активний стан. */
/* ============================================================
   ДРУГОРЯДНА КНОПКА — ТЕ САМЕ СКЛО, ТІЛЬКИ БЕЗ КОЛЬОРУ

   ⚠️ У неї не було НІ градієнта, ні відповіді на натиск: плаский
   кант і зміна кольору тексту. Поруч із золотою вона читалась як
   вимкнена, хоча «Переглянути роботи» — рівноправна дія.

   ⚠️⚠️ ЗАКОН №2 НЕ ПОРУШЕНО. Золото лишається тільки на кінцях;
   тут узято СТРУКТУРУ скла, а не його колір: пляма світла зверху
   (--btn-hi, той самий токен) і той самий п'ятистоповий рух, але
   зробленому з білого, а не з металу. Тобто це фрост, як і було
   задумано в коментарі нижче, — просто тепер він має об'єм і тече.

   ⚠️ ШИРИНА ФОНУ 230%, ЯК У ЗОЛОТОЇ. Саме через це на ховері
   зсув background-position ТЯГНЕ відблиск уздовж кнопки, а не
   перемикає два стани. Це і є «рідке» в «рідкому склі».
   ============================================================ */
.btn-ghost {
  background:
    radial-gradient(130% 180% at 18% -30%, var(--btn-hi), rgba(255,255,255,0) 52%),
    linear-gradient(100deg,
      rgba(255,255,255,0) 0%, rgba(255,255,255,.05) 30%,
      rgba(255,255,255,.11) 47%, rgba(255,255,255,.05) 64%,
      rgba(255,255,255,0) 100%);
  background-size: auto, 230% 100%;
  background-position: 0 0, 0% 0%;
  transition: transform .09s, border-color .16s, color .16s, box-shadow .16s,
              background-position .5s cubic-bezier(.22,.61,.36,1);
}
@media (hover: hover) and (pointer: fine) {
  /* ⚠️ ФРОСТ, А НЕ ЗОЛОТО. Другий закон файлу: золото стоїть тільки
     на «кінцях». Кант і текст на ховері золотяться — це «кінець»,
     точка дії; сама ж плівка лишається безбарвною. */
  .btn-ghost:hover {
    border-color: var(--gold); color: var(--gold);
    background-position: 0 0, 100% 0%;
    box-shadow: var(--rail-shadow), var(--btn-bevel);
  }
}
.btn-ghost:active {
  transform: scale(.965);
  box-shadow: var(--btn-press);
  transition-duration: .05s;
}

/* ============================================================
   ЗОЛОТА КНОПКА — РІДКЕ СКЛО БЕЗ backdrop-filter

   ⚠️⚠️ ЗАКОН №4 НЕ ЗНЯТО, А ОБІЙДЕНО. «Рідке скло» тут — не блюр
   позаду кнопки (він і був заборонений, у сусідньому проєкті вже
   морозив рендер під час скролу), а те, з чого й складається сама
   ідея скла: відблиск світла зверху й тінь під ним. Обидва —
   ЗВИЧАЙНІ ФОНОВІ ШАРИ, а не ефекти рендера, тому коштують як
   картинка, не як фільтр на весь екран.

   Два шари фону через кому — той самий прийом, що вже стоїть у
   .ask-btn (`background: var(--rail-bg), var(--surface)`):
     1. radial-gradient зверху-зліва — пляма світла на випуклому склі.
     2. --metal — той самий п'ятистоповий блиск, що й на цифрах
        прайсу. Другий шар зроблено ШИРШИМ за кнопку
        (background-size: 220%), тому на ховері зсув
        background-position тягне глянець уздовж кнопки — це і є
        «рідке»: колір тече, а не блимає між двома станами.
   ============================================================ */
.btn-gold {
  position: relative;
  background:
    radial-gradient(130% 180% at 18% -30%, var(--btn-hi), rgba(255,255,255,0) 48%),
    var(--metal);
  background-size: auto, 230% 100%;
  background-position: 0 0, 0% 0%;
  color: var(--on-gold); border-color: var(--gold); font-weight: 400;
  box-shadow: var(--btn-bevel);
  transition: transform .09s, box-shadow .16s ease, filter .16s ease, background-position .5s cubic-bezier(.22,.61,.36,1);
}
@media (hover: hover) and (pointer: fine) {
  .btn-gold:hover { background-position: 0 0, 100% 0%; filter: brightness(1.06); }
}
/* ⚠️ ПРИТИСКАННЯ — ЦЕ НЕ ТІЛЬКИ SCALE. Глибший стиск (.94 замість
   загальних .985) плюс bevel, що вивертається навиворіт
   (--btn-press замість --btn-bevel: верхній відблиск гасне, знизу
   з'являється тінь) — так, ніби скло справді продавлюється під
   пальцем. Швидший перехід НАЗАД у натиснутий стан (.05s) і
   повільніший назовні (успадкований .16s з .btn-gold) — палець
   повинен відчути натиск миттєво, а відпускання лишається м'яким. */
.btn-gold:active {
  transform: scale(.94);
  box-shadow: var(--btn-press);
  filter: brightness(.97);
  transition-duration: .05s;
}
.btn-wide { display: block; width: 100%; text-align: center; }

/* ---------- Запис ---------- */
.msg {
  position: relative; margin: 0 0 14px; padding: 16px; border: 0;
  border-radius: var(--r-m); background: var(--surface); box-shadow: var(--soft-shadow);
  font-size: 16px; line-height: 1.65; color: var(--fg-2);
}
.msg b { color: var(--gold); font-weight: 300; }
.msg-hint { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.alt-tel { font-size: 14.5px; color: var(--muted); margin: 16px 0 0; }
.alt-tel a { color: var(--gold); }

.form { margin-top: 34px; border-top: 1px solid var(--line); padding-top: 26px; }
.form-t { font-size: 15px; color: var(--muted); margin: 0 0 16px; }
.inp { display: block; margin-bottom: 14px; }
.inp span { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 6px; }
.inp input, .inp select {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  padding: 13px 14px; font-size: 16px; outline: none; border-radius: var(--r-s);
  transition: border-color .16s, box-shadow .16s;
}
.inp input:focus, .inp select:focus { border-color: var(--gold); }
.inp input.bad { border-color: #A6603C; }
.form-done { margin: 14px 0 0; padding: 14px; border: 1px solid var(--gold); color: var(--gold); font-size: 15px; }

/* ---------- М'який ритм ----------
   Контент лишається щільним, але тепер його збирає не суцільна рамка,
   а волосина, що розчиняється перед кутами. Так радіус читається формою,
   а не ще одним декоративним контуром. */
.airtouch,
.facts > li,
.svc > li,
.qa > li,
.tiles > li,
.gifts > li,
.works > li,
.numbers > li,
.salon-facts > li,
.guarantee,
.map,
.msg,
.proof,
.terms,
.switch {
  position: relative;
}

.airtouch::before,
.facts > li::before,
.svc > li::before,
.qa > li::before,
.tiles > li::before,
.gifts > li::before,
.works > li::before,
.numbers > li::before,
.salon-facts > li::before,
.guarantee::before,
.map::before,
.msg::before,
.proof::before,
.terms::before,
.switch::before {
  content: ''; position: absolute; inset: 0; z-index: 2;
  border-radius: inherit; pointer-events: none;
  background:
    linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent) top / 100% 1px no-repeat,
    linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent) bottom / 100% 1px no-repeat,
    linear-gradient(180deg, transparent, var(--line) 18%, var(--line) 82%, transparent) left / 1px 100% no-repeat,
    linear-gradient(180deg, transparent, var(--line) 18%, var(--line) 82%, transparent) right / 1px 100% no-repeat;
}

/* Пелюстки чергують нахил, тому серія карток більше не читається
   цегляною кладкою; різниця радіусів лишається в межах однієї шкали. */
.facts > li,
.svc > li,
.qa > li,
.gifts > li,
.works > li {
  border-radius: var(--r-l) var(--r-s) var(--r-l) var(--r-s);
  box-shadow: var(--soft-shadow);
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.facts > li:nth-child(even),
.svc > li:nth-child(even),
.qa > li:nth-child(even),
.gifts > li:nth-child(even),
.works > li:nth-child(even) {
  border-radius: var(--r-s) var(--r-l) var(--r-s) var(--r-l);
}

.proof,
.terms {
  border-radius: var(--r-m); padding: 14px 16px;
  background: var(--surface); box-shadow: var(--soft-shadow);
}

/* Рядок завершується світлом, а не різом від краю до краю. */
.prow::after,
.steps > li:not(:last-child)::after,
.guarantee li:not(:last-child)::after,
.works > li:not(:last-child)::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent);
  pointer-events: none;
}

input:not([type='checkbox']):not([type='radio']):not([type='range']),
textarea,
select { border-radius: var(--r-s); }

:where(a, button, input, textarea, select):focus-visible {
  /* Частина старих полів нижче має outline:none з більшою специфічністю;
     тут важливіше не дати фокусу зникнути, ніж змагатися каскадом. */
  outline: 2px solid var(--gold) !important; outline-offset: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .svc > li:hover,
  .works > li:hover { transform: translateY(-2px); }
  .btn:hover { transform: translateY(-1px); box-shadow: 0 10px 24px rgba(0,0,0,.24); }
}
.svc > li:focus-within,
.works > li:focus-within { box-shadow: var(--soft-shadow); }

/* ---------- Підвал ---------- */
.foot { padding: 30px var(--pad) 34px; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); }

/* ---------- Планка першого повідомлення ----------
   Прибита знизу з першої секунди. Висота фіксована завжди:
   якщо вона мінялась би від довжини тексту, сторінка стрибала б
   на кожен тап у прайсі. Суцільний колір, без backdrop-filter. */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  height: calc(var(--dock) + var(--safe));
  padding: 10px var(--pad) calc(10px + var(--safe));
  background: var(--surface); border-top: 1px solid var(--line);
  display: grid; grid-template-rows: auto 1fr; gap: 8px;
  transform: translate3d(0, 110%, 0);
  transition: transform .32s cubic-bezier(.22,.61,.36,1);
}
.dock.is-on { transform: none; }
.dock-msg {
  margin: 0; font-size: 13px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dock-msg b { color: var(--gold); font-weight: 300; }
/* ⚠️ ТОЙ САМИЙ СКЛЯНИЙ МЕТАЛ, ЩО Й .btn-gold, БО ЦЕ ТА САМА КНОПКА.
   Різні класи — бо різна розкладка (grid проти inline-block), не
   різний сенс: обидві «Записатися». Розійтись вигляду не можна. */
.dock-cta {
  display: grid; place-items: center; position: relative;
  background:
    radial-gradient(130% 220% at 18% -60%, var(--btn-hi), rgba(255,255,255,0) 48%),
    var(--metal);
  background-size: auto, 230% 100%;
  background-position: 0 0, 0% 0%;
  color: var(--on-gold);
  font-size: 15px; letter-spacing: .1em; text-transform: uppercase; font-weight: 400;
  box-shadow: var(--btn-bevel);
  transition: transform .09s, box-shadow .16s ease, filter .16s ease, background-position .5s cubic-bezier(.22,.61,.36,1);
}
@media (hover: hover) and (pointer: fine) {
  .dock-cta:hover { background-position: 0 0, 100% 0%; filter: brightness(1.06); }
}
.dock-cta:active {
  transform: scale(.96);
  box-shadow: var(--btn-press);
  filter: brightness(.97);
  transition-duration: .05s;
}

/* ---------- Поява відгуків і карток ---------- */
@media (prefers-reduced-motion: reduce) {
  .spine { transform: scaleY(1); transition: none; }
  .dock { transform: none; }
}

/* ============================================================
   Ширші екрани
   ============================================================ */
@media (min-width: 760px) {
  :root { --pad: 34px; }
  .qa { grid-template-columns: 1fr 1fr; }
  .gifts { grid-template-columns: repeat(3, 1fr); }
  .rail { grid-auto-columns: 300px; }
  .salon-facts { grid-template-columns: 1fr 1fr; }
  .where-grid { grid-template-columns: 1.1fr 1fr; align-items: start; }
  .tiles { grid-template-columns: repeat(4, 1fr); }
  .form { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
  .form-t, .form button, .form-done { grid-column: 1 / -1; }
}

@media (min-width: 1000px) {
  :root { --dock: 78px; }
  .sec { padding: 92px var(--pad); }
  /* auto-fit, а не жорсткі чотири колонки: на сторінках, де фактів
     три, четверта клітинка лишалась порожньою дірою в полотні. */
  .facts { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
  .hero { padding-top: 44px; }
  .dock {
    display: flex; align-items: center; gap: 22px;
    padding: 0 var(--pad); height: var(--dock);
  }
  .dock-msg { flex: 1; font-size: 15px; }
  .dock-cta { padding: 0 34px; height: 46px; }
}

/* ============================================================
   ВЕЛИКИЙ МОНІТОР — ЗАЙВА ШИРИНА ЙДЕ В КОЛОНКИ, А НЕ В РЯДОК

   ⚠️ ДО ЦЬОГО ПУБЛІЧНА СТОРІНКА ВЗАГАЛІ НЕ РЕАГУВАЛА НА ШИРИНУ
   ВИЩЕ 1000px. Останній публічний @media був саме на 1000; два
   вищих (1100 і 1500) — цілком кабінетні. Тому на 1920 сторінка
   стояла колонкою 1180px із 363px мертвого поля з кожного боку —
   38% екрана. Це не було рішенням, це була недописана частина.

   ⚠️⚠️ ШИРИНА ДАЄТЬСЯ КОЛОНКАМИ, А НЕ ДОВЖИНОЮ РЯДКА, і це не
   смак — це вже записаний прецедент цього ж файлу. Автор розв'язав
   рівно цю задачу для кабінету (@media 1100px нижче) і зафіксував
   замір: на 1600px колонка 900px лишала 701px порожніми, а лік
   був НЕ розтягнути поля, а додати другий стовпець і накрити
   введення на 640px. Тут те саме: рядок, довший за ~75 символів,
   читати незручно незалежно від монітора.

   ⚠️ ТОМУ ПЕРШИМ ДІЛОМ — СТЕЛІ ДЛЯ АБЗАЦІВ, ЯКИХ У НИХ НЕ БУЛО.
   `.lead` і `.sec-lead` мають власні ch-стелі й переживуть будь-яку
   ширину. А `.qa .a`, `.svc p`, `.steps .d` і `.guarantee li` не
   мають жодної: сьогодні їх тримає в межах читабельного САМ
   контейнер 1180px. Розширити його, не накривши їх, означало б
   відповідь у «Питаннях» на 130 символів у рядку.
   ============================================================ */
@media (min-width: 1440px) {
  :root { --max: 1460px; }

  /* Стеля рядка — 60ch, рівно як у `.prose` на підсторінках. Це вже
     домашній стандарт цього файлу для основного тексту (лід — 54ch,
     сек-лід — 52ch), і вигадувати тут своє число немає причин. */
  .qa .a, .svc p, .steps .d, .guarantee li { max-width: 60ch; }

  /* ⚠️ РЕЙКУ НАВМИСНО НЕ ЧІПАЄМО. Спокуса накрити її на 1180, щоб
     пігулки не розповзались, — це відкат двох рішень автора одразу:
     «рейка вирівнюється по контенту, інакше вона виглядає чужою»
     (@media 900px нижче) і «пункти розтягуються по колії, притиснуті
     ліворуч вони лишали половину колії порожньою». Вона їде за
     --max, як і задумано. */

  /* ⚠️ ФІКСОВАНІ СІТКИ СТАЮТЬ ГНУЧКИМИ — за зразком `.facts`, яка
     вже так зроблена на 1000px. Інакше три сертифікати по 480px
     кожен перетворюються на те саме «занадто порожньо», через яке
     й написаний закон №3. */
  .tiles { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
  .gifts { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

/* ============================================================
   БАГАТОСТОРІНКОВІСТЬ

   Каркас однаковий скрізь, тому й стилі його — в одному місці.
   Рейка замість бургера: головна біда салонного сайту в тому, що
   людина не знає, ЩО тут є, а бургер ховає саме це рівно тоді,
   коли вона щойно прийшла.
   ============================================================ */
.top { border-bottom: 1px solid var(--line); }
/* ⚠️ РЯДОК ШАПКИ БУВ НИЖЧИЙ ЗА ВЛАСНИЙ ВМІСТ. `height: 46px` при
   каліграфічному знаку заввишки 48px (32px × 1.5) давав коробку з
   top: −1, тобто знак починався ВИЩЕ за верхній край вікна, і
   розчерки «V» та «F» упирались у нього. На головній це ховала смуга
   «Чернетка», яка зсуває шапку вниз, — тому дефект був видимий
   тільки на одинадцяти підсторінках.
   Фікс не в тому, щоб зменшити знак: `min-height` + вертикальні поля
   дають рядку рости під вміст, а 46px лишаються підлогою для
   сторінок, де знак колись стане меншим. */
.top-in {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 46px; padding: 7px var(--pad);
}
.top-master {
  display: block; padding: 0 var(--pad) 9px;
  font-size: 12.5px; color: var(--muted); letter-spacing: .04em;
}
@media (hover: hover) and (pointer: fine) {
  .top-master:hover { color: var(--gold); }
}

/* ---------- Рейка розділів: скляна колія ----------
   Було: шість прямокутників у 1px обводці, притиснуті до лівого краю
   на будь-якій ширині. На телефоні це читалось як смужка вкладок, на
   десктопі — як мобільна смужка, забута на широкому екрані: контент
   починався на 164px, а рейка на 18px.

   Стало: одна КОЛІЯ зі скла, всередині якої їздять пігулки. Активна
   не обведена, а ПІДНЯТА — світло по верхній кромці й тінь під нею.
   Це і є весь прийом: обраний пункт лежить ближче до глядача.

   ⚠️ ЗОЛОТО ЛИШАЄТЬСЯ ТЕКСТОМ. Спокуса залити активну пігулку
   металом велика, але внизу екрана вже стоїть суцільно золота планка
   запису: два золоті прямокутники в одному кадрі порушують закон №2
   і здешевлюють обидва. Тому активність показує СКЛО, а золото —
   тільки літери. */
.rail-nav {
  display: flex; gap: 6px; overflow-x: auto;
  margin: 0 var(--pad) 12px; padding: 6px;
  border-radius: 24px;
  scrollbar-width: none; overscroll-behavior-x: contain;
  background: var(--rail-bg);
  border: 1px solid var(--rail-line);
  box-shadow: var(--rail-shadow);
}
.rail-nav::-webkit-scrollbar { display: none; }

.pill {
  flex: none; padding: 9px 17px; font-size: 14px; white-space: nowrap;
  border: 0; border-radius: 18px; color: var(--muted);
  transition: color .18s ease, background-color .18s ease, box-shadow .18s ease, transform .09s ease;
  /* ⚠️ ТА САМА ПАСТКА, ЩО Й У `.btn`: НА <button> ЦЕЙ КЛАС ВИХОДИВ
     БІЛИМ. На сайті рейка зроблена посиланнями, тому браузерне тло
     кнопки не проступало; у кабінеті вкладки — справжні кнопки, і
     всі неактивні пігулки світилися білими плямами на чорному.
     Заливку далі ставлять .pill:hover і .pill.is-on — обидва
     специфічніші, тож виграють. */
  background: none;
}
@media (hover: hover) and (pointer: fine) {
  .pill:hover { color: var(--fg); background: var(--rail-hover); }
}
/* ⚠️ ДОСІ НЕ БУЛО ЖОДНОГО ВІДГУКУ НА ТАП. `.btn` натискається від
   самого початку (`.btn:active`), а рейка — ні: тап по пігулці
   вигладав так само, ніби вона не відреагувала взагалі, і людина
   тицяла вдруге. */
.pill:active { transform: scale(.94); }
.pill.is-on {
  color: var(--gold);
  background: var(--rail-on);
  box-shadow: var(--rail-on-shadow);
}

/* ⚠️ НА ДЕСКТОПІ РЕЙКА ВИРІВНЮЄТЬСЯ ПО КОНТЕНТУ. Без max-width вона
   лишалась мобільною смужкою на 18px від краю, поки весь текст
   починався на 164px — саме через це вона й виглядала чужою. */
@media (min-width: 900px) {
  .rail-nav {
    max-width: var(--max); margin-inline: auto; margin-bottom: 16px;
    gap: 8px; padding: 7px; border-radius: 28px;
    /* ⚠ Пункти РОЗТЯГУЮТЬСЯ по колії. Притиснуті ліворуч, вони
       лишали половину колії порожньою, і скло читалось як зайва
       підкладка, а не як доріжка, по якій вони їздять. */
    justify-content: space-between;
  }
  .pill { padding: 12px 24px; font-size: 15px; border-radius: 22px; }
}

/* ---------- Заголовок підсторінки ---------- */
.page-head { padding: 30px var(--pad) 6px; max-width: var(--max); margin: 0 auto; }
.h1-page { font-size: clamp(34px, 9vw, 74px); margin-bottom: 16px; }
.prose { color: var(--fg-2); margin: 0 0 14px; max-width: 60ch; }
.sec-cta { text-align: center; }
.sec-cta .sec-lead { margin-left: auto; margin-right: auto; }
.sec-cta .msg { text-align: left; }
.sec-cta .sec-head::after { left: 50%; transform: translateX(-50%); }

.more {
  display: inline-block; margin-top: 20px; font-size: 15px;
  color: var(--gold); border-bottom: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
}

/* ---------- Стіна колег ----------
   Вмикається сама, коли в people.js з'явиться другий запис. */
.wall li { padding: 18px 0; border-bottom: 1px solid var(--line); }
.wall-name { display: block; font-size: clamp(28px, 7vw, 46px); font-weight: 200; line-height: 1.05; }
.wall-meta { display: block; font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-top: 5px; }
.wall-word { font-size: 16px; color: var(--fg-2); margin: 8px 0 0; max-width: 46ch; }

.gift-fits { display: block; font-size: 12.5px; color: var(--muted); margin-top: 8px; line-height: 1.4; }

/* ---------- Футер-карта ----------
   Повна карта сайту на кожній сторінці: страховка для того,
   хто прийшов з пошуку одразу на /brovy/ і не знає, що тут ще є. */
.foot { padding: 44px var(--pad) calc(30px + var(--safe)); }
.foot-map { display: grid; gap: 26px; max-width: var(--max); margin: 0 auto 34px; }
.fcol-t { font-size: 11px; letter-spacing: .28em; text-transform: uppercase; color: var(--muted); margin: 0 0 12px; }
.fcol a { display: block; font-size: 15px; color: var(--fg-2); padding: 5px 0; }
@media (hover: hover) and (pointer: fine) {
  .fcol a:hover { color: var(--gold); }
}
.foot-end { max-width: var(--max); margin: 0 auto; border-top: 1px solid var(--line); padding-top: 22px; }
.foot-mark {
  font-family: var(--font-script);
  font-size: 44px; font-weight: 400; line-height: 1.45; margin: 0 0 6px;
}
.foot-mark i { font-style: normal; color: var(--gold); margin-left: .18em; }
.foot-line { font-size: 13px; color: var(--muted); margin: 0 0 4px; }
.foot-line a { color: var(--fg-2); }

/* ---------- Журнал ----------
   Абсолютних дат немає жодної: два місяці тиші читаються як
   «Раніше», а «Раніше» — нормальна назва для архіву. */
.jgroup { padding: 0 var(--pad) 34px; max-width: var(--max); margin: 0 auto; }
.jgroup-t { font-size: 11px; letter-spacing: .28em; text-transform: uppercase; color: var(--muted); margin: 26px 0 14px; font-weight: 400; }
.jlist li { display: grid; grid-template-columns: 1fr auto; gap: 4px 14px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.jkind {
  grid-column: 1 / -1; font-size: 10.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--gold);
}
.jtext { margin: 0; font-size: 16px; }
.jmeta { font-size: 13px; color: var(--muted); white-space: nowrap; align-self: center; font-variant-numeric: tabular-nums; }
.jitem-window .jkind { color: var(--ok); }

/* ---------- Кабінет ---------- */
/* ⚠️ КОЛОНКА КАБІНЕТУ ШИРША ЗА ЧИТАЛЬНУ. 640px — правильна міра
   для тексту, але не для таблиці з трьох цін у рядок: на ноутбуці
   поля стискались до 130px, а рейка з шести вкладок обрізалась.
   Читальні тексти всередині тримає окремий max-width на .kb-note. */
#kab { max-width: 640px; margin: 0 auto; padding: 30px var(--pad) 60px; }
@media (min-width: 860px) { #kab { max-width: 900px; } }
.kab-login { max-width: 380px; }
.kab-err { color: var(--warn); font-size: 14px; min-height: 20px; }
.kab-kinds { display: flex; flex-wrap: wrap; gap: 8px; margin: 22px 0 10px; }
.kab-hint { font-size: 13.5px; color: var(--muted); margin: 0 0 20px; }
.kab-h2 { margin-top: 46px; font-size: 26px; }
.kab-list li { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.kab-del { background: none; border: 0; color: var(--muted); font-size: 13px; text-decoration: underline; align-self: center; }
@media (hover: hover) and (pointer: fine) {
  .kab-del:hover { color: var(--warn); }
}
.kab-done { border: 1px solid var(--gold); color: var(--gold); padding: 12px 14px; font-size: 15px; margin: 14px 0 0; }
.inp textarea {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  padding: 13px 14px; font-size: 16px; outline: none; border-radius: var(--r-s);
  resize: vertical; line-height: 1.6;
}
.inp textarea:focus { border-color: var(--gold); }

@media (min-width: 760px) {
  .foot-map { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================================
   БІЖУЧІ РЯДКИ

   ⚠ Біжить ЗМІСТ, а не вільні слоти. Рядок «сьогодні вільно
   14:30» — це публічна заява «у мене порожньо»; тут біжать
   відтінки, послуги й адреса, тобто те, що правда завжди.

   Швидкість задає marquee.js у пікселях на секунду, а не в
   секундах: інакше довший рядок їде швидше за коротший і дві
   стрічки на одній сторінці рухаються врозбій.
   ============================================================ */
/* Спільна зупинка для всього, що крутиться вічно. Клас, а не
   інлайн-стиль: зупиняти часто треба псевдоелемент. */
.off-screen .mq-track { animation-play-state: paused; }

/* display:block обов'язковий: дві з трьох стрічок — це <a>, а
   інлайновий елемент згортає висоту в рядок тексту. Колір країв
   їде змінною, бо стрічки стоять на різних тлах. */
.mq { display: block; overflow: hidden; position: relative; --fade: var(--surface); }
.mq-track {
  display: flex; width: max-content;
  animation-timing-function: linear; animation-iteration-count: infinite;
}
.mq-half { display: flex; align-items: center; flex: none; }
@keyframes mq-left  { from { transform: translate3d(0,0,0); }    to { transform: translate3d(-50%,0,0); } }
@keyframes mq-right { from { transform: translate3d(-50%,0,0); } to { transform: translate3d(0,0,0); } }

/* Тонка стрічка: той самий кегль і трекінг, що в .kicker —
   нового типографічного рівня на сторінці не з'являється. */
.mq-i {
  display: inline-flex; align-items: center; gap: 9px; white-space: nowrap;
  font-size: 11px; letter-spacing: .3em; text-transform: uppercase; color: var(--muted);
}
.mq-s { color: var(--gold); opacity: .55; padding: 0 15px; font-size: 10px; }
.mq-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }

/* Стрічка під шапкою: два шви в 1px, як усе полотно. */
.mq-top { border-bottom: 1px solid var(--line); padding: 9px 0; background: var(--surface); }

/* Краї розчиняються, інакше текст «врізається» в межу екрана
   і читається як обрізаний, а не як рухомий. */
.mq::before, .mq::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 46px; z-index: 2; pointer-events: none;
}
.mq::before { left: 0;  background: linear-gradient(90deg, var(--fade), transparent); }
.mq::after  { right: 0; background: linear-gradient(270deg, var(--fade), transparent); }

/* Велика смуга: єдине місце, де кегль виходить за три константи,
   і тому вона на сторінці одна. */
.mq-big { padding: 26px 0; }
.mq-big .mq-i {
  font-size: clamp(34px, 10vw, 78px); font-weight: 200; line-height: 1;
  letter-spacing: -.015em; color: var(--fg); text-transform: uppercase; gap: 0;
}
/* ⚠ РОЗМІР ТУТ НЕ МОЖЕ БУТИ В em.
   Роздільник — СУСІД слова, а не його нащадок, тому em рахується
   від 16.5px тіла, а не від 78px рядка: замість орнаменту виходив
   восьмипіксельний пилок, який читався як сміття на екрані.
   Вирівнювання — по центру смуги, а не по базовій лінії. */
.mq-big .mq-s {
  font-size: clamp(15px, 4.4vw, 34px); padding: 0 .3em; letter-spacing: 0; opacity: 1;
  display: inline-flex; align-items: center; align-self: center; line-height: 1;
}

/* Смуга-заклик перед записом: метал дозволений саме тут, бо
   це «кінець» у сенсі бюджету золота — головна дія сторінки. */
.mq-cta { border-block: 1px solid var(--line); background: var(--surface); }
/* Шов стоїть просто на полотні сторінки, без своєї поверхні:
   він РОЗДІЛЯЄ секції, а не є ще однією секцією. */
.mq-seam { --fade: var(--bg); border-block: 1px solid var(--line); }
.mq-seam .mq-i { color: var(--fg-2); }
.mq-seam .mq-s { color: var(--gold); opacity: .7; }
/* ⚠ Метал по тексту тут НЕ працює: розтяжка рахується від межі
   свого ж слова, а слово ширше за екран — видно випадковий
   шматок, і напис читається як обрізаний, а не як дорогий.
   Тому слово суцільним кольором, а золото — на зірочці. */
.mq-cta .mq-i { color: var(--fg); }
.mq-cta .mq-s { color: var(--gold); opacity: 1; }

/* ============================================================
   АКТУАЛЬНЕ — кружечки і повноекранний перегляд

   Усередині кружечка немає ні фотографії, ні літери-монограми:
   там розтяжка від темного кореня до світлого кінця. Тобто
   буквально те, що вона робить руками, і та сама мова, що в
   блоці «Відтінки». Порожня сіра пляма читалась би як «фото
   не завантажилось» — а це найшвидший спосіб закрити вкладку.
   ============================================================ */
.st-band { border-bottom: 1px solid var(--line); }
/* Рейка одразу продовжується полотном фактів. Інакше між ними
   лишається 40px порожнечі — рівно те, на що клієнтка скаржилась
   словами «занадто порожньо». */
.st-band + .facts { margin-top: 0; }
.st-band .kicker { margin: 0; padding: 20px var(--pad) 0; max-width: var(--max); margin-inline: auto; }
.st-rail {
  display: flex; gap: 15px; overflow-x: auto; padding: 14px var(--pad) 18px;
  scrollbar-width: none; overscroll-behavior-x: contain;
  max-width: var(--max); margin-inline: auto;
}
.st-rail::-webkit-scrollbar { display: none; }
.st-cell { flex: none; }
.st-btn {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: 76px; background: none; border: 0; padding: 0;
}
.st-ring {
  width: 68px; height: 68px; border-radius: 50%; padding: 3px;
  background: var(--metal); transition: .2s;
}
/* ⚠ КІЛЬЦЕ ЯК ПРИЛАД: стільки дуг, скільки карток усередині.
   Маска тут НЕ потрібна — .st-ring уже круглий, а середину
   закриває непрозорий обідок .st-disc. Це знімає єдиний
   серйозний ризик прийому (mask на старому Android WebView). */
.st-ring.is-seg {
  background: repeating-conic-gradient(from -90deg,
    var(--gold-hi) 0 calc(var(--arc) - 8deg), transparent calc(var(--arc) - 8deg) var(--arc));
}
.st-cell.is-seen .st-ring.is-seg {
  background: repeating-conic-gradient(from -90deg,
    color-mix(in srgb, var(--muted) 42%, transparent) 0 calc(var(--arc) - 8deg),
    transparent calc(var(--arc) - 8deg) var(--arc));
}
.st-disc {
  display: block; width: 100%; height: 100%; border-radius: 50%;
  border: 2px solid var(--bg); box-shadow: inset 0 0 0 1px rgba(255,255,255,.07);
}
.st-lab {
  font-size: 11.5px; color: var(--fg-2); line-height: 1.25; text-align: center;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
/* Переглянуте гасне — рівно як в Instagram. Без цього рейка
   виглядає однаково завжди, і повертатись у неї нема сенсу. */
/* Переглянуте кільце мусить лишатись ВИДИМИМ кільцем: на
   --line воно зливається з тлом, і кружечок читається як
   такий, що втратив рамку, а не як уже переглянутий. */
.st-cell.is-seen .st-ring { background: color-mix(in srgb, var(--muted) 42%, transparent); }
.st-cell.is-seen .st-lab { color: var(--muted); }
.st-btn:active .st-ring { transform: scale(.94); }

/* Свіжий запис із журналу дихає. Один елемент на сторінці, і
   тільки поки він справді новий: два тижні, далі кружечок
   зникає з рейки взагалі. */
.st-cell.is-new .st-ring { animation: st-pulse 2.6s ease-in-out infinite; }
@keyframes st-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(201,162,74,.34); }
  50%      { box-shadow: 0 0 0 7px rgba(201,162,74,0); }
}

.st-lock, .st-lock body { overflow: hidden; }

.st-view { position: fixed; inset: 0; z-index: 90; display: none; background: #0A0A0A; }
.st-view.is-on { display: block; }
.st-stage {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  overflow: hidden; touch-action: pan-y;
}
/* ⚠ ЦЕ НЕ ПІДСВІТКА, А ЄДИНИЙ ЗМІСТ ВЕРХНЬОЇ ПОЛОВИНИ ЕКРАНА.
   Фотографій немає, і без цього дві третини історії — рівна
   чорна пляма, тобто рівно те «занадто порожньо», на яке вона
   скаржилась. Тому весь верх — сама розтяжка цієї історії, яка
   гасне якраз там, де починається текст. Одна фізична ідея
   сайту працює і тут: розтяжка — це продукт, а не оздоба. */
.st-stage::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(78% 42% at 50% 6%, var(--b), transparent 72%),
    linear-gradient(180deg, var(--a) 0%, transparent 58%);
  opacity: .5;
}
/* Тонка золота дуга — межа світла. Те саме, що межа кореня
   й довжини, тільки в масштабі екрана. */
.st-stage::after {
  content: ''; position: absolute; left: 50%; top: 46%; width: 132vw; height: 132vw;
  margin-left: -66vw; border-radius: 50%; pointer-events: none;
  border-top: 1px solid color-mix(in srgb, var(--b) 40%, transparent);
}
.st-stage > * { position: relative; z-index: 1; }

.st-bars { display: flex; gap: 4px; padding: calc(12px + env(safe-area-inset-top, 0px)) 12px 0; }
.st-bar { flex: 1; height: 2px; background: rgba(242,239,233,.2); overflow: hidden; }
.st-bar b { display: block; height: 100%; background: var(--gold-hi); transform: scaleX(0); transform-origin: left; }
.st-bar.is-done b { transform: scaleX(1); }
.st-bar.is-live b { animation-name: st-fill; animation-timing-function: linear; animation-fill-mode: forwards; }
@keyframes st-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.st-head { display: flex; align-items: center; gap: 11px; padding: 13px 14px 0; }
.st-hdisc { width: 26px; height: 26px; border-radius: 50%; flex: none; box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); }
.st-hlab { flex: 1; font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--fg-2); }
.st-x { background: none; border: 0; color: var(--fg-2); font-size: 30px; line-height: 1; padding: 0 6px; }

.st-body { flex: 1; display: flex; align-items: flex-end; padding: 0 26px 6vh; }
.st-card { max-width: 30ch; animation: st-in .42s cubic-bezier(.2,.7,.3,1) both; }
@keyframes st-in { from { opacity: 0; transform: translate3d(0,14px,0); } to { opacity: 1; transform: none; } }
.st-big {
  margin: 0 0 10px; font-size: clamp(44px, 15vw, 84px); font-weight: 200; line-height: 1;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.st-t { margin: 0 0 12px; font-size: clamp(26px, 8vw, 40px); font-weight: 200; line-height: 1.08; }
.st-d { margin: 0; font-size: 17px; line-height: 1.5; color: var(--fg-2); }
/* Запис журналу заголовка не має — він дублював би назву типу
   в шапці. Замість цього сам текст іде більшим кеглем. */
.st-d-lead { font-size: clamp(21px, 6vw, 27px); line-height: 1.28; color: var(--fg); font-weight: 200; }
.st-note { margin: 12px 0 0; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

.st-foot {
  display: flex; gap: 10px; padding: 0 16px calc(18px + var(--safe));
}
.st-go, .st-dm {
  flex: 1; display: grid; place-items: center; height: 48px; font-size: 15px; text-align: center;
}
.st-go { border: 1px solid var(--line); color: var(--fg-2); }
.st-dm { flex: 0 0 40%; background: var(--metal); color: var(--on-gold); font-weight: 400; }

@media (prefers-reduced-motion: reduce) {
  .st-card { animation: none; }
  .st-cell.is-new .st-ring { animation: none; }
}

@media (min-width: 760px) {
  .st-ring { width: 76px; height: 76px; }
  .st-btn { width: 86px; }
  .st-stage { max-width: 460px; margin: 0 auto; border-inline: 1px solid var(--line); }
  .st-view { background: #060606; }
}


/* ============================================================
   ПОЯВА ПРИ ПРОКРУТЦІ

   Один прийом на весь сайт: блок з'являється, коли до нього
   доїхали. Анімуються ТІЛЬКИ opacity і transform, тобто робота
   композитора, а не перерахунок розкладки.

   ⚠ Клас .rv вішає JavaScript, а не розмітка. Якби він стояв
   у HTML, будь-яка помилка в скрипті лишила б сторінку
   порожньою назавжди — це найдорожча можлива ціна за анімацію.
   ============================================================ */
.rv { opacity: 0; transform: translate3d(0, 18px, 0); }
.rv-go {
  transition: opacity .62s ease, transform .62s cubic-bezier(.2,.7,.3,1);
  transition-delay: var(--d, 0ms);
}
.rv-on { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; }
  .rv-go { transition: none; }
}

/* ============================================================
   ЗЕРНО, ВІДБЛИСК І ЖИВИЙ СТАН

   Три дрібниці, яких не помічають окремо, але без яких чорне
   читається як заливка PDF, а не як знята плівка.
   ============================================================ */

/* ---------- Зерно ----------
   Не «ефект»: воно ховає бандинг на великих розтяжках (а вся
   ця сторінка з них і складається — герой, хребет, історії,
   плитки відтінків). На дешевій матриці рівна розтяжка йде
   смугами, і зерно — найдешевший спосіб цього позбутись.
   Шар не ловить дотики і не перемальовується при прокрутці:
   fixed без змін — це один композиторський шар. */
/* ============================================================
   АВРОРА — глибина під склом

   ⚠ Це НЕ оздоба, а те, без чого скло не має сенсу.
   Скло заломлює те, що позаду нього; позаду рівної
   заливки — та сама рівна заливка. Чотири мʼякі радіальні
   плями дають сторінці колір і глибину без жодної фотографії.
   Дрейф тільки transform (композитор), кольори — через токени,
   альфа тримається низькою, щоб текст не провалювався.
   ============================================================ */
/* ⚠️ ШОВК ЗАПЕЧЕНИЙ, А НЕ ПРИГЛУШЕНИЙ ПРОЗОРІСТЮ.
   Потрібна була тканина під усім — щоб чорне перестало бути
   заливкою. Шар із opacity тут не підходить: це ще один
   композитний шар на весь екран, а їх тут уже два (аврора й
   зерно). Тому 13 % шовку вже змішані з #121212 всередині
   самого файла: картинка важить 4 КБ і малюється один раз.
   Удень шовку немає взагалі: він запечений під темне тло
   й на світлому був би брудною плямою. */
:root { --silk: url("/vendor/foto/bg-silk.webp"); }
/* ⚠️⚠️ АТМОСФЕРА ЗГЕНЕРОВАНА, А НЕ ЗНЯТА, І ЦЕ НАВМИСНО.
   Просилось «запхати відео в розмитий фон». Саме відео туди не йде:
   (1) третій повноекранний шар прямо заборонений коментарем нижче,
   (2) відео перемальовується щокадру, а весь результат «14 000 px
   під 4× тротлом без жодного кадру довшого за 32 мс» тримається на
   тому, що фон НЕ перемальовується взагалі, (3) у ролику центрована
   людина у світлій блузі — під будь-яким розмиттям вона лишається
   блідою фігурою посеред екрана й перетягує погляд із тексту.
   Заміряно: усереднення 120 кадрів фігуру не прибирає, а на 16px
   вона все одно читається.

   ⚠️ ЧОМУ НЕ ЗНІМОК САЛОНУ. Правило сайту — «чужих робіт тут не
   буває», і воно ширше за фото робіт: вигаданий «інтер'єр салону»
   був би такою самою неправдою. Тому тут АБСТРАКЦІЯ — світло і
   складки тканини, які нічого не обіцяють і нічим не прикидаються.

   Зроблено як шовк у цьому ж файлі: не новий шар, а ще один
   запечений фон у вже наявному стеку. 100 байтів.

   ⚠️⚠️ ІМ'Я З ХЕШЕМ ВМІСТУ, І ЦЕ НЕ ПРИКРАСА. Тека /vendor/foto/
   віддається з `max-age=31536000, immutable` — РІК. Перезаписати той
   самий файл новим вмістом означає, що всі, хто його вже бачив, не
   отримають нову версію ніколи: браузер навіть не спитає сервер.
   Саме на це я й наступив — тричі переписав `vika-wash.webp`, і
   людина бачила першу з трьох. Правило записане в самому server.js
   біля заголовків кешу: «нове фото — новий файл, а не те саме ім'я
   з іншим вмістом». Тепер ім'я = вміст, і помилка неможлива.

   ⚠️⚠️ АЛЬФА 7%, І ЦЕ РАХОВАНЕ ЧИСЛО. Найгірший випадок — найяскравіший
   піксель відбитка ПЛЮС найгустіша пляма аврори в тій самій точці.
   На 12% тло підіймалось до rgb(55,50,41), і --muted давав 4.11 —
   НИЖЧЕ AA 4.5. Це рівно той баг, який у цьому файлі вже ловили на
   живому проді (див. розрахунок дня біля --au-*). На 7% найгірший
   випадок 4.68, на чистому тлі muted тримає 6.05.
   Скрипт розрахунку — scratchpad/contrast.js. */
:root { --wash: url("/vendor/foto/bg-wash-ae2f0310.webp"); }
body::before {
  content: ''; position: fixed; inset: -22vmax; z-index: -1; pointer-events: none;
  background:
    radial-gradient(38vmax 34vmax at 12% 8%,  var(--au-1), transparent 66%),
    radial-gradient(42vmax 40vmax at 92% 20%, var(--au-2), transparent 68%),
    radial-gradient(52vmax 46vmax at 80% 90%, var(--au-3), transparent 66%),
    radial-gradient(46vmax 42vmax at 6% 84%,  var(--au-4), transparent 70%),
    var(--silk),
    var(--wash);
  /* ⚠️ ВІДБИТКУ — 100% 100%, А НЕ cover, І ЦЕ НЕ ДРІБНИЦЯ. Він
     вузький і високий (64×401), а шар — широкий: `cover` масштабує
     його у 43 рази, робить 17 000 px заввишки й показує тонкий
     зріз ІЗ СЕРЕДИНИ, де саме темно. Тепле горішнє поле, заради
     якого все й робилось, обрізалось повністю — заміряно, ефект
     був майже нульовий. Розтяг без збереження пропорцій тут
     доречний: це абстрактне поле, спотворювати в ньому нічого. */
  background-size: auto, auto, auto, auto, cover, 100% 100%;
  background-position: 0 0, 0 0, 0 0, 0 0, center, center;
  background-repeat: no-repeat;
  animation: vf-aurora 66s ease-in-out infinite;
  will-change: transform;
}
[data-theme="day"] { --silk: none; --wash: none; }
/* ============================================================
   ⚠️⚠️ ЖИТТЯ ДОДАЄТЬСЯ РУХОМ, А НЕ АЛЬФОЮ.

   Було: `to { translate3d(0,-2.5%,0) scale(1.05) }` за 40 с. Це
   технічно рух, але 2,5% за сорок секунд — приблизно один піксель
   на секунду; око такого не ловить, і фон читався мертвим. Саме
   звідси й бралось відчуття «порожньо».

   ⚠️ АЛЬФИ НЕ ЧІПАЮТЬСЯ ЖОДНОЇ. Числа в 24 блоках
   `body[data-page=…]` — це РОЗВ'ЯЗОК задачі на контраст (є навіть
   скрипт, яким його рахували): максимум тону, за якого --muted,
   --gold і --fg-2 тримають 4.5:1 під усіма чотирма плямами разом.
   Підняти їх «щоб було помітніше» = повернути баг, який уже ловили
   на живому проді. Тому рухаємо ті самі плями, а не робимо їх
   густішими: помітність дає ЗМІНА, а не рівень.

   ⚠️ ОБЕРТАННЯ — КЛЮЧОВЕ. Один лише зсув тягне всі чотири плями в
   один бік, і картина лишається тією самою. Поворот на 2° водить
   їх по РІЗНИХ траєкторіях (кожна пляма далеко від центру, тому
   дуга в неї своя) — за ту саму ціну, бо transform композиторський.

   ⚠️ ЗВІДСИ Ж inset: -22vmax замість -15vmax. Повернутий прямокутник
   заводить кути всередину екрана; старого запасу бракувало, і на
   краях проступала б гола заливка. Перевірено рахунком: діагональ
   при 2° дає ~1.7% зсуву кута, 22vmax покриває з запасом.
   ============================================================ */
@keyframes vf-aurora {
  0%   { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); }
  50%  { transform: translate3d(-2.2%, -3.4%, 0) scale(1.07) rotate(2deg); }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) { body::before { animation: none; } }

body::after {
  content: ''; position: fixed; inset: -50%; z-index: 1; pointer-events: none;
  opacity: .05;
  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='.86' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Історія — окремий шар над зерном, тому зерно там своє. */
.st-view::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  opacity: .06;
  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='.86' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Відблиск по лінії планки ----------
   ⚠ Спершу це малювалось на хребті прайсу — і не спрацювало:
   хребет має близько 5800px висоти, на екрані видно менше ніж
   шосту його частину, і будь-яка пляма, що по ньому їде, читається
   не як рух, а як «лінія чомусь потемніла». Відблиск має сенс
   тільки на КОРОТКОМУ відрізку, який видно цілком.

   Тому він переїхав на верхню лінію липкої планки: вона завжди
   на екрані, вона рівно завширшки з телефон, і вона позначає
   головну дію. Раз на дев'ять секунд по ній проходить світло —
   рівно стільки, щоб око зачепилось, і замало, щоб набриднути. */
.dock::before {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-hi), transparent);
  background-size: 38% 100%; background-repeat: no-repeat;
  animation: dock-sheen 9s cubic-bezier(.5,0,.5,1) 2s infinite;
}
@keyframes dock-sheen {
  0%       { background-position: -45% 0; }
  55%,100% { background-position: 145% 0; }
}

/* ---------- Живий стан у шапці ----------
   Єдиний напис на сайті, який змінюється сам. Пульсує тільки
   в робочі години — решту часу це просто крапка. */
.top-master { display: flex; align-items: center; gap: 8px; }
.live-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--line); position: relative;
}
.top-master.is-live .live-dot { background: var(--gold); }
.top-master.is-live .live-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--gold); animation: live-ring 2.8s ease-out infinite;
}
@keyframes live-ring {
  0%   { transform: scale(1);   opacity: .8; }
  70%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}

/* Зміна рядка в планці: рухається ПІДПИС, кнопка стоїть. */
.dock-msg { transition: opacity .22s ease, transform .22s ease; }
.dock-msg.is-turn { opacity: 0; transform: translate3d(0, -5px, 0); }

@media (prefers-reduced-motion: reduce) {
  .dock::before,
  .top-master.is-live .live-dot::after { animation: none; }
  .dock-msg { transition: none; }
}

/* ============================================================
   СКРОЛ ЯК ДОРОГА

   Кістяк — зі сторінки «Розташування» ЖК Emirates. Людина обирає
   ДВІ речі: звідки (трамвай / метро / автобус / своя точка /
   адреса) і як (пішки або машиною). Без вибору способу будь-яка
   одна цифра бреше половині: пішки від метро сюди 50 хвилин,
   машиною — 8.

   ⚠️ Тайли зовнішні й від народження сірувато-сині. Фільтр
   переводить їх у теплий графіт, інакше карта поруч із золотом
   читається як чужий сайт, вставлений у цей.

   ⚠️ backdrop-filter НЕ використовується (закон №4): панелі —
   суцільний колір із рамкою.
   ============================================================ */
/* Висоту ставить JS із ваг сцен: 231 м від автобуса й
   5,1 км від метро не можуть гортатись однаково. */
.rt-track { position: relative; height: 460vh; background: var(--map-bg); }
.rt-stage {
  position: sticky; top: 0; overflow: hidden;
  height: calc(100vh - var(--dock) - var(--safe));
  height: calc(100svh - var(--dock) - var(--safe));
  background: var(--map-bg); border-block: 1px solid var(--line);
}
/* Контейнер масштабується CSS-ом на підльоті — звідси
   transform-origin і підказки композитору. */
.rt-map {
  position: absolute; inset: 0;
  transform-origin: 50% 50%; will-change: transform; backface-visibility: hidden;
}
.rt-map .leaflet-container { background: var(--map-bg); font-family: inherit; }
/* ⚠ Фільтр ТІЛЬКИ на базовий шар. Коли він висів на спільному
   .leaflet-tile-pane, разом із дорогами перефарбовувались і назви
   вулиць — читати їх ставало важко. Тепер підписи йдуть окремим
   шаром і лишаються такими, якими їх намалював CARTO. */
.rt-map .leaflet-pane[class*="vfBase"],
.rt-map .leaflet-vfBase-pane {
  filter: var(--tile-filter);
}
/* ⚠ НЕ opacity. Другий шар тайлів заведено саме заради
   читності назв — гасити їх прозорістю було б самозапереченням.
   До того ж opacity<1 на pane створює власний композитний
   шар, який перезмішується на кожен доданий тайл. */
.rt-map .leaflet-vfLbl-pane { filter: brightness(.82) saturate(.6); }
/* Підпис джерела — СУСІД карти, а не її вміст: контейнер
   масштабується на підльоті, і рідний контрол Leaflet
   виїжджав за сцену й зрізався. Це ще й умова CARTO/OSM. */
.rt-credit {
  position: absolute; left: 0; right: 0; bottom: 152px; z-index: 670;
  margin: 0; padding: 1px 6px; text-align: right; pointer-events: none;
  color: var(--muted); font-size: 9.5px;
}

/* Верх і низ кадру гасять карту, щоб текст лежав на темному
   незалежно від того, який шматок міста зараз під ним. */
.rt-stage::after {
  /* ⚠ z-index 660, а не 400: у Leaflet маркери лежать на 600,
     а підказки на 650. На 400 затемнення йшло ПІД ними, і підпис
     стартової точки друкувався просто по великій цифрі HUD. */
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 660;
  background:
    linear-gradient(180deg, rgba(var(--map-rgb), .92), transparent 22%),
    linear-gradient(0deg, var(--map-bg), rgba(var(--map-rgb), .86) 12%, transparent 34%);
}

/* ---------- позначки ---------- */
/* --mk — зворотний CSS-масштаб карти: позначка лишається того
   самого розміру на екрані, хоч би як близько під'їхала камера. */
.rt-mk { width: 100%; height: 100%; border-radius: 50%; transform: scale(var(--mk, 1)); }
.rt-mk-a { border: 2px solid var(--fg-2); background: var(--ink); }
.rt-mk-b { border: 2px solid var(--ink); background: var(--gold); position: relative; }
.rt-mk-b i {
  position: absolute; inset: -8px; border-radius: 50%;
  border: 1px solid var(--gold); opacity: .5;
  animation: rt-halo 2.8s ease-out infinite;
}
@keyframes rt-halo {
  0%   { transform: scale(.6); opacity: .6; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}
.rt-dot {
  width: 100%; height: 100%; border-radius: 50%;
  background: var(--muted); border: 1px solid var(--ink);
  transform: scale(var(--mk, 1));
}

/* ⚠ --mk — зворотний масштаб карти. Без нього підпис
   «Тулузи 3-Б» на підльоті роздувався з 82×25 до 147×45 px, тобто
   11,5px Jost рендерився як 18px — типографіка сайту тут
   просто не трималась. */
.rt-map .rt-lbl {
  background: rgba(var(--map-rgb), .9); border: 1px solid var(--line); color: var(--fg-2);
  font-size: 11.5px; letter-spacing: .06em; padding: 3px 8px; border-radius: 0;
  box-shadow: none; white-space: nowrap;
  transition: opacity .2s ease;
}
/* ⚠ КОМПЕНСУЄМО КЕГЛЕМ, А НЕ transform.
   Leaflet сам пише підпису інлайновий
   `transform: translate3d(...)` для позиції, і будь-який
   transform зі стильового файлу він перебиває — перевірено:
   computed лишається matrix(1,0,0,1,108,347). А ось розміри
   в calc() він не чіпає, і --mk туди доходить успадкуванням
   від #rtMap. Заодно зменшується і сама плашка, а не
   тільки текст у ній. */
.rt-map .rt-lbl {
  font-size: calc(11.5px * var(--mk, 1));
  padding: calc(3px * var(--mk, 1)) calc(8px * var(--mk, 1));
  border-width: calc(1px * var(--mk, 1));
}
.rt-map .rt-lbl.is-poi {
  font-size: calc(10.5px * var(--mk, 1));
  padding: calc(2px * var(--mk, 1)) calc(7px * var(--mk, 1));
}
.rt-map .rt-lbl::before { display: none; }
.rt-map .rt-lbl.is-home { border-color: var(--gold); color: var(--gold); }
.rt-map .rt-lbl.is-poi { font-size: 10.5px; color: var(--muted); padding: 2px 7px; }
.rt-map .leaflet-marker-icon, .rt-map .leaflet-tooltip { transition: opacity .45s ease; }

/* ---------- керування ----------
   Стоїть ЗВЕРХУ, а не знизу: унизу липка планка Instagram, і
   двох панелей на нижньому краї телефона бути не може. */
.rt-ctl {
  position: absolute; left: 0; right: 0; top: 0; z-index: 700;
  padding: 12px var(--pad) 0; display: grid; gap: 8px;
}
.rt-seg { display: inline-flex; border: 1px solid var(--line); background: var(--surface); width: max-content; }
.rt-seg button {
  background: none; border: 0; padding: 8px 18px; font-size: 13.5px; color: var(--muted);
  transition: color .16s, background .16s;
}
.rt-seg button + button { border-left: 1px solid var(--line); }
.rt-seg button.is-on { color: var(--on-gold); background: var(--gold); }

.rt-from { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.rt-from::-webkit-scrollbar { display: none; }
.rt-chip {
  flex: none; background: var(--surface); border: 1px solid var(--line); color: var(--muted);
  padding: 7px 13px; font-size: 12.5px; white-space: nowrap; transition: .16s;
}
.rt-chip.is-on { border-color: var(--gold); color: var(--gold); }

/* ⚠ Атрибут hidden програє правилу display:flex — без цього
   рядка поле адреси стоїть розкритим завжди. */
.rt-addr[hidden] { display: none; }
.rt-addr { display: flex; gap: 6px; }
.rt-addr input {
  flex: 1; background: var(--surface); border: 1px solid var(--line); color: var(--fg);
  padding: 8px 12px; font-size: 15px; outline: none; border-radius: var(--r-s); min-width: 0;
}
.rt-addr input:focus { border-color: var(--gold); }
.rt-addr button { background: var(--gold); color: var(--on-gold); border: 0; padding: 0 16px; font-size: 13.5px; }

[data-route].is-busy .rt-ctl { opacity: .5; pointer-events: none; }

/* ---------- HUD ---------- */
.rt-hud {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 700;
  padding: 0 var(--pad) calc(16px + var(--safe));
  pointer-events: none;
}
.rt-num { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rt-num b {
  font-size: clamp(38px, 12vw, 62px); font-weight: 200; line-height: 1;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
  font-variant-numeric: tabular-nums;
}
.rt-num span { font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.rt-bar { height: 2px; background: var(--line); margin: 12px 0 10px; overflow: hidden; }
.rt-bar i { display: block; height: 100%; background: var(--gold); transform: scaleX(0); transform-origin: left; }
.rt-cap { margin: 0; min-height: 44px; }
.rt-cap b { display: block; font-size: 17px; font-weight: 300; }
.rt-cap span { display: block; font-size: 13.5px; color: var(--muted); }

/* ---------- що поруч ---------- */
.rt-near {
  position: absolute; left: var(--pad); right: var(--pad); z-index: 700;
  top: 50%; transform: translate3d(0, -40%, 0);
  display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line);
  opacity: 0; transition: opacity .45s ease, transform .45s ease; pointer-events: none;
}
[data-route].is-end .rt-near { opacity: 1; transform: translate3d(0, -50%, 0); }
.rt-near li { display: flex; align-items: baseline; gap: 12px; background: var(--map-bg); padding: 7px 12px; }
.rt-near b { color: var(--gold); font-size: 15px; font-weight: 300; white-space: nowrap; font-variant-numeric: tabular-nums; }
.rt-near span { font-size: 13px; color: var(--fg-2); }

.rt-toast {
  position: absolute; left: 50%; top: 50%; z-index: 720; margin: 0;
  transform: translate(-50%, -50%) scale(.96);
  background: var(--surface); border: 1px solid var(--gold); color: var(--fg);
  padding: 11px 16px; font-size: 14px; text-align: center; max-width: 84%;
  opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease;
}
.rt-toast.is-on { opacity: 1; transform: translate(-50%, -50%) scale(1); }

.rt-hint {
  position: absolute; left: 0; right: 0; bottom: calc(150px + var(--safe)); z-index: 700;
  margin: 0; text-align: center; font-size: 12px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--muted); transition: opacity .3s ease;
}
.rt-hint.is-off { opacity: 0; }

[data-route].is-dead { display: none; }
[data-route].is-static .rt-track { height: auto; }
[data-route].is-static .rt-stage { position: relative; height: 74svh; }

@media (prefers-reduced-motion: reduce) { .rt-mk-b i { animation: none; } }

@media (min-width: 760px) {
  .rt-ctl { padding-top: 16px; display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
  .rt-from { flex: 1; }
  .rt-addr { flex-basis: 100%; max-width: 420px; }
  .rt-near { left: auto; right: var(--pad); width: 330px; }
  .rt-hud { padding-bottom: calc(22px + var(--safe)); }
  .rt-cap b { font-size: 19px; }
  .rt-credit { bottom: 4px; }
}

/* Полотно продуву на сторінці послуги: та сама рамка, що в
   героєві, але зі звичайними відступами секції. */
.sec-hair { padding-top: 10px; padding-bottom: 10px; }
.sec-hair .canvas-wrap { margin: 0; }

/* ============================================================
   ДЕНЬ — ніжна бірюза з rose gold

   ⚠️ ТЕМНА ТЕМА ЛИШАЄТЬСЯ ТИПОВОЮ. Чорне з золотом Вікторія
   обрала руками у брифі, і підміняти її вибір системною
   настройкою браузера не можна. Денна вмикається тільки
   натисканням і запам'ятовується — це друга шкіра, а не
   заміна першої.

   Уся тема — це блок змінних. Жодне правило нижче по файлу не
   знає, що тем дві: колір туди приходить через токени, які до
   цього стояли прибитими просто в правилах.

   ЧОМУ САМЕ ТАКІ ЧИСЛА:
   • --gold у дні це #A1596A, а не яскраве трояндове золото.
     Причина проста: у півсотні правил золото стоїть КОЛЬОРОМ
     ТЕКСТУ, і на бірюзовому тлі світла троянда дає 2,8:1 —
     нечитно. #A1596A дає 4,85:1, тобто проходить AA для
     основного тексту. Металевий блиск живе окремо, у --metal:
     там він і доречний, бо це заливка, а не текст.
   • --muted #4F726D, а не світліший: на 11-13 px підписах усе,
     що світліше, перестає читатись при денному світлі — а це
     рівно та ситуація, заради якої денну тему й вмикають.
   ============================================================ */
[data-theme="day"] {
  --bg: #E7F4F2;
  --surface: #F2FAF9;
  --surface-2: #FFFFFF;
  --fg: #10322E;
  --fg-2: #2C4F4A;
  --muted: #48665F;   /* було #4F726D — 4.70 на чистому тлі, тобто без запасу */
  --line: #C7E1DD;

  --gold: #91505F;    /* було #A1596A — 4.48 навіть без аврори */
  --gold-lo: #7C4150;
  --gold-hi: #F0D3CD;
  /* ⚠ Метал у дні мусить лишатись ЧИТНИМ. Він іде не тільки
     заливкою кнопок, а й background-clip:text на великих цифрах
     прайсу — а світлий стоп #F3DAD5 на бірюзовому тлі давав
     цифру, якої не видно. Блиск лишається, але всі стопи
     тримають контраст. */
  /* ⚠ САТИН, а не блиск. Попередній пік #CE939B давав
     2,25:1 на бірюзовому — середина кожної цифри прайсу
     майже зникала. Тепер пік йде не в світло, а глибше
     в троянду: всі стопи ≥ 3,65:1 (large-text AA). */
  --metal: linear-gradient(100deg, #7E3E52 0%, #A1596A 26%, #B0687A 47%, #9C5062 68%, #7E3E52 100%);

  --on-gold: #FFF6F4;
  --map-bg: #E3F0EE;
  --map-rgb: 227, 240, 238;
  --ink: #FFFFFF;
  --ok: #2E8B70;
  --warn: #B4553A;

  --card: linear-gradient(150deg, rgba(255,255,255,.95), rgba(231,244,242,.72) 54%, rgba(255,246,244,.92));
  --card-2: linear-gradient(150deg, rgba(255,255,255,.92), rgba(240,211,205,.34) 58%, rgba(255,255,255,.86));

  /* Світлі тайли CARTO від народження холодно-сірі. Фільтр веде
     їх у ту саму бірюзу, що й сторінку, інакше карта читається
     як вставлений чужий сайт — та сама причина, що й у темній. */
  /* М'який поворот у бірюзу, без вибілювання: карту треба
     ПІДФАРБУВАТИ під сторінку, а не стерти. */
  --tile-filter: saturate(.72) hue-rotate(-8deg) brightness(1.01) contrast(1.04);

  /* ---------- РІДКЕ СКЛО ----------
     Скло — це не одна прозорість, а чотири дешеві для рендера шари:
     заливка з нахилом, світлий кант зверху, трояндовий кант знизу
     і м'яка тінь. Глибину дає світло, а не розмиття сторінки під ним. */
  /* Прозоріше, щоб аврора проступила. Нижче .30 не
     опускати: під планкою лежить золота цифра прайсу. */
  /* Удень скло інше за природою: не плівка світла на чорному, а
     молочний аркуш на бірюзовому. Тінь у КОЛІР тла (hsl 172), не
     чорна — чорна на світлому читається як бруд. */
  --rail-bg: linear-gradient(180deg, rgba(255,255,255,.72), rgba(255,255,255,.44) 48%, rgba(255,241,239,.58));
  --rail-line: rgba(255,255,255,.86);
  --rail-shadow: inset 0 1px 0 rgba(255,255,255,.95), 0 6px 18px hsl(172 42% 22% / .12), 0 1px 3px hsl(172 42% 22% / .10);
  --rail-hover: rgba(255,255,255,.62);
  --rail-on: rgba(255,255,255,.92);
  --rail-on-shadow: inset 0 1px 0 #fff, 0 3px 10px hsl(172 42% 22% / .16);
  /* ⚠️ УДЕНЬ ЧОРНА ТІНЬ = БРУД (те саме правило, що й у --rail-shadow
     вище). Тінь під кнопкою йде в колір самого металу (--gold-lo
     дня, троянда), а не в чорний. */
  --btn-hi: rgba(255,255,255,.85);
  --btn-bevel: inset 0 1px 0 var(--btn-hi), inset 0 -3px 6px rgba(124,65,80,.22), 0 8px 18px hsl(340 24% 30% / .18);
  --btn-press: inset 0 2px 6px rgba(124,65,80,.3), inset 0 -1px 0 rgba(255,255,255,.55);
  --glass: linear-gradient(155deg, rgba(255,255,255,.60), rgba(255,255,255,.34) 46%, rgba(255,241,239,.52));
  --glass-edge: rgba(255,255,255,.92);
  --glass-rim: rgba(178,111,124,.32);
  --glass-shadow: 0 12px 32px rgba(16,74,68,.13), 0 2px 6px rgba(16,74,68,.06);
  --grain-op: .028;

  /* Аврора дня: колірні поля, які проступають крізь
     скло й дають сторінці глибину. Рожева — у ВЕРХНІЙ-
     ПРАВИЙ кут, геть від лівої колонки прайсу. Альфа
     ≤ .18: над найгустішою плямою текст #10322E ≥ 11,5:1. */
  /* ⚠⚠ АЛЬФИ ПОРАХОВАНІ, А НЕ ПІДІБРАНІ ОКОМ. Денна аврора в
     попередніх значеннях (.18/.14/.42/.10) заводила текст під AA
     на живому проді: над кожною з чотирьох плям --muted давав
     3.75 / 4.02 / 4.28 / 4.05 замість 4.5, а --gold 3.57 / 3.83 /
     4.08 / 3.86. Причина в тому, що на чистому денному тлі
     --muted має всього 4.70, тобто 4% запасу, і будь-який тон
     його з'їдає. Тепер альфи зменшені втричі, а обидва токени
     тексту опущені так, щоб навіть накладення всіх чотирьох плям
     тримало 4.5:1. Ніч перевірена окремо: там 5.03 і 6.49, тобто
     проблеми не було. */
  --au-1: rgba(161,89,106,.054);
  --au-2: rgba(46,139,112,.042);
  --au-3: rgba(240,211,205,.126);
  --au-4: rgba(124,65,80,.030);
  /* Заголовки дня: глибока бірюза → rose. Це два фірмові
     кольори, тобто САМ айртач як типографіка. Кожен стоп
     перевірений: 12,3 / 8,0 / 6,8 / 5,65:1 — усі AA. Світлих
     стопів у ТЕКСТІ немає навмисно. */
  --headline: linear-gradient(96deg, #10322E 0%, #2C4F4A 34%, #7C4150 82%, #8E4B58 100%);
  /* Тіні в КОЛІР тла (hsl 172°), а не чорні: кладка
     аркушів, що відриваються від аврори, замість
     сірого wireframe із 1px-ліній. */
  --lift-1: 0 1px 2px hsl(172 42% 22% / .10), 0 3px 6px hsl(172 42% 22% / .09), 0 7px 14px hsl(172 42% 22% / .07);
  --lift-2: 0 2px 4px hsl(172 42% 22% / .08), 0 6px 12px hsl(172 42% 22% / .08), 0 14px 28px hsl(172 42% 22% / .07), 0 28px 48px hsl(172 42% 22% / .05);
  --soft-shadow: var(--lift-1);
}

/* Зерно на світлому мусить ЗАТЕМНЮВАТИ, а не світити: на чорному
   воно додає плівкове зерно, на бірюзовому тим самим режимом
   давало б молочну пелену. */
[data-theme="day"] body::after { opacity: var(--grain-op); mix-blend-mode: multiply; }
[data-theme="day"] .st-view::after { opacity: .035; mix-blend-mode: multiply; }

/* ---------- Скло на конкретних елементах ----------
   ⚠️ Не на всьому підряд. Скло має сенс там, де воно ЛЕЖИТЬ
   ПОВЕРХ вмісту: липка планка, пігулки розділів, керування
   карти. На звичайних картках це просто зайвий шум. */
/* ⚠ `.pill` ЗВІДСИ ПРИБРАНО. Скло на кожній пігулці мало сенс, поки
   вони стояли поодинці на тлі сторінки. Тепер вони лежать усередині
   скляної КОЛІЇ, і подвійне скло робило всі сім пігулок однаково
   піднятими — активну не було видно взагалі. Скло тримає колія,
   підняття показує тільки активна через --rail-on. */
[data-theme="day"] .rt-seg,
[data-theme="day"] .rt-chip,
[data-theme="day"] .rt-near,
[data-theme="day"] .rt-addr input,
[data-theme="day"] .st-go,
[data-theme="day"] .switch,
[data-theme="day"] .theme-tog {
  background: var(--glass);
  border-color: var(--glass-edge);
  /* ⚠ Стос шарів = скло, а не матова плашка:
     яскраве ребро зверху-ліворуч (specular, НЕ рамка —
     інакше читається як обведення), трояндовий
     fresnel знизу, і мʼяка тінь під ним. */
  box-shadow:
    inset 1px 1px 0 rgba(255,255,255,.92),
    inset 0 -1px 2px rgba(124,65,80,.14),
    var(--glass-shadow);
}

/* Фіксована планка перекриває живий контент, тому її поверхня глуха:
   це тримає текст стабільним і не змушує браузер перемальовувати тло. */
[data-theme="day"] .dock {
  background: var(--surface); border-color: var(--glass-edge);
  box-shadow: inset 1px 1px 0 rgba(255,255,255,.92), var(--glass-shadow);
}

/* Трояндовий кант — саме він робить скло «rose gold», а не
   просто матовим. Стоїть окремим шаром, щоб не з'їдати рамку. */
[data-theme="day"] .dock::after,
[data-theme="day"] .rt-near::after,
[data-theme="day"] .rt-seg::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border: 1px solid transparent;
  background: linear-gradient(150deg, rgba(255,255,255,.95), transparent 34%, rgba(178,111,124,.5)) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
[data-theme="day"] .rt-near, [data-theme="day"] .rt-seg { position: relative; }

/* Смуга світла по планці в дні — трояндова, не золота. */
[data-theme="day"] .dock::before {
  background: linear-gradient(90deg, transparent, var(--gold-hi), transparent);
}

/* Активна пігулка піднята склом, не обведена: рамки в пігулок більше
   немає, тому border-color тут не діяв би взагалі. */
[data-theme="day"] .rt-chip.is-on { border-color: var(--gold); color: var(--gold); }
[data-theme="day"] .switch button.is-on { background: var(--surface-2); color: var(--gold); }

/* ⚠️ Повне правило для .facts/.qa/.numbers/.salon-facts/.tiles li
   (фон + box-shadow) стоїть нижче, разом із .gifts li — тут
   лишається тільки те, чого там немає. */
[data-theme="day"] .rt-near li { background: transparent; }

/* Герой і карта: тло полотна йде з токена, тому канвас
   перемальовується сам (див. app/canvas.js). */
[data-theme="day"] .canvas-wrap { background: var(--map-bg); }

/* ---------- Перемикач теми ----------
   Стоїть у шапці поруч із телефоном: це не налаштування, а
   те саме, що вимикач світла в кімнаті — його шукають руками
   там, де заходять. */
.theme-tog {
  display: inline-grid; place-items: center;
  width: 34px; height: 34px; flex: none;
  background: none; border: 1px solid var(--line); color: var(--muted);
  padding: 0; transition: color .18s ease, border-color .18s ease;
}
@media (hover: hover) and (pointer: fine) {
  .theme-tog:hover { color: var(--gold); border-color: var(--gold); }
}
.theme-tog svg { width: 17px; height: 17px; display: block; }
.theme-tog .i-sun { display: none; }
[data-theme="day"] .theme-tog .i-sun { display: block; }
[data-theme="day"] .theme-tog .i-moon { display: none; }

.top-in { gap: 12px; }
.top-tel { margin-left: auto; }

/* Плавний перехід між темами — але ТІЛЬКИ на колір і тільки
   поки перемикають. Постійний transition на background у всіх
   елементів робить сайт ватним при кожній появі. */
.theme-shift, .theme-shift * {
  transition: background-color .32s ease, color .32s ease, border-color .32s ease !important;
}
@media (prefers-reduced-motion: reduce) {
  .theme-shift, .theme-shift * { transition: none !important; }
}

/* ============================================================
   ДЕНЬ: СТРУКТУРА ПРОТИ ШАБЛОННОСТІ

   Не ще один ефект, а зміна ритму. Уночі пелюстки тримає щільний
   згасаючий шов; на бірюзі навіть така волосина потребує трохи більше
   повітря, інакше читається як сірий wireframe. Тому в дні полотно
   стає кладкою аркушів, що відриваються від аврори тінню, а одна
   секція ламає метроном, виходячи за поля.
   ============================================================ */

/* Полотно: контейнер прозорий, клітинки — білі аркуші з lift. */
[data-theme="day"] .facts,
[data-theme="day"] .qa,
[data-theme="day"] .numbers,
[data-theme="day"] .salon-facts,
[data-theme="day"] .tiles,
[data-theme="day"] .gifts { background: transparent; border: 0; gap: 8px; }

[data-theme="day"] .facts li,
[data-theme="day"] .qa li,
[data-theme="day"] .numbers li,
[data-theme="day"] .salon-facts li,
[data-theme="day"] .tiles li,
[data-theme="day"] .gifts li {
  background: var(--surface-2);
  /* inset СВІТЛИЙ, не кольоровий: кольоровий дав би брудний обідок. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), var(--lift-1);
}

/* Герой — найглибший аркуш над авророю. */
/* ⚠️⚠️ box-shadow ТУТ НІКОЛИ НЕ МАЛЮВАВСЯ. CSS-маска (патьоки
   знизу) обрізає весь намальований елемент по border-box, а
   зовнішня тінь лежить ЗА цією межею — тобто в масці, як і решта
   контенту поза border-box. `filter: drop-shadow` рахується
   ПІСЛЯ маски й повторює її силует, тому тінь лягає по краю
   патьоків, а не прямокутником навколо них. border-color теж не
   діяв: у .canvas-wrap стоїть `border: 0`. */
[data-theme="day"] .canvas-wrap { filter: drop-shadow(0 10px 26px rgba(16, 74, 68, .16)); }

/* ---------- Домінанта ----------
   Секція айртачу виходить за поля, коли всі інші лишаються в
   рамці, і друкує ціну гігантським числом. Рівно ОДНА на
   сторінку: саме контраст «одна повноширинна серед вставлених»
   ламає рівний ритм, тому дублювати не можна. */
[data-theme="day"] .airtouch {
  margin-inline: calc(var(--pad) * -1);
  border: 0; border-radius: var(--r-xl); padding: 26px var(--pad);
  box-shadow: var(--lift-1); background: var(--surface-2);
}

[data-theme="day"] .map { background: var(--map-bg); }
[data-theme="day"] .proof,
[data-theme="day"] .terms { background: var(--surface-2); box-shadow: var(--lift-1); }
[data-theme="day"] .btn { color: var(--fg); }
[data-theme="day"] .btn.btn-ghost { color: var(--fg-2); }
[data-theme="day"] .btn.btn-gold { color: var(--on-gold); }
[data-theme="day"] .airtouch .sum {
  font-size: clamp(52px, 16vw, 112px); line-height: .9;
  letter-spacing: -.02em; margin-top: 18px;
  background: var(--headline);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--fg);
}


/* ══════════════════════════════════════════════════════════════
   ПОЛЕ РОЗДІЛУ — «весь задній фон відповідає за розділ»
   ══════════════════════════════════════════════════════════════
   Кожна з дванадцяти сторінок фарбує ВЕСЬ екран у власний тон:
   волосся — золото айртачу, манікюр — лак, брови — горіх і графіт,
   дорога — холодний ранок. Механіка нульова: `data-page` уже стоїть
   на кожній сторінці, аврора вже намальована на `body::before`, тут
   лише перевизначаються чотири кольори. Жодного нового шару, жодної
   перемальовки, жодного кадру.

   ⚠️ АЛЬФИ ПОРАХОВАНІ, А НЕ ПІДІБРАНІ ОКОМ, і це не педантизм.
   На чистому денному тлі `--muted` має всього 4.70:1, тобто 4%
   запасу — будь-який тон зверху заводить текст під AA. Саме так і
   сталось із першою денною авророю: усі чотири плями давали
   3.75 / 4.02 / 4.28 / 4.05 замість 4.5, на живому проді.
   Тому альфи тут розв'язані чисельно: для кожного розділу взято
   МАКСИМУМ, за якого `--muted`, `--gold` і `--fg-2` тримають 4.5:1
   навіть у найгіршому випадку — коли всі чотири плями накладені
   одна на одну. Скрипт підбору: scratchpad/fields.py.

   ⚠️ ЯСКРАВІСТЬ ЗАТИСНУТА КОНТРАСТОМ, тому розділ упізнається
   ТОНОМ, а не силою. Спроба зробити фон помітнішим = спроба зробити
   текст нечитабельним; це арифметика, а не смак.
   ══════════════════════════════════════════════════════════════ */
body[data-page="home"] {
  --au-1: rgba(201,162,74,0.084);
  --au-2: rgba(124,65,80,0.066);
  --au-3: rgba(235,214,155,0.052);
  --au-4: rgba(60,45,20,0.046);
}
[data-theme="day"] body[data-page="home"] {
  --au-1: rgba(161,89,106,0.052);
  --au-2: rgba(46,139,112,0.041);
  --au-3: rgba(240,211,205,0.032);
  --au-4: rgba(124,65,80,0.029);
}
body[data-page="airtouch"] {
  --au-1: rgba(201,162,74,0.079);
  --au-2: rgba(138,106,46,0.061);
  --au-3: rgba(240,223,174,0.049);
  --au-4: rgba(42,33,24,0.043);
}
[data-theme="day"] body[data-page="airtouch"] {
  --au-1: rgba(161,89,106,0.053);
  --au-2: rgba(63,143,118,0.041);
  --au-3: rgba(244,222,214,0.033);
  --au-4: rgba(110,58,74,0.029);
}
body[data-page="strizhky"] {
  --au-1: rgba(154,163,174,0.085);
  --au-2: rgba(90,100,112,0.066);
  --au-3: rgba(199,205,214,0.053);
  --au-4: rgba(32,36,42,0.047);
}
[data-theme="day"] body[data-page="strizhky"] {
  --au-1: rgba(110,124,136,0.057);
  --au-2: rgba(46,139,112,0.044);
  --au-3: rgba(217,226,228,0.035);
  --au-4: rgba(74,90,100,0.031);
}
body[data-page="doglyad"] {
  --au-1: rgba(143,163,107,0.088);
  --au-2: rgba(78,95,58,0.069);
  --au-3: rgba(203,217,168,0.055);
  --au-4: rgba(30,36,22,0.049);
}
[data-theme="day"] body[data-page="doglyad"] {
  --au-1: rgba(92,122,78,0.056);
  --au-2: rgba(46,139,112,0.044);
  --au-3: rgba(220,232,204,0.035);
  --au-4: rgba(70,96,60,0.031);
}
body[data-page="manikyur"] {
  --au-1: rgba(201,86,110,0.114);
  --au-2: rgba(142,58,106,0.089);
  --au-3: rgba(232,160,168,0.071);
  --au-4: rgba(42,20,32,0.063);
}
[data-theme="day"] body[data-page="manikyur"] {
  --au-1: rgba(184,69,94,0.052);
  --au-2: rgba(199,122,74,0.041);
  --au-3: rgba(242,203,210,0.032);
  --au-4: rgba(142,58,106,0.029);
}
body[data-page="brovy"] {
  --au-1: rgba(138,115,88,0.128);
  --au-2: rgba(74,59,44,0.100);
  --au-3: rgba(188,168,138,0.079);
  --au-4: rgba(28,24,17,0.070);
}
[data-theme="day"] body[data-page="brovy"] {
  --au-1: rgba(107,86,62,0.049);
  --au-2: rgba(63,143,118,0.039);
  --au-3: rgba(222,210,192,0.031);
  --au-4: rgba(90,70,50,0.027);
}
body[data-page="tsiny"] {
  --au-1: rgba(185,169,138,0.089);
  --au-2: rgba(90,80,64,0.069);
  --au-3: rgba(216,205,180,0.055);
  --au-4: rgba(26,23,18,0.049);
}
[data-theme="day"] body[data-page="tsiny"] {
  --au-1: rgba(122,110,88,0.054);
  --au-2: rgba(46,139,112,0.042);
  --au-3: rgba(226,220,204,0.034);
  --au-4: rgba(94,83,66,0.030);
}
body[data-page="kontakty"] {
  --au-1: rgba(126,147,168,0.098);
  --au-2: rgba(68,84,104,0.077);
  --au-3: rgba(182,198,214,0.061);
  --au-4: rgba(24,28,34,0.054);
}
[data-theme="day"] body[data-page="kontakty"] {
  --au-1: rgba(83,105,126,0.052);
  --au-2: rgba(46,139,112,0.041);
  --au-3: rgba(210,222,230,0.032);
  --au-4: rgba(62,80,100,0.029);
}
body[data-page="zhurnal"] {
  --au-1: rgba(191,174,146,0.083);
  --au-2: rgba(106,90,70,0.065);
  --au-3: rgba(224,211,188,0.051);
  --au-4: rgba(30,26,20,0.046);
}
[data-theme="day"] body[data-page="zhurnal"] {
  --au-1: rgba(128,112,90,0.055);
  --au-2: rgba(46,139,112,0.043);
  --au-3: rgba(232,223,210,0.034);
  --au-4: rgba(96,82,62,0.030);
}
body[data-page="maister"] {
  --au-1: rgba(176,138,90,0.102);
  --au-2: rgba(94,67,38,0.079);
  --au-3: rgba(220,196,154,0.063);
  --au-4: rgba(32,24,16,0.056);
}
[data-theme="day"] body[data-page="maister"] {
  --au-1: rgba(138,100,72,0.052);
  --au-2: rgba(46,139,112,0.041);
  --au-3: rgba(230,214,196,0.032);
  --au-4: rgba(106,76,54,0.029);
}
body[data-page="sertyfikat"] {
  --au-1: rgba(210,172,88,0.076);
  --au-2: rgba(138,106,46,0.060);
  --au-3: rgba(240,223,174,0.047);
  --au-4: rgba(44,34,16,0.042);
}
[data-theme="day"] body[data-page="sertyfikat"] {
  --au-1: rgba(161,89,106,0.057);
  --au-2: rgba(192,138,74,0.044);
  --au-3: rgba(242,220,196,0.035);
  --au-4: rgba(124,65,80,0.031);
}
body[data-page="kabinet"] {
  --au-1: rgba(142,142,142,0.103);
  --au-2: rgba(74,74,74,0.081);
  --au-3: rgba(192,192,192,0.064);
  --au-4: rgba(26,26,26,0.057);
}
[data-theme="day"] body[data-page="kabinet"] {
  --au-1: rgba(106,106,106,0.053);
  --au-2: rgba(46,139,112,0.041);
  --au-3: rgba(218,218,218,0.033);
  --au-4: rgba(80,80,80,0.029);
}


/* ============================================================
   КАБІНЕТ

   ⚠️ ЦЕ НЕ «АДМІНКА», А ТОЙ САМИЙ САЙТ ЗСЕРЕДИНИ. Жодного
   окремого набору кольорів: скляна колія, Playfair у заголовках,
   золото на правлених рядках — усе на тих самих токенах, тому
   денна тема й будь-який обраний відтінок працюють тут самі,
   без єдиного окремого правила.
   ============================================================ */
.kb-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.kb-out { background: none; border: 0; color: var(--muted); font-size: 13.5px; text-decoration: underline; }
@media (hover: hover) and (pointer: fine) { .kb-out:hover { color: var(--warn); } }
/* ⚠️ НА ШИРОКОМУ ЕКРАНІ РЕЙКА ПЕРЕНОСИТЬСЯ, А НЕ ЇДЕ. Успадкований
   від сайту overflow-x:auto доречний на телефоні (там це звична
   смужка), але на ноутбуці шоста вкладка просто зрізалась об край
   колії — виглядало як зламана верстка, а не як «прокрути мене». */
.kb-rail { margin-inline: 0; margin-top: 16px; }
@media (min-width: 620px) {
  /* ⚠️ Колія по ширині ВКЛАДОК, а не колонки. Розтягнута на всі
     900px, вона лишала праворуч півметра порожнього скла — на сайті
     цього не видно, бо там пункти розсунуті space-between по всій
     ширині, а тут їх шість і вони вужчі. */
  .kb-rail { flex-wrap: wrap; overflow: visible; justify-content: flex-start; width: max-content; max-width: 100%; }
  .kb-rail .pill { padding: 11px 20px; }
}
.kb-keep { display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--fg-2); margin: 0 0 16px; }
.kb-keep input { accent-color: var(--gold); width: 17px; height: 17px; }

.kb-note { color: var(--fg-2); font-size: 15px; line-height: 1.55; margin: 6px 0 22px; max-width: 62ch; }
.kb-note-sm { font-size: 13.5px; color: var(--muted); }
.kb-note code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .92em; color: var(--gold); }
.kb-h2 { margin: 38px 0 14px; font-size: 24px; }

/* Плашка з перемикачем */
.kb-plate { border: 1px solid var(--line); padding: 16px; margin-bottom: 26px; }
.kb-switch { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.kb-switch input { accent-color: var(--gold); width: 19px; height: 19px; margin-top: 2px; flex: none; }
.kb-switch b { display: block; font-weight: 400; font-size: 15.5px; }
.kb-switch i { display: block; font-style: normal; font-size: 13.5px; color: var(--muted); margin-top: 3px; line-height: 1.45; }
.kb-switch-sm b { font-size: 14.5px; }

/* ---------- рядок прайсу ---------- */
.kb-rows { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.kb-row { background: var(--bg); padding: 15px 14px; position: relative; }
/* ⚠️ Правлене позначаємо КАНТОМ ЗЛІВА, а не заливкою: заливка
   золотим по всій картці — це «золото як фон», проти чого
   написаний увесь інший файл. */
.kb-row.is-edited, .kb-field.is-edited { box-shadow: inset 3px 0 0 var(--gold); }
.kb-row-h { margin-bottom: 11px; }
.kb-row-h b { font-weight: 400; font-size: 16px; }
.kb-row-h i { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 2px; }

.kb-triple { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.kb-row .kb-triple:has(label:only-child) { grid-template-columns: 1fr; max-width: 240px; }
.kb-triple label, .kb-time { display: block; }
.kb-triple span, .kb-time span, .kb-field > span {
  display: block; font-size: 11.5px; color: var(--muted); margin-bottom: 5px; letter-spacing: .02em;
}
.kb-time { margin-top: 10px; max-width: 240px; }
/* ⚠️⚠️ `.kb-triple` ТУТ ОБОВ'ЯЗКОВИЙ. Ці ж трійки полів стоять і в
   формі графіка, яка лежить у .kb-plate, а не в .kb-row — і туди
   не діставало жодне правило. Заміряно: color #F2EFE9 на
   background #FFFFFF, тобто контраст 1.1:1 — числа графіка були
   білим по білому й не читались узагалі. Скріншот цього не
   показав: майже біле на білому виглядає як «бліда підказка», а
   не як поломка. */
.kb-row input, .kb-field input, .kb-field textarea, .kb-triple input, .kb-form select {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  color: var(--fg); font: inherit; font-size: 15px; padding: 10px 11px;
}
.kb-field textarea { line-height: 1.5; resize: vertical; }
.kb-row input:focus, .kb-field input:focus, .kb-field textarea:focus,
.kb-triple input:focus, .kb-form select:focus { border-color: var(--gold); outline: none; }
.kb-reset {
  background: none; border: 0; color: var(--muted); font-size: 12.5px;
  text-decoration: underline; padding: 0; margin-top: 11px;
}
@media (hover: hover) and (pointer: fine) { .kb-reset:hover { color: var(--gold); } }
.kb-state { display: block; font-style: normal; font-size: 12px; min-height: 16px; margin-top: 7px; color: var(--muted); }
.kb-state.is-ok { color: var(--ok); }
.kb-state.is-bad { color: var(--warn); }

/* ---------- тексти: гармошка ---------- */
.kb-acc { border: 1px solid var(--line); margin-bottom: 10px; }
.kb-acc-h {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  width: 100%; background: none; border: 0; padding: 15px 14px; text-align: left; color: var(--fg);
}
.kb-acc-h b { font-weight: 400; font-size: 16.5px; font-family: var(--font-display); }
.kb-acc-h i { font-style: normal; font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.kb-acc.is-open .kb-acc-h { border-bottom: 1px solid var(--line); }
.kb-acc-b { padding: 16px 14px 6px; }
.kb-field { margin-bottom: 18px; padding-left: 11px; }
.kb-field-sw { padding-top: 4px; }

/* ---------- вигляд ---------- */
.kb-looks { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.kb-look {
  display: block; text-align: left; background: var(--surface); color: var(--fg);
  border: 1px solid var(--line); padding: 0 0 14px; overflow: hidden;
}
.kb-look.is-on { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.kb-look-n, .kb-look-d { display: block; height: 30px; }
.kb-look b { display: block; font-weight: 400; font-size: 16px; padding: 13px 14px 3px; }
.kb-look i { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); padding: 0 14px; }

/* ---------- історія ---------- */
.kb-hist { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.kb-hist li {
  background: var(--bg); padding: 14px; display: grid;
  grid-template-columns: 1fr auto; gap: 12px; align-items: center;
}
.kb-hist b { display: block; font-weight: 400; font-size: 14px; word-break: break-all; }
.kb-hist i { display: block; font-style: normal; font-size: 12px; color: var(--muted); margin-top: 2px; }
.kb-hist p { margin: 7px 0 0; font-size: 14px; color: var(--fg-2); }
.kb-hist s { color: var(--muted); }
.kb-rev { padding: 9px 15px; font-size: 13px; white-space: nowrap; }

/* ---------- помічник ---------- */
.kb-chat { display: grid; gap: 12px; margin-bottom: 16px; }
.kb-msg { padding: 13px 15px; font-size: 15px; line-height: 1.55; max-width: 46em; }
.kb-me { background: var(--surface-2); border: 1px solid var(--line); justify-self: end; }
.kb-it { border: 1px solid var(--line); }
.kb-wait { color: var(--muted); }
.kb-edit {
  margin-top: 12px; padding: 12px; border: 1px solid var(--gold);
  display: grid; gap: 7px; justify-items: start;
}
.kb-edit b { font-weight: 400; font-size: 13px; color: var(--gold); word-break: break-all; }
.kb-edit span { font-size: 15px; }
.kb-edit i { font-style: normal; font-size: 13px; color: var(--muted); }
.kb-edit .btn { padding: 10px 18px; font-size: 14px; }
.kb-ask { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: end; }
.kb-ask textarea {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  color: var(--fg); font: inherit; font-size: 15px; padding: 11px; resize: vertical;
}
.kb-ask textarea:focus { border-color: var(--gold); outline: none; }

@media (max-width: 520px) {
  .kb-triple { grid-template-columns: 1fr 1fr; }
  .kb-hist li { grid-template-columns: 1fr; }
  .kb-rev { justify-self: start; }
  .kb-ask { grid-template-columns: 1fr; }
}

/* ============================================================
   ПОМІЧНИК НА САЙТІ

   ⚠️ Кнопка сидить НАД планкою запису, а не поруч: планка фіксована
   внизу на всю ширину, і будь-що на її рівні або перекриває головну
   дію сайту, або тоне під нею.
   ============================================================ */
.ask-btn {
  position: fixed; right: var(--pad); z-index: 55;
  bottom: calc(var(--dock) + var(--safe) + 14px);
  padding: 11px 18px; border-radius: 22px;
  color: var(--gold); font-size: 14px; letter-spacing: .02em;
  /* ⚠️ ДВА ШАРИ, А НЕ ОДНЕ СКЛО. Кнопка висить над текстом сторінки;
     саме лише напівпрозоре скло пропускало літери під собою, і
     золотий підпис читався по чужих рядках. Знизу — глухий surface,
     зверху — та сама плівка світла, що й на рейці. */
  background: var(--rail-bg), var(--surface);
  border: 1px solid var(--rail-line);
  box-shadow: var(--rail-shadow);
  transition: transform .09s, box-shadow .18s ease;
}
.ask-btn:active { transform: scale(.97); }
.ask-btn.is-on { box-shadow: var(--rail-on-shadow); background: var(--rail-on); }

/* ⚠️ АТРИБУТ `hidden` ПРОГРАЄ У `display: flex` З КЛАСУ.
   ask.js ховає панель через panel.hidden = true, але UA-правило
   `[hidden]{display:none}` має специфічність 0,0,1, а це — 0,1,0.
   Закрита панель лишалась у потоці смужкою в 2 px (дві рамки)
   поверх КОЖНОЇ сторінки. */
.ask-panel[hidden] { display: none; }
.ask-panel {
  position: fixed; z-index: 56; right: var(--pad); left: var(--pad);
  bottom: calc(var(--dock) + var(--safe) + 62px);
  max-height: min(72vh, 620px);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: 0 20px 60px rgba(0,0,0,.55);
}
.ask-top {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 15px; border-bottom: 1px solid var(--line);
}
.ask-top b { font-weight: 400; font-size: 15px; font-family: var(--font-display); }
.ask-x { background: none; border: 0; color: var(--muted); font-size: 13px; text-decoration: underline; }
.ask-body {
  overflow-y: auto; padding: 14px 15px; display: grid; gap: 10px; align-content: start;
  /* ⚠️ СМУГА ПРОКРУТКИ ТЕЖ ЧАСТИНА ПАНЕЛІ. Системна світла смуга
     на чорному склі — найяскравіший елемент кадру, і око чіпляється
     за неї, а не за години запису. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.ask-body::-webkit-scrollbar { width: 8px; }
.ask-body::-webkit-scrollbar-track { background: transparent; }
.ask-body::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.ask-hello p { margin: 0 0 8px; font-size: 15px; color: var(--fg-2); line-height: 1.55; }
.ask-small { font-size: 13px; color: var(--muted); }
.ask-hints { display: grid; gap: 7px; justify-items: start; }
.ask-hint {
  text-align: left; font-size: 13.5px; color: var(--fg-2);
  border: 1px solid var(--line); background: none; padding: 9px 12px; border-radius: 16px;
}
@media (hover: hover) and (pointer: fine) { .ask-hint:hover { border-color: var(--gold); color: var(--gold); } }
.ask-msg { font-size: 15px; line-height: 1.55; padding: 11px 13px; max-width: 92%; }
.ask-me { background: var(--surface-2); border: 1px solid var(--line); justify-self: end; }
.ask-it { border: 1px solid var(--line); }
.ask-wait { color: var(--muted); }
.ask-form { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 11px; border-top: 1px solid var(--line); }
.ask-in {
  width: 100%; background: var(--bg); border: 1px solid var(--line);
  color: var(--fg); font: inherit; font-size: 15px; padding: 11px 12px;
}
.ask-in:focus { border-color: var(--gold); outline: none; }
.ask-go { border: 1px solid var(--line); background: none; color: var(--gold); font-size: 18px; padding: 0 16px; }
.ask-go:disabled, .ask-in:disabled { opacity: .5; }

@media (min-width: 700px) {
  /* ⚠️ АТРИБУТ `hidden` ПРОГРАЄ У `display: flex` З КЛАСУ.
   ask.js ховає панель через panel.hidden = true, але UA-правило
   `[hidden]{display:none}` має специфічність 0,0,1, а це — 0,1,0.
   Закрита панель лишалась у потоці смужкою в 2 px (дві рамки)
   поверх КОЖНОЇ сторінки. */
.ask-panel[hidden] { display: none; }
.ask-panel { left: auto; width: 420px; }
}
/* ⚠️ Планка запису є на КОЖНІЙ сторінці (shell.js ставить її в
   mountShell), тому запас під неї безумовний. Тут спершу стояло
   правило «якщо планки немає — сідай нижче» через клас, якого ніхто
   не виставляє: воно спрацьовувало завжди й садило кнопку просто
   на планку. */

/* Рядок «підтверджено» під значенням, яке він позначає. */
.kb-ask-row { display: flex; align-items: center; gap: 9px; margin-top: 9px; cursor: pointer; }
.kb-ask-row input { accent-color: var(--gold); width: 16px; height: 16px; flex: none; }
.kb-ask-row span { font-size: 12.5px; color: var(--muted); }
/* ⚠️ min-width:0 на гнучкому елементі: без нього довгий підпис не
   переноситься, а розпихає рядок і виїжджає за екран на 320px. */
.kb-switch > span, .kb-ask-row > span { min-width: 0; overflow-wrap: anywhere; }
.kb-switch { align-items: flex-start; }


/* ---------- кабінет: записи ---------- */
.kb-flag {
  border: 1px solid var(--gold); color: var(--gold);
  padding: 12px 14px; font-size: 15px; margin: 0 0 18px;
}
.kb-warn {
  border: 1px solid var(--warn); color: var(--fg-2);
  padding: 12px 14px; font-size: 14px; line-height: 1.5; margin: 0 0 18px;
}
.kb-btns { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.kb-btns .btn { padding: 11px 18px; font-size: 14px; }
/* ⚠️ ПЕРЕМИКАЧ БЕЗ ОЗНАКИ ВИБРАНОГО — ЦЕ НЕ ПЕРЕМИКАЧ. «Список»
   і «Воронка» виглядали однаково, і зрозуміти, що зараз відкрито,
   можна було тільки за вмістом нижче. Тримаємо ту саму мову, що й
   у пігулок рейки: золотий кант плюс золотий текст. */
.kb-btns .btn.is-on { border-color: var(--gold); color: var(--gold); }
.kb-form { margin-bottom: 26px; }
.kb-form .inp { margin-bottom: 12px; }
.kb-form select {
  width: 100%; background: var(--surface); border: 1px solid var(--line);
  color: var(--fg); font: inherit; font-size: 15px; padding: 10px 11px;
}
.kb-h2n { font-style: normal; font-size: 13px; color: var(--muted); font-family: var(--font-body); }

/* ⚠️ ГОДИНА ОКРЕМОЮ КОЛОНКОЮ ЗЛІВА. Вона єдина, по чому рядки
   шукають очима: «хто о третій». Усередині рядка час губиться. */
.kb-brow { display: grid; grid-template-columns: 62px 1fr; gap: 4px 14px; align-items: start; }
.kb-btime { font-size: 19px; font-weight: 300; line-height: 1.2; }
.kb-btime i { display: block; font-style: normal; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.kb-bmain b { display: block; font-weight: 400; font-size: 16px; }
.kb-bwho { display: block; font-size: 14.5px; color: var(--fg-2); margin-top: 3px; }
.kb-bwho a { color: var(--gold); }
.kb-bnote { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 3px; }
.kb-bstat { display: block; font-style: normal; font-size: 11.5px; color: var(--muted); margin-top: 5px; letter-spacing: .03em; }
.kb-bacts { grid-column: 2; display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 9px; }
.kb-bacts button {
  background: none; border: 0; padding: 0; color: var(--fg-2);
  font-size: 13px; text-decoration: underline;
}
@media (hover: hover) and (pointer: fine) { .kb-bacts button:hover { color: var(--gold); } }
.kb-bacts .kb-bdel { color: var(--muted); }
@media (hover: hover) and (pointer: fine) { .kb-bacts .kb-bdel:hover { color: var(--warn); } }

/* Стан рядка — кантом зліва, як і правлені поля. Заливкою не
   робимо: п'ять станів у п'яти кольорах перетворили б список на
   світлофор. */
.kb-brow.is-new { box-shadow: inset 3px 0 0 var(--gold); }
.kb-brow.is-ok { box-shadow: inset 3px 0 0 var(--ok); }
.kb-brow.is-no { box-shadow: inset 3px 0 0 var(--warn); }
.kb-brow.is-off { opacity: .55; }
.kb-past { opacity: .72; }

.kb-wday { display: grid; grid-template-columns: 1fr 110px 110px; gap: 10px; align-items: center; margin-bottom: 8px; }
.kb-wday span { font-size: 14.5px; color: var(--fg-2); }
.kb-wday input {
  background: var(--surface); border: 1px solid var(--line);
  color: var(--fg); font: inherit; font-size: 14.5px; padding: 8px 10px; width: 100%;
}
.kb-wday input:focus { border-color: var(--gold); outline: none; }

@media (max-width: 520px) {
  .kb-brow { grid-template-columns: 54px 1fr; }
  .kb-btime { font-size: 17px; }
  .kb-wday { grid-template-columns: 1fr 1fr; }
  .kb-wday span { grid-column: 1 / -1; }
}


/* ---------- помічник: вибір часу й запис ---------- */
.ask-bstart {
  display: block; margin-top: 11px; padding: 10px 16px;
  background: var(--gold); color: var(--on-gold); border: 0;
  font: inherit; font-size: 14.5px; letter-spacing: .02em;
}
.ask-book { border: 1px solid var(--gold); padding: 14px; display: grid; gap: 9px; }
.ask-book b { font-weight: 400; font-size: 16px; }
.ask-book p { margin: 0; font-size: 14.5px; color: var(--fg-2); line-height: 1.5; }
.ask-book .ask-x { justify-self: start; }
.ask-bad { color: var(--warn); }
.ask-book.is-done { border-color: var(--ok); }
.ask-book.is-done b { color: var(--ok); }

.ask-day { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.ask-day i {
  flex: 1 0 100%; font-style: normal; font-size: 12px;
  color: var(--muted); letter-spacing: .04em; text-transform: lowercase;
}
/* ⚠️ ГОДИНА ВЕЛИКА, «ДО» — ДРІБНЕ, АЛЕ ПОРУЧ. Це та сама вимога
   «за 15 хвилин велику роботу не зробиш»: людина обирає не точку,
   а відрізок свого дня, і кінець мусить бути видно ДО натиску. */
.ask-slot {
  display: grid; gap: 1px; padding: 8px 12px; min-width: 74px;
  border: 1px solid var(--line); background: var(--surface); color: var(--fg);
  font: inherit; font-size: 15px; text-align: center;
}
.ask-slot span { font-size: 10.5px; color: var(--muted); letter-spacing: .02em; }
@media (hover: hover) and (pointer: fine) {
  .ask-slot:hover { border-color: var(--gold); color: var(--gold); }
  .ask-slot:hover span { color: var(--gold); }
  .ask-bstart:hover { filter: brightness(1.06); }
}
.ask-brow { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.ask-go2 {
  padding: 11px 20px; background: var(--gold); color: var(--on-gold);
  border: 0; font: inherit; font-size: 15px;
}
.ask-go2:disabled { opacity: .6; }

.kb-h3 {
  font-family: var(--font-display); font-weight: 400; font-size: 17px;
  margin: 22px 0 10px;
}


/* ---------- сторінка «ваш запис» ---------- */
#ticket { max-width: 640px; margin: 0 auto; padding: 30px var(--pad) 80px; }
.tk-card { border: 1px solid var(--gold); padding: 20px 18px; margin: 6px 0 20px; }
.tk-card.is-off { border-color: var(--line); opacity: .7; }
.tk-svc { display: block; font-weight: 400; font-size: 18px; }
.tk-when {
  margin: 8px 0 0; font-size: 26px; font-weight: 200; line-height: 1.25;
  font-family: var(--font-display);
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tk-card.is-off .tk-when { background: none; color: var(--muted); -webkit-text-fill-color: currentColor; }
.tk-note { margin: 12px 0 0; font-size: 14.5px; color: var(--fg-2); line-height: 1.5; }
.tk-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.tk-acts .btn { padding: 12px 20px; font-size: 14.5px; }
.tk-small { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0 0 26px; max-width: 54ch; }
.tk-move { border: 1px solid var(--line); padding: 18px 16px; margin-bottom: 26px; display: grid; gap: 10px; }
.tk-move .h2 { font-size: 22px; margin: 0; }
.tk-move .ask-day { margin-bottom: 2px; }
.tk-where { border-top: 1px solid var(--line); padding-top: 22px; }
.tk-where .h2 { font-size: 22px; margin: 0 0 10px; }
.tk-where p { margin: 0 0 16px; color: var(--fg-2); line-height: 1.6; }

/* Довжина волосся — три однакові кнопки перед годинами. */
.ask-len {
  flex: 1 1 auto; padding: 11px 12px; min-width: 92px;
  border: 1px solid var(--line); background: var(--surface); color: var(--fg);
  font: inherit; font-size: 14.5px; text-align: center;
}
@media (hover: hover) and (pointer: fine) {
  .ask-len:hover { border-color: var(--gold); color: var(--gold); }
}
/* Посилання на власний запис усередині картки «записала». */
a.ask-go2 { display: inline-block; text-align: center; text-decoration: none; }


/* ============================================================
   КАБІНЕТ: КЛІЄНТКИ, ВОРОНКА, ГРОШІ

   ⚠️ ЖОДНОГО ЖОРСТКОГО КОЛЬОРУ НИЖЧЕ. Усе на токенах, бо в
   денній темі --bg, --line і --gold міняються цілком: один
   вписаний #2E2A26 став би темною смугою на бірюзовому тлі.
   ============================================================ */

/* Підрейка «Сайту» — та сама пігулкова колія, але дрібніша: вона
   другого рівня, і однаковий розмір читався б як дві рівноправні
   навігації одна під одною. */
.kb-subrail { margin-top: 10px; margin-bottom: 22px; }
.kb-subrail .pill { padding: 8px 15px; font-size: 13px; }

/* ---------- «кому написати» ---------- */
.cl-tasks { border: 1px solid var(--gold); padding: 15px 15px 6px; margin: 0 0 24px; }
.cl-tasks > b { display: block; font-weight: 400; font-size: 16px; color: var(--gold); }
.cl-tasks .kb-note { margin: 5px 0 12px; }
.cl-task {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 12px;
  align-items: center; padding: 10px 0; border-top: 1px solid var(--line);
}
.cl-task-who { font-size: 15.5px; }
.cl-task i {
  grid-column: 1; font-style: normal; font-size: 13px;
  color: var(--muted); line-height: 1.45;
}
.cl-task-go { grid-row: 1 / 3; grid-column: 2; color: var(--gold); font-size: 13.5px; white-space: nowrap; }
.cl-more { font-size: 13px; color: var(--muted); margin: 12px 0 10px; border-top: 1px solid var(--line); padding-top: 11px; }

/* ---------- список клієнток ---------- */
.cl-find { display: block; margin: 0 0 16px; }

/* ⚠️ ВЕСЬ РЯДОК — КНОПКА, а не «стрілочка розгорнути» збоку.
   Це екран для великого пальця: ціль у 44 px по ширині картки
   влучається не дивлячись, а іконка в 16 px — ні. */
.cl-head {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; padding: 0; color: inherit; font: inherit;
}
.cl-head b { display: block; font-weight: 400; font-size: 16.5px; }
.cl-stage {
  display: inline-block; font-style: normal; font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase;
  border: 1px solid var(--line); padding: 3px 8px; margin-top: 6px; color: var(--muted);
}
/* Кольором виділені тільки ті три стани, через які треба щось
   робити. Решта — сірим: якби світилися всі сім, не світився б
   жоден. */
.cl-stage.is-regular { border-color: var(--gold); color: var(--gold); }
.cl-stage.is-sleeping { border-color: var(--warn); color: var(--warn); }
.cl-stage.is-lost { border-color: var(--warn); color: var(--warn); opacity: .75; }
/* ⚠️ ЗАМІРЯНО: удень чистий --warn (#B4553A) на бірюзовому дає
   4,33:1, а тут 11-й кегль — треба 4,5. Тому вдень колір беремо
   той самий, але глибший: похідна від токена, а не вписаний код,
   інакше зміна палітри розсинхронізує ці два рядки з рештою. */
:root[data-theme="day"] .cl-stage.is-sleeping,
:root[data-theme="day"] .cl-stage.is-lost {
  color: color-mix(in srgb, var(--warn) 80%, #000);
}
:root[data-theme="day"] .cl-stage.is-lost { opacity: .85; }
.cl-sum { display: block; font-size: 14px; color: var(--fg-2); margin-top: 6px; }
.cl-head > i { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 3px; }
.cl-due {
  display: inline-block; font-style: normal; font-size: 12.5px;
  color: var(--gold); margin-top: 7px;
}
.cl-row.is-open { box-shadow: inset 3px 0 0 var(--gold); }

/* ---------- картка ---------- */
.cl-card { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 15px; }
.cl-acts { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
.cl-acts .btn { padding: 10px 16px; font-size: 14px; }
.cl-card .kb-field { padding-left: 0; }
.cl-visits { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.cl-visit { background: var(--bg); padding: 11px 12px; }
.cl-visit span { font-size: 13px; color: var(--muted); }
.cl-visit b { display: block; font-weight: 400; font-size: 15px; margin-top: 2px; }
.cl-visit i { display: block; font-style: normal; font-size: 13px; color: var(--fg-2); margin-top: 2px; }
.cl-visit em { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.cl-visit.is-done { box-shadow: inset 3px 0 0 var(--ok); }
.cl-visit.is-no { box-shadow: inset 3px 0 0 var(--warn); }
.cl-visit.is-off { opacity: .55; }
.cl-card .kb-reset { margin-top: 16px; }

/* ---------- воронка ----------
   ⚠️ ГОРИЗОНТАЛЬНА ПРОКРУТКА, А НЕ СІМ КОЛОНОК У СІТЦІ. На
   телефоні сім колонок дають смужки по 50 px, у яких не влазить
   жодне ім'я. Тут колонка має живу ширину, а решта від'їжджає
   вбік — як полиці. */
.cl-funnel {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(190px, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  /* ⚠️ СМУГУ ПРОКРУТКИ ХОВАТИ НЕ МОЖНА — вона тут єдина ознака,
     що вбік є ще колонки. Але системна світла смуга на чорному
     світилась яскравіше за самі імена, тому фарбуємо її в токени. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.cl-funnel::-webkit-scrollbar { height: 8px; }
.cl-funnel::-webkit-scrollbar-track { background: transparent; }
.cl-funnel::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.cl-col { background: var(--bg); padding: 13px 12px; min-width: 0; }
.cl-col > b { display: block; font-weight: 400; font-size: 15px; }
.cl-col > b span { color: var(--gold); }
.cl-col > i {
  display: block; font-style: normal; font-size: 12px;
  color: var(--muted); line-height: 1.45; margin: 4px 0 10px;
}
.cl-col ul { list-style: none; margin: 0; padding: 0; }
.cl-col li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  padding: 7px 0; border-top: 1px solid var(--line);
}
.cl-col li button {
  background: none; border: 0; padding: 0; color: var(--fg); font: inherit;
  font-size: 14px; text-align: left; text-decoration: underline;
  text-decoration-color: var(--line); min-width: 0; overflow-wrap: anywhere;
}
@media (hover: hover) and (pointer: fine) { .cl-col li button:hover { color: var(--gold); } }
.cl-col li em { font-style: normal; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.cl-empty { font-size: 12.5px; color: var(--muted); margin: 0; }

/* ---------- гроші ---------- */
.mn-top {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--line); border: 1px solid var(--line); margin-bottom: 26px;
}
.mn-card { background: var(--bg); padding: 16px 14px; }
.mn-card b {
  display: block; font-family: var(--font-display); font-weight: 200; font-size: 26px;
  line-height: 1.15;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.mn-card i { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin-top: 5px; }

/* ⚠️ СТОВПЧИК — ЦЕ ЧАСТКА ВІД НАЙБІЛЬШОГО МІСЯЦЯ, А НЕ ГРОШІ.
   Сума завжди стоїть цифрою поруч: смужку неможливо прочитати
   точно, і без числа вона б лише натякала. */
.mn-row { display: grid; grid-template-columns: 1fr; gap: 6px; }
.mn-m { font-size: 15px; }
.mn-bar { height: 6px; background: var(--line); }
.mn-bar i { display: block; height: 100%; background: var(--gold); }
.mn-row b { font-weight: 400; font-size: 15px; }
.mn-row em { font-style: normal; font-size: 12.5px; color: var(--muted); margin-left: 8px; }

@media (min-width: 620px) {
  .mn-top { grid-template-columns: repeat(4, 1fr); }
  .mn-row { grid-template-columns: 1fr 2fr auto auto; align-items: center; gap: 4px 14px; }
  .mn-row em { margin-left: 0; }
}


/* ---------- відгуки на сайті ---------- */
.revs { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.rev { background: var(--bg); padding: 20px 18px; }
.rev-text { margin: 0; font-size: 16.5px; line-height: 1.6; color: var(--fg-2); }
.rev-who { margin: 12px 0 0; font-size: 13.5px; color: var(--muted); }
.rev-who b { font-weight: 400; color: var(--fg); }
.rev-who span { margin-left: 8px; }
.rev-who span::before { content: '\2009\00b7\2009'; }
/* Джерело — дрібним і сірим, але воно є завжди: саме воно робить
   обіцянку «не вигадую» перевірною. */
.rev-who i { display: block; font-style: normal; font-size: 12.5px; margin-top: 4px; letter-spacing: .02em; }
.rev-more { display: inline-block; margin-top: 18px; }

/* ---------- відгуки в кабінеті ---------- */
.rv-row.is-off { opacity: .55; }
.rv-text { margin: 0; font-size: 15px; line-height: 1.55; }
.rv-meta { margin: 8px 0 0; font-size: 13px; color: var(--muted); }
.rv-meta b { font-weight: 400; color: var(--fg-2); }
.rv-meta i, .rv-meta em { font-style: normal; }
.rv-row .kb-bacts { grid-column: auto; margin-top: 10px; }


/* ---------- картка блока в «Сторінках» ---------- */
/* ⚠️ Кант зліва, а не рамка навколо. Рамка на рамці (картка
   всередині акордеона всередині вкладки) дає три вкладені
   прямокутники — на телефоні від цього лишається смужка тексту
   посередині екрана. */
.kb-blk { border-left: 1px solid var(--line); padding-left: 13px; margin: 0 0 22px; }
.kb-blk-h { margin: 0 0 12px; }
.kb-blk-h b { display: block; font-weight: 400; font-size: 15px; color: var(--fg-2); }
.kb-blk-h i {
  display: block; font-style: normal; font-size: 11.5px; color: var(--muted);
  letter-spacing: .05em; text-transform: uppercase; margin-top: 3px;
}
.kb-quiet { margin-top: 4px; }

/* Пояснення про [П] — золотим кантом, як і сама риска на сайті. */
.kb-mark {
  border-left: 2px solid var(--gold); padding: 2px 0 2px 10px; margin: 8px 0 0;
  font-size: 12.5px; line-height: 1.5; color: var(--muted);
}
.kb-mark b { color: var(--gold); font-weight: 400; }

/* Кілька textarea підряд усередині одного поля-масиву. */
.kb-field textarea + textarea, .kb-field textarea + input, .kb-field input + textarea { margin-top: 8px; }


/* ============================================================
   ШАПКА КАБІНЕТУ

   ⚠️ Вузька смуга замість шапки сайту. Мірою тут не краса, а
   висота: на телефоні кожні зайві 100 px угорі — це один зайвий
   рух великим пальцем на КОЖНОМУ заході.
   ============================================================ */
.kb-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 12px 0 14px; border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.kb-brand {
  font-family: var(--font-display); font-weight: 300; font-size: 17px;
  letter-spacing: .01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-brand i {
  font-style: normal; color: var(--muted); font-size: 12px;
  letter-spacing: .12em; text-transform: uppercase; margin-left: 10px;
}
.kb-top-acts { display: flex; align-items: center; gap: 14px; flex: none; }
.kb-site { color: var(--muted); font-size: 13.5px; text-decoration: underline; }
@media (hover: hover) and (pointer: fine) { .kb-site:hover { color: var(--gold); } }
.kb-top .theme-tog { position: static; }

/* ⚠⚠ РЕЙКА ВКЛАДОК ЛИПНЕ ДО ВЕРХУ. Вона тут єдиний спосіб
   перейти кудись, а списки довгі: без цього після прокрутки до
   кінця «Сторінок» повернутись у «Записи» можна тільки
   прокрутивши все назад. Тло непрозоре — інакше під нею
   просвічували б поля. */
.kb-rail-stick {
  position: sticky; top: 0; z-index: 30;
  background: var(--bg); padding-top: 10px; padding-bottom: 10px;
  margin-top: 0;
}
.kb-subrail { position: sticky; top: 62px; z-index: 29; background: var(--bg); }

@media (max-width: 619px) {
  .kb-brand { font-size: 15px; }
  .kb-brand i { display: none; }
  .kb-top-acts { gap: 12px; }
}


/* ============================================================
   ШИРОКИЙ ЕКРАН

   ⚠️ ВІКТОРІЯ ПРАЦЮЄ З ТЕЛЕФОНА — і це не змінилось. Усе нижче
   лежить у медіа-запиті від 1100px і жодного разу не чіпає те, що
   вона бачить щодня. Комп'ютер вона відкриває зрідка, але тоді
   кабінет мусить користатись екраном, а не показувати телефонну
   смужку посеред порожнечі.

   ЗАМІРЯНО НА 1600px ДО ЦИХ ПРАВИЛ:
     колонка 900px, з боків пусто 701px — 44% екрана;
     «Ціни» 16022px = 17,8 екранів прокрутки на 61 позицію;
     «Сторінки» 8,2 екрана; «Клієнтки» 2,3;
     воронка не влазила навіть тут (треба 1336px, було 832px).
   ============================================================ */

@media (min-width: 1100px) {
  /* Ширше, але не на весь екран: рядок, довший за ~75 символів,
     читати вже незручно. Тому зайва ширина йде в ДРУГИЙ СТОВПЕЦЬ,
     а не в розтягування полів. */
  #kab { max-width: 1240px; }

  /* ⚠⚠ ГОЛОВНИЙ ЗЛОДІЙ ПРОКРУТКИ БУВ НЕ ТАМ, ДЕ ЗДАВАЛОСЬ.
     Три ціни стоять в один ряд, а «триває» — ОКРЕМИМ РЯДКОМ під
     ними, і праворуч від нього дві третини ширини порожні. Це
     ~90px на кожну з 61 позиції, тобто близько 5500px = шість
     екранів прокрутки на саму лише порожнечу.
     Тепер тривалість — четверта колонка того ж ряду. Селектор
     `[data-row]` навмисно: він стоїть ТІЛЬКИ на рядках прайсу, а
     клас .kb-row спільний ще з клієнтками, відгуками й записами. */
  .kb-row[data-row] {
    display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
    column-gap: 10px; align-items: start;
  }
  .kb-row[data-row] > .kb-row-h,
  .kb-row[data-row] > .kb-reset,
  .kb-row[data-row] > .kb-state { grid-column: 1 / -1; }
  /* ⚠️ У сітці елемент розтягується на всю комірку, і посилання
     «повернути як було» опинялось посеред картки, ніби заголовок.
     Воно приткнуте до лівого краю всюди, крім цього режиму. */
  .kb-row[data-row] > .kb-reset { justify-self: start; }
  .kb-row[data-row] > .kb-time { margin-top: 0; max-width: none; }

  /* Два стовпці там, де порядок читання не несе змісту. Саме
     column-count, а не grid: картки різної висоти, і сітка лишала б
     під короткими дірки. */
  .kb-rows-2, .kb-acc-b { column-count: 2; }
  .kb-rows-2 > .kb-row, .kb-blk, .kb-acc-b > .kb-field {
    break-inside: avoid; -webkit-column-break-inside: avoid;
  }
  /* ⚠️ У багатоколонковому режимі волосяна лінія між рядками
     більше не малюється проміжком сітки (gap:1px + тло) — вона
     просто зникає. Повертаємо її кантом. */
  /* ⚠⚠ `display: block` ТУТ ОБОВ'ЯЗКОВИЙ І НЕ ОЧЕВИДНИЙ.
     .kb-rows — це `display: grid`, а БАГАТОКОЛОНКОВА РОЗКЛАДКА НА
     СІТКОВОМУ КОНТЕЙНЕРІ НЕ ДІЄ ВЗАГАЛІ: `column-count` мовчки
     ігнорується. Заміряно — прайс лишався 18,1 екрана, тобто
     правило виглядало застосованим і не робило нічого. */
  .kb-rows-2 { display: block; background: var(--bg); gap: 0; column-gap: 1px; }
  .kb-rows-2 > .kb-row { border-bottom: 1px solid var(--line); }
  .kb-acc-b { column-gap: 34px; padding-top: 20px; }

  /* Рядок клієнтки на телефоні стоїть стовпчиком — там це правильно,
     тут марнотратно: 830px ширини під чотири короткі рядки. */
  .cl-head {
    display: grid; align-items: baseline;
    grid-template-columns: minmax(110px, 1fr) auto minmax(140px, 1fr);
    gap: 3px 14px;
  }
  .cl-head b { font-size: 15.5px; }
  .cl-stage { margin-top: 0; justify-self: start; }
  .cl-sum { margin-top: 0; }
  .cl-head > i, .cl-due { grid-column: 1 / -1; margin-top: 2px; }

  /* Сім щаблів воронки тепер влазять без горизонтальної прокрутки. */
  .cl-funnel { grid-auto-columns: minmax(150px, 1fr); }
  .cl-visits { grid-template-columns: 1fr 1fr; }

  /* ⚠️ ПОЛЕ ВВОДУ НЕ МУСИТЬ РОСТИ ЗА КОЛОНКОЮ. Заміряно: після
     розширення пошук клієнток розтягнувся на 1172px — це рядок на
     ~150 символів, у якому не видно ні початку, ні кінця того, що
     набираєш. Читабельна межа ~75 символів. */
  #kb-body .kb-field > input,
  #kb-body .kb-field > textarea,
  .cl-find input,
  .kb-form .inp input,
  .kb-form .inp textarea { max-width: 640px; }
}

@media (min-width: 1500px) {
  /* Третій стовпець — тільки прайсу: там картки короткі й однакові.
     У текстах він дав би стовпець вужчий за поле вводу. */
  .kb-price-rows { column-count: 3; }
  .kb-row[data-row] { grid-template-columns: 1fr; }
  .kb-row[data-row] > .kb-time { margin-top: 10px; }
}


/* ---------- картки помічника в кабінеті ---------- */
.kb-data { margin: 12px 0 4px; border: 1px solid var(--line); padding: 12px 14px; }
.kb-data > b { display: block; font-weight: 400; font-size: 14.5px; color: var(--gold); margin-bottom: 8px; }
.kb-data ul { list-style: none; margin: 0; padding: 0; }
.kb-data li { display: grid; grid-template-columns: 1fr; gap: 2px; padding: 8px 0; border-top: 1px solid var(--line); }
.kb-data li span { font-size: 12.5px; color: var(--muted); }
.kb-data li b { font-weight: 400; font-size: 15px; }
.kb-data li i { font-style: normal; font-size: 13px; color: var(--fg-2); }
.kb-data p { margin: 6px 0 0; font-size: 14px; line-height: 1.6; color: var(--fg-2); }
/* Картка запису від помічника: та сама форма, що й «Додати руками» —
   Вікторія бачить одне й те саме в обох місцях. */
.kb-abook { margin: 12px 0 4px; border: 1px solid var(--gold); padding: 14px 14px 12px; }
.kb-abook .inp { margin-bottom: 10px; }
.kb-abook .kb-triple { margin-bottom: 10px; }
.kb-abook .kb-abput { margin-top: 4px; padding: 11px 18px; font-size: 14px; }
/* Порожнє поле, яке сервер не зміг розібрати, — світиться, а не мовчить. */
.kb-abook .is-miss input, .kb-abook .is-miss select { border-color: var(--warn); }
.kb-abook .is-miss > span { color: var(--warn); }
@media (min-width: 620px) {
  .kb-data li { grid-template-columns: 200px 1fr auto; align-items: baseline; gap: 4px 14px; }
}


/* ---------- журнал: чесні стани ---------- */
.kab-done.is-bad { color: var(--warn); }
/* Запис, який уже зійшов із сайту: видно, що він там був, і видно, що його нема. */
.kab-list li.is-off .jtext { opacity: .55; }
.kab-list li.is-off .jkind { opacity: .55; }
.jgone { margin: 4px 0 0; font-size: 12.5px; color: var(--warn); }


/* ---------- пакетна правка: одна картка замість 58 ---------- */
.kb-pack { margin: 12px 0 4px; border: 1px solid var(--gold); padding: 12px 14px; }
.kb-pack > b { display: block; font-weight: 400; font-size: 14.5px; color: var(--gold); }
.kb-pack > em { display: block; font-style: normal; font-size: 12.5px; color: var(--muted); margin: 2px 0 8px; }
.kb-pack > i { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 8px; }
.kb-pack ul { list-style: none; margin: 0; padding: 0; }
.kb-pack li {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; align-items: baseline;
  padding: 8px 0; border-top: 1px solid var(--line); font-size: 14px;
}
.kb-pack li span { color: var(--fg-2); }
.kb-pack .kb-pv { grid-column: 1; font-weight: 400; }
.kb-pack .kb-pv s { color: var(--muted); }
/* Решта позицій згорнута: 58 рядків читаються як стіна, а не як список. */
.kb-pack li.is-more { display: none; }
.kb-pack.is-open li.is-more { display: grid; }
/* Виключена позиція лишається видимою — видно, що саме не поїде. */
.kb-pack li.is-off span, .kb-pack li.is-off .kb-pv { opacity: .4; text-decoration: line-through; }
.kb-pack .kb-packoff {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  background: none; border: 0; padding: 4px 0 4px 10px;
  color: var(--muted); font: inherit; font-size: 12.5px; cursor: pointer; text-decoration: underline;
}
.kb-pack .kb-packmore {
  display: block; margin-top: 8px; background: none; border: 0; padding: 4px 0;
  color: var(--gold); font: inherit; font-size: 13px; cursor: pointer; text-decoration: underline;
}
.kb-pack .kb-packapply { margin-top: 12px; padding: 11px 18px; font-size: 14px; }
/* Рядок історії про пакет: три приклади й скільки ще. */
.kb-hist li.is-pack .kb-hist-more { color: var(--muted); font-size: 12.5px; }


/* ---------- вітрина проти графіка: розбіжність видно ---------- */
.kb-gap { margin: 0 0 16px; border: 1px solid var(--warn); padding: 12px 14px; }
.kb-gap > b { display: block; font-weight: 400; font-size: 14.5px; color: var(--warn); margin-bottom: 6px; }
.kb-gap p { margin: 0 0 8px; font-size: 14px; line-height: 1.6; }
.kb-gap .kb-gap-note { color: var(--muted); font-size: 13px; }
.kb-gap .btn { margin-top: 2px; }
.kb-gap-acts { display: flex; flex-wrap: wrap; gap: 8px; }
/* Після натиску картка лишається на місці, але вже не тривожна. */
.kb-gap.is-done { border-color: var(--gold); }
.kb-gap.is-done > b { color: var(--gold); }


/* ---------- поле, яке збирається саме ---------- */
.kb-field-der { opacity: .9; }
.kb-der-val {
  margin: 0; padding: 11px 14px; border: 1px dashed var(--line);
  font-size: 15px; color: var(--fg-2);
}
.kb-der-note { margin: 6px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--muted); }

/* ============================================================
   ВКЛАДКА «ФОТО»

   ⚠️ ЖОДНОГО ЖОРСТКОГО КОЛЬОРУ Й ЖОДНОГО ЗАОКРУГЛЕННЯ: кабінет —
   це той самий сайт зсередини, і обидва тут ніде не вживаються.
   Поле вибору файла лежить УСЕРЕДИНІ .kb-field навмисно — саме
   там воно отримує колір із загального правила вище. Поставлене
   поруч, воно в денній темі малювалось би майже білим по білому,
   і скріншот цього не показує.
   ============================================================ */
.kb-shot {
  display: block; width: 100%; max-width: 190px; height: auto;
  border: 1px solid var(--line); margin: 0 0 12px;
  background: var(--surface);
  /* ⚠️ ПІДЛОГА, ЩОБ ЕСКІЗ НЕ СХЛОПУВАВСЯ ДО ЗАВАНТАЖЕННЯ.
     У завантаженого ролика розміру в даних немає взагалі (ми читаємо
     розмір лише в картинок), тому до приїзду метаданих висота була б
     нульова. aspect-ratio тут не можна: вона перебила б справжні
     пропорції вже завантаженого файла й розтягла кадр. */
  min-height: 60px;
}
/* ⚠️ Кнопка всередині поля вибору — власне правило, бо `font:
   inherit` на сам input її НЕ дістає: у більшості рушіїв вона
   лишається системною й у денній темі стає сірою на сірому. */
.kb-field input[type="file"] { padding: 9px 10px; line-height: 1.3; }
.kb-field input[type="file"]::file-selector-button {
  background: none; border: 1px solid var(--line); color: var(--fg-2);
  font: inherit; font-size: 13px; padding: 5px 12px; margin-right: 11px;
}
@media (hover: hover) and (pointer: fine) {
  .kb-field input[type="file"]::file-selector-button:hover { color: var(--gold); border-color: var(--gold); }
}
.kb-field input[type="file"]:disabled { opacity: .55; }

/* ============================================================
   ВКЛАДКА «ЯК ЦЕ ПРАЦЮЄ»

   ⚠️ Тут довгий текст, а не поля. Тому єдине, чого йому треба, —
   ширина рядка й повітря між абзацами: суцільна колонка на весь
   монітор не читається. Кольорів своїх немає, як і всюди в
   кабінеті.
   ============================================================ */
.kb-help {
  max-width: 62ch;
  /* ⚠️⚠️ ОДНА КОЛОНКА, І ЦЕ НЕ ДРІБНИЦЯ. Загальне правило кабінету
     ріже вміст акордеона на дві колонки від 1100px — і для полів
     форми це правильно, бо порядок читання там не несе змісту.
     Але тут суцільний текст: у дві колонки його доводиться читати
     вниз, потім стрибати вгору й читати вниз ще раз. Заміряно
     очима на проді — саме так воно й виглядало. */
  column-count: 1;
}
.kb-help p { margin: 0 0 13px; font-size: 15px; line-height: 1.62; color: var(--fg-2); }
.kb-help p:last-child { margin-bottom: 0; }
.kb-help b { color: var(--fg); font-weight: 400; }
.kb-help u { text-decoration-color: var(--gold); text-underline-offset: 3px; }
.kb-ul { margin: 0 0 13px; padding-left: 18px; }
.kb-ul li {
  margin: 0 0 8px; font-size: 15px; line-height: 1.6; color: var(--fg-2);
  /* ⚠️ Маркер списку кольором тексту, а не золотом: золото в цьому
     сайті бюджетоване й стоїть лише на кінцівках — ціна, активний
     перемикач, риска чернетки. Розлите по списках, воно дешевіє. */
}
.kb-ul li::marker { color: var(--muted); }
.kb-help .kb-mark { margin: 13px 0; }
