/* ══════════════════════════════════════════════════════════════════════
   ТИПОГРАФІКА: IBM Plex Sans + IBM Plex Mono
   ТЗ everheat-typography-tz-v3, кроки 1 і 2. Крок 3 (герой) не тут:
   він чекає на затверджені скорочені тексти, див. розд. 4.1 ТЗ.

   ⚠️ ЧОМУ ТУТ, А НЕ В main.css. main.css генерується _build/build.sh
   з прототипу - усе, дописане туди руками, зникає при наступному прогоні.
   Цей файл підключається після нього, тому :root нижче перебиває
   --font-body за правилом «за однакової специфічності виграє нижче».

   Ubuntu лишається у @font-face main.css, але не вживається: --font-body
   перевизначено. Файли ubuntu-*.woff2 НЕ ВИДАЛЯТИ до кінця перевірки -
   на них тримається відкат (розд. 11 ТЗ).

   ⚠️ format('woff2'), а НЕ 'woff2-variations'. Останній - проміжний
   проєкт специфікації; невідомий format() змушує браузер пропустити
   ВЕСЬ src, і шрифт тихо не вантажиться.

   ⚠️ OFL.txt лежить поруч у assets/fonts/ - самохостинг Plex є
   редистрибуцією, і SIL OFL 1.1 цього вимагає.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ВІДХИЛЕННЯ ВІД ТЗ 3.2: MONO СТАТИКОЮ, А НЕ ВАРІАТИВНИМ.
   ТЗ передбачав два варіативні файли. Перевірено: варіативного
   IBM Plex Mono НЕ ІСНУЄ - ні в дистрибутиві IBM (release
   @ibm/plex-sans@1.1.0 і теки packages/plex-mono/fonts/complete містять
   лише статику), ні в Google Fonts (віддає окремі 400/600/700).
   Варіативний є лише в Plex Sans.

   Виміряно, які ваги моно реально потрібні на 10 сторінках:
     400  .nav-head-label, .ct-label, .cp-mini, .pf-label, .ms-coords
     600  .tp-num, .rv-count
     700  решта міток і чисел
   Тому рівно три файли. Разом 45 236 Б - менше, ніж важив би один
   варіативний, тож на вазі це не програш. */
@font-face{
  font-family:'IBM Plex Sans'; font-style:normal;
  font-weight:400 700; font-display:swap;
  src:url('../fonts/plex-sans-var.woff2') format('woff2');
  /* Той самий діапазон, що був у Ubuntu. ★ (U+2605) навмисно поза ним:
     зірки рейтингу малює системний шрифт, і так має лишитись. */
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
                U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,
                U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal;
  font-weight:400; font-display:swap;
  src:url('../fonts/plex-mono-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
                U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,
                U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal;
  font-weight:600; font-display:swap;
  src:url('../fonts/plex-mono-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
                U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,
                U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal;
  font-weight:700; font-display:swap;
  src:url('../fonts/plex-mono-700.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
                U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,
                U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ⚠️ ФОЛБЕК ІЗ ПІДІГНАНОЮ МЕТРИКОЮ - оптимізація, не умова роботи.
   Вмикати лише після того, як числа пораховано інструментом
   (fallback-font-generator або fontaine), а не вгадано. Поки закоментовано.
@font-face{
  font-family:'Plex Fallback'; src:local('Arial');
  size-adjust:105%; ascent-override:90%; descent-override:22%; line-gap-override:0%;
}
*/

:root{
  --font-body:'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* Назва саме --font-mono, а не --font-display: останнє збігається
     з дескриптором font-display і плутає при читанні файлу. */
  --font-mono:'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── Контроли форм не успадковують шрифт ───────────────────
   ⚠️ Кнопки й поля вводу беруть шрифт не від сторінки, а від браузера:
   UA-стилі задають їм власний font-family (у Chrome це Arial), і він
   не успадковується. Тема лагодила це точково, шорткатом `font: inherit`,
   лише на 11 контролях (ТЗ типографіки, розд. 6.2).

   Виміряно на живій головній ДО правки: 18 контролів малювались
   Arial, 18 - Plex Sans. По всьому сайту: 692 елементи з 12 955.
   Найпомітніше: <button class="btn"> стояв поруч із <a class="btn">,
   виглядали однаково, а шрифт мали різний. З Ubuntu було те саме,
   просто ніхто не міряв.

   Успадковуємо ТІЛЬКИ родину. Кегль і вагу не чіпаємо: їх задають
   власні правила теми, і зміна тут поїхала б по всіх формах.
   Селектор елементний (0,0,1), тому будь-яке класове правило теми
   його перебиває - це саме те, чого треба. */
button, input, select, textarea, optgroup{ font-family: inherit; }

/* Єдиний <code> на сайті (/privacy-policy/) малювався системним
   моноширинним. Ставимо той самий Plex Mono, що й решта моно. */
code, kbd, samp, pre{ font-family: var(--font-mono); }

/* ── Шар 1: технічні мітки ──────────────────────────────────────────
   Розрядка зменшена з .06-.1em до .045em: ті значення компенсували
   тісний uppercase Ubuntu, а моно вже широкий.

   ⚠️ table.price-table th нижче 700px має власну letter-spacing:.01em
   (цей же файл, нижче). Воно стоїть НИЖЧЕ і виграє - навмисно: на
   телефоні заголовки мають бути тіснішими. */
.nav-head-label, .case-system, .case-facts dt, .cred-label, .team-role,
.rv-label, .cm-price span, .calc-total .ct-label, .product-price .pf-label,
.calc-cta__price, .offer-badge, table.price-table th, .cp-demo{
  font-family: var(--font-mono);
  letter-spacing:.045em;
}
@media (max-width:1000px){
  .cp-title{ font-family: var(--font-mono); letter-spacing:.045em; }
}

/* ⚠️ КЕГЛЬ .cp-demo ЗАДАНО НЕ ТУТ, А В БЛОЦІ .cp-demo НИЖЧЕ В ЦЬОМУ Ж ФАЙЛІ.
   Тут стояло `.cp-demo{ font-size:.66rem }` за ТЗ 5.1, і воно НЕ ДІЯЛО:
   нижній блок має ту саму специфічність (0,1,0) і виграє за порядком.
   Виміряно на живій сторінці: computed font-size лишався 9.92px = .62rem.
   Щоб джерело правди було одне, значення перенесено в той блок. */

/* .eyebrow (kicker) увімкнений нижче, у розділі «РОЛЬ 3». */

/* ── РОЛЬ 2: число ─────────────────────────────────────────
   Ітемізований кошторис - головний аргумент сайту. Цифри моно
   табулярні за визначенням, тож суми в стовпці вирівнюються самі.

   ⚠️ .calc-lines li b ОБОВ'ЯЗКОВИЙ. Без нього в одній панелі підсумок
   (.ct-value) моно, а позиції кошторису над ним - Sans. Виміряно на
   /instant-estimate/ до правки: `.calc-lines li b` = Sans. Два шрифти
   в одному стовпці сум - найпомітніший розрив у всій схемі. ТЗ v4, розд. 1.2.

   tabular-nums у .ts-num/.tp-num/.rv-count/.wiz-count лишаємо як
   страховку, поки шрифт ще не завантажився. */
.equip-price span, .cm-price b, .cp-mini, .cred-value, .calc-total .ct-value,
.product-price b, .calc-cta__price b, td.price-cell, .cm-discount b,
.calc-lines li b,
.ts-num, .tp-num, .rv-count, .wiz-count,
.map-slot .ms-coords{        /* ← єдиний моно на сайті замість ui-monospace */
  font-family: var(--font-mono);
}
/* Від'ємна розрядка ТІЛЬКИ для великих чисел. .cred-value включений
   окремо: у main.css він має власну .02em, і без цього рядка лишився б
   єдиним великим числом із ПОЗИТИВНОЮ розрядкою. */
.calc-total .ct-value, .product-price b, .calc-cta__price b, .cm-price b{
  letter-spacing:-.02em;
}
.cred-value{ letter-spacing:0; }

/* Значення в .calc-spec - це ТЕКСТ, а не число («Replacement of an
   existing system», «Up to 1,000 sq ft»). Правило `.calc-lines li b` вище
   зачепило б їх разом із сумами, тому повертаємо явно.
   Специфічність (0,2,2) проти (0,1,2), тож порядок тут не вирішує. */
.calc-lines li.calc-spec b{ font-family: var(--font-body); }

/* ── РОЛЬ 3: kicker ───────────────────────────────────────
   Підпис над заголовком секції. У редакціях 1-3 був вимкнений,
   у v4 вмикається навмисно (ТЗ v4, розд. 4 і 7).

   Причина: геройські правила скоповані до .hero, а на 24 шаблонах
   із .services-hero героя немає взагалі (перевірено по розмітці всіх
   37 сторінок: .hero на 11, .services-hero на 24, ні того ні того на 2).
   Без kicker'а на цих 24 сторінках моно з'являється лише в панелі
   калькулятора й читається як випадковість. Kicker повертає системність:
   згори кожної секції моно-підпис, під ним Sans-заголовок.

   .9rem замість .95rem - компенсація ширини моно, щоб рядок
   лишився тієї самої довжини, що й досі. */
.eyebrow{
  font-family: var(--font-mono);
  font-size:.9rem;
  letter-spacing:.045em;
}

/* ⚠️ .calc-cta__price b ПРОСИТЬ ВАГУ 900, ЯКОЇ В PLEX MONO НЕМАЄ.
   Виміряно на живих сторінках: computed font-weight = 900, а найважче
   накреслення Plex Mono - 700. Браузер домалює штучний жир поверх і без
   того жирного моно, і цифра ціни «замилюється».
   З Ubuntu цього не було видно, бо там 900 теж клампився, але на ширші
   штрихи гуманістичного шрифту це лягало непомітно.
   Ставимо 700 явно: візуально це те саме накреслення, але мальоване
   шрифтом, а не синтезоване. */
.calc-cta__price b{ font-weight:700; }


/* ══════════════════════════════════════════════════════════════════════
   ДОДАТКОВІ СТИЛІ ТЕМИ, ЯКИХ НЕМАЄ В ПРОТОТИПІ

   ⚠️ ЧОМУ ОКРЕМИЙ ФАЙЛ. assets/css/main.css збирається з прототипу через
   _build/build.sh. Усе, дописане туди руками, зникає при наступному
   прогоні. Правила, що з'явились уже у WordPress-версії, живуть тут.

   Підключається в inc/enqueue.php одразу після main.css.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Безцінові позиції в панелі «Your Price» ──────────────────────────
   Людина ставить галочки «What types of systems?», і доти панель про це
   мовчала: вона малює лише рядки з сумою, а це питання на суму не впливає
   (так і підписано). Виходило, що вибір нікуди не дівся - але й ніде не
   підтверджувався.

   ⚠️ ОКРЕМИЙ ВИГЛЯД, А НЕ ЩЕ ОДИН РЯДОК ІЗ ЦІНОЮ.
   .calc-lines li - це flex із space-between, а b має white-space:nowrap
   під короткі суми. Перелік із чотирьох систем у такому рядку просто
   вилазить за край панелі. Тому спец-рядок розкладається у два рівні:
   підпис зверху, значення під ним, з переносом. */
/* ⚠️ ОДНОРЯДКОВО, ЯК І ЦІНОВІ ПОЗИЦІЇ.
   Спершу я розкладав спец-рядок у два рівні (підпис зверху, значення під
   ним). На пʼяти відповідях ремонту це давало 59px на рядок і розганяло
   панель до 860px при екрані 900 - а вона sticky, тож низ із кнопкою
   «Book Diagnostic Visit» опинявся за межами екрана і прокруткою не
   діставався.

   Тому лишаємо звичайний рядок панелі й міняємо рівно те, що заважає:
   дозволяємо ПЕРЕНОС значення. Короткі відповіді лишаються в один рядок,
   довгий перелік систем переноситься, замість вилазити за край. */
.calc-lines li.calc-spec {
  align-items: baseline;
}

.calc-lines li.calc-spec span {
  flex: 0 1 auto;
  opacity: .70;
}

.calc-lines li.calc-spec b {
  white-space: normal;   /* переважує nowrap із main.css */
  text-align: right;
  line-height: 1.4;
  font-weight: 600;
}

/* ══════════════════════════════════════════════════════════════════════
   ПРОПОРЦІЇ ШАПКИ: логотип більший, кнопки менш розпертi

   Виміряно на 1500px ДО правки:
     шапка 79px · логотип 38px (48% висоти) · кнопки 55px (padding 14/26)

   Кнопка 55px у шапці 79px лишає по 12px повітря згори й знизу - звідси
   відчуття, що все розперте. А логотип на 38px читається як дрібна іконка
   поруч із великими кнопками.

   ⚠️ НІЖЧЕ 641px НЕ ЧІПАЄМО. Там шапка 65px, кнопки 44-45px і бургер 44px -
   це рівно мінімум для пальця, зменшувати нічого не можна.

   ⚠️ ОДИН ПОРІГ НА ВСЕ - 641px. Спершу я зменшив шапку від 641, а кнопки
   лише від 901: на 800px вийшла шапка 71px із кнопкою 54px, тобто 8px
   повітря. Висота й вміст мусять мінятися разом, інакше проміжний діапазон
   лишається зіпсованим - і саме його ніхто не перевіряє.
   ══════════════════════════════════════════════════════════════════════ */
@media (min-width: 641px) {

  /* Висота шапки задана ОДНІЄЮ змінною (main.css:88) і вживається рівно у
     двох місцях: контейнер шапки і `top` мобільної панелі меню. У JS її
     немає - перевірено, тому міняти безпечно. */
  :root { --header-h: 70px; }

  /* Кнопки шапки - другорядні за розміром: головна дія на сторінці, а не
     в навігації. 11/20 дає ~47px замість 55px. */
  .site-header .btn {
    padding: 11px 20px;
    font-size: .95rem;
  }

  /* Герой лишається помітнішим за шапку, але без надміру: 13/24 -> ~52px. */
  .hero .btn {
    padding: 13px 24px;
  }
}

/* ── Розмір логотипа ──────────────────────────────────────────────────
   60px - вибір власника, перевірений ним у DevTools. Логотип квадратний,
   тож це і висота, і ширина.

   ⚠️ max-width на вузьких екранах лишається запобіжником: якщо колись
   поставлять ГОРИЗОНТАЛЬНИЙ логотип (знак + напис), при height:60px він
   розтягнеться вшир і виштовхне кнопку з бургером за край. 170px - межа,
   за якою на 375px місця вже не лишається. */
@media (min-width: 901px) {
  .logo-img { height: 60px; }
}

@media (max-width: 900px) {
  .logo-img {
    height: 60px;
    max-width: 170px;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   ЦІНОВІ ТАБЛИЦІ НА ТЕЛЕФОНІ

   Скарга: не зрозуміло, що це таблиця і що її можна гортати.

   Виміряно на 390px: КОЖНА таблиця рівно 560px у контейнері 356px, тобто
   204px приховано - і це не залежить від кількості колонок. Навіть
   двоколонкова «Efficiency | Price», яка вільно вмістилася б, однаково
   виїжджає за край.

   Причина не в контенті: main.css задає `min-width: 560px` усім таблицям
   плюс `white-space: nowrap` комірці з ціною (діапазон «$3,200 – $6,400»
   через це не переноситься і тягне колонку вшир).

   ⚠️ ЛІКУЄМО ПРИЧИНУ, А НЕ СИМПТОМ. Підказка «гортайте вбік» була б
   відповіддю на питання, якого не мало виникнути: більшість таблиць
   поміщаються, щойно зняти штучну ширину.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {

  /* Ширину визначає вміст, а не константа з десктопа. */
  table.price-table { min-width: 0; }

  /* 14/20 - десктопні відступи. На 356px вони з'їдають третину рядка. */
  table.price-table th,
  table.price-table td {
    padding: 10px 12px;
    font-size: .88rem;
  }

  table.price-table th {
    font-size: .72rem;
    letter-spacing: .01em;
  }

  /* ⚠️ Головне: діапазон мусить мати право перенестись.
     Рядок «$3,200 – $6,400» у nowrap вимагає ~150px однією стрічкою. */
  table.price-table td.price-cell { white-space: normal; }
}

/* ══════════════════════════════════════════════════════════════════════
   СМУГА ХЛІБНИХ КРИХТ

   Скарга: «великі відступи між хедером і хлібними крихтами».

   Виміряно на живій сторінці (1440px і 375px - однаково):
     смуга 62px на 21px тексту · 29px НАД текстом · 11px ПІД ним

   ⚠️ ПРИЧИНА - ДВА ПРАВИЛА, НАПИСАНІ В РІЗНИЙ ЧАС, ЩО СКЛАЛИСЬ.
   `.breadcrumbs{ padding:18px 0 0 }` - давній «повітряний» відступ.
   `.breadcrumbs a{ min-height:44px }` - пізніша правка на розмір пальця;
   вона сама додає по ~11px зверху й знизу від тексту. 18 + 11 = 29 згори
   проти 11 знизу. Звідси і висота, і перекіс: смуга ніби «провисає» під
   хедером.

   ⚠️ 44px НЕ ЧІПАЄМО - це ціль для пальця, а не оформлення. Прибираємо
   рівно зайве: власний padding смуги. Тоді її висотою стає сама кнопкова
   зона, і текст опиняється точно посередині: 11 / 12.
   ══════════════════════════════════════════════════════════════════════ */
.breadcrumbs {
  padding: 0;

  /* ⚠️ Смуга мусить бути СМУГОЮ, а не текстом у порожнечі.
     Білі крихти на білому тлі під білим хедером не мають межі, тому
     проміжок і читався як «дірка»: оку немає за що зачепитись. Власний
     тон плюс волосяна лінія знизу роблять із них окремий рівень. */
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);

  /* ⚠️ Помаранчевий - ТІЛЬКИ роздільники «/».
     Це єдиний елемент смуги, який нічого не означає: структуру несуть
     розмітка й aria, а «/» - чиста декорація. Тому колір тут ні з чим не
     конфліктує.

     Узятий не фірмовий #F5821F, а глибший бурштин --color-star: на цьому
     тлі перший дає 2.44:1, другий - 4.61:1. Для тексту 13.6px поріг 4.5:1,
     тож фірмовий не проходить, і це не питання смаку.

     Посилання й поточна сторінка мають власні кольори нижче, тож цей
     рядок фарбує саме роздільники - вони єдині успадковують колір. */
  color: var(--color-star);
}

/* Клас .container тут спільний із рештою сайту, тож бічні відступи й
   максимальна ширина лишаються ті самі - міняємо лише розкладку в рядок.
   Текстові вузли «/» у flex стають анонімними елементами, тому проміжок
   між ланками задається через gap, а не пробілами розмітки. */
.breadcrumbs .container {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 6px;
  min-height: 44px;   /* запобіжник: смуга не схлопнеться без посилань */
}

/* ⚠️ Синій, а не сірий: посилання мають виглядати як посилання.
   --color-blue (#1E77D6) на цьому тлі дає 4.24:1 - нижче порога, тому
   беремо --color-blue-dark: 7.50:1. */
.breadcrumbs a { color: var(--color-blue-dark); }

.breadcrumbs span[aria-current] {
  color: var(--color-text);
  font-weight: 600;
}

/* ══════════════════════════════════════════════════════════════════════
   ВІДСТУП ПІД КРИХТАМИ: БУЛО ТРИ ЧИСЛА, СТАЄ ДВА

   Виміряно на живому сайті - проміжок від тексту крихт до першого вмісту:

     .services-hero   24 шаблони   55px   (padding-top 44)
     .person-hero      3 шаблони   45px   (padding-top 34)
     .hero + фото     10 шаблонів  75px   (padding-top 64)

   Три різні значення ніхто не задумував: це просто три класи, написані
   окремо. Зводимо перші два до спільного 36px.

   ⚠️ ГЕРОЙ ІЗ ФОНОВИМ ФОТО НАВМИСНО ЛИШАЄТЬСЯ БІЛЬШИМ.
   Там 64px - це не відступ під крихтами, а поле всередині фотосмуги:
   текст, притиснутий до її верхнього краю, читається як помилка верстки.
   Зрівняти заради однакового числа означало б зіпсувати те, заради чого
   фон вмикали. Значення живе в hero-bg.css і навмисно не чіпається тут. */
.services-hero { padding-top: 36px; }
.person-hero   { padding-top: 36px; }

/* ══════════════════════════════════════════════════════════════════════
   СЕКЦІЙНИЙ РИТМ НА ТЕЛЕФОНІ

   Знайдено під час обходу: `.section{ padding:72px 0 }` не має ЖОДНОГО
   мобільного перевизначення. На 375×667 два сусідні блоки дають
   72 + 72 = 144px порожнечі - 22% екрана між абзацами змісту.

   Виміряно на /pricing/ при 375px: 7 секцій, 864px самих лише вертикальних
   відступів на сторінці 11 622px (7,4%).

   ⚠️ ЦЕ НЕДОГЛЯД, А НЕ РІШЕННЯ - і це видно з самого файлу: сусідня
   `.section--tight` мобільне зменшення МАЄ (44 -> 32px на ≤640px), базова
   `.section` - ні. Хтось зменшив варіант і не зменшив основу.

   ⚠️ ОНОВЛЕНО 21.09.2026. Спершу тут стояло 52px, виведені з пропорції
   --tight при десктопній базі 72px. Потім власник назвав число для
   десктопа: проміжок між секціями 96px, тобто padding 48px.

   Мобільне значення перераховано від нової бази тією самою пропорцією
   (52/72 ≈ 0.72): 48 × 0.72 ≈ 34. Взято 32px - рівне число й зручний
   проміжок 64px.

   ⚠️ Мобільний відступ МУСИТЬ лишатись меншим за десктопний. Якби я
   лишив 52px при новій базі 48px, телефон отримав би 104px проміжку
   проти 96px на десктопі - на вужчому екрані порожнечі було б більше,
   ніж на ширшому. Саме такі перевернуті пари й народжуються, коли
   правлять одне значення й не дивляться на сусіднє. */
@media (max-width: 640px) {
  .section { padding: 32px 0; }
}

/* ── Знижка у вікні «Schedule My Visit» ───────────────────────────────
   Рядок додає calculator.js, коли знижка діє (лише реальні гілки з
   діапазоном). Оформлення повторює .cm-price, але тихіше: головне число
   лишається головним, знижка - уточненням під ним, а не другим заголовком,
   з яким перше сперечається за увагу. */
.cm-discount {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--color-border);
}

.cm-discount span {
  font-size: .8rem;
  font-weight: 600;
  color: var(--color-text-secondary);
}

/* Зелений «вигода», а не помаранчевий CTA: помаранчевий у цьому вікні вже
   належить кнопці відправки, і другий такий акцент відбирає в неї увагу. */
.cm-discount b {
  font-size: 1.05rem;
  color: var(--color-success-text);
  white-space: nowrap;
}

/* На вузькому екрані підпис і сума в один рядок не вміщаються: підпис
   «First-time customer, 10% off» сам по собі займає ~215px. */
@media (max-width: 420px) {
  .cm-discount { display: block; }
  .cm-discount b { display: block; margin-top: 2px; }
}


/* ── Мітка демо-прайсу у згорнутій смузі ──────────────────────────────
   Виміряно на 390px: у згорнутому стані було видно "$150 – $700" і нічого
   більше - попередження "Demo pricing..." лежить у тілі панелі, яке на
   телефоні закрите. На десктопі обидва видно, тож проблема існувала рівно
   там, де сайт і дивляться найчастіше.

   ⚠️ Не червона і не велика. Це службова позначка стану, а не помилка й не
   акція: їй досить бути помітною поруч із сумою. */
.cp-demo {
  /* .66rem, а не .62rem: у Plex Mono x-height менша за Ubuntu, і на 9.9px
     мітка ставала помітно дрібнішою за попередню. ТЗ типографіки, розд. 5.1. */
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 2px 6px;
  margin-left: 8px;
  border-radius: 3px;
  white-space: nowrap;
  background: var(--color-warning-bg);
  color: #6B4A00;
  border: 1px solid var(--color-warning);
}

/* ══════════════════════════════════════════════════════════════════════
   СЛОТИ КАРТОК, У ЯКИХ УЖЕ Є ФОТО

   ⚠️ ЦЕ ВИПРАВЛЕННЯ ЖИВОГО ДЕФЕКТУ, А НЕ ОФОРМЛЕННЯ.
   У main.css є правила .rc-shot.has-photo, .card-shot.has-photo і сусідні.
   Клас has-photo у розмітку не додає НІХТО: everheat_slot() друкує
   <img class="eh-photo"> усередину слота і на сам слот класів не вішає.
   Поки фото на сайті не було, дефект не проявлявся. Щойно запасне фото
   приїхало, кожна картка малює знімок УСЕРЕДИНІ мальованої заглушки.

   Виміряно на живій головній (1280×900, 15.09.2026):

     .card-shot   рамка 359×248, фото 327×215  - поля 16px + пунктир
     .equip-shot  рамка 213×148, фото 193×127  - поля 10px + пунктир
     .rc-shot     рамка 258×178, фото 238×156  - поля 10px + пунктир

   Тобто по периметру кожного знімка видно блакитну заливку заглушки і
   пунктирну лінію знизу. У main.css таке правило є, але лише для
   .photo-slot - тому герой виглядає правильно, а картки ні.

   Ловимо станом самого слота через :has(), без класів і без правок у 31
   файлі шаблонів. Стара версія правил із has-photo лишається недоторканою:
   два способи не конфліктують.
   ══════════════════════════════════════════════════════════════════════ */

.card-shot:has(.eh-photo),
.equip-shot:has(.eh-photo),
.rc-shot:has(.eh-photo),
.cs-inner:has(.eh-photo) {
  padding: 0;
  border: 0;
  background: none;
  overflow: hidden;
  gap: 0;
}

/* ⚠️ border-radius успадковуємо від слота, а не задаємо числом:
   у .card-shot заокруглені ЛИШЕ верхні кути (картка), у .photo-slot -
   усі чотири. Одне число зіпсувало б один із двох випадків. */
.card-shot:has(.eh-photo) .eh-photo,
.equip-shot:has(.eh-photo) .eh-photo,
.rc-shot:has(.eh-photo) .eh-photo,
.cs-inner:has(.eh-photo) .eh-photo,
.photo-slot:has(.eh-photo) .eh-photo,
.person-photo:has(.eh-photo) .eh-photo {
  border-radius: inherit;
}

/* main.css знімає з цих двох padding і рамку, але не обрізає вміст. */
.photo-slot:has(.eh-photo),
.person-photo:has(.eh-photo) {
  overflow: hidden;
}


/* ══════════════════════════════════════════════════════════════════════
   ВІДГУКИ БЕЗ ТЕКСТУ

   На Google Maps у компанії 99 відгуків, і лише 83 з них мають написаний
   текст. Решта 16 це чиста оцінка зірками. Доти сайт показував тільки
   письмові й усюди писав 83, тож число на сайті розходилось із числом,
   яке людина бачить у Google. Рішення власника: показувати всі 99.

   Картка навмисно НИЖЧА і тихіша за звичайну: вона несе менше інформації,
   і якби виглядала однаково, сітка читалась би як набір порожніх карток.
   ══════════════════════════════════════════════════════════════════════ */
.rv-card--rating{
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  /* Звичайна картка тримається на тексті відгуку; тут тексту немає, тому
     висоту задаємо явно, інакше в сітці вона схлопнеться до висоти зірок. */
  min-height: 132px;
  background: var(--color-surface);
  border-style: dashed;
}
.rv-notext{
  margin: 0;
  font-size: .88rem;
  color: var(--color-text-secondary);
}


/* ══════════════════════════════════════════════════════════════════════
   ГАЛЕРЕЯ РЕАЛЬНИХ РОБІТ на /portfolio/

   Знімків близько шістдесяти, тож сітка мусить бути щільною і не
   розганяти сторінку. Співвідношення 3:2 задано жорстко: усі файли
   підрізані під нього заздалегідь, і aspect-ratio тут страхує від
   стрибка макета, поки зображення ще не завантажилось.
   ══════════════════════════════════════════════════════════════════════ */
/* ⚠️ КОЛОНКИ, А НЕ GRID, І ЖОДНОГО aspect-ratio НА ПЛИТЦІ.
   Було: grid із жорсткими 3:2. Виміряно на /products/furnaces/ - плитка
   317×212 при натуральних 317×211, тобто CSS нічого не різав, різав сам
   файл: печі й повітрообробники зняті вертикально (960×1280), а майстер
   збережено смугою 3:2, і верх апарата був відрізаний назавжди.
   Тринадцять таких кадрів перерізано з оригіналів у 3:4, і тепер плитка
   мусить уміти бути різної висоти. Колонки дають це без обрізки взагалі:
   висока піч лишається високою, зовнішній блок - широким.
   ⚠️ Стрибка макета це не додає: WordPress друкує width/height на <img>,
   тому браузер резервує місце ще до завантаження. */
.shots-grid{
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 240px 4;
  column-gap: 12px;
}
.shots-item{
  margin: 0 0 12px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--color-border);
  /* Без цього колонка розриває плитку навпіл між колонками. */
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
}
.shots-img{
  width: 100%;
  height: auto;
  display: block;
  /* Легке збільшення при наведенні: знімок читається як клікабельний
     об'єкт, хоча посилання під ним немає. Перехід короткий, щоб сітка
     з шістдесяти карток не здавалась «желейною». */
  transition: transform .25s ease;
}
.shots-item:hover .shots-img{ transform: scale(1.03); }

@media (prefers-reduced-motion: reduce){
  .shots-img{ transition: none; }
  .shots-item:hover .shots-img{ transform: none; }
}

/* ⚠️ БЕЗ ЦЬОГО ПРАВИЛА ПОЕТАПНИЙ ПОКАЗ НЕ ПРАЦЮЄ ВЗАГАЛІ.
   lightbox.js вішає .shots-item--more на зайві плитки й малює кнопку
   «Show all N photos», але правила не існувало: на /portfolio/ клас мали
   82 плитки, приховано було 0, сторінка лишалась 17 332px. Кнопка при
   цьому малювалась і виглядала робочою. */
.shots-item--more{ display: none; }

.shots-more{
  display: block;
  margin: 18px auto 0;
}

.shots-note{
  margin: 18px 0 0;
  font-size: .88rem;
  color: var(--color-text-secondary);
}

/* На телефоні дві колонки замість однієї: знімки впізнавані навіть
   дрібними, а одна колонка дала б смугу прокрутки на пів екрана. */
@media (max-width: 560px){
  .shots-grid{ columns: 2; column-gap: 8px; }
  .shots-item{ margin-bottom: 8px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   ФОТО У КАРТЦІ КЕЙСУ І В АВАТАРІ ЛЮДИНИ
   ═══════════════════════════════════════════════════════════════════════ */

/* Підпис поверх знімка в кейсі. ⚠️ Він обов’язковий, а не оздоблення:
   фото підібране за типом системи, а не зняте на цьому об’єкті, і читач має
   це бачити. Без підпису картка твердила б те, чого ми не знаємо. */
.gallery-shot{ position: relative; }
.case-shot-note{
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 5px 10px;
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(18, 33, 46, .78);
  border-top-right-radius: 8px;
}

/* Аватар з фото замість літери: ті самі 64px і коло, але без тла
   й із обрізкою по колу. */
.team-avatar--photo{ background: var(--color-border); overflow: hidden; }
.team-avatar--photo img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}


/* ═══════════════════════════════════════════════════════════════════════
   ЗНІМКИ РОБІТ, НА ЯКІ Є ВІДГУК
   ═══════════════════════════════════════════════════════════════════════ */

/* Сітка на /portfolio/ більше нічим не відрізняється від звичайної.
   Квадрат 1:1 тут був компромісом: кадри з телефонів, 13 із 19
   вертикальні, і 3:2 з'їдало половину висоти. Відколи плитка тримає
   пропорцію самого знімка, різати нема чого - клас лишається як гачок
   для розмітки, але геометрії вже не нав'язує. */

/* Мініатюра в картці відгуку.
   ⚠️ Саме в рядку .rv-foot, а не над текстом: картки стоять у сітці, і
   повнорозмірне фото зробило б 11 карток із 83 помітно вищими за решту.
   ⚠️ Ім'я та дата загорнуті в .rv-who, бо .rv-foot стає рядком flex, а без
   обгортки <b> і .rv-meta роз'їхались би в один рядок замість стовпчика
   (.rv-foot b{display:block} у main.css тоді вже нічого не тримає). */
.rv-foot:has(.rv-shots){
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Кілька знімків одного автора стають рядком. У Olena їх чотири, у Дарʼї три:
   раніше показувався лише перший, і решта ніде не стояла поруч зі своїм текстом. */
.rv-shots{
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
}

/* ⚠️ ДВА І БІЛЬШЕ ЗНІМКІВ - РЯДКОМ НАД ПІДПИСОМ, А НЕ ПОРУЧ.
   Поруч працює лише для одного: чотири мініатюри Olena з'їдали всю ширину
   картки, і ім'я з датою стискались у колонку по одному слову
   («Olena / Murav / 1 / year / ago»). Перевірено на 1280px. */
.rv-foot:has(.rv-shots .rv-shot:nth-child(2)){
  display: block;
}
.rv-foot:has(.rv-shots .rv-shot:nth-child(2)) .rv-shots{
  margin-bottom: 10px;
}
.rv-shots .rv-shot{ flex: 0 0 72px; width: 72px; height: 72px; }
.rv-shots .rv-shot:only-child{ flex-basis: 96px; width: 96px; height: 96px; }
.rv-who{ min-width: 0; }

.rv-shot{
  flex: 0 0 96px;
  width: 96px;
  height: 96px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--color-border);
}
.rv-shot img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media (max-width: 520px){
  .rv-shot,
  .rv-shots .rv-shot,
  .rv-shots .rv-shot:only-child{ flex-basis: 58px; width: 58px; height: 58px; }
}


/* Тепер у цих карток є підпис автора, тож вони вже не порожні: вирівнюємо
   зверху вниз, як звичайні. Пунктирна рамка лишається - вона й далі чесно
   каже, що тексту відгуку немає. */
.rv-card--rating{ justify-content: flex-start; }

/* ═══════════════════════════════════════════════════════════════════════
   ЗБІЛЬШЕННЯ ФОТО
   ═══════════════════════════════════════════════════════════════════════ */

/* Кнопка-обгортка навколо знімка. Саме <button>, а не клік по <img>:
   інакше знімок недосяжний з клавіатури і невидимий для екранної дикторки. */
.shots-zoom,
.rv-zoom{
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  color: inherit;
  font: inherit;
}
.shots-zoom:focus-visible,
.rv-zoom:focus-visible{
  outline: 3px solid var(--color-blue);
  outline-offset: 2px;
}

.eh-lb{
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* ⚠️ Починалось із .92, але крізь це просвічувала біла шапка й плашка
     про cookies: нагорі видно було світлу смугу з привидом меню.
     Перевірено: elementFromPoint там повертає саме вікно, тобто це
     був не z-index, а прозорість. */
  background: rgba(10, 12, 16, .975);
}
.eh-lb.is-open{ display: flex; }

/* Прокрутку сторінки позаду замикаємо, інакше палець гортає її, а не фото. */
.eh-lb-lock{ overflow: hidden; }

.eh-lb__figure{
  margin: 0;
  max-width: min(1200px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}
.eh-lb__img{
  max-width: 100%;
  /* 96px - місце під підпис і лічильник під знімком. */
  max-height: calc(100vh - 96px - 48px);
  width: auto;
  height: auto;
  border-radius: 12px;
  display: block;
  background: #1c1f26;
}
.eh-lb__cap{
  display: flex;
  gap: 14px;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  color: #e8eaee;
  font-size: .9rem;
  line-height: 1.45;
  text-align: center;
  max-width: 70ch;
}
.eh-lb__num{
  font-family: var(--font-mono);
  font-size: .78rem;
  color: #9aa1ad;
  white-space: nowrap;
}

.eh-lb__close,
.eh-lb__nav{
  position: absolute;
  border: 0;
  background: rgba(255, 255, 255, .10);
  color: #fff;
  cursor: pointer;
  border-radius: 999px;
  line-height: 1;
  transition: background .15s ease;
}
.eh-lb__close:hover,
.eh-lb__nav:hover{ background: rgba(255, 255, 255, .22); }
.eh-lb__close:focus-visible,
.eh-lb__nav:focus-visible{ outline: 3px solid #fff; outline-offset: 2px; }

.eh-lb__close{
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  font-size: 1.8rem;
}
.eh-lb__nav{
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 52px;
  font-size: 2rem;
}

/* На широкому екрані обгортка не малює власного боксу, тож кнопки всередині
   позиціонуються відносно самого вікна і стоять по боках, як і раніше. */
.eh-lb__bar{ display: contents; }
.eh-lb__nav--prev{ left: 16px; }
.eh-lb__nav--next{ right: 16px; }

/* На телефоні стрілки з боків перекривали б сам знімок, тому вони внизу. */
@media (max-width: 640px){
  /* ⚠️ Смугу зі стрілками віднімаємо ПАДДІНГОМ контейнера, а не відступом
     під підписом. Відступ у центрованого flex зсуває весь блок угору, і
     знімок опинявся у верхній третині екрана з великою пусткою під ним.
     Перевірено на 390×780. */
  /* ⚠️ На телефоні стрілки стають РЯДКОМ ПІД ПІДПИСОМ, а не прибиті до краю
     екрана. Прибиті лишали 180px порожнечі між знімком і кнопками: виглядало
     так, ніби керування загубилось. Виміряно на 390×780. */
  .eh-lb{
    flex-direction: column;
    gap: 18px;
    padding: 12px;
  }
  .eh-lb__img{ max-height: calc(100vh - 230px); }
  .eh-lb__bar{
    display: flex;
    gap: 28px;
    justify-content: center;
  }
  .eh-lb__nav{
    position: static;
    transform: none;
    width: 48px;
    height: 48px;
  }
}

@media (prefers-reduced-motion: reduce){
  .eh-lb__close,
  .eh-lb__nav{ transition: none; }
}


/* ═══════════════════════════════════════════════════════════════════════
   СЕРТИФІКАТ ВИРОБНИКА НА /licensing/
   ═══════════════════════════════════════════════════════════════════════ */

.cred-doc{
  margin: 22px 0 0;
  max-width: 560px;
}
.cred-doc__zoom{
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  cursor: zoom-in;
}
.cred-doc__zoom:focus-visible{ outline: 3px solid var(--color-blue); outline-offset: 2px; }
.cred-doc__img{ display: block; width: 100%; height: auto; }
.cred-doc figcaption{
  margin-top: 8px;
  font-size: .82rem;
  color: var(--color-text-secondary);
}


/* ═══════════════════════════════════════════════════════════════════════
   ФОТО СТОРІНКИ - ДРУГА КОЛОНКА ВСТУПУ
   Було: смуга на всю ширину 1132×330 (3.43:1). Вона зрізала 56% кадру 3:2
   і читалась як випадковий банер. Тепер так само, як на сторінках із
   героєм: текст ліворуч, знімок праворуч, кадр не ріжеться взагалі.

   ⚠️ Обгортки для тексту НЕМАЄ і не треба: усі текстові діти вступу
   явно кладуться в першу колонку, а фото займає другу на всі рядки.
   Так не довелось переписувати розмітку в 19 шаблонах.
   ═══════════════════════════════════════════════════════════════════════ */

@media (min-width: 900px){
  .services-hero:has(.hero-photo){
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
    column-gap: 44px;
    align-items: center;
  }
  /* Текст стає лівим: по центру він виглядав зсунутим у своїй колонці,
     бо праворуч від нього тепер знімок, а не порожнеча. */
  .services-hero:has(.hero-photo){ text-align: left; }
  .services-hero:has(.hero-photo) .sh-text > *:last-child{ margin-bottom: 0; }
  .services-hero:has(.hero-photo) .hero-sub,
  .services-hero:has(.hero-photo) .section-sub{ margin-left: 0; margin-right: 0; }
  .services-hero:has(.hero-photo) .hero-actions{ justify-content: flex-start; }
  .services-hero:has(.hero-photo) .eyebrow{ justify-content: flex-start; }
  .services-hero:has(.hero-photo) h1,
  .services-hero:has(.hero-photo) h2{ margin-left: 0; margin-right: 0; }
  /* ⚠️ ДВА ГРІД-ЕЛЕМЕНТИ, А НЕ ДЕСЯТЬ. Текст - один блок .sh-text.
     Раніше кожен абзац був окремим рядком, а фото з grid-row: 1/-1
     розподіляло свою висоту по цих рядках: на /products/ перший рядок
     ставав 280px і eyebrow висів сам. Тепер рядок один, розподіляти нема що. */
  .services-hero:has(.hero-photo) > .sh-text{ grid-column: 1; }
  .services-hero:has(.hero-photo) > .hero-photo{ grid-column: 2; }
}

.hero-photo{ margin-top: 18px; }
.hero-photo__zoom{
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-border);
  cursor: zoom-in;
  line-height: 0;
}
.hero-photo__zoom:focus-visible{ outline: 3px solid var(--color-blue); outline-offset: 3px; }
.hero-photo__img{ display: block; width: 100%; height: auto; }

@media (min-width: 900px){
  .hero-photo{ margin-top: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════
   БЛОК ЦІНИ В ГЕРОЇ ТОВАРНИХ СТОРІНОК

   ⚠️ ГОЛОВНА ПРИЧИНА, ЧОМУ ЦІНА ВИГЛЯДАЛА СЛАБКО: вона була набрана
   МОНОШИРИННИМ шрифтом на 35px. У моно кожен знак займає однакову
   комірку, тому кома і долар «роздувають» число, і «$4,600» читається
   розріджено. Від'ємний трекінг -0.7px, який там стояв, лікував симптом.
   Моно лишається там, де він доречний: дрібна мітка «FROM» і технічні
   числа. Сама сума тепер Plex Sans із табличними цифрами.

   Друге: «FROM» стояв на одній базовій лінії з сумою і був утричі
   дрібніший - читався як загублений хвостик. Тепер це рядок-мітка над
   сумою, як на цінниках.
   ═══════════════════════════════════════════════════════════════════════ */

.product-facts{
  padding: 16px 22px 18px;
  border-radius: 14px;
}

.product-price{
  display: grid;
  grid-template-columns: auto;
  row-gap: 3px;
}

.product-price .pf-label{
  font-family: var(--font-mono);
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  line-height: 1;
}

.product-price b{
  font-family: var(--font-body);
  font-size: clamp(2.1rem, 3.6vw, 2.75rem);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.035em;
  /* Табличні цифри: у сусідніх цінах ($3,300 і $12,400) знаки стоять
     в одну колонку, а не «стрибають». */
  font-variant-numeric: tabular-nums;
  color: var(--color-blue-dark);
}

.product-price .pf-note{
  font-size: .84rem;
  line-height: 1.35;
  color: var(--color-text-secondary);
}


/* ═══════════════════════════════════════════════════════════════════════
   ШИРИНА БЛОКІВ FAQ І SEO-ТЕКСТУ
   Виміряно: усі секції мають контейнер 1180px, а .faq-list і .seo-copy -
   664 і 668px. Перепад майже вдвічі читався як недороблений блок.

   ⚠️ АЛЕ ПРОСТО РОЗТЯГНУТИ ТЕКСТ НА 1180px НЕ МОЖНА. Зараз у рядку 79
   символів, це вже верхня межа читабельності; на 1180px вийшло б близько
   140, і текст став би важким для читання. Тому SEO-блок займає всю
   ширину ДВОМА КОЛОНКАМИ: рядок лишається коротким, а блок більше не
   виглядає вужчим за сусідів. FAQ розширено помірно, до 860px: там
   короткі питання, і довгий рядок їм не шкодить.
   ═══════════════════════════════════════════════════════════════════════ */

.faq-list{ max-width: 860px; }

@media (min-width: 1024px){
  .seo-copy{
    max-width: 1180px;
    column-count: 2;
    column-gap: 56px;
  }
  /* Заголовок розриває колонки і йде на всю ширину, інакше він опинявся б
     посеред правої колонки і читався як підпис до сусіднього абзацу. */
  .seo-copy h2,
  .seo-copy h3{
    column-span: all;
    margin-top: 1.4em;
  }
  .seo-copy h2:first-child,
  .seo-copy h3:first-child{ margin-top: 0; }
}


/* Документ і пояснення поруч. Виміряно: сам сертифікат 560px лишав 620px
   порожнечі праворуч під рівним рядом із трьох карток. */
.cred-doc-row{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 32px;
  align-items: start;
  margin-top: 22px;
}
.cred-doc-row .cred-doc{ margin: 0; max-width: none; }
.cred-doc-row .cred-note{ margin: 0; align-self: center; }

@media (max-width: 860px){
  .cred-doc-row{ grid-template-columns: 1fr; gap: 18px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   ФОТО В КАРТКАХ - КВАДРАТ
   Було три різні рамки (16:10 і 16:9) під одне зображення 1.52:1, тобто
   кожна картка різала кадр удруге - саме так зникав верх блока. Квадратна
   рамка під квадратний розмір everheat-square не ріже нічого.
   ═══════════════════════════════════════════════════════════════════════ */

.card-shot,
.equip-shot,
.rc-shot{ aspect-ratio: 1 / 1; }

/* ═══════════════════════════════════════════════════════════════════════
   ТЕМИ З ВІДГУКІВ - ЦЕ ДАНІ, А НЕ КНОПКИ
   Заливка, кругла форма і жирний шрифт читались як кнопка, і людина
   намагалась клікнути. Клікати нема куди: шість фраз із десяти («quick
   work», «reliable crew») не мають сторінки на сайті. Тому вигляд
   змінено на статистику.
   ═══════════════════════════════════════════════════════════════════════ */

.topic-pill{
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  font-weight: 500;
  border-radius: 8px;
  padding: 5px 10px;
  cursor: default;
}
.topic-pill .tp-num{
  background: transparent;
  min-width: 0;
  height: auto;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: .78rem;
  color: var(--color-text);
}


/* ═══════════════════════════════════════════════════════════════════════
   ПЕРЕМИКАЧ РЕЖИМІВ КАЛЬКУЛЯТОРА
   Було текстове посилання всередині абзацу: «Prefer them one at a time?
   Switch to the step-by-step version». Воно читалось як звичайне
   посилання кудись убік, і людина не розуміла, що це той самий
   калькулятор у двох режимах. Сегментований перемикач показує обидва
   варіанти одразу і який із них активний.
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ margin-bottom обов'язковий: перемикач більше не стоїть лише внизу
   вступу калькулятора. Він тепер і над .product-facts на сторінках
   обладнання, і над .hero-actions на сторінках цін, і без відступу
   капсула злипалась із ціною під нею. */
.calc-switch{
  display: inline-flex;
  margin: 14px auto 16px;
  padding: 4px;
  gap: 4px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 999px;
}
.calc-switch__item{
  display: inline-flex;
  align-items: center;
  padding: 8px 18px;
  border-radius: 999px;
  font-size: .9rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  color: var(--color-text-secondary);
  transition: background .15s ease, color .15s ease;
}
.calc-switch__item:hover{ color: var(--color-blue-dark); background: var(--color-blue-light); }
.calc-switch__item.is-on{
  background: var(--color-blue-dark);
  color: #fff;
  cursor: default;
}
.calc-switch__item:focus-visible{ outline: 3px solid var(--color-blue); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce){
  .calc-switch__item{ transition: none; }
}
@media (max-width: 420px){
  .calc-switch{ width: 100%; }
  .calc-switch__item{ flex: 1; justify-content: center; padding: 9px 10px; font-size: .84rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   «WHAT THE PRICE COVERS» - ОДНА ПАНЕЛЬ ЗАМІСТЬ П'ЯТИ ПЛИТОК
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ П'ЯТЬ КАРТОК У СІТЦІ ПО ТРИ (НА ШИРОКОМУ - ПО ЧОТИРИ) ЗАВЖДИ ДАЮТЬ
   СИРОТУ. На /pricing/*-installation/ пунктів рівно п'ять на всіх чотирьох
   сторінках, тож остання картка стояла сама в порожньому рядку, а решта
   рядка світилась дірою - це й видно на скріншоті власника.
   Це список того, що входить у ціну, а не п'ять рекламних плиток: він
   читається згори вниз, а не порівнюється попарно. Тому одна панель із
   двома колонками тексту: сироти немає за побудовою, повітря менше,
   а зміст той самий. */
.covers-grid{
  display: block;
  columns: 2;
  column-gap: 34px;
  padding: 22px 26px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 14px;
}
.covers-grid .covers-card{
  display: flex;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  margin: 0;
  padding: 11px 0;
  background: none;
  border: 0;
  box-shadow: none;
  border-radius: 0;
}
/* Роздільник між пунктами всередині колонки, а не рамка навколо кожного:
   рамок було п'ять, тепер одна на всю панель. */
.covers-grid .covers-card + .covers-card{
  border-top: 1px solid var(--color-border);
}

@media (max-width: 720px){
  .covers-grid{ columns: 1; padding: 16px 18px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   ФОТО РОБОТИ В КАРТЦІ ВІДГУКУ ПОЗА СТОРІНКОЮ /reviews/
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ВІДГУКИ НА САЙТІ МАЛЮЮТЬСЯ ТРЬОМА РІЗНИМИ РОЗМІТКАМИ, І ФОТО БУЛО
   ЛИШЕ В ОДНІЙ. .rv-card - на /reviews/ і підсторінках, .review-card -
   у каруселі на головній, послугах і товарах, .person-quote - на
   сторінках Eric і Vlad. Знімок роботи бачила тільки перша. Тепер
   everheat_review_shot() друкує ту саму .rv-shots у всіх трьох, а тут
   лишається дати їй місце в двох нових контекстах.
   ⚠️ Збіг лише за іменем автора: із 86 захардкоджених карток по всьому
   сайту фото має 16. Решта відгуків написані людьми, чиїх знімків у нас
   немає, і вигадувати їм чуже фото не можна. */
.review-card .rv-shots,
.person-quote .rv-shots{
  margin-top: 12px;
}
.review-card .rv-shots .rv-shot,
.person-quote .rv-shots .rv-shot{
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--color-border);
}
.review-card .rv-shots .rv-shot:only-child,
.person-quote .rv-shots .rv-shot:only-child{
  flex-basis: 84px;
  width: 84px;
  height: 84px;
}
.review-card .rv-shots img,
.person-quote .rv-shots img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ═══════════════════════════════════════════════════════════════════════
   СМУГА ЗНІМКІВ У СЕКЦІЇ «HOW IT WORKS» НА ГОЛОВНІЙ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ Секція процесу була єдиною великою секцією головної взагалі без
   жодного зображення: пʼять нумерованих абзаців поспіль. Смуга йде ПІСЛЯ
   кроків, а не між ними: чесного знімка для кроку «Full-Detail Quote»
   у нас немає, а розставити фото через один означало б зробити сходинку
   з дірками. */
.process-shots{ margin-top: 34px; }

/* ═══════════════════════════════════════════════════════════════════════
   СМУГА КРОКІВ: РІВНІ ПЛИТКИ, А НЕ КОЛОНКИ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ТУТ КОЛОНКОВА КЛАДКА ХИБНА, І ЦЕ ВИМІРЯНО.
   .shots-grid загалом навмисно тримає пропорцію самого знімка: у галереї
   з 87 фото рваний нижній край читається як галерея. Але в цій смузі
   знімків рівно чотири, і висоти вийшли 133, 235, 157 і 235 - верхи
   вирівняні, низи в трьох різних місцях. Чотири пояснювальні кадри з
   таким краєм читаються не як галерея, а як зламана верстка.
   Тому саме цій смузі - рівна сітка з однаковою пропорцією. */
.shots-grid--steps{
  columns: auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.shots-grid--steps .shots-item{
  margin: 0;
  background: none;
  border-radius: 0;
  overflow: visible;
}
.shots-grid--steps .shots-zoom{
  display: block;
  width: 100%;
  border-radius: 12px;
  overflow: hidden;
  background: var(--color-border);
  /* ⚠️ height:auto СКАСОВУЄ height:100% ЗІ СПІЛЬНОГО ПРАВИЛА .shots-zoom,
     І БЕЗ ЦЬОГО ПІДПИС НАЛІЗАЄ НА НАСТУПНИЙ БЛОК. Виміряно 21.09.2026.
     Механізм: плитка це елемент сітки, її рядок має розмір за вмістом -
     знімок 204px + 9px відступу + 18px підпису = 231.5px. Кнопка з
     height:100% бере ці 231.5px ЦІЛКОМ, тобто з'їдає і ту частину, що
     належала підпису, і центрує знімок у собі. Підпис виштовхується
     на 27px НИЖЧЕ дна плитки, а плитка має overflow:visible, тож він
     лягає поверх того, що йде далі: на /services/heating-installation/
     це кнопка «How We Install, Step By Step», перекриття 5px.
     Було вражених 12 підписів на трьох сторінках: головна,
     /services/heating-installation/, /services/cooling-installation/.
     Правило звужене саме до цієї смуги: у галереї на /portfolio/ і в
     .rv-zoom height:100% лишається, бо там підпису поруч немає і
     відсоток резолвиться в auto (батько без заданої висоти). */
  height: auto;
}
.shots-grid--steps .shots-img{
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Підпис під кадром: він і робить смугу послідовністю, а не набором
   картинок. Нумерація не дублюється - кроки пронумеровані вище. */
.shots-cap{
  display: block;
  margin-top: 9px;
  font-size: .84rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--color-text);
}

@media (max-width: 860px){
  .shots-grid--steps{ grid-template-columns: repeat(2, 1fr); gap: 12px; }
}
@media (max-width: 440px){
  .shots-grid--steps{ grid-template-columns: 1fr; }
}

/* ⚠️ САМЕ ЦЕ ПРАВИЛО РОБИТЬ СМУГУ КРОКІВ СЛАЙДЕРОМ НА ТЕЛЕФОНІ.
   Правило вище кидало смугу в ОДНУ колонку до 440px, і чотири кадри
   з підписами займали 1 232px - цілий екран із третиною на головній
   (виміряно при 375px). Тепер PHP вішає на неї data-mslider, sliders.js
   до 620px обгортає її у Swiper, і блок став 362px.

   Сітковий display і grid-template-columns вище лишаються в силі на
   ширшому екрані: sliders.js розбирає слайдер назад після 620px, а поки
   він зібраний, .swiper-wrapper дає display:flex і сіткові правила
   просто не застосовуються до флекс-контейнера.

   align-self: start потрібен для мішаних пропорцій. Swiper тягне слайди
   до висоти найвищого, і без цього горизонтальний кадр 800×533 малювався
   б угорі коробки 407px, а під ним лишалось би 204px тла .shots-item.
   У --steps пропорція одна (4/3), тож це страховка на випадок, коли
   data-mslider колись отримає й мішану галерею. */
.ms-track .shots-item{
  align-self: start;
  margin-bottom: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   КАРТКИ ВИБОРУ СИСТЕМИ ЗІ ЗНІМКОМ (ПОКРОКОВИЙ КАЛЬКУЛЯТОР)
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ЛЮДИНА МАЄ БАЧИТИ, ЩО ОБИРАЄ. Перше й найважливіше питання майстра -
   «What system are you looking for?» - було чотирма рядками тексту:
   «Furnace / Central Air Conditioner / Heat Pump / Ductless Mini-Split».
   Для власника це очевидні слова, для домовласника, який уперше міняє
   систему, - ні. Тепер у картці стоїть знімок саме такої нашої установки.
   ⚠️ Стосується ЛИШЕ тих груп, де фото справді є (.wiz-opts--photo).
   Решта питань («How urgent is it?») лишається текстовими картками:
   вигадувати їм фото нема з чого і нема навіщо. */
/* ⚠️ РІВНО ДВІ КОЛОНКИ, А НЕ auto-fit. Колонка майстра - 540px, і auto-fit
   давав три картки в ряд: при чотирьох варіантах четверта лишалась сама.
   Дві колонки дають 2×2 без сироти і вдвічі більший знімок. */
.wiz-opts--photo{
  grid-template-columns: repeat(2, 1fr);
}
.wiz-opts--photo .wiz-opt{
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  padding: 0;
  gap: 0;
  overflow: hidden;
  min-height: 0;
}
/* Кружечок-радіо переїжджає НА ЗНІМОК - і тільки туди.
   ⚠️ Селектор навмисно .wiz-opt--photo, а не вся група. Спершу я
   прив'язав абсолют до групи: будь-яка картка в ній, навіть без
   зображення, отримувала кружечок у лівому верхньому куті, а підпис
   починався з відступом 14px - тобто рівно під ним, і текст налазив на
   кружечок. Тепер абсолют не існує без картинки, під якою йому лежати,
   тож накласти його на текст неможливо за побудовою. */
.wiz-opts--photo .wiz-opt--photo{ position: relative; }
.wiz-opts--photo .wiz-opt--photo::before{
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(255, 255, 255, .92);
  z-index: 1;
}

/* ⚠️ height:auto ОБОВ'ЯЗКОВИЙ. На <img> стоять width/height 300×300 заради
   резервування місця до завантаження, і презентаційний атрибут height
   перебиває aspect-ratio: знімок виходив 170×300 замість 170×128. */
.wiz-opt__img{
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--color-border);
}
.wiz-opts--photo .wiz-opt__label{
  display: block;
  padding: 11px 14px 13px;
  line-height: 1.3;
}
/* ⚠️ КАРТКА БЕЗ ФОТО В ГРУПІ З ФОТО - ЦЕ ЗВИЧАЙНИЙ РЯДОК, А НЕ КАЛІЧНА
   КОЛОНКА. Перша версія лишала їй колонковий вигляд: кружечок висів
   абсолютом у лівому верхньому куті, а підпис починався з відступом
   14px - тобто рівно під кружечком, текст «Something else» налазив на
   нього. Плюс картка розтягувалась на висоту сусідніх фото-карток і
   лишала велику білу пляму.
   Тепер такі картки повертаються до рядка: кружечок у потоці, підпис
   поруч, висота по вмісту. */
.wiz-opts--photo .wiz-opt:not(.wiz-opt--photo){
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  align-self: start;
}
.wiz-opts--photo .wiz-opt:not(.wiz-opt--photo)::before{
  position: static;
  background: none;
}
.wiz-opts--photo .wiz-opt:not(.wiz-opt--photo) .wiz-opt__label{
  padding: 0;
}


/* ═══════════════════════════════════════════════════════════════════════
   ДОПЛАТИ В ПОКРОКОВОМУ РЕЖИМІ: ТАКІ САМІ КАРТКИ, ЯК РЕШТА ПИТАНЬ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ «НЕ НАТИСКАЄТЬСЯ» ТУТ ОЗНАЧАЛО «НЕ ВИГЛЯДАЄ НАТИСКАБЕЛЬНИМ».
   Перевірено: клік працює, панель ціни одразу додає рядок «Filter
   Cabinet and Filter $350». Але на дев'яти попередніх кроках майстра
   людина тикала у великі картки, а на десятому раптом бачить чотири
   вузькі пігулки різної ширини з системними чекбоксами. Рука туди не
   йде. Робимо той самий формат картки, що й у решти питань. */
.is-wizard .opt-row{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 10px;
}
.is-wizard .opt-row .opt{
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 64px;
  margin: 0;
  padding: 12px 14px;
  background: #fff;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-card);
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.is-wizard .opt-row .opt:hover{ border-color: var(--color-blue); }
/* Обраний стан читається з самої картки, а не лише з дрібної галочки. */
.is-wizard .opt-row .opt:has(input:checked){
  border-color: var(--color-blue);
  background: var(--color-blue-light);
  color: var(--color-blue-dark);
}
.is-wizard .opt-row .opt input[type="checkbox"]{
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--color-blue);
}
/* ⚠️ 40px БУЛО ЗАМАЛО. Термостат на знімку - невелика коробка на
   великій стіні, і в квадраті 40px він читався темною плямою, а не
   приладом. 56px - мінімум, при якому видно, що це. Якщо власник
   зніме крупний план самого приладу, розмір можна буде зменшити. */
.is-wizard .opt-row .opt-thumb{
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
}

@media (max-width: 640px){
  .is-wizard .opt-row{ grid-template-columns: 1fr; }
}

@media (max-width: 640px){
  .wiz-opts--photo{ grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .wiz-opts--photo .wiz-opt__label{ padding: 9px 11px 11px; font-size: .92rem; }
}

/* Знімок обраної системи в панелі ціни. hidden знімає його повністю,
   тому порожнього місця в панелі не лишається. */
/* ⚠️ ВИСОТА ОБМЕЖЕНА ЖОРСТКО, І ЦЕ НЕ ОЗДОБЛЕННЯ.
   Перша версія стояла з aspect-ratio 4/3 і width:100%. У бічній колонці
   це 260px завширшки і все гаразд, але панель має ДРУГИЙ стан - вікно
   поверх сторінки завширшки близько 870px. Там знімок виходив ~650px
   заввишки, займав увесь екран і зіштовхував і рядки ціни, і саму суму
   за межі видимого. Головне в панелі - число, а не фото. */
.cp-photo{
  margin: 0 0 14px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255, 255, 255, .14);
  max-height: 170px;
}
.cp-photo img{
  display: block;
  width: 100%;
  height: 170px;
  aspect-ratio: auto;
  object-fit: cover;
}
@media (max-width: 1000px){
  /* На телефоні панель - згорнута смуга внизу екрана. Знімок там з'їдав би
     ту саму висоту, заради якої смугу й згортали. */
  .cp-photo{ display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   ПАНЕЛЬ ЦІНИ: ВИДНО, ЩО ВОНА ГОРТАЄТЬСЯ, І ВИДНО САМУ СУМУ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ВИМІРЯНО НА ЖИВІЙ СТОРІНЦІ, 1000×760. У розгорнутому стані
   .cp-body має scrollHeight 532 при clientHeight 334 і overflow:auto -
   тобто третина вмісту за межами видимого, і жодного натяку про це.
   Смуги прокрутки браузер на macOS не малює, поки не крутнеш.
   Гірше інше: .calc-total лежить УСЕРЕДИНІ цієї області, тож головне
   число просто виїжджало вгору разом із рядками. Людина гортала список
   доплат і втрачала з очей суму, заради якої все й відкривала.
   Тепер сума приклеєна до низу панелі, а тінь над нею показує, що під
   нею ще є вміст. */
.calc-panel.is-open .calc-total{
  position: sticky;
  bottom: -14px;                 /* на висоту нижнього падінга .cp-body */
  z-index: 2;
  margin: 0 -20px;
  padding: 16px 20px 14px;
  background: var(--color-blue-dark);
  box-shadow: 0 -16px 20px -10px var(--color-blue-dark);
}

/* Той самий натяк угорі: коли список прокручений, видно, що вище ще є. */
.calc-panel.is-open .cp-body{
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .45) transparent;
}
.calc-panel.is-open .cp-body::-webkit-scrollbar{ width: 8px; }
.calc-panel.is-open .cp-body::-webkit-scrollbar-thumb{
  background: rgba(255, 255, 255, .42);
  border-radius: 4px;
}
.calc-panel.is-open .cp-body::-webkit-scrollbar-track{ background: transparent; }

/* Мініатюра доплати в рядку чекбокса. Лише там, де знімок є: рядок без
   фото лишається звичайним і не отримує ані порожньої рамки, ані відступу. */
.opt:has(.opt-thumb){
  display: flex;
  align-items: center;
  gap: 10px;
}
.opt-thumb{
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 8px;
  object-fit: cover;
  display: block;
  background: var(--color-border);
}

/* Рядок над смугою кроків. */
.process-shots__lead{
  margin: 0 0 14px;
  font-size: .9rem;
  color: var(--color-text-secondary);
}


/* ═══════════════════════════════════════════════════════════════════════
   ЗНИЖЕННЯ РІВНІВ ЗАГОЛОВКІВ: ВИГЛЯД ЛИШАЄТЬСЯ ТОЙ САМИЙ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ЗМІНЕНО СЕМАНТИКУ, А НЕ ВИГЛЯД.
   На /services/cooling-installation/ було 18 H2 при одному H1, який до того
   ж стояв на 77% документа. Рішення власника: H2 лишаються тільки ті, що
   затверджені в ТЗ (заголовки SEO-блоку і FAQ) плюс продажний заголовок
   угорі; усі наші секційні заголовки опускаються до H3, а їхні внутрішні
   H3 - до H4.
   ⚠️ ОДИН H2 НА СТОРІНЦІ ЛИШАЄТЬСЯ ЗАВЖДИ. Інакше на сторінках без
   SEO-блоку (контакти, портфоліо, локації) вийшло б h1 -> h3, тобто
   пропуск рівня і порушення WCAG 1.3.1.
   ⚠️ ПРАВИЛА НИЖЧЕ ОБОВ'ЯЗКОВІ. У main.css до тега h3 прив'язано
   дев'ятнадцять правил (.service-card h3, .team-card h3, .process-item h3,
   .branch-card h3, .fa-county h3 і так далі). Без дзеркальних правил для
   h4 зміна тега мовчки зламала б усі ці компоненти. Згенеровано з
   main.css, а не написано руками. */

/* ⚠️ КЛАС НА САМОМУ ЗАГОЛОВКУ, А НЕ СЕЛЕКТОР ПО КОНТЕЙНЕРУ.
   Спершу я написав .section-head h3 - і заголовки синіх секцій
   («Why Homeowners Choose Us») зменшились із 30,7px до 18,4px, бо вони
   не загорнуті в .section-head. Контейнери на сайті різні, а ознака
   в усіх одна: це колишній H2 секції. Тому клас ставиться під час
   заміни тега, і жоден контейнер більше не має значення. */
.sec-h{ font-size: clamp(1.5rem, 3vw, 2.1rem); }
.section-head h3{ font-size: clamp(1.5rem, 3vw, 2.1rem); }
.section--blue h3,
.section--blue h4{ color: #fff; }

/* Підвал: підписи колонок стали h3, назви округів - h4. */
.footer-col h3{ color:#fff; font-size:.92rem; letter-spacing:.02em;
                margin: 1.33em 0 16px; line-height: 1.55; }
.footer-col > summary h3{ margin: 0; }
.footer-area h3{ color:#fff; font-size:.92rem; letter-spacing:.02em;
                 margin-bottom:10px; line-height:1.55; }

/* Дзеркальні правила h3 -> h4, згенеровані автоматично. */
h4{ font-weight:700; color: var(--color-text); margin:0 0 .5em; line-height:1.2; }
h4{ font-size: 1.15rem; }
.service-card h4{ margin-bottom:8px; }
.team-card h4{ margin:0 0 2px; font-size:1.05rem; }
.team-card h4 a{ display:inline-block; padding:3px 6px; margin:-3px -6px; border-radius:8px; }
.process-item h4{ margin-bottom:4px; }
.wiz-done h4{ margin:0 0 6px; font-size:1.1rem; }
.is-wizard .branch-card h4{ font-size:.98rem; margin:0; }
.branch-card h4{ margin:10px 0 6px; font-size:1.08rem; }
.calc-panel h4{ color:#fff; margin:0 0 4px; font-size:1.05rem; }
.calc-modal-box h4{ margin:0 0 6px; }
.calc-modal-box h4{ font-size:1.12rem; line-height:1.25; padding-right:34px; }
.gallery-body h4{ font-size:1.02rem; margin:0 0 8px; }
.channel h4{ font-size:1rem; margin:0 0 8px; }
.calc-cta h4{ color:#fff; margin:0 0 6px; font-size:1.25rem; }
.fa-county h4{ margin:0 0 6px; line-height:1.55; font-size:.82rem; font-weight:700; letter-spacing:.06em;
                 text-transform:uppercase; color:#fff; display:flex; align-items:center; gap:8px; }
h4{ page-break-after:avoid; }
.seo-copy h4{ column-span: all;
    margin-top: 1.4em; }
.seo-copy h4:first-child{ margin-top: 0; }

/* Смуга під «Want To See The Work Itself?». Кнопка йде після неї. */
.btp-shots{ margin: 26px 0 22px; }

/* ⚠️ РЯДОК ІЗ РЕЙТИНГОМ ВИРІВНЮЄТЬСЯ ПО ЛІВОМУ КРАЮ, ЯК І ВЕСЬ ВСТУП.
   У .rating-line стоїть justify-content:center - це правильно там, де
   блок центрований, але у вступі сторінки відгуків заголовок і абзац
   ліворуч, а зірки з посиланням висіли посеред колонки шириною 512px.
   Плюс margin:0 злiплював його і з абзацом угорі, і з перемикачем унизу. */
.sh-text .rating-line{
  justify-content: flex-start;
  margin: 6px 0 2px;
}

/* ═══════════════════════════════════════════════════════════════════════
   ІКОНКИ В КАРТКАХ КАНАЛІВ ЗВ'ЯЗКУ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ Шість карток «How to Reach Us» були шістьма однаковими стовпчиками
   тексту: телефон, пошта, адреса, години, профілі, район - усе однієї
   ваги й однієї форми, і око не мало за що зачепитись. Іконка дає кожній
   картці впізнаваний знак за пів секунди до читання заголовка. */
.ch-ico{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-bottom: 12px;
  border-radius: 10px;
  background: var(--color-blue-light);
  color: var(--color-blue-dark);
}


/* ═══════════════════════════════════════════════════════════════════════
   ЦІНА В ГЕРОЇ ТОВАРНОЇ СТОРІНКИ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ПРИЧИНА БУЛА НЕ В ШРИФТІ, А В КОЛЬОРАХ І КОНТЕКСТІ.
   Виміряно на /products/mini-splits/: герой темний, заголовок і текст
   білі, а цінник успадкував світлу тему - «FROM» і примітка
   rgb(91,96,104), сума rgb(20,82,143) на блідо-блакитній плашці.
   Темно-синє на блідо-блакитному поверх темного фото читається як
   чужа наліпка, приклеєна на знімок.
   Друге: .product-facts має display:inline-flex, тому після появи
   перемикача «Equipment / Prices» цінник став із ним в один рядок і
   вони тіснили одне одного.
   Тепер цінник - частина героя: без плашки, білим по темному, з
   помаранчевою рискою замість рамки, і з власного рядка. */
.hero .product-facts{
  display: flex;
  margin: 4px 0 14px;
  padding: 2px 0 2px 15px;
  background: none;
  border-radius: 0;
  border-left: 3px solid var(--color-orange);
}
.hero .product-price .pf-label{ color: rgba(255, 255, 255, .72); }
.hero .product-price b{ color: #fff; }
.hero .product-price .pf-note{ color: rgba(255, 255, 255, .82); }

/* ═══════════════════════════════════════════════════════════════════════
   ПРИХОВАНА ДОПЛАТА МУСИТЬ БУТИ ПРИХОВАНОЮ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ЦЕ БУЛА НАЙТИХІША ПОЛАМКА КАЛЬКУЛЯТОРА.
   Для спліт-систем рушій правильно ставить hidden на «Filter Cabinet»,
   «UV Air Scrubber» і «Humidity Control» (усі три потребують
   повітроводів, яких у спліта немає) і правильно НЕ рахує їх у ціні:
   calcInstall() пропускає опцію, чия обгортка .opt прихована.
   Але в main.css є `.opt { display: inline-flex }`, і воно перебиває
   браузерне `[hidden] { display: none }` - специфічність однакова, а
   авторське правило завжди сильніше за стильовий аркуш браузера.
   Наслідок: людина бачила три галочки, ставила їх, і ціна не рухалась.
   Перевірено після правки: прихованих-але-видимих елементів на сторінці
   лишилось нуль. */
.opt[hidden],
.is-wizard .opt-row .opt[hidden]{
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   ХАБ МАРОК
   ═══════════════════════════════════════════════════════════════════════ */

.brand-grid{ grid-template-columns: repeat(4, 1fr); }
.brand-tile{
  display: block;
  color: inherit;
  text-decoration: none;
  border-radius: 12px;
}
.brand-tile .shots-img{
  border-radius: 12px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform .25s ease;
}
.brand-tile:hover .shots-img{ transform: scale(1.03); }
.brand-tile .shots-cap{ margin-top: 10px; font-size: 1rem; }
.brand-tile__n{
  display: block;
  margin-top: 2px;
  font-size: .82rem;
  font-weight: 400;
  color: var(--color-text-secondary);
}
.brand-tile:focus-visible{ outline: 3px solid var(--color-blue); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce){
  .brand-tile .shots-img{ transition: none; }
  .brand-tile:hover .shots-img{ transform: none; }
}
@media (max-width: 860px){ .brand-grid{ grid-template-columns: repeat(2, 1fr); } }


/* ═══════════════════════════════════════════════════════════════════════
   ВІДЕО З ОБ'ЄКТІВ: ВЕРТИКАЛЬНИЙ КЛІП ПОРУЧ ІЗ ТЕКСТОМ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ УСІ ШІСТЬ КЛІПІВ 720×1280, ТОБТО 9:16. Це не вибір, це те, як їх
   зняли на об'єктах телефоном. Розтягнути таке на ширину контенту не
   можна: при 1100px блоку кадр мав би 1955px висоти, тобто три екрани
   на один кліп. Тому кліп тримає вузьку колонку, а текст іде поруч. */
/* ⚠️ .vclip: стара сітка 220px + 440px дала 472px порожнечі в кожному
   кліпі. Нові правила - у блоці «ВІДЕОКЛІПИ: КАРТКА» нижче. */
.vclip-el{
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 9 / 16;
  border-radius: 14px;
  /* Чорне тло, а не сіре: поки постер вантажиться, рамка відео однаково
     чорна, і сірий прямокутник блимав би на його місці. */
  background: #000;
}
.vclip-title{
  display: block;
  font-weight: 700;
  font-size: 1.06rem;
  line-height: 1.3;
  color: var(--color-text);
}

/* ⚠️ ПРО ЗВУК ПИШЕМО ЗАВЖДИ, І ЦЕ НЕ ОЗДОБЛЕННЯ.
   Три кліпи з шести німі (виміряно RMS −42…−54 dB), у двох шум
   інструмента, в одному людина говорить. Людина в транспорті або на
   роботі має знати це до того, як натисне play. */
.vclip-meta{
  display: block;
  margin-top: 4px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: .78rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.vclip-text{
  display: block;
  margin-top: 10px;
  color: var(--color-text-secondary);
  line-height: 1.55;
}

/* На темних секціях підпис мусить читатись. */
.section-dark .vclip-title{ color: #fff; }
.section-dark .vclip-meta,
.section-dark .vclip-text{ color: rgba(255,255,255,.78); }

/* ⚠️ НА ТЕЛЕФОНІ КЛІП НЕ НА ВСЮ ШИРИНУ.
   Виміряно на 375px: кадр 9:16 на всю ширину дав би 343×610, тобто
   майже весь екран під один кліп, і підпис виїхав би за межі видимого.
   340px по висоті лишає підпис у тому ж екрані. */


/* ═══════════════════════════════════════════════════════════════════════
   ПОШУК У БУРГЕР-МЕНЮ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ТА САМА ПАСТКА СПЕЦИФІЧНОСТІ, ЩО Й З .nav-call, І ВОНА ТУТ ЗАПИСАНА,
   ЩОБ НЕ НАСТУПИТИ ВТРЕТЄ.
   Правило `.primary-nav > ul > li{ display:flex }` має специфічність
   (0,1,2). Простий `.nav-search{display:none}` це (0,1,0), і на десктопі
   пункт друкувався б у рядку меню другим пошуком поруч із іконкою в
   шапці - рівно те, що вже сталося з телефоном. Тому селектор повний. */
.primary-nav > ul > li.nav-search{ display: none; }

@media (max-width: 960px){
  .primary-nav > ul > li.nav-search{ display: block; }

  /* І та сама пастка з вагою: `.primary-nav > ul > li > a{font-weight:600}`
     не чіпає <button>, але решта розмірів мусить збігатися з пунктами
     меню до пікселя, інакше рядок випадає з ритму списку. */
  .primary-nav > ul > li.nav-search > button{
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 56px;
    padding: 0 20px;
    border: 0;
    background: none;
    font: inherit;
    font-size: 1.06rem;
    font-weight: 600;
    color: var(--color-text);
    text-align: left;
    cursor: pointer;
  }
  .primary-nav > ul > li.nav-search > button:hover{ background: var(--color-surface); }
  .primary-nav > ul > li.nav-search > button:focus-visible{
    outline: 3px solid var(--color-blue);
    outline-offset: -3px;
  }
  .nav-search svg{ flex: none; color: var(--color-text-secondary); }
}


/* ═══════════════════════════════════════════════════════════════════════
   ERIC = YAROSLAV: ПОЗНАЧКА ПІД ЦИТАТОЮ І РОЗГОРНУТЕ ПОЯСНЕННЯ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ПОЗНАЧКА МУСИТЬ ЧИТАТИСЬ ЯК НАША РЕПЛІКА, А НЕ ЯК ЧАСТИНА ВІДГУКУ.
   Це найважливіше в цьому блоці. Якщо вона виглядатиме продовженням
   цитати, вийде, ніби ми дописали щось у чужий відгук - рівно те, чого
   ми й уникаємо. Тому інший кегль, приглушений колір, стрілка на початку
   і ЗАВЖДИ поза лапками. */
.rv-alias{
  margin: 8px 0 0;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--color-text-secondary);
}
.rv-alias span{
  margin-right: 5px;
  color: var(--color-border);
}
.rv-alias a{
  color: var(--color-blue-dark);
  text-underline-offset: 2px;
}

/* ⚠️ ТУТ БУВ СВІТЛИЙ ТЕКСТ ДЛЯ ТЕМНИХ СЕКЦІЙ, І ЦЕ БУЛА ПОМИЛКА.
   Міркування було таке: на .section--blue приглушений сірий зникне,
   отже треба білий. Міркування, а не вимір - і воно виявилось хибним.

   Виміряно 21.09 на живому: позначка лежить не на синій секції, а
   всередині .review-card, у якої тло БІЛЕ незалежно від секції навколо.
   Тобто білий текст опинявся на білій картці:

     /about/                          контраст 1.00
     /services/                       контраст 1.00
     /pricing/furnace-installation/   контраст 1.00
     /reviews/                        контраст 6.33  (там картка не в синій секції)

   Тобто на трьох сторінках із чотирьох пояснення «Yaroslav is Eric»
   було фізично невидиме - саме те, заради чого його й додавали.

   Правило прибрано повністю. Картка завжди біла, отже сірий
   --color-text-secondary правильний скрізь, і він дає 6.33. */

/* Розгорнуте пояснення на сторінці Еріка. Ціль якоря #same-person. */
.alias-note{
  margin: 0 0 26px;
  padding: 20px 22px;
  background: var(--color-surface);
  border-left: 3px solid var(--color-orange);
  border-radius: 0 12px 12px 0;
}
.alias-note h3{
  margin: 0 0 8px;
  font-size: 1.08rem;
  line-height: 1.3;
}
.alias-note p{
  margin: 0 0 10px;
  color: var(--color-text-secondary);
  line-height: 1.6;
}
.alias-note p:last-child{ margin-bottom: 0; }
.alias-note code{
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: .88em;
}

/* ⚠️ Прокрутка до якоря має враховувати липку шапку (65px), інакше
   заголовок пояснення опиняється ПІД нею, і людина, яка щойно клікнула
   «same technician», бачить середину абзацу. */
.alias-note{ scroll-margin-top: 86px; }


/* ═══════════════════════════════════════════════════════════════════════
   ДРУК: ТЕМНІ СЕКЦІЇ НА БІЛОМУ ПАПЕРІ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ПРИНТЕР НЕ ДРУКУЄ ТЛО, І САМЕ ЦЕ ЛАМАЛО ПІВСТОРІНКИ.
   Виміряно 21.09 на головній: якщо застосувати наявні @media print
   правила й порахувати обчислені кольори, 121 елемент виходить білим
   текстом на білому папері. Розподіл: підвал 73, синя секція 6,
   номери кроків 3, бейдж рейтингу і решта.

   Чому наявне правило не рятує: у main.css стоїть body{color:#000},
   але в темних секцій свій власний білий колір на власному селекторі,
   і він специфічніший за body. Тло при цьому браузер за замовчуванням
   не друкує, тож лишається білий на білому.

   ⚠️ -webkit-text-fill-color потрібен окремо від color. Градієнтні
   заголовки малюються через background-clip: text із прозорою
   заливкою, і сам по собі color їх не поверне. */
@media print {
  /* ⚠️ СКИДАННЯ ЧЕРЕЗ *, А НЕ ПЕРЕЛІК КЛАСІВ. І ЦЕ ДРУГА СПРОБА.
     Перша версія перелічувала конкретні темні поверхні: .site-footer,
     .section--blue, .why-num, .hero-badge, .rating-line. На головній і
     на /pricing/ це дало нуль невидимих елементів, і я вирішив, що
     готово. Аудит на інших сторінках показав, що ні:

       /licensing/   3  (.cred-label, .cred-value)
       /reviews/    12  (.calc-cta 6, .rv-chip 2, .team-avatar 1,
                         і - окремо смішно - стрілка в моїй же .rv-alias)

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

     Для друку це не грубо, а правильно: принтер тло не друкує, отже
     будь-який світлий текст на папері зникає незалежно від того, який
     у нього клас. */
  *,
  *::before,
  *::after {
    color: #000 !important;
    -webkit-text-fill-color: #000 !important;
    background: transparent !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }

  /* Рамки були світлими під темне тло - на папері зникли б разом із ним. */
  .site-footer *,
  .section--blue * {
    border-color: #999 !important;
  }

  /* Кружечок номера кроку без тла перетворюється на самотню цифру.
     Повертаємо контур, щоб послідовність лишалась читабельною. */
  .why-num,
  .team-avatar,
  .rv-chip {
    border: 1.5pt solid #000 !important;
  }

  /* Кнопка без заливки це просто текст. На папері має лишитись
     прямокутником, інакше з роздруку зникає заклик до дії. */
  .btn {
    border: 1pt solid #000 !important;
  }

  /* Органи керування на папері не працюють і тільки заважають. */
  .skip-link,
  .calc-switch {
    display: none !important;
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   НИЖНІЙ РЯД ПІДВАЛУ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ ПРИЧИНА ПЕРЕКОСУ БУЛА НЕ В ВЕРСТЦІ РЯДУ, А В ПРАВИЛІ ДЛЯ ПОСИЛАНЬ.
   Виміряно 21.09 на 1440px: усі п'ять блоків мали висоту 44px, бо
   `.footer-bottom a{ min-height:44px; align-items:center }` (правило про
   розмір зони натискання). У блоках із посиланням текст центрувався по
   цих 44px, а в блоках БЕЗ посилання - «© 2026» і «Last updated» -
   лишався вгорі коробки, яку flex розтягнув. Різниця виміряна: текст
   без посилання стояв на 13px вище за сусідній. Саме це й читалось
   як «криво».

   align-items: center вирівнює всіх по одній лінії незалежно від того,
   є всередині посилання чи ні. */
.footer-bottom{
  align-items: center;
}

/* ⚠️ І ДРУГА ПРИЧИНА: П'ЯТЬ РІВНОПРАВНИХ БЛОКІВ У space-between.
   Авторство, дата, пошта, юридичні посилання й згода розтягались по
   всій ширині однаковими проміжками по 25px, без жодної логіки поруч.
   Тепер дві групи: зліва те, що ПРО сайт, справа те, на що можна
   натиснути. Проміжок між групами тримає space-between, усередині
   груп він удвічі щільніший. */
.fb-left,
.fb-right{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 18px;
}
.fb-right{
  justify-content: flex-end;
}

/* На телефоні дві групи стають двома рядками, кожна вирівняна ліворуч:
   вирівнювання праворуч на вузькому екрані читається як помилка. */
@media (max-width: 720px){
  .footer-bottom{ flex-direction: column; align-items: flex-start; gap: 14px; }
  .fb-right{ justify-content: flex-start; }
}


/* ═══════════════════════════════════════════════════════════════════════
   ОДНА КНОПКА ЗАКРИТТЯ НА ВЕСЬ САЙТ
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠️ БУЛО ШІСТЬ РІЗНИХ ХРЕСТИКІВ, І ЦЕ ВИМІРЯНО, А НЕ НА ОКО.
   Знято обчислені стилі 21.09 на живому сайті:

     .cp-close      23×23   13,3px   чорний на #f0f0f0   радіус 0
     .cm-close      25×24   22,4px   сірий, прозоре      радіус 0
     .us-close      32×32   24px     сірий, прозоре      радіус 8px
     .eh-lb__close  44×44   1,8rem   білий на напівпрозорому, радіус є
     .nav-close     svg
     .sticky-close  ×

   ⚠️ .cp-close не мав стилів ВЗАГАЛІ: 13,3px і сіре тло rgb(240,240,240)
   це типова кнопка браузера. Тобто в панелі калькулятора стояв
   неоформлений системний елемент.

   Крім вигляду, тут ще й доступність: 23×23 і 25×24 менші за 24×24
   (WCAG 2.5.8) або на межі, і пальцем у них не влучиш.

   За зразок узято .eh-lb__close з лайтбокса - єдиний, зроблений
   правильно: 44×44, видимий фокус, стан наведення. Решта приведена до
   нього, з поправкою на світле тло.

   ⚠️ .us-close живе в плагіні upcheg-search, і стилізується звідси
   навмисно: extras.css підключається ПІСЛЯ search.css (перевірено в
   порядку <link>), тож правило виграє за рівної специфічності й
   переживе оновлення плагіна. */
.nav-close,
.cp-close,
.cm-close,
.sticky-close,
.eh-lb__close,
.us-close{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  /* ⚠️ min-* ОБОВ'ЯЗКОВІ, І ЦЕ ВИМІРЯНО ПІСЛЯ ПЕРШОЇ СПРОБИ.
     Самого width/height не вистачило: у main.css є
     @media (max-width:700px){ .sticky-close{ min-width:46px; min-height:52px } },
     а min-* перемагає width незалежно від порядку файлів. Виміряно на
     375px: кнопка лишалась 46×52, коли решта вже були 44×44. */
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--color-text-secondary);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.nav-close:hover,
.cp-close:hover,
.cm-close:hover,
.sticky-close:hover,
.us-close:hover{
  background: var(--color-surface);
  color: var(--color-blue-dark);
}
.nav-close:focus-visible,
.cp-close:focus-visible,
.cm-close:focus-visible,
.sticky-close:focus-visible,
.us-close:focus-visible{
  outline: 3px solid var(--color-blue);
  outline-offset: 2px;
}

/* Хрестик на темній смузі: там світлий текст, і сірий зник би. */
.section--blue .cm-close,
.section--blue .sticky-close{
  color: rgba(255, 255, 255, .8);
}
.section--blue .cm-close:hover,
.section--blue .sticky-close:hover{
  background: rgba(255, 255, 255, .14);
  color: #fff;
}

@media (prefers-reduced-motion: reduce){
  .nav-close, .cp-close, .cm-close, .sticky-close, .us-close{ transition: none; }
}


/* Мініатюра в картці переліку обладнання на сторінці марки.
   Розмір той самий, що в .lc-ico (38px), тож ряд карток не міняє висоту.
   object-fit: cover, бо знімки різної пропорції, а картка мусить
   лишатись рівною. */
.lc-shot{
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.lc-shot img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


/* ⚠️ ЛАЙТБОКС ТЕПЕР У СПІЛЬНОМУ ПРАВИЛІ ВИЩЕ, АЛЕ КОЛІР У НЬОГО СВІЙ.
   Він лежить поверх затемненого знімка, і сірий текст там не читався б.
   Виміряно перед правкою: 44×44 у нього вже було, але радіус 999px -
   єдиний круглий хрестик серед п'яти прямокутних. Тепер геометрія
   спільна, колір лишається світлим.
   Селектор із двома класами, щоб перебити правило в main.css. */
.eh-lb .eh-lb__close,
.eh-lb__close{
  background: rgba(255, 255, 255, .10);
  color: #fff;
  border-radius: 10px;
}
.eh-lb__close:hover{
  background: rgba(255, 255, 255, .22);
  color: #fff;
}
.eh-lb__close:focus-visible{
  outline: 3px solid #fff;
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════
   ВІДЕОКЛІПИ: КАРТКА, А НЕ РЯДОК З ПОРОЖНЕЧЕЮ
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ БУЛО: .vclip - grid 220px + 440px усередині блока на 1132px.
   Тобто 660px змісту і 472px порожнечі праворуч, у кожному кліпі.
   Два кліпи на /products/mini-splits/ ще й стояли один під одним,
   хоча поруч було місце на обидва.

   СТАЛО: кліп - самостійна картка тієї самої мови, що й решта карток
   сайту (білий фон, та сама рамка, той самий радіус). Ряд - auto-fit:
   один кліп дає одну картку по центру, два - дві поруч. Порожнечі
   немає в жодному з випадків, бо ширину задає вміст, а не фіксовані
   660px у контейнері невідомої ширини.
   ═══════════════════════════════════════════════════════════════════════ */
.vclip-row{
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  align-items: stretch;
}
/* Один кліп не має розтягуватись на всю ширину: 9:16 поруч із текстом
   на 1100px виглядає як помилка верстки. */
/* ⚠️ ОДИН КЛІП - ПО ЦЕНТРУ, І ЦЕ НЕ СМАК.
   Картка на 620px, притиснута до лівого краю контейнера на 1180px,
   лишає 560px порожнечі праворуч - око читає це як обрив верстки,
   рівно як у старому варіанті. По центру та сама порожнеча ділиться
   навпіл і читається як поле. */
.vclip-row:has(.vclip:only-child){
  grid-template-columns: minmax(320px, 680px);
  justify-content: center;
}

.vclip{
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  margin: 0;
  padding: 18px;
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  transition: box-shadow .18s ease, transform .18s ease;
}
.vclip:hover{ box-shadow: var(--shadow-card-hover); transform: translateY(-2px); }

.vclip-el{
  max-width: none;
  width: 190px;
  height: auto;
  aspect-ratio: 9 / 16;
  display: block;
  border-radius: calc(var(--radius-card) - 6px);
  background: #000;
  object-fit: cover;
}

.vclip-cap{ display: block; padding-top: 0; align-self: center; }

/* Тривалість і звук - окремим чипом, а не сірим рядком: людина в
   транспорті вирішує саме за цим рядком, чи натискати play. */
.vclip-meta{
  display: inline-block;
  margin-top: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--color-surface, #f4f6f8);
  border: 1px solid var(--color-border);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

/* На темній секції картка теж має читатись. */
.section--blue .vclip, .section-dark .vclip{
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.22);
}
.section--blue .vclip-meta, .section-dark .vclip-meta{
  background: rgba(255,255,255,.10);
  border-color: rgba(255,255,255,.28);
  color: rgba(255,255,255,.85);
}

@media (max-width: 720px){
  .vclip{ grid-template-columns: 150px minmax(0, 1fr); gap: 14px; padding: 14px; }
  .vclip-el{ width: 150px; }
}
@media (max-width: 420px){
  .vclip{ grid-template-columns: 1fr; justify-items: start; }
  .vclip-el{ width: 100%; max-width: 220px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   ФОТО У ВІДГУКАХ: ДОКАЗ, А НЕ ВИПАДКОВІСТЬ
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ ЩО БУЛО НЕ ТАК. Заміряно на головній: три сусідні картки однакової
   висоти 363×365, а знімок у них починався на 168px, 259px і 213px від
   верху картки. Причина: .review-card - display:block, і .rv-shots
   просто тече за текстом, довжина якого в кожному відгуку своя.
   На /reviews/* цієї біди немає, бо там .rv-foot{margin-top:auto};
   у картках слайдера цього правила не було ніколи.

   ⚠️ ДРУГЕ: ШІСТЬ конкурентних правил розміру - 96, 84, 72, 64 і 58px,
   плюс окреме :only-child. Реальний розмір вирішувала специфічність,
   а не задум, і на цьому я спіймався вже під час правки: перша версія
   цього блоку не спрацювала, бо `.review-card .rv-shots .rv-shot:only-child`
   має (0,4,0) через псевдоклас і перебиває (0,3,0) без нього.
   Тому нижче обидві форми - і звичайна, і :only-child.

   ⚠️ ЧОМУ НЕ ШИРОКА СМУГА НА ВСЮ КАРТКУ. Джерело - квадрат 600×600
   (розмір everheat-square). Смуга 319×110 обрізала б квадрат до тонкої
   стрічки й з'їла б сам предмет зйомки. Тому квадрати, але більші й на
   одній лінії.
   ═══════════════════════════════════════════════════════════════════════ */

/* 1. Спільна лінія низу. Текст розсуває картку, а підпис зі знімками
      лишається притиснутим до низу - однаково в усіх картках ряду. */
.review-card{ display: flex; flex-direction: column; }
.review-card > p{ flex: 1 1 auto; }

/* 2. Сітка знімків: завжди заповнює ширину картки.
      1 знімок - фіксовані 112px (на всю ширину квадрат був би вищий за
      саму картку). 2–4 - рівні частки, тож ряд завжди виглядає складеним. */
/* ⚠️ .person-quote ТУТ ОБОВʼЯЗКОВИЙ, І ЙОГО ЗАБУЛИ. Виміряно 22.09.2026
   на /about/team/eric/: знімок відгуку віддавався розміром 3002×3002px,
   сторінка ставала 6180px завширшки при вікні 1440, знизу зʼявлялась
   горизонтальна прокрутка.

   Причина рівно в цьому переліку. Нижче, у блоці «Сам кадр»,
   .person-quote Є - і кадр там дістає width:auto; height:auto, бо розмір
   мусить прийти від сітки. Але сітки .person-quote не діставав: у цьому
   переліку його немає, тож контейнер лишався flex-рядком зі спільного
   .rv-shots{display:flex}. Кадр із width:auto у flex-рядку бере
   ВЛАСНИЙ розмір зображення - 3000px.

   ⚠️ Два переліки селекторів, які мусять збігатися, - це пастка. Вона
   тут уже спрацювала: спершу .person-quote не знали взагалі (третій
   компонент відгуків знайшли, коли зведення не зійшлось на 3 картки),
   потім додали в один блок із двох. Правити треба ОБИДВА. */
.review-card .rv-shots,
.rv-foot .rv-shots,
.person-quote .rv-shots{
  display: grid;
  gap: 8px;
  grid-template-columns: 112px;
}
.review-card .rv-shots:has(.rv-shot:nth-child(2)),
.rv-foot .rv-shots:has(.rv-shot:nth-child(2)),
.person-quote .rv-shots:has(.rv-shot:nth-child(2)){ grid-template-columns: repeat(2, minmax(0, 1fr)); }
.review-card .rv-shots:has(.rv-shot:nth-child(3)),
.rv-foot .rv-shots:has(.rv-shot:nth-child(3)),
.person-quote .rv-shots:has(.rv-shot:nth-child(3)){ grid-template-columns: repeat(3, minmax(0, 1fr)); }
.review-card .rv-shots:has(.rv-shot:nth-child(4)),
.rv-foot .rv-shots:has(.rv-shot:nth-child(4)),
.person-quote .rv-shots:has(.rv-shot:nth-child(4)){ grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* 3. Сам кадр. Один розмір замість п'яти: квадрат, задається сіткою. */
.review-card .rv-shots .rv-shot,
.rv-foot .rv-shots .rv-shot,
.person-quote .rv-shots .rv-shot{
  flex: none;
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  overflow: hidden;
  background: var(--color-border);
  border: 1px solid rgba(0,0,0,.08);
  position: relative;
}
/* Та сама заява для :only-child: без неї стара латка на 84px перебиває
   правило вище власним псевдокласом. Специфічність однакова, виграє
   порядок - тому це має стояти саме тут, а не раніше. */
.review-card .rv-shots .rv-shot:only-child,
.rv-foot .rv-shots .rv-shot:only-child,
.person-quote .rv-shots .rv-shot:only-child{
  flex: none;
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  border: 1px solid rgba(0,0,0,.08);
}
.review-card .rv-shots img,
.rv-foot .rv-shots img,
.person-quote .rv-shots img{
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .25s ease;
}

/* 4. Знімок клікабельний - це має бути видно до кліку.
      Кадр не рухається, рухається лише зображення всередині. */
.rv-zoom:hover img, .rv-zoom:focus-visible img{ transform: scale(1.07); }
.rv-shot::after{
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px transparent;
  transition: box-shadow .2s ease;
  pointer-events: none;
}
.rv-shot:hover::after{ box-shadow: inset 0 0 0 2px var(--color-orange); }

/* 5. Тонка лінія відділяє доказ від тексту відгуку. */
.review-card .rv-shots{
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--color-border);
}

/* 6. На сторінках /reviews/* підпис і знімок стоять поруч - там лінія
      зайва, бо .rv-foot уже відокремлений. */
.rv-foot .rv-shots{ margin-top: 0; padding-top: 0; border-top: 0; }

/* 7. Телефон: чотири кадри в ряд по 74px читаються, три і два - тим
      паче. Нічого не міняємо, крім відступів. */
@media (max-width: 480px){
  .review-card .rv-shots{ gap: 6px; margin-top: 12px; padding-top: 12px; }
  .review-card .rv-shots{ grid-template-columns: 96px; }
  .review-card .rv-shots:has(.rv-shot:nth-child(2)){ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════════════════
   МОБІЛЬНІ ЦІЛІ ДОТИКУ Й КЕГЛЬ
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ ЧОМУ САМЕ МОБІЛЬНИЙ. Search Console за 16 місяців: CTR з мобільного
   2.21% проти 0.62% з настільного - утричі вище. Кожна дрібна ціль б'є
   саме по тому сегменту, який найкраще конвертує.

   ⚠️ 44px НЕ ДЛЯ ВСІХ. WCAG 2.5.8 прямо ВИНОСИТЬ за дужки посилання
   всередині речення: розтягнути їх означало б розірвати міжрядковий
   інтервал абзацу. Тому тут збільшені лише САМОСТІЙНІ цілі, а інлайнові
   посилання (`.fa-note a`, `.cb-text a`, `.consent-note a`) лишаються
   як є - їм виправлено кегль, а не геометрію.

   ⚠️ КРАПКИ СЛАЙДЕРА - НЕ 44px. Заміряно: п'ять слайдерів, 4–6 крапок,
   крок 16px. Область 44px на кожну дала б перекриття сусідніх цілей і
   промахи замість влучань. Крок збільшено до 32px: ряд із шести займає
   192px при екрані 375px, а область дотику 32×44 удвічі перевищує
   мінімум WCAG 24×24 і ні з чим не перетинається.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px){

  /* 1. Крапки слайдера: видимий кружок більший, область дотику - окремо.

     ⚠️ РОЗМІР І ВІДСТУП - ЧЕРЕЗ ЗМІННІ SWIPER, А НЕ ПРЯМИМИ ПРАВИЛАМИ.
     swiper.min.css підключений ПІСЛЯ extras.css (порядок у черзі:
     search, main, extras, swiper, hero-bg). За однакової специфічності
     виграє той, хто пізніше, тож `.swiper-pagination-bullet{width:10px}`
     тут просто не спрацював: крапка лишалась 8px, а крок 16px. Область
     ::after застосувалась лише тому, що в Swiper такого правила немає -
     і це давало найгірший варіант: області по 32px з кроком 16px
     ПЕРЕКРИВАЛИСЬ, тобто промахи замість влучань.
     Змінні Swiper читає його власне правило, тож порядок не важить.

     ⚠️ І ЩЕ ОДНА ПАСТКА, ВЖЕ З ЦИМИ ЗМІННИМИ. Тема виносить пагінацію
     з `.swiper` у власний `.slider-nav` (див. main.css). Змінна,
     оголошена на `.swiper`, до крапок просто не доходить - вони вже
     не її нащадки. Тому оголошення стоїть на ОБОХ. */
  .swiper,
  .slider-nav{
    --swiper-pagination-bullet-width: 10px;
    --swiper-pagination-bullet-height: 10px;
    --swiper-pagination-bullet-horizontal-gap: 11px;   /* крок 10 + 22 = 32px */
  }
  .swiper-pagination-bullet{ position: relative; }
  .swiper-pagination-bullet::after{
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 32px;
    height: 44px;
  }

  /* 2. Кнопка пошуку в шапці: було 40×40, не вистачало чотирьох пікселів. */
  .us-open{ width: 44px; height: 44px; }

  /* 3. Самостійні посилання-кнопки. Саме вони, а не текст у реченні. */
  .rating-line a,
  .fa-all,
  .link-btn,
  .reviews-all a{
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* 4. Кегль. 11.5px у банері згоди - нижче межі читабельності на
        телефоні; 12.5px лишає той самий вигляд, але текст читається. */
  .consent-note,
  .consent-note a{ font-size: 12.5px; line-height: 1.5; }
  .offer-badge{ font-size: 12.5px; }
  .fa-count{ font-size: 12.5px; }
  /* Дрібний рядок під ціною в калькуляторі: «you pay only for the repair».
     Саме та фраза, що знімає заперечення перед дзвінком - 11.5px на
     телефоні її ховає. */
  .calc-cta__price i{ font-size: 12.5px; }
}

/* ---------- Зона обслуговування: індекси біля міста ---------- */
/* ⚠️ .loc-list li у main.css - flex У РЯДОК, колонки від 190px.
   Для Сіетла це 36 кодів одним рядком: картка розірвала б сітку.
   Тому для списку з індексами - колонка, назва зверху, коди під нею,
   і ширша мінімальна колонка. */
.loc-list--zip{ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.loc-list--zip li{
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
.loc-zip{
  font-size: .78rem;
  line-height: 1.55;
  color: var(--color-text-secondary, #5b6068);
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════════════════════════════════════
   ГОЛОВНА: ГЕРОЙ БЕЗ БІЧНОГО ФОТО

   Рішення власника 26.09.2026: знімок у правій колонці героя прибрати.
   На телефоні він стояв першим під текстом і був найважчою картинкою
   першого екрана.

   ⚠️ САМОГО ВИДАЛЕННЯ РОЗМІТКИ ЗАМАЛО. У main.css стоїть
   `.hero .container{ grid-template-columns: 1.05fr .95fr }`. Прибрати
   другу колонку означає лишити текст на 52% ширини, а праворуч діру:
   порожня комірка сітки все одно займає своє місце. Це той самий випадок,
   що описаний у hero-bg.css для класу hero-hide-slot.

   ⚠️ ЧОМУ НЕ ПЕРЕВИКОРИСТАВ hero-hide-slot. Той клас ставиться лише коли
   активна підкладка героя (`has-hero-bg`). Якщо підкладку колись вимкнуть,
   клас зникне, а фото на головній уже видалене з шаблону - і сітка знову
   лишилась би дві колонки з дірою. Прив'язка до body.home від цього не
   залежить.

   ⚠️ max-width 760px - те саме число, що тема вже вживає для героя без
   слота. Без нього рядок розтягнувся б на всі 1132px контейнера, а це
   майже 100 символів, тобто поза стелею WCAG 1.4.8.
   ══════════════════════════════════════════════════════════════════════ */
body.home .hero .container{
  grid-template-columns: 1fr;
  gap: 0;
}
body.home .hero .container > div:first-child{
  max-width: 760px;
}

/* ═══════════════════════════════════════════════════════════════════════
   DIAMOND CONTRACTOR: ШИРИНА БЛОКІВ
   26.09.2026, третя редакція. Дві попередні були неправильні, і замовник
   обидва рази показав це знімком.

   ІСТОРІЯ, ЩОБ НЕ ПОВТОРИТИ ВТРЕТЄ:

   1. Спершу текст був у .prose. Це компонент ТЕКСТОВИХ сторінок (у main.css
      підписаний «About / Portfolio / Contacts / юридичні»), живе рівно на
      /about/, /terms/, /privacy-policy/. Він центрований: 620px, margin auto.
      Поруч на посадковій стоять сітки на 24px - сторінка стала рваною,
      п'ять різних лівих країв.

   2. Потім я перекрив лише max-width (640, щоб збігалось із .section-head) і
      лишив успадковане margin:0 auto. Текст і заголовок зійшлись МІЖ СОБОЮ,
      і далі не збігались із рештою. Половинчаста правка.

   3. Потім прибрав центрування: текст став на 24px, як герой. Але ширина
      лишилась 620 при контейнері 1132 - справа півекрана порожнечі.
      Замовник: «нахуя оце скорочення ширини, треба щоб ширина скрізь була
      однакова».

   ВІН МАЄ РАЦІЮ, І В САЙТА ВЖЕ Є ВІДПОВІДЬ. Довгий текст на повну ширину
   тримає .seo-copy: до 1024px одна колонка, від 1024px - column-count:2 з
   проміжком 56px. Ширина блоку при цьому повна, а рядок лишається ~460px,
   тобто в межах норми з main.css (45-80 символів).

   Тому текстові блоки цих двох сторінок беруть .seo-copy - справжній
   компонент сайту, а не мій новий клас. Тут лишається тільки те, чого в
   ньому немає.
   ═══════════════════════════════════════════════════════════════════════ */

/* Статусна коробка: ширина як у всіх решти блоків секції.
   ⚠️ .offer-box народився промо-банером (max-width:720, margin auto,
   text-align:center) - широка коробка ПО ЦЕНТРУ сторінки. Після зняття
   знижки він вживається рівно на цих двох сторінках, прецеденту не має, і
   будь-яка його власна ширина робила б його єдиним блоком, що не збігається
   з сусідами. Сам .offer-box не чіпаємо. */
.dc-box{ max-width: none; margin-inline: 0; text-align: left; }

/* ⚠️ ВНУТРІШНОСТІ КОРОБКИ ТЕЖ БУЛИ ПІД ЦЕНТРУВАННЯ, І САМОЇ .dc-box
   ЗАМАЛО. У власних правилах вони мають свою міру і свій auto:

       .offer-text{ margin:0 auto;    max-width:52ch; }
       .offer-note{ margin:16px auto 0; max-width:56ch; }

   У широкій лівій коробці це давало абзац, зсунутий усередину відносно
   власного заголовка - видно на знімку замовника. Клас-обгортка ширину
   нащадків не міняє: кожен із них тримає свою.

   Урок той самий, що й з .prose: перевіряти треба не сам блок, а всі його
   краї разом із сусідами. */
.dc-box .offer-text,
.dc-box .offer-note{ max-width: none; margin-left: 0; margin-right: 0; }

/* Текст цих двох сторінок: ПОВНА ширина, ОДНА колонка.
   ⚠️ ДВІ КОЛОНКИ ТУТ БУЛИ ПОМИЛКОЮ. Я взяв .seo-copy цілком, разом із
   column-count:2, бо шукав «як показати довгий текст на повну ширину», і
   компонент справді це вміє. Але дві колонки на цьому сайті - ознака
   SEO-блоку внизу сторінки, який скімлять, а не читають. Основний текст
   сторінки так верстати не можна: око мусить іти вниз до кінця колонки й
   вертатись угору.

   Типографіку .seo-copy лишаємо: це перевірений на 21 сторінці набір
   (колір, кегль, власні маркери списків, відступи li). Знімаємо рівно те,
   що зайве, - колонки й стелю ширини. */
.dc-copy{ column-count: 1; max-width: none; }

/* Білий проміжок перед сірою смугою. Рішення замовника 26.09.2026: 48px,
   поки що ТІЛЬКИ на двох сторінках Diamond Contractor.

   ⚠️ ЧОМУ НЕ ПРАВИЛОМ НА `.section--surface` ОДРАЗУ. Цей клас стоїть на 41
   сторінці з 52 (на /products/mini-splits/ шість смуг, на
   /services/cooling-repair/ пʼять). Глобальне правило перебудувало б ритм
   усього сайту одним рядком, і перевіряти довелось би 41 сторінку. Спершу
   дивимось на двох; якщо заходить - той самий рядок міняє селектор.

   ⚠️ 48px, А НЕ НОВЕ ЧИСЛО: це той самий padding, що вже має `.section`.
   У макет не вноситься нова величина.

   ⚠️ СУСІДНІХ СМУГ НА ЦИХ СТОРІНКАХ НЕМАЄ (послідовність перевірена:
   surface, plain, plain, surface, plain...). Це важливо, бо в сайта є
   правило `.section--surface + .section--surface{ border-top: 1px }` - на
   двох смугах поспіль вийшли б і рамка, і проміжок одночасно. */
.dc-gap{ margin-top: 48px; }

/* Сітка знімків на сторінці Diamond Contractor: три колонки, не чотири.
   ⚠️ .shots-grid це columns: 240px 4 - багатоколонковий макет, а не grid.
   Число 4 тут стеля, а не вимога: при контейнері 1132px браузер робить саме
   чотири колонки, і три знімки лишають четверту порожньою. Ряд виглядає
   притиснутим ліворуч, із діркою 286px справа.

   ⚠️ ЧОМУ НЕ `columns: 3`, А `columns: 240px 3`. Перше число - мінімальна
   ширина колонки; прибравши його, ми змусили б телефон теж малювати три
   колонки по ~110px. Із ним поведінка на вузьких екранах лишається такою
   самою, як у решти сіток сайту, а стеля просто опускається з 4 до 3.

   ⚠️ Правило адресне: на брендовій сторінці знімків одинадцять, і там
   чотири колонки якраз доречні. */
.dc-shots{ columns: 240px 3; }


/* ═══════════════════════════════════════════════════════════════════════
   27.09.2026 — ЧОТИРИ ПРАВКИ ЗА ЗАМІРАМИ В БРАУЗЕРІ, А НЕ ЗА ВИГЛЯДОМ
   ═══════════════════════════════════════════════════════════════════════ */

/* 1. СІТКА ЗНІМКІВ: БАГАТОКОЛОНКОВИЙ МАКЕТ → FLEX ІЗ ЦЕНТРУВАННЯМ
   ─────────────────────────────────────────────────────────────────────
   ⚠️ ЗАМІРЯНО на /about/team/ при 1440px: .shots-grid це columns: 240px 4,
   тобто чотири колонки по 274px у контейнері 1132px. П'ять знімків браузер
   розклав як 2+1+2, і ЧЕТВЕРТА КОЛОНКА ЛИШИЛАСЬ ПОРОЖНЬОЮ: плитки стоять
   на 154, 440, 726, а простір 1012…1286 порожній. Звідси «фото злізли в
   ліво» - це не відступи, це порожня колонка праворуч.

   ⚠️ ЦЕ НЕ ОДНА СТОРІНКА. Компонент живе на 24 сторінках, кількість
   знімків від 1 до 106. На /brands/lennox/ і /brands/senville/ знімок
   ОДИН - він стоїть у першій колонці, а три порожні тягнуться праворуч.
   Раніше це лікувалось адресно (.dc-shots), тобто симптом на одній
   сторінці; тут виправлено причину.

   ⚠️ ЧОМУ FLEX, А НЕ GRID. Grid теж вирівняв би колонки, але останній
   неповний ряд у grid лишається притиснутим ліворуч - рівно та сама
   скарга. justify-content: center у flex центрує САМЕ неповний ряд.

   ⚠️ ЧИСЛА ПІДІБРАНІ ТАК, ЩОБ ПОВНИЙ РЯД НЕ ЗМІНИВСЯ: flex-basis 240 +
   gap 12 при 1132px дають ті самі чотири плитки по 274px, що й зараз
   (1132 − 3×12 = 1096; 1096 ÷ 4 = 274). Тобто сторінки з 4, 8, 12
   знімками виглядатимуть точнісінько як раніше.

   ⚠️ max-width ОБОВ'ЯЗКОВИЙ: без нього самотній знімок у неповному ряду
   розтягнувся б на всю ширину контейнера.

   ⚠️ :not(.shots-grid--steps) ОБОВ'ЯЗКОВИЙ. Варіант --steps це справжній
   grid-template-columns (рядок 1316) ПЛЮС data-mslider. Без виключення
   моє правило перемогло б за однаковою специфічністю просто тому, що
   стоїть нижче у файлі, і зламало б слайдер «Behind The Panel». */
.shots-grid:not(.shots-grid--steps){
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  columns: auto;            /* знімаємо багатоколонковий макет */
}
.shots-grid:not(.shots-grid--steps) > .shots-item{
  flex: 1 1 240px;
  max-width: 360px;
  margin: 0;                /* проміжок тепер дає gap, а не margin-bottom */
}

/* Телефон: ті самі дві плитки в ряд, що й раніше (@media 560px вище).
   Заміряно на 375px: контейнер 327px, basis 140 + gap 8 → рівно дві. */
@media (max-width: 560px){
  .shots-grid:not(.shots-grid--steps){ gap: 8px; }
  .shots-grid:not(.shots-grid--steps) > .shots-item{ flex-basis: 140px; }
}

/* Diamond Contractor: три в ряд замість чотирьох.
   ⚠️ Правило `.dc-shots{ columns: 240px 3 }` вище (рядок ~2689) тепер
   НЕДІЙСНЕ: багатоколонкові властивості до flex-контейнера не
   застосовуються. Лишаю його на місці, щоб не чіпати історію файлу, але
   працює саме це. */
.dc-shots:not(.shots-grid--steps) > .shots-item{ flex-basis: 320px; }


/* 2. КАРТА НА /contacts/ ПРИТИСНУТА ДО КАРТОК
   ─────────────────────────────────────────────────────────────────────
   ⚠️ ЗАМІРЯНО: проміжки між блоками секції 17px, 44px, 36px — і
   .profile-grid → .map-slot = РІВНО 0px. Тобто сірий короб карти
   починається там, де закінчуються картки. Беремо 36px — те саме число,
   що вже має .profile-grid зверху, щоб ритм секції лишився однаковим. */
.map-slot{ margin-top: 36px; }

/* ── Карта за кліком ──────────────────────────────────────────────────
   ⚠️ Замість службового рядка «Map placeholder…», який бачив кожен
   відвідувач, тут адреса й кнопка. Карта вставляється в DOM лише після
   натискання, бо банер згоди на сайті є, а Google ставить куки в мить
   завантаження iframe. */
.map-slot{
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  text-align: center; padding: 28px 20px;
}
.map-slot .ms-addr{ display: flex; flex-direction: column; gap: 4px; }
.map-slot .ms-addr b{ font-size: 1.05rem; }
.map-slot .ms-addr span{ color: var(--color-text-secondary); }
.map-slot .ms-actions{ display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.map-slot .ms-note{ margin: 0; font-size: .82rem; color: var(--color-text-secondary); }
/* ⚠️ Після вставки iframe короб перестає бути вузьким блоком із кнопкою,
   тому відступи прибираємо, інакше навколо карти лишиться сіра рамка. */
.map-slot.is-loaded{ padding: 0; gap: 0; }
.map-slot iframe{
  width: 100%; height: 380px; border: 0; display: block;
  border-radius: var(--radius-card);
}
.map-slot.is-loaded .ms-addr{ padding: 16px 20px 0; }
@media (max-width: 640px){ .map-slot iframe{ height: 280px; } }


/* 3. САМОТНЯ КНОПКА ПІД БЛОКОМ «BEHIND THE PANEL»
   ─────────────────────────────────────────────────────────────────────
   ⚠️ ЗАМІРЯНО: заголовок секції .section-head центрований (400…1040), а
   кнопка починалась на 154 — по лівому краю контейнера. Кнопка лежала в
   голому <p> з text-align: start.

   ⚠️ КЛАС У ШАБЛОНІ, А НЕ СЕЛЕКТОР НА ГОЛИЙ <p>. Правило виду
   `.container > p:has(.btn)` зачепило б кожну кнопку в тексті по всьому
   сайту, зокрема ті, що стоять ліворуч навмисно. Шаблонів із цим блоком
   рівно два (heating-installation і cooling-installation) — перевірено
   по всіх 51 шаблоні теми. */
.btp-cta{ margin-top: 20px; text-align: center; }


/* 4. КАЛЬКУЛЯТОР НА ТЕЛЕФОНІ
   ─────────────────────────────────────────────────────────────────────
   ⚠️ ХРЕСТИК БУВ НЕВИДИМИЙ, І ЦЕ ЧИСЛО, А НЕ ВРАЖЕННЯ. Заміряно:
   колір rgb(91,96,104) на тлі rgb(20,82,143) — контраст 1.26:1 при
   мінімумі 3:1 для елементів керування (WCAG 2.5.11 / 1.4.11).

   ⚠️ Правило «хрестик на темній смузі» у файлі вже БУЛО (див. вище,
   .section--blue .cm-close) — просто .calc-panel до нього не внесли.
   Тобто випадок передбачили, а один клас забули. */
.calc-panel .cp-close{ color: rgba(255, 255, 255, .85); }
.calc-panel .cp-close:hover{
  background: rgba(255, 255, 255, .14);
  color: #fff;
}

/* ⚠️ КНОПКА «ВГОРУ» ЛЕЖАЛА ПОВЕРХ КНОПКИ «BACK».
   Заміряно на 375×812: .back-to-top займає 20…64 × 686…730, а кнопка
   Back — 16…182 × 672…723. Перекриття 44×37px, і z-index 65 проти 5 у
   .wiz-nav означає, що стрілка малюється ЗВЕРХУ. Тобто лівий край «Back»
   був не натискний.

   ⚠️ ДВІ ПРАВКИ, А НЕ ОДНА, І ДРУГА — СТРАХОВКА.
   `bottom: 164px` (152px двох смуг + 12px) прибирає перекриття, але
   селектор спирається на :has(). Якщо браузер його не знає, правило
   відкидається цілком — тому z-index у .wiz-nav піднято окремим
   правилом: навіть без :has() смуга з кнопками перекриє стрілку, а не
   навпаки. */
/* ⚠️ СЕЛЕКТОР .is-wizard .wiz-nav, А НЕ ПРОСТО .wiz-nav — І ЦЕ ВИМІРЯНО
   ПІСЛЯ ПЕРШОЇ СПРОБИ. Я написав `.wiz-nav{ z-index:66 }`, залив, і
   заміряв знову: z-index лишився 5. Бо в main.css правило записане як
   `.is-wizard .wiz-nav{ ... z-index:5 }` — специфічність (0,2,0) проти
   моїх (0,1,0), і порядок файлів тут ні до чого. Порядок <link>
   перевірено окремо: search.css → main.css → extras.css, тож за рівної
   специфічності виграє це правило. */
.is-wizard .wiz-nav{ z-index: 66; }
body.calc-bar-on:has(.wiz-nav) .back-to-top{ bottom: 164px; }

/* ⚠️ ЦІНА ВИЛАЗИЛА ЗА СВОЮ КОРОБКУ — ЦЕ Й БУЛО «ВСЕ НАЛАЗИТЬ».
   Заміряно на 375px: .cp-mini має white-space: nowrap і при 20.8px
   потребує 187px, а коробка .cp-head-text — 147px. Сорок зайвих пікселів
   ішли під каретку розкриття і далі під кнопку «Book visit».

   ⚠️ ДВІ ДІЇ РАЗОМ, БО ОДНІЄЇ НЕ ВИСТАЧАЄ. Тільки зменшити шрифт — ціна
   стає дрібною; тільки віддати місце — 187px однаково не влазять у 177px
   смуги. Тому: смуга віддає 6px (лівий відступ 20→14) і 2px (проміжок
   10→8), а шрифт падає з 1.3rem до 1rem. 187 × 16 ÷ 20.8 ≈ 144px при
   доступних 155px — із запасом. */
@media (max-width: 400px){
  .calc-panel .cp-bar{ padding-left: 14px; gap: 8px; }
  .calc-panel .cp-mini{ font-size: 1rem; }
}


/* ═══════════════════════════════════════════════════════════════════════
   27.09.2026 — ПОРОЖНЕЧА ПІСЛЯ ЗАКРИТТЯ СМУГИ РОЗРАХУНКУ
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ ЗАМІРЯНО на 375×812 після кліку по хрестику: смуга сховалась, клас
   calc-bar-on знявся, а .calc-layout лишився з padding-bottom: 168px, і
   .wiz-nav лишилась на 660…737 при висоті екрана 812. Тобто під кнопками
   «Back / Next» зяяли 75px порожнечі, а внизу сторінки — ще 168px.

   Причина: обидва запаси в main.css висять на .is-wizard, а не на
   calc-bar-on, тому зняття класу на них не впливало взагалі.

   ⚠️ 92px замість 168px — це висота однієї смуги (.wiz-nav 77px) плюс
   невеликий відступ. Нуль ставити не можна: сама .wiz-nav лишається
   фіксованою і накрила б кінець сторінки. */
body.calc-bar-off .is-wizard .wiz-nav{
  bottom: calc(env(safe-area-inset-bottom) + var(--consent-h, 0px));
}
body.calc-bar-off .is-wizard .calc-layout{
  padding-bottom: 92px;
}

/* ⚠️ Мікрофон у формі на сторінці /search/ (додається з JS, бо залежить
   від підтримки SpeechRecognition у браузері). Форма там - звичайний
   рядок із полем і кнопкою, тож кнопку треба лише вирівняти й прибрати
   рамку: решту стилів .us-mic уже має з search.css. */
.us-mic--page{
  flex: none;
  align-self: center;
  margin-left: -46px;
  margin-right: 10px;
  background: none;
  border: 0;
  z-index: 1;
}


/* ═══════════════════════════════════════════════════════════════════════
   27.09.2026 — ВІДСТУП МІЖ СЕКЦІЯМИ ПО ВСЬОМУ САЙТУ
   ═══════════════════════════════════════════════════════════════════════
   Раніше 48px діяли лише на двох сторінках Diamond Contractor через
   адресний клас `.dc-gap`. За рішенням власника розкочується всюди.

   ⚠️ ЛИШЕ ТАМ, ДЕ ПОПЕРЕДНЯ СЕКЦІЯ НЕ СІРА. У main.css уже є правило
   `.section--surface + .section--surface{ border-top: 1px }`: дві сірі
   смуги поспіль розділяє рамка. Додавши їм ще й проміжок, ми отримали б
   рамку, що висить у порожнечі, — і замість одного розділювача два різні.
   Тому сусідні сірі секції лишаються без відступу, а відступ отримує та,
   що йде після звичайної.

   ⚠️ .section--blue теж виключена: синя смуга це повноекранний акцент, і
   біла щілина перед нею читається як помилка верстки, а не як повітря. */
.section:not(.section--surface):not(.section--blue) + .section--surface{
  margin-top: 48px;
}

/* На телефоні 48px з'їдають забагато екрана: там і так усе стосом. */
@media (max-width: 640px){
  .section:not(.section--surface):not(.section--blue) + .section--surface{
    margin-top: 28px;
  }
}


/* ═══════════════════════════════════════════════════════════════════════
   27.09.2026 — КАРТКА ОБЛАДНАННЯ
   ═══════════════════════════════════════════════════════════════════════
   ⚠️ Заміряно: блок .product-facts на всіх чотирьох сторінках обладнання
   містив РІВНО ОДНЕ число, «From $4,600». Решта фактів жила прозою нижче.

   ⚠️ Картка навмисно НЕ картка-коробка з рамкою: вона стоїть у герої
   поруч із заголовком і ціною, і ще одна рамка всередині героя читалась
   би як чужий вставлений блок. Тому розділювачі, а не бордер. */
.pcard{
  margin: 14px 0 18px;
  max-width: 520px;
}
.pcard-block + .pcard-block{
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--color-border);
}
.pcard-h{
  font-size: .76rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: 8px;
}
.pcard-rows{
  list-style: none;
  margin: 0;
  padding: 0;
}
.pcard-rows li{
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 4px 0;
  font-size: .95rem;
}
/* ⚠️ tabular-nums обовʼязкові: без них «$4,600» і «$11,100» розходяться
   по ширині цифр, і колонка цін перестає бути колонкою. */
.pcard-v{
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pcard-k{ color: var(--color-text-secondary); }
.pcard-note{
  margin: 8px 0 0;
  font-size: .82rem;
  color: var(--color-text-secondary);
}
.pcard-brands{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.pcard-brands a{
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: .86rem;
  text-decoration: none;
  color: var(--color-blue-dark);
}
.pcard-brands a:hover{ background: var(--color-surface); }
.pcard-more{ margin: 12px 0 0; font-size: .9rem; }

/* ============ КАРТКА ОБЛАДНАННЯ НА СВІТЛІЙ СЕКЦІЇ ============
   Картка більше не лежить у фото-героєві (див. коментар у
   templates/page-products-*.php). Тут вона отримує власну поверхню і
   розкладається в колонки, щоб на широкому екрані не тягнутись однією
   вузькою стрічкою на 520px. */
.pcard{
  max-width: none;
  margin: 0;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: 24px 26px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 26px 44px;
  align-items: start;
}

/* ⚠️ У grid КОЖЕН прямий нащадок стає коміркою. `.pcard-more` лежить
   поруч із блоками, тому без цього рядка посилання «Full price
   breakdown» поїхало б четвертою колонкою замість підсумкового рядка. */
.pcard-more{
  grid-column: 1 / -1;
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
}

/* Колонки вже розділені проміжком, лінія між ними була б зайвою. */
.pcard-block + .pcard-block{ margin-top: 0; padding-top: 0; border-top: 0; }

/* ⚠️ Значення успадковували білий колір від героя. На світлій поверхні
   білим по білому не видно нічого, тому колір задаємо явно, а не
   покладаємось на те, від кого успадкуємо. */
.pcard-v{ color: var(--color-text); }

@media (max-width: 860px){
  .pcard{ grid-template-columns: 1fr; gap: 0; padding: 18px 20px; }
  .pcard-block + .pcard-block{
    margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--color-border);
  }
  .pcard-more{ margin-top: 16px; }
}
