/* ==========================================================================
   STYLES.CSS — стилі секцій сайту
   Підключається ПІСЛЯ tokens.css
   Секції додаватимуться сюди поступово, окремими блоками
   ========================================================================== */

/* ==========================================================================
   RESET
   ========================================================================== */

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

/* ==========================================================================
   SCROLL-REVEAL — fade-in + translate на завантаженні (hero) та при скролі
   (IntersectionObserver), керується js/reveal.js
   ========================================================================== */

.scroll-reveal {
  opacity: 0;
  /* Safari-фікс: заздалегідь промотує шар для майбутнього opacity/
     transform-переходу (IntersectionObserver, js/reveal.js) — Chrome
     і так достатньо агресивно робить це сам, Safari — ні */
  will-change: opacity, transform;
  transition: opacity .65s var(--ease-smooth),
              transform .65s var(--ease-smooth);
  /* Stagger — через CSS custom property (js/reveal.js виставляє лише
     --reveal-delay, ніколи transition-delay/transition напряму), тому
     затримка структурно прив'язана ТІЛЬКИ до opacity/transform і не може
     "протекти" на будь-яку іншу transition-властивість цього ж елемента
     (напр. color/border-color на hover) — на відміну від колишнього
     inline transition-delay, тут немає race condition і нічого не треба
     знімати таймером після появи */
  transition-delay: var(--reveal-delay, 0s);
}
.scroll-reveal-up {
  transform: translateY(40px);
}
.scroll-reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Елементи, що поєднують .scroll-reveal із ВЛАСНИМ hover-transition
   (.cta-button, .see-all-work) — їхня власна `transition: color ...`
   (equal specificity, пізніше в каскаді) інакше повністю перекрила б
   opacity/transform-transition вище (shorthand `transition` не
   мерджиться між різними правилами, лише повністю замінюється).
   Compound-селектор (0,2,0) — гарантований переможець незалежно від
   порядку в файлі — об'єднує обидва набори властивостей в ОДНЕ
   оголошення: --reveal-delay торкається лише opacity/transform,
   hover-властивості завжди 0s. Додаючи новий .scroll-reveal-елемент із
   власним hover-transition — додай такий самий compound-рядок тут */
.cta-button.scroll-reveal {
  transition:
    opacity .65s var(--ease-smooth) var(--reveal-delay, 0s),
    transform .65s var(--ease-smooth) var(--reveal-delay, 0s),
    color 300ms ease;
}

.see-all-work.scroll-reveal {
  transition:
    opacity .65s var(--ease-smooth) var(--reveal-delay, 0s),
    transform .65s var(--ease-smooth) var(--reveal-delay, 0s),
    color 200ms ease,
    border-color 200ms ease;
}

.delay-0   { transition-delay: 0ms;   animation-delay: 0s; }
.delay-100 { transition-delay: 100ms; animation-delay: .1s; }
.delay-200 { transition-delay: 200ms; animation-delay: .2s; }
.delay-300 { transition-delay: 300ms; animation-delay: .3s; }
.delay-400 { transition-delay: 400ms; animation-delay: .4s; }
.delay-500 { transition-delay: 500ms; animation-delay: .5s; }

/* ==========================================================================
   BASE
   ========================================================================== */

/* Фікс: горизонтальний скрол/свайп сторінки на Mobile (375–767px) —
   overflow-x:hidden лише на body (стара версія) не блокував сам
   viewport-скрол (root scroller у стандартному режимі — html, не body).
   Додавання overflow-x:hidden напряму на html теоретично мало б це
   виправити, але емпірично (headless Chrome, реальний scroll-тест)
   ЛАМАЄ .services__sticky (position:sticky перестає прилипати під час
   скролу Services-таблички) — відомий браузерний нюанс: overflow-x,
   відмінний від visible, змушує html обчислювати overflow-y як auto,
   html стає власним scroll-контейнером, і хоча він візуально збігається
   з viewport, sticky-елементи глибоко всередині втрачають прилипання.
   `overflow-x: clip` (замість hidden) на ОБОХ html/body дає той самий
   результат — жодного горизонтального скролу/свайпу, елементи ширші за
   viewport лишаються як є, просто невидимі за межами — але, на відміну
   від hidden, НЕ створює новий scroll-контейнер (не встановлює
   scrollability, лише paint-кліп), тому sticky не ламається (перевірено
   тим самим тестом). Ширина 100% на обох — про всяк випадок, як явна
   підстраховка проти появи горизонтального overflow */
html {
  overflow-x: clip;
  width: 100%;
}

body {
  background: var(--color-background);
  min-width: 375px;
  width: 100%;
  /* Ілюстрація в Services навмисно виходить за межі екрана зліва —
     ховаємо горизонтальний скролбар (clip, не hidden — див. коментар
     вище про html), не обрізаючи вертикальний */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Крок 120 — глобальне блокування виділення тексту (усі сторінки),
     доповнює js/copy-protect.js (copy/contextmenu/dragstart) */
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

/* Крок 120 — виняток: поля контактної форми лишаються звичайними —
   виділення/копіювання/paste мають працювати як у будь-якій формі */
.contact-form input,
.contact-form textarea {
  user-select: text;
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
}

/* Контент не розтягується ширше 1920px — центрується на більших екранах */
main {
  max-width: 1920px;
  margin: 0 auto;
}

/* ==========================================================================
   HEADER — логотип, навігація, кнопка Contact

   Ширина 1164px = ширині сітки, position: fixed, центрується через
   left:0; right:0; margin:auto. Хедер завжди видимий; при скролі
   (header.js перемикає клас .header--scrolled) фон/строук/навігація/
   роздільники плавно зникають, а CONTACT перетворюється на кнопку —
   уся різниця станів "top" / "scrolled" описана нижче через цей клас
   ========================================================================== */

.header {
  position: fixed;
  top: 18px;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: 1164px;
  height: 60px;
  z-index: 100;
  display: flex;
  align-items: center;
  padding: 16px;
  background-color: var(--color-background);
  /* Фікс: inset (не зовнішній) stroke — без inset box-shadow малює 1px
     ЗА межами border-box (width:1164 з box-sizing:border-box, з reset
     вище), тому лівий/правий строуки хедера виходили на 1px за межі
     стандартної 1164px сітки замість збігатись з нею */
  box-shadow: inset 0 0 0 1px var(--grey-15);
  transition: background-color 300ms ease, box-shadow 300ms ease;
}

/* Стан "scrolled": фон і зовнішній stroke зникають. inset тут теж —
   інакше transition між inset/не-inset box-shadow не інтерполюється
   плавно (браузер не може анімувати між різними типами тіні) */
.header--scrolled {
  background-color: transparent;
  box-shadow: inset 0 0 0 1px transparent;
}

/* -------------------------------------------------------------------------
   Кластер логотипа — у стані "top" виглядає як зараз (лого + роздільник,
   без фону). У стані "scrolled" стає власним боксом (фон + зовнішній
   stroke), а всередині розкривається кнопка меню. Логотип не рухається:
   margin-left:-16px компенсує padding хедера, а власний padding-left:16px
   повертає лого на те саме місце — так само, як CONTACT "тягнеться"
   до правого краю через negative margin (див. .header__contact-link)
   ------------------------------------------------------------------------- */

.header__brand {
  display: flex;
  align-items: center;
  height: 60px;
  margin-left: -16px;
  padding-left: 16px;
  padding-right: 0;
  background-color: transparent;
  box-shadow: 0 0 0 1px transparent;
  transition: background-color 300ms ease, box-shadow 300ms ease, padding-right 300ms ease;
}

/* Бокс ~120×60: фон, зовнішній stroke і місце для кнопки меню праворуч.
   Фікс: box-shadow тут ліворуч збігається з лівим краєм .header (тому
   й лівим краєм самої сітки, .header__brand стоїть впритул до нього
   через margin-left:-14px, Крок 132) — без inset той самий 1px-баг, що
   вже фіксили для .header (рядок 137): не-inset stroke малює 1px ЗА
   межами border-box, тому строук-роздільник ліворуч виходив на 1px за
   межі сітки/контейнера в scrolled-стані */
.header--scrolled .header__brand {
  background-color: var(--color-background);
  box-shadow: inset 0 0 0 1px var(--grey-15);
  padding-right: 19px;
}

/* Лого обгорнуте в <a href="index.html"> (Фікс) — посилання само стає
   flex-item замість <img>, тому flex-shrink:0 переїжджає сюди;
   display:block запобігає зайвому inline-space навколо картинки.
   Розмір посилання сам підлаштовується під .header__logo (img) —
   власного width/height не задаємо, щоб не дублювати цю логіку на
   кожному брейкпоінті (24px Landscape/Portrait тощо, нижче) */
.header__logo-link {
  display: block;
  flex-shrink: 0;
}

.header__logo {
  display: block;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}

/* Висота 60px — більша за 28px-вий контент-бокс хедера, тому за рахунок
   align-items: center роздільник симетрично виходить за внутрішні відступи
   і займає всю висоту хедера (від верхнього до нижнього краю).
   Роздільник біля лого завжди видимий — і в "top", і в "scrolled"
   (це внутрішня межа кластера .header__brand, вона не зникає) */
.header__divider {
  width: 1px;
  height: 60px;
  margin-left: 16px;
  background: var(--grey-15);
  flex-shrink: 0;
  transition: opacity 300ms ease;
}

/* Третій строук — лише для Tablet Portrait (768–1023px, Крок 156-фікс),
   одразу після логотипа. На всіх інших breakpoint'ах немає еквівалента,
   тому за замовчуванням прихований — стилюється лише в медіа-запиті нижче */
.header__divider--logo {
  display: none;
}

/* Без ширини/відступу за замовчуванням, щоб у стані "top" не займати місця
   і не зсувати роздільник — "розкривається" всередині кластера .header__brand */
.header__menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 0;
  margin-left: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: width 300ms ease, margin-left 300ms ease, opacity 300ms ease;
}

.header__menu-btn img {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

/* 19px від роздільника до іконки */
.header--scrolled .header__menu-btn {
  width: 22px;
  margin-left: 19px;
  opacity: 1;
  pointer-events: auto;
}

/* -------------------------------------------------------------------------
   Навігація
   ------------------------------------------------------------------------- */

.header__nav {
  margin-left: 46px;
  transition: opacity 300ms ease;
}

/* Навігація зникає у стані "scrolled" */
.header--scrolled .header__nav {
  opacity: 0;
  pointer-events: none;
}

.header__nav-list {
  display: flex;
  align-items: center;
  gap: 34px;
  list-style: none;
}

.header__nav-item {
  flex-shrink: 0;
}

.header__nav-item--home { width: 66px; }
.header__nav-item--work { width: 61px; }
.header__nav-item--services { width: 87px; }
.header__nav-item--about { width: 68px; }

.header__nav-link {
  display: block;
  color: var(--grey-50);
  text-decoration: none;
  transition: color 200ms ease;
}

.header__nav-link.is-active {
  color: var(--grey-100);
}

/* Активний пункт на hover не реагує — лишається var(--grey-100) */
.header__nav-link:not(.is-active):hover {
  color: var(--grey-60);
}

/* Position:relative на текстовому елементі — точка відліку для номера */
.header__nav-text {
  position: relative;
  display: inline-block;
}

/* Position:absolute на номері — суперскрипт після тексту з відступом 6px,
   верхній край на 4.5px нижче верхнього краю слова */
.header__nav-num {
  position: absolute;
  left: calc(100% + 6px);
  top: 4.5px;
  white-space: nowrap;
  color: var(--grey-100);
  visibility: hidden;
}

.header__nav-link.is-active .header__nav-num {
  visibility: visible;
}

/* -------------------------------------------------------------------------
   Кнопка Contact

   Роздільник більше не бере участі в горизонтальних відступах через margin —
   текст позиціонується власним padding посилання (32px з обох боків),
   а negative margin-right компенсує паддінг хедера (16px), щоб фон-бокс
   у стані "scrolled" сягав рівно до правого краю хедера. Завдяки цьому
   текст лишається піксель у піксель на тому самому місці в обох станах.
   ------------------------------------------------------------------------- */

/* Той самий роздільник на всю висоту хедера, притиснутий до правого краю —
   простір між About і роздільником гнучкий. На відміну від роздільника
   біля лого, цей зникає у стані "scrolled" — межу задає фон кнопки CONTACT */
.header__divider--contact {
  margin-left: auto;
}

.header--scrolled .header__divider--contact {
  opacity: 0;
  pointer-events: none;
}

/* Вертикальний паддінг 20px зверху/знизу (20 + 20 line-height + 20 = 60)
   виходить за межі 16px-вого паддінгу хедера тим самим прийомом,
   що й у .header__divider — через align-items: center на батьківському flex.
   Крок 100: background-color/color/box-shadow/transition звідси прибрано —
   в "scrolled" це тепер повноцінна .cta-button (нижче), а "top"/"peek"
   повертають старий текстовий вигляд окремим, більш специфічним правилом */
.header__contact-link {
  position: relative;
  isolation: isolate;
  margin-left: 0;
  margin-right: -16px;
  padding: 20px 32px;
  text-decoration: none;
  flex-shrink: 0;
}

/* Перекриває overflow: hidden з базового .cta-button (Крок 100, нижче
   по каскаду) — власний ::before "top"/"peek" навмисно виходить за межі
   боксу на 1px (inset: -1px), щоб перекрити зовнішній stroke хедера й
   роздільник; overflow: hidden тут обрізав би цей виліт і повернув
   видимі 1px-лінії. Два клас-селектори — вища специфічність за одиночний
   .cta-button, тому перемагає незалежно від порядку в каскаді */
.header__contact-link.cta-button {
  overflow: visible;
}

/* Фікс: 1px "не вистачає" зліва кнопці в "scrolled". Причина —
   .header__divider--contact лишається в flex-потоку (лише opacity:0,
   не display:none/width:0) і тримається на margin-left:auto, тому БУДЬ-
   яка зміна margin/width самої кнопки чи роздільника перерозподіляється
   через цей auto-margin і повертає той самий рендер-результат (перевірено
   емпірично) — реального зсуву layout-властивостями досягти не можна.
   Замість цього — суто візуальне розширення на 1px ліворуч через
   box-shadow (0 blur/spread, offset -1px по X): не займає місця в
   layout, тому й не потрапляє під перерахунок auto-margin. Колір
   збігається з базовим (не-hover) станом кнопки — box-shadow покриває
   лише DEFAULT стан, бо в ньому crossfade-шар нижче має opacity:0
   (нічого не малює в цій колонці, інакше був би непофарбований пропуск).

   Hover/pressed — не той самий трюк повторно (::after на елементі один,
   другий поверх існуючого додати не можна, а сурогатний суцільний колір
   замість градієнта дає видимий шов, перевірено). Замість цього нижче
   розширюємо ЛІВИЙ край самого спільного crossfade-шару (.cta-button::after,
   Крок 100) — той самий шар, що вже коректно переходить colір↔градієнт
   на hover/pressed, просто рахує градієнт під форму на 1px ширшу. z-index:0
   позиційного нащадка завжди малюється поверх background/box-shadow
   батька, тому в hover/pressed він повністю перекриває цю колонку
   справжнім градієнтом, а в default (opacity:0) крізь нього видно
   box-shadow — жодного стику кольорів в обох станах */
.header--scrolled:not(.header--peek) .header__contact-link.cta-button {
  box-shadow: -1px 0 0 0 var(--primary-100);
}

.header--scrolled:not(.header--peek) .header__contact-link.cta-button::after {
  left: -1px;
}

/* Крок 100: у "scrolled" CONTACT — повноцінна .cta-button (Default/Hover/
   Pressed стейти застосовуються глобальним правилом .cta-button нижче
   по каскаду, нічого додаткового тут не треба). У "top"/"peek" кнопка й
   далі НЕ повинна виглядати заповненою — .cta-button дає background
   ЗАВЖДІ (рівна специфічність, але пізніше в каскаді, тому переміг би
   всюди), тому тут явно повертаємо старий прозорий вигляд із вищою
   специфічністю (два клас-селектори) */
.header:not(.header--scrolled) .header__contact-link.cta-button,
.header--scrolled.header--peek .header__contact-link.cta-button {
  background: transparent;
  color: var(--grey-100);
}

.header:not(.header--scrolled) .header__contact-link.cta-button:hover,
.header--scrolled.header--peek .header__contact-link.cta-button:hover,
.header:not(.header--scrolled) .header__contact-link.cta-button:active,
.header--scrolled.header--peek .header__contact-link.cta-button:active {
  background: transparent;
  color: var(--color-background);
}

/* "top"/"peek" заливають hover власним ::before-шаром (нижче, суцільний
   колір) — глобальний .cta-button::after (градієнт-crossfade) тут
   вимикаємо повністю, інакше він проявлявся б поверх transparent-фону
   одночасно з ::before */
.header:not(.header--scrolled) .header__contact-link.cta-button::after,
.header--scrolled.header--peek .header__contact-link.cta-button::after {
  content: none;
}

/* Заливка hover у "top"/"peek" — окремий шар з inset: -1px (не background
   самого лінка): зона CONTACT впритул до зовнішнього stroke хедера
   (top/right/bottom) і до роздільника зліва (він теж рівно 1px), тому
   звичайний background-color, обмежений власним боксом лінка, лишав би
   ці 1px лінії видимими поверх помаранчевого. Шар розширюється на 1px
   в усі боки й перекриває їх, не чіпаючи розмір/зону кліку самого лінка.
   isolation: isolate на батьківському лінку тримає z-index: -1 шару
   локальним (лише під власним текстом CONTACT), не даючи йому піти
   під сусідні елементи хедера (роздільник, лого) в спільному контексті.
   Явно скопований до "top"/"peek" (вища специфічність, два клас-селектори)
   — у "scrolled" тут ::before не потрібен взагалі (hover/pressed там —
   лише зміна фону самої кнопки, Крок 100) */
.header:not(.header--scrolled) .header__contact-link::before,
.header--scrolled.header--peek .header__contact-link::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  background-color: transparent;
  transition: background-color 200ms ease;
}

.header:not(.header--scrolled) .header__contact-link:hover::before,
.header--scrolled.header--peek .header__contact-link:hover::before,
.header:not(.header--scrolled) .header__contact-link:active::before,
.header--scrolled.header--peek .header__contact-link:active::before {
  background-color: var(--primary-pressed);
}

/* Роздільник зникає при hover на CONTACT — межу задає сам фон кнопки.
   Актуально в усіх станах (top/peek/scrolled), тому без додаткового
   скоупінгу */
.header__divider--contact:has(+ .header__contact-link:hover) {
  opacity: 0;
}

/* -------------------------------------------------------------------------
   PEEK — наведення на іконку меню в стані "scrolled" тимчасово розгортає
   хедер у вигляд "top" (js/header.js додає клас .header--peek, не знімаючи
   .header--scrolled — скрол-логіка й далі відстежує реальну позицію).

   Кожне правило нижче просто повертає ту саму властивість до її значення
   зі стану "top", перекриваючи відповідне .header--scrolled-правило вищою
   специфічністю (дві клас-умови замість однієї) — самі transition вже
   задані на базових елементах, тому анімується тими самими ~300ms/200ms
   ------------------------------------------------------------------------- */

.header--scrolled.header--peek {
  background-color: var(--color-background);
  /* Фікс: inset (не зовнішній) stroke — той самий баг/фікс, що вже є
     на базовому .header (рядок 141): не-inset box-shadow малює 1px ЗА
     межами border-box, тому лівий/правий строуки в peek-стані виходили
     на 1px за межі сітки (908px планшет / 1164px десктоп) з кожного
     боку. Сама анімація/тайминги/логіка переходу — без змін */
  box-shadow: inset 0 0 0 1px var(--grey-15);
}

.header--scrolled.header--peek .header__brand {
  background-color: transparent;
  box-shadow: inset 0 0 0 1px transparent;
  padding-right: 0;
}

/* Іконка меню в розгорнутому стані знову зникає — лівий кластер
   повертається до звичайного вигляду лого + роздільник */
.header--scrolled.header--peek .header__menu-btn {
  width: 0;
  margin-left: 0;
  opacity: 0;
  pointer-events: none;
}

.header--scrolled.header--peek .header__nav {
  opacity: 1;
  pointer-events: auto;
}

.header--scrolled.header--peek .header__divider--contact {
  opacity: 1;
  pointer-events: auto;
}

/* Базовий/hover/active вигляд CONTACT у peek уже покриває правило
   .header--scrolled.header--peek .header__contact-link.cta-button
   (Крок 100) вище — окреме правило тут більше не потрібне */

/* ==========================================================================
   WORK HERO — фонова секція сторінки Work (work.html)

   На відміну від .hero на головній (масштабується під висоту екрана,
   background-size: auto 100%) — тут розмір ФІКСОВАНИЙ 1920×900,
   background-size: 1920px 900px завжди, і сама секція фіксованої
   висоти 900px (не 100vh/svh). При вужчому за 1920px екрані зображення
   обрізається симетрично з боків (той самий принцип, що й .hero, і сам
   <main> все одно капається на 1920px, Крок 42); при нижчому за 900px
   екрані — просто не влазить і обрізається знизу, бо не масштабується
   під висоту вікна.
   ========================================================================== */

.work-hero {
  position: relative;
  /* z-index:0 (не auto) — примушує секцію завести ВЛАСНИЙ stacking
     context, інакше z-index:-1 на .work-hero__bg (нижче) "втікає" в
     найближчий чужий stacking context вище по дереву й лягає ПІД
     власним фоном тієї предківської секції — картинка "зникає",
     хоча всі властивості лишаються коректними (реальний баг фіксу) */
  z-index: 0;
  width: 100%;
  /* min-height, не фіксована height: Крок 46 додав ряди робіт як звичайних
     flex-дітей секції, вони не влазять у 900px банера. Фіксована height
     не росте під overflow-контент у normal flow — наступна секція (CTA-2,
     Крок 47) стартувала б одразу за формальним низом 900px і перекривала б
     ряди. min-height гарантує ті самі 900px фону (background-size і
     нижче лишаються 1920×900, обрізаються так само, як задумано в Кроці 42),
     і секція природно росте під рядами робіт */
  min-height: 900px;
  background-color: var(--color-background);

  /* Контент, за патерном .hero — але тут відступ зверху фіксований
     константою (170px), а не пропорційний висоті секції: сама секція
     теж фіксованої висоти (900px), не 100vh/svh */
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 170px;
}

/* Фікс: фон винесено в окремий шар (.work-hero__bg), щоб застосувати той
   самий scroll-reveal fade-in, що й до контенту (Крок з анімацією появи
   фонів). z-index:-1 відносно position:relative .work-hero — лягає НАД
   власним background-color секції, але ПІД усім іншим (звичайним
   in-flow) контентом, без потреби огортати сам контент у z-index-шар
   (той самий трюк на .*-hero__bg інших сторінок).

   Фікс (спалах фону): .work-hero__bg і .scroll-reveal РАНІШЕ висіли на
   ОДНОМУ Й ТОМУ Ж елементі — коли opacity reveal-переходу тимчасово 0,
   background-color ЦЬОГО Ж елемента теж ставав прозорим на цю мить,
   оголюючи те, що позаду. Тепер .work-hero__bg — стабільний непрозорий
   шар ЛИШЕ з background-color (жодної reveal-анімації), а ілюстрація
   (background-image) винесена в дочірній .work-hero__image, який і
   отримує .scroll-reveal/.scroll-reveal-up — колір фону завжди
   стабільний, анімується лише сама ілюстрація зверху нього */
.work-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;

  /* Той самий "belt-and-suspenders" фікс, що .contact-hero__bg — раніше
     колір фону цього шару покладався лише на батьківський .work-hero
     (вище) й на власний opacity:0 до reveal (.scroll-reveal), що
     працювало ЛИШЕ випадково: явний колір тут прибирає залежність від
     цього збігу */
  background-color: var(--color-background);
}

.work-hero__image {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 1920px 900px;
  background-image: url("../assets/images/work-bg.webp");
  background-image: image-set(
    url("../assets/images/work-bg.webp") 1x,
    url("../assets/images/work-bg@2x.webp") 2x
  );
}

/* Було випробувано низку альтернативних механізмів появи цього шару
   (clip-path з різними easing/тривалістю, mask-image з градієнтом через
   @property) замість стандартного opacity-fade — щоб уникнути
   кольорового "спалаху", помітного на конкретному 4K-моніторі через
   альфа-блендинг GPU-композитора під час opacity-переходу. Жоден
   варіант не влаштував візуально (clip-path виглядав як різке
   "розкриття", mask-image давав рябіння на тому самому 4K), тому
   свідомо повернуто звичайний .scroll-reveal/.scroll-reveal-up
   (opacity + translateY), як і на решті сайту — спалах на 4K як
   компроміс прийнятний. Двошарова структура (.work-hero__bg для
   стабільного кольору фону, .work-hero__image для ілюстрації, що
   анімується) лишається — вона незалежно правильна й безпечна */

.work-hero__eyebrow {
  color: var(--grey-50);
  text-transform: uppercase;
}

.work-hero__title {
  margin-top: 12px;
  width: 653px;
  color: var(--grey-100);
  text-align: center;
}

.work-hero__desc {
  margin-top: 18px;
  color: var(--grey-60);
  text-align: center;
}

/* Ручний перенос боді-тексту Hero, специфічний для Mobile (≤767px) —
   3 рядки замість 2, розрив в інших місцях речення — вимкнений за
   замовчуванням (той самий tablet-break прийом, що
   .footer__who-body-break--mobile). Вмикається/вимикається разом
   з десктопним варіантом у медіа-запиті нижче */
.work-hero__desc-break--mobile {
  display: none;
}

/* Заголовок списку робіт — 304px від опису (боді-тексту) з Кроку 43,
   align-self: stretch виносить його з центрованого потоку .work-hero
   на всю ширину, а внутрішній max-width:1164px/margin:auto (той самий
   принцип, що .trusted-by__grid) вирівнює "Work" по лівому краю сітки
   (колонка 1) */
.work-hero__list-heading {
  align-self: stretch;
  margin-top: 304px;
}

.work-hero__list-heading-inner {
  display: flex;
  align-items: flex-start;
  max-width: 1164px;
  margin: 0 auto;
}

.work-hero__list-title {
  color: var(--grey-100);
}

.work-hero__list-count {
  margin-left: 10px;
  color: var(--grey-60);
}

/* -------------------------------------------------------------------------
   Панель фільтрів — 24px нижче "Work (6)". Верхній/нижній строук і
   50px-зона вертикальних строуків стикаються впритул одне з одним
   (без проміжку): .work-hero__filters-band — це рівно та сама висота
   50px, що й вертикальні строуки (rule б, Крок 45) — вони починаються
   РІВНО на рівні верхнього строука, а нижній строук іде одразу під
   ними, тому текст, центрований по висоті цієї зони (align-items:
   center на 50px), і візуально опиняється десь на ~15-16px нижче
   верхньої лінії — це наслідок центрування, а не окремий відступ.
   Усі елементи всередині зони позиційовані абсолютно за точними
   px-координатами сітки (128/20, max-width:1164px) — рядок фільтрів
   не мапиться на колонки рівномірно (ALL INDUSTRIES/Sort by зсунуті
   відносно строуків на власні відступи), тому це надійніше за grid-column
   ------------------------------------------------------------------------- */

.work-hero__filters {
  align-self: stretch;
  margin-top: 24px;
  /* Фікс: власний stacking context (position без зсуву + явний z-index,
     не auto) — без нього тригер/дропдаун-панель (.work-hero__filter-group/
     __filter-dropdown, обидва position:absolute всередині) не мають
     ЖОДНОГО реального stacking context між собою й документом, тому
     z-index:20 дропдауна порівнювався десь на рівні кореня документа.
     Це працювало, поки .work-card (.scroll-reveal) не отримав
     will-change (Safari-фікс продуктивності) — власний stacking context
     картки почав непередбачувано перебивати дропдаун знизу. Тепер увесь
     рядок фільтрів гарантовано стекується вище БУДЬ-ЧОГО, що йде після
     нього в .work-hero (ряди карток), незалежно від їхніх власних
     stacking-context-переходів — перевірено рендером (headless Chrome,
     A/B: без цього фіксу дропдаун ховався під карткою, з фіксом —
     повністю поверх) */
  position: relative;
  z-index: 10;
}

.work-hero__filters-inner {
  max-width: 1164px;
  margin: 0 auto;
}

/* span — інлайновий за замовчуванням: height/width ігноруються без display:block,
   тому строук колапсував до 0×0 (Фікс) */
.work-hero__filters-line {
  display: block;
  width: 100%;
  height: 1px;
  background-color: var(--grey-15);
}

.work-hero__filters-band {
  position: relative;
  height: 50px;
}

/* Обгортка навколо Services/vline1/Industries/Sort — на Tablet Portrait
   (768–1023px) стає окремою панеллю, що показується/ховається кліком по
   .work-hero__filters-toggle (js/work-filters.js). На десктопі/Tablet
   Landscape display:contents прибирає власний бокс обгортки: її діти
   лишаються звичайними absolute-дітьми .work-hero__filters-band, точно
   як до цієї обгортки — жодної візуальної різниці для цих breakpoint'ів */
.work-hero__filters-panel {
  display: contents;
}

/* Крок 108: раніше .work-hero__filter--services/--industries самі були
   position:absolute (left:0 / left:168px). Тепер це .work-hero__filter-group
   (обгортка тригера + дропдаун-панелі), а сам .work-hero__filter — звичайний
   flex-елемент всередині групи (position:relative — точка відліку для
   .work-hero__filter-dropdown, position:absolute) */
.work-hero__filter {
  position: relative;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
}

.work-hero__filter-group {
  position: absolute;
  top: 0;
  height: 100%;
}

.work-hero__filter-group--services {
  left: 0;
}

/* 148px = ліва межа колонки 2 (128 + 20) */
.work-hero__filters-vline--1 {
  position: absolute;
  top: 0;
  left: 148px;
  width: 1px;
  height: 100%;
  background-color: var(--grey-15);
}

/* 20px правіше строука 1 (148 + 20) — не прив'язано до колонок */
.work-hero__filter-group--industries {
  left: 168px;
}

.work-hero__filter-label {
  color: var(--grey-50);
  text-transform: uppercase;
  transition: color 200ms ease;
}

/* Крок 108: тригери "All Services"/"All Industries" — grey-60 закриті.
   Фікс: статичний лейбл "Sort by:" сюди НЕ входить — його базовий колір
   grey-50 (успадковується від .work-hero__filter-label вище), у Кроці 109
   це було помилково прирівняно до Services/Industries */
.work-hero__filter-group--services .work-hero__filter-label,
.work-hero__filter-group--industries .work-hero__filter-label {
  color: var(--grey-60);
}

/* Стрілка — inline SVG з stroke="currentColor" (раніше <img> з жорстко
   зашитим #7E7E7E = grey-50 у самому SVG-файлі), щоб керувати кольором
   при відкритому дропдауні через CSS, а не тримати два растрові файли */
.work-hero__filter-arrow {
  color: var(--grey-50);
  transition: transform 200ms ease, color 200ms ease;
}

/* Крок 109: is-open тепер на .work-hero__filter-group (не на самому
   тригері) — так CSS одним махом дістає і стрілку (нащадок тригера,
   всередині групи), і статичний лейбл "Sort by:" (сусід тригера,
   теж всередині групи), без :has()/JS-стилізації напряму */
.work-hero__filter-group.is-open .work-hero__filter-arrow {
  transform: rotate(180deg);
  color: var(--grey-100);
}

/* Фікс: статичний лейбл "Sort by:" при відкритому дропдауні — grey-60
   (було помилково grey-100 в Кроці 109) */
.work-hero__filter-group--sort.is-open .work-hero__filter-label {
  color: var(--grey-60);
}

/* Фікс: текст тригера (не статичний лейбл) при ВІДКРИТОМУ дропдауні —
   grey-100 в усіх трьох, узгоджено з кольором стрілки (Крок 108).
   Services/Industries: текст лежить у .work-hero__filter-label (тому
   ж елементі, що й сам тригер — там немає окремого статичного лейбла).
   Sort: текст лежить у .work-hero__filter-value ("Date" тощо),
   .work-hero__filter-label тут — ІНШИЙ елемент, статичний "Sort by:" —
   саме тому для sort ця пара кольорів (лейбл/значення) інвертована
   відносно Services/Industries */
.work-hero__filter-group--services.is-open .work-hero__filter-label,
.work-hero__filter-group--industries.is-open .work-hero__filter-label {
  color: var(--grey-100);
}

.work-hero__filter-group--sort.is-open .work-hero__filter-value {
  color: var(--grey-100);
}

/* Фікс: hover на тексті тригера (не на пунктах дропдауна — для них hover
   окремо, Крок 111) — grey-100, поки курсор над елементом, незалежно від
   open/closed. Специфічність (0,3,0) дорівнює правилам .is-open вище,
   тому пріоритет hover забезпечує лише порядок у каскаді — цей блок має
   стояти НИЖЧЕ за них. Group-рівень (не сам тригер) навмисно — для
   Sort by це єдиний спосіб зачепити одразу і статичний лейбл "Sort by:"
   (сусід тригера), і значення "Date" (усередині тригера) одним селектором */
.work-hero__filter-group--services:hover .work-hero__filter-label,
.work-hero__filter-group--industries:hover .work-hero__filter-label,
.work-hero__filter-group--sort:hover .work-hero__filter-label,
.work-hero__filter-group--sort:hover .work-hero__filter-value {
  color: var(--grey-100);
}

/* Фікс: 8px нижче нижнього краю тригера (=низ .work-hero__filter-group,
   що дорівнює висоті 50px-смуги фільтрів) — було 24px.
   Фікс: висота більше НЕ фіксована (312px/364px) — авто, сума висот
   пунктів (кожен формується власними 15px/20px паддінгами) + дівайдери
   між ними; однаково для всіх трьох дропдаунів незалежно від кількості
   пунктів */
.work-hero__filter-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 206px;
  background: var(--color-background);
  box-shadow: inset 0 0 0 1px var(--grey-15);
  z-index: 20;
  display: none;
}

/* Фікс: панель мала left:0 (= тригер), але текст пунктів усередині несе
   власний padding-left:20px (.work-hero__filter-item нижче) — тому був
   видимий 20px зсув вправо відносно тексту тригера. Зсуваємо ЛИШЕ ці два
   дропдауни (не спільне правило вище) — виміряно, що Sort by має ІНШУ,
   протилежну за напрямком розбіжність (текст пункту вже ~43px ЛІВІШЕ
   тригера "Date", бо .work-hero__filter-group--sort починається від
   статичного лейбла "Sort by:", а не від самої кнопки-тригера), тому
   той самий зсув туди лише погіршив би вирівнювання */
.work-hero__filter-group--services .work-hero__filter-dropdown,
.work-hero__filter-group--industries .work-hero__filter-dropdown {
  left: -20px;
}

/* Sort — протилежний напрямок (див. коментар вище): панель успадковує
   left:0 від .work-hero__filter-group--sort, який починається від
   лейбла "Sort by:", а не від тригера "Date". Виміряно рендером (Playwright,
   getBoundingClientRect): лейбл ~55.4px + 8px flex-gap − 20px padding
   пункту = +43px вправо, щоб текст пункту зрівнявся з текстом тригера */
.work-hero__filter-group--sort .work-hero__filter-dropdown {
  left: 43px;
}

.work-hero__filter-dropdown.is-open {
  display: block;
}

/* Крок 121 — viewport-aware позиціонування (той самий підхід і той самий
   8px відступ, тепер від верхнього краю тригера вгору, що й
   .form-field__dropdown-panel--opens-up на contact.html), керується
   js/dropdown-position.js через js/work-filters.js */
.work-hero__filter-dropdown--opens-up {
  top: auto;
  bottom: calc(100% + 8px);
}

/* Фікс: аперкейс на ВСІХ пунктах дропдаунів (раніше лише тригер-лейбл
   був аперкейсом, а Services/Industries пункти лишались як введено —
   Consulting/Audit/...; тепер уніфіковано з Sort) */
.work-hero__filter-item {
  position: relative;
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 15px 20px;
  text-align: left;
  text-transform: uppercase;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--grey-50);
}

/* Дівайдери МІЖ пунктами, не після останнього */
.work-hero__filter-item:not(:last-child) {
  border-bottom: 1px solid var(--grey-15);
}

/* Фікс: градієнтний строук замінено на фон var(--grey-10) на весь фрейм
   активного пункту — підтверджено пілотом на "All Services", тепер
   застосовано глобально на всіх дропдаунах work.html (Services/
   Industries/Sort). .work-hero__filter-item уже width:100%/box-sizing:
   border-box (база вище) — його власний box і так точно збігається з
   прямокутником "від строука до строука, від краю до краю дропдауна"
   (border-bottom-дівайдери між пунктами, box-shadow-інсет дропдауна по
   контуру), тому background-color тут сам заповнює саме той фрейм, без
   додаткової геометрії */
.work-hero__filter-item.is-active {
  color: var(--grey-100);
  background-color: var(--grey-10);
}

/* Крок 111: hover — окремий тимчасовий стан, перекриває і базовий
   (grey-50), і активний (grey-100) кольори тексту, поки курсор над
   пунктом; після — пункт повертається до свого справжнього стану.
   Правило нижче за .is-active в каскаді (та сама специфічність, 1 клас
   понад базовий .work-hero__filter-item) — тому саме hover перемагає
   при наведенні на активний пункт (фон .is-active лишається — hover тут
   міняє лише колір тексту) */
.work-hero__filter-item:hover {
  color: var(--grey-60);
}

/* Right-anchored: права межа стрілки на 43px лівіше строука 2 (868 − 43 = 825),
   що в координатах "right" відносно 1164px-контейнера = 1164 − 825 = 339px.
   Крок 109: раніше .work-hero__filters-sort — сам тригер (label+value+
   стрілка в одному <button>); тепер це .work-hero__filter-group-обгортка
   навколо статичного лейбла "Sort by:" (сусід, не частина кліку) +
   окремого тригера (value+стрілка, клікабельний) + дропдаун-панелі */
.work-hero__filter-group--sort {
  position: absolute;
  top: 0;
  right: 339px;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Іконка-заміна лейбла/значення/стрілки на Tablet Portrait (768–1023px) —
   прихована за замовчуванням, з'являється лише в медіа-запиті нижче */
.work-hero__filter-sort-icon {
  display: none;
}

/* Крок 109: аперкейс через CSS (не хардкод у розмітці) — той самий
   принцип, що .work-hero__filter-label, бо textContent тригера тепер
   пишеться JS-ом із назви обраного пункту дропдауна ("Date"/"A to Z"/
   "Z to A") */
.work-hero__filter-value {
  color: var(--grey-60);
  text-transform: uppercase;
  transition: color 200ms ease;
}

/* Правий край строука на 868px (кінець колонки 6: 5×148 + 128) —
   у координатах "right" відносно 1164px-контейнера = 1164 − 868 = 296px */
.work-hero__filters-vline--2 {
  position: absolute;
  top: 0;
  right: 296px;
  width: 1px;
  height: 100%;
  background-color: var(--grey-15);
}

/* 888px = початок колонки 7 (740 + 128 + 20, тобто одразу за строуком 2).
   Фікс: right:0 розтягує контейнер до 1164px (правий край сітки) — без
   цього ширина визначалась контентом (auto) і не сягала точно 1164,
   через що clear-кнопка (margin-left:auto нижче) не мала за що чіплятись */
.work-hero__filters-search {
  position: absolute;
  top: 0;
  left: 888px;
  right: 0;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: text;
}

.work-hero__search-icon {
  cursor: pointer;
}

/* Крок 110: раніше .work-hero__search-label — статичний <span>. Тепер
   завжди справжній <input> зі скинутими UA-стилями (border/outline/
   padding/margin), у порожньому/незафокушеному стані виглядає ідентично
   старому тексту через placeholder — тому "повернення до
   тексту-плейсхолдера" (п.5 Кроку 110) відбувається саме нативно,
   без окремого JS-стану */
/* Фікс: колір ВВЕДЕНОГО тексту — grey-100 (плейсхолдер лишається
   grey-50 через окреме ::placeholder-правило нижче, яке не успадковує
   цей color) */
.work-hero__search-input {
  width: 200px;
  color: var(--grey-100);
  text-transform: uppercase;
  background: none;
  border: none;
  outline: none;
  padding: 0;
  margin: 0;
  cursor: text;
}

.work-hero__search-input::placeholder {
  color: var(--grey-50);
  text-transform: uppercase;
  opacity: 1;
}

/* Фікс: при активації (фокус) плейсхолдер повністю зникає — лишається
   порожній input з курсором, замість тексту "Search case studies" поверх
   вводу. Ховаємо лише через колір/прозорість (не display:none — той
   ламає fade у деяких браузерах і не потрібен тут) */
.work-hero__search-input:focus::placeholder {
  color: transparent;
  opacity: 0;
}

/* Фікс: іконка очищення — з'являється лише коли в полі є текст
   (.is-visible додає/знімає JS), сама кнопка без UA-стилів кнопки.
   Фікс: margin-left:auto притискає кнопку до правого краю контейнера
   (тепер right:0 = 1164px, край сітки) замість зайвого відступу
   праворуч від фіксованої ширини input — заміняє собою 6px gap лише
   з цього боку, gap між іконкою пошуку й input лишається незмінним */
.work-hero__search-clear {
  display: none;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: auto;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.work-hero__search-clear.is-visible {
  display: flex;
}

/* Фікс: hover — grey-100 замість дефолтного grey-60 (#B6B6B6, збігається
   з кольором самого clear.svg). Іконка — <img> (не інлайн-SVG), тому колір
   міняємо через CSS filter: brightness(1.308) — точний множник для
   переведення rgb(182,182,182) → rgb(238,238,238) (--grey-60 → --grey-100),
   коректно лише для сірих/ахроматичних кольорів (R=G=B), що тут і є */
.work-hero__search-clear img {
  transition: filter 200ms ease;
}

.work-hero__search-clear:hover img {
  filter: brightness(1.308);
}

/* Іконка-тригер фільтрів — замінює Services/Industries/Sort-дропдауни на
   Tablet Portrait (768–1023px). Прихована за замовчуванням (той самий
   tablet-break прийом, що .footer__who-body-break--mobile) — з'являється
   лише в медіа-запиті нижче. Дропдаун-поведінка ще не реалізована —
   поки що статична іконка (наступний крок) */
.work-hero__filters-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
}

/* ==========================================================================
   HERO — каркас секції (фонове зображення)

   Референсний макет фону — 1920×1080px. У межах висоти в'юпорта (100vh)
   має бути видно РІВНО 800px висоти цього референсу (масштабовано) —
   решта (1080 − 800 = 280px референсу = 35% від 800px) "переливається"
   вниз, під наступну секцію. Звідси коефіцієнт 100vh відповідає 800px
   референсу, а 135vh (= 100vh × 1080/800) відповідає повній висоті
   зображення 1080px — тому background-size: auto 135vh (висота ЗАВЖДИ
   135% реальної висоти в'юпорта, у абсолютних vh, а не у % від висоти
   власного 135%-боксу нижче — те саме число, але рахується від
   в'юпорта напряму, без самопосилання) дає ширину (auto), що завжди
   пропорційна висоті екрана — на будь-якому viewport, без медіа-запитів,
   ширина ніколи не "не вміщує" зображення, воно просто виходить за краї
   в'юпорта по боках (без спотворень) на вузьких/квадратних пропорціях.

   .hero__bg — full-bleed (left:50%; width:100vw;
   margin-left:-50vw — стандартний breakout-прийом): якщо лишити
   width:100% (=100% від .hero, який лежить у <main>, де max-width:1920px
   центрує контент на екранах ширших за 1920px), на 4K/широких екранах
   бокс сам обрізав би ширину фону до 1920px, незалежно від
   background-size. Full-bleed гарантує, що бокс завжди дорівнює
   ФІЗИЧНІЙ ширині в'юпорта, тому auto-ширина фону ніколи не впирається
   в штучно вузький контейнер.

   Сама секція .hero — рівно один екран (100svh), наступна секція завжди
   починається нижче фолду. Фоновий шар .hero__bg ВИЩИЙ за
   секцію (135% = 1080/800 макета, box height): нижні ~26% зображення
   навмисно виходять за низ .hero (overflow: visible, не обрізаємо) і
   лягають під наступну секцію — box height (135%) і background-size
   (135vh) тепер рахуються з тієї самої точної формули, тому завжди
   збігаються піксель у піксель, без порожнього "хвоста".
   ========================================================================== */

.hero {
  position: relative;
  width: 100%;
  overflow: visible;
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: var(--color-background);
}

/* Фоновий шар — винесений окремо, бо його висота (135% від .hero) більша
   за саму секцію: нижня частина зображення виходить за її межі вниз.
   Full-bleed (left:50%/width:100vw/margin-left:-50vw) — не залежить від
   .hero (нащадок <main>, max-width:1920px), тому й на широких/4K-екранах
   бокс завжди дорівнює фізичній ширині в'юпорта */
.hero__bg {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  height: 135%;
  z-index: 0;
  pointer-events: none;

  background-repeat: no-repeat;
  background-position: center top;
  background-size: auto 135vh;
  background-image: url("../assets/images/hero-bg.webp");
  background-image: image-set(
    url("../assets/images/hero-bg.webp") 1x,
    url("../assets/images/hero-bg@2x.webp") 2x
  );
}

/* -------------------------------------------------------------------------
   Вертикальне позиціювання контенту — обидва відступи пропорційні висоті
   секції (height: % на flex-column .hero, height: 100vh/100svh — définite,
   тому % дітей рахується від неї): верх 35% (280/800 на базовій 1280×800),
   низ 29.25% (234/800). Масштабуються РАЗОМ при зміні висоти вікна — не
   один фіксований і один плаваючий. Блок контенту між ними — природної
   висоти (flex-grow/shrink: 0), сам не масштабується
   ------------------------------------------------------------------------- */

.hero__spacer {
  flex-shrink: 0;
}

.hero__spacer--top {
  height: 35%;
}

.hero__spacer--bottom {
  height: 29.25%;
}

/* -------------------------------------------------------------------------
   Контент hero — лежить поверх фонового шару (z-index)
   ------------------------------------------------------------------------- */

.hero__content {
  position: relative;
  z-index: 2;
  flex-grow: 0;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero__eyebrow {
  color: var(--grey-50);
  text-transform: uppercase;
}

.hero__title {
  margin-top: 12px;
  /* Фікс: 811px (попередній текст) замінено на 920px — новий заголовок
     ("Product design for complex, data-dense," / "regulated SaaS and
     enterprise software") на 811px переносився ще раз посередині першого
     рядка. 920px — найкоротша ширина, що вміщує обидва рядки без зайвого
     автопереносу (виміряно: 906px). Активно на Десктопі й Tablet Landscape
     (спільне базове правило, без окремого перевизначення) */
  width: 920px;
  color: var(--grey-100);
}

.hero__desc {
  margin-top: 18px;
  /* Фікс: 545px звужувало текст на 2 рядки на Десктопі й Tablet Landscape —
     боді-текст тут має бути в один рядок, без ручного переносу. 660px —
     найкоротша ширина, що вміщує весь рядок без переносу (виміряно: 647px).
     Tablet Portrait лишається 2-рядковим завдяки форсованому
     .hero__desc-break--narrow (активний у тому breakpoint незалежно від
     ширини боксу, доки вона ≥338px) — ширший бокс тут його не чіпає.
     Mobile має власне перевизначення ширини нижче, це значення не
     успадковує */
  width: 660px;
  color: var(--grey-60);
}

/* Ручний перенос тайтла Hero — 4 потенційні точки розриву, кожна зі своєю
   комбінацією активних breakpoint'ів (той самий tablet-break прийом, що
   .work-hero__desc-break--desktop/--mobile). За замовчуванням (десктоп/
   Tablet Landscape) активний лише --3 (default <br>, без окремого правила);
   --1/--2/--4 вимкнені тут і вмикаються по-своєму в Tablet Portrait/Mobile
   нижче */
.hero__title-break--1,
.hero__title-break--2,
.hero__title-break--4 {
  display: none;
}

/* Ручний перенос боді-тексту Hero — вимкнений за замовчуванням (десктоп/
   Tablet Landscape отримують природний перенос без форсованого розриву),
   вмикається в Tablet Portrait/Mobile нижче */
.hero__desc-break--narrow {
  display: none;
}

.hero__buttons {
  /* Фікс: відступ від нижнього краю боді-тексту (.hero__desc) до CTA-
     кнопки — 50px (було 32px) */
  margin-top: 50px;
  display: flex;
  gap: 8px;
}

/* Фікс: justify-content:center — текст(+іконка, .cta-button__content,
   єдина дитина) центрується як ГРУПА в межах кнопки, а не притискається
   до лівого краю (був симетричний padding:32px з обох боків, але без
   justify-content:center контент лишався flex-start, і "центрування"
   раніше імітувалось асиметричним padding-left на кожній конкретній
   кнопці — ці хаки прибрано нижче й по всьому файлу) */
.hero__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 48px;
  padding: 14px 32px;
  text-decoration: none;
  white-space: nowrap;
  /* Колір іконки (fill="currentColor") успадковує color посилання,
     тому анімується синхронно з текстом без окремого коду */
  transition: background-color 200ms ease, color 200ms ease, box-shadow 200ms ease;
}

.hero__btn-icon {
  flex-shrink: 0;
}

/* Text-scramble кнопки (js/text-scramble-hover.js, поширено на ВСІ
   CTA-/секондарі-кнопки сайту) — іконка всередині зсувається на 5px
   вправо, поки скрембл активний. JS додає/знімає клас .is-scrambling
   на [data-text-scramble] однаково для hover (Desktop/Tablet) і press
   (Mobile), тому одне CSS-правило покриває обидва тригери без
   дублювання. Позначається окремим класом .scramble-icon (не всі
   .hero__btn-icon мають text-scramble) — offices__arrow-icon ("More
   about us") цей клас не отримує, там свій узгоджений 2px-зсув нижче
   (styles.css, Offices-блок), без змін */
[data-text-scramble] .scramble-icon {
  transition: transform 220ms var(--ease-smooth);
}

[data-text-scramble].is-scrambling .scramble-icon {
  transform: translateX(5px);
}

/* background/color тепер на .cta-button (Крок 100) — завжди поєднаний
   клас з .hero__btn--primary на всіх кнопках сайту. Фікс: padding-left
   35px (асиметричний хак під центрування "на око") прибрано —
   justify-content:center на .hero__btn вище тепер центрує контент
   насправді, симетричний padding:32px звідти й так лишається */
.hero__btn--primary {
  position: relative;
  width: 191px;
}

/* Секондарі-кнопки — стейти Default/Hover/Pressed/Disabled, спільні для
   ВСІХ .secondary-button сайту (той самий підхід, що .cta-button,
   Крок 100). Фікс: нижній градієнтний строук (::after) прибрано —
   стейти тепер виражені фоном (var(--grey-20) у hover/pressed,
   var(--grey-15) у default/disabled) і кольором тексту/іконки
   (currentColor тягне за собою іконку, якщо вона fill="currentColor",
   тому одне правило кольору покриває варіанти "лише іконка",
   "лише текст" і "іконка+текст" одночасно) */
.secondary-button {
  background: var(--grey-15);
  color: var(--grey-100);
  position: relative;
  text-transform: uppercase;
  transition: background-color 300ms ease, color 300ms ease;
}

.secondary-button:hover {
  background: var(--grey-20);
}

.secondary-button:active {
  background: var(--grey-20);
  color: var(--grey-additional-pressed);
}

.secondary-button:disabled,
.secondary-button.is-disabled {
  background: var(--grey-15);
  color: var(--grey-additional-disabled);
}

/* ==========================================================================
   SERVICES — заголовний блок + таблиця практик зі scrollytelling

   Секція прозора (крізь неї видно "хвіст" фону .hero, що виходить за межі
   секції), тому position: relative + z-index: 1 — контент лягає поверх
   absolute-шару .hero__bg.

   Структура (навмисно у 2 незалежні блоки):
   - .services__intro — рядок-лейбл + заголовок + опис, звичайний потік
     документа, скролиться геть, як завжди
   - .services__sticky — ТІЛЬКИ ілюстрація + вікно таблиці, пінується
     (position: sticky; top: 0), щойно опис повністю виходить за верх
     екрана (бо панель йде одразу за інтро)

   Scrollytelling: висота вікна таблиці ТЕПЕР ДИНАМІЧНА (js/services-table.js) —
   стільки, скільки вільно під нею у 100vh панелі, але не більше 844px
   (дизайнерський максимум, рівно 844 на екрані 1080). Дистанція гортання =
   2178 − поточна висота вікна: користувач завжди мусить догорнути таблицю
   до кінця незалежно від висоти екрана. Висоту .services (обгортки) —
   інтро + 100vh + ця дистанція — теж рахує й підставляє JS.
   ========================================================================== */

.services {
  position: relative;
  z-index: 1;
}

.services__intro {
  /* 194px від нижнього краю .hero (секції йдуть впритул одна за одною) */
  padding-top: 194px;
}

/* Сітка 8 колонок по 128px, gutter 20px, Center — та сама, що й в .grid-overlay.
   Патерн заголовного блоку (лейбл+номер → 26px → заголовок → 28px → опис
   з колонки 6) повторюється в Selected Work, Industries і Offices —
   спільні властивості задані одним правилом на всі класи, щоб не
   дублювати стилі */
.services__intro-grid,
.selected-work__grid,
.industries__grid,
.offices__grid,
.about-approach__grid,
.about-stats__grid,
.how-we-work__grid,
.leadership__grid,
.about-offices__grid,
.our-commitments__grid,
.faq__grid,
.footer__grid {
  display: grid;
  grid-template-columns: repeat(8, 128px);
  column-gap: 20px;
  max-width: 1164px;
  margin: 0 auto;
}

.services__label,
.selected-work__label,
.industries__label,
.offices__label,
.about-approach__label,
.how-we-work__label,
.leadership__label,
.about-offices__label,
.our-commitments__label,
.faq__label {
  grid-column: 1;
  grid-row: 1;
  color: var(--grey-50);
}

/* Фікс: "OUR COMMITMENTS" довший за колонку 1 (128px) — на відміну від
   інших лейблів цього патерна ("TRUSTED BY", "OFFICES" тощо), тому
   переносився на 2 рядки. nowrap лишає текст в один рядок, він просто
   візуально виходить за межі своєї grid-колонки (як і скрізь по сайту —
   grid-item тут не обрізає overflow) */
.our-commitments__label {
  white-space: nowrap;
}

/* Колонка 6 = 740px від лівого краю сітки (5×128 + 5×20) */
.services__index,
.selected-work__index,
.industries__index,
.offices__index,
.about-approach__index,
.how-we-work__index,
.leadership__index,
.about-offices__index,
.our-commitments__index,
.faq__index {
  grid-column: 6;
  grid-row: 1;
  color: var(--grey-50);
}

/* Колонки 1–5, 26px до верхнього краю від низу рядка-лейбла */
.services__title,
.selected-work__title,
.industries__title,
.offices__title,
.about-approach__title,
.how-we-work__title,
.leadership__title,
.about-offices__title,
.our-commitments__title,
.faq__title {
  grid-column: 1 / 6;
  grid-row: 2;
  margin-top: 26px;
  color: var(--grey-100);
}

/* FAQ: без боді — тайтл шириною точно під текст (fit-content, не auto:
   auto в grid-item за замовчуванням розтягується на всю колонку 1–6,
   720px, — тут навмисно НЕ на всю колонку, а рівно під довжину рядка),
   на відміну від інших заголовків цього патерна, що навмисно вужчі за
   720px, аби форсувати перенос у 2 рядки */
.faq__title {
  width: fit-content;
  white-space: nowrap;
}

/* Фікс: "IV." тут з колонки 5 (592px), не 6 (740px), як в інших заголовках
   цього патерна — вертикальне вирівнювання з лейблом FAQ (grid-row:1)
   лишається незмінним, лише горизонтальна позиція */
.faq__index {
  grid-column: 5;
}

/* Заголовки вужчі за природну ширину колонок 1–5 (720px) — форсують
   природний перенос у 2 рядки замість ручного <br>, як у Services */
.selected-work__title {
  width: 463px;
}

.industries__title {
  width: 429px;
}

.offices__title {
  width: 494px;
}

.about-approach__title {
  width: 586px;
}

.how-we-work__title {
  width: 586px;
}

.leadership__title {
  width: 563px;
}

/* Ручний перенос тайтлу Leadership потрібен лише в планшетній сітці
   (Крок 147-фікс) — за замовчуванням вимкнений (display:none), як і
   .about-stats__break/.how-we-work__desc-break--tablet вище */
.leadership__title-break {
  display: none;
}

.about-offices__title {
  width: 494px;
}

.our-commitments__title {
  width: 494px;
}

/* Колонки 6–8 = 424px, окремий рядок (3) — рівно під заголовком.
   28px рахуються від нижнього краю заголовка */
.services__desc,
.selected-work__desc,
.industries__desc,
.offices__desc,
.about-approach__desc,
.how-we-work__desc,
.leadership__desc,
.about-offices__desc,
.our-commitments__desc {
  grid-column: 6 / 9;
  grid-row: 3;
  margin-top: 28px;
  color: var(--grey-60);
}

/* Ручний перенос боді-тексту Services — 6 потенційних точок розриву,
   кожна зі своєю комбінацією активних breakpoint'ів (той самий tablet-
   break прийом, що .work-hero__desc-break--desktop/--mobile). За
   замовчуванням (десктоп і Mobile — в обох однаковий перенос) активні
   лише --2/--5 (default <br>, без окремого правила); --1/--3/--4/--6
   вимкнені тут і вмикаються по-своєму в Tablet Portrait нижче */
.services__desc-break--1,
.services__desc-break--3,
.services__desc-break--4,
.services__desc-break--6 {
  display: none;
}

/* Ручний перенос боді-тексту Selected Work — той самий tablet-break
   прийом: 7 потенційних точок розриву, за замовчуванням (Desktop/Tablet
   Landscape/Mobile — однаковий перенос) активні лише --2/--4/--6;
   --1/--3/--5/--7 вимкнені тут і вмикаються замість них у Tablet Portrait
   нижче (Крок — фікс боді-тексту) */
.selected-work__desc-break--1,
.selected-work__desc-break--3,
.selected-work__desc-break--5,
.selected-work__desc-break--7 {
  display: none;
}

/* Тайтл Services на Mobile (≤767px, Крок 178) — не просто інший перенос
   рядків, а переписаний текст ("SaaS design services / for every product
   stage" замість "Five practices. One integrated team"), тому окрема <h2>
   (.services__title--mobile), не набір <br> — той самий прийом, що
   .faq-item__body--tablet (окрема <p> з переписаним текстом). Вимкнена
   за замовчуванням, вмикається разом із вимкненням .services__title--desktop
   у медіа-запиті нижче */
.services__title--mobile {
  display: none;
}

/* Боді-текст айтемів Offices (Home) — той самий "--desktop/--mobile"
   прийом, що .services__title--desktop/--mobile: New York отримує
   переписаний текст на Mobile (не просто інший перенос), тому окремий
   <p> (.offices__body--mobile), приховано за замовчуванням; London/Kyiv —
   лише інший перенос того самого тексту, тому один спільний <br>-клас
   у кожен бік (.offices__body-break--desktop/--mobile) */
.offices__body--mobile,
.offices__body-break--mobile,
.work-empty__desc-break--mobile {
  display: none;
}

/* Ручний перенос тайтла Hero (about.html, Крок 206: оновлений текст) —
   "--wide" відображається за замовчуванням (десктоп/Tablet Landscape/
   Tablet Portrait, той самий 2-рядковий розрив на всіх трьох), вимикається
   лише на Mobile. "--mobile" — навпаки, вимкнений за замовчуванням,
   вмикається лише на Mobile (свій, 3-рядковий розрив, tablet-break
   прийом, що вже є в проєкті, напр. .work-hero__desc-break--mobile) */
.about-hero__title-break--mobile {
  display: none;
}

/* Ручні переноси тайтла/боді Our Commitments і боді Industries
   (services.html), специфічні для Tablet Portrait (768–1023px, Фікс після
   Кроків 173/174) — той самий tablet-break прийом, що вище. Компонування
   рядків тут відрізняється і від десктопу, і від Tablet Landscape (не
   просто увімкнення вже наявних --tablet/--desktop розривів), тому окремий
   набір класів, вимкнений за замовчуванням, вмикається в медіа-запиті
   нижче */
.our-commitments__title-break--portrait,
.our-commitments__item-body-break--portrait,
.industries__desc-break--portrait,
.offices__desc-break--portrait,
.selected-work__title-break--mobile {
  display: none;
}

/* Боді Offices (index.html) — Tablet Landscape (1024–1279px) має власний
   розподіл рядків, відмінний і від десктопу (--strategy лишається
   активним там за замовчуванням, без класу), і від Tablet Portrait
   (--portrait) — тому окремий клас, вимкнений за замовчуванням,
   вмикається лише в TL медіа-запиті нижче (той самий tablet-break прийом) */
.offices__desc-break--landscape {
  display: none;
}

/* Боді Industries (services.html) — Mobile (≤767px) має свій ВЛАСНИЙ
   розподіл рядків, відмінний і від десктопу/Tablet Landscape
   (--desktop), і від Tablet Portrait (--portrait), тому окремий клас,
   вимкнений за замовчуванням, вмикається лише в mobile медіа-запиті
   нижче (той самий tablet/mobile-break прийом) */
.industries__desc-break--mobile {
  display: none;
}

/* Строук під підтекстом How We Work (about.html) — новий елемент,
   є лише в розмітці для Tablet Portrait (768–1023px, Крок 167-фікс),
   у десктопі/Tablet Landscape його немає в дизайні, тому прихований
   за замовчуванням і показаний лише в медіа-запиті нижче */
.how-we-work__extra-line {
  display: none;
}

/* height — фолбек 100vh, JS не змінює (панель завжди рівно на екран).
   БЕЗ overflow/clip-path: на низьких екранах ілюстрація (1003px) фізично
   не влазить у 100vh і навмисно звисає нижче панелі, а не обрізається —
   js/services-table.js рахує реальний звис і відсуває trusted-by рівно
   на 158px від СПРАВЖНЬОГО (не обрізаного) низу ілюстрації. Горизонтальне
   глушіння виступу ілюстрації ліворуч живе на body (overflow-x: hidden) —
   тут його НЕ додаємо: overflow-x на панелі зробив би overflow-y авто
   й обрізав би саме той вертикальний звис, якого тут навмисно хочемо */
.services__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
}

.services__panel-grid {
  display: grid;
  grid-template-columns: repeat(8, 128px);
  column-gap: 20px;
  max-width: 1164px;
  margin: 0 auto;
}

/* -------------------------------------------------------------------------
   Ілюстрація зліва — частина sticky-панелі (нерухома, поки гортається
   таблиця), лежить під таблицею (z-index нижче). Той самий рядок (1),
   що й вікно таблиці, — 40px від верху панелі, що візуально збігається
   з низом опису саме в момент пінінгу (панель пінується top: 0)

   Горизонтально: правий край на 59px лівіше лівого краю таблиці.
   592px (колонка 5) − 59px − 1016px (ширина ілюстрації) = −483px —
   ілюстрація навмисно виходить за межі сітки й частково за край екрана
   ------------------------------------------------------------------------- */
/* Стек шарів ілюстрації (Крок 97): один базовий шар (services-illustration.webp,
   1016×1016) + 5 кольорових glow-масок (mask-group-1..5) поверх нього —
   стек тримає позицію/розмір, що раніше були прямо на .services__illustration */
/* Фікс (crossfade замість видимого обертання): весь стек (база + активна
   маска + теги) тепер кросфейдить як ОДНЕ ціле — opacity/transition тут,
   а не на кожному шарі окремо. js/services-illustration.js гасить стек
   (opacity 0), поки він невидимий — миттєво міняє --services-illustration-
   rotate/data-active-mask/позиції тегів, і лише тоді проявляє стек назад.
   400ms ease — та сама тривалість/easing, що вже усталена в цій секції
   для crossfade (раніше жила на .services__illustration-mask) */
.services__illustration-stack {
  position: relative;
  z-index: 0;
  grid-column: 1;
  grid-row: 1;
  margin-top: 40px;
  margin-left: -483px;
  width: 1016px;
  height: 1016px;
  opacity: 1;
  transition: opacity 400ms ease;
}

/* Базова ілюстрація — єдиний шар, завжди той самий файл. Обертається на
   фіксований кут за activeIndex (js/services-illustration.js виставляє
   --services-illustration-rotate на .services__illustration-stack) —
   кут НЕ залежить від активної маски (два незалежні набори значень,
   прив'язані до одного activeIndex, Крок 97 п.5). Фікс: transform більше
   НЕ анімується (немає власного transition) — JS міняє кут лише поки
   .services__illustration-stack невидимий (opacity: 0), тож сам поворот
   ніколи не видно, як би довго не тривав */
.services__illustration-base {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 1016px;
  height: 1016px;
  transform: rotate(var(--services-illustration-rotate, 0deg));
  transform-origin: center center;
}

/* Glow-маски — усі 5 одразу в DOM, перемикаються через opacity (той самий
   підхід, що глобуси Industries, щоб уникнути блимання при першому
   спрацюванні): data-active-mask на .services__illustration-stack
   (js/services-illustration.js). Поверх базової ілюстрації (z-index вищий).
   mix-blend-mode не застосовується — прозорість вже "запечена" в
   альфа-канал файлу (Figma: blend mode Normal).
   Фікс: сам перемикач маски більше не анімується власним transition —
   він відбувається миттєво, поки батьківський .services__illustration-stack
   невидимий (opacity: 0); видимий crossfade робить лише стек цілком */
.services__illustration-mask {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 1016px;
  height: 1016px;
  opacity: 0;
}

/* Дефолт (до першого виклику з JS, і на випадок, якщо він так і не
   спрацює) — Consulting активний одразу, без блимання при завантаженні */
.services__illustration-stack:not([data-active-mask]) .services__illustration-mask--consulting {
  opacity: 1;
}

.services__illustration-stack[data-active-mask='consulting'] .services__illustration-mask--consulting,
.services__illustration-stack[data-active-mask='audit'] .services__illustration-mask--audit,
.services__illustration-stack[data-active-mask='product'] .services__illustration-mask--product,
.services__illustration-stack[data-active-mask='brand'] .services__illustration-mask--brand,
.services__illustration-stack[data-active-mask='operations'] .services__illustration-mask--operations {
  opacity: 1;
}

/* Крок 99: 5 персистентних тегів-практик поверх ілюстрації — left/top
   (відносно фрейма 1016×1016px) і активний/неактивний стан перемикає
   js/services-illustration.js синхронно з масками (той самий activeIndex).
   Фікс: власного opacity/transition тут більше немає — тег видимий
   завжди (opacity:1), а сам crossfade робить лише батьківський
   .services__illustration-stack; left/top і активний/неактивний клас
   оновлюються миттєво, поки стек невидимий (opacity: 0). height: 34px
   фіксована в обох станах: border 1px присутній ЗАВЖДИ (box-sizing:
   border-box), змінюється лише його колір — тому розмір не стрибає між
   активним/неактивним станом */
.services__tag {
  position: absolute;
  z-index: 2;
  height: 34px;
  padding: 7px 20px;
  box-sizing: border-box;
  background: var(--grey-15);
  border: 1px solid var(--color-background);
  color: var(--grey-60);
  text-transform: uppercase;
  white-space: nowrap;
}

/* Неактивний — inside stroke var(--color-background) (реально видимий,
   не замаскований під фон чіпа) */
.services__tag--inactive {
  color: var(--grey-60);
  border-color: var(--color-background);
}

/* Активний — border прибрано ПОВНІСТЮ (border: none, а не просто
   прозорий колір): якщо ширина бордера лишається 1px, вона й далі
   зсуває padding-box відносно border-box, а саме padding-box є
   точкою відліку для left/right/bottom абсолютно спозиційованого
   ::after — тому "прозорий" бордер раніше залишав 1px відступ
   навколо градієнтної лінії замість рівно країв чіпа. Нижній
   строук — через ::after, бо border-color не приймає градієнт напряму */
.services__tag--active {
  color: var(--grey-100);
  border: none;
}

.services__tag--active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--primary-grad);
}

/* -------------------------------------------------------------------------
   Таблиця практик — вікно 572×[динамічна] з overflow: hidden, всередині
   якого js/services-table.js зсуває повну 2178px-ву таблицю через transform
   ------------------------------------------------------------------------- */

/* Колонки 5–8 = 572px (592px від лівого краю сітки), той самий рядок (1),
   119px від верху панелі — візуально це 119px між описом і таблицею,
   бо панель починається рівно там, де закінчується опис (пін top: 0).
   height: 844px — фолбек/дизайнерський максимум, JS підставляє точне
   значення під конкретну висоту екрана. z-index вище за
   .services__illustration-stack — таблиця лягає поверх неї */
.services-table-window {
  position: relative;
  z-index: 1;
  grid-column: 5 / 9;
  grid-row: 1;
  margin-top: 119px;
  width: 572px;
  height: 844px;
  overflow: hidden;
}

.services-table {
  width: 100%;
  border: 1px solid var(--grey-15);
  /* Desktop (≥1280px, базове правило) — ОРИГІНАЛЬНА поведінка: js/
     services-table.js на цьому breakpoint і далі квантує позицію до
     activeIndex×step, а transition сам доїжджає до нової цілі за 300ms
     (design intent Кроку 29, навмисний "доганяючий" ефект). На Mobile/
     Tablet Landscape/Tablet Portrait (≤1279px) transition знято нижче —
     там JS пише позицію напряму 1:1 (progress×scrollRange, той самий
     фікс, що в Industries, js/industries-mobile-scrolly.js), і окремий
     transition лише додавав би відставання від скролу/пальця */
  transition: transform 300ms ease-out;
  /* Safari-фікс: transform пишеться на кожен тик 'scroll' Lenis
     (js/services-table.js) — will-change заздалегідь промотує шар у
     compositor, без цього Safari (на відміну від Chrome) менш охоче
     робить це сама, даючи видиму затримку на перший repaint */
  will-change: transform;
}

@media (max-width: 1279px) {
  .services-table {
    transition: none;
  }
}

.services-table__row {
  width: 100%;
}

.services-table__row--heading {
  height: 54px;
  padding: 17px 0 17px 32px;
  color: var(--grey-60);
  background-color: var(--grey-5);
  text-transform: uppercase;
  transition: color 150ms ease;
}

/* Активна група (керує js/services-table.js за activeIndex, як і .services-table__row--item.is-active) */
.services-table__row--heading.is-active {
  color: var(--grey-100);
}

/* Лейбл (напр. "P. I.") — доданий у фрейм тайтла лише для десктопа
   (≥1280px, п.4 ТЗ нижче); прихований за замовчуванням, щоб не зʼявлятись
   на Tablet Landscape (1024–1279px, повністю успадковує ці базові правила
   без власного оверрайду) чи інших breakpoint */
.services-table__heading-label {
  display: none;
}

.services-table__row--strokes {
  height: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* Вертикальні (бокові) лінії малює лише .services-table (зовнішній контур) —
   рядки дають тільки горизонтальні роздільники зверху, щоб нічого не
   подвоювалось ні по боках, ні між сусідніми рядками */
.services-table__row--item {
  height: 68px;
  padding: 22px 0 22px 32px;
  color: var(--grey-60);
  border-top: 1px solid var(--grey-15);
  transition: color 150ms ease;
}

/* Активний item (керує js/services-table.js за прогресом гортання) */
.services-table__row--item.is-active {
  color: var(--grey-100);
}

/* Як item, але без тексту */
.services-table__row--empty {
  height: 56px;
  border-top: 1px solid var(--grey-15);
}

/* Затемнення знизу й зверху вікна — натякають, що в цьому напрямку є ще
   вміст. Спільні position/height/pointer-events/transition — різні лише
   бік і напрямок градієнта. Нижній видний за замовчуванням і зникає на
   progress = 1; верхній прихований, поки активний перший item (Discovery &
   Strategy), і з'являється лише з activeIndex >= 1 (js/services-table.js) —
   на самому першому item'і затіняти CONSULTING зверху нічим */
.services-table-window__fade {
  position: absolute;
  left: 0;
  right: 0;
  height: 120px;
  pointer-events: none;
  transition: opacity 300ms ease;
}

.services-table-window__fade--bottom {
  bottom: 0;
  background: linear-gradient(to bottom, transparent, var(--color-background));
  opacity: 1;
}

.services-table-window__fade--bottom.is-hidden {
  opacity: 0;
}

.services-table-window__fade--top {
  top: 0;
  background: linear-gradient(to bottom, var(--color-background), transparent);
  opacity: 0;
}

.services-table-window__fade--top.is-visible {
  opacity: 1;
}

/* ==========================================================================
   DESKTOP (≥1280px) — Services: нові стилі активного чіпа-тега, фрейма
   тайтла групи (+ лейбл "P. I." тощо) і фрейма айтема таблиці практик.

   Навмисно винесено в окремий @media (min-width: 1280px), а не вписано в
   базові (unguarded) правила вище: ті базові правила успадковує без
   власного оверрайду і Tablet Landscape (1024–1279px) — якби ми змінили
   їх напряму, зміна проступила б і туди. Ця секція стосується ЛИШЕ
   реального десктопа (≥1280px), Tablet Landscape/Portrait/Mobile
   лишаються на старому вигляді через базові правила вище.
   ========================================================================== */
@media (min-width: 1280px) {
  /* Активний чіп на ілюстрації — прибрано нижній градієнтний строук
     (колір тексту вже var(--grey-100) у базовому .services__tag--active) */
  .services__tag--active::after {
    display: none;
  }

  /* Фрейм тайтла сервісу — тайтл (dm-22-reg) + лейбл ("P. I." тощо) в один
     ряд, лейбл притиснутий до правого краю фрейма (32px завдяки padding +
     justify-content: space-between) */
  .services-table__row--heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 62px;
    padding: 0 32px;
  }

  /* Тайтл — стиль завжди однаковий (DM Sans/22 Reg, var(--grey-100)),
     незалежно від активності групи (раніше залежав — керувалось
     .services-table__row--heading.is-active вище) */
  .services-table__heading-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--grey-100);
  }

  .services-table__heading-label {
    display: inline-block;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-50);
  }

  /* Фрейм айтема (значення, напр. "Discovery & Strategy") — Red Hat/12
     Bold (tracking), var(--grey-55); var(--grey-100), якщо айтем активний
     (.is-active — уже задає базове правило вище, спрацьовує і тут завдяки
     вищій специфічності .services-table__row--item.is-active). Аперкейс —
     лише через CSS, текст-контент у HTML лишається в звичайному регістрі */
  .services-table__row--item {
    height: 56px;
    padding: 0 0 0 32px;
    display: flex;
    align-items: center;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-55);
  }

  /* Лівий строук активного айтема — тепер на ВЕСЬ блок сервісу (обгортка
     .services-table__group: фрейм тайтла + патерн + всі фрейми айтемів +
     пустий фрейм), а не лише на активний фрейм айтема — :has() ловить
     групу, що містить активний айтем, top/bottom:0 самі розтягуються на
     реальну (змінну — кількість айтемів різна для різних сервісів) висоту
     обгортки, без хардкоду конкретного значення в px */
  .services-table__group {
    position: relative;
  }

  /* ::before завжди в DOM (а не лише коли :has() матчить) — властивість
     content не анімується, тож поява/зникнення строука мала б бути
     миттєвою, якби сам псевдоелемент з'являвся/зникав разом із :has().
     Замість цього тут завжди opacity:0 і перемикається лише opacity —
     той самий timing/easing, що .scroll-reveal (js/reveal.js) */
  .services-table__group::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--primary-grad-services);
    opacity: 0;
    transition: opacity .65s var(--ease-smooth);
  }

  .services-table__group:has(.services-table__row--item.is-active)::before {
    opacity: 1;
  }
}

/* ==========================================================================
   TABLET LANDSCAPE (1024–1279px) — Services: той самий підхід, що на
   десктопі вище (активний чіп-тег без нижнього строука, фрейм тайтла
   групи 62px + лейбл, фрейм айтема з Red Hat/12 Bold (tracking), лівий
   градієнтний строук на весь блок сервісу) — ЄДИНА відмінність: висота
   фрейму айтема 68px (56px у десктопі). Блок сервісу разом: 62 (тайтл) +
   40 (патерн, успадковано з базового .services-table__row--strokes) +
   68 (айтем) + 56 (пустий фрейм, успадковано з базового
   .services-table__row--empty) = 226px */
@media (min-width: 1024px) and (max-width: 1279px) {
  .services__tag--active::after {
    display: none;
  }

  .services-table__row--heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 62px;
    padding: 0 32px;
  }

  .services-table__heading-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--grey-100);
  }

  .services-table__heading-label {
    display: inline-block;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-50);
  }

  /* Єдина відмінність від десктопа: height 68px (56px там) */
  .services-table__row--item {
    height: 68px;
    padding: 0 0 0 32px;
    display: flex;
    align-items: center;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-55);
  }

  .services-table__group {
    position: relative;
  }

  .services-table__group::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--primary-grad-services);
    opacity: 0;
    transition: opacity .65s var(--ease-smooth);
  }

  .services-table__group:has(.services-table__row--item.is-active)::before {
    opacity: 1;
  }
}

/* ==========================================================================
   TRUSTED BY — рядок лейблів + сітка логотипів

   .trusted-by йде одразу після .services у звичайному потоці документа.
   margin-top тут — лише фолбек (158px); точне значення на 158px від
   справжнього (не обрізаного) низу ілюстрації, з урахуванням її можливого
   звису нижче sticky-панелі на низьких екранах, рахує й підставляє
   js/services-table.js
   ========================================================================== */

.trusted-by {
  margin-top: 158px;
}

.trusted-by__grid {
  display: grid;
  grid-template-columns: repeat(8, 128px);
  column-gap: 20px;
  max-width: 1164px;
  margin: 0 auto;
}

/* white-space: nowrap — той самий принцип, що .our-commitments__label:
   текст довший за вузьку мобільну колонку 1 (72px) переносився на 2
   рядки ("TRUSTED"/"BY"); grid-item тут не обрізає overflow (по всьому
   сайту), тому текст просто бleed-ить праворуч за межі власної колонки,
   лишаючись в один рядок */
.trusted-by__label {
  grid-column: 1;
  grid-row: 1;
  color: var(--grey-50);
  white-space: nowrap;
}

/* Колонка 6 = 740px від лівого краю сітки (5×128 + 5×20) */
.trusted-by__index {
  grid-column: 6;
  grid-row: 1;
  color: var(--grey-50);
}

/* Окрема вкладена сітка 8×2, gap 20px в обидва боки — блоки колонок
   збігаються з колонками основної сітки. Власний grid-row (2) уникає
   auto-розстановки у вільні клітинки рядка 1 (та сама логіка, що й
   у секції Services вище). Блоки — лише контейнери для логотипів,
   БЕЗ жодних бордерів: усі лінії малює один оверлей .trusted-by__lines
   нижче, щоб кожна лінія існувала рівно один раз */
.trusted-by__logos {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 2;
  margin-top: 16px;
  display: grid;
  grid-template-columns: repeat(8, 128px);
  grid-template-rows: repeat(2, 128px);
  gap: 20px;
}

.trusted-by__logo-cell {
  position: relative;
  width: 128px;
  height: 128px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
}

/* Фікс: обгортка навколо самих <img> (Mobile/Tablet Portrait ротація,
   js/trusted-by-rotate.js) — 100%/100% УНІВЕРСАЛЬНО, незалежно від
   breakpoint, щоб .trusted-by__logo-cell (фрейм) залишався СТАТИЧНИМ і
   ніколи не отримував transform/opacity власної ротаційної анімації.
   position:relative тут (а не лише на клітинці) — коли клас --fading
   додає transform на цей елемент (нижче, лише Mobile/Tablet Portrait),
   transform сам собою створює новий containing block для абсолютно
   спозиційованих <img> усередині; без явних 100%/100% тут цей контейнер
   був би 0×0 (порожній div без "живого" контенту в потоці) і зображення
   зістрибували б у верхній лівий кут кожного разу, коли з'являється
   transform. Фон при ховері (::after нижче) лишається на КЛІТИНЦІ — не
   на цій обгортці — тому ніколи не анімується/не зсувається разом із
   логотипом.
   Фікс: z-index:3 тут ОБОВ'ЯЗКОВИЙ, не косметичний — will-change:
   opacity, transform (додається нижче на Mobile/Tablet Portrait) сам по
   собі створює для цього елемента новий stacking context (за specою,
   незалежно від того, чи opacity/transform зараз активно відрізняються
   від початкових значень). Без власного z-index обгортка потрапляє в
   зовнішній stacking context із z-index:auto й програє клітинковому
   ::after (z-index:2, фон-при-ховері) — тому логотип (і білий, і
   чорний варіант) ставав повністю невидимим під суцільним жовтим
   фоном, хоч opacity/клас на самих <img> перемикались правильно */
.trusted-by__logo-wrap {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 100%;
}

/* Hover-фон — окремий шар з inset: -1px (не фон самої клітинки):
   розширюється на 1px в усі боки, тому "з'їдає" лінії оверлея, що
   межують з блоком, замість того щоб ховатись під ними. z-index: 2
   вище за .trusted-by__lines (1) — лінії опиняються під помаранчевим
   фоном на hover; z-index: 3 у логотипів (нижче) тримає їх поверх фону */
/* Асиметрично, а не inset: -1px — бо межі оверлея не симетричні.
   Внутрішні лінії (гаттери, y=128) сидять РІВНО на координаті блока
   (0, 128, 148…), тобто зовнішня для блока сторона лінії лежить на
   1px ПОЗА його власним 128×128 діапазоном — туди й треба дотягнутись
   (-1px). Але дві КРАЙНІ лінії групи (правий край x=1163, низ y=275)
   навмисно зсунуті на 1px усередину (щоб не обрізатись межею
   контейнера, див. .trusted-by__lines) — тому для блоків останньої
   колонки й другого ряду ця лінія вже СЕРЕД власного 128×128
   діапазону блока, і розширення там зайве (0, не -1px):
   - top/left завжди 0 (ліва/верхня лінія кожного блока збігається
     з його власним верхнім лівим кутом)
   - right: -1px, КРІМ останньої колонки (там 0)
   - bottom: -1px, КРІМ другого ряду (там 0)
   Перевірено пиксельним рендером на кутовому/середньому/крайньому блоках */
.trusted-by__logo-cell::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: -1px;
  bottom: -1px;
  z-index: 2;
  background-color: transparent;
  transition: background-color 200ms ease;
  pointer-events: none;
}

/* Останній стовпець кожного ряду (8, 16) — права лінія групи вже
   всередині власного діапазону блока */
.trusted-by__logo-cell:nth-child(8n)::after {
  right: 0;
}

/* Другий ряд (9–16) — нижня лінія групи вже всередині власного
   діапазону блока */
.trusted-by__logo-cell:nth-child(n + 9)::after {
  bottom: 0;
}

.trusted-by__logo-cell:hover::after {
  background-color: var(--primary-100);
}

/* -------------------------------------------------------------------------
   Єдиний оверлей-шар з усією сіткою ліній (position: absolute; inset: 0;
   pointer-events: none), останній у DOM — тому лягає поверх фонів
   блоків (у т.ч. помаранчевого hover), логотипів це не стосується.

   27 шарів через background-image (кожен — суцільний 1px grey-15
   прямокутник заданого розміру/позиції):
   - 16 вертикальних, на всю висоту групи (0→276): краї (0, 1164)
     + обидві межі кожного з 7 гаттерів (128/148, 276/296, ...)
   - 3 горизонтальні на всю ширину (1164): y=0 (верх), y=128 (низ
     ряду 1), y=276 (низ групи) — рядок 2 суцільної лінії згори
     НЕ отримує, лише...
   - 8 горизонтальних відрізків 128px завширшки на y=148 — по одному
     точно під кожним блоком ряду 2, гаттери лишаються відкритими

   Для двох крайніх ліній (x=1164, y=276) — keyword-синтаксис
   "right 0px top 0" / "left 0 bottom 0px" замість пиксельних
   координат: він однозначно притискає смугу до справжньої межі
   контейнера незалежно від математики (container - layer), яку
   легко прорахувати на 1px неточно з calc(100% - Npx)
   ------------------------------------------------------------------------- */
.trusted-by__lines {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15)),
    linear-gradient(var(--grey-15), var(--grey-15));
  background-size:
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1px 276px,
    1164px 1px,
    1164px 1px,
    1164px 1px,
    128px 1px,
    128px 1px,
    128px 1px,
    128px 1px,
    128px 1px,
    128px 1px,
    128px 1px,
    128px 1px;
  background-position:
    0px 0,
    128px 0,
    148px 0,
    276px 0,
    296px 0,
    424px 0,
    444px 0,
    572px 0,
    592px 0,
    720px 0,
    740px 0,
    868px 0,
    888px 0,
    1016px 0,
    1036px 0,
    right 0px top 0,
    0 0px,
    0 128px,
    left 0 bottom 0px,
    0px 148px,
    148px 148px,
    296px 148px,
    444px 148px,
    592px 148px,
    740px 148px,
    888px 148px,
    1036px 148px;
}

/* Два <img> (білий/чорний) абсолютно спозиційовані по центру блока,
   один поверх одного. Усі лого — 128×128px, файли самі мають єдиний
   розмір (Крок 91), тому індивідуальних width/height на кожне лого
   більше не треба. object-fit: contain — бокс лишається заданого
   розміру, але вміст масштабується ОДНИМ коефіцієнтом за рідним
   viewBox SVG, а не розтягується по X/Y незалежно */
.trusted-by__logo {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 3;
  transform: translate(-50%, -50%);
  display: block;
  width: 128px;
  height: 128px;
  object-fit: contain;
  transition: opacity 200ms ease;
}

.trusted-by__logo--white {
  opacity: 1;
}

.trusted-by__logo--black {
  opacity: 0;
}

.trusted-by__logo-cell:hover .trusted-by__logo--white {
  opacity: 0;
}

.trusted-by__logo-cell:hover .trusted-by__logo--black {
  opacity: 1;
}

/* ==========================================================================
   SELECTED WORK — заголовний блок

   Структура ідентична заголовному блоку Services (лейбл+номер → 26px →
   заголовок → 28px → опис з колонки 6) — спільні CSS-правила винесені
   разом із .services__label/__index/__title/__desc вище.
   ========================================================================== */

/* 206px від нижньої лінії периметра сітки логотипів (.trusted-by__logos) —
   секції йдуть впритул одна за одною, тому це просто margin-top від кінця
   попередньої секції */
.selected-work {
  margin-top: 206px;
}

/* -------------------------------------------------------------------------
   Ряд карток: 720px + 20px + 424px = 1164 (уся сітка). Права колонка —
   окрема flex-колонка, бо під карткою 2 йде ще декоративний блок-патерн
   (.selected-work__strokes) — вирівнювання по верхньому краю (align-items: flex-start)
   ------------------------------------------------------------------------- */
.selected-work__cards {
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 96px;
  display: flex;
  align-items: flex-start;
  gap: 20px;
}

.selected-work__col-secondary {
  display: flex;
  flex-direction: column;
  width: 424px;
}

.selected-work__strokes {
  margin-top: 20px;
  width: 424px;
  height: 213px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* Крок 112: коли мала картка над цим патерном прихована (фільтр/пошук) —
   патерн зливається з її звільненим місцем в один суцільний блок:
   520px (мала картка) + 20px (margin-top) + 213px (патерн) = 753px,
   що дорівнює повній висоті великої картки в цьому ж рядку */
.selected-work__strokes--full {
  margin-top: 0;
  height: 753px;
}

/* -------------------------------------------------------------------------
   Картка роботи — спільна структура для обох розмірів. display:flex;
   flex-direction:column на .work-card дає дочірнім блокам (topbar/image/
   info/tags) стандартний align-items:stretch — кожен сам розтягується
   на всю ширину картки, тому "ширина картки" ніде не дублюється зайвим
   width-правилом.

   Строуки НАВМИСНО не утворюють суцільну рамку: у topbar немає низу,
   у image немає жодного бордера, у info/tags немає верху — це відкриває
   шви між блоками, як і задумано (ніде не подвоюється, "закриває"
   периметр лише info__bottom + tags__bottom)
   ------------------------------------------------------------------------- */
.work-card {
  display: flex;
  flex-direction: column;
}

.work-card--primary {
  width: 720px;
}

.work-card--secondary {
  width: 424px;
}

/* position: relative — точка відліку для .work-card__cta (текст
   "READ THE CASE STUDY", з'являється зліва від стрілки на hover) */
.work-card__topbar {
  position: relative;
  height: 36px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-left: 1px solid var(--grey-15);
  border-right: 1px solid var(--grey-15);
  border-top: 1px solid var(--grey-15);
}

.work-card__topbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.work-card__dot {
  width: 3px;
  height: 3px;
  flex-shrink: 0;
  background-color: var(--grey-50);
  opacity: 0.3;
}

.work-card__date {
  color: var(--grey-50);
  transition: color 200ms ease;
}

.work-card:hover .work-card__date {
  color: var(--grey-100);
}

.work-card__icon {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  color: var(--grey-50);
  transition: color 200ms ease;
}

/* Фікс (тимчасово): приховує "Read the case study" і стрілки на картках
   Selected Work — сторінок окремих робіт ще немає. .work-card__cta
   позиціонована absolute (не бере участі в потоці), а .work-card__icon —
   останній flex-item топбару, тому display: none на обох нічого не
   зсуває. Прибрати клас, коли з'являться сторінки окремих робіт. */
.is-hidden-temp {
  display: none;
}

.work-card:hover .work-card__icon {
  color: var(--grey-100);
}

/* Зафіксована через right (не впливає на позицію стрілки): 20px паддінг
   топбару + 10px ширина іконки + 10px відступ = 40px від правого краю */
.work-card__cta {
  position: absolute;
  top: 50%;
  right: 40px;
  transform: translateY(-50%);
  color: var(--grey-100);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

.work-card:hover .work-card__cta {
  opacity: 1;
}

/* Точні розміри виводу: Hermes 720×565, решта 424×332 (задає CSS,
   реальний файл може бути й більшим — under retina 2x).
   Крок 96 — ч/б за замовчуванням, кольорове на hover картки */
.work-card__image {
  display: block;
  width: 100%;
  background-color: var(--grey-10);
  object-fit: cover;
  filter: grayscale(100%);
  transition: filter 400ms ease;
}

.work-card:hover .work-card__image {
  filter: grayscale(0%);
}

/* Tablet Landscape/Portrait/Mobile (<1280px) не мають справжнього hover —
   .work-card__scroll-color.js додає/знімає .is-active на .work-card через
   IntersectionObserver (центральна третина viewport), той самий
   filter/transition, що й hover вище. Desktop (≥1280px) лишається
   чистим hover-ефектом без цієї логіки. */
@media (max-width: 1279px) {
  .work-card.is-active .work-card__image {
    filter: grayscale(0%);
  }
}

.work-card--primary .work-card__image {
  height: 565px;
}

.work-card--secondary .work-card__image {
  height: 332px;
}

.work-card__info {
  height: 122px;
  padding: 24px 20px 0;
  border-left: 1px solid var(--grey-15);
  border-right: 1px solid var(--grey-15);
  border-bottom: 1px solid var(--grey-15);
}

.work-card__title {
  color: var(--grey-100);
}

/* Крок 110: активний пошук — немає окремого класу на .work-card__title
   для "звичайного" стану (він і так grey-100 за замовчуванням вище);
   --dimmed додається/знімається JS-ом лише поки в полі пошуку є текст */
.work-card__title--dimmed {
  color: var(--grey-50);
}

.search-match {
  color: var(--grey-100);
}

/* Ширина = ширина картки − 40px виходить сама собою: блок обмежений
   лише паддінгами .work-card__info (по 20px), нічого рахувати вручну */
.work-card__body {
  margin-top: 6px;
  color: var(--grey-60);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.work-card__tags {
  height: 30px;
  padding-left: 20px;
  display: flex;
  align-items: center;
  gap: 20px;
  border-left: 1px solid var(--grey-15);
  border-right: 1px solid var(--grey-15);
  border-bottom: 1px solid var(--grey-15);
}

.work-card__tag {
  color: var(--grey-50);
  white-space: nowrap;
  transition: color 200ms ease;
}

.work-card:hover .work-card__tag {
  color: var(--grey-60);
}

/* align-self: stretch — на всю висоту плашки (30px), попри те що
   контейнер центрує решту дітей по вертикалі (align-items: center) */
.work-card__tag-divider {
  align-self: stretch;
  width: 1px;
  flex-shrink: 0;
  background-color: var(--grey-15);
}

/* -------------------------------------------------------------------------
   Ряд 2: патерн 276px → картка 424 → картка 424 (276+20+424+20+424 = 1164).
   Висота карток тут — стандартні 520px (--secondary), тому патерн
   і картки просто вирівнюються по верху/низу через фіксовану height
   ------------------------------------------------------------------------- */
.selected-work__row2 {
  grid-column: 1 / 9;
  grid-row: 5;
  margin-top: 48px;
  display: flex;
  align-items: flex-start;
  gap: 20px;
}

/* Макетні 522px округлено до 520 — рівно висота картки .work-card--secondary
   (36+332+122+30), тож верх і низ збігаються автоматично */
.selected-work__pattern {
  width: 276px;
  height: 520px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* Крок 112: коли лише ОДИН з двох малих айтемів рядка лишився (фільтр/
   пошук) — патерн розтягується 276→720px (276 + 20px gap + 424px, тобто
   поглинає колонку відсутнього айтема). DOM-порядок дітей не міняється:
   уся секція .work-hero__row--2/--4 просто flex, тому коли ДРУГИЙ
   (сховний) айтем — display:none, перший автоматично опиняється
   одразу після патерна й доїжджає рівно туди, де мав би починатись
   другий (сховний) айтем — саме "20px відступу від айтема, що лишився" */
.selected-work__pattern--wide {
  width: 720px;
}

/* -------------------------------------------------------------------------
   Ряд 3: картка 424 (колонка 1) → SEE ALL OUR WORK (з колонки 6, 740px).
   424 + 424 = 848, залишок 1164 − 848 = 316px — рівно проміжок зі
   специфікації, тому просто justify-content: space-between без ручних
   відступів
   ------------------------------------------------------------------------- */
.selected-work__row3 {
  grid-column: 1 / 9;
  grid-row: 6;
  margin-top: 48px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.see-all-work {
  position: relative;
  width: 424px;
  height: 520px;
  flex-shrink: 0;
  border: 1px solid var(--grey-15);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--grey-50);
  text-decoration: none;
  transition: color 200ms ease, border-color 200ms ease;
}

/* Hover (Крок 104): сірий border-bottom ховається, на його місці —
   градієнтний 2px строук ::after нижче (top/left/right лишаються
   var(--grey-15) без змін) */
.see-all-work:hover {
  color: var(--grey-100);
  border-bottom-color: transparent;
}

/* Смужка знизу — той самий прийом, що в .secondary-button::after
   (Крок 103): 2px, var(--primary-grad). bottom: -1px компенсує
   border-bottom: 1px, щоб градієнт ліг рівно на місці сірого строука,
   а не зсунувся на 1px вище нього */
.see-all-work::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--primary-grad-narrow);
  opacity: 0;
  transition: opacity 300ms ease;
}

.see-all-work:hover::after {
  opacity: 1;
}

.see-all-work__icon {
  flex-shrink: 0;
}

/* -------------------------------------------------------------------------
   Ряди робіт на сторінці Work (Крок 46) — переВикористовують картки/
   патерни зі .selected-work вище як є, без дублювання CSS карток.
   .selected-work__cards і .selected-work__row2 самі по собі — shrink-to-fit
   1164px flex-рядки (720+20+424, 276+20+424+20+424), тому просто
   центруються тим самим align-items: center, що вже є на .work-hero —
   окремий wrapper із max-width:1164/margin:auto тут не потрібен.

   Ряд 1: .selected-work__cards на головній має margin-top:96px
   (відступ від заголовка секції) — тут потрібно 48px від строука
   фільтрів, тому лише цей рядок переозначається (нижче в каскаді —
   перебиває 96px). Ряд 3 — дзеркало ряду 1, той самий контейнер, той
   самий override (Крок 131: рядок 3 тепер має лише ОДИН .work-card —
   статичний патерн зліва замість другого слоту, детальніше в JS-
   коментарі над updateRow3). Ряд 2 використовує .selected-work__row2
   без жодних змін — margin-top:48px там уже коректний */
.work-hero__row--1,
.work-hero__row--3 {
  margin-top: 48px;
}

/* ==========================================================================
   WORK — empty-стан (Крок 130, перероблено — нова ілюстрація/лейаут)

   Звичайна flex-дитина .work-hero (display:none за замовчуванням, JS
   перемикає .is-visible на display:block) — займає ту саму "позицію" в
   потоці, що ряди робіт. На відміну від старої версії (full-bleed
   1920×600 патерн, текст центрований на всю ширину екрана) — тепер
   .work-empty сам звужений до стандартної сітки (width:1164px, center,
   той самий принцип, що .work-hero__title/__desc — явний width, а НЕ
   max-width: .work-empty — flex-дитина .work-hero з усіма власними
   дітьми position:absolute, тому без явного width вона колапсує до 0
   у shrink-to-fit розрахунку align-items:center і "центрується" в точку
   замість того, щоб дати справжню 1164px-сітку — виявлено рендером),
   ілюстрація — фіксований 868×545px зліва (left:0 відносно сітки),
   текстовий блок — ЛІВОРУЧ вирівняний (align-items:flex-start замість
   center), зі своїм left-інсетом від початку сітки (не від ілюстрації).
   48px — відступ від блоку фільтрів до ілюстрації (margin-top на самому
   .work-empty). 470px — відступ від блоку фільтрів до текстового блоку,
   тобто top:422px (470−48) усередині .work-empty.
   height:568px — виміряно рендером під реальний контент (title+desc+btn,
   Крок 130 текст, без змін): текст (422px top) виявляється нижчим краєм,
   ніж ілюстрація (545px), тому висота .work-empty визначається текстовим
   блоком, а не ілюстрацією — .work-hero + .cta--second{margin-top:140px}
   рахує цей відступ від ФАКТИЧНОГО низу .work-hero (тому саме тут height
   має бути точним, а не приблизним) */
.work-empty {
  display: none;
  position: relative;
  width: 1164px;
  height: 568px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 48px;
}

.work-empty.is-visible {
  display: block;
}

/* Фон — окремий абсолютний шар (не на .work-empty самому), щоб мати
   власний .empty-state-reveal незалежно від текстового блоку. Фіксований
   868×545. Фікс: left:148px (було 0) — центрує ілюстрацію в сітці
   (1164px) з точним відступом 148px з кожного боку: 1164 − 2×148 = 868,
   рівно ширина ілюстрації, тому лівий і правий геп однакові.

   Двошаровий прийом (той самий фікс "спалаху кольору", що
   .work-hero__bg/.work-hero__image — див. коментар там): .work-empty__bg
   — стабільний непрозорий шар ЛИШЕ з background-color, БЕЗ reveal-класу,
   позиція/розмір (top/left/width/height). .work-empty__image — вкладений
   inset:0, несе background-image + .empty-state-reveal (fade+translateY
   при показі empty-стану) — колір фону завжди стабільний під час
   анімації появи ілюстрації */
.work-empty__bg {
  position: absolute;
  top: 0;
  left: 148px;
  width: 868px;
  height: 545px;
  background-color: var(--color-background);
}

.work-empty__image {
  position: absolute;
  inset: 0;
  background-position: left top;
  background-repeat: no-repeat;
  background-size: 868px 545px;
  background-image: url("../assets/images/empty.webp");
  background-image: image-set(
    url("../assets/images/empty.webp") 1x,
    url("../assets/images/empty@2x.webp") 2x
  );
}

/* top:422px = 470px від блоку фільтрів − 48px margin-top .work-empty.
   left:338px від початку сітки (не від ілюстрації). align-items:flex-start
   (було center) — тайтл/боді/кнопка тепер вирівняні по лівому краю */
.work-empty__content {
  position: absolute;
  top: 422px;
  left: 338px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.work-empty__title {
  color: var(--grey-100);
}

.work-empty__desc {
  margin-top: 14px;
  color: var(--grey-60);
}

.work-empty__btn {
  margin-top: 32px;
  width: 166px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
}

/* Крок 130, п.6 — той самий fade+translateY(40px), 650ms var(--ease-smooth),
   що .scroll-reveal/.scroll-reveal-up (Крок 90), але ОКРЕМИЙ клас: reveal.js
   спостерігає лише за .scroll-reveal і назавжди знімає observer після
   першого спрацювання, а тут анімація має програватись щоразу заново,
   коли empty-стан ховається/показується повторно — керує
   js/work-filters.js (playEmptyStateReveal), не IntersectionObserver */
.empty-state-reveal {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 650ms var(--ease-smooth), transform 650ms var(--ease-smooth);
}

.empty-state-reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Легкий stagger тексту відносно ілюстрації — compound-селектор (не
   .delay-100), бо загальний .delay-100 (Крок 90) задає transition-delay
   ОКРЕМИМ правилом раніше в каскаді, а shorthand transition вище тут
   перезаписав би її назад у 0s, якби порядок джерела вирішував */
.work-empty__content.empty-state-reveal {
  transition-delay: 100ms;
}

/* ==========================================================================
   ABOUT PAGE — HERO (Крок 48)

   Той самий патерн, що .work-hero (Кроки 42-43): фон-зображення
   1920×900 фіксованого розміру (не масштабується під вікно), контент
   з фіксованим відступом зверху 170px. min-height (не фіксована height) —
   як і в .work-hero: background-size лишається 1920×900 (текст сам
   собою не займає 900px), а секція природно росте під контентом,
   доданим нижче (Крок 49, ФІКС) — інакше цей контент отримав би
   margin-top від нижнього краю 900px-боксу, а не від фактичного
   низу тексту опису */
.about-hero {
  position: relative;
  z-index: 0;
  width: 100%;
  min-height: 900px;
  background-color: var(--color-background);

  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 170px;
}

/* Той самий "фон в окремому шарі" прийом, що .work-hero__bg вище — див.
   коментар там (scroll-reveal fade-in + z-index:-1/:0 stacking-context
   фікс) */
.about-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;

  background-repeat: no-repeat;
  background-position: center top;
  background-size: 1920px 900px;
  background-image: url("../assets/images/about-bg.webp");
  background-image: image-set(
    url("../assets/images/about-bg.webp") 1x,
    url("../assets/images/about-bg@2x.webp") 2x
  );
}

.about-hero__eyebrow {
  color: var(--grey-50);
  text-transform: uppercase;
}

.about-hero__title {
  margin-top: 12px;
  width: 955px;
  color: var(--grey-100);
  text-align: center;
}

.about-hero__desc {
  margin-top: 18px;
  width: 437px;
  color: var(--grey-60);
  text-align: center;
}

/* -------------------------------------------------------------------------
   "Our Approach" — заголовний блок, той самий патерн, що Services/
   Selected Work/Industries/Offices (спільні правила label/index/title/
   desc вище). Не окрема секція, а флекс-дитина всередині .about-hero
   (той самий принцип, що .work-hero__list-heading) — align-self:stretch
   виносить її з центрованого flex-потоку hero на всю ширину, а
   margin-top:304px рахується від попереднього флекс-сиблінга
   (.about-hero__desc) напряму, незалежно від фіксованого розміру
   фону hero */
.about-approach {
  align-self: stretch;
  margin-top: 304px;
}

/* Патерн-розділювач + текст під описом — колонки 6–8 (424px), той самий
   рядок, що .selected-work__pattern/.footer__pattern (8×8 inline SVG
   косих ліній, адаптовано до висоти 6px) */
.about-approach__pattern {
  grid-column: 6 / 9;
  grid-row: 4;
  margin-top: 20px;
  height: 6px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

.about-approach__extra {
  grid-column: 6 / 9;
  grid-row: 5;
  margin-top: 20px;
  color: var(--grey-50);
}

/* Фікс: точні переноси "We learn your domain..." по breakpoint (звірено
   зі скріншотами) — Desktop видимий за замовчуванням (вимикається в
   TL/TP/Mobile медіа-запитах нижче), Tablet Landscape (той самий
   розподіл, що Desktop) і Tablet Portrait (інший розподіл, 4 рядки
   замість 3) — обидва вимкнені за замовчуванням, вмикаються кожен
   у своєму медіа-запиті */
.about-approach__extra-break--tablet {
  display: none;
}

.about-approach__extra-break--portrait {
  display: none;
}

/* -------------------------------------------------------------------------
   Секція показників — адаптація .offices__cities (Крок 25): 4 групи
   замість 3, кожна на своїх 2 колонках сітки (276px), без великого
   квадрата-стрілки в кінці лінії й без сабтайтла під тайтлом (замінений
   маленьким лейблом біля тайтла). Геометрія лінії/маркера — та сама
   формула, що в Offices (тайтл dm-h1 52px висотою + 16px до лінії):
   маркер top:64px (52+16+1-5), лінія margin-top:16px (52+16=68 сумарно
   від верху тайтла) — тут досягається чистим grid-flow (рядок 1 = тайтли,
   висота авто 52px, рядок 2 = лінія з margin-top:16), а не absolute
   позиціюванням, як у Offices (там потрібно було через нерівну ширину
   міст на flex) */
.about-stats {
  align-self: stretch;
  margin-top: 124px;
}

.about-stats__item {
  position: relative;
  grid-row: 1;
}

.about-stats__item--1 {
  grid-column: 1 / 3;
}

.about-stats__item--2 {
  grid-column: 3 / 5;
}

.about-stats__item--3 {
  grid-column: 5 / 7;
}

.about-stats__item--4 {
  grid-column: 7 / 9;
}

.about-stats__head {
  display: flex;
  align-items: flex-start;
}

.about-stats__title {
  color: var(--grey-100);
}

/* 6px правіше правого краю тайтла (margin-left у flex-рядку), top 2px
   відносно верху тайтла (margin-top у flex-рядку з align-items:flex-start) */
.about-stats__label {
  margin-left: 6px;
  margin-top: 2px;
  color: var(--grey-60);
}

/* Тайтл — .dm-h0 (line-height 64px, рядок 1 має висоту 64 у grid-потоці).
   7px від нижнього краю тайтла до верху квадрата: top:71 (64+7) */
.about-stats__marker {
  position: absolute;
  left: 0;
  top: 71px;
  width: 5px;
  height: 5px;
  background-color: var(--grey-15);
}

/* Лінія лягає на нижній піксельний рядок квадратів: низ квадрата
   71+5=76, останній піксельний рядок квадрата — 75, тому верх лінії
   теж 75. Рядок 2 (grid) починається одразу за рядком 1 (64px),
   тож margin-top: 75-64=11px */
.about-stats__line {
  grid-column: 1 / 9;
  grid-row: 2;
  margin-top: 11px;
  height: 1px;
  background-color: var(--grey-15);
}

.about-stats__body {
  grid-row: 3;
  margin-top: 24px;
  color: var(--grey-50);
}

/* Ручні переноси, потрібні лише в планшетній сітці (444px, tablet-фікс
   структури метрик) — при десктопній ширині (276px, 2 колонки) текст і
   так вже переноситься природно на ті самі 3 рядки, але в ІНШИХ місцях,
   тому <br> тут за замовчуванням прибрані з потоку (display:none) і
   вмикаються лише в медіа-запиті 1024–1279px нижче */
.about-stats__break {
  display: none;
}

/* Mobile отримує ВЛАСНИЙ розрив для метрик "300+"/"2020"/"3" (інші
   позиції, ніж десктоп/Tablet Landscape/Tablet Portrait, які всі
   ділять .about-stats__break) — окремі <br>-теги поряд з існуючими
   (той самий "adjacent tags, не спільний клас" прийом, що Offices) */
.about-stats__break--mobile {
  display: none;
}

/* Фікс: на широкому десктопі (≥1280px) природний вордвреп більше не
   збігається зі затвердженим 3-рядковим текстом (переноси падали в
   інших місцях) — вмикаємо ті самі ручні <br>, що й у планшетній сітці */
@media (min-width: 1280px) {
  .about-stats__break {
    display: inline;
  }
}

.about-stats__body--1 {
  grid-column: 1 / 3;
}

.about-stats__body--2 {
  grid-column: 3 / 5;
}

.about-stats__body--3 {
  grid-column: 5 / 7;
}

.about-stats__body--4 {
  grid-column: 7 / 9;
}

/* -------------------------------------------------------------------------
   "How We Work" — заголовний блок, той самий патерн, що Our Approach
   вище (спільні правила label/index/title/desc). Флекс-дитина всередині
   .about-hero (align-self:stretch), margin-top:286px рахується від
   попереднього флекс-сиблінга (.about-stats) напряму */
.how-we-work {
  align-self: stretch;
  margin-top: 286px;
}

.how-we-work__grid {
  position: relative;
}

/* 5px нижче рядка лейблів (rh-12-bold-track, line-height:20px):
   top: 20+5=25px від верху сітки */
.how-we-work__hline {
  position: absolute;
  left: 0;
  right: 0;
  top: 25px;
  height: 1px;
  background-color: var(--grey-15);
}

/* Кінець 5-ї колонки = 720px від лівого краю сітки (5×128 + 4×20).
   height:1254px — витягнутий рендером рівно до верхнього краю першого
   фрейму сітки логотипів Trusted By (.trusted-by__logo-cell), без
   розриву (Фікс: раніше 1294px, перетягувало на 40px нижче цільової
   позиції — перерахований заново headless-браузером від top:25px до
   реального firstCellTop, підтверджено на 1280/1440/1920/2560px) */
.how-we-work__vline {
  position: absolute;
  left: 720px;
  top: 25px;
  width: 1px;
  height: 1254px;
  background-color: var(--grey-15);
}

/* Сфера-ілюстрація: Фікс — top більше НЕ фіксований відступ від
   заголовка. Тепер вертикальний ЦЕНТР ілюстрації вирівнюється РІВНО по
   y-координаті строука під OPERATIONS (.how-we-work__divider--bottom,
   той самий строук, що "17px від тексту Operations"; попередній +3px
   зсув вниз скасовано) — рахується динамічно в js/how-we-work.js (той
   самий "виміряти реальний DOM" принцип, що сам строук під Operations),
   на кожному resize. top:213px нижче — стартове (fallback) значення до
   першого запуску JS, похідне від fallback-позиції строука (642px): 642
   (top строука) + 0.5 (пів висоти строука, 1px) - 429.5 (пів висоти
   сфери, 859px) = 213. Правий край — 110px ЛІВІШЕ вертикального строука
   (720 семантично):
   right-edge = 720-110 = 610, left = 610-934 = -324px. Виходить за межі
   сітки ЗЛІВА (від'ємна позиція) — так задумано, як і ілюстрація
   services.svg на головній. Розмір фіксований 934×859, не
   масштабується. z-index:1 — вище за широкий нижній строук
   (.how-we-work__divider--bottom, z-index:0), нижче за список практик
   (z-index:2), не перекриває текст */
.how-we-work__sphere {
  position: absolute;
  left: -324px;
  top: 213px;
  width: 934px;
  height: 859px;
  z-index: 1;
}

/* Мобільна ілюстрація-сфера — окремий елемент/асет (mobile-sphere.webp,
   375×286, не масштабоване перевикористання десктопного .how-we-work__sphere:
   інший crop/композиція під вузький екран, не просто зменшена копія).
   Прихована за замовчуванням, показана лише в Mobile-медіа-запиті нижче */
.how-we-work__sphere-mobile {
  display: none;
}

/* Список практик — на всю ширину сітки (1164px), 54px від низу опису
   (Фікс: боді → перший айтем сервісу, десктоп-специфічне значення —
   Tablet Landscape нижче явно фіксує стару 36px, щоб не успадкувати цю
   зміну). z-index:2 — лишається поверх сфери-ілюстрації */
.how-we-work__list {
  position: relative;
  z-index: 2;
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 54px;
}

/* margin-left:740px — колонка 6 (5×128 + 5×20), текст назви починається
   тут; правий край рядка лишається на 1164 (кінець сітки), тому
   justify-content:space-between і далі вирівнює опис по правому краю */
.how-we-work__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-left: 740px;
}

.how-we-work__row-name {
  color: var(--grey-50);
  transition: color 200ms ease;
}

.how-we-work__row-desc {
  color: var(--grey-50);
}

.how-we-work__row:hover .how-we-work__row-name {
  color: var(--grey-100);
}

/* 17px від тексту до розділювача, 18px від розділювача до наступного
   тексту (асиметрично) — рядки самі без відступів */
.how-we-work__divider {
  display: block;
  margin-top: 17px;
  margin-bottom: 18px;
  margin-left: 720px;
  width: 444px;
  height: 1px;
  background-color: var(--grey-15);
}

/* Строук під OPERATIONS — на відміну від розділювачів між рядками
   (444px, від кінця 5-ї колонки), іде на всю ширину сітки (0 → 1164px)
   і винесений з нормального потоку .how-we-work__list в абсолютне
   позиціювання: інакше, лишаючись у стек-контексті списку (z-index:2),
   він не міг би опинитись НИЖЧЕ сфери (z-index:1) — стекінг-контекст
   завжди малюється як єдине ціле відносно зовнішніх сиблінгів.
   top:642px — стартове (fallback) значення до першого запуску JS;
   реальна позиція тепер рахується динамічно в js/how-we-work.js
   (getBoundingClientRect останнього .how-we-work__row + 17px, на
   resize) замість хардкод-піксельного значення, що розсинхронізувалось
   зі стилями після наступних правок тексту/відступів */
.how-we-work__divider--bottom {
  position: absolute;
  margin: 0;
  left: 0;
  top: 642px;
  width: 1164px;
  z-index: 0;
}

/* Колонка 6 до кінця сітки (424px). Фікс: 46px має бути від строука
   (.how-we-work__divider--bottom), не від низу списку практик — але
   строук винесений з потоку (position:absolute) і не додає власної
   висоти в flow, тому margin-top тут рахується від низу
   .how-we-work__list (=низ рядка OPERATIONS) і має включати весь шлях
   до строука: 17px (рядок→строук) + 1px (висота строука) + 46px
   (строук→підтекст) = 64px */
.how-we-work__extra {
  grid-column: 6 / 9;
  grid-row: 5;
  margin-top: 64px;
  color: var(--grey-50);
}

/* Ручні переноси боді-тексту How We Work (над айтемами сервісів,
   .how-we-work__desc — "Hue & Machine is a product design company...") —
   10-рядковий розрив, спільний для десктопу/Mobile/Tablet Landscape
   (--desktop, за замовчуванням увімкнений, окремого правила не
   потрібно), і власний 11-рядковий для Tablet Portrait (--tablet,
   вимкнений тут, вмикається лише в медіа-запиті 768–1023px нижче) */
.how-we-work__desc-break--tablet {
  display: none;
}

/* Ручні переноси секондарі-боді-тексту How We Work (під айтемами
   сервісів, .how-we-work__extra — "Every project is led by a
   designer..."). Розподіл рядків відрізняється на КОЖНОМУ з 4
   breakpoint'ів (7/8/6/9 рядків), тому 4 незалежні класи: --desktop
   увімкнений за замовчуванням і вимикається явно в кожному з інших
   трьох медіа-запитів; --mobile/--tl/--portrait вимкнені за
   замовчуванням і вмикаються кожен лише у своєму медіа-запиті.
   Деякі <br> діляться між двома breakpoint'ами (напр. "--desktop
   --tl" на спільній точці розриву) — display:inline на --desktop
   тут прописаний явно (а не залишений на дефолтну поведінку <br>),
   інакше на такому спільному елементі display:none від другого
   класу переміг би каскад незалежно від viewport */
.how-we-work__extra-break--mobile,
.how-we-work__extra-break--tl,
.how-we-work__extra-break--portrait {
  display: none;
}

.how-we-work__extra-break--desktop {
  display: inline;
}

/* Trusted By (About) — секція перевикористана без змін з index.html.
   Фікс: раніше 227px рахувались від НИЖНЬОГО КРАЮ вертикального
   строука (позиційований елемент, не впливає на flow-висоту
   .about-hero) замість реального боді-тексту — тепер 310px напряму від
   низу .how-we-work__extra (секондарі боді-текст), який на десктопі є
   останнім flow-елементом .how-we-work__grid/.about-hero (
   .how-we-work__extra-line — display:none тут), тому margin-top на
   сусідньому селекторі рахується прямо від нього без додаткової
   математики */
.about-hero + .trusted-by {
  margin-top: 310px;
}

/* -------------------------------------------------------------------------
   "Leadership" — заголовний блок, той самий патерн, що Our Approach/
   How We Work (спільні правила label/index/title/desc вище). Звичайний
   sibling-section margin-top (206px від низу .trusted-by, секції йдуть
   впритул) — на відміну від блоків усередині .about-hero, тут немає
   проблеми overflow/фіксованої висоти, тому просто margin-top */
.leadership {
  margin-top: 206px;
}

/* -------------------------------------------------------------------------
   Карусель членів команди. .leadership__viewport — позиційний якір
   (grid-item, без власних розмірів/overflow — просто обгортка для
   .leadership__clip + .leadership__gradient нижче). .leadership__clip —
   фактичне вікно каруселі, фіксоване 1542×590, overflow:hidden (усе за
   межами не показується). Track — горизонтальний flex-ряд усіх айтемів
   (888×590 кожен: фото 424 + інфо-блок 464), впритул один до одного, без
   проміжків; js/leadership-carousel.js зсуває його через
   transform:translateX на -888px за клік */
.leadership__viewport {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 96px;
}

.leadership__clip {
  width: 1542px;
  height: 590px;
  overflow: hidden;
}

.leadership__track {
  display: flex;
  transition: transform 500ms ease-in-out;
}

/* Фікс: leadership-mask.webp (растрове зображення-накладка) замінено на
   простий CSS linear-gradient — та сама функція (затемнення справа,
   де останній видимий айтем "виїжджає" за межі в'юпорту), без окремого
   файлу.
   Фікс-2: ширина тепер динамічна замість фіксованих 1542px — лівий край
   лишається на початку сітки (left:0 відносно .leadership__viewport,
   чий власний лівий край збігається з лівим краєм колонки 1, тобто з
   тим самим "початком сітки", що й в інших секціях), а правий завжди
   дотягується до РЕАЛЬНОГО правого краю вʼюпорта: 582px = половина
   ширини сітки (1164px/2). Сітка центрується в'юпортом (main{max-width:
   1920px;margin:auto} + .leadership__grid{max-width:1164px;margin:auto}
   — центрування вкладене, але telescope'иться в одну формулу
   50vw−582px для лівого краю сітки за БУДЬ-якої ширини вʼюпорта, як
   вужчої, так і ширшої за 1920px). .leadership__viewport НЕ має
   overflow:hidden (це тепер лише на .leadership__clip), тому градієнт
   вільно "простягається" за межі старих 1542px без обрізання.
   .leadership__nav — окремий сиблінг поза .leadership__clip
   (overflow:hidden), тому фізично не може опинитись під градієнтом
   незалежно від z-index */
.leadership__gradient {
  position: absolute;
  top: 0;
  left: 0;
  right: calc(582px - 50vw);
  height: 590px;
  z-index: 1;
  pointer-events: none;
  opacity: 1;
  transition: opacity 200ms ease;
  /* Фікс: 2-стопний градієнт показував видиму ступінчастість на 4K
     (щільні пікселі роблять 8-bit квантування альфа-каналу помітним,
     особливо в темній частині кривої, де око найчутливіше). Замінено
     на 9 стопів з неоднорідним (eased, степінь ~1.7) розподілом
     альфи — більше проміжних значень у темному/низько-альфовому
     кінці кривої замість рівномірного лінійного кроку — щоб перехід
     читався плавно навіть при 2x+ device pixel ratio */
  background: linear-gradient(
    to right,
    rgba(17, 17, 17, 0) 57%,
    rgba(17, 17, 17, 0.03) 62%,
    rgba(17, 17, 17, 0.09) 67%,
    rgba(17, 17, 17, 0.19) 72%,
    rgba(17, 17, 17, 0.31) 77%,
    rgba(17, 17, 17, 0.45) 82%,
    rgba(17, 17, 17, 0.61) 87%,
    rgba(17, 17, 17, 0.8) 92%,
    rgba(17, 17, 17, 1) 97%
  );
}

/* Крок 128: коли карусель доскрольована до останнього айтема (кнопка
   "вправо" disabled, js/leadership-carousel.js) — градієнт-затемнення
   ховається, щоб не притлумлювати останню картку й патерн, що
   виїжджає у звільнене місце. .leadership__nav-btn--next — сиблінг
   .leadership__viewport (обидва всередині .leadership__grid), тому
   :has() на найближчому спільному предку, а не на самому .viewport */
.leadership__grid:has(.leadership__nav-btn--next:disabled) .leadership__gradient {
  opacity: 0;
}

/* flex-shrink:0 — track не стискає айтеми під ширину в'юпорту
   (1542px), кожен лишається рівно 888px, скільки б їх не було */
.leadership__item {
  position: relative;
  flex-shrink: 0;
  display: flex;
  width: 888px;
  height: 590px;
}

/* Крок 128-фікс — той самий патерн косих ліній, що .selected-work__pattern/
   .about-approach__pattern/.footer__pattern (той самий 276px, збіг не
   випадковий — стандартна ширина "залишку" по всьому сайту). Звичайний
   flex-сиблінг ПІСЛЯ останнього .leadership__item у track — 0px відступу
   від правого краю останньої картки виходить сам собою (це наступний
   елемент у ряду), стає видимим лише коли трек доскрольований до кінця.
   Ширина рахується від межі СІТКИ (1164px від початку сітки = від
   лівого краю .leadership__clip, який сам починається на grid-start),
   А НЕ від краю вікна каруселі (1542px) чи екрана: 276 = 1164 − 888
   (ширина одної картки) — фіксована локальна відстань у координатах
   track, не залежить від ширини вʼюпорта */
.leadership__end-pattern {
  flex-shrink: 0;
  box-sizing: border-box;
  width: 276px;
  height: 590px;
  border-top: 1px solid var(--grey-15);
  border-bottom: 1px solid var(--grey-15);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* Фото — реальний асет 424×590, фіксований. Крок 128: рамка винесена в
   окремий .leadership__photo-stroke нижче (box-shadow inset тут раніше
   малював усі 4 сторони — тепер потрібні лише 3, без правої) */
.leadership__photo {
  display: block;
  width: 424px;
  height: 590px;
  object-fit: cover;
}

/* Крок 128: плейсхолдер для айтемів без реального фото ще (Andrew/Slava/
   The wider team) — той самий розмір/клас .leadership__photo, просто div
   замість img із суцільним заповненням замість зображення */
.leadership__photo--placeholder {
  background-color: var(--grey-10);
}

/* Крок 128 — рамка ПОВЕРХ фото: 3 сторони (без правої, де фото впритул
   до .leadership__info). <img>/плейсхолдер-div не можуть мати ::after
   (не рендериться на replaced-елементах), тому окремий сиблінг-span,
   абсолютно позиційований точно на фото; малюється останнім у DOM —
   природно поверх зображення, z-index не потрібен */
.leadership__photo-stroke {
  position: absolute;
  top: 0;
  left: 0;
  width: 424px;
  height: 590px;
  box-sizing: border-box;
  border-left: 1px solid var(--grey-15);
  border-top: 1px solid var(--grey-15);
  border-bottom: 1px solid var(--grey-15);
  pointer-events: none;
}

/* box-sizing:border-box — border включений у 464×590 */
.leadership__info {
  position: relative;
  box-sizing: border-box;
  width: 464px;
  height: 590px;
  border: 1px solid var(--grey-15);
}

/* Прив'язка знизу, а не зверху: bottom:7px — 7px від низу інфо-блоку
   до низу тегів. Уся група (ім'я → опис → строук → теги) — один
   flex-column, тому браузер сам рахує фактичну висоту опису (2-4
   рядки залежно від рендеру шрифту) і виштовхує ім'я вище — без
   фіксованої позиції зверху, яка раніше могла не влазити в 590px */
.leadership__content {
  position: absolute;
  left: 28px;
  bottom: 7px;
  display: flex;
  flex-direction: column;
}

.leadership__name {
  width: 258px;
  color: var(--grey-100);
}

.leadership__bio {
  margin-top: 16px;
  width: 312px;
  color: var(--grey-60);
}

/* Фікс: боді-текст (посада) — DM Sans/16 Light (.dm-16-light, tokens.css)
   замість заданого в розмітці .dm-14-light, на Desktop ≥1280px, Tablet
   Landscape (1024–1279px) І Tablet Portrait (768–1023px, той самий
   стиль, що на десктопі/Tablet Landscape) — Mobile нижче (<768px) не
   перевизначає шрифт цього елемента, тому лишається на успадкованому з
   розмітки .dm-14-light без змін */
@media (min-width: 768px) {
  .leadership__bio {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }
}

/* "The wider team" — рядок "Every specialist, held to the same standard —"
   рендериться на ~328px (з урахуванням letter-spacing:0.02em), ширше за
   стандартні 312px column (єдина картка, де це трапляється) — власна
   ширина під ручний перенос на 2 рядки, без зміни базового 312px для
   решти карток */
.leadership__bio--wide {
  width: 330px;
}

/* Фікс: на 16px Light (.dm-16-light вище) рядок "Every specialist, held
   to the same standard —" рендериться на ~332px — ширше за успадковані
   330px (виміряно реальним рендером), тому 2-рядковий ручний перенос
   (--desktop-break нижче) розповзається на 3 рядки. 336px — 330 + запас
   на суб-піксельне округлення. Desktop, Tablet Landscape І Tablet
   Portrait (той самий 16px шрифт, що вище) — Mobile нижче лишається на
   330px (там 14px шрифт, там усе й так вміщується). .leadership__info
   на Tablet Portrait — 376px (20px content-offset), на Tablet Landscape
   — 400px (28px content-offset), тож 336px впритул без переповнення
   картки на обох */
@media (min-width: 768px) {
  .leadership__bio--wide {
    width: 336px;
  }
}

/* Фікс: аналогічно — картка Anastasia Shengel, ручний перенос на 4 рядки
   (п.1 ТЗ). "and on the standard the team is known for." рендериться на
   ~313px на 16px Light — ширше за успадковані 312px базового
   .leadership__bio (виміряно реальним рендером). 316px — запас на
   суб-піксельне округлення. Desktop, Tablet Landscape І Tablet Portrait
   (той самий 16px шрифт) — Mobile не займається (там 14px шрифт,
   природний вордвреп без цього класу) */
@media (min-width: 768px) {
  .leadership__bio--anastasia {
    width: 316px;
  }
}

/* Mobile отримує власний ручний перенос боді-текстів карток (інші
   позиції, ніж природний вордвреп/наявні unscoped <br> для інших
   breakpoint) — окремі <br>-теги поряд з існуючими (той самий
   "adjacent tags, не спільний клас" прийом, що Offices/About Approach).
   --desktop не потребує display-правила (видимий за замовчуванням,
   як і решта --desktop-класів на сайті) */
.leadership__bio-break--mobile {
  display: none;
}

/* Фікс: Anastasia Shengel — ручний перенос на 4 рядки (п.1 ТЗ), увімкнений
   на Desktop ≥1280px, Tablet Landscape (1024–1279px) І Tablet Portrait
   (768–1023px, той самий перенос, що на десктопі/Tablet Landscape) —
   Mobile (<768px) лишається на природному вордвреп при 14px шрифті, той
   самий підхід, що --mobile вище */
.leadership__bio-break--lg {
  display: none;
}

@media (min-width: 768px) {
  .leadership__bio-break--lg {
    display: inline;
  }
}

/* margin-left:-28px — вирівнює строук на всю ширину інфо-блоку (464px),
   виходячи за межі власного відступу .leadership__content (28px) */
.leadership__hline {
  display: block;
  margin-top: 32px;
  margin-left: -28px;
  width: 464px;
  height: 1px;
  background-color: var(--grey-15);
}

/* "The wider team" — другий (нижній) рядок тегів: 7px від низу тексту
   верхнього рядка тегів до цього строука (7 + 1px строук + 6px
   .leadership__tags margin-top до тексту = 14px текст-до-тексту, як у
   ТЗ), замість стандартних 32px, які рахуються від .leadership__bio */
.leadership__hline--tight {
  margin-top: 7px;
}

/* 6px від строука до верху тегів — тепер звичайний margin-top у
   тому самому flex-column, а не окреме абсолютне позиціювання */
.leadership__tags {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 28px;
}

.leadership__tag {
  color: var(--grey-50);
  white-space: nowrap;
}

/* align-self:stretch спирається на власну (маленьку, ~висота рядка
   тексту) висоту .leadership__tags — замало для "від строука до
   низу інфо-блоку" (той самий патерн, що work-card__tags). Замість
   зміни висоти самого рядка (це зсунуло б і текст тегів) розтягуємо
   САМ строук через від'ємні margin: -6px вгору (місток через
   відступ до горизонтального строука) і -7px вниз (місток через
   відступ .leadership__content від низу інфо-блоку) */
.leadership__tag-divider {
  align-self: stretch;
  margin-top: -6px;
  margin-bottom: -7px;
  width: 1px;
  flex-shrink: 0;
  background-color: var(--grey-15);
}

/* Пагінація — 24px нижче рядка айтемів, вирівняна по правому краю
   сітки (1164px) */
.leadership__nav {
  grid-column: 1 / 9;
  grid-row: 5;
  margin-top: 24px;
  display: flex;
  justify-content: flex-end;
  gap: 20px;
}

/* Колір/opacity іконки — не через CSS: JS підміняє сам файл src
   (arrow-*-active.svg / arrow-*-disabled.svg, кожен уже несе власний
   колір/opacity). Фон кнопки завжди var(--grey-10), окрім hover —
   і тільки на активній кнопці */
.leadership__nav-btn {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--grey-10);
  border: none;
  cursor: pointer;
  transition: background-color 150ms ease;
}

.leadership__nav-btn:not(:disabled):hover {
  background-color: var(--grey-15);
}

.leadership__nav-btn:disabled {
  cursor: default;
  pointer-events: none;
}

/* -------------------------------------------------------------------------
   "Offices" — заголовний блок, той самий патерн, що Our Approach/
   How We Work/Leadership (спільні правила label/index/title/desc вище).
   Звичайний sibling-section margin-top (204px від низу .leadership,
   секції йдуть впритул) — .leadership__viewport не абсолютно
   позиційований, тому висота секції вже коректно включає кнопки
   перемикання без overflow-трюків */
.about-offices {
  margin-top: 204px;
}

/* -------------------------------------------------------------------------
   Ряд міст — 114px від низу опису, з відступом 20px від лівого краю
   сітки для САМИХ тайтлів (маркери/лінія лишаються на x=0, без
   відступу — той самий трюк, що .offices__marker на головній).
   min-height — маркер/лінія абсолютні, не тягнуть висоту власним
   потоком (див. .offices__cities на головній) */
/* min-height:322px — виміряно рендером (Крок 67): найвищий контент
   серед трьох міст — Kyiv (боді-текст переносить у 6 рядків замість
   5 заданих через <br>, бо третій рядок не влазить у 293px, див.
   окреме зауваження). Маркер/лінія/city-info абсолютні, самі по
   собі не тягнуть висоту .about-offices__cities */
.about-offices__cities {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 114px;
  min-height: 356px;
}

.about-offices__titles {
  display: flex;
  margin-left: 20px;
}

.about-offices__city {
  position: relative;
}

/* ФІКС — точні відступи (проміжок правий край попереднього тайтла →
   лівий край наступного): 192px London→New York, 157px New York→Kyiv.
   НЕ ті самі 173/197, що в .offices__city--ny/--kyiv на головній
   сторінці, і не 167/133 з попередньої (неправильної) ітерації */
.about-offices__city--ny {
  margin-left: 192px;
}

.about-offices__city--kyiv {
  margin-left: 157px;
}

.about-offices__city-title {
  color: var(--grey-100);
  white-space: nowrap;
}

/* 6px правіше правого краю тайтла, 2px ВИЩЕ його верхньої грані
   (на відміну від .about-stats__label, де було +2px нижче) */
.about-offices__city-label {
  position: absolute;
  left: calc(100% + 6px);
  top: -2px;
  color: var(--grey-50);
}

/* left:-20px — компенсує margin-left:20px на .about-offices__titles,
   маркер повертається на x=0 відносно .about-offices__cities (на
   20px лівіше від початку свого тайтла). top:66px = 52 (висота
   рядка тайтла) + 14 (задане в Кроці 66; в .offices__marker на
   головній цей самий відступ дорівнював 12px — тут свідомо інше
   значення) */
.about-offices__marker {
  position: absolute;
  left: -20px;
  top: 66px;
  width: 5px;
  height: 5px;
  background-color: var(--grey-15);
}

/* Вертикальна лінія від квадратика вниз — та сама x-позиція (left:-20px),
   top:70px збігається з горизонтальною .about-offices__line (квадратик
   налазить на неї знизу на 1px), 287px вниз */
.about-offices__vline {
  position: absolute;
  left: -20px;
  top: 70px;
  width: 1px;
  height: 286px;
  background-color: var(--grey-15);
}

/* Лінія — на всю ширину .about-offices__cities (1164px, без відступу
   20px), нижній піксельний рядок маркера збігається з лінією:
   66+5-1=70 */
.about-offices__line {
  position: absolute;
  left: 0;
  right: 0;
  top: 70px;
  height: 1px;
  background-color: var(--grey-15);
}

/* 116px від низу тайтла: 52 (висота рядка тайтла) + 116 = 168.
   left:0 — вирівняний по лівому краю свого тайтла (той самий x,
   що .about-offices__city-title, оскільки .city не має власного
   відступу) */
.about-offices__city-info {
  position: absolute;
  left: 0;
  top: 168px;
}

.about-offices__subtitle {
  width: 258px;
  color: var(--grey-60);
  text-transform: uppercase;
}

.about-offices__body {
  margin-top: 10px;
  width: 293px;
  color: var(--grey-50);
}

/* Планшетні ручні переноси боді-текстів міст (Крок 148-фікс) —
   за замовчуванням вимкнені, той самий tablet-break прийом, що
   .about-stats__break/.how-we-work__desc-break--tablet вище */
.about-offices__body-break--tablet {
  display: none;
}

/* Tablet Portrait отримує ВЛАСНИЙ розрив (5 рядків на айтем міста,
   інший, ніж 6-рядковий Tablet Landscape) — окремі виділені <br>-теги
   поряд з існуючими --desktop/--tablet (а не спільні класи на одному
   тезі), щоб уникнути конфлікту каскаду між "--desktop за
   замовчуванням видимий" (без базового правила) і новим
   "--portrait за замовчуванням прихований" на одному елементі */
.about-offices__body-break--portrait {
  display: none;
}

/* Mobile отримує ВЛАСНИЙ розрив боді-текстів айтемів міст (4/4/5 рядків
   London/New York/Kyiv) — окремий клас, вимкнений за замовчуванням,
   вмикається лише в Mobile медіа-запиті (той самий tablet-break прийом) */
.about-offices__body-break--mobile {
  display: none;
}

/* Той самий прийом для секційного боді-тексту "Three offices..." —
   на відміну від боді-тексту айтемів міст, тут раніше НЕ було жодного
   break-класу (голі <br>, завжди видимі); винесено в --desktop (видимий
   за замовчуванням, як і .about-offices__body-break--desktop) +
   новий --portrait */
.about-offices__desc-break--portrait {
  display: none;
}

.about-approach__desc-break--portrait {
  display: none;
}

.about-approach__desc-break--mobile {
  display: none;
}

.leadership__desc-break--portrait {
  display: none;
}

/* 24px нижче найнижчого з трьох боді-текстів. Після фіксу переносу
   Kyiv (прибрано зайвий <br>, тепер теж 5 рядків, як і London/
   New York) усі три однакові — 302px, тому 302+24=326px. Не на
   всю сітку (1164) — 1079px від початку */
.about-offices__body-line {
  position: absolute;
  left: 0;
  top: 326px;
  width: 1079px;
  height: 1px;
  background-color: var(--grey-15);
}

/* 4px нижче горизонтального строука — рахуючи від його НИЖНЬОГО
   краю (326+1 висота лінії +4=331), а не від верхнього (330 —
   так виходило лише 3px видимого проміжку, фікс) */
.about-offices__gmt {
  position: absolute;
  left: 0;
  top: 331px;
  color: var(--grey-50);
}

/* 20px правіше правого краю тегу (left:calc(100%+20px) відносно
   .about-offices__gmt), від строука (326) — абсолютна геометрія
   без змін (Крок 70), тому top:-5px відносно тегу (331-5=326,
   компенсує зсув тегу на +1px), висота 28px */
.about-offices__gmt-divider {
  position: absolute;
  left: calc(100% + 20px);
  top: -5px;
  width: 1px;
  height: 29px;
  background-color: var(--grey-15);
}

/* Строук ПЕРЕД GMT-міткою (Mobile, п.2 ТЗ) — обрамлює мітку строуками
   з обох боків. Прихований за замовчуванням (потрібен лише на Mobile,
   де мітка отримує повноцінний "фрейм"); вмикається нижче в
   @media(max-width:767px) */
.about-offices__gmt-divider--before {
  display: none;
}

/* Строук на правому краю СІТКИ (336px, Mobile), а не впритул до тексту
   мітки (те, що вже робить .about-offices__gmt-divider) — окремий
   елемент, оскільки :before/:after на .about-offices__gmt вже зайняті
   верхнім/нижнім горизонтальними строуками фрейму. Прихований за
   замовчуванням, вмикається лише в @media(max-width:767px) */
.about-offices__gmt-edge-line {
  display: none;
}

/* Строук під тегами GMT — одразу після закінчення вертикальних
   строуків (326+28=354), на всю ширину сітки (1164px, не 1079,
   як строук під описами) */
/* top:355px (не 354) — 4px від низу рядка тегу GMT (331+20=351,
   351+4=355), раніше виходило 3px */
.about-offices__gmt-line {
  position: absolute;
  left: 0;
  top: 355px;
  width: 1164px;
  height: 1px;
  background-color: var(--grey-15);
}

/* Додатковий строук — 82px правіше правого краю сабтайтла Kyiv
   (258px ширина + 82 = 340px відносно .about-offices__city--kyiv).
   Той самий старт (70px, від квадратика) і висота (287px), що й
   3 строуки з Кроку 70 */
.about-offices__extra-vline {
  position: absolute;
  left: 340px;
  top: 70px;
  width: 1px;
  height: 286px;
  background-color: var(--grey-15);
}

/* Патерн косих ліній — той самий inline SVG 8×8, що в .about-approach__pattern/
   .selected-work__pattern/.footer__pattern. Одразу праворуч від
   .about-offices__extra-vline (341 = 340+1), зверху — ФІКС: від
   верхнього строука секції (.about-offices__line, 70px, Крок 66),
   а не від строука під описами (326px, Крок 68) */
.about-offices__pattern {
  position: absolute;
  left: 341px;
  top: 70px;
  width: 84px;
  height: 286px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* ==========================================================================
   CTA — фінальний заклик

   Крок 124-фікс-3: margin-top 0 — ілюстрація (whale-bg) починається
   ОДРАЗУ від останнього айтема .selected-work, без проміжку. Тайтл
   зсунутий на 180px ВІД ТІЄЇ Ж точки (верху секції) через padding-top
   на самій секції — це двигає лише контент (h2 + кнопка), а не фон:
   background-position "top" рахується від верху padding-box, який
   фізично збігається з верхом border-box (border: 0), тому padding-top
   ілюстрацію не зсуває. box-sizing: border-box (глобальний reset вище)
   тримає height:1020px включно з цим padding-top — контейнер і далі
   точно дорівнює висоті ілюстрації (Крок 124-фікс-2), просто тепер
   1020px розподілені як 180px padding + 840px вміст, а не 1020px суто
   вміст. background-size лишається фіксованим у пікселях (не
   масштабується під контейнер, як у hero) — на вужчих за 1920px
   екранах ілюстрація обрізається лише з боків.
   ========================================================================== */

.cta {
  position: relative;
  margin-top: 0;
  padding-top: 180px;
  height: 1020px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Фікс: явний background-color (той самий колір, що й у краю самого
     whale-bg.webp — виміряно #111111, точний збіг з var(--color-background))
     — до того, як картинка задекодується, простір під нею вже правильного
     кольору, тому "спалаху" невідповідного кольору не видно */
  background-color: var(--color-background);
  background-position: center top;
  background-repeat: no-repeat;
  background-size: 1920px 1020px;
  background-image: url("../assets/images/whale-bg.webp");
  background-image: image-set(
    url("../assets/images/whale-bg.webp") 1x,
    url("../assets/images/whale-bg@2x.webp") 2x
  );
}

.cta__title {
  text-align: center;
}

.cta__line {
  display: block;
}

.cta__line--1 {
  color: var(--grey-100);
}

.cta__line--2 {
  color: var(--grey-50);
}

/* Фікс: ручний перенос "No pitch." / "Just a conversation." на 3-й рядок
   тайтла — лише Mobile (≤767px, index.html, .selected-work + .cta нижче);
   на десктопі/Tablet лишається 2 рядки (--1/--2), без змін */
.cta__line-break--mobile {
  display: none;
}

/* Перевикористовує структуру/кольори/hover кнопки з hero (.hero__btn,
   .hero__btn--primary) — тут міняється лише ширина. margin-top: 44px —
   спільне правило для .cta__btn у CTA (кит) і CTA-2 (.cta--second), тому
   міняється відразу на всіх сторінках */
.cta__btn {
  margin-top: 44px;
  width: 239px;
}

/* -------------------------------------------------------------------------
   CTA-2 — той самий патерн, що .cta, лише інші фон/розміри/відступи.
   padding-top зсуває контент вниз усередині секції (замість "від верху
   секції" як у першої CTA): 472px = 652px від низу .offices − 180px
   margin-top секції — перевірка з ТЗ сходиться
   ------------------------------------------------------------------------- */
.cta--second {
  margin-top: 180px;
  height: 832px;
  padding-top: 472px;
  /* Фікс: контейнер CTA-2 явно отримує var(--color-background) (#111111).
     Сирий WebP-файл при декодуванні через PIL показує лівий/правий край
     ~#101010, АЛЕ це виявився артефакт декодера — прямий рендер того ж
     файлу в Chrome дає шумні (WebP-компресія) значення в діапазоні
     16–18 з середнім ~16.5–16.9, тобто по факту нема жодного суцільного
     "іншого" кольору для хардкоду, лише dither-шум навколо цільового
     тону. var(--color-background) — правильний, навмисний цільовий
     колір (той самий, що й .cta нижче/body) */
  background-color: var(--color-background);
  background-size: 1920px 832px;
  background-image: url("../assets/images/cta2-bg.webp");
  background-image: image-set(
    url("../assets/images/cta2-bg.webp") 1x,
    url("../assets/images/cta2-bg@2x.webp") 2x
  );
}

/* Фікс (Desktop ≥1280px): точні відступи index.html — 502px від верху
   ілюстрації CTA-2 до тайтла (padding-top; 472px вище — про.about.html,
   яка ділить цю саму базову .cta--second без власного десктопного
   оверрайду, лишається без змін) і 180px від низу боді-тексту "London"
   (виміряно через getBoundingClientRect: боді-текст London/New York/
   Kyiv на десктопі в одному рядку, тому їхній низ ідентичний — низ
   секції .offices теж збігається, окремої компенсації "слеку" не
   потрібно) до верху ілюстрації CTA-2 (margin-top; 184px виміряно
   при 180px margin-top → 176px компенсує 4px різниці) */
.offices + .cta--second {
  margin-top: 176px;
  padding-top: 502px;
}

/* Фікс (Desktop/Tablet Landscape/Tablet Portrait): 64px від низу
   ілюстрації CTA-2 до лого футера — скоуп через :has(), бо <footer>
   не є прямим сусіднім елементом .cta--second (закриває </main> між
   ними), тому звичайний суміжний селектор тут не спрацював би.
   Матчиться лише на index.html (про.about/work/services/contact.html —
   інші класи секції перед CTA-2, без змін). Mobile — окреме
   перевизначення (225px) нижче */
main:has(.offices + .cta--second) + .footer {
  margin-top: 64px;
}

/* Текст кнопки CTA-2 (Home) — "Begin a project" замінює "BOOK A
   CONSULTATION" лише на Mobile (≤767px, Крок 183), тому окрема пара
   span'ів замість зміни єдиного текстового вузла — той самий прийом,
   що .services__title--mobile/--desktop. Мобільний варіант прихований
   за замовчуванням */
.cta__btn-label--mobile {
  display: none;
}

/* Work (work.html, Крок 47): та сама .cta--second, лише інший відступ
   зверху (140px від низу секції з роботами, а не 180px від .offices) —
   звужено до сусідства з .work-hero, тому index.html не зачіпає */
.work-hero + .cta--second {
  margin-top: 140px;
}

/* ==========================================================================
   INDUSTRIES — заголовний блок

   Структура ідентична заголовним блокам Services і Selected Work —
   спільні CSS-правила винесені разом із .services__label/__index/
   __title/__desc вище.
   ========================================================================== */

/* Крок 124-фікс-3: 624px рахується від нижнього краю .cta__btn (кнопки
   всередині CTA-блоку з китом), а НЕ від низу секції .cta: margin-top
   тут = 4px = 624 − (1020 − 400), де 1020 — висота .cta, 400 — відстань
   від верху .cta до низу кнопки (180px padding-top секції + 220px від
   контенту до низу кнопки). ВАЖЛИВО: міряти ЦІ 400px ТІЛЬКИ після
   .is-visible (scroll-reveal) — до нього title/btn мають
   transform: translateY(40px), що завищує виміряну відстань на 40px і
   дає неправильний margin-top */
.industries {
  margin-top: 4px;
}

/* Фікс: рядок 1 боді тексту ("...and user") природно переносився —
   виміряно headless Chrome (реальний dm-sans-light.woff2, 18px,
   letter-spacing 0.02em): текст 424.3px проти контейнера 424px
   (grid-column: 6/9, спільне правило вище) — переносило ручний <br>
   на другий рядок майже впритул. +12px запасу на субпіксельні
   відмінності рендерингу між браузерами */
.industries__desc {
  width: 436px;
}

/* -------------------------------------------------------------------------
   Глобус — той самий рядок (4), що й список (окремий grid-item, тому
   не впливає на layout списку). Вертикально: margin-top: 6px від низу
   опису (рядок 4 починається одразу після рядка 3 з описом).
   Горизонтально: grid-column: 1 (128px фіксована колонка) + margin-left,
   що зсуває на 792px від лівого краю сітки — той самий прийом, що
   й у .services__illustration. z-index нижче за список, поза кліками.

   Крок 98: globe-X — розріджені акцентні накладки (не повні ілюстрації,
   як старі SVG), тому базовий шар лягає ПІД ними й лишається на місці
   назавжди, а не бере участі в кросфейді (інакше "просвічування"
   базового шару крізь розріджений акцент оголювало б фон — саме та
   проблема, через яку цю схему раніше відкинули, коли варіанти ще
   були повними ілюстраціями). .industries__globe-stack тримає
   позиціювання/розмір (те, що раніше було на самому .industries__globe),
   шари всередині — position: absolute; inset: 0, акценти перемикаються
   атрибутом data-active-globe на .industries (js/industries-globe.js) */
.industries__globe-stack {
  position: relative;
  z-index: 0;
  grid-column: 1;
  grid-row: 4;
  margin-top: 6px;
  margin-left: 792px;
  width: 786px;
  height: 786px;
  pointer-events: none;
}

/* Базовий шар — ЗАВЖДИ видимий, opacity: 1 постійно, ніколи не змінюється
   й не бере участі в жодному fade-переході */
.industries__globe--base {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 786px;
  height: 786px;
}

/* Акцентні шари — лежать поверх базового (z-index вищий), приховані за
   замовчуванням, проявляються при hover відповідного рядка. Без
   transform/scale — на тонких лініях масштабування виглядає як
   розбухання (перевірено раніше) */
.industries__globe-accent {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 786px;
  height: 786px;
  opacity: 0;
  transition: opacity 450ms ease;
  /* Safari-фікс продуктивності (той самий принцип, що .services-table,
     styles.css:1849) — без will-change WebKit не промотує шар заздалегідь,
     тому перший repaint кросфейду (на Tablet тут кероване скролом, не
     hover, js/industries-tablet-scrolly.js) відчувається як затримка */
  will-change: opacity;
}

.industries[data-active-globe='f'] .industries__globe-accent--f,
.industries[data-active-globe='h'] .industries__globe-accent--h,
.industries[data-active-globe='e'] .industries__globe-accent--e,
.industries[data-active-globe='c'] .industries__globe-accent--c,
.industries[data-active-globe='p'] .industries__globe-accent--p {
  opacity: 1;
}

/* Верхній градієнт-затемнення — поверх усієї ілюстрації (z-index
   найвищий у стеку), у самому верху контейнера. pointer-events: none —
   не блокує hover на рядках під ним/поруч */
.industries__globe-fade {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: 786px;
  height: 208px;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(17, 17, 17, 1) 14%, rgba(17, 17, 17, 0) 100%);
}

/* -------------------------------------------------------------------------
   Список індустрій — колонки 1–5 (720px), той самий рядок, що й глобус.
   z-index вище за глобус — лягає поверх нього
   ------------------------------------------------------------------------- */
.industries__list {
  position: relative;
  z-index: 1;
  grid-column: 1 / 6;
  grid-row: 4;
  margin-top: 96px;
}

.industry-row {
  position: relative;
  height: 122px;
  display: flex;
}

/* Обгортка лишається в потоці flex (64px, як раніше сам img) — усередині
   дві картинки стопкою (position: absolute), кросфейд на hover рядка */
.industry-row__illustration-wrap {
  position: relative;
  width: 64px;
  height: 122px;
  flex-shrink: 0;
}

/* transition-delay: 100ms (Крок 95) — симетрично на вхід і вихід */
.industry-row__illustration {
  position: absolute;
  inset: 0;
  display: block;
  width: 64px;
  height: 122px;
  object-fit: cover;
  transition: opacity 200ms ease 100ms;
}

.industry-row__illustration--base {
  opacity: 1;
}

.industry-row__illustration--hover {
  opacity: 0;
}

.industry-row:hover .industry-row__illustration--base {
  opacity: 0;
  transition: opacity 200ms ease 100ms;
}

.industry-row:hover .industry-row__illustration--hover {
  opacity: 1;
  transition: opacity 200ms ease 100ms;
}

/* padding-top: 24px розміщує тайтл; висота блока розтягується до 122px
   через дефолтний align-items: stretch рядка (display: flex) — решта
   висоти знизу лишається порожнім місцем автоматично */
.industry-row__content {
  margin-left: 32px;
  padding-top: 24px;
}

/* Трикутник (посилання, якого поки не буде) прибрано разом з
   HTML-елементом (Фікс Industries) */
/* Крок 124: базовий стан — усі рядки "яскраві". Приглушення (dim)
   стається не на самому rows :hover, а на СУСІДНІХ рядках через
   :has() на батьківському .industries__list — коли якийсь рядок
   у списку в hover, усі рядки КРІМ нього переходять у dim-стан.
   Стан самого hover-рядка ідентичний базовому, тому окремого
   правила на .industry-row:hover тут немає.
   transition-delay: 100ms (Крок 95) — симетрично на вхід і вихід */
.industry-row__title {
  position: relative;
  display: inline-block;
  color: var(--grey-100);
  transition: color 200ms ease 100ms;
}

.industries__list:has(.industry-row:hover) .industry-row:not(:hover) .industry-row__title {
  color: var(--grey-50);
  transition: color 200ms ease 100ms;
}

/* transition-delay: 100ms (Крок 95) — симетрично на вхід і вихід */
.industry-row__tags {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 20px;
  color: var(--grey-60);
  transition: color 200ms ease 100ms;
}

.industries__list:has(.industry-row:hover) .industry-row:not(:hover) .industry-row__tags {
  color: var(--grey-50);
  transition: color 200ms ease 100ms;
}

/* Дефолт — повноцінний (grey-60, opacity: 1); коли в hover інший
   рядок списку — dim (grey-50, opacity: 30%), той самий 100ms
   delay, що й решта переходів рядка */
.industry-row__dot {
  width: 4px;
  height: 4px;
  flex-shrink: 0;
  background-color: var(--grey-60);
  opacity: 1;
  transition: background-color 200ms ease 100ms, opacity 200ms ease 100ms;
}

.industries__list:has(.industry-row:hover) .industry-row:not(:hover) .industry-row__dot {
  background-color: var(--grey-50);
  opacity: 0.3;
  transition: background-color 200ms ease 100ms, opacity 200ms ease 100ms;
}

/* left/right замість width — 720 − 96 − 52 = 572px виходить сам собою */
.industry-row__divider {
  position: absolute;
  left: 96px;
  right: 52px;
  bottom: 0;
  height: 1px;
  background: var(--grey-15);
}

/* -------------------------------------------------------------------------
   Mobile (≤767px) sticky-глобус scrollytelling — обгортки навколо
   .industries__list (.industries__scrolly-mobile/-sticky/__list-window)
   існують у розмітці на ВСІХ breakpoint, але за замовчуванням
   display: contents — .industries__list лишається прямим grid-дитям
   .industries__grid (grid-column/row вище) без жодних змін на
   Desktop/Tablet. Мобільний globe-асет (563×286, окремий від десктопного
   786×786 .industries__globe-stack) і fade-маски вікна списку — приховані
   (display: none) поза Mobile. Реальні стилі — у медіа-запиті Mobile
   нижче; логіка руху/активного айтема — js/industries-mobile-scrolly.js.
   ------------------------------------------------------------------------- */
.industries__scrolly-mobile,
.industries__scrolly-mobile-sticky,
.industries__list-window {
  display: contents;
}

.industries__globe-stack-mobile,
.industries__list-window-fade {
  display: none;
}

/* ==========================================================================
   OFFICES — заголовний блок

   Структура ідентична заголовним блокам Services, Selected Work
   і Industries — спільні CSS-правила винесені разом із
   .services__label/__index/__title/__desc вище.
   ========================================================================== */

/* 146px від нижнього краю .industries. Список і глобус — окремі
   grid-item в одному рядку (4) вкладеної сітки Industries, тому сам
   рядок (а отже й уся секція) уже авто-розтягнутий під вищий з них —
   рахувати вручну, що саме нижче, не треба */
.offices {
  margin-top: 146px;
}

/* -------------------------------------------------------------------------
   Блок міст. Гео-логіка вирахувана від верху рядка тайтлів (.dm-h1,
   висота рядка 52px). Лінія (L) — це САМ пиксельний рядок top:68
   (52+16), тобто top:68px займає рядок Y=68. CSS-бокси описують межі,
   а не самі пікселі, тож щоб нижній пиксельний рядок квадрата ЗБІГАВСЯ
   з рядком лінії (а не просто торкався її верхньої межі), низ квадрата
   має бути на 1px НИЖЧЕ за top лінії:
   - маркер (5px): top 68+1-5=64 → займає рядки 64…68, останній збігається з L
   - лінія: top 52+16=68
   - arrow-box (44px): top 68+1-44=25 → нижній border-bottom лягає на рядок 68
   - інфо-колонка: top 68+24=92 (лінія не рухалась, відступ той самий)

   Замість дублювання 173/197px в окремому "рядку маркерів" (як
   підказано) кожен маркер/інфо-блок — position:absolute всередині
   ВЛАСНОГО .offices__city: так вони автоматично успадковують точний
   лівий край свого тайтла, яким би не був реальний рендер-ширина
   тексту (не треба знати ширину "London"/"New York" наперед)
   ------------------------------------------------------------------------- */
/* min-height обов'язковий: .offices__city-info (сабтайтл+боді) — position:
   absolute, тому сам по собі НЕ тягне висоту .offices__cities/.offices —
   без цього секція обривається одразу після рядка тайтлів (52px),
   а видимий текст висить нижче її боксу. 170px — безпечний верхній
   орієнтир: 92 (top інфо-колонки) + 24 (сабтайтл) + 10 (відступ)
   + до 44px боді (dm-14-light, 20px рядок — навіть 2 рядки лишаються
   в межах цього запасу) */
.offices__cities {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 124px;
  min-height: 170px;
}

.offices__titles {
  display: flex;
}

.offices__city {
  position: relative;
}

.offices__city--ny {
  margin-left: 173px;
}

.offices__city--kyiv {
  margin-left: 197px;
}

.offices__city-title {
  color: var(--grey-100);
  white-space: nowrap;
}

.offices__marker {
  position: absolute;
  left: 0;
  top: 64px;
  width: 5px;
  height: 5px;
  background-color: var(--grey-15);
}

/* Від краю сітки (колонка 1) до краю сітки (1164px) — на всю ширину
   .offices__cities, незалежно від вузького рядка тайтлів усередині */
.offices__line {
  position: absolute;
  left: 0;
  right: 0;
  top: 68px;
  height: 1px;
  background-color: var(--grey-15);
}

/* border-bottom — та сама лінія, що продовжує .offices__line під кнопкою:
   завжди var(--grey-15), в усіх стейтах (фон/колір/строук тепер веде
   .secondary-button, Крок 103, — тут лишається лише layout/розмір) */
.offices__arrow-box {
  position: absolute;
  top: 25px;
  right: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  border-bottom: 1px solid var(--grey-15);
}

.offices__city-info {
  position: absolute;
  left: 0;
  top: 92px;
}

/* Текст "More about us" — лише для Mobile (≤767px, Крок 182), де
   .offices__arrow-box стає повноцінною кнопкою з текстом замість
   іконки-квадрата 44×44; на десктопі/tablet-версіях лишається
   прихованим (той самий прийом, що .services__title--mobile) */
.offices__arrow-text {
  display: none;
}

.offices__subtitle {
  color: var(--grey-60);
}

.offices__body {
  margin-top: 10px;
  width: 276px;
  color: var(--grey-50);
}

/* ==========================================================================
   FOOTER

   50px від низу CTA-2 — звичайний margin-top, секції йдуть впритул.
   .footer__grid — той самий патерн сітки, що вище (винесений у спільний
   селектор). Явні grid-row на кожному рядку — той самий прийом, що
   в інших секціях (тут не обов'язково, бо кожен рядок сам займає
   всю ширину 1/9, але лишаю для однорідності коду).
   ========================================================================== */

.footer {
  margin-top: 50px;
  padding-bottom: 20px;
}

.footer__top {
  grid-column: 1 / 9;
  grid-row: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.footer__logo {
  display: block;
  width: 181.69px;
  height: 25px;
}

.footer__email {
  color: var(--grey-60);
  text-decoration: none;
}

.footer__line-a {
  grid-column: 1 / 9;
  grid-row: 2;
  margin-top: 16px;
  height: 1px;
  background-color: var(--grey-15);
}

/* height: 302px обов'язковий (32 патерн + 270 вертикальні строуки) —
   увесь вміст усередині position:absolute, тому сам по собі не тягне
   висоту (той самий нюанс, що виправляли в .offices__cities вище) */
.footer__body {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 3;
  height: 302px;
}

/* Колонка 1, 161px нижче ЛІНІЇ-А (= верху .footer__body) */
.footer__who {
  position: absolute;
  left: 0;
  top: 161px;
}

.footer__who-title {
  color: var(--grey-50);
}

.footer__who-body {
  margin-top: 12px;
  color: var(--grey-60);
}

/* 531px від лівого краю сітки; починається одразу від ЛІНІЇ-А (top: 0) */
.footer__vline {
  position: absolute;
  top: 0;
  width: 1px;
  height: 302px;
  background-color: var(--grey-15);
}

.footer__vline--1 {
  left: 531px;
}

/* Від низу патерна (32px), висота 270px — 32+270 = 302, той самий низ,
   що й у строука 1 */
.footer__vline--2 {
  left: 742px;
  top: 32px;
  height: 270px;
}

.footer__vline--3 {
  left: 952px;
  top: 32px;
  height: 270px;
}

/* Той самий x, що й строук 1 (531 + 633 = 1164, правий край сітки) */
.footer__pattern {
  position: absolute;
  left: 531px;
  top: 0;
  width: 633px;
  height: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M0 8L8 0' stroke='%231D1D1D' stroke-width='1'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* 24px правіше свого вертикального строука; перший лейбл на 54px
   нижче низу патерна (32+54=86) */
.footer__col {
  position: absolute;
  top: 86px;
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* без цього flex-stretch розтягує кожен .footer__label
    до ширини найширшого сусіда в колонці (напр. AUDIT = width CONSULTING) —
    ::after-строук (Крок 102) тоді лягав би під розтягнутий бокс, а не під
    власний текст напису */
  gap: 12px;
}

.footer__col--1 {
  left: 555px;
}

.footer__col--2 {
  left: 766px;
}

.footer__col--3 {
  left: 976px;
}

/* Стейти (Крок 102): Default grey-60/без строука → Hover grey-100 +
   строук на всю ширину напису → Pressed знову grey-60, той самий строук.
   ::after (а не border-bottom) — щоб строук не зсував layout сусідів;
   currentColor підхоплює колір тексту автоматично, тому окремо прописувати
   колір строука для hover/pressed не треба */
.footer__label {
  position: relative;
  color: var(--grey-60);
  text-decoration: none;
  transition: color 200ms ease;
}

.footer__label::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: currentColor;
  opacity: 0;
  transition: opacity 200ms ease;
}

.footer__label:hover {
  color: var(--grey-100);
}

.footer__label:hover::after {
  opacity: 1;
}

.footer__label:active {
  color: var(--grey-60);
}

.footer__label:active::after {
  opacity: 1;
}

/* Фікс: 3-тя колонка (LinkedIn/Clutch/Dribbble/Behance + Blog) — контент
   тепер типізується у звичайному регістрі в розмітці (напр. "LinkedIn"),
   аперкейс лише візуальний, через CSS (на відміну від колонок 1/2, де
   текст і далі набраний капсом напряму в HTML — там не займаємось) */
.footer__col--3 .footer__label {
  text-transform: uppercase;
}

/* Фікс: "Blog" — неактивний стан (без посилання, без hover/active-стану
   .footer__label вище) + якір для абсолютно позиційованої іконки-зірки.
   display:inline-block — той самий "надійний containing block для
   position:absolute нащадка" прийом, що .header__nav-text/.header__nav-num */
.footer__label--inactive {
  display: inline-block;
  color: var(--grey-50);
  pointer-events: none;
}

/* Іконка після "Blog": 3px від тексту, верхній край вирівняний по
   верхньому краю тексту (top підібраний під rh-12-bold-track/dm-14-light
   метрику лейбла — верифіковано скріншотом). mask (не <img>) — щоб колір
   керувався var(--grey-50) напряму, а не хардкодним stroke у самому SVG.
   Фікс: mask-image раніше посилався на ЗОВНІШНІЙ файл
   (assets/images/star.svg) — за протоколом file:// (відкриття HTML
   напряму подвійним кліком, без локального сервера) браузер блокує цей
   фетч як CORS-запит з "origin: null" (підтверджено консольною помилкою:
   "Access to image at 'file:///.../star.svg'... blocked by CORS
   policy"), тому маска не завантажувалась і іконка була невидимою —
   ЛИШЕ на file://, через http(s) той самий код працював, тому баг не
   відтворювався в попередніх перевірках. Inline data-URI (той самий
   прийом, що .services-table__row--strokes вище) не робить окремий
   фетч — CORS тут ні до чого. stroke='%23fff' (білий, не '%23B6B6B6'
   з файла) — WebKit-режим -webkit-mask-image за замовчуванням
   luminance-based (не alpha), тьмяний сірий stroke дав би частково
   прозору маску там; сам видимий колір іконки й далі задає
   background-color нижче, значення stroke у масці на нього не впливає */
.footer__blog-icon {
  position: absolute;
  left: calc(100% + 3px);
  top: 2px;
  width: 8px;
  height: 8px;
  background-color: var(--grey-50);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath d='M4.33398 8V5.39995L5.33398 4.76387M7.47912 1.82991L5.33398 3.6666V4.76387M7.72214 5.8475L5.33398 4.76387' stroke='%23fff'/%3E%3Cpath d='M3.72168 0V2.60005L2.72168 3.23613M0.576541 6.17009L2.72168 4.3334V3.23613M0.333526 2.1525L2.72168 3.23613' stroke='%23fff'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath d='M4.33398 8V5.39995L5.33398 4.76387M7.47912 1.82991L5.33398 3.6666V4.76387M7.72214 5.8475L5.33398 4.76387' stroke='%23fff'/%3E%3Cpath d='M3.72168 0V2.60005L2.72168 3.23613M0.576541 6.17009L2.72168 4.3334V3.23613M0.333526 2.1525L2.72168 3.23613' stroke='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* Обгортка саме слова "Blog" (без іконки) — окремий елемент від
   .footer__label--inactive, щоб тултіп (Крок, Desktop ≥1280px)
   центрувався по горизонталі відносно ЛИШЕ тексту "Blog", а не всього
   лейбла (текст+іконка) — position:relative тут, не на батьківському
   .footer__label--inactive, той самий "containing block" прийом, що
   .footer__blog-icon вище */
.footer__blog-text {
  position: relative;
  display: inline-block;
}

/* Тултіп "Coming soon" (Desktop ≥1280px, Крок нижче) — прихований за
   замовчуванням на ВСІХ breakpoint (opacity:0 + pointer-events:none, щоб
   ніколи не перехоплював курсор і не міг лишитись видимим після
   :hover), з'являється лише через :hover-правило в медіа-запиті нижче.
   bottom:100% + margin-bottom:5px — стрілка (низ стека) на 5px вище
   верхнього краю тексту "Blog" (п.4 ТЗ); left:50%+translateX(-50%) —
   центрування відносно .footer__blog-text */
.footer__blog-tooltip {
  position: absolute;
  left: 50%;
  bottom: 100%;
  margin-bottom: 5px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

/* Фрейм 126×40, фон var(--grey-15), текст по центру (обидві осі).
   text-transform:none — скасовує успадкований .footer__col--3
   .footer__label{text-transform:uppercase} (uppercase — inherited
   властивість, доходить і до цього descendant-тексту всупереч тому,
   що сам фрейм не має класу .footer__label) */
.footer__blog-tooltip-frame {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 126px;
  height: 40px;
  background-color: var(--grey-15);
  color: var(--grey-55);
  text-align: center;
  text-transform: none;
  white-space: nowrap;
}

/* Трикутник-стрілка 22×12, вершина вниз, впритул під фреймом (0px,
   немає gap — border-трюк: border-top = висота+колір, left/right
   прозорі по половині ширини) */
.footer__blog-tooltip-arrow {
  width: 0;
  height: 0;
  border-left: 11px solid transparent;
  border-right: 11px solid transparent;
  border-top: 12px solid var(--grey-15);
}

/* Desktop ≥1280px лише (п.5 ТЗ) — на інших breakpoint hover узагалі
   нерелевантний (touch), тому pointer-events лишається none, успадковане
   з .footer__label--inactive вище (жоден :hover тут не спрацює без
   pointer-events:auto). Нейтралізує загальний .footer__label:hover/
   :active (колір/строук-підкреслення, вище) — Blog і в hover має
   лишатись var(--grey-50), без hover-строука: той самий "неактивний"
   вигляд, лише з тултіпом */
@media (min-width: 1280px) {
  .footer__label--inactive {
    pointer-events: auto;
  }

  .footer__label--inactive:hover,
  .footer__label--inactive:active {
    color: var(--grey-50);
  }

  .footer__label--inactive:hover::after,
  .footer__label--inactive:active::after {
    opacity: 0;
  }

  .footer__label--inactive:hover .footer__blog-tooltip {
    opacity: 1;
  }
}

/* Крок: Mobile/Tablet Portrait/Tablet Landscape (≤1279px) — той самий
   тултіп, лише тригер клік/тап замість :hover (немає hover на тач).
   Розмір/позиція/вигляд самого тултіпа — той самий .footer__blog-tooltip
   (styles вище), без жодних змін тут. .is-open перемикається js/footer.js
   (той самий "toggle + document-click закриває" прийом, що дропдауни
   .work-hero__filter-group, js/work-filters.js) — повторний тап на "Blog"
   чи тап поза тултіпом закриває його */
@media (max-width: 1279px) {
  .footer__label--inactive {
    pointer-events: auto;
  }

  .footer__label--inactive:hover,
  .footer__label--inactive:active {
    color: var(--grey-50);
  }

  .footer__label--inactive:hover::after,
  .footer__label--inactive:active::after {
    opacity: 0;
  }

  .footer__label--inactive.is-open .footer__blog-tooltip {
    opacity: 1;
  }
}

/* 68px нижче останнього лейбла: 86 + 5×20 + 4×12 + 68 = 302 —
   той самий низ, що й у вертикальних строуків (перевірка з ТЗ) */
.footer__line-b {
  grid-column: 1 / 9;
  grid-row: 4;
  height: 1px;
  background-color: var(--grey-15);
}

.footer__bottom {
  grid-column: 1 / 9;
  grid-row: 5;
  margin-top: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.footer__copyright {
  color: var(--grey-50);
}

.footer__policies {
  display: flex;
  gap: 36px;
}

.footer__policy {
  color: var(--grey-50);
  text-decoration: none;
}

/* ==========================================================================
   СІТКА-ОВЕРЛЕЙ (dev-інструмент, аналог guides у Figma)

   Desktop + Tablet (≥768px): 8 колонок, Center, колонка 128px, gutter 20px,
   offset 0 → загальна ширина 8×128 + 7×20 = 1164px
   Mobile (≤767px): 4 колонки, Stretch, колонка Auto, gutter 16px,
   offset 20px з обох боків

   Перемикається шорткатом Shift+G (js/grid-overlay.js), за замовчуванням вимкнена
   ========================================================================== */

.grid-overlay {
  display: none;
  position: fixed;
  inset: 0;
  height: 100vh;
  pointer-events: none;
  z-index: 9999;
}

body.show-grid .grid-overlay {
  display: block;
}

.grid-overlay__row {
  height: 100%;
  max-width: 1164px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(8, 128px);
  gap: 20px;
}

.grid-overlay__col {
  height: 100%;
  background: var(--grid-overlay-color);
}

@media (max-width: 767px) {
  /* Фікс: сітка Mobile — 4 колонки по 72px + gutter 16px = 336px,
     ФІКСОВАНА й центрована (margin: 0 auto), а не розтягнута на всю
     ширину екрана мінус margin (колишні max-width:none/padding:0 20px/
     1fr — помилкове "stretch"-визначення, Крок 176-фікс) */
  .grid-overlay__row {
    max-width: 336px;
    margin: 0 auto;
    grid-template-columns: repeat(4, 72px);
    gap: 16px;
  }

  /* Type: Stretch — на мобільному використовуються лише перші 4 колонки */
  .grid-overlay__col:nth-child(n + 5) {
    display: none;
  }
}

/* ==========================================================================
   CONTACT PAGE — HERO (Крок 73, ФІКС у Кроці N)

   Крок 73 лишав height фіксованою 900px, бо контенту ще не було. Тепер
   заголовок+підпис+форма+кнопка разом ростуть далеко за 900px (форма з
   7 фреймами сама по собі ~618px), тому за патерном .work-hero/.about-hero
   height замінено на min-height — фон лишається тим самим 1920×900
   (background-size не змінюється), секція просто природно росте під
   контентом нижче */
.contact-hero {
  position: relative;
  /* z-index:0 — та сама причина, що .work-hero__bg (див. коментар там):
     заводить ВЛАСНИЙ stacking context, щоб .contact-hero__bg (z-index:-1
     нижче) коректно лягав ПІД контентом, а не втікав у чужий контекст
     вище по дереву. Success/limit-стан (.contact-hero__after-submission-bg
     нижче) і так уже явно заявляв z-index:0/1 (Крок раніше) — тепер
     обидва коректно скоуплені в ТОЙ САМИЙ, щойно заведений тут контекст,
     відносний порядок між ними не змінюється */
  z-index: 0;
  width: 100%;
  min-height: 1080px;
  background-color: var(--color-background);

  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 316px;
}

/* Двошаровий прийом (той самий фікс "спалаху кольору", що
   .work-hero__bg/.work-hero__image — див. коментар там): .contact-hero__bg
   — стабільний непрозорий шар ЛИШЕ з background-color, БЕЗ reveal-класу
   (раніше background-color і background-image та .scroll-reveal
   висіли РАЗОМ на цьому елементі — той самий клас крихкості, що вже
   виправлено в .work-hero). Ілюстрація (background-image) винесена в
   дочірній .contact-hero__image — колір фону завжди стабільний під час
   reveal-переходу. `.contact-hero:has(...) > .contact-hero__bg
   { display:none }` (нижче за файлом) продовжує працювати без змін —
   ховає весь шар (разом із вкладеною ілюстрацією) при показі Thanks/
   Message Limit стану */
.contact-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--color-background);
}

.contact-hero__image {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 1920px 1080px;
  background-image: url("../assets/images/contact-bg-desktop.webp");
  background-image: image-set(
    url("../assets/images/contact-bg-desktop.webp") 1x,
    url("../assets/images/contact-bg-desktop@2x.webp") 2x
  );
}

.contact-hero__title {
  color: var(--grey-100);
}

.contact-hero__desc {
  margin-top: 16px;
  width: 448px;
  color: var(--grey-60);
  text-align: center;
}

/* Ручний перенос Hero-боді для Mobile (≤767px) — перенос після "on."
   замість після "respond" (десктоп/tablet) — вимкнений за замовчуванням,
   той самий tablet-break прийом, що .footer__who-body-break--mobile.
   Вмикається/вимикається разом з десктопним варіантом у медіа-запиті */
.contact-hero__desc-break--mobile {
  display: none;
}

/* ==========================================================================
   CONTACT PAGE — FORM (Крок 74, повна перебудова)

   Кожен .form-field — flex-column бокс ФІКСОВАНОЇ висоти 70px з
   justify-content:flex-end: діти пакуються від НИЗУ фрейма, тож останній
   (.form-field__stroke) завжди впритул до нижнього краю — це і є
   "стабільна точка відліку", а не абсолютне позиціювання. Коли
   .form-field__value згорнутий (Empty: height:0, margin-top:0), він
   фактично не займає місця, і стройук лягає одразу під лейблом (15px,
   через свій власний margin-top); коли розгорнутий (Active/Filled), той
   самий margin-top:15px на строуці тепер рахується від НИЗУ видимого
   тексту, а не від лейблу — жодних окремих правил для цього не треба.
   Крок 114: 70px обрано НЕ довільно — активний стан (20+12+22+15+1=70px)
   рівно збігається з рамкою, без overflow (раніше 68px, і ці 2px йшли в
   overflow зверху фрейма — звідси видимий "стрибок" при фокусі).

   Стейти перемикаються лише класом на .form-field (JS:
   js/contact-form.js) — жодних окремих класів на дітях */
/* Фікс: власний stacking context з явним z-index (не auto) — та сама
   причина/фікс, що .work-hero__filters (Крок раніше, styles.css:684):
   .contact-form вже отримує stacking context через will-change
   (.scroll-reveal), але з z-index:auto він порівнюється з наступним
   сиблінгом .contact-stats за порядком DOM, а не за z-index. На
   Mobile/Tablet Portrait .contact-stats{margin-top} (88/128px) менший
   за реальну висоту відкритої dropdown-панелі (Product stage/Target
   outcome/Budget range), тому панель фізично заходила в зону .contact-stats
   і ховалась під нею (.contact-stats__item теж .scroll-reveal → власний
   stacking context, пізніший у DOM → малювався поверх). Явний z-index
   гарантує .contact-form вище БУДЬ-ЧОГО пізнішого в .contact-hero,
   незалежно від того, скільки місця залишається під формою */
.contact-form {
  position: relative;
  z-index: 10;
  margin-top: 48px;
  width: 448px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* min-height (не height): flex-shrink:0 на всіх трьох дітях (нижче)
   забороняє стиснення декоративного .form-field__stroke до 0px —
   без цього дефолтний flex-shrink:1 давав строуку поглинати будь-який
   дефіцит висоти першим */
.form-field {
  position: relative;
  width: 448px;
  min-height: 70px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.form-field__label {
  flex-shrink: 0;
  font-family: var(--font-red-hat);
  cursor: text;
  transition: font-size 180ms ease, line-height 180ms ease,
    font-weight 180ms ease, letter-spacing 180ms ease, color 180ms ease;
}

/* Фікс: grey-60 (було grey-100) — лише empty-стан; --active/--filled
   (нижче) лишаються без змін, у т.ч. для dropdown-полів, які поділяють
   цей самий клас у порожньому стані (Budget range/Target outcome) */
.form-field--empty .form-field__label {
  font-weight: 400;
  font-size: 16px;
  line-height: 22px;
  letter-spacing: 0em;
  color: var(--grey-60);
  text-transform: none;
}

.form-field--active .form-field__label,
.form-field--filled .form-field__label {
  font-weight: 700;
  font-size: 12px;
  line-height: 20px;
  letter-spacing: 0.13em;
  color: var(--grey-50);
  text-transform: uppercase;
}

.form-field__required {
  margin-left: 2px;
  font-family: var(--font-red-hat);
  font-weight: 700;
  font-size: 12px;
  line-height: 20px;
  letter-spacing: 0.13em;
  color: var(--primary-100);
}

.form-field__value {
  flex-shrink: 0;
  width: 448px;
  margin: 0;
  padding: 0;
  border: none;
  outline: none;
  resize: none;
  background: transparent;
  font-family: var(--font-red-hat);
  font-weight: 400;
  font-size: 16px;
  line-height: 22px;
  letter-spacing: 0em;
  color: var(--grey-100);
  height: 0;
  margin-top: 0;
  opacity: 0;
  overflow: hidden;
  transition: height 180ms ease, margin-top 180ms ease, opacity 150ms ease;
}

.form-field--active .form-field__value,
.form-field--filled .form-field__value {
  height: 22px;
  margin-top: 12px;
  opacity: 1;
}

/* Фікс — browser autofill (Chrome/Safari) інакше форсує власний світлий
   фон/колір тексту в заповнених полях, ігноруючи звичайний CSS. Останній
   transition — стандартний хак: браузер відкладає застосування СВОГО
   фону на 5000s, тому inset box-shadow (наш --color-background) лишається
   візуально єдиним видимим фоном */
.form-field__value:-webkit-autofill,
.form-field__value:-webkit-autofill:hover,
.form-field__value:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--grey-100);
  -webkit-box-shadow: 0 0 0 1000px var(--color-background) inset;
  transition: background-color 5000s ease-in-out 0s;
}

.form-field__stroke {
  flex-shrink: 0;
  width: 448px;
  height: 1px;
  margin-top: 15px;
  transition: background-color 180ms ease;
}

.form-field--empty .form-field__stroke,
.form-field--filled .form-field__stroke {
  background-color: var(--grey-15);
}

.form-field--active .form-field__stroke {
  background-color: var(--grey-100);
}

/* Фікс: дропдаун-поля (Product stage/Target outcome/Budget range) при
   відкритті панелі отримують лише .is-open (js/contact-form.js) — НЕ
   .form-field--active (те просто для текстових інпутів у фокусі), тому
   строук лишався в default grey-15 замість grey-100 доти, доки не
   обрано значення (.form-field--filled). Той самий колір, що вище */
.form-field.is-open .form-field__stroke {
  background-color: var(--grey-100);
}

/* Крок 116 — "Tell us a bit more": справжній <textarea> з авто-ростом.
   Висота НЕ керується --active/--filled CSS-правилом вище (height:22px
   фіксовано) — js/contact-form.js напряму пише інлайновий style.height
   під фактичний scrollHeight контенту (1-4 рядки), а max-height:88px
   (4×22px рядок .rh-16-reg) тут лише СТРАХУЄ верхню межу на CSS-рівні.
   overflow-y:hidden — дефолт (успадковано з .form-field__value), JS
   перемикає його на auto інлайново, коли контент вже перевищив 4 рядки.
   Фікс: приховуємо ВІЗУАЛЬНИЙ скролбар (не сам скрол — data-lenis-prevent
   у розмітці лишає нативний внутрішній скрол textarea робочим, Lenis
   лише перестає перехоплювати wheel над цим елементом) */
.form-field--textarea .form-field__value {
  max-height: 88px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.form-field--textarea .form-field__value::-webkit-scrollbar {
  display: none;
}

/* Фікс — повідомлення невалідного email: тепер ЗВИЧАЙНА flex-дитина
   .form-field (не position:absolute, як у Кроці 116) — коли показане,
   ДОДАЄ висоту контейнеру поля (min-height — лише floor, контейнер
   природно росте, той самий принцип, що й ріст textarea вище), тому
   стандартний 24px .contact-form gap рахується від СПРАВЖНЬОГО нижнього
   краю повідомлення, а не перекривається ним. max-height+opacity
   (замість display) — щоб поява/зникнення були плавною transition, а
   не миттєвим стрибком */
/* Фікс: margin-top переїхав у .is-visible нижче — max-height:0/
   overflow:hidden клипають лише ВНУТРІШНІЙ контент елемента, а не його
   власний зовнішній margin, тому фіксований margin-top тут (навіть у
   прихованому стані) додавав invisible 6px до .form-field постійно.
   В --empty це маскував 70px min-height floor (сума без помилки < 70),
   але в --active/--filled справжня сума дітей вже = рівно 70px, тому ці
   зайві 6px виштовхували контейнер до 76px — звідси зсув саме при фокусі */
.form-field__error {
  flex-shrink: 0;
  margin-top: 0;
  color: var(--semantic-error);
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 300ms ease, max-height 300ms ease, margin-top 300ms ease;
}

.form-field__error.is-visible {
  margin-top: 6px;
  opacity: 1;
  max-height: 20px;
}

/* Поле 7 (Budget range) — без стейтів, лейбл завжди Empty-вигляду.
   Іконка абсолютно позиційована по правому краю фрейма, вертикально
   вирівняна з лейблом (лейбл 22px висотою сидить впритул над строуком
   15px — центр іконки 12px = 15 + (22-12)/2 = bottom:20px) */
.form-field__dropdown-icon {
  position: absolute;
  right: 0;
  bottom: 20px;
  width: 12px;
  height: 12px;
  color: var(--grey-50);
  transition: transform 200ms ease, color 200ms ease;
}

/* Крок 114 — Target outcome: поле-дропдаун. Порожній стан ідентичний
   Budget range (Крок 74); коли обрано пункт, --empty→--filled перемикає
   .form-field__label/__value на ТІ САМІ правила, що вже описані вище для
   текстових полів (--active стан тут не використовується — лише
   empty/filled). Клікабельна площа — весь .form-field, за принципом
   "клік будь-де у фреймі" з js/contact-form.js */
.form-field--dropdown {
  cursor: pointer;
}

/* Фікс: .form-field__label вище безумовно задає cursor:text (усі текстові
   поля) — на dropdown-полях (Product stage/Target outcome/Budget range)
   лейбл візуально Є тригером, тому власний cursor:text на ньому
   переважав успадкований pointer з .form-field--dropdown і показував
   I-бім там, де насправді клік відкриває список */
.form-field--dropdown .form-field__label {
  cursor: pointer;
}

.form-field--dropdown.is-open .form-field__dropdown-icon {
  transform: rotate(180deg);
  color: var(--grey-100);
}

/* Фікс — "Tell us about your target outcome" (Крок 114, п.5): плавний
   fade+slide замість миттєвого display, той самий принцип, що
   .scroll-reveal (Крок 90) і .form-field__error (попередній фікс).
   max-height:70px — точна висота фрейма поля (Крок 114): в --empty
   стані (яким це поле завжди з'являється — щойно показане, ще не
   торкане юзером) сума дітей менша за 70px min-height floor, тож
   реальна відображена висота = рівно 70px, без запасу на marginи (gap
   між полями — flex-gap:24px .contact-form, він не залежить від
   max-height/overflow цієї дитини) */
/* Фікс: попередній фікс (min-height:0 нижче) прибрав конфлікт
   min-height/max-height, але геп лишався — справжня причина: .contact-form
   { display:flex; gap:24px } додає 24px ДО і 24px ПІСЛЯ кожної
   flex-дитини автоматично, незалежно від max-height/opacity САМОЇ
   дитини. Приховане поле лишалось звичайним (не display:none)
   flex-елементом, тому 48px gap навколо нього нікуди не діставались —
   звідси видимий розрив, а не max-height взагалі.
   Рішення: display:none у прихованому стані (тоді flex ВЗАГАЛІ не
   рахує елемент і gap навколо нього не з'являється) — js/contact-form.js
   керує ним напряму (inline style.display), синхронізовано з opacity/
   max-height transition: display:flex виставляється ПЕРЕД стартом
   transition появи (з форсованим reflow між ними), і назад на none —
   ЛИШЕ після завершення 400ms transition зникнення */
.target-outcome-other-field {
  display: none;
  /* .form-field (базовий клас, вище) безумовно задає min-height:70px —
     при рівній специфічності CSS віддає перевагу min-height над
     max-height, коли вони конфліктують, тому 0 тут — не декоративне */
  min-height: 0;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 400ms var(--ease-smooth), max-height 400ms var(--ease-smooth),
    min-height 400ms var(--ease-smooth);
}

.target-outcome-other-field.is-visible {
  /* Повертає ту саму 70px-підлогу, що й решта --empty полів (Крок 114) —
     тепер узгоджено з max-height, а не в конфлікті з ним */
  min-height: 70px;
  opacity: 1;
  max-height: 70px;
}

/* Крок 117 — форма ховається (не form.hidden — той самий специфічність-
   конфлікт з display:flex, що й вище) при успішній відправці,
   замінюється .contact-form-success */
.contact-form.is-hidden {
  display: none;
}

/* Панель дропдауна — ТОЧНЕ перевикористання механіки .work-hero__filter-dropdown
   (Кроки 108/111): 448px замість 206px (=ширині фрейма інпута), 8px
   відступ від низу тригера замість 24px, висота автоматична (сума висот
   пунктів + дівайдери між ними, без дівайдера після останнього) */
.form-field__dropdown-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 448px;
  background: var(--color-background);
  box-shadow: inset 0 0 0 1px var(--grey-15);
  z-index: 20;
  display: none;
}

.form-field--dropdown.is-open .form-field__dropdown-panel {
  display: block;
}

/* Фікс — viewport-aware позиціонування: js/contact-form.js виміряє
   реальну висоту панелі та вільний простір над/під тригером ПІСЛЯ
   is-open (поки панель ще display:none, offsetHeight = 0 — вимірювати
   можна лише коли вона вже видима), і додає цей клас, якщо знизу не
   вистачає місця, а зверху вистачає — той самий 8px відступ, тепер
   рахується від ВЕРХНЬОГО краю тригера вгору */
.form-field__dropdown-panel--opens-up {
  top: auto;
  bottom: calc(100% + 8px);
}

.form-field__dropdown-item {
  position: relative;
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 15px 20px;
  text-align: left;
  text-transform: uppercase;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--grey-50);
}

.form-field__dropdown-item:not(:last-child) {
  border-bottom: 1px solid var(--grey-15);
}

/* Фікс: градієнтний строук замінено на фон var(--grey-10) на весь фрейм
   активного пункту — той самий принцип, що вже застосований глобально на
   work.html (.work-hero__filter-item.is-active). .form-field__dropdown-
   item уже width:100%/box-sizing:border-box (база вище), тому background-
   color сам заповнює точний прямокутник пункту, без додаткової геометрії */
.form-field__dropdown-item.is-active {
  color: var(--grey-100);
  background-color: var(--grey-10);
}

/* Hover — перекриває і базовий, і активний колір, поки курсор над пунктом
   (той самий принцип, що .work-hero__filter-item:hover, Крок 111) */
.form-field__dropdown-item:hover {
  color: var(--grey-60);
}

/* CTA-кнопки (Крок 100) — стейти Default/Hover/Pressed/Disabled,
   спільні для ВСІХ .cta-button сайту (замінює background-color/color,
   що раніше жили на .hero__btn--primary — той клас лишає собі лише
   position/width). Розмитий radial-gradient еліпс (Крок 92) і pressed-коло
   (Крок 93) прибрано разом з їхніми ::before/::after — hover/pressed тепер
   ЄДИНИЙ ефект: градієнт-нашарування (нижче).
   Hover/pressed — не background напряму (колір↔градієнт не інтерполюється,
   тому давав миттєвий стрибок/блимання при mouseleave), а crossfade
   окремим шаром-накладкою ::after поверх базового кольору (той самий
   підхід, що для масок Trusted By/Industries/Services). ::after, а не
   ::before — .header__contact-link уже займає ::before під власний
   fill-ефект у "top"/"peek" (лишається як є, не перетинається) */
.cta-button {
  position: relative;
  background: var(--primary-100);
  color: var(--color-background);
  overflow: hidden;
  text-transform: uppercase;
  transition: color 300ms ease;
}

.cta-button::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 300ms ease;
  z-index: 0;
}

/* Фікс: hover/pressed — ІДЕНТИЧНИЙ суцільний var(--primary-pressed)
   замість градієнтного crossfade (::after-нашарування лишається —
   колір↔колір теж не анімується напряму без миготіння, той самий трюк,
   що вже описано в коментарі блоку вище). Текст/іконки лишаються
   unchanged (currentColor на іконках, color кнопки не перевизначається
   тут) */
.cta-button:hover::after,
.cta-button:active::after {
  background: var(--primary-pressed);
  opacity: 1;
}

.cta-button__content {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Перевикористовує структуру/кольори кнопки з hero (.hero__btn,
   .hero__btn--primary) — тут міняється лише ширина (448px замість 202px),
   як і .cta__btn */
.contact-form__submit {
  /* Фікс: 36px (було 44px) — Крок 116 підняв базовий flex-gap .contact-form
     з 16px до 24px, тому загальний відступ до кнопки лишається тими самими
     60px (24 + 36), а не випадково виріс до 68px */
  margin-top: 36px;
  width: 448px;
  /* <button>, на відміну від <a> в hero, несе UA-стилі рамки/курсора —
     .hero__btn/.hero__btn--primary їх не скидають, бо там не потрібно */
  border: none;
  cursor: pointer;
  /* Без іконки (прибрана) текст лишається єдиним flex-контентом —
     center замість успадкованого flex-start з .hero__btn */
  justify-content: center;
}

/* Disabled (Крок 100) — той самий вигляд незалежно від того, чи це
   рідний :disabled на <button>, чи .is-disabled/.cta-button--disabled
   на елементах, де :disabled неможливий (наприклад <a>). --disabled —
   вже наявний у розмітці BEM-модифікатор (contact-form__submit) */
.cta-button:disabled,
.cta-button.is-disabled,
.cta-button--disabled {
  background: var(--primary-disabled);
  color: var(--grey-15);
  pointer-events: none;
  cursor: not-allowed;
}

/* Крок 118 — honeypot: position:absolute + off-screen зсув, НЕ display:
   none/visibility:hidden — деякі боти вміють розпізнавати ці властивості
   й пропускати такі поля при автозаповненні */
.form-honeypot {
  position: absolute;
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

/* Крок 117 — помилка відправки EmailJS, під CTA-кнопкою. Форма
   лишається на екрані (не очищується) — юзер бачить помилку й може
   спробувати ще раз */
.contact-form__error {
  display: none;
  color: var(--semantic-error);
  text-align: center;
}

.contact-form__error.is-visible {
  display: block;
}

/* Крок 117 — успішна відправка: заміщує .contact-form (яка отримує
   [hidden]) тим самим паттерном заголовок+опис, що .contact-hero__title/
   __desc вище (Крок 74) — той самий display:flex/column/align-items:center
   і margin-top:16px між ними, тому й перевикористовує ці класи напряму,
   без нового CSS для типографіки/кольору. margin-top:48px — той самий
   відступ від опису Contact-hero, що мала .contact-form (Крок 74) */
.contact-form-success {
  display: none;
  flex-direction: column;
  align-items: center;
  margin-top: 48px;
}

.contact-form-success.is-visible {
  display: flex;
}

/* ==========================================================================
   Thank-you state (contact.html) — СПІЛЬНА структура (Mobile/Tablet
   Landscape/Desktop)

   :has(.contact-form-success.is-visible) — та сама умовна техніка, що
   вже скрізь на сайті (services-table/leadership/industries/faq тощо) —
   вмикає Thank-you-стилі ЛИШЕ коли JS показав success-блок
   (form.classList.add('is-hidden') + formSuccess.classList.add
   ('is-visible'), js/contact-form.js), без потреби у власному
   JS-тогглі саме для стилів.

   Верхній рівень (>) на .contact-hero__title/__desc — ховає лише
   ОРИГІНАЛЬНІ тайтл/боді Hero ("Contact"/"Tell us..."), прямих дітей
   .contact-hero; ті самі класи, перевикористані ВСЕРЕДИНІ
   .contact-form-success ("Thanks"/боді подяки), під цей селектор не
   підпадають (не прямі діти) — Thank-you-блок стає єдиним видимим
   контентом Hero, той самий принцип, що self-contained Hero-секції на
   інших сторінках (index.html), яким нічого не передує. Тайтл/боді тут
   успадковують типографіку від .contact-hero__title/__desc НАПРЯМУ (без
   додаткового CSS у цьому блоці) — на Mobile це вже .dm-28-reg/
   .dm-14-light (Hero-фікс, окремий Крок), на Tablet Landscape/Desktop —
   .dm-h2/.dm-desc (база) — типографіка Thank-you-тайтла/боді на кожному
   брейкпоінті збігається з тим, що там уже задано для Hero.

   Ці структурні правила раніше були скоуплені на (min-width:1024px),
   (max-width:767px) — Tablet Portrait (768–1023px) ще не мав власного
   Thank-you-кроку, і без спейсерів-замінників padding-top:0/min-height:0
   там знімали б успадкований Крок209-відступ (224px), а тайтл "Thanks"
   наїжджав би на фіксований хедер. Тепер Tablet Portrait має власний
   ::before + spacer--top/--bottom (нижче), тому правило безумовне —
   застосовується на всіх брейкпоінтах однаково */

.contact-hero:has(.contact-form-success.is-visible) {
  min-height: 0;
  padding-top: 0;
}

.contact-hero:has(.contact-form-success.is-visible) > .contact-hero__title,
.contact-hero:has(.contact-form-success.is-visible) > .contact-hero__desc {
  display: none;
}

/* Фікс: стандартний Hero-фон реально вимикається (display:none), а не
   лише перекривається по z-index ілюстрацією after-submission (::before
   нижче) — раніше обидва шари рендерились одночасно, і стандартний фон
   проглядав крізь місця, де after-submission.webp (auto-width, 100vh)
   не сягає повної ширини 100vw */
.contact-hero:has(.contact-form-success.is-visible) > .contact-hero__bg {
  display: none;
}

/* Скидає успадкований margin-top:48px (рахований від НЕвидимого тепер
   опису Hero, Крок 117) — .contact-form-success тепер перший видимий
   flex-child .contact-hero, увесь відступ від верху задає ЛИШЕ
   spacer--top (нижче, по брейкпоінтах) */
.contact-form-success {
  margin-top: 0;
}

.contact-hero:has(.contact-form-success.is-visible) .contact-form-success {
  position: relative;
  z-index: 1;
}

.contact-form-success__spacer {
  flex-shrink: 0;
}

/* Фікс: текст+іконка центруються як ГРУПА (justify-content:center)
   замість "текст зліва/іконка справа" через асиметричний
   padding: 0 31px 0 35px */
.contact-form-success__btn {
  margin-top: 32px;
  width: 274px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
}

.contact-form-success__btn img {
  width: 12px;
  height: 12px;
}

/* Фон — full-bleed (той самий прийом, що .hero__bg на index.html:
   left:50%/width:100vw/margin-left:-50vw — не залежить від
   max-width:1920px на <main>, тому й на вужчих/ширших екранах бокс
   завжди дорівнює фізичній ширині в'юпорта), background-size:auto 100vh
   (нижче, по брейкпоінтах) — висота фону завжди=висоті в'юпорта,
   ширина масштабується пропорційно, ніколи не обрізається (на широких
   екранах виходить за межі в'юпорта по боках). z-index:0 — контент
   піднятий у position:relative;z-index:1 (вище), інакше absolute-шар з
   z-index:0 малювався б ПОВЕРХ звичайного in-flow контенту (порядок
   малювання CSS2.1: positioned z-index:auto/0 — після звичайного
   in-flow). Структуру (не значення background-size/position) тримаємо
   СКОУПЛЕНОЮ по брейкпоінтах (не unscoped) — щоб на неопрацьованих
   ширинах (Tablet Portrait) не з'являвся зображення з дефолтним
   (native px, top-left) розміром/позицією замість пропорційного
   масштабування.

   Двошаровий прийом (той самий фікс "спалаху кольору", що
   .work-hero__bg/.work-hero__image — див. коментар там), застосований
   до РЕАЛЬНИХ дочірніх елементів замість ::before (раніше тут був
   псевдо-елемент, що ОДНОЧАСНО ніс і background-color, і background-
   image, і .opacity-transition — на повільній мережі ВЕСЬ шар, разом
   із кольором, чекав на .after-submission-ready, тому "нічого не
   видно" секунду довше, ніж потрібно). Тепер .contact-hero__after-
   submission-bg — стабільний колірний шар: з'являється ОДРАЗУ
   (display:block, без transition) щойно .contact-form-success стає
   .is-visible, незалежно від готовності картинки. .contact-hero__after-
   submission-image — вкладений inset:0, несе саме зображення й весь
   fade-in+translateY, і, як і раніше, чекає на .after-submission-ready
   (js/contact-form.js, waitForImages-принцип) — лише сама ілюстрація
   затримується до реального decode, а не колір під нею */

@media (min-width: 1024px) {

  .contact-hero__after-submission-bg {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: none;
    background-color: var(--color-background);
  }

  .contact-hero:has(.contact-form-success.is-visible) .contact-hero__after-submission-bg {
    display: block;
  }

  .contact-hero__after-submission-image {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: translateY(40px);
    transition: opacity .65s var(--ease-smooth), transform .65s var(--ease-smooth);
    background-repeat: no-repeat;
    background-size: auto 100vh;
    background-image: url("../assets/images/after-submission.webp");
    background-image: image-set(
      url("../assets/images/after-submission.webp") 1x,
      url("../assets/images/after-submission@2x.webp") 2x
    );
  }

  /* Фікс: .after-submission-ready (js/contact-form.js додає лише ПІСЛЯ
     реального onload картинки, той самий waitForImages-принцип, що
     js/reveal.js) — без цього класу opacity/transform так і лишаються
     0/translateY(40px), навіть якщо .contact-form-success уже .is-
     visible, тому fade-in стартує РАЗОМ із готовим зображенням, а не
     раніше */
  .contact-hero.after-submission-ready:has(.contact-form-success.is-visible) .contact-hero__after-submission-image {
    opacity: 1;
    transform: none;
  }
}

/* Desktop ≥1280px — референс 1080px висоти в'юпорта: 371px до блоку
   (34.352vh), 515px після (47.685vh); фон без зсуву (center top).
   .contact-stats margin-top:140px — перевизначає успадковані 190px
   (розраховані під довгу форму) лише в Thank-you-стані */
@media (min-width: 1280px) {

  .contact-hero__after-submission-image {
    background-position: center top;
  }

  .contact-form-success__spacer--top {
    height: 34.352vh;
  }

  .contact-form-success__spacer--bottom {
    height: 47.685vh;
  }

  .contact-hero:has(.contact-form-success.is-visible) .contact-stats {
    margin-top: 140px;
  }
}

/* Tablet Landscape 1024–1279px — референс 810px висоти в'юпорта: 212px
   до блоку (26.173vh), 404px після (49.877vh); фон зсунутий на 24px
   від верху сторінки (center 24px). Референс розміру самої ілюстрації —
   1320×742px (той самий принцип, що десктопний референс 1920×1080 —
   реальні пропорції файлу after-submission.webp/@2x, від яких іде
   масштабування; сам файл спільний для всіх брейкпоінтів, тому це не
   окремий асет, а лише довідкове співвідношення сторін для цього
   брейкпоінта).
   Фікс: background-size — auto calc(100vh - 24px), а НЕ auto 100vh —
   верхній 24px-відступ (background-position вище) + сама ілюстрація
   мають РАЗОМ дорівнювати висоті в'юпорта, інакше ілюстрація виходила б
   за нижню межу екрана на 24px (auto 100vh масштабував її під ПОВНУ
   висоту в'юпорта, ігноруючи вже зайнятий зверху відступ) */
@media (min-width: 1024px) and (max-width: 1279px) {

  .contact-hero__after-submission-image {
    background-position: center 24px;
    background-size: auto calc(100vh - 24px);
  }

  .contact-form-success__spacer--top {
    height: 26.173vh;
  }

  .contact-form-success__spacer--bottom {
    height: 49.877vh;
  }
}

/* Tablet Portrait 768–1023px — референс 1024px висоти в'юпорта: 364px
   до блоку (35.547vh), 484px після (47.266vh); фон зсунутий на 280px від
   верху сторінки (center 280px). Референс розміру самої ілюстрації —
   1320×742px, той самий, що Tablet Landscape (спільний файл, лише інший
   referens висоти в'юпорта для позиції тексту). ::before тут не
   успадковує структуру з min-width:1024px вище (той блок не покриває
   768–1023px) — власна повна
   декларація, той самий "безумовний ::before + opacity/transform toggle
   через :has()" прийом, що на інших брейкпоінтах. Типографіка тайтла/
   боді ("Thanks"/"You've submitted recently") нічого додаткового тут не
   потребує — .contact-hero__title/__desc уже мають власний Tablet
   Portrait-оверрайд (30px/36px, 16px/22px — Крок 208), а Thank-you-блок
   перевикористовує ці самі класи напряму в розмітці.
   Фікс: background-size — auto calc(100vh - 280px), а НЕ auto 100vh —
   той самий принцип, що Tablet Landscape (див. коментар там): верхній
   280px-відступ + сама ілюстрація мають РАЗОМ дорівнювати висоті
   в'юпорта */
@media (min-width: 768px) and (max-width: 1023px) {

  .contact-hero__after-submission-bg {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: none;
    background-color: var(--color-background);
  }

  .contact-hero:has(.contact-form-success.is-visible) .contact-hero__after-submission-bg {
    display: block;
  }

  .contact-hero__after-submission-image {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: translateY(40px);
    transition: opacity .65s var(--ease-smooth), transform .65s var(--ease-smooth);
    background-repeat: no-repeat;
    background-size: auto calc(100vh - 280px);
    background-position: center 280px;
    background-image: url("../assets/images/after-submission.webp");
    background-image: image-set(
      url("../assets/images/after-submission.webp") 1x,
      url("../assets/images/after-submission@2x.webp") 2x
    );
  }

  .contact-hero.after-submission-ready:has(.contact-form-success.is-visible) .contact-hero__after-submission-image {
    opacity: 1;
    transform: none;
  }

  .contact-form-success__spacer--top {
    height: 35.547vh;
  }

  .contact-form-success__spacer--bottom {
    height: 47.266vh;
  }
}

/* Mobile ≤767px — референс 812px висоти в'юпорта: 283px до блоку
   (34.852vh), 327px після (40.271vh); фон зсунутий на 411px/50.616vh
   (не фіксований px, як на Tablet Landscape, — саме vh, щоб зсув лишався
   пропорційним на всьому діапазоні висот Mobile-в'юпортів, від ~600 до
   ~950px). Референс розміру самої ілюстрації — 659×371px (той самий
   принцип, що десктопний 1920×1080/Tablet 1320×742 — реальні пропорції
   спільного файлу after-submission.webp/@2x).
   Фікс: background-size — auto 49.384vh (=100vh−50.616vh), а НЕ auto
   100vh — той самий "відступ + ілюстрація = висота в'юпорта" принцип,
   що Tablet Landscape/Portrait. Тут ОБИДВА числа (позиція й розмір)
   лишаються у vh, НЕ px (на відміну від фіксованих 24px/280px на
   Tablet) — інакше на реальних Mobile-висотах, відмінних від 812px
   референсу, offset (vh, пропорційний) і віднімання в calc() (якби
   було фіксованим px) розійшлися б, і "відступ+ілюстрація=100vh" не
   виконувалось би рівно ніде, крім самого референсу */
@media (max-width: 767px) {

  /* Той самий "безумовний шар + opacity/transform toggle через :has()"
     прийом, що min-width:1024px вище */
  .contact-hero__after-submission-bg {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: none;
    background-color: var(--color-background);
  }

  .contact-hero:has(.contact-form-success.is-visible) .contact-hero__after-submission-bg {
    display: block;
  }

  .contact-hero__after-submission-image {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: translateY(40px);
    transition: opacity .65s var(--ease-smooth), transform .65s var(--ease-smooth);
    background-repeat: no-repeat;
    background-size: auto 49.384vh;
    background-position: center 50.616vh;
    background-image: url("../assets/images/after-submission.webp");
    background-image: image-set(
      url("../assets/images/after-submission.webp") 1x,
      url("../assets/images/after-submission@2x.webp") 2x
    );
  }

  .contact-hero.after-submission-ready:has(.contact-form-success.is-visible) .contact-hero__after-submission-image {
    opacity: 1;
    transform: none;
  }

  .contact-form-success__spacer--top {
    height: 34.852vh;
  }

  .contact-form-success__spacer--bottom {
    height: 40.271vh;
  }
}

/* ==========================================================================
   CONTACT PAGE — STATS (Крок 75, перебудова)

   Той самий вертикальний патерн, що .about-stats на about.html (dm-h0
   тайтл, rh-12-bold-track лейбл, dm-14-light боді, 5×5 маркер, 1px лінія;
   маркер top:71 = 64(висота рядка dm-h0) + 7, лінія top:75 = низ маркера).

   МЕТОД горизонтального позиціонування — за принципом рядка міст
   .about-offices__cities на about.html: у нормальному потоці кожного
   .contact-stats__item лишається ЛИШЕ тайтл (white-space:nowrap) —
   лейбл/маркер/боді всі position:absolute відносно айтема, тому не
   впливають на його flow-ширину. Завдяки цьому margin-left наступного
   айтема (173px, 178px) — це РЕАЛЬНИЙ проміжок від правого краю
   ПОПЕРЕДНЬОГО ТАЙТЛА (а не від правого краю всього айтема разом з
   лейблом), точно як просив користувач. Це також усуває попередній баг:
   раніше лейбл був у флоу поряд з тайтлом і "тягнув" ширину айтема, тому
   довгий лейбл ("Products") заходив на тайтл наступного айтема; тепер
   лейбл абсолютний і на розрахунок відстані не впливає.

   .contact-stats__titles — flex-ряд природної ширини (shrink-to-fit:
   сума ширин трьох тайтлів + 173px + 178px), центрований по горизонталі
   через margin:0 auto відносно сторінки (а не прив'язаний до лівого
   краю сітки офсетом, як було раніше). position:relative на ньому ж —
   щоб .contact-stats__line (width:100%, нижче) рахувався від краю
   САМОГО РЯДКА, а не від ширини .contact-stats__grid.

   Явний min-height на .contact-stats__grid — той самий прийом, що
   .about-offices__cities (коментар там: "маркер/лінія/city-info
   абсолютні, самі по собі не тягнуть висоту батька") */
.contact-stats {
  align-self: stretch;
  margin-top: 190px;
}

.contact-stats__grid {
  position: relative;
  max-width: 1164px;
  margin: 0 auto;
  min-height: 140px;
}

/* 174px — від лівого краю сітки (.contact-stats__grid) до тайтла
   айтема 1 ("300+"), замість попереднього центрування (margin:0 auto) */
.contact-stats__titles {
  position: relative;
  display: flex;
  width: fit-content;
  margin: 0 0 0 174px;
}

.contact-stats__item {
  position: relative;
}

/* 173px — від правого краю тайтла айтема 1 до лівого краю тайтла айтема 2 */
.contact-stats__item--2 {
  margin-left: 173px;
}

/* 178px — від правого краю тайтла айтема 2 до лівого краю тайтла айтема 3 */
.contact-stats__item--3 {
  margin-left: 178px;
}

.contact-stats__title {
  color: var(--grey-100);
  white-space: nowrap;
}

/* 6px правіше правого краю тайтла, 2px нижче його верхньої грані —
   та сама формула, що в оригінальному .about-stats__label, лише
   виражена через absolute (100%+6px) замість flex-margin, оскільки
   тайтл тепер єдиний flow-контент айтема */
/* white-space:nowrap — фікс: без нього двослівний лейбл ("OF CLIENTS")
   переносився на 2 рядки через shrink-to-fit ширину контейнера
   (.contact-stats__item, position:relative, ширина = ширина самого
   тайтла, менша за лейбл) — однослівні лейбли ("PRODUCTS"/"OFFICES")
   цього не показували лише тому, що їх нема де переносити */
.contact-stats__label {
  position: absolute;
  left: calc(100% + 6px);
  top: 2px;
  color: var(--grey-60);
  white-space: nowrap;
}

.contact-stats__marker {
  position: absolute;
  left: 0;
  top: 71px;
  width: 5px;
  height: 5px;
  background-color: var(--grey-15);
}

/* top:100px = 75 (лінія) + 1 (висота лінії) + 24 (gap) */
.contact-stats__body {
  position: absolute;
  left: 0;
  top: 100px;
  width: 200px;
  color: var(--grey-50);
}

/* Сиблінг .contact-stats__titles (не дитина) — тому containing block
   це .contact-stats__grid (position:relative, 1164px), а не вужчий
   відцентрований рядок тайтлів: лінія тягнеться на всю ширину сітки
   незалежно від центрування рядка, той самий принцип, що
   .about-offices__line (left:0;width:100% відносно .about-offices__cities,
   а не .about-offices__titles) */
.contact-stats__line {
  position: absolute;
  left: 0;
  top: 75px;
  width: 100%;
  height: 1px;
  background-color: var(--grey-15);
}

/* Крок 76 — Offices на Contact: повне перевикористання .about-offices__*
   (About, Крок 65-71), тому вся внутрішня стилістика вже задана спільними
   правилами вище — .contact-offices лише перевизначає top-level відступ
   секції (186px від .contact-stats, замість 204px, які .about-offices
   рахує від Leadership на About) */
.contact-offices {
  margin-top: 186px;
}

/* -------------------------------------------------------------------------
   Крок 78 — Services (нова сторінка): hero

   Крок 78 навмисно ставив height:900px (тоді всередині секції був лише
   лейбл+тайтл+опис, це справді не переростало 900px). Крок 79 (заголовок
   списку) і Крок 80 (список практик, 800px-скрол-вікно) додали набагато
   більше вмісту нижче — тепер це, як і .work-hero, min-height: фіксована
   height лишила б box рівно 900px, а весь наступний контент (і будь-яка
   секція після цієї) заліг би поверх нього (overflow не впливає на потік
   сусідів). background 1920×900 лишається приколотим до top, під ним —
   просто var(--color-background), той самий прийом, що й у .work-hero.
   ------------------------------------------------------------------------- */
.services-hero {
  position: relative;
  z-index: 0;
  width: 100%;
  min-height: 900px;
  background-color: var(--color-background);

  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 170px;
}

/* Двошаровий прийом (той самий фікс "спалаху кольору", що
   .work-hero__bg/.work-hero__image — див. коментар там): .services-hero__bg
   — стабільний непрозорий шар ЛИШЕ з background-color, БЕЗ reveal-класу.
   Раніше цей шар (тоді ще й background-image, і .scroll-reveal РАЗОМ на
   одному елементі) взагалі не мав власного background-color — колір під
   час opacity:0 (до reveal) покладався ЛИШЕ на те, що просвічує
   батьківський .services-hero з тим самим var(--color-background), що
   випадково збігалось, а не гарантовано (той самий клас крихкості, що
   вже виправлено в .contact-hero__bg/.work-hero__bg) — явний
   background-color тут прибирає цю залежність від збігу */
.services-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--color-background);
}

.services-hero__image {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 1920px 900px;
  background-image: url("../assets/images/services-bg.webp");
  background-image: image-set(
    url("../assets/images/services-bg.webp") 1x,
    url("../assets/images/services-bg@2x.webp") 2x
  );
}

.services-hero__eyebrow {
  color: var(--grey-50);
  text-transform: uppercase;
}

.services-hero__title {
  margin-top: 12px;
  width: 1080px;
  color: var(--grey-100);
  text-align: center;
}

.services-hero__desc {
  margin-top: 18px;
  width: 617px;
  color: var(--grey-60);
  text-align: center;
}

/* Планшетні ручні переноси тайтла (Крок 149) відрізняються компонуванням
   рядків від десктопних — за замовчуванням вимкнені, той самий
   tablet-break прийом, що в Our Approach/Offices */
.services-hero__title-break--tablet {
  display: none;
}

/* Мобільні ручні переноси тайтла (Крок 191) — своя, окрема точка
   розриву, ніж --tablet/--desktop — за замовчуванням вимкнені */
.services-hero__title-break--mobile {
  display: none;
}

/* Мобільні ручні переноси боді-тексту Hero (Крок) — боді-текст на
   Mobile прибраний з потоку (display:none нижче), розриви тут ні на
   що не впливають, але лишаються вимкненими за замовчуванням, той
   самий прийом, що тайтл вище */
.services-hero__desc-break--mobile {
  display: none;
}

/* Крок 79 — заголовок списку сервісів: "Services (21)" + порядковий
   номер "I." у колонці 6, за тим самим принципом, що .work-hero__list-heading
   (align-self:stretch виносить блок із центрованого потоку .services-hero
   на всю ширину, inner max-width:1164/margin:auto вирівнює по сітці) */
.services-hero__list-heading {
  align-self: stretch;
  margin-top: 252px;
}

.services-hero__list-heading-inner {
  position: relative;
  display: flex;
  align-items: flex-start;
  max-width: 1164px;
  margin: 0 auto;
}

.services-hero__list-title {
  color: var(--grey-100);
}

.services-hero__list-count {
  margin-left: 10px;
  color: var(--grey-60);
}

/* Колонка 6 = 740px від лівого краю сітки (5×128 + 5×20). Абсолютне
   позиціонування, бо низ цифри має сидіти на 3px ВИЩЕ низу тайтла
   "Services" — .list-heading-inner своєю висотою дорівнює найвищому
   flex-дитині (тайтлу dm-h2), тож bottom:3px від контейнера = 3px
   вище низу тайтла */
.services-hero__list-index {
  position: absolute;
  left: 740px;
  bottom: 3px;
  color: var(--grey-50);
}

.services-hero__list-stroke {
  width: 1164px;
  height: 1px;
  margin: 15px auto 0;
  background-color: var(--grey-15);
}

/* -------------------------------------------------------------------------
   Крок 80 — список практик, що скролиться. Адаптація scrollytelling-механіки
   .services/.services__sticky/.services-table-window з index.html
   (js/services-table.js) — той самий принцип "pin + JS підставляє висоту
   обгортки, sticky-вікно лишається на екрані, поки не докрутиться внутрішній
   вміст", але БЕЗ дискретного activeIndex/гістерезису/ілюстрації: тут немає
   активного стану айтемів, самі айтем-блоки різної висоти (item 3 значно
   більший за 1/2/4/5), тож зсув суцільний (1:1 із прогресом), не поквантований.

   .services-hero__practices — той самий "тall spacer", що .services на
   index.html: висоту (928px sticky-панелі + scrollRange) підставляє
   js/services-practices.js. margin-top: 0 — навмисно ВПРИТУЛ до Кроку 79
   (як .services__intro впритул до .services__sticky на index.html): це
   і є тригер-точка "page scroll → internal scroll" (Фікс, після Кроку 82) —
   position:sticky сама активується (панель "прилипає" до top:0 viewport)
   рівно в момент, коли її природна (незаскрольована) top-позиція, яка
   ТУТ дорівнює низу строука Кроку 79, проходить верхню межу viewport,
   тобто рівно тоді, коли строук повністю зникає з екрана. align-self:
   stretch + max-width:1164/margin:auto — щоб sticky-панель нижче мала
   контейнером (containing block) САМЕ цей елемент (а не якийсь проміжний
   non-sized wrapper — інакше висота-запас губиться і sticky одразу
   "відпускається").
   ------------------------------------------------------------------------- */
.services-hero__practices {
  align-self: stretch;
  max-width: 1164px;
  margin: 0 auto;
  position: relative;
}

/* Крок 82 + Фікс тригер-точки: sticky — САМЕ ця панель (не .practices-window,
   як було в Кроці 80), за принципом .services__sticky/.services__panel-grid
   з index.html — вона тримає РАЗОМ статичну ілюстрацію (Крок 82) і вікно
   списку (яке саме вже НЕ sticky, просто overflow:hidden box, JS транслює
   .practices-list всередині нього). height:928 = 128px (зазор, раніше був
   зовнішнім margin-top на .services-hero__practices — переїхав УСЕРЕДИНУ
   панелі, щоб панель сама починалась ВПРИТУЛ до строука Кроку 79, а не
   на 128px нижче) + 800px (видиме вікно списку) */
.services-hero__practices-sticky {
  position: sticky;
  top: 0;
  height: 928px;
  /* padding-top, НЕ margin-top на .window: margin-top на єдиній in-flow
     дитині (illu/bridge — position:absolute, з потоку виключені) колапсує
     крізь батька (сюди немає border/padding/BFC, що це блокує) і зсуває
     ВЖЕ САМУ панель на ці 128px, а не тільки вміст усередині — тоді верх
     ілюстрації/вікна опинявся на 256px, а не на 128px, нижче строука.
     padding ніколи не колапсує — так само служить референсом (top-edge
     панелі) для абсолютних ілюстрації/містка, як і раніше */
  padding-top: 128px;
}

/* Крок 82 — ілюстрація ліворуч, статична (не скролиться з .practices-list).
   top:112px (Фікс: підняли на 16px від початкових 128px — той самий
   128px-зазор всередині панелі, мінус 16px). offset відлічується від
   padding-edge панелі (абсолютні нащадки ігнорують власний padding
   контейнера), тому зміна тут НЕ впливає на вікно/лінію/місток нижче.
   right edge = 534px від лівого краю сітки = 721px (велика лінія, Крок 81)
   мінус 187px → left = 534 − 1016 = −482px. Той самий принцип "right edge
   виміряний від вертикальної лінії, а не прямо від колонки сітки, і зсув
   за межу сітки зліва — очікуваний", що й .how-we-work__sphere (right edge
   110px лівіше .how-we-work__vline) і .services__illustration-stack
   на index.html */
.services-hero__practices-illustration {
  position: absolute;
  top: 112px;
  left: -482px;
  width: 1016px;
  height: 1016px;
}

/* Крок 113: контейнер несе й спільний клас .services__illustration-stack
   (index.html, Крок 97) — перевикористовує всю CSS база/маски/теги без
   дублювання. Те правило також задає margin-top:40px/margin-left:-483px
   (розраховані під grid-column:1 позицію index.html) — тут позиція вже
   завершена через top/left вище, тому обнуляємо margin окремим,
   специфічнішим правилом (2 класи замість 1 — вищий пріоритет
   незалежно від порядку в файлі) */
.services-hero__practices-illustration.services__illustration-stack {
  margin: 0;
}

/* margin-left:720px — кінець колонки 5 (не 740, як тайтл/тег/боді нижче:
   фрейми сервісів навмисно бleed на 20px лівіше тексту, щоб закінчитись
   рівно на 1164). 128px-зазор над вікном — це padding-top на
   .practices-sticky (НЕ margin-top тут, див. коментар там).
   Фікс: width 444→450 (+6px) — той самий буфер, що на .practice__body
   вище (subpixel-фікс переносу "...real consequences"), щоб вікно не
   обрізало текст, який тепер bleed-ить трохи далі за старі 1164px */
/* Фікс: margin-left 720→721 — вікно (і, відповідно, .practice::before,
   лівий градієнтний строук активної практики) було на 1px лівіше за
   .services-hero__practices-line (left:721px вище). Landscape/Tablet
   Portrait вже мають вікно=лінія (444=444, 326=326, "впритул") — тут
   вирівнюємо десктоп до того самого принципу */
.services-hero__practices-window {
  position: relative;
  margin-left: 721px;
  width: 450px;
  height: 800px;
  overflow: hidden;
}

.services-hero__practices-list {
  position: relative;
  width: 444px;
  /* Safari-фікс: transform пишеться на кожен тик 'scroll' Lenis
     (js/services-practices.js) — той самий will-change принцип, що
     .services-table вище */
  will-change: transform;
}

/* База (сиблінг .window всередині .sticky, той самий вузол, що завжди
   використовували Tablet Landscape/Portrait, і no-JS/до-виконання-JS
   фолбек на десктопі) — статичний строук на всю висоту sticky-панелі.
   Tablet Landscape/Portrait перевизначають left/height нижче, top:0
   лишається спільним для обох */
.services-hero__practices-line {
  position: absolute;
  left: 721px;
  top: 0;
  width: 1px;
  height: 928px;
  background-color: var(--grey-15);
}

/* Фікс (глибока діагностика, десктоп ≥1280px, поширено на Tablet
   Landscape 1024–1279px) — природна, а не штучно обрізана довжина
   строука. js/services-practices.js (isDesktopWidth, тепер ≥1024)
   переносить .line ВСЕРЕДИНУ .list — звідти строук рухається тим самим
   transform, що текст практик, і кліпається природним overflow:hidden
   на .window, а не власним фіксованим top/height (попередній фікс:
   top:128/height:800 — технічно ховало зайве, але виглядало як штучний
   обрив, а не природне зникнення за краєм вікна). Той самий принцип, що
   border .services-table на index.html — вертикальний строук ТАМ є
   частиною скрольованого контенту, тому фізично не може виступати за
   межі вікна незалежно від fade. left:0/top:0/bottom:0 (не height:100%
   — .list має auto-висоту від контенту, height:100% на absolute-дитині
   не resolve'иться від auto-висоти predка; top+bottom без height
   коректно розтягується від РЕЗОЛВНУТОЇ auto-висоти .list). Правило
   саморегулюється під ширину вікна на будь-якому breakpoint (left:0/
   top:0/bottom:0 без хардкод-px), тому спільне для десктопа, Landscape й
   Tablet Portrait (768–1023px, Крок 172) */
@media (min-width: 768px) {
  .services-hero__practices-list > .services-hero__practices-line {
    left: 0;
    top: 0;
    bottom: 0;
    height: auto;
  }
}

/* No-JS/до-виконання-JS фолбек: доки скрипт (defer) ще не переніс .line
   всередину .list, вона лишається сиблінгом .window зі старих координат
   (.sticky) — межі .window РІЗНІ на десктопі (128/800) і Tablet Landscape
   (208/800, .services-hero__practices-sticky{padding-top:208px} вище),
   тому два окремі блоки замість спільного ≥1024px */
@media (min-width: 1280px) {
  .services-hero__practices-sticky > .services-hero__practices-line {
    top: 128px;
    height: 800px;
  }
}

@media (min-width: 1024px) and (max-width: 1279px) {
  .services-hero__practices-sticky > .services-hero__practices-line {
    top: 208px;
    height: 800px;
  }
}

/* Той самий no-JS/до-виконання-JS фолбек, поширений на Tablet Portrait
   (768–1023px, Крок 172): межі .window тут 100/920 (не 128/800 чи
   208/800) — окремий блок, а не спільний з рештою */
@media (min-width: 768px) and (max-width: 1023px) {
  .services-hero__practices-sticky > .services-hero__practices-line {
    top: 100px;
    height: 920px;
  }
}

/* Фікс (десктоп ≥1280px, глибока діагностика) — top/bottom fade-маски
   над табличкою практик, тепер 1:1 з index.html
   (.services-table-window__fade--top/--bottom, styles.css:1903): ДІТИ
   .services-hero__practices-window (не .sticky), ПІСЛЯ .list — той
   самий "усередині вікна, overflow:hidden на .window кліпає їх до
   450×800, звичайний DOM-порядок стекує їх поверх .list і .line" підхід
   (.line тепер теж всередині тих самих меж вікна, вище). Попередня
   версія (окремий сиблінг .window/.line всередині .sticky) була
   ЗАВЖДИ в тому самому stacking-контексті, що й .line — це НЕ був
   z-index/stacking-context баг — просто overlay покривав не ту зону
   (top:128, а не 0, лишаючи непокритим верх лінії над вікном; фікс
   вище прибирає саму причину, роблячи цю зону взагалі порожньою).
   height:120px (було 96) — той самий, що index.html. is-visible/
   is-hidden керуються js/services-practices.js, той самий тригер, що
   js/services-table.js (activeIndex>=1 / progress>=1) — замінює
   попередній IntersectionObserver-based .services-hero__scroll-gradient
   (видалено), який був ЄДИНОРАЗОВИМ тригером на видимість строука Кроку 79
   і, будучи звичайним (non-sticky) сиблінгом .services-hero__practices-sticky,
   фізично скролився геть з екрана вже за кілька кадрів пінінгу — звідси
   й "градієнт з'являється лише під час активного скролу" (п.5 ТЗ) */
.services-hero__practices-window__fade {
  display: none;
}

/* Поширено з десктопа на Tablet Landscape (1024–1279px) і Tablet Portrait
   (768–1023px) — той самий фікс, той самий підхід (left:0/right:0
   саморегулюється під ширину .window на будь-якому breakpoint,
   height:120px незалежно від ширини) */
@media (min-width: 768px) {
  .services-hero__practices-window__fade {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    height: 120px;
    pointer-events: none;
    transition: opacity 300ms ease;
  }

  .services-hero__practices-window__fade--top {
    top: 0;
    background: linear-gradient(to bottom, var(--color-background), transparent);
    opacity: 0;
  }

  .services-hero__practices-window__fade--top.is-visible {
    opacity: 1;
  }

  .services-hero__practices-window__fade--bottom {
    bottom: 0;
    background: linear-gradient(to bottom, transparent, var(--color-background));
    opacity: 1;
  }

  .services-hero__practices-window__fade--bottom.is-hidden {
    opacity: 0;
  }
}

/* Айтем-блок практики. Текст (тайтл/тег/боді/боді2) відступає 20px від
   лівого краю вікна, щоб дійти рівно до колонки 6 (720+20=740) — фрейми
   сервісів нижче цей відступ НЕ мають, вони на всю ширину вікна (444px) */
.practice {
  position: relative;
  width: 444px;
}

.practice + .practice {
  margin-top: 140px;
}

/* Лівий градієнтний строук активної практики — той самий прийом, що
   .services-table__group::before на index.html (Services): псевдоелемент
   завжди в DOM з opacity:0 і transition саме на opacity (а не на
   присутність), бо "content" не анімується — інакше поява/зникнення була
   б миттєвою. .is-active перемикає js/services-practices.js (той самий
   practiceThresholds/progress, що вже рахує activeIndex ілюстрації) */
.practice::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--primary-grad-services);
  opacity: 0;
  transition: opacity .65s var(--ease-smooth);
}

.practice.is-active::before {
  opacity: 1;
}

.practice__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding-left: 20px;
}

.practice__title {
  color: var(--grey-100);
}

.practice__tag {
  color: var(--grey-50);
  text-transform: uppercase;
}

/* Фікс: рядок "where a design or data mistake has real consequences"
   природно переносився — виміряно headless Chrome (реальний
   dm-sans-light.woff2, 17px): текст 424.4px проти контейнера 424px,
   переносило на 2 рядки. +6px запасу на субпіксельні відмінності
   рендерингу між браузерами (той самий прийом, що вже в
   .industries__desc/Landscape-фіксі Product нижче) — .services-hero__
   practices-window росте на ті самі +6px (444→450), щоб текст і далі
   впритул бив у правий край вікна (bleed-принцип, без змін) */
.practice__body {
  margin-top: 24px;
  margin-left: 20px;
  width: 430px;
  color: var(--grey-60);
}

/* Ручний перенос боді-текстів практик (.practice__body) — Tablet
   Landscape (1024–1279px) переносить рядки в ІНШИХ точках, ніж
   десктоп (не просто звуження контейнера — інший розподіл слів),
   тому окремий набір break-класів, той самий tablet-break прийом, що
   вже в проєкті (напр. .industries__desc-break--portrait): --desktop
   видимий за замовчуванням (вимикається в медіа-запиті Landscape
   нижче), --tablet-landscape вимкнений за замовчуванням (вмикається
   там-таки). Де розрив збігається для обох breakpoint — два сусідні
   <br>, по одному на клас (не два класи на одному <br> — комбінування
   класів на одному елементі раніше конфліктувало в каскаді) */
.practice__body-break--tablet-landscape {
  display: none;
}

/* Tablet Portrait (768–1023px) — третій, ще інакший розподіл рядків
   (не Landscape й не десктоп) — той самий toggle-прийом, окремий клас,
   вимкнений за замовчуванням, вмикається в медіа-запиті Portrait нижче
   (де заразом вимикається --desktop, а --tablet-landscape й так уже
   лишається вимкненим за замовчуванням) */
.practice__body-break--tablet-portrait {
  display: none;
}

.practice__frames {
  margin-top: 36px;
}

.practice__frame {
  display: flex;
  align-items: center;
  width: 444px;
  height: 56px;
  border-bottom: 1px solid var(--grey-15);
}

.practice__frame-text {
  margin-left: 20px;
  color: var(--grey-100);
  text-transform: uppercase;
}

/* Секондарі боді-текст практики (де є) — тепер ПІСЛЯ .practice__frames
   (раніше між .practice__body і .practice__frames), відступ рахується від
   тексту ОСТАННЬОГО айтема: 73px до іконки star.svg (display:block —
   img інакше inline, margin-top не бере участі в block-flow-колапсі як
   слід) + 8px власна висота іконки + 3px від іконки до тексту (margin-
   top на .practice__body2, колапсує з нульовим margin-bottom іконки) */
/* Колір іконки — var(--grey-60), заданий не тут (CSS color на <img> не
   впливає на растеризований SVG-контент), а вже вшитий у сам файл:
   assets/images/star.svg використовує stroke="#B6B6B6" — це буквально
   те саме значення, що var(--grey-60) в tokens.css */
.practice__body2-icon {
  display: block;
  width: 8px;
  height: 8px;
  margin-top: 73px;
  margin-left: 20px;
}

.practice__body2 {
  margin-top: 3px;
  margin-left: 20px;
  width: 430px;
  color: var(--grey-55);
}

/* Operations — секондарі боді-текст на Tablet Landscape (1024–1279px) не
   просто інакше переноситься, а має ІНШИЙ текстовий контент, ніж десктоп
   (2 рядки замість 3) — тому не break-класи на <br>, а два окремі <p>
   (--desktop/--tablet-landscape), той самий toggle-прийом, лише на рівні
   цілого параграфа. Product/Brand — той самий текст на обох breakpoint,
   тому їхній --tablet-landscape <p> лише вимикає ручні <br> (природний
   перенос у межах 447px) — .practice__body2--desktop все одно ховається
   на цьому брейкпоінті нижче (styles.css), тому свій <p> потрібен і тут,
   інакше секондарі боді-текст зникає повністю (Фікс) */
.practice__body2--tablet-landscape {
  display: none;
}

/* Tablet Portrait (768–1023px) — Operations: той самий текст, що
   Landscape ("Ongoing partnership..."), але СВІЙ, третій розподіл
   рядків (3 замість 2) — тому окремий, третій <p>-варіант (той самий
   toggle-прийом, вимкнений за замовчуванням) */
.practice__body2--tablet-portrait {
  display: none;
}

/* Mobile (≤767px) — усі 5 боді/секондарі-боді отримали свій, окремий
   переписаний-на-нові-точки-розриву <p>-варіант (той самий "друга <p>"
   прийом, що вже в Operations' --tablet-landscape/--tablet-portrait
   вище) — оригінальний десктопний <p> (тепер позначений --desktop)
   ховається лише в Mobile медіа-запиті нижче, тут за замовчуванням
   лишається джерелом істини для десктопу/Tablet, як і раніше */
.practice__body--mobile,
.practice__body2--mobile {
  display: none;
}

/* -------------------------------------------------------------------------
   Крок 83 — "Our Commitments": заголовний блок, той самий патерн, що
   .about-approach/.how-we-work/.about-offices на about.html (спільні
   класи __grid/__label/__index/__title/__desc вище).

   margin-top:348px — НЕ буквальні "148px нижче ілюстрації". .our-commitments
   — звичайний сусід одразу після .services-hero__practices (тall-обгортка
   scrollytelling-списку, Крок 80), а її власна висота (928px sticky-панелі +
   scrollRange) визначає, де в ДОКУМЕНТІ починається цей сусід — це НЕ
   збігається з тим, де на екрані фактично закінчується ілюстрація (вона
   абсолютна, всередині sticky-панелі, і фізично звисає на 200px НИЖЧЕ
   власної 928px-висоти панелі: top:112 + height:1016 = 1128 > 928).
   Тому натуральний зазор (margin-top:0) між низом ілюстрації й цим блоком
   був би 928−1128 = −200px (перекриття!). 348px = 148px (потрібний зазор)
   − (−200px) компенсує це так, щоб ФАКТИЧНИЙ видимий зазор від низу
   ілюстрації дорівнював рівно 148px. Той самий принцип, що
   trustedBy.style.marginTop у js/services-table.js (index.html), але тут —
   фіксована CSS-константа, а не JS: і панель (928px), і ілюстрація (112+1016)
   в цьому кроці — фіксовані px, не залежні від висоти вікна браузера. */
.our-commitments {
  align-self: stretch;
  margin-top: 348px;
}

/* -------------------------------------------------------------------------
   Крок 84 — три ілюстрації-комітменти. grid-row:4 в тому самому
   .our-commitments__grid — "124px нижче боді" виходить природно (auto-row
   висотою рівно під desc, margin-top рахується від нього).

   Ліві краї ілюстрацій: 0, 388 (149+239), 776 (388+149+239) — не мапляться
   рівномірно на 8-колонкову сітку, тому явний flex+gap:239px замість
   grid-column. width:149px на .item (= ширина ілюстрації, flex-shrink:0) —
   тайтл (226px) і боді (356px) свідомо ширші за цю коробку й перетікають
   праворуч без обрізання (overflow не заданий), лишаючись притому
   "вирівняними по лівому краю ілюстрації", бо це прямі діти з тим самим
   left:0 */
.our-commitments__items {
  position: relative;
  grid-column: 1 / 9;
  grid-row: 4;
  margin-top: 124px;
  display: flex;
  gap: 239px;
}

.our-commitments__item {
  width: 149px;
  flex-shrink: 0;
}

.our-commitments__illustration {
  width: 149px;
  height: 86px;
  background-repeat: no-repeat;
  background-size: 149px 86px;
}

.our-commitments__illustration--1 {
  background-image: url("../assets/images/commitments-01.png");
}

.our-commitments__illustration--2 {
  background-image: url("../assets/images/commitments-02.png");
}

.our-commitments__illustration--3 {
  background-image: url("../assets/images/commitments-03.png");
}

.our-commitments__item-title {
  margin-top: 72px;
  width: 226px;
  color: var(--grey-100);
}

/* Фікс: "Decisions documented," саме на 0.375px ширша за 226px-box при
   dm-20-reg — цієї частки пікселя досить, щоб рядок природно переносився
   ЩЕ РАЗ перед примусовим <br>, даючи 3 рядки замість задуманих 2.
   nowrap лише на цьому сегменті (не на всьому .item-title — це зламало
   б природний перенос тайтлів 1/3) прибирає зайвий перенос */
.our-commitments__item-title-nowrap {
  white-space: nowrap;
}

/* Квадратик — той самий компонент, що .offices__marker (index.html) і
   .about-stats__marker (about.html): 5×5px var(--grey-15). Лишається
   у звичайному потоці (margin-top:15px від тайтла) — по одному на item,
   позиція кожного лишається незалежною від сусідніх колонок */
.our-commitments__item-marker {
  display: block;
  margin-top: 15px;
  width: 5px;
  height: 5px;
  background-color: var(--grey-15);
}

/* Фікс: один суцільний строук на всю ширину (принцип .offices__line/
   .about-stats__line — окремий absolute-елемент, а не по одному
   короткому сегменту на item, що раніше лишало 32px розрив між
   колонками). left:0/width:1132px виміряні по вже відрендерених
   квадратиках (усі 3 на одній висоті, item-left'и 0/388/776 + 356px
   ширина останнього сегмента = 1132px, Крок 84) — .our-commitments__items
   тепер має position:relative для цього.

   Фікс top: 269px був виміряний, поки .our-commitments__item ще мав
   активний scroll-reveal-up transform:translateY(40px) (лінія — окремий
   елемент без scroll-reveal, тому міряти по маркеру треба ПІСЛЯ
   .is-visible, коли translateY знімається). Реальна (post-reveal)
   позиція квадратика: top:229px/height:5px (останній піксель знизу —
   рядок 233-234px). Фікс: лінія проходить не по центру (231px), а по
   нижньому краю квадратика — top:233px, щоб останній піксель лінії
   (height:1px) збігався з останнім пікселем квадратика знизу */
.our-commitments__line {
  position: absolute;
  top: 233px;
  left: 0;
  width: 1132px;
  height: 1px;
  background-color: var(--grey-15);
}

/* margin-top:25px (було 24px, коли проміжок марker→body складався з
   марkera + 1px .item-line у потоці + 24px margin) — тепер .item-line
   прибрано з потоку (Фікс, лінія тепер absolute-оверлей), тому цей 1px
   компенсується прямо тут, щоб проміжок лишився тим самим 25px */
.our-commitments__item-body {
  margin-top: 25px;
  width: 356px;
  color: var(--grey-50);
}

/* Планшетні ручні переноси боді-тексту (Крок 151) розбивають рядки в
   інших точках, ніж десктопні, — за замовчуванням вимкнені, той самий
   tablet-break прийом, що в Our Approach/Offices (about.html) */
.our-commitments__item-body-break--tablet {
  display: none;
}

/* Ручні переноси боді-тексту секції (.our-commitments__desc, не окремого
   item'а) на Tablet Portrait — за замовчуванням вимкнені, той самий
   tablet-break прийом, що вище */
.our-commitments__desc-break--portrait {
  display: none;
}

/* -------------------------------------------------------------------------
   Крок 85 — Industries на services.html: та сама секція, що на index.html
   (.industries/.industry-row/js/industries-globe.js — усе перевикористано
   1:1, без змін розмітки/CSS/JS). Тільки 2 модифікатори нижче, що
   override'ять .industries/.industries__title для ЦЬОГО конкретного
   використання (класи спільні для обох сторінок, тому властивості, що
   мають відрізнятись, винесені в окремі --services-модифікатори з
   ідентичним селектором-специфічністю, розташовані ПІСЛЯ базових правил
   вище — каскад віддає перевагу їм, index.html не зачеплено)
   ------------------------------------------------------------------------- */

/* 180px нижче останнього боді тексту трьох комітментів (Крок 84) —
   .industries тут звичайний сусід одразу після .services-hero, і оскільки
   .our-commitments__items — останній вміст у ньому (нормальний потік,
   без scrollytelling-трюків), .services-hero сам природно закінчується
   рівно на нижньому краю найвищого item'а (Крок 84) */
.industries--services {
  margin-top: 180px;
}

/* Прибирає фіксовану 429px-ширину базового .industries__title (index.html) —
   тут тайтл на всю ширину колонок 1–5 (720px, природний grid-column:1/6) */
.industries__title--services {
  width: auto;
}

/* -------------------------------------------------------------------------
   Крок 86 — заголовний блок FAQ: той самий патерн, що .our-commitments/
   .about-approach/.how-we-work, але без боді — 156px нижче .industries
   (звичайний сусід, .industries не має жодного overflow/absolute-звису
   за межі власного box, тому margin-top тут напряму дає потрібний зазор,
   без JS-компенсації, як у Кроці 83)
   ------------------------------------------------------------------------- */
.faq {
  margin-top: 156px;
}

/* -------------------------------------------------------------------------
   Крок 87 — FAQ-акордеон.

   grid-column:5/9 = колонки 5–8 (572px, до кінця сітки 1164) — той самий
   механізм, що .industries__desc/.our-commitments__desc (grid-column,
   margin-top від row2-тайтла), лише інша колонка/значення відступу.
   ------------------------------------------------------------------------- */
.faq__list {
  grid-column: 5 / 9;
  grid-row: 3;
  margin-top: 20px;
}

.faq-item {
  position: relative;
}

/* 24px від строука попереднього айтема (його останній дочірній елемент)
   до тайтла наступного — звичайний потік сам рахує це від ФАКТИЧНОГО
   низу строука, який зсувається вниз, коли попередній айтем розгорнутий */
.faq-item + .faq-item {
  margin-top: 24px;
}

/* Кнопка на всю зону рядка (тайтл+іконка) — скидання дефолтних стилів
   button, клік у будь-якій точці рядка перемикає стан (js/faq-accordion.js) */
.faq-item__row {
  display: flex;
  align-items: flex-start;
  width: 572px;
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* Крок 127: dim-ефект за принципом Industries (Крок 124) — базовий стан
   (жоден айтем не розкритий) grey-60; коли розкритий БУДЬ-ЯКИЙ айтем,
   :has() на .faq__list дим-ить тайтли ВСІХ НЕ розкритих айтемів до
   grey-50 (працює однаково і при кількох одночасно розкритих айтемах —
   акордеон не ексклюзивний, Крок 87) */
.faq-item__title {
  width: 536px;
  color: var(--grey-60);
  transition: color 200ms ease;
}

.faq-item.is-expanded .faq-item__title {
  color: var(--grey-100);
}

.faq__list:has(.faq-item.is-expanded) .faq-item:not(.is-expanded) .faq-item__title {
  color: var(--grey-50);
}

/* margin-left:24 + width:12 = 536+24+12 = 572px = ширина .faq-item__row.
   margin-top:8 — іконка на 8px нижче верхнього краю тайтла (обидва
   стартують з одного row-top через align-items:flex-start) */
.faq-item__icon {
  margin-left: 24px;
  margin-top: 8px;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
}

/* Максимальна анімована висота підставляється інлайново з JS
   (scrollHeight боді-тексту) — max-height:0 + overflow:hidden замість
   display:none, бо display не анімується; візуально нерозрізнимо
   (0 висоти = невидимо, місця не займає). Це вже РЕАЛЬНИЙ scrollHeight,
   не довільне велике фіксоване значення — тому класичний "стрибок"
   наприкінці переходу тут не застосовний (grid-template-rows: 0fr/1fr
   не потрібен, ризик заміни механізму не виправданий). Фікс: 600ms
   (було 400ms, до того 280ms) + var(--ease-smooth) на ОБОХ властивостях
   (opacity раніше мала звичайний ease, 300ms) — той самий easing, що
   .scroll-reveal по всьому сайту, відчувається менш різким і встигає
   синхронно завершитись із паралельним доскролом (js/faq-accordion.js),
   симетрично в обидва боки (та сама transition для expand і collapse) */
.faq-item__body-wrap {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height 600ms var(--ease-smooth),
              opacity 450ms var(--ease-smooth);
}

/* Фікс: без цього текст під час розгортання/згортання "вискакував"/
   зникав миттєво в момент, коли max-height його розкривала/ховала —
   opacity-transition (коротша за max-height, 450ms проти 600ms) робить
   появу/зникнення самого тексту плавним, синхронним із розкриттям
   висоти, а не різким стрибком у кінці/на початку переходу */
.faq-item.is-expanded .faq-item__body-wrap {
  opacity: 1;
}

.faq-item__body {
  margin-top: 12px;
  /* Фікс: 536px (успадковане від .faq-item__title) звужувало кілька
     заданих <br>-рядків на Десктопі — найдовший (Айтем 5) виміряно
     543.31px, ще кілька рядків (Айтеми 1/2/6) також перевищували
     536px, тому останнє слово автопереносилось на новий рядок попри
     відсутність зайвого <br>. 552px — найкоротша "кругла" ширина, що
     вміщує НАЙДОВШИЙ виміряний рядок з запасом (доступний простір під
     колонку — 572px, .faq-item__row, тому 552px нічого не ламає) */
  width: 552px;
  color: var(--grey-60);
}

/* Планшетний ручний перенос тайтла — за замовчуванням вимкнений, той
   самий tablet-break прийом, що в Our Commitments/Our Approach/Offices.
   Боді-текст десктопної <p> (.faq-item__body--desktop) більше не несе
   ручних <br> (Фікс) — переноситься природно (word-wrap) у межах
   536px; планшет/портрет/мобайл лишаються окремими переписаними <p> */
.faq-item__title-break--tablet {
  display: none;
}

.faq-item__body--tablet {
  display: none;
}

/* Tablet Portrait (768–1023px) — той самий "окрема <p> з переписаним
   текстом" прийом, що вище (Айтем 4/--tablet), тепер на всіх 6 айтемах
   (боді-текст переписаний, не просто перенесений) + один новий тайтл-
   розрив (Айтем 1, інша точка, ніж --tablet). За замовчуванням вимкнені */
.faq-item__title-break--portrait,
.faq-item__body--portrait {
  display: none;
}

/* Mobile (≤767px) — свій, четвертий розподіл рядків тайтла (інший, ніж
   --tablet/--portrait) + окремий переписаний-на-природний-перенос
   боді-варіант (той самий "друга <p>" прийом) — за замовчуванням
   вимкнені */
.faq-item__title-break--mobile,
.faq-item__body--mobile {
  display: none;
}

/* Строук — завжди 23px нижче ТОГО, що зараз рендериться перед ним:
   у згорнутому стані .body-wrap висотою 0, тому 23px рахуються від
   низу рядка (тайтл+іконка); у розгорнутому .body-wrap реальної
   висоти (padding-top:12 + текст), тому ті самі 23px виходять від
   низу боді-тексту — той самий margin-top справляється з обома
   станами сам, без окремих правил на кожен */
/* width:572px — не 527 (ширина тайтла/боді), а на всю ширину .faq__list
   (colonки 5–8, до 1164px, правого краю сітки) */
.faq-item__stroke {
  display: block;
  margin-top: 23px;
  width: 572px;
  height: 1px;
  background-color: var(--grey-15);
}

/* Фікс — без строука під ОСТАННІМ FAQ-айтемом (6-м), усі breakpoint
   (спершу лише десктоп, тепер поширено на Tablet Landscape/Portrait/
   Mobile). .faq__list містить лише .faq-item (без декоративних
   сиблінгів після останнього, на відміну від Leadership-треку), тому
   просте :last-child надійне тут — не потрібен :not(:has(~ .faq-item))
   трюк. Unconditional (не в @media) — вища специфічність (0,2,0) за
   ЖОДЕН з breakpoint-специфічних .faq-item__stroke{width} оверрайдів
   (0,1,0) гарантує, що display:none виграє на всіх чотирьох */
.faq-item:last-child .faq-item__stroke {
  display: none;
}

/* 140px від останнього FAQ-айтема до CTA-2 — той самий прийом
   суміжного селектора, що .work-hero + .cta--second (Крок 47) */
.faq + .cta--second {
  margin-top: 140px;
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 132: сітка, хедер, hero (Home)

   Навмисно вужчий діапазон, ніж загальний "Tablet 768–1280" з коментаря
   у tokens.css — 768–1023px буде окремим кроком. Хедер тут спільний
   для всіх сторінок (як і в десктопі), .hero-правила де-факто діють
   лише на index.html — розмітка з класом .hero є тільки там.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Сітка: 8 колонок × 96px + 7 gutter × 20px = 908px, center, offset 0 */
  .grid-overlay__row {
    max-width: 908px;
    grid-template-columns: repeat(8, 96px);
    gap: 20px;
  }

  /* Хедер — та сама структура/логіка станів, що в десктопі (styles вище),
     тут лише нові розміри під ширину сітки 908px. .header__divider
     покриває обидва роздільники (біля лого й перед CONTACT) — спільний клас */
  .header {
    width: 908px;
    height: 52px;
    top: 20px;
    padding: 14px;
  }

  .header__brand,
  .header__divider {
    height: 52px;
  }

  .header__brand {
    margin-left: -14px;
    padding-left: 14px;
  }

  .header__logo {
    width: 24px;
    height: 24px;
  }

  /* Роздільник → перший пункт навігації: 40px (46px у десктопі) */
  .header__nav {
    margin-left: 40px;
  }

  /* Текст навігації — dm-14-reg замість dm-16-reg із розмітки
     (gap МІЖ пунктами — .header__nav-list, лишається без змін) */
  .header__nav-text {
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: порядковий номер (Home/Work/Services/About) мав бути вирівняний
     по ВЕРХньому краю тексту айтема — успадкований з десктопу top:4.5px
     (зсув униз від верху слова) на тутешньому меншому dm-14 тексті читався
     як вирівнювання по НИЖньому краю. top:-8px — верхній край номера на
     8px вище верхнього краю слова (еквівалентно 8px нижче верхнього краю
     хедера: хедер вирівнює вміст по вертикальному центру, 52px height,
     text line-height:20px тут → верх слова ≈16px від верху хедера) */
  .header__nav-num {
    top: -8px;
  }

  /* Hero — вертикальна позиція контенту: 250px/240px від верху/низу при
     референсній висоті в'юпорта 768px (Крок 132, як і планувалось
     спочатку), у % від .hero (яка сама 100vh/100svh) — той самий прийом,
     що в десктопі, тому відступи пропорційно масштабуються при зміні
     висоти вікна (250/768 і 240/768). Фікс: попередній фікс помилково
     перевів референс на 1080px (23.1481%/21.4815%) — правильний
     референс завжди був 768px; bottom тепер також уточнено на 240px
     (було 232px) */
  .hero__spacer--top {
    height: 32.5521%;
  }

  .hero__spacer--bottom {
    height: 31.25%;
  }

  /* Hero — фон: той самий "переливання в наступну секцію" принцип, що в
     десктопі (height:135%/135vh) — тут з новим tablet-landscape ассетом
     (1440×810) і коефіцієнтом k = 810/768 ≈ 1.0547 (референсний вʼюпорт
     768px заввишки → фон 810px). height:105.47% (від .hero, самої
     100vh/100svh) і background-size:105.47vh — те саме число, тому
     збігаються піксель у піксель (той самий прийом, що 135%/135vh
     у десктопі), решта (105.47vh − 100vh) виходить за низ .hero
     (overflow:visible, успадковано з бази) і лягає під Services */
  .hero__bg {
    height: 105.47%;
    background-position: center top;
    background-size: auto calc(105.47vh);
    background-image: url("../assets/images/hero-bg-tablet-landscape.webp");
    background-image: image-set(
      url("../assets/images/hero-bg-tablet-landscape.webp") 1x,
      url("../assets/images/hero-bg-tablet-landscape@2x.webp") 2x
    );
  }

  /* Фікс: висота CTA-кнопки в хедері дорівнювала десктопним 60px
     (20px паддінг + 20px line-height тексту + 20px паддінг), хоча
     хедер уже 52px (Крок 132) — кнопка виступала за межі хедера.
     Горизонтальні паддінги (32px) без змін, вертикальні перераховані
     під нову висоту: (52 − 20 line-height) / 2 = 16px.
     Фікс (наступний крок): ширина тепер фіксована 128px (не "як у
     десктопі" — те попереднє формулювання й було помилкою), права межа
     кнопки — рівно край сітки/хедера (908px, 0px зазору, той самий
     принцип, що в .header__brand для лого): margin-right:-14px точно
     компенсує РЕАЛЬНИЙ padding-right хедера (14px, Крок 132) — десктопне
     -16px більше йому не відповідає (14−16=-2px overshoot). Це замінює
     собою окремий scrolled-only "15px зазор" з попереднього фіксу —
     зазор прибрано за прямим запитом (флаш до краю в усіх станах) */
  .header__contact-link {
    width: 128px;
    padding-top: 16px;
    padding-bottom: 16px;
    margin-right: -14px;
  }

  /* Відступи scrolled-стану хедера (лого/роздільник/іконка меню) —
     15px з усіх країв (було 14/16/19). margin-left на .header__brand
     лишається -14px (структурний трюк: рівно компенсує РЕАЛЬНИЙ
     padding-left хедера 14px, Крок 132, — не чіпаємо, інакше бокс
     вилізе за межу), тому "лого-до-краю" міняємо лише через ВЛАСНИЙ
     padding-left боксу (14→15) */
  .header--scrolled .header__brand {
    padding-left: 15px;
  }

  /* Лого → роздільник: 16px у десктопі → 15px. Скоуп через .header__brand
     обов'язковий: .header__divider — спільний клас з другим роздільником
     (.header__divider--contact, поза .header__brand, тримається на
     margin-left: auto для притискання Contact праворуч) — без цього
     скоупу правило зачепило б і auto-margin, ламаючи вирівнювання кнопки */
  .header--scrolled .header__brand .header__divider {
    margin-left: 15px;
  }

  /* Роздільник → іконка меню: 19px у десктопі → 15px (width/opacity/
     pointer-events лишаються з базового десктопного правила, тут
     перевизначається лише сам відступ) */
  .header--scrolled .header__menu-btn {
    margin-left: 15px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 133: секція Services (Home)

   Номер "I.", боді-текст і табличка зсуваються на колонку 5 (замість 6)
   нової 8-колонкової сітки 96px/908px (Крок 132). Ілюстрацію-квітку тут
   спершу навмисно не займали — додана нижче окремим фіксом.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від нижнього краю Hero до верху лейбла/номера "I.": 80px
     (194px у десктопі) */
  .services__intro {
    padding-top: 80px;
  }

  /* Обидва класи унікальні для Services — на відміну від
     .services__index/__desc нижче, тут нема спільного списку селекторів
     з іншими секціями, тому перевизначення безпечне саме по собі */
  .services__intro-grid,
  .services__panel-grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки (4×96 + 4×20) — і номер "I.",
     і боді-текст тепер починаються тут (замість колонки 6 у десктопі) */
  .services__index {
    grid-column: 5;
  }

  .services__desc {
    grid-column: 5 / 9;
  }

  /* Табличка лишається на тій самій grid-column: 5 / 9, що й у десктопі —
     старт автоматично стає 464px при новій ширині колонки (96px). Але
     width — явний px (не auto-stretch по grid-колонці), тому 444px
     (4×96 + 3×20) треба перевизначити окремо. Відступ від боді-тексту:
     104px (119px у десктопі). height: 720px — фолбек (як і 844px у
     десктопі): js/services-table.js підставляє точне значення й сам
     вибирає межу 720/844 за шириною вʼюпорта (Крок 133) */
  .services-table-window {
    margin-top: 104px;
    width: 444px;
    height: 720px;
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — 880×880px
     (0.8661 від десктопних 1016px), той самий рotate/mask/tag-механізм,
     що на десктопі (js/services-illustration.js тут не чіпається). Той
     самий grid-row:1/margin-top прийом позиціонування, що в десктопі —
     margin-top:24px (фікс: замінює попередні 130px) — відступ від
     боді-тексту секції (.services__desc, той самий рядок/панель, що й
     .services-table-window нижче) до верху ілюстрації. Горизонталь:
     правий край на 60px лівіше лівого краю таблички (464px, колонка 5)
     → margin-left = 464 − 60 − 880 = −476px */
  .services__illustration-stack {
    width: 880px;
    height: 880px;
    margin-top: 24px;
    margin-left: -476px;
  }

  .services__illustration-base,
  .services__illustration-mask {
    width: 880px;
    height: 880px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 134: секція Trusted By (Home)

   Той самий принцип, що в Кроках 132/133: сітка 96px/908px, номер
   зсувається на колонку 5. Клітинка логотипа = розмір логотипа = 96px
   (без внутрішнього паддінгу, як і в десктопі). .trusted-by__lines —
   той самий оверлей з 27 суцільних шарів (background-image не змінюється,
   лише перерахований background-size/position під нову геометрію:
   908px ширина групи, 212px висота (2×96 + gutter 20), колонки/гаттери
   на 116px кроці (96 + 20) замість 148px (128 + 20) у десктопі).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Унікальний для Trusted By клас — безпечно перевизначити самостійно */
  .trusted-by__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки — той самий старт, що й
     у номера Services (Крок 133) */
  .trusted-by__index {
    grid-column: 5;
  }

  .trusted-by__logos {
    grid-template-columns: repeat(8, 96px);
    grid-template-rows: repeat(2, 96px);
  }

  .trusted-by__logo-cell,
  .trusted-by__logo {
    width: 96px;
    height: 96px;
  }

  /* 16 вертикальних (висота групи 212px) + 3 горизонтальні на всю
     ширину (908px) + 8 горизонтальних сегментів (96px) під рядком 2 —
     та сама послідовність шарів, що в десктопі, перерахована на
     колонку 96px/гаттер 20px/крок 116px */
  .trusted-by__lines {
    background-size:
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      1px 212px,
      908px 1px,
      908px 1px,
      908px 1px,
      96px 1px,
      96px 1px,
      96px 1px,
      96px 1px,
      96px 1px,
      96px 1px,
      96px 1px,
      96px 1px;
    background-position:
      0px 0,
      96px 0,
      116px 0,
      212px 0,
      232px 0,
      328px 0,
      348px 0,
      444px 0,
      464px 0,
      560px 0,
      580px 0,
      676px 0,
      696px 0,
      792px 0,
      812px 0,
      right 0px top 0,
      0 0px,
      0 96px,
      left 0 bottom 0px,
      0px 116px,
      116px 116px,
      232px 116px,
      348px 116px,
      464px 116px,
      580px 116px,
      696px 116px,
      812px 116px;
  }

  /* Фікс: 80px від нижнього краю ілюстрації Services до верху Trusted By —
     тепер лише CSS-фолбек (якщо JS не відпрацював). js/services-table.js
     тепер рахує й ТУТ реальний inline marginTop динамічно (formula
     компенсує звис ілюстрації за межу 100vh-панелі — фіксоване число тут
     давало РЕАЛЬНИЙ відступ менший за заявлений). about.html екранований
     власним специфічнішим .about-hero + .trusted-by (Крок 146) —
     значення тут його не зачіпає */
  .trusted-by {
    margin-top: 80px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 135: секція Selected Work (Home)

   work.html (сторінка Work) перевикористовує ці самі класи карток/патернів/
   .selected-work__cards/.selected-work__row2 (Крок 46/131) — тому всі
   спільні класи тут навмисно скоуплені під предком .selected-work
   (є лише в index.html; work.html обгортає ті самі елементи в .work-hero),
   щоб НЕ зачепити ще не зверстану планшетну версію сторінки Work.
   .selected-work__grid/__index/__desc/__row3 унікальні лише для index.html,
   тому лишаються без скоупу, як і в Кроках 133/134.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу Trusted By до верху лейбла/номера Selected Work: 160px
     (206px у десктопі) */
  .selected-work {
    margin-top: 160px;
  }

  .selected-work__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Фікс: лейбл успадковував grid-column:1 (одна колонка, 96px) зі
     спільного правила (рядок ~1385) — "SELECTED WORK" туди не влазить і
     переносився на 2 рядки. На всю ширину сітки (1/9, 908px), той самий
     фікс, що .about-approach__label/.how-we-work__label */
  .selected-work__label {
    grid-column: 1 / 9;
  }

  /* Колонка 5 = 464px від лівого краю сітки — той самий старт, що й номер/
     боді-текст у Services (Крок 133) і Trusted By (Крок 134) */
  .selected-work__index {
    grid-column: 5;
  }

  .selected-work__desc {
    grid-column: 5 / 9;
  }

  /* Відступ від низу боді-тексту до верху першого рядка айтемів: 64px
     (96px у десктопі) */
  .selected-work .selected-work__cards {
    margin-top: 64px;
  }

  /* Великий айтем — 5 колонок: 5×96 + 4×20 = 560px (720px у десктопі).
     Маленький айтем — 3 колонки: 3×96 + 2×20 = 328px (424px у десктопі).
     Внутрішня верстка карток (превʼю/тайтл/теги/hover) — без змін,
     тут міняється лише ширина контейнера */
  .selected-work .work-card--primary {
    width: 560px;
  }

  .selected-work .work-card--secondary {
    width: 328px;
  }

  /* Фікс: фото успадковувало десктопну фіксовану height (565/332px) —
     разом із новою вужчою шириною картки (560/328) це спотворювало
     пропорцію фото (об'єкт лишається cover, тому просто обрізався б
     інакше, а не спотворювався, але з неправильним співвідношенням
     сторін). height: auto знімає десктопний хардкод, aspect-ratio
     задає правильну пропорцію (та сама 1.277:1, що на десктопі,
     560:438 і 328:257) — object-fit: cover з базового правила лишається
     без змін, просто тепер обрізає під коректний aspect-ratio */
  .selected-work .work-card--primary .work-card__image {
    aspect-ratio: 560 / 438;
    height: auto;
  }

  .selected-work .work-card--secondary .work-card__image {
    aspect-ratio: 328 / 257;
    height: auto;
  }

  .selected-work .selected-work__col-secondary {
    width: 328px;
  }

  /* Патерн-заповнювач ряду 1 (під малою карткою), вирівнюється по нижньому
     краю великого айтема — той самий принцип, що в десктопі (height =
     велика картка − мала картка − 20px margin-top), але з новими
     розмірами фото (Фікс пропорцій фото): великий айтем 36+438+122+30=
     626px, малий 36+257+122+30=445px → 626−445−20=161px (було 213px
     на десктопних 753/520) */
  .selected-work .selected-work__strokes {
    width: 328px;
    height: 161px;
  }

  /* Коли вся друга картка ряду 1 прихована — патерн поглинає всю колонку,
     тому дорівнює повній висоті великого айтема (626px, було 753px) */
  .selected-work .selected-work__strokes--full {
    height: 626px;
  }

  /* Ряд 2: патерн (2 колонки основної сітки + 1 gutter = 2×96 + 20 = 212px,
     той самий принцип, що й 276px у десктопі) → картка 328 → картка 328 —
     212+20+328+20+328 = 908 (уся сітка), той самий баланс, що в десктопі */
  .selected-work .selected-work__row2 {
    margin-top: 32px;
  }

  /* Ряд 2 — лише малі айтеми, патерн вирівнюється по їхньому нижньому
     краю: дорівнює повній висоті малого айтема (445px, було 520px на
     десктопі, з тими самими 424→328/332→257 змінами, що й у Фіксі фото).
     --wide (нижче) успадковує цю ж height — там міняється лише width */
  .selected-work .selected-work__pattern {
    width: 212px;
    height: 445px;
  }

  /* Коли лишається лише один малий айтем ряду — патерн поглинає колонку
     відсутнього: 212 + 20 + 328 = 560px (= ширина великого айтема,
     той самий збіг, що й 720px у десктопі) */
  .selected-work .selected-work__pattern--wide {
    width: 560px;
  }

  /* Ряд 3: та сама відстань між рядками, що й ряд 2 (32px замість 48px) */
  .selected-work__row3 {
    margin-top: 32px;
  }

  /* SEE ALL OUR WORK — той самий розмір "малого айтема" (328px), і той
     самий принцип вирівнювання по нижньому краю айтемів свого рядка:
     445px (висота малого айтема), а не десктопні 520px */
  .selected-work .see-all-work {
    width: 328px;
    height: 445px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 136: секція CTA з китом (Home)

   .cta (bare-клас) перевикористовується про і на інших сторінках
   (about/contact/services/work — там своя окрема секція перед ним, не
   .selected-work), тому скоуп через суміжний селектор .selected-work + .cta —
   той самий прийом, що вже є в коді для .work-hero + .cta--second /
   .about-hero + .trusted-by. Матчиться лише на index.html.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .selected-work + .cta {
    /* 80px від низу останнього айтема робіт до верху фону секції —
       на відміну від десктопу (margin-top:0, фон впритул) */
    margin-top: 80px;

    /* 166px від низу останнього айтема робіт до тайтла/кнопки: рахується
       від верху СЕКЦІЇ (яка вже зсунута на 80px через margin-top вище),
       тому тут 166 − 80 = 86px, а не 166px напряму */
    padding-top: 86px;

    /* height — не в списку п.2 дослівно, але той самий принцип, що в
       десктопі: контейнер точно дорівнює висоті фону (1020 там, 765
       тут), інакше під зображенням лишався б порожній хвіст фону секції */
    height: 765px;

    /* Той самий кит, той самий "fixed, no scale" принцип і вирівнювання
       (center top, no-repeat, не перевизначені — успадковані з базового
       правила), просто менший фіксований розмір під планшет.
       Пропорція та сама (1920:1020 = 1440:765 = 1.882) — новий файл не
       потрібен, той самий whale-bg.webp/@2x через існуючий image-set */
    background-size: 1440px 765px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 137: секція Industries (Home)

   .industries/.industry-row/.industries__list/.industries__globe-stack
   тощо перевикористані 1:1 на services.html (Крок 85, там — модифікатор
   .industries--services) — тому все тут скоуплено через суміжний
   селектор .cta + .industries (той самий whale-CTA з Кроку 136, є лише
   на index.html одразу перед Industries) за тим самим принципом, що
   .selected-work + .cta/.work-hero + .cta--second. На services.html
   Industries іде одразу після .services-hero, тому цей селектор там
   ніколи не збігається.

   Ілюстрація-літера переїжджає з окремої лівої flex-колонки (64×122,
   у потоці) всередину фрейму (абсолютно, у правий верхній кут,
   40×50) — .industry-row__illustration (старі десктопні <img> без
   ретини) приховані на цьому брейкпоінті, замість них — два псевдо-
   елементи (::before/::after) на .industry-row__illustration-wrap із
   новими tablet-файлами через image-set, з тим самим opacity-кросфейдом
   (200ms ease 100ms), що на десктопі. Порядок рядків фіксований
   (F, H, E, C, P) — nth-child замість нових класів у розмітці.

   Висота фрейму (112px / 142px, 1 чи 2 рядки тегів) НІДЕ не хардкодиться:
   вона природно виходить з arithmetic 20(відступ тайтла)+34(рядок
   тайтла, rh-16-sb-lh)+12(gap)+22 або 52(теги, 1 чи 2 рядки по 22px
   з row-gap 8px)+24(запас до строука) = 112 / 142 — height:auto на
   .industry-row і робить цю формулу дизайну реальністю без JS.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* 6px від низу .cta__btn до верху номера Industries (465px за ТЗ) —
     вивірено арифметично: цільовий-зазор(465) + cta-padding-top(86) +
     "контент→низ кнопки"(220, той самий дизайнерський блок, що й на
     десктопі: 128 тайтл + 44 margin + 48 висота кнопки, без змін) −
     cta-height(765) = 6 */
  .cta + .industries {
    margin-top: 6px;
  }

  .cta + .industries .industries__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px — той самий старт, що й в інших секціях (Кроки 133–136) */
  .cta + .industries .industries__index {
    grid-column: 5;
  }

  .cta + .industries .industries__desc {
    grid-column: 5 / 9;
  }

  /* Список: тепер лише колонки 1–4 (444px = 4×96 + 3×20), а не 1–5
     (720px) — праву частину звільняє ілюстрація-літера, що переїхала
     всередину фрейму (п.6). 64px від боді-тексту до першого фрейму */
  .cta + .industries .industries__list {
    grid-column: 1 / 5;
    margin-top: 64px;
  }

  /* Глобус: 0px від боді-тексту (впритул, замість 6px), 534px від
     лівого краю сітки (444 + 90, замість 792px) */
  .cta + .industries .industries__globe-stack {
    margin-top: 0;
    margin-left: 534px;
  }

  /* Фрейм — висота більше не фіксована 122px: 24px запасу знизу до
     строука дає auto-висоті природно вийти на 112/142 (див. коментар
     вище блоку). Гортизонтальних відступів МІЖ фреймами й далі нема —
     той самий звичайний потік, що в десктопі, просто без фіксованої height */
  .cta + .industries .industry-row {
    height: auto;
    padding-bottom: 24px;
  }

  /* Контент — тепер на всю ширину фрейму (444px): десктопна flex-колонка
     ілюстрації звільнена (ілюстрація стала absolute, п. нижче), тому
     margin-left:32 (відступ від колишньої лівої колонки) прибирається.
     position:relative + z-index:1 — вище за ілюстрацію (z-index:0
     нижче), щоб текст лишався читабельним поверх неї */
  .cta + .industries .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 20px;
  }

  /* 12px від тайтлу до тегів (6px у десктопі). flex-wrap + row-gap:8px —
     перенос на другий рядок тегів, якщо не влазять у 444px */
  .cta + .industries .industry-row__tags {
    margin-top: 12px;
    flex-wrap: wrap;
    row-gap: 8px;
  }

  /* Фікс: Fintech (nth-child(1)) — сума ширин трьох тегів ("KYC
     Onboarding" • "Trading Platforms" • "Payment Flows") лежить впритул
     до 444px контейнера, тому природний flex-wrap ненадійно тримає
     "Payment Flows" на першому рядку. flex-basis:100% на останньому
     тезі форсує перенос на другий рядок незалежно від точної ширини —
     той самий прийом, що вже є для Cybersecurity/Proptech на Mobile */
  .cta + .industries .industry-row:nth-child(1) .industry-row__tags span:last-child {
    flex-basis: 100%;
  }

  /* Немає надійного hover на Tablet (дотик) — активний рядок керується
     скролом (js/industries-tablet-scrolly.js через .is-active), той
     самий dim/bright принцип, що вже реалізований на Mobile нижче:
     дефолт приглушений (grey-50), .is-active — повна яскравість */
  .cta + .industries .industry-row__title {
    color: var(--grey-50);
  }

  .cta + .industries .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .cta + .industries .industry-row__tags {
    color: var(--grey-50);
  }

  .cta + .industries .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .cta + .industries .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
  }

  .cta + .industries .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  /* Строук на всю ширину фрейму (0/0), а не інсет під колишню ілюстрацію
     (96px зліва, 52px справа в десктопі) — фрейми тепер розділені
     суцільною лінією на всю ширину */
  .cta + .industries .industry-row__divider {
    left: 0;
    right: 0;
  }

  /* Старі десктопні <img> (без ретини, окремі файли) — приховані,
     замість них tablet-псевдоелементи нижче */
  .cta + .industries .industry-row__illustration {
    display: none;
  }

  /* Ілюстрація-літера: з лівої flex-колонки (64×122, у потоці) —
     у правий верхній кут фрейму (40×50, absolute, 12px від верху,
     впритул до правого краю фрейму = правий край колонки 4) */
  .cta + .industries .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .cta + .industries .industry-row__illustration-wrap::before,
  .cta + .industries .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .cta + .industries .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .cta + .industries .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  /* Порядок рядків фіксований у розмітці: F, H, E, C, P — nth-child
     замість нових класів на .industry-row__illustration-wrap */
  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 138: секція Offices (Home)

   .offices (bare-клас) унікальний для index.html — about.html має власний
   окремий набір класів .about-offices__* (не перевикористовує ці),
   тому нічого скоупити через суміжний селектор тут не треба, на
   відміну від Кроків 135–137.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* ЦІЛЬ: 160px від низу ОСТАННЬОГО ФРЕЙМУ Industries (не від низу секції!).
     margin-top тут рахується від низу .industries, а це — вищий з двох
     grid-item рядка 4 (глобус чи список фреймів). На цьому брейкпоінті
     список (142+142+142+112+112=650px, margin-top:64 від боді-тексту)
     КОРОТШИЙ за глобус (786px, margin-top:0 — не чіпали в Кроці 137):
     низ глобуса = 0+786=786, низ списку = 64+650=714, різниця 786−714=72px.
     Пряме margin-top:160px дало б 160+72=232px від фрейму, а не 160.
     Компенсація: 160−72=88px */
  .offices {
    margin-top: 88px;
  }

  .offices__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px — той самий старт, що й в інших секціях (Кроки 133–137) */
  .offices__index {
    grid-column: 5;
  }

  .offices__desc {
    grid-column: 5 / 9;
  }

  /* Відступи між айтемами міст: London→New York 103px (173px у десктопі),
     New York→Kyiv 111px (Фікс: було 11px — замало, info-блок New York
     (276px) перекривав тайтл/інфо Kyiv; 197px у десктопі) — margin-left
     на кожному наступному айтемі, той самий механізм, що в десктопі,
     лише нові значення. Перевірено: London(166.4px реальна ширина
     тексту) + 103 + New York(203px) + 111 + Kyiv(89.1px) ≈ 672.5px —
     вміщується в 908px сітки з запасом, підганяти нічого не довелось */
  .offices__city--ny {
    margin-left: 103px;
  }

  .offices__city--kyiv {
    margin-left: 111px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 139: секція CTA-2 (Home)

   .cta--second перевикористовується на about/contact/services/work.html
   (кожен зі своїм відступом-сусідом: .work-hero + .cta--second,
   .faq + .cta--second) — тут те саме через .offices + .cta--second,
   бо на index.html Offices — секція одразу перед CTA-2. Матчиться
   лише на index.html.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .offices + .cta--second {
    /* Фікс: 120px від низу боді-тексту "London" до верху фону CTA-2
       (виміряно: 124px при 120px margin-top → 116px компенсує 4px
       різниці, той самий принцип, що на десктопі — London/New York/
       Kyiv в одному рядку, низ ідентичний) */
    margin-top: 116px;

    /* height дорівнює висоті фону (той самий принцип, що в Кроці 136) —
       624px, а не десктопні 832px */
    height: 624px;

    /* Фікс: 361px від верху фону до тайтла (502px на десктопі) */
    padding-top: 361px;

    /* Пропорція та сама, що на десктопі (1920:832 = 1440:624 = 2.308) —
       новий файл не потрібен, той самий cta2-bg.webp/@2x */
    background-size: 1440px 624px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 140: Footer (сайт-вайд, не лише index.html —
   .footer/.footer__grid/тощо ідентичні на всіх 5 сторінках, без жодної
   різниці чи модифікатора між ними, на відміну від Selected Work/CTA/
   Industries/Offices — тому тут нема кого/від кого скоупити суміжним
   селектором: зміна коректно й навмисно застосовується сайт-вайд)

   Фікс (наступний крок): vline1 більше не 531px (десктопне значення) —
   тепер явно задано 348px (лівий край колонки 4), геп між строуками
   лишається 186px (Крок 140): vline2=348+186=534, vline3=534+186=720.
   Перевірено: усе вміщується в 908px без перевищення (див. коментар
   під .footer__col--3 нижче) — на відміну від попередньої (531px)
   версії, де колонка 3 виходила за межі сітки на ~90px.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .footer__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Фікс: 348px — лівий край колонки 4 (3×96 + 3×20), замість
     успадкованих десктопних 531px */
  .footer__vline--1 {
    left: 348px;
  }

  /* Геп між строуками — 186px (Крок 140): vline2=348+186=534,
     vline3=534+186=720 */
  .footer__vline--2 {
    left: 534px;
  }

  .footer__vline--3 {
    left: 720px;
  }

  /* Контент колонки — той самий відступ 24px від свого строука, що в
     десктопі (без змін самого принципу, лише нова позиція строука).
     Фікс: .footer__col--1 (373px= vline1+24 не мала окремого правила
     й лишалась на десктопних 555px — майже збігалась із новим
     .footer__col--2 (558px), текст колонок 1/2 накладався один на
     одного */
  .footer__col--1 {
    left: 372px;
  }

  .footer__col--2 {
    left: 558px;
  }

  /* Перевірено: колонка 3 (744px) + найширший лейбл "INSTAGRAM"
     (~71.3px) = ~815.3px, вміщується в 908px сітки з запасом ~93px —
     на відміну від попередньої (vline1=531px) версії, де колонка 3
     виходила за межі сітки на ~90px */
  .footer__col--3 {
    left: 744px;
  }

  /* Фікс: патерн тягнеться від vline1 до правого краю сітки (той самий
     принцип, що в десктопі: 531+633=1164 — правий край тодішньої сітки).
     Попередній фікс перерахував лише width (560px = 908−348), але не
     left — той лишався на десктопних 531px, тому патерн починався не
     з того місця (531, а не 348). height/лінії/строуки — без змін */
  .footer__pattern {
    left: 348px;
    width: 560px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 141: Hero-секція (work.html)

   Хедер — без змін (спільний планшетний хедер, Кроки 132–133 + фікси).
   Текст/кнопки — 1:1 як у десктопі, без перевизначень. padding-top:170px
   уже фіксований (не пропорційний) і в десктопі (Крок 42), тому для
   планшета збігається сам собою — тут перевизначаються лише фон і
   min-height секції.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Той самий ассет (image-set 1x/2x), CSS-масштабування до 1440×675
     (пропорція та сама, що в десктопі: 1920:900 = 1440:675 = 2.133).
     background-position зсуває фон на 134px вниз від верху секції
     (замість "center top" у десктопі) — center лишається по горизонталі.
     min-height = 134 (зсув) + 675 (висота фону) = 809px, той самий
     принцип, що в десктопі (900 = 0 + 900), щоб фон не обрізався знизу
     секцією коротшою за суму зсуву й висоти */
  .work-hero {
    min-height: 809px;
  }

  .work-hero__image {
    background-position: center 134px;
    background-size: 1440px 675px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 142: список робіт (work.html)

   Логіка фільтрів/сортування/пошуку/каунтера/empty-стану/рядів — та сама,
   що в десктопі (JS не чіпається). Тут лише вирівнювання по сітці
   908px/center/offset 0 і нові розміри карток.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Фікс: тайтл "Work" з каунтером — той самий прийом, що .work-hero__filters-inner
     нижче: контейнер звужується з 1164px до 908px, лівий край тексту
     (margin:0 auto всередині align-self:stretch батька) зсувається до
     лівого краю сітки (0px), як і решта контенту work.html */
  .work-hero__list-heading-inner {
    max-width: 908px;
  }

  /* Ряд фільтрів: контейнер звужується з 1164px до 908px. Усі елементи
     позиціоновані в ньому через left/right у px (не %), тому просто
     звуження max-width автоматично зсуває лівий кластер (Services/
     vline1/Industries, left-anchored, значення не міняються) і правий
     кластер (Sort/vline2/Search, right-anchored, значення теж не
     міняються) ближче один до одного — і саме це стискає ЄДИНИЙ "гнучкий"
     проміжок (Industries → Sort). Усі інші відступи (Sort → vline2 = 42px,
     vline2 → Search = 20px, Services → vline1 → Industries) лишаються
     пікселево ідентичними десктопу, бо жодне з їхніх left/right-значень
     не перевизначається.
     Перевірено рендером (Playwright, getBoundingClientRect при 1100px
     вʼюпорті): ряд лягає точно 908px (services.left = inner.left,
     search.right = inner.right), проміжок Industries → Sort стискається
     до 167.08px (був 423.08px у 1164px-контейнері) — решта проміжків
     не зрушили. */
  .work-hero__filters-inner {
    max-width: 908px;
  }

  /* Search на десктопі — left:888px І right:0 одночасно (ширина визначена
     обома краями відносно 1164px-контейнера). Саме тому це єдиний елемент
     ряду, який не можна лишити "як є" при звуженні контейнера — старий
     left:888px майже впритул до нового правого краю (908px). Новий left
     рахується від нового vline2 (612px у 908px-контейнері) + той самий
     20px-відступ, що на десктопі (888 − 868 = 20): 612 + 20 = 632px.
     Ширина виходить та сама (908 − 632 = 276px, було 1164 − 888 = 276px) —
     значення підібрані так, щоб і ширина поля пошуку, і відступ до
     vline2 лишились ідентичними десктопу */
  .work-hero__filters-search {
    left: 632px;
  }

  /* Відступ від фільтрів до першого ряду карток: 64px (48px у десктопі) */
  .work-hero__row--1,
  .work-hero__row--3 {
    margin-top: 64px;
  }

  /* Ряд 2 перевикористовує .selected-work__row2 (спільний з index.html) —
     той самий 32px, що вже реалізовано для Selected Work на index.html
     (Крок 135), скоуплений під .work-hero, щоб не зачепити index.html */
  .work-hero .selected-work__row2 {
    margin-top: 32px;
  }

  /* Розміри карток — ті самі значення, що вже реалізовані для Selected
     Work на index.html у планшетній версії (Крок 135): велика картка
     560×438 (5 колонок), мала 328×257 (3 колонки), gutter 20px між
     картками в рядку (незмінний flex-gap), 32px між рядками (вище).
     Скоуплено під .work-hero, щоб не зачепити .selected-work на
     index.html (той самий прийом, що в коментарі над Кроком 135) */
  .work-hero .work-card--primary {
    width: 560px;
  }

  .work-hero .work-card--secondary {
    width: 328px;
  }

  .work-hero .work-card--primary .work-card__image {
    aspect-ratio: 560 / 438;
    height: auto;
  }

  .work-hero .work-card--secondary .work-card__image {
    aspect-ratio: 328 / 257;
    height: auto;
  }

  .work-hero .selected-work__col-secondary {
    width: 328px;
  }

  /* Патерн-заповнювач ряду 1 (під малою карткою) і ряду 3 (--full,
     поглинає всю колонку) — той самий принцип вирівнювання по нижньому
     краю карток свого рядка й ті самі розраховані значення, що на
     index.html (Крок 135): 626 (велика картка) − 445 (мала картка) −
     20px margin-top = 161px; --full = 626px (повна висота великого айтема) */
  .work-hero .selected-work__strokes {
    width: 328px;
    height: 161px;
  }

  .work-hero .selected-work__strokes--full {
    height: 626px;
  }

  /* Ряд 2: патерн 212px (2 колонки + 1 gutter) → картка 328 → картка 328 =
     212+20+328+20+328 = 908px (уся сітка) — той самий баланс, що на
     index.html. Патерн вирівнюється по нижньому краю малих карток свого
     рядка: 445px (повна висота малого айтема); --wide поглинає колонку
     відсутнього другого айтема: 212+20+328=560px */
  .work-hero .selected-work__pattern {
    width: 212px;
    height: 445px;
  }

  .work-hero .selected-work__pattern--wide {
    width: 560px;
  }

  /* Empty-стан: вирівнюється по сітці 908px/center/offset 0. Ілюстрація —
     окремий Tablet Landscape-файл (empty-landscape.webp/@2x, 868×346,
     та сама пропорція 868:545, що десктоп, лише нижча). 64px до
     ілюстрації; текстовий блок — 370px від фільтрів = top:306px (370−64)
     усередині .work-empty, left:210px від початку сітки (ліворуч,
     align-items:flex-start успадковується з бази) */
  .work-empty {
    width: 908px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 64px;
    height: 448px;
  }

  /* Фікс: left:20px (замість успадкованого десктопного 148px) —
     центрує ілюстрацію в сітці (908px): 908 − 2×20 = 868, рівно ширина
     ілюстрації, тому лівий і правий геп однакові */
  .work-empty__bg {
    left: 20px;
    width: 868px;
    height: 346px;
  }

  .work-empty__image {
    background-size: 868px 346px;
    background-image: url("../assets/images/empty-landscape.webp");
    background-image: image-set(
      url("../assets/images/empty-landscape.webp") 1x,
      url("../assets/images/empty-landscape@2x.webp") 2x
    );
  }

  .work-empty__content {
    top: 306px;
    left: 210px;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-17-light */
  .work-empty__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 142: CTA-2 (work.html)

   .cta--second перевикористовується сайт-вайд (Крок 139 вже задав базові
   висоту/фон/паддінг через .offices + .cta--second на index.html) — тут
   той самий набір значень через сусідній селектор .work-hero + .cta--second
   (як і в десктопі, Крок 47), звужений лише під work.html.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .work-hero + .cta--second {
    /* 120px від низу сітки карток робіт (або empty-стану) до верху фону
       CTA-2 (140px у десктопі) */
    margin-top: 120px;
    height: 624px;
    padding-top: 311px;
    background-size: 1440px 624px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 143: Hero-секція (about.html)

   Той самий принцип, що .work-hero (Крок 141): текстовий контент і всі
   відступи — 1:1 з десктопом, без адаптації під нову ширину сітки
   (навмисно виходить за межі сітки 908px). Тут перевизначається лише
   фон: той самий ассет (image-set 1x/2x), CSS-масштабування до
   1440×675 (та сама пропорція 1920:900 = 1440:675 = 2.133), зсув
   134px вниз від верху секції, center по горизонталі.
   Хедер — без змін (спільний планшетний хедер, Кроки 132–133 + фікси).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* min-height = 134 (зсув) + 675 (висота фону) = 809px, той самий
     принцип, що .work-hero, щоб фон не обрізався знизу секцією
     коротшою за суму зсуву й висоти */
  .about-hero {
    min-height: 809px;
  }

  .about-hero__bg {
    background-position: center 134px;
    background-size: 1440px 675px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 144: секція Our Approach (about.html)

   Той самий принцип, що Services (Крок 133): номер "I." і боді-текст
   зсуваються на колонку 5 (замість 6) нової сітки 96px/908px, текстові
   стилі без змін. Метрики (about-stats) — той самий грід, розбитий на
   два ряди по два айтеми замість одного ряду з чотирьох; контент/стилі
   айтемів 1:1 з десктопом, змінюється лише компонування. Лінія/боді-текст
   метрик і "патерн"/"extra" текст блоку Our Approach тут не чіпаються —
   лишаються на десктопних grid-row (окремий крок пізніше).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу боді-тексту Hero (Крок 143) до верху номера "I.": 270px
     (304px у десктопі), рахується напряму від попереднього флекс-сиблінга
     (.about-hero__desc) — той самий принцип, що в десктопі */
  .about-approach {
    margin-top: 270px;
  }

  .about-approach__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки (4×96 + 4×20) — і номер "I.",
     і боді-текст тепер починаються тут (замість колонки 6 у десктопі) */
  .about-approach__index {
    grid-column: 5;
  }

  .about-approach__desc {
    grid-column: 5 / 9;
  }

  /* Фікс: лейбл успадковував grid-column:1 (одна колонка, 96px) зі
     спільного правила (рядок ~1251) — "OUR APPROACH" туди не влазить і
     переносився на 2 рядки. На всю ширину сітки (1/9, 908px): текст
     лишається притиснутим до лівого краю (0px), просто більше не
     обмежений вузькою колонкою */
  .about-approach__label {
    grid-column: 1 / 9;
  }

  /* Фікс: патерн і текст "We learn your domain..." лишались на
     десктопній колонці 6 (580px у планшетній сітці) — виведено на ту
     саму колонку 5 (464px), що й боді-текст вище (п.2) */
  .about-approach__pattern {
    grid-column: 5 / 9;
  }

  .about-approach__extra {
    grid-column: 5 / 9;
  }

  .about-approach__extra-break--desktop {
    display: none;
  }

  .about-approach__extra-break--tablet {
    display: inline;
  }

  /* Метрики: та сама сітка 96px/908px. Фікс: відступ рахується до верху
     СТРОУКА під рядком 1 (не до верху самих номерів) — 150px від низу
     .about-approach__extra ("We learn your domain...") до верху строука.
     85px тут дає ці 150px з урахуванням висоти номера (64px, dm-h0) і
     власного відступу строука над ним (11px, десктопне значення) —
     виміряно рендером */
  .about-stats {
    margin-top: 85px;
  }

  .about-stats__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Фікс (за референсом): кожен айтем — 4 колонки (444px = 4×96 + 3×20),
     той самий принцип, що фрейми Industries (Крок 137) — замість
     помилкового 2-колонкового (212px) кроку з попередньої версії.
     Рядок 1: "300+" (колонка 1, 0px) / "2020" (колонка 5, 464px) */
  .about-stats__item--1 {
    grid-column: 1 / 5;
    grid-row: 1;
  }

  .about-stats__item--2 {
    grid-column: 5 / 9;
    grid-row: 1;
  }

  /* Фікс: попередній "position:relative; top:4px" (Крок 166) насправді
     зсував строук на 4px НИЖЧЕ за нижній піксель квадрата, а не на нього
     — перевиміряно headless-рендером з transition:0s (попередній замір
     ловив проміжний кадр stagger/scroll-reveal переходу, ще не
     завершеного). Реальні координати: marker "300+"/"2020" top:1178,
     bottom:1183 → нижній піксель 1182. Успадковане margin-top:11px (без
     жодного top-зсуву) саме й кладе строук на 1182 — тобто зсув був
     зайвим, тепер прибраний. Другий строук (під рядком "5"/"3") — той
     самий елемент, box-shadow додає копію: 236px був підібраний під
     СТАРИЙ (зсунутий на +4) top цього елемента, щоб абсолютна позиція
     копії лишалась коректною (marker "5"/"3" bottom:1423 → нижній
     піксель 1422); тепер, коли власний top більше не зсунутий на +4,
     офсет повертається на 240px (236+4), щоб та сама абсолютна позиція
     (1422) лишилась незмінною */
  .about-stats__line {
    grid-row: 2;
    box-shadow: 0 240px 0 0 var(--grey-15);
  }

  /* Боді-текст рядка 1 — під ту саму ширину айтема (444px), що й номер
     вище, замість 2-колонкового кроку в десктопі */
  .about-stats__body--1 {
    grid-column: 1 / 5;
    grid-row: 3;
  }

  .about-stats__body--2 {
    grid-column: 5 / 9;
    grid-row: 3;
  }

  /* Рядок 2: "5" (колонка 1) / "3" (колонка 5) — 80px від низу
     боді-тексту рядка 1 (не від низу самого номера) до верху номера
     рядка 2 */
  .about-stats__item--3 {
    grid-column: 1 / 5;
    grid-row: 4;
    margin-top: 80px;
  }

  .about-stats__item--4 {
    grid-column: 5 / 9;
    grid-row: 4;
    margin-top: 80px;
  }

  /* Фікс: рядок 5 (боді-текст) іде впритул за рядком 4 (айтеми,
     64px), без резерву простору під строук рядка 2 — той строук не
     окремий grid-рядок, а box-shadow-копія (вище), яка НЕ займає
     місця в потоці. 32px (не 36) — виміряно пікселем рендеру після
     фіксу офсету строука (240px, вирівняний по нижньому пікселю
     квадратика), щоб відступ строук→боді-текст лишався тими самими
     ~24-25px, що й для рядка 1 */
  .about-stats__body--3 {
    grid-column: 1 / 5;
    grid-row: 5;
    margin-top: 32px;
  }

  .about-stats__body--4 {
    grid-column: 5 / 9;
    grid-row: 5;
    margin-top: 32px;
  }

  /* Ручні переноси боді-тексту метрик (3 рядки за референсом) —
     вимкнені за замовчуванням (десктоп/мобайл), тут — увімкнені */
  .about-stats__break {
    display: inline;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 145: секція How We Work (about.html)

   Той самий принцип, що Our Approach (Крок 144): номер "II." і боді-текст
   зсуваються на колонку 5 (464px) нової сітки 96px/908px. Великий
   вертикальний строук (.how-we-work__vline) і рядковий розділювач
   (.how-we-work__divider) — та сама пара, що в десктопі мали однакове
   значення (720 = кінець 5-ї колонки) — тепер зсуваються синхронно на
   444px (кінець 4-ї колонки). Контент рядків (.how-we-work__row) — та
   сама пара з боді-текстом (740 = колонка 6 у десктопі) — зсувається на
   464px (колонка 5). Ілюстрацію-сферу в цьому кроці НЕ чіпаємо (окремий
   крок пізніше).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу другого рядка метрик Our Approach (Крок 144) до
     верху номера "II.": 160px, рахується напряму від попереднього
     флекс-сиблінга (.about-stats) — той самий принцип, що в десктопі */
  .how-we-work {
    margin-top: 160px;
  }

  .how-we-work__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки (4×96 + 4×20) — і номер
     "II.", і боді-текст тепер починаються тут (замість колонки 6 у
     десктопі) */
  .how-we-work__index {
    grid-column: 5;
  }

  .how-we-work__desc {
    grid-column: 5 / 9;
  }

  /* Фікс: боді → перший айтем сервісу, 36→54px (той самий цільовий
     відступ, що й десктоп) */
  .how-we-work__list {
    margin-top: 54px;
  }

  /* Фікс: лейбл успадковував grid-column:1 (одна колонка, 96px) зі
     спільного правила — "HOW WE WORK" туди не влазить і переносився на
     2 рядки. На всю ширину сітки (1/9, 908px), той самий фікс, що
     .about-approach__label */
  .how-we-work__label {
    grid-column: 1 / 9;
  }

  /* Правий край 4-ї колонки = 444px від лівого краю сітки (4×96 + 3×20).
     Стилі строука (товщина/колір/висота) без змін — лише горизонтальна
     позиція */
  .how-we-work__vline {
    left: 444px;
  }

  /* Розділювач-рядка ("фрейм") — та сама позиція, що строук вище (720
     у десктопі, тепер 444), впритул до нього, без додаткового відступу.
     Фікс: ширина лишалась десктопною (444px, до 888px) — тепер тягнеться
     до правого краю сітки (908 − 444 = 464px). Відступи навколо
     перевизначені під тарпет 18px (текст→строук) / 17px (строук→наступний
     текст) — свапнуті відносно десктопу (17/18) */
  .how-we-work__divider {
    margin-left: 444px;
    margin-top: 18px;
    margin-bottom: 17px;
    width: 464px;
  }

  /* Фікс: .how-we-work__divider--bottom успадковує клас .how-we-work__divider
     і без цього перевизначення отримав би ті самі margin-left:444px/
     margin-top:18px/margin-bottom:17px/width:464px — цей строук, на
     відміну від рядкових розділювачів, позиціюється через left:0
     (position:absolute), тому margin/margin-top/margin-bottom лишаються
     як у десктопі: margin:0. Фікс ширини: left:0 тут — лівий край САМОЇ
     .how-we-work__grid (її position:relative — найближчий позиційований
     предок, не в'юпорт), тому щоб строук закінчувався рівно на правому
     краю сітки, досить прямого width:908px (сітка тепер 908px, не
     1164px) — той самий локальний "0 → ширина сітки" принцип, що в
     десктопі, лише з новим числом. Фікс: top тут раніше не
     перевизначався й успадковував десктопне значення (642px) — на цій
     сітці рядки/висоти інші, тому позиція строука була невірна. top
     тепер рахується динамічно в js/how-we-work.js (той самий формат
     "реальний низ останнього рядка + 17px" для всіх абсолютно
     позиційованих breakpoint), тому CSS-значення нижче — лише fallback
     до першого запуску JS */
  .how-we-work__divider--bottom {
    margin-left: 0;
    margin-top: 0;
    margin-bottom: 0;
    top: 642px;
    width: 908px;
  }

  /* Фікс: "Hue & Machine is a product..." (Крок 207: оновлений текст)
     лишався на десктопній колонці 6 (580px) — виведено на колонку 5
     (464px), як і решта боді-тексту. Ручні переноси — той самий
     10-рядковий розрив, що десктоп/Mobile (Крок 207), тому жодного
     tablet-break перемикача тут більше не потрібно (успадковується
     дефолтна поведінка: "--desktop" видимий, "--tablet" прихований) */
  /* Фікс: строук → секондарі-боді, 46px (виміряно рендером: 48→64,
     той самий "17px рядок→строук + 1px строук + 46px строук→текст"
     принцип, що десктоп) */
  .how-we-work__extra {
    grid-column: 5 / 9;
    margin-top: 64px;
  }

  /* Секондарі-боді (.how-we-work__extra) отримує власний 6-рядковий
     розрив на Tablet Landscape — вимикаємо десктопний і вмикаємо --tl */
  .how-we-work__extra-break--desktop {
    display: none;
  }

  .how-we-work__extra-break--tl {
    display: inline;
  }

  /* Контент усередині фрейму (назва практики/опис) — колонка 5 (464px),
     20px (gutter) правіше строука/фрейму. Решта стилів рядка — без змін */
  .how-we-work__row {
    margin-left: 464px;
  }

  /* Ілюстрація-сфера — нарешті адаптована під цю сітку (раніше свідомо
     не чіпалась, успадковувала десктопні left/top). top: 177px від низу
     заголовка (Фікс: було 173px, опущено на 4px нижче; row1:20 +
     margin-top:26 + row2:92 = 138, +177 = 315px). left: права межа
     ілюстрації на 10px лівіше лівого краю боді-тексту (не фрейму) —
     лівий край боді-тексту тут 464px (колонка 5), right-edge = 464-10 =
     454, left = 454-934 = -480px */
  .how-we-work__sphere {
    top: 315px;
    left: -480px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 146: секція Trusted By (about.html)

   Та сама адаптація, що на index.html (Крок 134) — сітка логотипів
   (.trusted-by__grid/__logos/__logo-cell/__logo/__lines) і позиція
   номера (.trusted-by__index) уже перевизначені там через НЕскоуплені
   класи, тому діють тут автоматично без дублювання. Єдине, що
   потребує окремого правила на about.html — власний селектор
   .about-hero + .trusted-by (Крок 53/56, 227px у десктопі): він
   специфічніший за загальний .trusted-by з Кроку 134 (2 класи проти 1),
   тому без цього перевизначення десктопне значення продовжило б діяти
   й на планшеті.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Фікс: секондарі-боді → Trusted By, 254px (було 160px) — рахується
     напряму від низу .how-we-work__extra, останнього flow-елемента
     .about-hero на цьому breakpoint (.how-we-work__extra-line тут теж
     display:none, як і в десктопі) */
  .about-hero + .trusted-by {
    margin-top: 254px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 147: секція Leadership (about.html)

   Той самий принцип, що Trusted By (Крок 146): номер "IV." і боді-текст
   зсуваються на колонку 5 (464px) нової сітки 96px/908px. Айтем картки
   зменшується з 888×590 до 780×529, фото — з 424×590 до 380×529,
   інфо-блок — похідні 400×529 (780−380=400, та сама формула, що в
   десктопі: photo+info=item width). Уся внутрішня розмітка інфо-блоку
   (відступи/розміри тексту, hover/активні стани) — без змін, окрім
   .leadership__hline, який завжди дорівнює ширині info (464→400) за
   тим самим принципом, що в десктопі. Кнопки гортання вже вирівняні
   по правому краю .leadership__grid (justify-content:flex-end на
   grid-column:1/9) — після зміни max-width сітки на 908px вони
   автоматично опиняються на 908px, без окремого правила.
   js/leadership-carousel.js читає ширину айтема з реального рендеру
   (getBoundingClientRect), тому крок трансляції треку підлаштовується
   під 780px тут сам, без змін у JS. */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу Trusted By до верху номера "IV.": 160px */
  .leadership {
    margin-top: 160px;
  }

  .leadership__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки — і номер "IV.", і
     боді-текст тепер починаються тут (замість колонки 6 у десктопі) */
  .leadership__index {
    grid-column: 5;
  }

  .leadership__desc {
    grid-column: 5 / 9;
  }

  /* Вікно каруселі — висота під новий розмір айтема (529px, ширина
     1542px лишається незмінною, не в межах цього кроку) */
  .leadership__clip {
    height: 529px;
  }

  /* Ректангл-градієнт (Крок 129) — та сама висота, Крок 147.
     Фікс: right: calc(582px − 50vw) — десктопна "телескоп"-формула,
     582 = половина ДЕСКТОПНОЇ сітки (1164/2). Тут сітка вже 908px
     (.leadership__grid перевизначено вище), тому константа теж має
     стати половиною НОВОЇ ширини: 908/2=454px. Без цього фікса права
     межа ректангла зупинялась на 128px раніше правого краю в'юпорта
     (582−454=128, виміряно рендером) замість full-bleed */
  .leadership__gradient {
    height: 529px;
    right: calc(454px - 50vw);
  }

  /* Ручний перенос тайтлу — увімкнений лише тут (за замовчуванням
     вимкнений вище, щоб не чіпати десктопний однорядковий рендер) */
  .leadership__title-break {
    display: inline;
  }

  .leadership__item {
    width: 780px;
    height: 529px;
  }

  .leadership__photo {
    width: 380px;
    height: 529px;
  }

  .leadership__photo-stroke {
    width: 380px;
    height: 529px;
  }

  /* Інфо-блок — 400×529 (780 − 380 = 400, той самий принцип, що в
     десктопі: photo + info = ширина айтема) */
  .leadership__info {
    width: 400px;
    height: 529px;
  }

  /* Строук на всю ширину інфо-блоку (400px, як 464px у десктопі) —
     margin-left:-28px лишається (компенсує той самий відступ
     .leadership__content, який тут без змін) */
  .leadership__hline {
    width: 400px;
  }

  /* Фікс: патерн у кінці ряду (Крок 128, п.3) — той самий принцип, що
     в десктопі (276 = 1164 − 888, тут 908 − 780 = 128), заповнює
     "залишок" сітки після одного айтема, а не фіксоване десктопне
     значення. Строуки зверху/знизу (Крок 128, п.1) — це border-top/
     border-bottom того самого елемента, тому автоматично йдуть за
     новою шириною/висотою без окремих правил; товщина (1px) і колір
     (var(--grey-15)) не змінюються. Висота — 529px, той самий принцип,
     що .leadership__item/__photo/__info вище */
  .leadership__end-pattern {
    width: 128px;
    height: 529px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 148: секція Offices (about.html)

   Той самий принцип, що Leadership (Крок 147): номер "V." і боді-текст
   зсуваються на колонку 5 (464px) нової сітки 96px/908px. Уся внутрішня
   структура кожного айтема міста (тайтл+індекс країни, маркер/вертикальна
   лінія, лейбл+боді, GMT-тег+дivider) позиціонується АБСОЛЮТНО ВІДНОСНО
   САМОГО айтема (.about-offices__city, position:relative), тому нічого
   там не перевизначається — досить змінити лише margin-left на
   .about-offices__city--ny/--kyiv (сам горизонтальний відступ між
   айтемами). Глобальні (на всю ширину рядка) строуки — перераховані під
   нову сумарну ширину рядка (виміряно рендером, той самий принцип, що
   .about-offices__body-line у десктопі).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу кнопок гортання Leadership (Крок 147) до верху
     номера "V.": 160px */
  .about-offices {
    margin-top: 160px;
  }

  .about-offices__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки — і номер "V.", і
     боді-текст тепер починаються тут (замість колонки 6 у десктопі) */
  .about-offices__index {
    grid-column: 5;
  }

  .about-offices__desc {
    grid-column: 5 / 9;
  }

  /* Відступ від низу боді-тексту до верху рядка айтемів міст: 96px
     (114px у десктопі). min-height = 357px (356px у десктопі), той
     самий "= низ вертикальних строуків" принцип, що в десктопі —
     перераховано під фікс відступу строук→лейбл нижче (357 = 356+1,
     новий низ .about-offices__gmt-line/vline) */
  .about-offices__cities {
    margin-top: 96px;
    min-height: 357px;
  }

  /* Фікс: нові відступи МІЖ айтемами (право попереднього → ліво
     наступного): 136px London→New York, 99px New York→Kyiv (було
     108/74, 192/157 у десктопі). Уся внутрішня структура кожного
     айтема — position:absolute відносно самого .about-offices__city,
     тому автоматично йде за цим зсувом без окремих правил */
  .about-offices__city--ny {
    margin-left: 136px;
  }

  .about-offices__city--kyiv {
    margin-left: 99px;
  }

  /* На всю ширину сітки (908px, 1164px у десктопі) */
  .about-offices__gmt-line {
    width: 908px;
  }

  /* Фікс: .about-offices__city-info піднявся на 19px (top:149, було
     168 — фікс відступу строук→лейбл вище), тому й низ боді-тексту
     піднявся на ту саму різницю — тепер 303px (виміряно рендером
     ПІСЛЯ scroll-reveal, 1100px вʼюпорт; було 322px до цього фіксу,
     302px у десктопі). Той самий принцип, що раніше: top = низ боді
     + 24 = 303+24=327px. Не на всю сітку (як і в десктопі) — правий
     край рівно на правому краю .about-offices__extra-vline нижче */
  .about-offices__body-line {
    top: 327px;
    width: 908px;
  }

  /* Той самий "4px від низу строука" принцип, що в десктопі
     (331 = 326+1+4) — тут від нового top:327 строука: 327+1+4=332 */
  .about-offices__gmt {
    top: 332px;
  }

  /* Той самий "4px від низу рядка тегу GMT" принцип, що в десктопі
     (355 = 331+20+4) — тут від нового top:332 тегу: 332+20+4=356 */
  .about-offices__gmt-line {
    top: 356px;
  }

  /* Вертикальні строуки (маркер-лінія кожного міста + Kyiv-екстра)
     раніше закінчувались на 356px (70+286, збігаючись зі старим
     gmt-line на 355+1) — тепер мають дотягуватись до нового gmt-line
     (356+1=357): height = 357−70=287px */
  .about-offices__vline,
  .about-offices__extra-vline {
    height: 287px;
  }

  /* Фікс-2: попереднє значення (284px) вирівнювало ЛІВИЙ край
     1px-строука по правому краю сітки — правий край строука через
     власну ширину (1px) виходив на ~1.4px ЗА межу (виміряно рендером
     на 1024/1100/1279px: стабільний оверхенг на всіх трьох). 282px
     (не 283 — цілочислове округлення ВНИЗ, а не найближче, щоб
     гарантовано не вилазити за межу за жодного субпіксельного
     заокруглення браузера) ставить ПРАВИЙ край строука рівно на
     правому краю сітки (908px): 282 + 624 (лівий край Kyiv локально
     відносно .about-offices__cities) + 1 (ширина строука) ≈ 907,
     що на ~1px всередині 908 — той самий принцип, що для London/
     New York, прив'язка лишається відносною до
     .about-offices__city--kyiv (position:absolute) */
  /* Фікс-3: −0.5px (282.5, було 283) — 283px виявився ледь ЗА межею
     сітки (~908.4px), точна пікселева позиція — дробове значення */
  .about-offices__extra-vline {
    left: 282.5px;
  }

  /* Фікс: відступ від верхнього горизонтального строука (.about-offices__line,
     top:70, впритул під тайтлами міст) до лейбла (subtitle) — 78px
     (70+1+78=149), замість успадкованого десктопного top:168 (яке
     давало 97px). Каскадом зсуває боді-текст (у потоці всередині
     .city-info) на ту саму різницю — body-line/gmt/gmt-line/vline
     нижче перераховані під нову позицію, щоб 24px (боді→строук над
     GMT, попередній фікс) лишились незмінними */
  .about-offices__city-info {
    top: 149px;
  }

  /* Фікс (Крок 148, п.1): патерн косих ліній праворуч від айтемів міст
     на планшеті повністю прибирається */
  .about-offices__pattern {
    display: none;
  }

  /* Ручні переноси боді-текстів міст (Крок 148-фікс) — десктопні
     вимикаються, планшетні (нові рядки за референсом) вмикаються */
  .about-offices__body-break--desktop {
    display: none;
  }

  .about-offices__body-break--tablet {
    display: inline;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Фікс: секція CTA-2 на about.html

   Той самий готовий блок, що вже на index.html (.offices + .cta--second,
   Крок 139) і work.html (.work-hero + .cta--second, Крок 142) —
   .cta--second і .footer самі вже сайт-вайд (Крок 140, без сторінко-
   специфічних відмінностей), тут потрібен лише відступ-сусід через
   .about-offices + .cta--second (на about.html Offices — секція одразу
   перед CTA-2, як і Offices на index.html), з тими самими значеннями,
   що в Кроці 139.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .about-offices + .cta--second {
    /* 120px від низу Offices до верху фону CTA-2 (204px у десктопі) */
    margin-top: 120px;
    height: 624px;
    padding-top: 311px;
    background-size: 1440px 624px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 149: Hero-секція (services.html)

   Той самий принцип, що .work-hero (Крок 141) / .about-hero (Крок 143):
   текстовий блок і всі відступи — 1:1 з десктопом (padding-top:170px уже
   фіксований у базовому правилі, тому для планшета збігається сам собою,
   окремого перевизначення не потрібно). Тут перевизначається лише фон
   (той самий ассет, CSS-масштабування до 1440×675, зсув 134px вниз,
   center по горизонталі) і компонування тайтла (ручні переноси —
   десктопні <br> вимикаються, планшетні вмикаються, той самий tablet-
   break прийом, що в Our Approach/Offices на about.html).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* min-height = 134 (зсув) + 675 (висота фону) = 809px, той самий
     принцип, що .work-hero/.about-hero, щоб фон не обрізався знизу
     секцією коротшою за суму зсуву й висоти */
  .services-hero {
    min-height: 809px;
  }

  .services-hero__image {
    background-position: center 134px;
    background-size: 1440px 675px;
  }

  .services-hero__title-break--desktop {
    display: none;
  }

  .services-hero__title-break--tablet {
    display: inline;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 150: секція Services (scrollytelling-табличка,
   services.html)

   Ліва частина (ілюстрація-квітка, .services-hero__practices-illustration)
   спершу тут навмисно не чіпалась — додана нижче окремим фіксом. Права частина (тайтл/
   строук/номер/лінія/табличка) переходить на грід 908px/8×96 — той самий
   "колонка 5 = 464px" принцип, що вже реалізований для .services__index/
   __desc (Крок 133): тайтл+каунтер і строук виходять на всю ширину 908px
   (замість 1164), номер і табличка стартують з колонки 5.

   Зазор над табличкою росте зі 128px до 208px, тому й висота sticky-
   панелі росте з 928px (128+800) до 1008px (208+800) — той самий
   принцип, що TABLE_MAX_WINDOW_TABLET у js/services-table.js: JS-
   константа PANEL_HEIGHT у js/services-practices.js перевизначена
   окремо під цей самий брейкпоінт (не читає CSS), тому має лишатись
   синхронізованою з цим 1008px вручну. Видима висота вікна (800px) і
   крок між айтемами (140px) — ті самі значення, що в десктопі, тому
   окремо не перевизначаються.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від низу боді-тексту Hero до верху тайтла "Services": 212px
     (252px у десктопі) */
  .services-hero__list-heading {
    margin-top: 212px;
  }

  /* Тайтл+каунтер і строук нижче виходять на всю ширину сітки 908px
     (замість 1164px) — контейнери центровані (margin:0 auto), тому
     звуження max-width/width само вирівнює лівий край по лівому краю
     сітки, без окремого left/margin-left */
  .services-hero__list-heading-inner {
    max-width: 908px;
  }

  .services-hero__list-stroke {
    width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки (4×96 + 4×20) — номер "I."
     тепер починається тут (замість колонки 6, 740px, у десктопі) */
  .services-hero__list-index {
    left: 464px;
  }

  /* Той самий грід 908px — контейнер, від лівого краю якого відлічуються
     left/margin-left лінії й таблички нижче */
  .services-hero__practices {
    max-width: 908px;
  }

  /* Зазор від строука до контенту таблички: 208px (128px у десктопі).
     Висота sticky-панелі росте на ту саму різницю (1008 = 208 + 800px
     вікна, без змін). padding-top лишається референсом лише для
     табличкового вікна нижче (в потоці) — абсолютна ілюстрація-квітка
     має свій власний top нижче, незалежний від цього padding-top (той
     самий принцип, що й у десктопі, де top:112px теж не залежить від
     padding-top:128px) */
  .services-hero__practices-sticky {
    height: 1008px;
    padding-top: 208px;
  }

  /* Велика вертикальна лінія — кінець колонки 4 = 444px (721px у
     десктопі), товщина/колір без змін. height росте разом із панеллю
     (1008px), щоб і далі покривати її повну висоту, як раніше на
     десктопі. Явний top:0 (Фікс: десктопний base тепер top:128/
     height:800, скоуплений під фікс "верх строука видно крізь
     градієнт" — цей блок НЕ в зоні того фіксу, тому явно зберігає
     стару "на всю висоту .sticky" поведінку, а не успадковує нову) */
  .services-hero__practices-line {
    left: 444px;
    top: 0;
    height: 1008px;
  }

  /* Фікс: контейнер таблички починається ВІДРАЗУ від великого
     вертикального строука (444px, впритул, 0px відступу) — не з
     колонки 5 (464px), як було раніше. Текстовий контент (тайтли/
     боді практик) при цьому й далі виходить на 464px САМ, без
     додаткового padding тут: .practice__head/.practice__body вже
     мають власний margin-left/padding-left:20px (Крок 80 — той самий
     "фрейми bleed на 20px лівіше тексту" принцип, що в десктопі,
     720→740). .practice__frame (444px, без власного зсуву) лишається
     впритул до контейнера, так само навмисно, як і в десктопі.
     width росте до 464px (908−444), щоб правий край контейнера, як і
     в десктопі (720+444=1164=правий край сітки), і далі точно
     збігався з правим краєм сітки (444+464=908) */
  .services-hero__practices-window {
    margin-left: 444px;
    width: 467px;
  }

  /* Фікс: боді-текст практик (.practice__body/__body2, старт 464px)
     упирався в успадковану десктопну width:424px, тому закінчувався на
     888px — на 20px коротше за правий край сітки (908px). Нова ширина
     444px (444 = 908 − 464) розтягує його рівно до правого краю сітки.
     .practice__frame (444px, впритул до контейнера з 444px) тут НЕ
     чіпається — навмисний "bleed 20px лівіше тексту" принцип лишається
     без змін (див. коментар вище).
     Фікс: +3px до 444/464 (447/467) — новий Landscape-текст Product
     ("...architecture and handoff —") виміряно реальним рендером
     (headless Chrome, справжній dm-sans-light.woff2, 17px) 444.7px
     проти контейнера 444px — переносив "—" на власний рядок. +3px
     запасу на субпіксельні відмінності рендерингу між браузерами (той
     самий прийом, що вже в .industries__desc). .practice__frame
     (444px) НЕ чіпається — bleed-принцип лишається */
  .practice__body,
  .practice__body2 {
    width: 447px;
  }

  /* Перенос рядків .practice__body — свій на Tablet Landscape (Фікс):
     вимикаємо десктопні розриви, вмикаємо tablet-landscape-розриви
     (класи розмітки, база — styles.css вище) */
  .practice__body-break--desktop {
    display: none;
  }

  .practice__body-break--tablet-landscape {
    display: inline;
  }

  /* Operations — секондарі боді-текст: інший ТЕКСТ (не лише розрив), тому
     перемикаємо, який із двох <p> видимий, а не окремі <br> (база вище) */
  .practice__body2--desktop {
    display: none;
  }

  .practice__body2--tablet-landscape {
    display: block;
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — 880×880px
     (0.8661 від десктопних 1016px), той самий rotate/mask/tag-механізм,
     що на десктопі (js/services-hero-illustration.js тут не чіпається).
     top:24px (фікс: замінює попередні 130px) — офсет від padding-edge
     панелі, виміряний від боді-тексту секції до верху ілюстрації.
     Горизонталь: правий край на 60px лівіше лівого краю контейнера
     таблички (444px, впритул до великої лінії) →
     left = 444 − 60 − 880 = −496px */
  .services-hero__practices-illustration {
    top: 24px;
    left: -496px;
    width: 880px;
    height: 880px;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 151: секція Our Commitments (services.html)

   Референс — Figma-скрін (3 айтеми в ряд). Номер і боді-текст заголовного
   блоку зсуваються на колонку 5 (464px), той самий принцип, що скрізь
   по сторінці (Крок 133/150) — тайтл лишається на колонках 1-6, без змін.

   Горизонтальні відступи між айтемами (154px/153px, виміряні між
   ілюстраціями) НЕ однакові — на відміну від десктопного flex-gap:239px
   (однаковий для всіх), тому тут gap:0 + індивідуальний margin-left на
   2-му/3-му айтемі через nth-child (класів --1/--2/--3 на .item нема,
   лише на .illustration). Перевірено: 0 (item1) + 149 (ілюстрація) + 154
   (gap) + 149 + 153 (gap) + 149 = 754px — уміщується в сітку 908px.

   .our-commitments__line (суцільний строук під квадратиками, Крок 84)
   перерахований під нові ліві краї айтемів (0/303/605) за тією самою
   формулою, що в десктопі (лівий край останнього айтема + ширина його
   боді-тексту 356px = 1132 у десктопі): 605 + 356 = 961px — виходить за
   межі сітки (908px) на 53px, так само навмисно, як боді-текст/тайтл
   кожного айтема вже перетікають праворуч за межі власної 149px-коробки
   і в десктопі (Крок 84, той самий overflow-принцип). Значення виведене
   формулою (не задане прямо в ТЗ) — не перевірено проти скріна.

   Ручні переноси боді-тексту (п.6 ТЗ) — item 1 лише додає ОДИН новий
   планшетний розрив усередині вже існуючого десктопного 3-го рядка
   (перші 2 розриви спільні для обох брейкпоінтів, plain <br> без класу);
   item 2/3 розбивають рядки в геть інших точках, тому там повністю
   окремі десктопні/планшетні набори — той самий tablet-break прийом,
   що в Our Approach/Offices (about.html).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Відступ від видимого низу таблички Services (800px видиме вікно +
     208px зазор = 1008px sticky-панель, Крок 150) до верху номера "II.":
     246px. На відміну від десктопного margin-top:348px (який компенсує
     звис ілюстрації-квітки за межі 928px sticky-панелі, Крок 83), тут
     ілюстрацію не чіпали (Крок 150) — sticky-панель і "видима частина"
     табличкu збігаються один в один (1008px = 208 + 800, без звису),
     тому natural margin-top:0 вже сам собою продовжує рівно з видимого
     низу таблички — 246px застосовується напряму, без компенсації */
  .our-commitments {
    margin-top: 246px;
  }

  .our-commitments__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Колонка 5 = 464px від лівого краю сітки (4×96 + 4×20) — номер і
     боді-текст тепер починаються тут (замість колонки 6, 740px, у
     десктопі); тайтл лишається на колонках 1-6, без змін */
  .our-commitments__index {
    grid-column: 5;
  }

  .our-commitments__desc {
    grid-column: 5 / 9;
  }

  /* Відступ від низу боді-тексту до верху ілюстрацій: 80px (124px у
     десктопі) */
  .our-commitments__items {
    margin-top: 80px;
    gap: 0;
  }

  /* Індивідуальні горизонтальні відступи між ілюстраціями (154px/153px,
     не однакові — на відміну від десктопного gap:239px), рахуються від
     першого айтема (лівий край 0px): 149 (ширина ілюстрації) + 154 = 303,
     303 + 149 + 153 = 605 */
  .our-commitments__item:nth-child(2) {
    margin-left: 154px;
  }

  .our-commitments__item:nth-child(3) {
    margin-left: 153px;
  }

  /* Фікс: попереднє значення (961px, "лівий край 3-го айтема + ширина
     його боді", той самий принцип, що в десктопі 776+356=1132) виходило
     за правий край сітки на 53px. .our-commitments__items сам уже
     точно дорівнює ширині сітки (grid-column:1/9 у 908px-гріді, Крок
     151) — обмежуємо строук саме цим контейнером, а не розрахунком по
     тексту: 908px, лівий край 0, тому правий край рівно на межі сітки */
  .our-commitments__line {
    width: 908px;
  }

  .our-commitments__item-body-break--desktop {
    display: none;
  }

  .our-commitments__item-body-break--tablet {
    display: inline;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 152: секція Industries (services.html)

   1:1 копія вже реалізованої планшетної версії на index.html (Крок 137) —
   та сама розмітка/стилі/ассети/логіка, скоуплена через суміжний
   селектор .services-hero + .industries--services (замість .cta +
   .industries на index.html — на services.html Industries іде одразу
   після .services-hero, той самий принцип, що вже описаний у коментарі
   Кроку 137). Єдина відмінність від Кроку 137 — margin-top (160px від
   боді-тексту останнього айтема Our Commitments, замість 6px від низу
   кита CTA на index.html), значення підібране рендером (Playwright,
   1100px вʼюпорт) під фактичну висоту Our Commitments на цьому
   брейкпоінті (Крок 151).
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .services-hero + .industries--services {
    margin-top: 160px;
  }

  .services-hero + .industries--services .industries__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  .services-hero + .industries--services .industries__index {
    grid-column: 5;
  }

  .services-hero + .industries--services .industries__desc {
    grid-column: 5 / 9;
  }

  .services-hero + .industries--services .industries__list {
    grid-column: 1 / 5;
    margin-top: 64px;
  }

  .services-hero + .industries--services .industries__globe-stack {
    margin-top: 0;
    margin-left: 534px;
  }

  .services-hero + .industries--services .industry-row {
    height: auto;
    padding-bottom: 24px;
  }

  .services-hero + .industries--services .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 20px;
  }

  .services-hero + .industries--services .industry-row__tags {
    margin-top: 12px;
    flex-wrap: wrap;
    row-gap: 8px;
  }

  /* Фікс: Fintech (nth-child(1)) — сума ширин трьох тегів ("KYC
     Onboarding" • "Trading Platforms" • "Payment Flows") лежить впритул
     до 444px контейнера, тому природний flex-wrap ненадійно тримає
     "Payment Flows" на першому рядку. flex-basis:100% на останньому
     тезі форсує перенос на другий рядок незалежно від точної ширини —
     1:1 з тим самим фіксом на index.html (.cta + .industries) */
  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__tags span:last-child {
    flex-basis: 100%;
  }

  /* Немає надійного hover на Tablet (дотик) — активний рядок керується
     скролом (js/industries-tablet-scrolly.js через .is-active), той
     самий dim/bright принцип, що вже реалізований на Mobile нижче:
     дефолт приглушений (grey-50), .is-active — повна яскравість */
  .services-hero + .industries--services .industry-row__title {
    color: var(--grey-50);
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .services-hero + .industries--services .industry-row__tags {
    color: var(--grey-50);
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .services-hero + .industries--services .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row__divider {
    left: 0;
    right: 0;
  }

  .services-hero + .industries--services .industry-row__illustration {
    display: none;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before,
  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 153: секція FAQ (services.html)

   .faq/.faq__* унікальні для services.html (єдина сторінка з FAQ) —
   на відміну від Industries/Offices тут не треба скоупити через
   суміжний селектор, звичайні перевизначення. Змінюється лише
   ширина/позиція контейнера (грід 908px/96px, .faq__index/.faq__list
   вже на grid-column:5/5-9 у десктопі — колонки самі стають вужчими),
   акордеон-механіка/стилі/переноси боді-тексту — БЕЗ ЗМІН.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* ЦІЛЬ: 160px від низу ОСТАННЬОГО ФРЕЙМУ Industries (списку, не від
     глобуса!) — margin-top тут рахується від фактичного низу
     .industries--services, а це вищий з двох grid-item рядка 4
     (глобус чи список фреймів). На цьому брейкпоінті список
     (Крок 152: 64px + 650px = 714px від верху Industries) КОРОТШИЙ за
     глобус (786px, margin-top:0) — різниця 786−714=72px. Пряме
     margin-top:160px дало б 160+72=232px від фрейму, а не 160
     (перевірено рендером). Компенсація: 160−72=88px — той самий
     розрахунок/значення, що для Offices на index.html (Крок 138), бо
     геометрія Industries тут ідентична (Крок 152 — 1:1 копія) */
  .faq {
    margin-top: 88px;
  }

  .faq__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* .faq__index/.faq__list уже на grid-column:5/5-9 у десктопі (Фікс
     Кроку 87) — колонки самі стають вужчими (96px замість 128px), тому
     окремого перевизначення grid-column тут не треба */

  /* Ширина ряду/тайтла/боді/строука рахувалась під колонки 5–8 у
     десктопній сітці (572px = 4×128 + 3×20) — тепер 444px (4×96+3×20).
     Тайтл/боді: 444 − 24 (відступ до іконки) − 12 (іконка) = 408px
     (та сама формула, що в десктопі: 572−24−12=536). Строук — на всю
     ширину ряду (444px, як і 572px у десктопі), а не 408 */
  .faq-item__row {
    width: 444px;
  }

  .faq-item__title {
    width: 408px;
  }

  /* Фікс: той самий принцип, що десктоп (552px) — 408px (успадковане
     від .faq-item__title) звужувало найдовший заданий рядок на Tablet
     Landscape (Айтем 4, виміряно 414.05px), слово автопереносилось на
     новий рядок попри правильний <br>. 420px — найкоротша "кругла"
     ширина із запасом (доступний простір — 444px, .faq-item__row вище,
     тому 420px нічого не ламає) */
  .faq-item__body {
    width: 420px;
  }

  .faq-item__stroke {
    width: 444px;
  }

  /* Фікс: планшетний ручний перенос тайтла (десктопний розбивається в
     інших точках, вимикається тут) — той самий tablet-break прийом,
     що в Our Commitments. Боді — окрема <p> з переписаним текстом
     (.faq-item__body--tablet): вимикаємо десктопну <p> і вмикаємо
     планшетну */
  .faq-item__title-break--desktop {
    display: none;
  }

  .faq-item__title-break--tablet {
    display: inline;
  }

  .faq-item__body--desktop {
    display: none;
  }

  .faq-item__body--tablet {
    display: block;
  }
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 154: CTA-2 і Footer (services.html)

   Той самий готовий блок, що вже на index.html (.offices + .cta--second,
   Крок 139), work.html (.work-hero + .cta--second, Крок 142) і about.html
   (.about-offices + .cta--second) — той самий набір значень (624/311/
   1440×624), скоуплений через .faq + .cta--second (на services.html
   секція одразу перед CTA-2 — FAQ, Крок 153, не Our Commitments: між
   ними вже стоять Industries і FAQ, Кроки 152–153). Footer — сайт-вайд
   (Крок 140 + всі фікси), уже застосовується тут без жодних додаткових
   правил.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  .faq + .cta--second {
    /* 120px від низу FAQ до верху фону CTA-2 (140px у десктопі) */
    margin-top: 120px;
    height: 624px;
    padding-top: 311px;
    background-size: 1440px 624px;
  }
}

/* Фікс — Contact: боді-тексти секції Offices на планшеті (1024–1279px)
   потребують ІНШОГО (коротшого) тексту, а не лише інших переносів рядків
   — тому, на відміну від .about-offices__body-break--tablet (той самий
   прийом, лише перемикає <br>, той самий текст), тут дублюється весь
   <p>: desktop-версія (наявний текст/розмітка, без змін) ховається на
   планшеті, tablet-версія (новий текст, ручні <br>) ховається на
   десктопі. Класи власні для contact.html (contact-offices__*), тому
   .about-offices__desc/__body на about.html (той самий БЕМ-клас,
   спільна типографіка/grid-позиція) лишаються геть незачепленими. */
.contact-offices__desc--tablet,
.contact-offices__body--tablet,
.contact-offices__desc--portrait,
.contact-offices__body--portrait,
.contact-offices__body--mobile {
  display: none;
}

/* Фікс — боді-тексти міст на десктопі (нове формулювання, точні ручні
   переноси): дві з нових рядків ("...discovery & strategy,"/"...US time
   zones —") ширші за успадковані 293px (.about-offices__body, виміряно
   рендером ~302-308px) — без цього браузер сам розбивав би ще один
   рядок поверх заданого <br>. 312px — з невеликим запасом над
   виміряним максимумом (308px). Скоуп лише на contact.html
   (.about-offices__body на about.html лишається 293px, без змін) */
.contact-offices__body--desktop {
  width: 312px;
}

/* ==========================================================================
   TABLET (1024–1279px) — Крок 155: Hero + Форма + Статистика + Offices +
   CTA-2/Footer (contact.html)

   Hero-контент (тайтл/боді/форма/CTA-кнопка) — 1:1 з десктопом, без
   адаптації під нову ширину сітки (той самий принцип, що .work-hero/
   .about-hero/.services-hero) — тут перевизначається лише фон:
   background-size 1440×810 — рівно 0.75 від фактичних 1920×1080
   (contact-bg-desktop.webp, Крок 208), без зсуву зверху
   (0px, на відміну від 134px у work/about/services.html).

   Offices (.contact-offices.about-offices) і сусідній CTA-2
   (.about-offices + .cta--second) уже перевизначені сайт-вайд у Кроках
   148/149-фікс — contact-offices ділить ті самі BEM-класи, що
   about-offices, тому й margin-top:160px (Крок 148) та 120px/624/311/
   1440×624 (фікс CTA-2 на about.html) підхоплюються тут автоматично,
   без жодних додаткових правил. Footer — сайт-вайд (Крок 140), також
   без змін.
   ========================================================================== */

@media (min-width: 1024px) and (max-width: 1279px) {

  /* Фон одразу від верху секції (0px зсув, на відміну від інших
     hero-секцій) — min-height дорівнює висоті фону (0+810) */
  .contact-hero {
    min-height: 810px;
    /* Фікс: 224px від верху в'юпорта до тайтла — фіксоване значення
       (не пропорційне до висоти, той самий принцип, що work.html/
       services.html, Крок 141/149), замість успадкованих десктопних 316px */
    padding-top: 224px;
  }

  .contact-hero__image {
    background-position: center top;
    background-size: 1440px 810px;
  }

  /* Фікс: 120px (було 160px) від низу форми/CTA-кнопки до верху секції
     статистики (190px у десктопі, без змін) */
  .contact-stats {
    margin-top: 120px;
  }

  /* Ширина секції: 908px замість десктопних 1164px, center/offset 0 —
     margin:0 auto на .contact-stats__grid (без змін) далі центрує це
     в'юпорт-ширині */
  .contact-stats__grid {
    max-width: 908px;
  }

  /* Фікс горизонтального розташування: замість центрування рядка
     (margin:0 auto, десктоп) айтем 1 тепер починається з лівого краю
     сітки (0px) — просто прибираємо auto-центрування */
  .contact-stats__titles {
    margin: 0;
  }

  /* Фікс — боді-тексти секції Offices: показуємо коротший
     tablet-варіант замість десктопного (див. коментар перед цим блоком) */
  .contact-offices__desc--desktop,
  .contact-offices__body--desktop {
    display: none;
  }

  .contact-offices__desc--tablet,
  .contact-offices__body--tablet {
    display: block;
  }

  /* 203px від правого краю тайтла "300+" до лівого краю тайтла "92%"
     (173px у десктопі) */
  .contact-stats__item--2 {
    margin-left: 203px;
  }

  /* 232px від правого краю тайтла "92%" до лівого краю тайтла айтема 3
     (178px у десктопі) */
  .contact-stats__item--3 {
    margin-left: 232px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 156: Хедер (глобально) + Hero-секція
   (Home)

   НОВИЙ, окремий від Tablet Landscape (1024–1279px, Крок 132+) breakpoint —
   власний медіа-запит, стилі між ними не перетинаються.

   Хедер тут — ОДИН статичний вигляд (логотип + строук-меню-строук + CONTACT
   як CTA), без "top"/"scrolled"/"peek"-переходів по скролу: js/header.js
   і далі перемикає .header--scrolled/.header--peek за скролом (сам файл
   не чіпаємо, спільний для всіх breakpoint'ів), тому кожне правило нижче,
   де в десктопі/тарлеті існує стан-залежний селектор (2+ класи), продубльоване
   з тією самою чи вищою специфічністю, щоб перемагати в БУДЬ-якому стані.
   Де конфліктний селектор лише вмикає/вимикає opacity (не display) — досить
   одного display:none/безумовного правила, конфлікт по специфічності не
   виникає (.header__nav, нижче).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Сітка: 4 колонки × 155px + 3 gutter × 16px = 668px, center, offset 0 */
  .grid-overlay__row {
    max-width: 668px;
    grid-template-columns: repeat(4, 155px);
    gap: 16px;
  }

  .grid-overlay__col:nth-child(n + 5) {
    display: none;
  }

  /* Фікс: фон хедера — токен var(--color-background) (базовий фон сторінки),
     не прозорий і не grey-токен scrolled-стану. Строук — inset 1px по
     контуру, var(--grey-15), той самий токен, що на десктопі/Tablet
     Landscape (завжди присутній, без "top"/"scrolled"-переходу) */
  .header {
    width: 668px;
    height: 48px;
    top: 20px;
    padding: 12px;
    background-color: var(--color-background);
    box-shadow: inset 0 0 0 1px var(--grey-15);
  }

  /* Розкриває .header__brand (логотип + внутрішній строук + кнопка меню)
     як прямих флекс-дітей самого .header — так порядок/gap між ними можна
     керувати звичайним flex-потоком нарівні з .header__divider--contact/
     .header__contact-link, а не вкладеним підпотоком усередині .header__brand */
  .header__brand {
    display: contents;
  }

  .header__logo {
    width: 22px;
    height: 22px;
  }

  /* Фікс: строук одразу після лого — 12px від правого краю логотипа
     (той самий відступ, що з усіх боків самого лого, п.2 вище). DOM-
     позиція елемента (одразу за .header__logo, перед внутрішнім
     строуком/кнопкою меню в розмітці .header__brand) сама дає потрібний
     порядок після display:contents — жодних додаткових order не треба */
  .header__divider--logo {
    display: block;
    width: 1px;
    height: 48px;
    margin-left: 12px;
    background: var(--grey-15);
    flex-shrink: 0;
  }

  /* Фікс: цей внутрішній строук (успадкований з десктопу/Tablet Landscape,
     де він стоїть перед кнопкою меню) тут зайвий за дизайном — правильна
     структура (справа наліво): CONTACT → строук (0px) → фрейм меню (0px),
     БЕЗ додаткового строука ще лівіше. display:none замість видимого
     строука; "гумова" роль (margin-left:auto, забирає вільну ширину між
     лого і кластером праворуч) переїхала на сам .header__menu-btn нижче,
     щоб правостороннє притискання кластера не зламалось */
  .header__brand .header__divider {
    display: none;
  }

  /* Іконка меню — завжди видима (немає "collapsed"-стану, на відміну від
     десктопу). Три селектори нижче — той самий клас, що й "top"/
     "scrolled"/"scrolled+peek"-варіанти десктопного правила (styles
     вище), продубльовані з тією ж специфічністю, щоб перемогти незалежно
     від того, який стан зараз тримає header.js.
     Фрейм 48×48 (на всю висоту хедера, box-sizing:border-box глобальний
     — border входить у 48px, не додається зверху) — іконка (22×22)
     лишається по центру завдяки успадкованому display:flex;align-items:
     center;justify-content:center із базового правила. Строуки лише
     зліва/зверху/знизу (без правого — фрейм межує з наступним елементом
     праворуч через власний gap, четвертий строук був би зайвим).
     Фрейм впритул (0px) до строука після лого, без власного лівого
     строука (дублював строук після лого) — той самий строук натомість
     справа від фрейму. "Гумова" роль (забирає вільну ширину між
     кластером лого+меню і CONTACT) переїхала на .header__divider--contact
     нижче */
  .header__menu-btn,
  .header--scrolled .header__menu-btn,
  .header--scrolled.header--peek .header__menu-btn {
    width: 48px;
    height: 48px;
    margin-left: 0;
    opacity: 1;
    pointer-events: auto;
    border-left: none;
    border-top: 1px solid var(--grey-15);
    border-bottom: 1px solid var(--grey-15);
    border-right: 1px solid var(--grey-15);
  }

  /* Ховер фрейму — фон grey-15 (той самий колір, що й активний/відкритий
     стан нижче — see .header--menu-open .header__menu-btn) */
  .header__menu-btn:hover {
    background-color: var(--grey-15);
  }

  /* Навігація в цьому breakpoint відсутня за дизайном — display:none (не
     opacity), тому конфліктні стан-залежні правила (.header--scrolled
     .header__nav, .header--scrolled.header--peek .header__nav — обидва
     лише перемикають opacity/pointer-events, display не займають) тут
     не заважають: жодне інше правило .header__nav взагалі не задає display */
  .header__nav {
    display: none;
  }

  /* Строук між фреймом меню і CONTACT, 0px справа (фрейм меню (48×48)
     впритул зліва до строука, строук впритул зліва до CONTACT
     (.header__contact-link margin-left:0, нижче, без змін)).
     "Гумова" роль (margin-left:auto, забирає вільну ширину між
     кластером лого+меню зліва і CONTACT справа) — той самий принцип,
     що вже підтверджено на Mobile */
  .header__divider--contact,
  .header--scrolled .header__divider--contact {
    height: 48px;
    margin-left: auto;
    opacity: 1;
    pointer-events: auto;
  }

  /* CONTACT — завжди CTA (заповнена кнопка), без альтернативного
     "top"/"peek"-вигляду. Ті самі селектори, що вимикають/змінюють вигляд
     у десктопному правилі (styles вище), тут продубльовані з тією самою
     специфічністю (4 класи), щоб повернути суцільний CTA-фон у будь-якому
     стані. ::after — вимкнене в "top"/"peek" desktop-правилі (content:none)
     crossfade-шар кнопки — вмикається назад (content:'') і успадковує
     hover/pressed-градієнт із базового .cta-button::after без додаткових
     властивостей тут */
  .header:not(.header--scrolled) .header__contact-link.cta-button,
  .header--scrolled.header--peek .header__contact-link.cta-button {
    background: var(--primary-100);
    color: var(--color-background);
  }

  .header:not(.header--scrolled) .header__contact-link.cta-button:hover,
  .header--scrolled.header--peek .header__contact-link.cta-button:hover,
  .header:not(.header--scrolled) .header__contact-link.cta-button:active,
  .header--scrolled.header--peek .header__contact-link.cta-button:active {
    background: var(--primary-100);
    color: var(--color-background);
  }

  .header:not(.header--scrolled) .header__contact-link.cta-button::after,
  .header--scrolled.header--peek .header__contact-link.cta-button::after {
    content: '';
  }

  /* "top"/"peek"-заливка ::before (окремий hover-шар, актуальний лише для
     прозорого текстового вигляду CONTACT у десктопі) тут не потрібна —
     hover уже покриває crossfade ::after вище */
  .header:not(.header--scrolled) .header__contact-link::before,
  .header--scrolled.header--peek .header__contact-link::before {
    content: none;
  }

  /* Фіксований розмір 126×46px (-1px ширина/-2px висота від попередніх
     127×48px, Фікс) — кнопка тепер вписується ВСЕРЕДИНІ фрейму хедера,
     не перекриваючи верхній/нижній/правий строуки (48px висота = повна
     висота хедера, раніше перекривала inset-строук; align-items:center
     на .header лишає по 1px зверху/знизу автоматично). margin-right
     зменшено з -12px до -11px У ТІЙ САМІЙ пропорції, що ширина (-1px) —
     інакше auto-margin на .header__menu-btn (гумовий простір зліва від
     фрейму меню) компенсував би зміну ширини кнопки і зсунув би ввесь
     правий кластер (фрейм меню + роздільник + CONTACT) на 1px праворуч,
     залишивши правий край кнопки, як і раніше, впритул до строука
     (замість бажаного 1px проміжку) */
  .header__contact-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 126px;
    height: 46px;
    padding: 0;
    margin-left: 0;
    margin-right: -11px;
  }

  /* Фікс: кнопка виглядала 128×48px замість обчислених 127×48px (лише при
     наведенні саме на кнопку — не на іконку меню). Причина — глобальний
     "scrolled" хак вище (рядки 391–397): -1px box-shadow і зсув
     .cta-button::after на -1px зліва компенсують те, що
     .header__divider--contact тримається на margin-left:auto в десктопі
     (auto-margin перерозподіляє будь-яку зміну ширини кнопки назад). Тут,
     у Tablet Portrait, роздільник давно має ФІКСОВАНИЙ margin-left:12px
     (рядок 7658+, не auto) — компенсувати нічого, тому цей хак лише додає
     зайвий 1px зліва (найпомітніше на hover, коли crossfade-шар ::after
     стає видимим). .header--scrolled:not(.header--peek) спрацьовує тут
     так само, як у десктопі (header.js перемикає ці класи лише за
     scrollY, незалежно від ширини в'юпорта) — тому нейтралізуємо обидва
     правила саме в цьому breakpoint'і, не чіпаючи десктопну версію хака */
  .header--scrolled:not(.header--peek) .header__contact-link.cta-button {
    box-shadow: none;
  }

  .header--scrolled:not(.header--peek) .header__contact-link.cta-button::after {
    left: 0;
  }

  /* Hero — фон: той самий "переливання в наступну секцію" принцип, що в
     десктопі/Tablet Landscape — новий tablet-portrait ассет (1920×1080),
     коефіцієнт k = 1080/1024 ≈ 1.0547 (референсний вʼюпорт 1024px
     заввишки → фон 1080px, тобто БІЛЬШЕ за висоту вʼюпорта). height і
     background-size — те саме число (105.47%/105.47vh), решта виходить
     за низ .hero (overflow:visible, успадковано з бази) і лягає під
     Services, без обрізання й без кольорової заливки знизу */
  .hero__bg {
    height: 105.47%;
    background-position: center top;
    background-size: auto calc(105.47vh);
    background-image: url("../assets/images/hero-bg-tablet-portrait.webp");
    background-image: image-set(
      url("../assets/images/hero-bg-tablet-portrait.webp") 1x,
      url("../assets/images/hero-bg-tablet-portrait@2x.webp") 2x
    );
  }

  /* Тайтл — Tablet/H1 (.dm-36-reg, tokens.css) замість десктопного .dm-h1.
     Відступ від лейбла: 10px (12px у десктопі) — боді(18px)/кнопки(32px)
     нижче лишаються тими самими значеннями, що в десктопі, тому окремо
     не перевизначені */
  .hero__title {
    margin-top: 10px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Перемикання розривів тайтла для Tablet Portrait — вмикаємо --2/--4,
     вимикаємо --3 (активний у десктопі/Tablet Landscape за замовчуванням) */
  .hero__title-break--2,
  .hero__title-break--4 {
    display: inline;
  }

  .hero__title-break--3 {
    display: none;
  }

  /* Ручний перенос боді-тексту — вмикається тут (і в Mobile нижче) */
  .hero__desc-break--narrow {
    display: inline;
  }

  /* Позиція текстового блока — 384px від верху / 328px від низу при
     референсній висоті в'юпорта 1024px (384/1024 = 37.5%, 328/1024 ≈
     32.03125%), у % від .hero (сама 100vh/100svh) — той самий прийом, що
     в десктопі/Tablet Landscape, тому масштабується пропорційно висоті
     вікна. Фікс: bottom помилково дублював top (37.5%/37.5%, симетрично)
     замість правильних асиметричних 37.5%/32.03125% */
  .hero__spacer--top {
    height: 37.5%;
  }

  .hero__spacer--bottom {
    height: 32.03125%;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 157: секція Services, права частина
   (Home)

   Спершу тут працювали лише над тайтлом/боді-текстом/номером/табличкою —
   ілюстрацію-квітку (.services__illustration-*, .services__tag) свідомо
   не займали, додана нижче окремим фіксом.

   Десктопний 2-колонковий патерн (лейбл+номер у ряд 1, тайтл на всю
   ширину в ряд 2, опис праворуч у ряд 3) тут не застосовується: номер/
   тайтл/боді-текст/табличка всі починаються з тієї самої лівої межі —
   колонки 3 нової 4-колонкової сітки (155px, gutter 16px, 668px).
   Лейбл ("SERVICES") лишається на колонці 1 — успадковує спільне правило
   .services__label вище (Крок 157 його не чіпає, у завданні не згаданий).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .services__intro-grid,
  .services__panel-grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) */
  .services__index {
    grid-column: 3;
  }

  /* Фікс: тайтл починається з КОЛОНКИ 1 (0px), а не 3 — окремий блок від
     номера/боді-тексту/таблички (лишаються на колонці 3, без змін).
     Колонки 1–2 = 326px (155 + 16 + 155) — та сама ширина, що була раніше,
     просто зсунута на початок сітки. Tablet/H2 (.dm-30-reg, tokens.css)
     замість десктопного .dm-h2 */
  .services__title {
    grid-column: 1 / 3;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, та сама колонка 3/5, що й номер/табличка.
     Фікс: ручний перенос рядків, специфічний для цього breakpoint —
     .services__desc-break--1/--3/--6 (той самий tablet-break прийом, що
     .services-hero__title-break--tablet/--desktop, Крок 149) */
  .services__desc {
    grid-column: 3 / 5;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  .services__desc-break--1,
  .services__desc-break--3,
  .services__desc-break--6 {
    display: inline;
  }

  .services__desc-break--2,
  .services__desc-break--4 {
    display: none;
  }

  /* Табличка — та сама колонка 3/5 (342px → 668px, до кінця сітки), 326px
     ширини. margin-top: 111px від низу боді-тексту до верху таблички —
     той самий прийом sticky-піну, що й 119px (десктоп) / 104px (Tablet
     Landscape, Крок 133): панель починається рівно там, де закінчується
     опис, тому цей margin-top візуально й є відступом опис→табличка.
     height: 778px — фолбек/дизайнерський максимум для цього діапазону
     ширин; РЕАЛЬНЕ значення далі рахує й підставляє js/services-table.js
     (не чіпаємо — дистанція гортання/таймінги/тригери 1:1 як у десктопі) */
  .services-table-window {
    grid-column: 3 / 5;
    margin-top: 111px;
    width: 326px;
    height: 778px;
  }

  /* Фікс: той самий підхід, що на десктопі/Tablet Landscape (активний чіп
     без нижнього строука, фрейм тайтла 62px + лейбл, фрейм айтема Red
     Hat/12 Bold (tracking), лівий градієнтний строук на весь блок) —
     єдина відмінність тут: висота фрейму айтема 56px (68px у Tablet
     Landscape). Блок сервісу разом: 62 (тайтл) + 40 (патерн, успадковано
     з базового .services-table__row--strokes) + 56 (айтем) + 56 (пустий
     фрейм, успадковано з базового .services-table__row--empty) = 214px.
     Замінює попередній варіант (DM Sans/16 Reg, 24px padding-left) —
     той стиль тепер вважається застарілим щодо узгодженої ревізії */
  .services__tag--active::after {
    display: none;
  }

  .services-table__row--heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 62px;
    padding: 0 32px;
  }

  .services-table__heading-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--grey-100);
  }

  .services-table__heading-label {
    display: inline-block;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-50);
  }

  .services-table__row--item {
    height: 56px;
    padding: 0 0 0 32px;
    display: flex;
    align-items: center;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-55);
  }

  .services-table__group {
    position: relative;
  }

  .services-table__group::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--primary-grad-services);
    opacity: 0;
    transition: opacity .65s var(--ease-smooth);
  }

  .services-table__group:has(.services-table__row--item.is-active)::before {
    opacity: 1;
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — той самий
     880×880px (0.8661 від десктопних 1016px), що на Tablet Landscape.
     margin-top:50px (фікс: замінює попередні 166px) — відступ від
     боді-тексту секції до верху ілюстрації (той самий "row", що й
     .services-table-window вище). Горизонталь: правий край на 46px
     лівіше лівого краю таблички (342px, колонка 3) →
     margin-left = 342 − 46 − 880 = −584px */
  .services__illustration-stack {
    width: 880px;
    height: 880px;
    margin-top: 50px;
    margin-left: -584px;
  }

  .services__illustration-base,
  .services__illustration-mask {
    width: 880px;
    height: 880px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 162: секція Trusted By (Home,
   index.html лише)

   Фікс: скасовує весь попередній підхід із Кроків 158/161 (marquee-
   автоскрол, клоновані логотипи для безшовного лупу, full-bleed на всю
   ширину в'юпорта). Секція повертається в межі сітки (668px, центр,
   offset 0 — як решта секцій сторінки) і використовує ту саму статичну
   розмітку/логіку, що на десктопі (.trusted-by__logos — CSS grid з
   .trusted-by__lines-оверлеєм ліній, той самий hover білий/чорний
   варіант логотипа), БЕЗ анімації.

   about.html ділить ті самі BEM-класи (.trusted-by, .trusted-by__grid,
   .trusted-by__logos...), тому всі правила нижче скоуплені через
   ".services + .trusted-by" — суміжний селектор, що збігається лише з
   Trusted By, який ІДЕ ОДРАЗУ ЗА Services (це структурно тільки
   index.html: about.html — about-hero → trusted-by, без .services
   узагалі). about.html лишається desktop-версією на цьому breakpoint —
   окремий крок пізніше.

   Фікс (замінює попередній підхід "16 логотипів на 4 ряди"): показуємо
   лише ПЕРШІ 8 логотипів (той самий порядок, що на десктопі) — 2 ряди по
   4, замість повної сітки. Логотипи 9–16 (nth-child(n+9)) — display:none,
   не займають місця в grid auto-flow. Розмір клітинки/логотипа — 155×155px
   (144×144px у попередній версії), gap — 16px в обидва боки (було 20px):
   4×155 + 3×16 = 668px, точно ширина сітки, без залишку.
   .trusted-by__lines — той самий оверлей із суцільних 1px-шарів
   (перерахований під нову геометрію 4×2/155/16, 326px висота групи):
   - 8 вертикальних (на всю висоту групи, 326px): 2 краї + 2 на кожен з
     3 внутрішніх гаттерів (155/171, 326/342, 497/513)
   - 3 горизонтальних на всю ширину (668px): y=0 (верх), y=155 (низ
     ряду 1), низ групи (326)
   - 4 горизонтальних відрізки 155px завширшки — по одному на колонку,
     на y=171 (верх ряду 2) — той самий принцип, що в десктопі (рядок,
     що йде нижче гаттера, отримує повну лінію лише під власними
     клітинками, гаттер лишається відкритим, бо вже перекритий
     вертикальними лініями на всю висоту)
   nth-child(4n)/(n+5) — останні колонка/рядок для 4×2 (замість 8n/n+9
   у 8×2 десктопу, лише інша кількість колонок): останній стовпець
   кожного ряду не отримує зайвого +1px hover-розширення праворуч,
   останній (2-й) рядок — знизу. Той самий принцип, що
   .trusted-by__logo-cell::after у базовому CSS.

   Фікс: та сама ротація групами по 8 кожні 7с (js/trusted-by-rotate.js,
   тепер розширений на 768–1023px), що на Mobile — crossfade на
   .trusted-by__logo-wrap (не на .trusted-by__logo-cell/фрейм — той
   лишається повністю статичним, hover-фон ::after ніколи не анімується
   разом із логотипом).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .services + .trusted-by {
    /* Фікс: 80px від нижнього краю ілюстрації Services до верху Trusted By —
       тепер лише CSS-фолбек. js/services-table.js рахує ТУТ реальний
       inline marginTop динамічно (formula компенсує звис ілюстрації за
       межу 100vh-панелі — фіксоване число тут давало РЕАЛЬНИЙ відступ
       менший за заявлений, напр. 25px замість 80px) */
    margin-top: 80px;
  }

  .services + .trusted-by .trusted-by__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     .services__index (Крок 157). Текстовий стиль номера — без змін */
  .services + .trusted-by .trusted-by__index {
    grid-column: 3;
  }

  .services + .trusted-by .trusted-by__logos {
    grid-column: 1 / 5;
    grid-row: 2;
    margin-top: 16px;
    grid-template-columns: repeat(4, 155px);
    grid-template-rows: repeat(2, 155px);
    gap: 16px;
  }

  .services + .trusted-by .trusted-by__logo-cell,
  .services + .trusted-by .trusted-by__logo {
    width: 155px;
    height: 155px;
  }

  /* Лише перші 8 логотипів (2 ряди по 4) — решта приховані, не займають
     місця в grid auto-flow */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(n + 9) {
    display: none;
  }

  /* Останній стовпець кожного ряду (4, 8) — права лінія групи вже
     всередині власного діапазону блока (0 замість -1px, див. базовий
     .trusted-by__logo-cell::after) */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(4n)::after {
    right: 0;
  }

  /* Другий (останній) ряд (5–8) — нижня лінія групи вже всередині
     власного діапазону блока */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(n + 5)::after {
    bottom: 0;
  }

  .services + .trusted-by .trusted-by__lines {
    background-size:
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      668px 1px,
      668px 1px,
      668px 1px,
      155px 1px,
      155px 1px,
      155px 1px,
      155px 1px;
    background-position:
      0px 0,
      155px 0,
      171px 0,
      326px 0,
      342px 0,
      497px 0,
      513px 0,
      right 0px top 0,
      0 0px,
      0 155px,
      left 0 bottom 0px,
      0px 171px,
      171px 171px,
      342px 171px,
      513px 171px;
  }

  /* Crossfade під час ротації (js/trusted-by-rotate.js) — на
     .trusted-by__logo-wrap, не на .trusted-by__logo-cell (фрейм лишається
     статичним, hover-фон ::after ніколи не рухається/не гасне разом із
     логотипом). Той самий принцип/easing/значення, що Mobile */
  .services + .trusted-by .trusted-by__logo-wrap {
    will-change: opacity, transform;
    transition: opacity 650ms var(--ease-smooth), transform 650ms var(--ease-smooth);
  }

  .services + .trusted-by .trusted-by__logo-wrap--fading {
    opacity: 0;
    transform: translateY(12px);
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 159: секція Selected Work (Home)

   work.html перевикористовує ці самі класи карток/патернів/
   .selected-work__cards/.selected-work__col-secondary/.selected-work__row2
   (той самий факт, що вже задокументований для Tablet Landscape, Крок 135) —
   тому всі спільні класи нижче скоуплені під предком .selected-work
   (є лише в index.html; work.html обгортає ті самі елементи в .work-hero).
   .selected-work__grid/__index/__title/__desc/__row3 унікальні лише для
   index.html, як і в Кроці 135, — лишаються без скоупу.

   На відміну від Tablet Landscape (Крок 135, де десктопна структура
   ряд-primary+secondary/ряд2/ряд3 лишається, лише звужена) — тут ЄДИНА
   колонка: усі 5 айтемів (+ SEE ALL OUR WORK) просто йдуть один під одним
   на всю ширину сітки, без патернів-заповнювачів. Замість переписування
   розмітки — display: contents на всіх трьох обгортках (.selected-work__cards/
   __col-secondary/__row2/__row3, той самий прийом, що .header__brand,
   Крок 156) "розкриває" їх, і 5 .work-card + .see-all-work стають прямими
   flex/grid-дітьми .selected-work__grid у справжньому DOM-порядку —
   рівно тому порядку, що потрібен (Hermes→Obviant→Clair→Aurelia→
   Transcarent→SEE ALL). Приховані патерни (display:none) не займають
   місця в auto-flow, тому не лишають зайвих проміжків.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 100px від низу Trusted By до верху лейбла/номера Selected Work
     (.selected-work — bare-клас, унікальний лише для index.html, той
     самий факт, що вже підтверджений у Кроці 135, — скоуп не потрібен) */
  .selected-work {
    margin-top: 100px;
  }

  .selected-work__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Лейбл уже на колонці 1 за замовчуванням (успадковане спільне правило,
     без змін) — тайтл починається там само. Колонки 1–2 = 326px, той
     самий принцип/ширина, що тайтл Services (Крок 157-фікс, п.1) —
     явного значення ширини в цьому завданні не задано, тому орієнтуємось
     на вже узгоджений розмір цієї ж текстової зони на Services */
  .selected-work__title {
    grid-column: 1 / 3;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     номер/боді-текст Services (Крок 157, п.3) */
  .selected-work__index {
    grid-column: 3;
  }

  .selected-work__desc {
    grid-column: 3 / 5;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Свій перенос боді-тексту Selected Work на Tablet Portrait (5 рядків
     замість 4) — вмикає --1/--3/--5/--7, вимикає --2/--4/--6 (той самий
     tablet-break прийом, що Services) */
  .selected-work__desc-break--1,
  .selected-work__desc-break--3,
  .selected-work__desc-break--5,
  .selected-work__desc-break--7 {
    display: block;
  }

  .selected-work__desc-break--2,
  .selected-work__desc-break--4,
  .selected-work__desc-break--6 {
    display: none;
  }

  /* "Розкриває" обгортки — їхні власні grid-row/column/margin/padding
     більше не рендеряться (display: contents прибирає власний бокс),
     значення мають лише властивості самих карток/CTA-плашки нижче */
  .selected-work .selected-work__cards,
  .selected-work .selected-work__col-secondary,
  .selected-work .selected-work__row2,
  .selected-work .selected-work__row3 {
    display: contents;
  }

  /* Без патернів-заповнювачів у цьому breakpoint (п.5) */
  .selected-work .selected-work__strokes,
  .selected-work .selected-work__pattern {
    display: none;
  }

  /* Кожен айтем — на всю ширину сітки (668px, колонки 1–4). Специфічність
     двох класів (.selected-work + .work-card) вища за десктопні
     .work-card--primary/--secondary (по одному класу), тому одного
     правила досить для ОБОХ типів картки — не треба дублювати під
     кожен модифікатор окремо */
  .selected-work .work-card {
    grid-column: 1 / 5;
    width: 100%;
  }

  /* 56px від низу боді-тексту до верху ПЕРШОГО айтема (Hermes,
     work-card--primary — єдина картка з цим модифікатором) */
  .selected-work .work-card--primary {
    margin-top: 56px;
  }

  /* 44px між усіма рештою айтемів (усі --secondary в порядку DOM:
     Obviant→Clair→Aurelia→Transcarent) — та сама відстань, що й до
     SEE ALL OUR WORK нижче */
  .selected-work .work-card--secondary {
    margin-top: 44px;
  }

  /* Фото — власний оригінальний aspect-ratio КОЖНОГО типу айтема
     (720:564 великого/primary, 424:332 малого/secondary — desktop-
     розміри цих же карток), а не єдиний спільний коефіцієнт: aspect-ratio
     замість фіксованої height прибирає похибку округлення на новій
     668px ширині (≈523px висоти для обох типів, тому лінія межі щоразу
     трохи різна навіть попри майже однакове відношення сторін) */
  .selected-work .work-card--primary .work-card__image {
    aspect-ratio: 720 / 564;
    height: auto;
  }

  .selected-work .work-card--secondary .work-card__image {
    aspect-ratio: 424 / 332;
    height: auto;
  }

  /* Фікс: SEE ALL OUR WORK — з десктопної великої картки-плейсхолдера
     (424×520, тонкий border) стає секондарі-кнопкою. Текст/іконка (flex,
     align-items/justify-content:center, gap:10px) успадковані з
     .see-all-work — лишаються без змін, центрування вже було. 213×48px,
     44px від низу останнього айтема (Transcarent) */
  /* Фікс: кнопка була притиснута до лівого краю грід-área (1/5) — grid-item
     з фіксованою шириною за замовчуванням вирівнюється по start, не
     stretch. justify-self:center центрує 213px-кнопку відносно ширини
     сітки (668px) */
  /* Фікс: нові стейти глобального .secondary-button (нижній градієнтний
     строук прибрано; hover/pressed — фон var(--grey-20); pressed —
     колір тексту/іконки var(--grey-additional-pressed); disabled — фон
     var(--grey-15) + колір var(--grey-additional-disabled)) — .see-all-work
     не є .secondary-button (десктопна велика картка-плейсхолдер має
     інший вигляд, той стиль тут не чіпаємо), тому стейти продубльовано
     тут з тими самими токенами */
  .selected-work .see-all-work {
    grid-column: 1 / 5;
    justify-self: center;
    width: 213px;
    height: 48px;
    margin-top: 44px;
    border: none;
    background: var(--grey-15);
    color: var(--grey-100);
    transition: background-color 300ms ease, color 300ms ease;
  }

  .selected-work .see-all-work::after {
    display: none;
  }

  .selected-work .see-all-work:hover {
    background: var(--grey-20);
  }

  .selected-work .see-all-work:active {
    background: var(--grey-20);
    color: var(--grey-additional-pressed);
  }

  .selected-work .see-all-work:disabled,
  .selected-work .see-all-work.is-disabled {
    background: var(--grey-15);
    color: var(--grey-additional-disabled);
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 160: секція CTA з китом (Home)

   .cta (bare-клас) перевикористовується на інших сторінках (about/contact/
   services/work — там своя окрема секція перед ним, не .selected-work),
   тому скоуп через суміжний селектор .selected-work + .cta — той самий
   прийом, що вже є в коді для Tablet Landscape (Крок 136) і Крокив 158/159
   цього ж breakpoint'а. Матчиться лише на index.html.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .selected-work + .cta {
    /* 48px від низу останнього айтема робіт до верху фону секції
       (margin-top:0 у десктопі — фон впритул) */
    margin-top: 48px;

    /* 92px від низу останнього айтема робіт до верху тайтла: рахується
       від верху СЕКЦІЇ (уже зсунутої на 48px через margin-top вище),
       тому тут 92 − 48 = 44px, а не 92px напряму */
    padding-top: 44px;

    /* Контейнер точно дорівнює висоті фону (1020px у десктопі, 765px на
       Tablet Landscape, той самий принцип тут) — інакше під зображенням
       лишався б порожній хвіст фону секції */
    height: 544px;

    /* Той самий кит, той самий "fixed, no scale" принцип і вирівнювання
       (center top, no-repeat, успадковані з базового правила) — просто
       менший фіксований розмір. Новий файл не потрібен — той самий
       whale-bg.webp/@2x через успадкований image-set */
    background-size: 1024px 544px;
  }

  /* Тайтл — Tablet/H1 (.dm-36-reg, tokens.css) замість десктопного .dm-h0 —
     той самий клас/значення, що hero-тайтл на Home (Крок 156, п.1) */
  .selected-work + .cta .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* 32px від тайтла до кнопки (44px у десктопі — те саме правило спільне
     з CTA-2, .cta--second, тому тут скоупимо явно, щоб не зачепити її).
     Сама кнопка — розмір/стилі/стейти без змін, успадковані з десктопу */
  .selected-work + .cta .cta__btn {
    margin-top: 32px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 161: секція Industries (Home)

   .industries/.industry-row/.industries__list/.industries__globe-stack
   перевикористані 1:1 на services.html (.industries--services) — тому
   скоуп через суміжний селектор .cta + .industries, той самий прийом,
   що вже в Кроці 137 (Tablet Landscape) і Кроках 157–160 цього ж
   breakpoint'а. На services.html Industries іде одразу після
   .services-hero, тому цей селектор там ніколи не збігається.

   Ілюстрації-літери: перевикористані готові tablet-файли (40×50px,
   image-set 1x/2x) з Кроку 137/152 — розмір ідентичний, новий експорт
   не потрібен.

   На відміну від Tablet Landscape (Крок 137, де висота фрейму — auto,
   112/142px залежно від 1/2 рядків тегів), тут ОДНА фіксована висота
   138px для всіх фреймів незалежно від кількості рядків тегів: 25
   (відступ тайтла) + 24 (рядок тайтла, .rh-16-sb) + 17 (відступ тегів) +
   48 (2 рядки тегів по 20px, row-gap 8px) + 24 (запас до строука) = 138.
   Строук — position:absolute; bottom:0 (без змін відносно бази/Кроку 137),
   тому для айтемів з ОДНИМ рядком тегів (Cybersecurity, Proptech) запас
   до строука природно більший за 24px — очікувано й не потребує окремої
   обробки.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 30px від нижнього краю фону CTA (висота 544px, Крок 160) до верху
     лейбла Industries — звичайний margin-top, секції йдуть впритул одна
     за одною в потоці документа */
  .cta + .industries {
    margin-top: 30px;
  }

  .cta + .industries .industries__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Лейбл лишається на колонці 1 (0px) — успадковане спільне правило,
     без змін. Тайтл — та сама колонка 1/2 (326px) і Tablet/H2
     (.dm-30-reg, tokens.css), що тайтли Services/Selected Work
     (Кроки 157/159) */
  .cta + .industries .industries__title {
    grid-column: 1 / 3;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     номер/боді-текст Services/Selected Work */
  .cta + .industries .industries__index {
    grid-column: 3;
  }

  /* Боді-текст — та сама колонка 3/5 (326px) і DM Sans/16 Light
     (.dm-16-light, tokens.css), що Services/Selected Work. Текст —
     той самий, що на десктопі (HTML без змін) */
  .cta + .industries .industries__desc {
    grid-column: 3 / 5;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Список фреймів — колонки 1/2 (326px, та сама ширина, що тайтл),
     72px від низу боді-тексту до верху першого фрейму */
  .cta + .industries .industries__list {
    grid-column: 1 / 3;
    margin-top: 72px;
  }

  /* Глобус: 24px від низу боді-тексту (замість 6px у десктопі/0px на
     Tablet Landscape), 358px від лівого краю сітки (326 + 32, замість
     792/534px) — розмір 786×786 без змін (успадкований з бази) */
  .cta + .industries .industries__globe-stack {
    margin-top: 24px;
    margin-left: 358px;
  }

  /* Фрейм — фіксована висота 138px (не auto, на відміну від Tablet
     Landscape) — див. арифметику в коментарі блоку вище. Gap між
     фреймами — 0px, той самий принцип, що на Tablet Landscape
     (звичайний потік, без margin між .industry-row) */
  .cta + .industries .industry-row {
    height: 138px;
  }

  /* Контент — на всю ширину фрейму (326px), 25px відступу зверху до
     тайтла (той самий прийом, що Крок 137, лише інше числове значення) */
  .cta + .industries .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 25px;
  }

  /* Тайтл — Red Hat/16 SB (.rh-16-sb, tokens.css) замість десктопного
     варіанту з line-height (.rh-16-sb-lh, 34px) — тут звичайний 24px */
  .cta + .industries .industry-row__title {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 16px;
    line-height: 24px;
    letter-spacing: 0.12em;
  }

  /* Теги — DM Sans/14 Light (.dm-14-light, tokens.css) замість
     десктопного .dm-16-light. 17px від тайтлу до тегів. flex-wrap +
     row-gap:8px — перенос на другий рядок, якщо не влазять у 326px
     (горизонтальний gap між тегами/крапками — 20px, успадкований) */
  .cta + .industries .industry-row__tags {
    margin-top: 17px;
    flex-wrap: wrap;
    row-gap: 8px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Немає надійного hover на Tablet (дотик) — активний рядок керується
     скролом (js/industries-tablet-scrolly.js через .is-active), той
     самий dim/bright принцип, що вже реалізований на Mobile нижче:
     дефолт приглушений (grey-50), .is-active — повна яскравість */
  .cta + .industries .industry-row__title {
    color: var(--grey-50);
  }

  .cta + .industries .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .cta + .industries .industry-row__tags {
    color: var(--grey-50);
  }

  .cta + .industries .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .cta + .industries .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
  }

  .cta + .industries .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  /* Строук на всю ширину фрейму (326px) — той самий прийом (0/0), що
     Tablet Landscape, замість десктопного інсету під колишню ілюстрацію */
  .cta + .industries .industry-row__divider {
    left: 0;
    right: 0;
  }

  /* Старі десктопні <img> (без ретини) — приховані, замість них
     tablet-псевдоелементи нижче (той самий принцип, що Крок 137) */
  .cta + .industries .industry-row__illustration {
    display: none;
  }

  /* Ілюстрація-літера: правий верхній кут фрейму (40×50, absolute, 12px
     від верху, впритул до правого краю фрейму = правий край колонки 2) —
     ті самі значення й ті самі tablet-файли, що Tablet Landscape (Крок 137) */
  .cta + .industries .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .cta + .industries .industry-row__illustration-wrap::before,
  .cta + .industries .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .cta + .industries .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .cta + .industries .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  /* Порядок рядків фіксований у розмітці: F, H, E, C, P — nth-child
     замість нових класів на .industry-row__illustration-wrap (та сама
     розкладка асетів, що Крок 137) */
  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 162: секція Offices (Home)

   .offices (bare-клас) унікальний для index.html (той самий факт, що вже
   підтверджений у Кроці 138 для Tablet Landscape) — жодного суміжного
   селектора-скоупу не потрібно.

   Ряд London/New York — раніше (десктоп/Tablet Landscape) flex + margin-
   left, порахований від РЕАЛЬНОЇ рендер-ширини попереднього тайтлу.
   Тут — фіксовані пиксельні колонки (0/342px, п.4), тому .offices__titles
   стає власною вкладеною сіткою 4×155/16 (та сама геометрія, що
   .offices__grid), з London/New York явно на колонках 1/3 рядка 1,
   а Kyiv — явно на колонці 1 рядка 2 (46px margin-top, п.5 — див. фікс
   нижче: 46px, а не 64px, бо форсований min-height:170px рядка 1 лишає
   18px "слеку" нижче реального боді-тексту London).

   .offices__subtitle/__body — БЕЗ ЗМІН: успадковані як є з десктопу
   (Tablet Landscape їх так само не чіпав).

   Фікс (перенесено з about.html, де ці 4 пункти були помилково
   застосовані до .about-offices__*): відступ тайтл→квадратик 11px і
   строук→лейбл 20px (замість успадкованих десктопних 64/68/92px,
   виведених з 52px line-height десктопного .dm-h1, а не 42px нового
   .dm-36-reg) — marker top = 42+11=53, line top = 53+4=57 (той самий
   +4px принцип, що десктопні 64→68), city-info top = 57+1+20=78.
   Kyiv (рядок 2) отримує власний горизонтальний строук через
   ::before (у розмітці немає власного .offices__line — той єдиний
   екземпляр у DOM належить рядку 1 і не дотягується до рядка 2):
   той самий top:57 (row-relative відносно .offices__city--kyiv,
   яка position:relative), ширина — від лівого краю сітки (0px,
   збігається з лівим краєм .city--kyiv) до початку 3-ї колонки
   (342px). Кнопка "More about us" (.offices__arrow-box, той самий
   HTML-елемент, що вже існує на десктопі/Mobile) виходить з
   десктопної 44×44-іконки в повноцінну кнопку 326×48: left:342px
   (лівий край 3-ї колонки), top так, щоб нижній піксель кнопки
   збігався з Kyiv-строуком (row2-top 216 + 57 + 1 = 274 → button
   top = 274−48 = 226), текст/іконка — 20px відступів з обох боків
   (padding:0 20px + justify-content:space-between).

   .offices__city-info — position:absolute відносно ВЛАСНОГО
   .offices__city (не бере участі в потоці), тому автоматична висота
   рядка 1 вкладеної сітки (.offices__titles) без явного min-height на
   .offices__city дорівнювала б лише висоті рядка тайтлу (42px). Тому
   .offices__city отримує min-height:170px (той самий орієнтир, що
   десктопний .offices__cities) — це й дає "низ 1-го рядка" для Kyiv.

   Фікс (відступ боді-текст London → тайтл Kyiv, п.5): реальний низ
   .offices__body Лондона (виміряно через getBoundingClientRect) лежить
   на 18px ВИЩЕ форсованого низу 170px-вого min-height (боді-текст —
   лише 2 рядки, не дотягується до самого низу інфо-блоку). Тому
   margin-top Kyiv — 46px (не 64px): 46 + 18px "слеку" від min-height
   дають РЕАЛЬНИЙ відступ рівно 64px. Рядок 1 = 170px, Kyiv-топ =
   170+46=216px. .offices__cities.min-height — до НИЗУ інфо-блоку Kyiv:
   216+170=386px (а не десктопні 170px — там усі 3 міста в одному
   рядку, тут Kyiv у другому) */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 78px від нижнього краю ілюстрації-глобуса Industries (Крок 161) до
     верху лейбла Offices. Глобус (810px від верху рядка 4: 24 margin +
     786 висота) вищий за список фреймів (762px: 72 margin + 5×138) —
     тому низ .industries (секції) вже й є низом глобуса, компенсація,
     як у Кроці 138, не потрібна: простий margin-top у звичайному потоці */
  .offices {
    margin-top: 78px;
  }

  .offices__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Лейбл лишається на колонці 1 (0px) — успадковане спільне правило,
     без змін. Тайтл — та сама колонка 1/2 (326px) і Tablet/H2
     (.dm-30-reg, tokens.css), що тайтли Services/Selected Work/Industries */
  .offices__title {
    grid-column: 1 / 3;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     номер/боді-текст Services/Selected Work/Industries */
  .offices__index {
    grid-column: 3;
  }

  /* Боді-текст — та сама колонка 3/5 (326px) і DM Sans/16 Light
     (.dm-16-light, tokens.css), що Services/Selected Work/Industries.
     Фікс: ручний перенос рядків, специфічний для цього breakpoint —
     .offices__desc-break--desktop/--portrait (той самий tablet-break
     прийом, що .industries__desc-break--desktop/--portrait) */
  .offices__desc {
    grid-column: 3 / 5;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  .offices__desc-break--desktop {
    display: none;
  }

  .offices__desc-break--portrait {
    display: inline;
  }

  /* Колонки 1/4 (668px, на всю ширину сітки) — контейнер під вкладену
     сітку рядка тайтлів нижче. 80px від низу боді-тексту до верху
     першого рядка (Лондон/Нью-Йорк). min-height — див. арифметику в
     коментарі блоку вище (386px, а не десктопні 170px) */
  .offices__cities {
    grid-column: 1 / 5;
    margin-top: 80px;
    min-height: 386px;
  }

  /* Власна вкладена сітка 4×155/16 (та сама геометрія, що .offices__grid) —
     замість десктопного flex-рядка. London (без модифікатора) лишається
     на колонці 1/рядку 1 за замовчуванням (перша в DOM, авто-розстановка).
     min-height:170px на КОЖНОМУ місті (London/New York/Kyiv) — реальний
     "низ рядка" для відступу Kyiv (п.5, див. коментар блоку вище) замість
     висоти самого лише тайтлу (42px) */
  .offices__titles {
    display: grid;
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
  }

  .offices__city {
    min-height: 170px;
  }

  /* New York — явно колонка 3 (342px), рядок 1 — замість margin-left,
     порахованого від ширини "London" */
  .offices__city--ny {
    grid-column: 3;
    grid-row: 1;
    margin-left: 0;
  }

  /* Kyiv — колонка 1 (0px), рядок 2. Фікс: 46px (не 64px) — реальний
     низ .offices__body Лондона лежить на 18px ВИЩЕ форсованого низу
     170px-вого min-height рядка 1 (боді-текст London — лише 2 рядки,
     не дотягується до самого низу інфо-блоку), тому 46px margin-top +
     18px "слек" від min-height дають РЕАЛЬНИЙ відступ боді-текст→тайтл
     Kyiv рівно 64px (перевірено виміром реального bounding rect) */
  .offices__city--kyiv {
    grid-column: 1;
    grid-row: 2;
    margin-top: 46px;
    margin-left: 0;
  }

  /* Тайтли міст — Tablet/H1 (.dm-36-reg, tokens.css), той самий клас/
     значення, що hero-тайтл (Крок 156, п.1) і тайтл CTA (Крок 160),
     замість десктопного .dm-h1 (п.6) */
  .offices__city-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Фікс: відступ тайтл→квадратик 11px (42px line-height тайтла + 11) */
  .offices__marker {
    top: 53px;
  }

  /* Фікс: той самий +4px зсув строука відносно квадратика, що в десктопі
     (64→68) — тут 53→57 */
  .offices__line {
    top: 57px;
  }

  /* Фікс: відступ строук→лейбл 20px (57 top строука + 1 товщина + 20) */
  .offices__city-info {
    top: 78px;
  }

  /* Фікс: власний горизонтальний строук для Kyiv (рядок 2) — єдиний
     .offices__line у розмітці належить рядку 1 і не дотягується сюди.
     top:57 — той самий row-relative y, що марker/line вище (Kyiv не має
     власного зсуву top:0, тому офсет рахується відносно самого
     .offices__city--kyiv). Ширина — від лівого краю сітки (0px,
     збігається з лівим краєм .city--kyiv, колонка 1) до початку
     3-ї колонки (342px) */
  .offices__city--kyiv::before {
    content: "";
    position: absolute;
    left: 0;
    top: 57px;
    width: 342px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Кнопка "More about us" (.offices__arrow-box) — з absolute-іконки
     44×44 (десктоп) стає повноцінною кнопкою: з лівого краю 3-ї колонки
     сітки (342px, збігається з правим краєм строука Kyiv вище), ширина
     2 колонки (326px, 342→668px). Нижній піксель кнопки збігається зі
     строуком Kyiv: низ строука = 216 (низ рядка 1, фікс — margin-top
     Kyiv 46px замість 64px) + 57 (kyiv-строук top) + 1 = 274;
     button.top = 274 − 48 = 226.
     Фікс: текст 20px від лівого краю кнопки, іконка 20px від правого —
     кожен притиснутий до свого краю (justify-content:space-between +
     padding:0 20px), а не згруповані по центру */
  .offices__arrow-box {
    top: 226px;
    left: 342px;
    right: auto;
    width: 326px;
    height: 48px;
    justify-content: space-between;
    padding: 0 20px;
    border-bottom: none;
  }

  .offices__arrow-text {
    display: block;
  }
}

/* ==========================================================================
   DESKTOP (≥1280px) + TABLET LANDSCAPE (1024–1279px) — секція Offices:
   нові стейти кнопки-стрілки "More about us" (.offices__arrow-box),
   окремі від спільних .secondary-button (styles.css вище, Крок 103) —
   Hover/Pressed отримують акцентний фон var(--primary-pressed) замість
   нейтрального var(--grey-20), а іконка стрілки зсувається на 2px вправо
   (менш помітний рух, ніж 5px у Hero CTA "Start project") —
   плавно на hover, миттєво (без transition) на pressed. Однакова
   специфічність із .secondary-button:hover/:active/:disabled (клас +
   псевдо-клас) — перемагає порядком у файлі (нижче в каскаді), без
   потреби у вищій специфічності. Tablet Portrait/Mobile — та сама кнопка
   стає повнорозмірною й лишається на спільних .secondary-button стейтах
   (не чіпається) */
@media (min-width: 1024px) {
  .offices__arrow-icon {
    transition: transform 220ms var(--ease-smooth);
  }

  .offices__arrow-box:hover {
    background: var(--primary-pressed);
    color: var(--color-background);
  }

  .offices__arrow-box:hover .offices__arrow-icon {
    transform: translateX(2px);
  }

  .offices__arrow-box:active {
    background: var(--primary-pressed);
    color: var(--color-background);
  }

  /* Pressed — та сама позиція іконки (2px), але без transition (миттєво) */
  .offices__arrow-box:active .offices__arrow-icon {
    transition: none;
    transform: translateX(2px);
  }

  .offices__arrow-box:disabled,
  .offices__arrow-box.is-disabled {
    background: var(--grey-15);
    color: var(--grey-additional-disabled);
  }

  .offices__arrow-box:disabled .offices__arrow-icon,
  .offices__arrow-box.is-disabled .offices__arrow-icon {
    transform: none;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 163: секція CTA-2 (Home)

   .cta--second перевикористовується на about/contact/services/work.html —
   тут скоуп через .offices + .cta--second, той самий прийом, що вже в
   Кроці 139 (Tablet Landscape) і Крокив 157–162 цього ж breakpoint'а.
   Матчиться лише на index.html.

   Фон (cta2-bg.webp/@2x) — той самий файл, лише CSS-масштаб 1440×624
   (та сама пропорція 1920:832 = 1440:624, що вже в Кроці 139) — новий
   ассет не потрібен. height дорівнює висоті фону (той самий принцип,
   що в Кроці 139/160).

   Тайтл — Tablet/H1 (.dm-36-reg, tokens.css), той самий клас/значення,
   що hero-тайтл (Крок 156, п.1), CTA-1 (Крок 160) і тайтли міст Offices
   (Крок 162, п.6), замість десктопного .dm-h0. Позиція — по центру
   секції: висота контенту (2 рядки тайтлу × 42px + 44px відступ + 48px
   кнопка = 176px), padding-top = (624 − 176) / 2 = 224px. Кнопка —
   без змін (спільне правило .cta__btn: margin-top:44px, width:239px,
   успадковане з десктопу, п.3) */

@media (min-width: 768px) and (max-width: 1023px) {

  .offices + .cta--second {
    /* Фікс: тут Offices — 2-рядковий layout (London/New York — рядок 1,
       Kyiv+кнопка "More about us" — рядок 2, нижче London на ~216px,
       Крок 162). 80px від низу боді-тексту Kyiv (не London — інакше
       CTA-2 перекрила б Kyiv/кнопку) до верху фону CTA-2: виміряно 98px
       при 80px margin-top → 62px компенсує 18px різниці */
    margin-top: 62px;
    /* Фікс: 362px від верху ілюстрації до тайтла + 100px від низу кнопки
       до низу ілюстрації (однаково на 4 сторінках із CTA-2) — при
       незмінних тайтл/кнопка/32px-відступі висота контенту фіксована
       (~165px), тому висота секції росте на ту саму дельту понад
       background-size (624px); зайвий простір знизу — той самий
       background-color (var(--color-background)), що вже й так
       обрамляє фон, тому непомітний */
    height: 628px;

    /* Фікс: 362px від верху фону до тайтла (502px на десктопі, 361px на
       Tablet Landscape) */
    padding-top: 362px;
    background-size: 1440px 624px;
  }

  .offices + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Фікс: тайтл→кнопка — 32px (44px база, .cta__btn, успадковане з
     десктопу) */
  .offices + .cta--second .cta__btn {
    margin-top: 32px;
  }

  /* ФІКС — той самий готовий блок для about.html (Offices секція йде
     одразу перед CTA-2, як і на index.html): 80px від низу Offices
     (разом зі строуком під Kyiv) до верху фону CTA-2 */
  .about-offices + .cta--second {
    margin-top: 80px;
    /* Фікс: 362/100px — той самий готовий блок, що .offices + .cta--second
       вище (index.html) */
    height: 628px;
    padding-top: 362px;
    background-size: 1440px 624px;
  }

  .about-offices + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Фікс: тайтл→кнопка — 32px, той самий готовий блок, що .offices +
     .cta--second .cta__btn вище */
  .about-offices + .cta--second .cta__btn {
    margin-top: 32px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 164: Footer (сайт-вайд, той самий
   принцип скоупу, що Крок 140 Tablet Landscape — .footer__* класи без
   різниці між сторінками, тому звичайні селектори без адjacent-sibling)

   Сітка — 4×155/16, max-width:668px (та сама геометрія, що
   .offices__grid цього ж breakpoint'а), замість спільного 8-колонкового
   .footer__grid — тому .footer__top/__line-a/__body/__line-b/__bottom
   переходять з десктопних grid-column:1/9 на 1/5.

   Верхня частина (лого+email) окремих правил не отримує: flex
   space-between сам підлаштовується під нову ширину контейнера, той
   самий підхід, що в Кроці 140 (там .footer__top теж не перевизначався).

   .footer__body перекомпоновано у вертикальний стек замість десктопного
   "WHO WE ARE" зліва + патерн/навігація справа:
   патерн (на всю ширину) → навігація (3 колонки, 2 строуки,
   .footer__vline--3 більше не потрібен і ховається — лишається розділити
   3 колонки, тобто рівно 2 строуки, перевикористано --1/--2) → строук
   (новий ::after — HTML-елемента для нього нема, той самий прийом, що
   .footer__label::after) → WHO WE ARE (тайтл+боді) → строук → копірайт.
   Строук під копірайтом і 20px нижній відступ — уже наявні
   .footer__line-b (grid-row 4) і .footer__bottom/.footer (margin-top:20 і
   padding-bottom:20 вже дефолтні, збігаються з ТЗ п.9/10 без змін);
   .footer__body отримує точну height, що закінчується рівно там, де має
   бути .footer__line-b (0 row-gap між грід-рядками, той самий принцип,
   що в десктопній версії, коментар біля .footer__line-b вище).

   Арифметика вертикалі (від верху .footer__body = 0):
   патерн: 0–32
   vline/col top = 32 (одразу під патерном); col top = 32+48 = 80
   vline height 292 → низ навігації = 32+292 = 324
   строук під навігацією (::after): top 324, height 1
   WHO title top = 324+1+20 = 345, height 20 (rh-12-bold, line-height:20)
   WHO body top = 345+20+8 = 373, height 40 (dm-14-light, 2 рядки×20)
   низ боді-тексту = 373+40 = 413
   .footer__body height = 413+20 = 433 (сюди приходить .footer__line-b)
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .footer__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  .footer__top,
  .footer__line-a,
  .footer__body,
  .footer__line-b,
  .footer__bottom {
    grid-column: 1 / 5;
  }

  .footer__body {
    height: 433px;
  }

  .footer__pattern {
    left: 0;
    width: 668px;
  }

  .footer__vline--1 {
    left: 222px;
    top: 32px;
    height: 292px;
  }

  .footer__vline--2 {
    left: 444px;
    top: 32px;
    height: 292px;
  }

  .footer__vline--3 {
    display: none;
  }

  .footer__col {
    gap: 20px;
  }

  .footer__col--1 {
    left: 24px;
    top: 80px;
  }

  .footer__col--2 {
    left: 246px;
    top: 80px;
  }

  .footer__col--3 {
    left: 468px;
    top: 80px;
  }

  .footer__body::after {
    content: '';
    position: absolute;
    left: 0;
    top: 324px;
    width: 668px;
    height: 1px;
    background-color: var(--grey-15);
  }

  .footer__who {
    top: 345px;
  }

  .footer__who-body {
    margin-top: 8px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 165: Hero-секція (about.html)

   Сітка/хедер — без змін (спільні, Крок 156 + фікси). Фон — той самий
   ассет, що на Tablet Landscape (image-set 1x/2x), без нового файлу:
   лише зсув від 134px (Tablet Landscape) до 104px, background-size
   лишається тим самим 1440×675. Текстовий блок — той самий, що на
   Tablet Landscape (padding-top:170px уже фіксований у базовому правилі
   .about-hero, тому лейбл на 170px від верху в'юпорта збігається сам
   собою, окремого перевизначення не потрібно); тут перевизначаються
   лише стиль тайтла (.dm-36-reg замість десктопного .dm-h1, відступ від
   лейбла 10px замість 12px). Ручний перенос рядків — успадкований
   "--wide" розрив (Крок 206, той самий, що десктоп/Tablet Landscape,
   вимкнений лише на Mobile), тут нічого перевизначати не потрібно.
   Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
   десктопного .dm-desc, відступ від тайтла (18px) збігається з
   десктопним значенням, тому margin-top окремо не перевизначений */

@media (min-width: 768px) and (max-width: 1023px) {

  .about-hero__bg {
    background-position: center 104px;
    background-size: 1440px 675px;
  }

  .about-hero__title {
    margin-top: 10px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  .about-hero__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 166: секція Our Approach (about.html)

   Той самий принцип, що Крок 165: контент/структура 1:1 з Tablet Landscape
   (Крок 144 + фікси), тут перевизначаються лише сітка (4×155/16, 668px),
   позиції (колонка 3 = 342px замість колонки 5 = 464px восьмиколонкової
   планшетної сітки) і стилі тайтлів/боді-тексту.

   Метрики (about-stats) лишаються 2-рядковою структурою, вже реалізованою
   в Кроці 144 (item--1/2 = рядок 1, item--3/4 = рядок 2), тут кожен айтем
   звужується до 2 колонок нової сітки (326px = 2×155+16) замість
   4-колонкового кроку (444px) Tablet Landscape.

   Тайтл метрики міняється з .dm-h0 (line-height 64px) на .dm-36-reg
   (line-height 42px) — це зсуває геометрію, прив'язану до висоти
   рядка 1 (.about-stats__marker top:71px → 49px, 42+7, та сама формула
   "lh+7px", що в десктопі/Landscape) і box-shadow-копію другого строука
   під рядком 2 (.about-stats__line, той самий прийом, що Крок 144 —
   без нового DOM-елемента), офсет перерахований під нову висоту рядка
   й новий 64px-відступ між рядками (замість 80px, п.4 ТЗ) — виміряно
   рендером. Лейбл метрики — новий стиль Red Hat/11 Bold + uppercase
   (клас .rh-11-bold, tokens.css, уже містить потрібні значення
   700/11/20/0.07em — під ту саму специфікацію, що "Red Hat/16 SB",
   Крок 161, окремого нового класу не знадобилося); контент у HTML
   лишається як є (вже написаний капсом), text-transform — про запас,
   за ТЗ. Строук/розмір квадратика (5×5px) — без змін відносно
   Tablet Landscape.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .about-approach__grid,
  .about-stats__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Фікс: лейбл "OUR APPROACH" не влазить в одну колонку (155px) —
     на всю ширину сітки (1/5, 668px), той самий фікс, що в Кроці 144
     (там 1/9 для восьмиколонкової сітки); текст лишається притиснутим
     до лівого краю (0px) */
  .about-approach__label {
    grid-column: 1 / 5;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) — номер "I."
     тут (замість колонки 5 = 464px у Tablet Landscape) */
  .about-approach__index {
    grid-column: 3;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
     .dm-h2. grid-column на всю ширину сітки (1/5, 668px) — та сама
     причина, що в лейбла вище (дефолтне 1/6 виходить за межі
     4-колонкової сітки); фіксована ширина 586px (успадкована з
     десктопу, без змін) лишає бокс притиснутим до лівого краю (0px) */
  .about-approach__title {
    grid-column: 1 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, колонка 3 (342px) замість колонки 5. Відступ
     від тайтла (28px) — десктопне значення, без змін (не входить у
     п.2 ТЗ, там лише боді→патерн→підтекст) */
  .about-approach__desc {
    grid-column: 3 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  .about-approach__desc-break--portrait {
    display: inline;
  }

  /* Патерн і підтекст — колонка 3 (342px), той самий фікс-зсув, що в
     Кроці 144. Відступи 12px з обох боків (п.2 ТЗ) замість десктопних
     20px */
  .about-approach__pattern {
    grid-column: 3 / 5;
    margin-top: 12px;
  }

  .about-approach__extra {
    grid-column: 3 / 5;
    margin-top: 12px;
  }

  .about-approach__extra-break--desktop {
    display: none;
  }

  .about-approach__extra-break--portrait {
    display: inline;
  }

  /* Відступ від низу підтексту до верху рядка 1 метрик — 80px (п.3 ТЗ),
     .about-stats margin-top рахується напряму від попереднього
     флекс-сиблінга (.about-approach, до якого належить __extra), тому
     значення співпадає з відступом 1:1 */
  .about-stats {
    margin-top: 80px;
  }

  /* Рядок 1: "300+" (колонка 1, 0px) / "2020" (колонка 3, 342px) —
     кожен айтем звужений до 2 колонок нової сітки (326px) замість
     4-колонкового кроку Tablet Landscape */
  .about-stats__item--1 {
    grid-column: 1 / 3;
  }

  .about-stats__item--2 {
    grid-column: 3 / 5;
  }

  /* Тайтл метрики — Tablet/H1 (.dm-36-reg, tokens.css) замість
     десктопного/Landscape .dm-h0 */
  .about-stats__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Лейбл метрики — Red Hat/11 Bold (.rh-11-bold, tokens.css), капс —
     text-transform про запас (текст-контент у HTML вже написаний
     капсом, не змінюється) */
  .about-stats__label {
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 11px;
    line-height: 20px;
    letter-spacing: 0.07em;
    text-transform: uppercase;
  }

  /* Маркер (5×5px, розмір без змін) — позиція перерахована під нову
     висоту рядка 1 (тайтл метрики тепер 42px, не 64px): 7px від
     нижнього краю тайтла, та сама формула, що в десктопі/Landscape
     (lh+7) */
  .about-stats__marker {
    top: 49px;
  }

  /* Боді-текст рядка 1 — колонка 1/3, 3/5 замість 4-колонкового кроку
     Tablet Landscape, стиль без змін */
  .about-stats__body--1 {
    grid-column: 1 / 3;
  }

  .about-stats__body--2 {
    grid-column: 3 / 5;
  }

  /* Рядок 2: "5" (колонка 1) / "3" (колонка 3) — 64px від низу
     боді-тексту рядка 1 до верху номера рядка 2 (п.4 ТЗ, замість 80px
     у Tablet Landscape) */
  /* Фікс: grid-row:4 для рядка 2 (Крок 144 задавав це лише в межах
     свого власного медіа-запиту 1024–1279px, тут не успадковується —
     без явного повторення тут айтеми впали б назад у grid-row:1
     (спільне базове правило) й перекрились би з рядком 1 */
  .about-stats__item--3 {
    grid-column: 1 / 3;
    grid-row: 4;
    margin-top: 64px;
  }

  .about-stats__item--4 {
    grid-column: 3 / 5;
    grid-row: 4;
    margin-top: 64px;
  }

  /* Той самий фікс — grid-row:5 (Крок 144, не успадковується поза
     власним медіа-запитом) */
  .about-stats__body--3 {
    grid-column: 1 / 3;
    grid-row: 5;
  }

  .about-stats__body--4 {
    grid-column: 3 / 5;
    grid-row: 5;
  }

  /* Фікс: той самий фікс, що вище (grid-row) — Крок 144 вмикав ручні
     переноси боді-тексту метрик (display:inline) лише в межах свого
     власного медіа-запиту (1024–1279px); тут без явного повторення
     текст падав назад у display:none (базове правило) і рядки склеювались
     без пробілу ("dashboards,enterprise") */
  .about-stats__break {
    display: inline;
  }

  /* Фікс: grid-column успадковувалося з десктопного 1/9 (8-колонкова
     сітка) — виходить за межі нової 4-колонкової сітки й ламає ширину
     контейнера; на всю ширину нової сітки (1/5, 668px). Строук під
     рядком 2 — box-shadow-копія (без нового DOM-елемента), той самий
     прийом, що Крок 144; офсет перерахований під нову геометрію рядка
     (42px тайтл замість 64px, 64px відступ між рядками замість 80px) —
     виміряно рендером */
  .about-stats__line {
    grid-column: 1 / 5;
    box-shadow: 0 202px 0 0 var(--grey-15);
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 167: секція How We Work (about.html)

   Той самий принцип, що Крок 166: контент/структура 1:1 з Tablet
   Landscape (Крок 145 + фікси), тут перевизначаються лише сітка
   (4×155/16, 668px), позиції (правий край колонки 2 = 326px замість
   правого краю колонки 4 = 444px восьмиколонкової планшетної сітки;
   колонка 3 = 342px замість колонки 5 = 464px) і стилі тайтла/боді-тексту.
   Ілюстрацію-сферу (.how-we-work__sphere) свідомо НЕ чіпаємо (окремий
   крок пізніше, як і в самому Tablet Landscape). Підтекст
   (.how-we-work__extra, "Every project is led...") теж НЕ входить у
   цей крок — лишається на успадкованих (некоректних для нової сітки)
   значеннях до окремого фікс-кроку, той самий патерн, що Кроки 144→145
   з фіксами пізніше.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Відступ від низу рядка 2 метрик Our Approach (Крок 166) до верху
     лейбла "HOW WE WORK": 110px (п.1 ТЗ), margin-top .how-we-work
     рахується напряму від попереднього флекс-сиблінга (.about-stats) */
  .how-we-work {
    margin-top: 110px;
  }

  .how-we-work__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Фікс: лейбл успадковував grid-column:1 (одна колонка, 155px) зі
     спільного правила — "HOW WE WORK" туди не влазить і переносився
     на 2 рядки. На всю ширину сітки (1/5, 668px), той самий фікс, що
     .about-approach__label (Крок 166) */
  .how-we-work__label {
    grid-column: 1 / 5;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
     .dm-h2 (виправлено фіксом — .dm-36-reg/tablet-H1 було помилкою).
     Ручний перенос лишається тим самим, завжди увімкненим <br> у
     розмітці (без tablet-break класу — той самий текст на 2 рядки в
     будь-якому breakpoint). grid-column на всю ширину сітки (1/5) —
     те саме обґрунтування, що в лейбла вище (дефолтне 1/6 виходить за
     межі 4-колонкової сітки); ширина (Крок 167-фікс, width:auto нижче)
     успадковується від самого grid-column-боксу (668px, з запасом під
     обидва рядки) */
  .how-we-work__title {
    grid-column: 1 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) — номер
     "II." тут (замість колонки 5 = 464px у Tablet Landscape) */
  .how-we-work__index {
    grid-column: 3;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, колонка 3 (342px) замість колонки 5 */
  .how-we-work__desc {
    grid-column: 3 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Фікс: список практик успадковував grid-column:1/9 (8-колонкова
     сітка) — виходить за межі нової 4-колонкової сітки, той самий
     баг-патерн, що .about-stats__line (Крок 166). На всю ширину нової
     сітки (1/5, 668px). 46px від низу боді-тексту (Фікс: було 28px) */
  .how-we-work__list {
    grid-column: 1 / 5;
    margin-top: 46px;
  }

  /* Правий край 2-ї колонки = 326px від лівого краю сітки (2×155 + 16)
     — "контейнер фреймів" (вертикальний строук) починається тут (п.5
     ТЗ, замість правого краю 4-ї колонки = 444px у Tablet Landscape).
     Товщина/колір/висота строука — без змін відносно Tablet Landscape */
  .how-we-work__vline {
    left: 326px;
  }

  /* Розділювач рядка ("фрейм") — та сама позиція, що строук вище,
     впритул до нього. Ширина — до правого краю сітки (668 − 326 =
     342px, замість 464px у Tablet Landscape). Відступи 18px (текст→
     строук) / 17px (строук→наступний текст) — без змін відносно
     Tablet Landscape (там свапнуті відносно десктопу, тут лишаються
     тими самими) */
  .how-we-work__divider {
    margin-left: 326px;
    margin-top: 18px;
    margin-bottom: 17px;
    width: 342px;
  }

  /* Строук під OPERATIONS — той самий фікс-принцип, що в Tablet
     Landscape (клас .how-we-work__divider успадкував би 326/18/17/342
     вище без цього перевизначення): позиціюється абсолютно, left:0 —
     лівий край самої .how-we-work__grid, width:668px — нова ширина
     сітки (замість 908px у Tablet Landscape) */
  .how-we-work__divider--bottom {
    margin-left: 0;
    margin-top: 0;
    margin-bottom: 0;
    width: 668px;
  }

  /* Контент усередині фрейму (назва практики/опис) — колонка 3 (342px),
     16px (gutter) правіше строука/фрейму (326px, п.5 ТЗ). Решта стилів
     рядка — без змін */
  .how-we-work__row {
    margin-left: 342px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Фікс: Our Approach (перенос тайтла) +
   How We Work (тайтл, строук під Operations, підтекст, строук під
   підтекстом)

   Our Approach: тайтл (Крок 206) тепер несе БЕЗУМОВНИЙ <br> у розмітці
   (той самий розрив на всіх 4 breakpoint, за завданням) — жодного
   tablet-break перемикача тут більше не потрібно. desktop-ширина 586px
   (без змін, успадкована з Кроку 166) достатня для обох рядків.

   How We Work: тайтл (Крок 167) мав фіксовану ширину 276px — рядок
   "Five practices built" сам не влазив у 276px і переносився ще раз,
   даючи 3 рядки замість 2 (третій — від уже наявного невимкненого <br>
   в розмітці). Фікс — прибрати обмеження ширини напряму з правила
   .how-we-work__title (успадковується від grid-column:1/5, 668px — з
   запасом під обидва рядки), <br> у розмітці лишається без змін.

   Строук під "Operations" (.how-we-work__divider--bottom) — top тут
   був хардкод-піксельним значенням (621px, від застарілого заміру), що
   розсинхронізувалось із реальним низом тексту "Operations" після
   наступних правок. Позиція тепер рахується динамічно в
   js/how-we-work.js (реальний низ останнього .how-we-work__row +
   17px, на resize) на всіх breakpoint, де строук лишається
   position:absolute — CSS-значення нижче лишається лише як fallback
   до першого запуску JS. Підтекст (.how-we-work__extra) — колонка 3 (342px),
   margin-top рахується напряму від низу рядка OPERATIONS (флоу
   .how-we-work__list закінчується рівно тут, сам строук під ним
   винесений з потоку абсолютним позиціюванням і на цей margin не
   впливає) — 80px, виміряно рендером. Строук під підтекстом — новий
   елемент (.how-we-work__extra-line, розмітка about.html), 28px від
   низу підтексту, той самий "фрейм" відступ зліва (326px, правий край
   2-ї колонки) і ширина (342px), що строук під Operations/розділювачі
   рядків. Усі точні значення виміряно рендером.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 18px від низу рядка "OPERATIONS" (останній рядок списку, флоу
     .how-we-work__list закінчується рівно тут — строук під ним
     винесений з потоку абсолютним позиціюванням, Крок 145) до
     верхнього краю строука */
  .how-we-work__divider--bottom {
    top: 621px;
  }

  /* Фікс: строук → секондарі-боді, 80px (17px рядок→строук + 1px
     строук + 80px строук→текст = 98px, той самий принцип, що
     десктоп/Tablet Landscape) */
  .how-we-work__extra {
    grid-column: 3 / 5;
    margin-top: 98px;
  }

  /* Ілюстрація-сфера — нарешті адаптована під цю сітку (раніше свідомо
     не чіпалась, успадковувала десктопні left/top). top: 177px від низу
     заголовка (Фікс: було 147px, опущено на 30px нижче; тайтл тут
     коротший — .dm-30-reg, row1:20 + margin-top:26 + row2:72 = 118,
     +177 = 295px). left: права межа ілюстрації на 313px лівіше правого
     краю сітки (668px), right-edge = 668-313 = 355, left = 355-934 =
     -579px */
  /* Фікс: ще на 20px вище (295→275px), потім ще на 5px вище (275→270px) */
  .how-we-work__sphere {
    top: 270px;
    left: -579px;
  }

  /* Крок 207: Tablet Portrait отримує ВЛАСНИЙ розрив (11 рядків, інший
     розподіл, ніж десктоп/Tablet Landscape/Mobile — 10 рядків) — той
     самий tablet-break прийом, що раніше стояв на Tablet Landscape
     (перенесено сюди, бо Tablet Landscape тепер використовує дефолтний
     10-рядковий розрив нарівні з десктопом) */
  .how-we-work__desc-break--desktop {
    display: none;
  }

  .how-we-work__desc-break--tablet {
    display: inline;
  }

  /* Секондарі-боді (.how-we-work__extra) отримує власний 9-рядковий
     розрив на Tablet Portrait — вимикаємо десктопний і вмикаємо --portrait */
  .how-we-work__extra-break--desktop {
    display: none;
  }

  .how-we-work__extra-break--portrait {
    display: inline;
  }

  /* Фікс: top тут був хардкод-піксельним значенням (990px), що
     розсинхронізувалось після зміни .how-we-work__extra margin-top
     (80→98px вище). Позиція тепер рахується динамічно в
     js/how-we-work.js (реальний низ .how-we-work__extra + 28px, той
     самий принцип, що строук під Operations) — CSS-значення нижче
     лишається лише fallback до першого запуску JS */
  .how-we-work__extra-line {
    display: block;
    position: absolute;
    left: 326px;
    width: 342px;
    height: 1px;
    background-color: var(--grey-15);
    top: 990px;
  }

  /* Фікс: секондарі-боді → Trusted By, 156px. Раніше не перевизначався
     тут і мовчки успадковував десктопне значення (310px, вищий за
     специфічністю за загальний .trusted-by{margin-top}) — тепер
     явний override. Рахується напряму від низу .how-we-work__extra:
     about-hero завершується рівно тут, .how-we-work__extra-line —
     absolute, не додає власної flow-висоти */
  .about-hero + .trusted-by {
    margin-top: 156px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Фікс: секція Trusted By (about.html) —
   точна копія вже реалізованої й перевіреної версії з index.html (Крок
   162, ".services + .trusted-by" вище), лише замінено суміжний селектор
   на ".about-hero + .trusted-by" (структурний адрес about.html: тут
   Trusted By йде одразу за .about-hero, не за .services). Позиція
   лейбла/номера — без змін відносно поточної реалізації (лейбл
   успадковує базовий grid-column:1, номер — grid-column:3 нижче, той
   самий принцип, що в index.html).

   about.html до цього кроку лишався на десктопній 8-колонковій сітці
   (1164px) на цьому breakpoint ("окремий крок пізніше" — Крок 162) —
   тепер той самий 4×155px/16px-gutter/668px layout, лише перші 8 із 16
   логотипів (2 ряди по 4), решта (nth-child(n+9)) приховані. Ротація
   (js/trusted-by-rotate.js, той самий factory/логіка, що index.html —
   crossfade на .trusted-by__logo-wrap, 7с, пауза при ховері) на момент
   цього кроку увімкнена лише тут (Mobile-версія Trusted By на about.html
   додана окремим наступним кроком — тепер той самий factory-виклик
   покриває обидва breakpoint об'єднано, як у index.html).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .about-hero + .trusted-by .trusted-by__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  .about-hero + .trusted-by .trusted-by__index {
    grid-column: 3;
  }

  .about-hero + .trusted-by .trusted-by__logos {
    grid-column: 1 / 5;
    grid-row: 2;
    margin-top: 16px;
    grid-template-columns: repeat(4, 155px);
    grid-template-rows: repeat(2, 155px);
    gap: 16px;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell,
  .about-hero + .trusted-by .trusted-by__logo {
    width: 155px;
    height: 155px;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(n + 9) {
    display: none;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(4n)::after {
    right: 0;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(n + 5)::after {
    bottom: 0;
  }

  .about-hero + .trusted-by .trusted-by__lines {
    background-size:
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      1px 326px,
      668px 1px,
      668px 1px,
      668px 1px,
      155px 1px,
      155px 1px,
      155px 1px,
      155px 1px;
    background-position:
      0px 0,
      155px 0,
      171px 0,
      326px 0,
      342px 0,
      497px 0,
      513px 0,
      right 0px top 0,
      0 0px,
      0 155px,
      left 0 bottom 0px,
      0px 171px,
      171px 171px,
      342px 171px,
      513px 171px;
  }

  .about-hero + .trusted-by .trusted-by__logo-wrap {
    will-change: opacity, transform;
    transition: opacity 650ms var(--ease-smooth), transform 650ms var(--ease-smooth);
  }

  .about-hero + .trusted-by .trusted-by__logo-wrap--fading {
    opacity: 0;
    transform: translateY(12px);
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Фікс: How We Work — стиль тайтла
   (tablet/H2) + висота великого вертикального строука

   1. Тайтл: .dm-36-reg (tablet/H1) був помилкою — виправлено напряму в
      правилі .how-we-work__title (Крок 167) на .dm-30-reg (tablet/H2).
      Ручний перенос (<br> у розмітці, без змін) далі дає ті самі 2
      рядки, лише меншим кеглем — це зсуває решту вмісту секції вгору,
      тому top-значення строука під Operations/строука під підтекстом
      (фікс вище) перераховані відповідно до нової висоти тайтла.

   2. Великий вертикальний строук (.how-we-work__vline, left:326px)
      мав фіксовану height:1171px, успадковану з десктопу/Tablet
      Landscape (виміряну під зовсім іншу вертикальну композицію —
      секцію Trusted By, яку цей крок не чіпає). Тут строук має
      закінчуватись рівно на верхньому краю строука під підтекстом
      (.how-we-work__extra-line). Фікс: height більше не хардкод-
      піксельне значення (розсинхронізувалось після зміни
      .how-we-work__extra margin-top в попередньому кроці) — тепер
      рахується динамічно в js/how-we-work.js (різниця реальних
      offsetTop .how-we-work__extra-line і самого .how-we-work__vline,
      на resize), той самий принцип, що top строука під
      Operations/підтекстом. CSS-значення нижче — лише fallback до
      першого запуску JS.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .how-we-work__vline {
    height: 965px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 169: секція Leadership (about.html)

   Той самий принцип, що Крок 166/167: контент/структура 1:1 з Tablet
   Landscape (Крок 147 + фікси), тут перевизначаються лише сітка (4×155/16,
   668px), позиції (колонка 3 = 342px замість колонки 5 = 464px
   восьмиколонкової планшетної сітки) і стилі тайтла/боді-тексту. Лейбл
   ("LEADERSHIP", .rh-12-bold-track) не перевизначається — той самий
   короткий текст, що не потребував фіксу навіть у вужчій 96px-колонці
   Tablet Landscape, тим паче влазить у 155px тут.

   Фікс: .leadership__viewport/.leadership__nav успадковують
   grid-column:1/9 (восьмиколонкова сітка, база) — виходить за межі нової
   4-колонкової сітки, той самий баг-патерн, що .how-we-work__list/
   .about-stats__line (Крок 166/167). На всю ширину нової сітки (1/5,
   668px).

   Айтем картки зменшується з 780×529 (Tablet Landscape) до 651×382, фото —
   з 380×529 до 275×382, інфо-блок — похідні 376×382 (651−275=376, той
   самий принцип, що в десктопі/Tablet Landscape: photo+info=item width).
   Уся внутрішня розмітка інфо-блоку (відступи/розміри тексту, hover/
   активні стани) — без змін, окрім .leadership__hline, який завжди
   дорівнює ширині info (400→376) за тим самим принципом.

   Ректангл-градієнт — right: calc(334px − 50vw), той самий "телескоп"-
   формула, що в десктопі/Tablet Landscape (582=1164/2, 454=908/2), тут
   334=668/2 (половина НОВОЇ ширини сітки). Патерн у кінці ряду — той
   самий принцип, що в десктопі/Tablet Landscape (276=1164−888,
   128=908−780), тут 17=668−651. Кнопки гортання (.leadership__nav-btn) —
   без окремого правила, автоматично лишаються по правому краю нової
   сітки (justify-content:flex-end на .leadership__nav, лише
   grid-column якого перевизначено вище, фікс).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Відступ від низу останнього айтема Trusted By до верху лейбла
     "LEADERSHIP": 100px */
  .leadership {
    margin-top: 100px;
  }

  .leadership__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
     .dm-h2. Ручний перенос (title-break) — увімкнений лише тут (за
     замовчуванням вимкнений вище), той самий принцип, що Tablet
     Landscape (Крок 147). grid-column на всю ширину сітки (1/5, 668px) —
     дефолтне 1/6 виходить за межі 4-колонкової сітки; успадкована ширина
     563px (без змін) лишає бокс притиснутим до лівого краю (0px) */
  .leadership__title {
    grid-column: 1 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  .leadership__title-break {
    display: inline;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) — номер
     "IV." тут (замість колонки 5 = 464px у Tablet Landscape) */
  .leadership__index {
    grid-column: 3;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, колонка 3 (342px) замість колонки 5 */
  .leadership__desc {
    grid-column: 3 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  .leadership__desc-break--portrait {
    display: inline;
  }

  .leadership__viewport {
    grid-column: 1 / 5;
    margin-top: 80px;
  }

  /* Вікно каруселі — висота під новий розмір айтема (382px, ширина
     1542px лишається незмінною, не в межах цього кроку) */
  .leadership__clip {
    height: 382px;
  }

  .leadership__gradient {
    height: 382px;
    right: calc(334px - 50vw);
  }

  .leadership__item {
    width: 651px;
    height: 382px;
  }

  .leadership__photo {
    width: 275px;
    height: 382px;
  }

  .leadership__photo-stroke {
    width: 275px;
    height: 382px;
  }

  /* Інфо-блок — 376×382 (651 − 275 = 376, той самий принцип, що в
     десктопі/Tablet Landscape: photo + info = ширина айтема) */
  .leadership__info {
    width: 376px;
    height: 382px;
  }

  /* Фікс: відступ фото→тайтл (.leadership__content left) — 28px
     (десктопне значення) → 20px. Каскад title→bio→hline→tags — той
     самий flex-column усередині .leadership__content, зсувається
     разом з ним (одна absolute-точка прив'язки) */
  .leadership__content {
    left: 20px;
  }

  /* Строук на всю ширину інфо-блоку (376px, як 400px у Tablet Landscape).
     margin-left перераховано під нове left:20px .leadership__content
     (було -28px під десктопні 28px) — щоб лишитись на 0 відносно
     .leadership__info (20-20=0), а не виступати на 8px за межі */
  .leadership__hline {
    width: 376px;
    margin-left: -20px;
  }

  /* Тег→строук/строук→тег — 20px, замість успадкованого десктопного
     28px (той самий принцип, що Mobile, у зв'язку зі зміною відступу
     фото→тайтл вище на ті самі 20px) */
  .leadership__tags {
    gap: 20px;
  }

  /* Патерн у кінці ряду — 668 − 651 = 17px (той самий принцип, що
     1164 − 888 = 276 у десктопі, 908 − 780 = 128 у Tablet Landscape) */
  .leadership__end-pattern {
    width: 17px;
    height: 382px;
  }

  .leadership__nav {
    grid-column: 1 / 5;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 170: секція Offices (about.html)

   Той самий принцип, що Leadership (Крок 169): сітка 4×155/16 (668px),
   номер/боді-текст на колонці 3 (342px), тайтл секції — .dm-30-reg
   (tablet/H2). Лейбл ("OFFICES") не перевизначається — той самий короткий
   текст, що не потребував фіксу в жодному з попередніх кроків.

   Фікс: .about-offices__cities успадковує grid-column:1/9 (восьмиколонкова
   сітка, база) — той самий баг-патерн, що виправлено для
   .leadership__viewport/__nav у Кроці 169. На всю ширину нової сітки
   (1/5, 668px).

   Структурна зміна відносно Tablet Landscape (Крок 148): замість одного
   ряду з 3 міст (кумулятивні margin-left) — 2 ряди по сітці: London
   (колонки 1–2, 0–326px) + New York (колонки 3–4, 342–668px) у ряду 1,
   Kyiv (колонки 1–2, 0–326px) у ряду 2. Кожен .about-offices__city
   переведений на position:absolute відносно .about-offices__cities
   (обходить статичний .about-offices__titles, той самий containing-block
   принцип, що вже використовують .about-offices__line/__body-line/
   __gmt-line) — це дозволяє позиціювати London/New York/Kyiv незалежно
   один від одного через left/top, замість крихкого flex+margin-left
   ланцюжка, який не підтримує перенос у 2 ряди.

   Уся ВНУТРІШНЯ геометрія айтема міста (маркер/лінія/city-info/gmt/
   gmt-line-в-тегу, боді-текст) — ті самі значення, що вже встановлені для
   Tablet Landscape (Крок 148 + фікси), скопійовані сюди напряму (медіа-
   запити не успадковують значення одне від одного): city-info top:149,
   vline/extra-vline height:287, gmt top:332. Висота одного "ряду" міста —
   357px (149... фактично 70(vline top)+287(vline height)=357,
   356(gmt-line top)+1=357 — той самий "низ" в обох формулах, що й
   min-height:357 у Кроці 148), звідси top Kyiv (ряд 2) = 357 + 80 (п.5
   ТЗ) = 437px, і min-height .about-offices__cities = 437 + 357 = 794px
   (низ ряду 2, той самий принцип).

   .about-offices__extra-vline (декоративний строук праворуч від Kyiv,
   раніше позначав кінець ряду з 3 міст) — перерахований під правий край
   НОВОЇ колонки Kyiv (326px, той самий принцип, що London/New York
   вище), замість виміряного під старий однорядковий макет значення
   (282.5px, Крок 148). .about-offices__pattern — лишається схованим
   (display:none), той самий принцип, що Крок 148 (не успадковується з
   Tablet Landscape, тому продубльовано тут).

   contact.html (.contact-offices.about-offices) ділить ці самі BEM-класи
   — увесь блок нижче підхоплюється там автоматично, без окремих правил
   (той самий принцип, що margin-top:160px з Кроку 148, задокументований
   у Кроці 155).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Відступ від низу кнопок гортання Leadership (Крок 169) до верху
     лейбла "OFFICES": 120px */
  .about-offices {
    margin-top: 120px;
  }

  .about-offices__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
     .dm-h2. grid-column на всю ширину сітки (1/5, 668px) — дефолтне 1/6
     виходить за межі 4-колонкової сітки; успадкована ширина 494px (без
     змін) лишає бокс притиснутим до лівого краю (0px) */
  .about-offices__title {
    grid-column: 1 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) — номер "V."
     тут (замість колонки 5 = 464px у Tablet Landscape) */
  .about-offices__index {
    grid-column: 3;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, колонка 3 (342px) замість колонки 5 */
  .about-offices__desc {
    grid-column: 3 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  .about-offices__desc-break--desktop {
    display: none;
  }

  .about-offices__desc-break--portrait {
    display: inline;
  }

  /* Відступ від низу боді-тексту до верху першого ряду міст: 80px
     (96px у Tablet Landscape). grid-column — фікс overflow (та сама
     причина, що .leadership__viewport, Крок 169). min-height — 794px,
     низ ряду 2 (Kyiv), формула в шапці блоку вище */
  .about-offices__cities {
    grid-column: 1 / 5;
    margin-top: 80px;
    min-height: 794px;
  }

  /* Кожне місто — position:absolute відносно .about-offices__cities
     (обходить статичний .about-offices__titles). База — London (без
     модифікатора), top:0/left:0 = ряд 1, колонка 1 (0px) */
  .about-offices__city {
    position: absolute;
    top: 0;
    left: 0;
  }

  /* New York — ряд 1, колонка 3 (342px). margin-left:0 скасовує
     успадкований кумулятивний відступ (192px у десктопі, не
     застосовний до position:absolute-макета) */
  .about-offices__city--ny {
    top: 0;
    left: 342px;
    margin-left: 0;
  }

  /* Kyiv — ряд 2, колонка 1 (0px), top:437px (низ ряду 1 = 357px + 80px) */
  .about-offices__city--kyiv {
    top: 437px;
    left: 0;
    margin-left: 0;
  }

  /* Тайтл міста ("London"/"New York"/"Kyiv") — Tablet/H1 (.dm-36-reg,
     tokens.css) замість десктопного .dm-h1. margin-left:20px — відступ
     контенту від початку сітки (London/Kyiv, п.1/4 ТЗ); скасовується
     нижче для New York, чий контент починається природно на 342px */
  .about-offices__city-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
    margin-left: 20px;
  }

  .about-offices__city--ny .about-offices__city-title {
    margin-left: 0;
  }

  .about-offices__city--ny .about-offices__city-info {
    left: 0;
  }

  .about-offices__city--ny .about-offices__gmt {
    left: 0;
  }

  /* Marker/vline/line — успадковані десктопні top:66/70/70 (Крок 66),
     Крок 148 їх теж не перевизначав */
  .about-offices__vline,
  .about-offices__extra-vline {
    height: 287px;
  }

  /* Фікс (п.7 ТЗ): строук під квадратиком для Kyiv (ряд 2) — .about-offices__line
     сам по собі один спільний елемент (top:70px відносно .cities, збігається
     з рядом 1/London/New York). Копія на офсеті вниз через box-shadow (той
     самий прийом, що .about-stats__line, Tablet Landscape) — 437px, той
     самий зсув, що .about-offices__city--kyiv{top:437px}, тому квадратик
     Kyiv (успадкований top:66px відносно СВОГО .city) і ця копія
     збігаються на нижньому пікселі (66+5-1=70, як і в ряду 1) */
  .about-offices__line {
    box-shadow: 0 437px 0 0 var(--grey-15);
  }

  /* ФІКС — London/Kyiv: .city тепер position:absolute напряму на
     координаті сітки (0px), тому успадкований left:-20px (розрахований
     під старий flex+margin-left:20 макет .about-offices__titles) зносить
     маркер/строук за межі сітки. Marker/vline повертаються на власний
     лівий край айтема (0 = початок сітки), відступ 20px переноситься
     на контент (тайтл/city-info/gmt) нижче */
  .about-offices__marker,
  .about-offices__vline {
    left: 0;
  }

  /* Скопійовано напряму з Крок 148 (Tablet Landscape) */
  .about-offices__city-info {
    left: 20px;
    top: 149px;
  }

  .about-offices__gmt {
    left: 20px;
    top: 332px;
  }

  /* New York — власний маркер/строук не є "лівим краєм" контенту
     (той є на 342px, природний відступ = gutter сітки), а межею між
     колонками 2 і 3 (326px = правий край 2-ї колонки): -16px відносно
     .city--ny (342 - 16 = 326) */
  .about-offices__city--ny .about-offices__marker,
  .about-offices__city--ny .about-offices__vline {
    left: -16px;
  }

  /* Третій строук — правий край 4-ї колонки сітки (668px = 342 + 325
     відносно .city--ny + 1px власної ширини), закриває блок New York
     праворуч. ФІКС: 325px (було 326) — на 326 правий край строука
     (326+1=327 відносно .city--ny, тобто 342+327=669 абсолютно) виходив
     на 1px за межі сітки (668) */
  .about-offices__city--ny::after {
    content: "";
    position: absolute;
    left: 325px;
    top: 70px;
    width: 1px;
    height: 287px;
    background-color: var(--grey-15);
  }

  /* Ширина — нова сітка (668px, було 908 у Tablet Landscape). top —
     скопійовано напряму з Крок 148 (Tablet Landscape) */
  .about-offices__body-line {
    top: 327px;
    width: 668px;
  }

  .about-offices__gmt-line {
    top: 356px;
    width: 668px;
  }

  /* Перерахований під правий край нової колонки Kyiv (326px, той самий
     принцип, що London/New York вище) — замість виміряного під старий
     однорядковий макет значення (282.5px, Крок 148) */
  .about-offices__extra-vline {
    left: 326px;
  }

  /* ФІКС — відновлення горизонтальних строуків для ряду 2 (Kyiv), той
     самий row-relative офсет, що body-line/gmt-line ряду 1 (327/356,
     .city--kyiv не має власного top:0, тому офсети рахуються відносно
     самого .city--kyiv, а не .cities): строук над GMT — у межах айтема
     Kyiv (326px), строук під GMT — на всю ширину сітки (668px, той самий
     принцип, що строук під Kyiv/п.2 ТЗ — це один і той самий,
     найнижчий строук ряду) */
  .about-offices__city--kyiv::before {
    content: "";
    position: absolute;
    left: 0;
    top: 327px;
    width: 326px;
    height: 1px;
    background-color: var(--grey-15);
  }

  .about-offices__city--kyiv::after {
    content: "";
    position: absolute;
    left: 0;
    top: 356px;
    width: 668px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* ФІКС — патерн косих ліній вмикається знову (на відміну від Кроку 148):
     одразу після другого строука Kyiv (326px, без додаткового відступу)
     до кінця сітки (668px), ширина 342px, висота — та сама, що vline/
     extra-vline (287px = повна висота рядка) */
  .about-offices__pattern {
    display: block;
    left: 326px;
    top: 70px;
    width: 342px;
    height: 287px;
  }

  .about-offices__body-break--desktop {
    display: none;
  }

  /* Фікс: Tablet Portrait раніше перевикористовував --tablet (той самий
     6-рядковий розрив, що Tablet Landscape) — тепер власний 5-рядковий
     --portrait розрив (окремі <br>-теги в розмітці, п.6 ТЗ), --tablet
     вимикається тут */
  .about-offices__body-break--tablet {
    display: none;
  }

  .about-offices__body-break--portrait {
    display: inline;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 171: Hero-секція (services.html)

   Той самий принцип, що .about-hero (Крок 165): фон — той самий ассет, що
   на Tablet Landscape (image-set 1x/2x, без нового файлу), лише зсув від
   134px (Tablet Landscape) до 104px, background-size лишається тим самим
   1440×675; min-height підрівняний під 104+675=779px, щоб фон не обрізався
   знизу секцією коротшою за суму зсуву й висоти (padding-top:170px уже
   фіксований у базовому правилі .services-hero, тому лейбл на 170px від
   верху в'юпорта збігається сам собою, окремого перевизначення не
   потрібно). Тайтл/боді — контент і ручні переноси ті самі, що на Tablet
   Landscape (Крок 149): --title-break--desktop вимикається,
   --title-break--tablet вмикається (той самий tablet-break прийом),
   перевизначаються лише стиль тайтла (.dm-36-reg замість десктопного
   .dm-h1, відступ від лейбла 10px замість 12px) і боді-текст (.dm-16-light
   замість десктопного .dm-desc, відступ від тайтла 18px збігається з
   десктопним значенням, тому margin-top окремо не перевизначений) */

@media (min-width: 768px) and (max-width: 1023px) {

  .services-hero {
    min-height: 779px;
  }

  .services-hero__image {
    background-position: center 104px;
    background-size: 1440px 675px;
  }

  .services-hero__title-break--desktop {
    display: none;
  }

  .services-hero__title-break--tablet {
    display: inline;
  }

  .services-hero__title {
    margin-top: 10px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  .services-hero__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 172: секція Services (scrollytelling-
   табличка, services.html)

   Той самий принцип, що Крок 150 (Tablet Landscape) — контейнер/строук/
   номер стискаються під нову сітку (668px замість 908px), той самий "0px
   відступ від великого строука" для вікна таблички. Ліва ілюстрація-квітка
   (.services-hero__practices-illustration) НЕ чіпається — окремий крок
   пізніше, той самий принцип, що й Крок 150.

   Колонка 3 = 342px (2×155 + 2×16) — номер і текстовий контент таблички
   тепер тут (замість колонки 5 = 464px на Landscape). Права межа 2-ї
   колонки = 326px (2×155 + 1×16) — велика вертикальна лінія й контейнер
   таблички (0px відступу від лінії, той самий принцип, що Крок 150).
   Контейнер таблички (326→668px = 342px завширшки) отримує внутрішній
   лівий відступ 16px (=gutter, замість 20px у десктопі/Landscape), щоб
   текстовий контент починався рівно з колонки 3 (342px) і йшов до кінця
   сітки (668px, ширина контенту 326px). Фрейми (.practice__frame) і сам
   .practice — на всю ширину контейнера (342px, впритул, 0 інсету) —
   ВІДНОВЛЮЄ true bleed-принцип десктопу (frame = ширина вікна, текст
   інсетиться відступом і закінчується на тому самому правому краю, що й
   frame), а НЕ буквально копіює Landscape (де .practice__frame лишили
   недоторканим на 444px — на цьому вужчому 342px-контейнері таке значення
   спричинило б горизонтальне обрізання під overflow:hidden вікна).

   Зазор від строука до першого айтема ("Consulting"): 100px (208px на
   Landscape) — той самий принцип PANEL_HEIGHT, що в
   js/services-practices.js/measure(), але сама висота видимого вікна
   тут ЗМІНЮЄТЬСЯ (920px замість 800px, п.6 ТЗ) — height sticky-панелі
   1020px = 100 (зазор) + 920 (вікно). Відступ між айтемами таблички:
   80px (140px у десктопі/Landscape). JS-логіка (activeIndex/threshold/
   scrollRange/анімація) свідомо НЕ чіпається в цьому кроці (п.7 ТЗ) —
   лишається WINDOW_HEIGHT=800 у JS, синхронізація під 920px — окремий
   майбутній крок, той самий "не читає CSS" принцип, що вже задокументовано
   для PANEL_HEIGHT у Кроці 150.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Тайтл+каунтер і строук — на всю ширину нової сітки (668px замість
     1164px), той самий принцип, що Крок 150 (908px) */
  .services-hero__list-heading-inner {
    max-width: 668px;
  }

  .services-hero__list-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки — номер "I." тут (замість
     колонки 5 = 464px на Landscape) */
  .services-hero__list-index {
    left: 342px;
  }

  .services-hero__list-stroke {
    width: 668px;
  }

  /* Той самий грід 668px — контейнер, від лівого краю якого відлічуються
     left/margin-left лінії й таблички нижче */
  .services-hero__practices {
    max-width: 668px;
  }

  /* Зазор від строука до контенту таблички: 100px (208px на Landscape).
     Висота sticky-панелі: 1020px = 100 (зазор) + 920 (нове видиме вікно,
     п.6 ТЗ, замість 800px) */
  .services-hero__practices-sticky {
    height: 1020px;
    padding-top: 100px;
  }

  /* Права межа колонки 2 = 326px (721px у десктопі, 444px на Landscape).
     height росте разом із панеллю (1020px), щоб і далі покривати її
     повну висоту. Явний top:0 — той самий принцип, що Tablet Landscape
     вище (десктопний base top:128 не стосується цього breakpoint) */
  .services-hero__practices-line {
    left: 326px;
    top: 0;
    height: 1020px;
  }

  /* Контейнер таблички починається ВІДРАЗУ від великого вертикального
     строука (326px, впритул, 0px відступу) — той самий принцип, що
     Крок 150. width: 342px (668−326) — до кінця сітки. height: 920px
     (нове видиме вікно, п.6 ТЗ) */
  .services-hero__practices-window {
    margin-left: 326px;
    width: 342px;
    height: 920px;
  }

  .practice {
    width: 342px;
  }

  /* Відступ між айтемами таблички: 80px (140px у десктопі/Landscape) */
  .practice + .practice {
    margin-top: 80px;
  }

  /* Внутрішній лівий відступ контейнера — 16px (=gutter, 20px у
     десктопі/Landscape), щоб текст починався рівно з колонки 3 (342px) */
  .practice__head {
    padding-left: 16px;
  }

  /* width: 326px (668−342) — текст триває до кінця сітки, той самий
     правий край, що й фрейми нижче.
     Фікс: боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css)
     замість десктопного .dm-17-light з розмітки (17px) */
  .practice__body,
  .practice__body2 {
    margin-left: 16px;
    width: 326px;
  }

  .practice__body {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Фікс: відступ до іконки star.svg — 69px (73px на десктопі/Landscape) */
  .practice__body2-icon {
    margin-left: 16px;
    margin-top: 69px;
  }

  /* Фрейм — на всю ширину контейнера (342px, впритул, без інсету) —
     той самий правий край (668px), що й текст вище */
  .practice__frame {
    width: 342px;
  }

  /* Фікс: айтеми — Red Hat/12 Bold (tracking) (.rh-12-bold-track з
     розмітки), var(--grey-100), як на десктопі/Landscape — попередній
     DM Sans/16 Light override скасовано; лишається лише margin-left */
  .practice__frame-text {
    margin-left: 16px;
  }

  /* Перенос рядків .practice__body — свій на Tablet Portrait: вимикаємо
     десктопні розриви (--tablet-landscape й так вимкнений за
     замовчуванням), вмикаємо tablet-portrait-розриви */
  .practice__body-break--desktop {
    display: none;
  }

  .practice__body-break--tablet-portrait {
    display: inline;
  }

  /* Operations — секондарі боді-текст: свій, третій <p>-варіант (--tablet-
     landscape й так вимкнений за замовчуванням) */
  .practice__body2--desktop {
    display: none;
  }

  .practice__body2--tablet-portrait {
    display: block;
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — той самий
     880×880px, що на Tablet Landscape. top:50px (фікс: замінює попередні
     166px) — офсет від padding-edge панелі, виміряний від боді-тексту
     секції до верху ілюстрації. Горизонталь: правий край на 46px лівіше
     лівого краю контейнера таблички (326px, впритул до великої лінії) →
     left = 326 − 46 − 880 = −600px */
  .services-hero__practices-illustration {
    top: 50px;
    left: -600px;
    width: 880px;
    height: 880px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 173: секція Our Commitments
   (services.html)

   Той самий контент, що на Tablet Landscape (Крок 151 + фікс порядку
   рядків "Decisions documented, not relitigated") — лише структура/стилі
   міняються. Десктопний/Landscape "3 колонки в ряд" (flex-row, gap між
   ілюстраціями) тут замінюється на 3 повноширинні "фрейми" (668×186px),
   складені у стовпчик (32px між ними, п.6 ТЗ). .our-commitments__item-title/
   __item-body вже несуть breakpoint-агностичні токен-класи (.dm-20-reg/
   .dm-14-light з розмітки) — типографіку тут НЕ перевизначаємо, лише
   розміри/позиції. Тайтл секції/боді — досі на "dm-h2"/"dm-desc" з
   розмітки, тому перевизначаються тут (той самий принцип, що
   .how-we-work__title/__desc, Крок 167).

   Усередині фрейму: ілюстрація виходить із потоку (position:absolute,
   top:0/right:0 — правий верхній кут фрейму) — звільняє тайтлу (in-flow,
   margin-top:30, зліва 0) верхній лівий кут, замість десктопного
   вертикального стеку "ілюстрація зверху → тайтл знизу". Квадратик+строук
   — той самий популярний паттерн, що .about-stats__marker/__line
   (about.html): квадратик лишається в потоці (margin-top:11 від тайтла,
   задає й "відступ від тайтла" для строука), строук — ::after квадратика,
   absolute відносно нього (position:relative на самому квадратику),
   вирівняний по його вертикальному центру (top:2px = (5−1)/2), на всю
   ширину фрейму (668px, зліва 0 — той самий лівий край, що квадратик і
   тайтл). Це заміняє старий ОДИН спільний absolute-строук на всі 3 item
   (.our-commitments__line, десктопний "3-в-ряд" підхід — тут вимкнений,
   display:none, бо для стовпчика з 3 незалежних фреймів потрібен строук
   НА КОЖЕН фрейм, а не один спільний). Боді-текст — margin-top:24px від
   квадратика (11+5+24=40px від тайтла, п.5 ТЗ "відступ від тайтла — 40px"
   — вимірюється від тайтла, а не від квадратика, тому 24px тут — це вже
   ЗА ВИРАХУВАННЯМ 16px, які забирають margin+висота квадратика).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Відступ від видимої частини секції Services (920px, Крок 172) до
     верху номера "II.": 100px */
  .our-commitments {
    margin-top: 100px;
  }

  .our-commitments__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Колонка 3 = 342px від лівого краю сітки (2×155 + 2×16) — номер "II."
     тут (замість колонки 6, 740px, у десктопі) */
  .our-commitments__index {
    grid-column: 3;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
     .dm-h2. grid-column на всю ширину сітки (1/5, 668px) — дефолтне 1/6
     виходить за межі 4-колонкової сітки */
  .our-commitments__title {
    grid-column: 1 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc, колонка 3 (342px) замість колонки 6 */
  .our-commitments__desc {
    grid-column: 3 / 5;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Фрейми починаються з лівого краю сітки (0px) — на всю ширину (1/5,
     668px), замість десктопного 1/9 (8-колонкова сітка). Відступ від
     низу боді-тексту до верху першого фрейму: 56px. Стовпчик (замість
     десктопного flex-row) — 32px між фреймами (п.6 ТЗ) */
  .our-commitments__items {
    grid-column: 1 / 5;
    margin-top: 56px;
    display: flex;
    flex-direction: column;
    gap: 32px;
  }

  /* Фрейм — 668×186px (на всю ширину сітки, п.4 ТЗ), замість десктопного
     149px-бокса. position:relative — containing block для абсолютної
     ілюстрації нижче */
  .our-commitments__item {
    position: relative;
    width: 668px;
    height: 186px;
  }

  /* Ілюстрація — правий верхній кут фрейму (0px від кінця сітки/фрейму,
     0px від верху фрейму), звільняє верхній лівий кут для тайтла.
     Розмір (149×86px) — без змін відносно десктопу */
  .our-commitments__illustration {
    position: absolute;
    top: 0;
    right: 0;
  }

  /* Тайтл айтема — верхній лівий кут фрейму: 30px від верху, 0px зліва
     (п.5 ТЗ). Ширина 248px (226px у десктопі) — типографіка (.dm-20-reg)
     успадковується з розмітки, тут не перевизначена */
  .our-commitments__item-title {
    margin-top: 30px;
    width: 248px;
  }

  /* Квадратик — 11px від тайтла (15px у десктопі, п.5 ТЗ). position:
     relative — containing block для строука (::after нижче) */
  .our-commitments__item-marker {
    position: relative;
    margin-top: 11px;
  }

  /* Строук — на всю ширину фрейму (668px), той самий лівий край (0px),
     що квадратик/тайтл. Фікс: вирівняний по НИЖНЬОМУ пікселю квадратика
     (top:4px = height−1 = 5−1), а не по центру (був top:2px) — той самий
     принцип, що .about-stats__marker/__line (about.html): квадратик
     займає пікселі-рядки 0–4, останній ряд — 4, тому верх 1px-строука
     теж 4 */
  .our-commitments__item-marker::after {
    content: '';
    position: absolute;
    left: 0;
    top: 4px;
    width: 668px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Старий спільний строук на всі 3 item (десктопний "3-в-ряд" підхід)
     — замінений строуком на кожен фрейм окремо (::after квадратика вище) */
  .our-commitments__line {
    display: none;
  }

  /* margin-top:24px від квадратика = 40px від тайтла (11+5+24, п.5 ТЗ).
     Ширина — 2 колонки (326px = 2×155 + 16), замість десктопних 356px */
  .our-commitments__item-body {
    margin-top: 24px;
    width: 326px;
  }

  .our-commitments__item-body-break--desktop {
    display: none;
  }

  .our-commitments__item-body-break--tablet {
    display: inline;
  }

  .our-commitments__desc-break--portrait {
    display: inline;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 174: секція Industries (services.html)

   Точна копія вже реалізованої версії на index.html для цього ж
   breakpoint'а (Крок 161) — та сама розмітка/стилі/ассети (.industries/
   .industry-row/.industries__list/.industries__globe-stack перевикористані
   1:1 на обох сторінках), скоуплена через суміжний селектор .services-hero
   + .industries--services (замість .cta + .industries на index.html), той
   самий принцип, що вже в Кроці 152 (Tablet Landscape). Текстовий контент
   (лейбл/боді/тайтли-теги айтемів) — той самий, що вже в розмітці
   services.html з Tablet Landscape (Крок 152) — HTML тут не чіпається,
   лише структура/стилі. Єдина відмінність від Кроку 161 — margin-top
   (100px від низу останнього фрейму Our Commitments, п.1 ТЗ, замість 30px
   від низу фону CTA на index.html).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Відступ від низу останнього фрейму Our Commitments (Крок 173) до
     верху лейбла Industries: 100px */
  .services-hero + .industries--services {
    margin-top: 100px;
  }

  .services-hero + .industries--services .industries__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Лейбл лишається на колонці 1 (0px) — успадковане спільне правило,
     без змін. Тайтл — та сама колонка 1/2 (326px) і Tablet/H2
     (.dm-30-reg, tokens.css), що тайтли Services/Selected Work */
  .services-hero + .industries--services .industries__title {
    grid-column: 1 / 3;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     номер/боді-текст Services/Selected Work */
  .services-hero + .industries--services .industries__index {
    grid-column: 3;
  }

  /* Боді-текст — та сама колонка 3/5 (326px) і DM Sans/16 Light
     (.dm-16-light, tokens.css), що Services/Selected Work */
  .services-hero + .industries--services .industries__desc {
    grid-column: 3 / 5;
    width: 326px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Список фреймів — колонки 1/2 (326px, та сама ширина, що тайтл),
     72px від низу боді-тексту до верху першого фрейму */
  .services-hero + .industries--services .industries__list {
    grid-column: 1 / 3;
    margin-top: 72px;
  }

  /* Глобус: 24px від низу боді-тексту, 358px від лівого краю сітки
     (326 + 32) — розмір 786×786 без змін (успадкований з бази) */
  .services-hero + .industries--services .industries__globe-stack {
    margin-top: 24px;
    margin-left: 358px;
  }

  /* Фрейм — фіксована висота 138px (не auto), той самий розрахунок, що
     Крок 161 index.html */
  .services-hero + .industries--services .industry-row {
    height: 138px;
  }

  /* Контент — на всю ширину фрейму (326px), 25px відступу зверху до
     тайтла */
  .services-hero + .industries--services .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 25px;
  }

  /* Тайтл — Red Hat/16 SB (.rh-16-sb, tokens.css) замість десктопного
     варіанту з line-height (.rh-16-sb-lh, 34px) — тут звичайний 24px */
  .services-hero + .industries--services .industry-row__title {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 16px;
    line-height: 24px;
    letter-spacing: 0.12em;
  }

  /* Теги — DM Sans/14 Light (.dm-14-light, tokens.css) замість
     десктопного .dm-16-light. 17px від тайтлу до тегів. flex-wrap +
     row-gap:8px — перенос на другий рядок, якщо не влазять у 326px */
  .services-hero + .industries--services .industry-row__tags {
    margin-top: 17px;
    flex-wrap: wrap;
    row-gap: 8px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Немає надійного hover на Tablet (дотик) — активний рядок керується
     скролом (js/industries-tablet-scrolly.js через .is-active), той
     самий dim/bright принцип, що вже реалізований на Mobile нижче:
     дефолт приглушений (grey-50), .is-active — повна яскравість */
  .services-hero + .industries--services .industry-row__title {
    color: var(--grey-50);
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .services-hero + .industries--services .industry-row__tags {
    color: var(--grey-50);
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .services-hero + .industries--services .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  /* Строук на всю ширину фрейму (326px) — той самий прийом (0/0), що
     Tablet Landscape, замість десктопного інсету під колишню ілюстрацію */
  .services-hero + .industries--services .industry-row__divider {
    left: 0;
    right: 0;
  }

  /* Старі десктопні <img> (без ретини) — приховані, замість них
     tablet-псевдоелементи нижче */
  .services-hero + .industries--services .industry-row__illustration {
    display: none;
  }

  /* Ілюстрація-літера: правий верхній кут фрейму (40×50, absolute, 12px
     від верху, впритул до правого краю фрейму = правий край колонки 2) —
     ті самі значення й ті самі tablet-файли, що Крок 152 */
  .services-hero + .industries--services .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before,
  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  /* Порядок рядків фіксований у розмітці: F, H, E, C, P — nth-child
     замість нових класів на .industry-row__illustration-wrap (та сама
     розкладка асетів, що Крок 152) */
  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }
}


/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 175: секція FAQ (services.html)

   Той самий контент/логіка, що на Tablet Landscape (Крок 153 + фікс
   видалення дублікат-айтема й ручних переносів) — 6 FAQ-айтемів, той
   самий текст/tablet-break класи (успадковані без змін, вже увімкнені
   базовим правилом поза медіа-запитом Landscape — тут не перевизначаються
   повторно). .faq__title лишається на успадкованому width:fit-content/
   white-space:nowrap (база) — на відміну від інших тайтлів секцій, він
   ніколи не переносився на 2 рядки в жодному брейкпоінті (ні в Tablet
   Landscape), тому dm-30-reg тут навмисно НЕ застосовується (п.5 ТЗ,
   "решта без змін відносно Tablet Landscape" — там теж не був
   перевизначений).

   На відміну від Tablet Landscape (де .faq__index/__list успадковували
   десктопне grid-column:5, що випадково збігалось із потрібною позицією
   й у 8-колонковій Landscape-сітці) — нова сітка тут лише 4-колонкова,
   тому grid-column:5 вийшов би за межі; index/list перевизначені явно
   (п.2 ТЗ). FAQ-блок (ряд/тайтл/боді/строук) розтягнутий на всю ширину
   сітки (668px, п.3 ТЗ), замість "останніх 4 колонок" Landscape (444px) —
   тайтл/боді: 668 − 24 (відступ до іконки) − 12 (іконка) = 632px (та
   сама формула, що в десктопі/Landscape).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* ЦІЛЬ: 150px від низу ОСТАННЬОГО ФРЕЙМУ Industries (списку, не від
     глобуса!) — той самий принцип компенсації, що в Кроці 153 (Landscape)/
     138 (index.html): рядок 4 грід-контейнера Industries визначається
     ВИЩИМ з двох елементів — глобус (24px + 786px = 810px, Крок 174)
     довший за список (72px + 5×138px = 762px, Крок 174) на 48px. Пряме
     margin-top:150px дало б 150+48=198px від списку, а не 150.
     Компенсація: 150−48=102px */
  .faq {
    margin-top: 102px;
  }

  .faq__grid {
    grid-template-columns: repeat(4, 155px);
    column-gap: 16px;
    max-width: 668px;
  }

  /* Колонка 3 = 342px від лівого краю сітки — той самий принцип, що
     номер в інших секціях цієї сторінки */
  .faq__index {
    grid-column: 3;
  }

  /* FAQ-блок на всю ширину сітки — від лівого краю (1/5, 0px) до
     правого (668px), замість останніх 4 колонок (908−444=464px старт)
     у Tablet Landscape. Відступ від тайтла до верху блоку: 56px */
  .faq__list {
    grid-column: 1 / 5;
    margin-top: 56px;
  }

  .faq-item__row {
    width: 668px;
  }

  .faq-item__title {
    width: 632px;
  }

  /* Фікс: той самий принцип, що десктоп (552px)/Tablet Landscape (420px)
     — 632px (успадковане від .faq-item__title) звужувало найдовший
     заданий рядок на Tablet Portrait (Айтем 6, виміряно 637.94px),
     слово автопереносилось на новий рядок попри правильний <br>. 644px
     — найкоротша "кругла" ширина із запасом (доступний простір — 668px,
     .faq-item__row вище, тому 644px нічого не ламає) */
  .faq-item__body {
    width: 644px;
  }

  .faq-item__stroke {
    width: 668px;
  }

  /* Повне оновлення контенту 6 айтемів (боді-текст переписаний, не лише
     перенесений) — та сама --desktop/--tablet перемикачка, що вже в Айтемі
     4, тепер увімкнена на всіх 6 через нову --portrait <p>/розрив тайтла */
  .faq-item__title-break--desktop {
    display: none;
  }

  .faq-item__title-break--portrait {
    display: inline;
  }

  .faq-item__body--desktop {
    display: none;
  }

  .faq-item__body--portrait {
    display: block;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Фікс: Our Commitments (перенос тайтла
   секції, боді-текст 3 рядки) + Industries (боді-текст) — services.html

   Тайтл Our Commitments: "How engagements work" розбивається на 2 рядки
   ручним <br> (новий --portrait клас, база — вище, поряд з іншими
   --portrait-класами).

   Боді-текст айтемів Our Commitments (Крок 173): переносяться в ІНШИХ
   точках, ніж і десктоп, і Tablet Landscape (не просто увімкнення вже
   наявних розривів) — тому тут ПЕРЕВИЗНАЧАЄ toggle Кроку 173 (--tablet
   назад на display:none, той самий принцип, що --desktop) і вмикає нові
   --portrait розриви замість них. Айтем 1 ("No account-manager
   handoffs...") новий розрив не потребує — з вимкненими --tablet/--desktop
   вже наявні прості <br> у розмітці самі дають потрібні 3 рядки.

   Боді-текст Industries (services.html): один розрив ("...grounded")
   лишається спільним для десктопу й портрету (plain <br>, без класу,
   не чіпається). Інші 2 десктопні розриви ховаються (новий --desktop
   клас) і замінюються 4 новими --portrait розривами.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .our-commitments__title-break--portrait {
    display: inline;
  }

  .our-commitments__item-body-break--tablet {
    display: none;
  }

  .our-commitments__item-body-break--portrait {
    display: inline;
  }

  .industries__desc-break--desktop {
    display: none;
  }

  .industries__desc-break--portrait {
    display: inline;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Фікс: FAQ (стиль тайтла) + CTA-2/Footer
   (services.html)

   Тайтл FAQ: Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного
   .dm-h2 — той самий стиль, що тайтли інших секцій цієї сторінки
   (Our Commitments/Industries, Кроки 173/174). width:fit-content/
   white-space:nowrap (база, .faq__title) лишаються без змін — тайтл і
   так ніколи не переносився на 2 рядки (коментар Кроку 175).

   CTA-2: .cta--second перевикористовується на about/contact/index/
   work.html — тут скоуп через .faq + .cta--second (FAQ, а не Our
   Commitments, іде прямо перед CTA-2 на services.html, Крок 154), той
   самий готовий блок (80/624/224/1440×624 + .cta__line dm-36-reg), що
   вже реалізований для .offices/.about-offices + .cta--second (Крок 163).

   Footer: сайт-вайд (Крок 164 + фікс 20px між посиланнями колонок,
   .footer__col{gap:20px} у тому ж блоці) — .footer__* класи без різниці
   між сторінками (звичайні селектори, без adjacent-sibling), тому вже
   застосовується тут автоматично, без жодних додаткових правил.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .faq__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* 80px від низу FAQ-блоку (Крок 175) до верху фону CTA-2 */
  .faq + .cta--second {
    margin-top: 80px;
    /* Фікс: 362/100px — той самий готовий блок, що .offices/.about-offices
       + .cta--second (index/about.html) */
    height: 628px;
    padding-top: 362px;
    background-size: 1440px 624px;
  }

  .faq + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Фікс: тайтл→кнопка — 32px, той самий готовий блок, що .offices +
     .cta--second .cta__btn (index.html) */
  .faq + .cta--second .cta__btn {
    margin-top: 32px;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Хедер (глобально, всі 5 сторінок) + фон Hero-секції
   (Home)

   Фікс: Header перероблений 1:1 із Tablet Portrait (768–1023px, Крок 156) —
   лого + внутрішній строук + фреймована кнопка меню (48×48, з border) +
   CONTACT (127×48 CTA), той самий порядок/розміри/паддінги. ЄДИНА
   відмінність — ширина хедера по мобільній сітці (336px замість 668px),
   через що "гумовий" простір між строуком після лого і фреймом меню
   (margin-left:auto на .header__menu-btn) природно стає меншим — усі
   решта чисел (22px лого, 12px до строука, 48×48 фрейм меню, border 1px,
   127×48 CONTACT, -12px right-margin) — БЕЗ ЗМІН, ідентичні Tablet
   Portrait. Так само, як і там, це ОДИН статичний вигляд без "top"/
   "scrolled"/"peek"-переходів по скролу, тому кожне правило зі стан-
   залежним селектором (2+ класи) у базовому CSS продубльоване тут з тією
   самою чи вищою специфічністю.
   ========================================================================== */

@media (max-width: 767px) {

  /* Фікс: ширина — по сітці, ФІКСОВАНА 336px (4×72 + 3×16), центрована
     (left:0; right:0; margin:0 auto — той самий прийом, що вже на
     базовому .header, тут лише явно повторений), а не 100vw − 40px
     (колишнє помилкове "stretch"-визначення, Крок 176-фікс). "top" —
     20px від верху в'юпорта (було 62px — браузер/пристрій сам враховує
     safe area системних елементів, зайвий відступ прибрано). padding —
     12px, той самий, що Tablet Portrait (не 13px) */
  .header {
    top: 20px;
    left: 0;
    right: 0;
    width: 336px;
    margin: 0 auto;
    height: 48px;
    padding: 12px;
    background-color: var(--color-background);
    box-shadow: inset 0 0 0 1px var(--grey-15);
    /* Фікс: hide-on-scroll-down/show-on-scroll-up (js/header.js, лише
       Mobile) — ЛИШЕ opacity+transform, той самий дует/easing-токен
       (--ease-smooth), що .scroll-reveal. background-color/box-shadow
       (300ms ease, з базового правила) свідомо НЕ переносяться сюди —
       на цьому breakpoint .header завжди має однакові background-color/
       box-shadow (константа вище, не залежить від .header--scrolled),
       тому та transition ніколи нічого не анімувала, лише додавала зайвий
       шар поверх scroll-reveal-переходу (Фікс, п.1-2) */
    transition: opacity .65s var(--ease-smooth), transform .65s var(--ease-smooth);
  }

  /* .header--hidden перемикається JS-ом (js/header.js) виключно в межах
     matchMedia('(max-width:767px)') — клас навмисне скоуплений тут-таки в
     цьому ж breakpoint-блоці як друга лінія захисту: навіть якби JS
     помилково лишив клас на елементі під час ресайзу за межі Mobile,
     він ніяк не впливає на вигляд хедера на Tablet/Desktop */
  .header--hidden {
    opacity: 0;
    transform: translateY(-20px);
    pointer-events: none;
  }

  /* Розкриває .header__brand (лого + внутрішній строук + кнопка меню) як
     прямих флекс-дітей самого .header — той самий прийом, що Tablet
     Portrait */
  .header__brand {
    display: contents;
  }

  .header__logo {
    width: 22px;
    height: 22px;
  }

  /* Строук одразу після лого — 12px від правого краю лого (той самий
     відступ, що Tablet Portrait) */
  .header__divider--logo {
    display: block;
    width: 1px;
    height: 48px;
    margin-left: 12px;
    background: var(--grey-15);
    flex-shrink: 0;
  }

  /* Цей внутрішній строук (успадкований з десктопу, де він стоїть перед
     кнопкою меню) тут зайвий за дизайном — той самий фікс, що Tablet
     Portrait: display:none, "гумова" роль (margin-left:auto) переїжджає
     на сам .header__menu-btn нижче */
  .header__brand .header__divider {
    display: none;
  }

  /* Іконка меню — фреймована кнопка 48×48 (на всю висоту хедера), border
     зверху/знизу, той самий прийом, що Tablet Portrait. Фрейм впритул
     (0px) до строука після лого, без власного лівого строука (дублював
     строук після лого) — той самий строук натомість справа від фрейму.
     "Гумова" роль (забирає вільну ширину між кластером лого+меню і
     CONTACT) переїхала на .header__divider--contact нижче. Три
     селектори нижче дублюють один і той самий стан-залежний клас із
     базового CSS (top/scrolled/scrolled+peek), щоб перемогти незалежно
     від того, який стан тримає header.js */
  .header__menu-btn,
  .header--scrolled .header__menu-btn,
  .header--scrolled.header--peek .header__menu-btn {
    width: 48px;
    height: 48px;
    margin-left: 0;
    opacity: 1;
    pointer-events: auto;
    border-left: none;
    border-top: 1px solid var(--grey-15);
    border-bottom: 1px solid var(--grey-15);
    border-right: 1px solid var(--grey-15);
  }

  /* Ховер фрейму — фон grey-15, той самий колір, що Tablet Portrait */
  .header__menu-btn:hover {
    background-color: var(--grey-15);
  }

  /* Навігації немає за дизайном (як і на Tablet Portrait) — display:none */
  .header__nav {
    display: none;
  }

  /* Строук між фреймом меню і CONTACT, 0px справа — той самий прийом,
     що Tablet Portrait. "Гумова" роль (margin-left:auto, забирає вільну
     ширину між кластером лого+меню зліва і CONTACT справа) — той самий
     прийом, що вже використовує сам .header у flex */
  .header__divider--contact,
  .header--scrolled .header__divider--contact {
    height: 48px;
    margin-left: auto;
    opacity: 1;
    pointer-events: auto;
  }

  /* CONTACT — завжди CTA (заповнена кнопка), без альтернативного
     "top"/"peek"-вигляду, той самий прийом, що Tablet Portrait */
  .header:not(.header--scrolled) .header__contact-link.cta-button,
  .header--scrolled.header--peek .header__contact-link.cta-button {
    background: var(--primary-100);
    color: var(--color-background);
  }

  .header:not(.header--scrolled) .header__contact-link.cta-button:hover,
  .header--scrolled.header--peek .header__contact-link.cta-button:hover,
  .header:not(.header--scrolled) .header__contact-link.cta-button:active,
  .header--scrolled.header--peek .header__contact-link.cta-button:active {
    background: var(--primary-100);
    color: var(--color-background);
  }

  .header:not(.header--scrolled) .header__contact-link.cta-button::after,
  .header--scrolled.header--peek .header__contact-link.cta-button::after {
    content: '';
  }

  .header:not(.header--scrolled) .header__contact-link::before,
  .header--scrolled.header--peek .header__contact-link::before {
    content: none;
  }

  /* Фіксований розмір 126×46px (-1px ширина/-2px висота, Фікс) — той
     самий прийом і те саме обґрунтування, що Tablet Portrait (styles
     вище): margin-right зменшено з -12px до -11px У ТІЙ САМІЙ пропорції,
     що ширина, інакше auto-margin на .header__menu-btn компенсував би
     зміну ширини й правий край кнопки лишився б, як і раніше, впритул
     до строука */
  .header__contact-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 126px;
    height: 46px;
    padding: 0;
    margin-left: 0;
    margin-right: -11px;
  }

  /* Той самий фікс, що Tablet Portrait — нейтралізує глобальний
     "scrolled"-хак (-1px box-shadow/зсув ::after), зайвий тут, бо
     роздільник має ФІКСОВАНИЙ margin-left:0 (не auto) */
  .header--scrolled:not(.header--peek) .header__contact-link.cta-button {
    box-shadow: none;
  }

  .header--scrolled:not(.header--peek) .header__contact-link.cta-button::after {
    left: 0;
  }

  /* Фон Hero (Home) — новий mobile-ассет (1262×710), коефіцієнт
     k = 710/812 ≈ 0.8744 (референсний вʼюпорт 812px заввишки → фон 710px).
     На відміну від Десктопу/Tablet Landscape/Tablet Portrait, фон тут НЕ
     переливається в наступну секцію: box height обмежена рівно 100vh
     (100svh) — стільки ж, скільки сама .hero — тому висота фону 87.44vh
     завжди МЕНША за box, і різниця (100vh − 87.44vh) знизу лишається
     порожньою (прозорою) частиною .hero__bg, крізь яку проступає
     суцільний background-color самої .hero (var(--color-background),
     задано в базовому правилі .hero) */
  .hero__bg {
    height: 100vh;
    height: 100svh;
    background-position: center top;
    background-size: auto calc(87.44vh);
    background-size: auto calc(87.44svh);
    background-image: url("../assets/images/hero-bg-mobile.webp");
    background-image: image-set(
      url("../assets/images/hero-bg-mobile.webp") 1x,
      url("../assets/images/hero-bg-mobile@2x.webp") 2x
    );
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 177: текстовий блок і кнопки Hero (Home)

   Контент лейбла/тайтла/боді той самий, що на планшетних версіях —
   HTML не чіпаємо, лише перестилюємо. Тайтл — .dm-28-reg (Mob/H1,
   tokens.css), значення продубльовані тут напряму (той самий прийом,
   що Tablet Portrait, Крок 156, п. .hero__title — не через додавання
   класу в розмітку).
   ========================================================================== */

@media (max-width: 767px) {

  /* Тайтл — Mob/H1 (.dm-28-reg). Відступ від лейбла — 8px (12px у
     десктопі/планшеті). Фікс: ширина — 336px (сітка), а не успадковані
     811px (десктоп) — на відміну від планшета/десктопу, де вихід тексту
     за межі сітки допустимий, на мобільному тайтл/боді мають вміщуватись
     строго в 336px */
  .hero__title {
    margin-top: 8px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Перемикання розривів тайтла для Mobile — вмикаємо --1/--4 (--3
     лишається активним успадковано з десктопного правила за
     замовчуванням, --2 лишається вимкненим так само) */
  .hero__title-break--1,
  .hero__title-break--4 {
    display: inline;
  }

  /* Відступ від тайтла до боді — 16px (18px у десктопі). Фікс: ширина —
     344px, а не успадковані 545px (десктоп). Було 336px (сітка), але новий
     боді-текст ("Every engagement starts with evidence") на 336px
     переносився ще раз усередині першого рядка (виміряно: рядок потребує
     338px) — 344px лишає невеликий запас */
  /* Фікс: боді-текст — DM Sans/14 Light (.dm-14-light), не успадкований
     .dm-desc (18px, з розмітки) — тут перевизначається напряму, той самий
     прийом, що .hero__title вище (значення продубльовані, а не через
     заміну HTML-класу) */
  .hero__desc {
    margin-top: 16px;
    width: 344px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Ручний перенос боді-тексту — той самий перемикач, що Tablet Portrait
     (окремий медіа-запит, тому правило продубльоване тут) */
  .hero__desc-break--narrow {
    display: inline;
  }

  /* Позиція текстового блока — 277px/295px від верху/низу в'юпорта при
     референсній висоті 778px (277/778 і 295/778), у % від .hero (сама
     100vh/100svh) — той самий прийом, що в десктопі/планшетних версіях,
     тому масштабується пропорційно висоті вікна. Кнопки (.hero__buttons)
     сюди не входять — вони винесені з потоку нижче (position: fixed) */
  .hero__spacer--top {
    height: 35.6041%;
  }

  .hero__spacer--bottom {
    height: 37.9177%;
  }

  /* Фікс: кнопки прив'язані до низу HERO-СЕКЦІЇ (.hero), а не до вікна
     браузера — position: absolute (не fixed), 20px від нижнього краю
     .hero (було 12px). .hero__content (найближчий позиційований предок
     між .hero__buttons і .hero) переводиться на position: static нижче,
     інакше він, а не .hero, перехопив би containing block — і "20px від
     низу" рахувалось би від низу текстового блоку (лейбл+тайтл+боді),
     а не від низу секції. z-index: 2 на .hero__content і далі working:
     z-index застосовується до flex-item навіть при position: static
     (спец. Flexbox), стекінг не ламається.
     Секондарі-кнопку прибрано (лишається лише CTA) — .hero__buttons
     тепер один флекс-айтем, тому обгортка природно стискається до його
     висоти без "дірки" на місці видаленої кнопки. Ширина — фіксована
     336px (сітка), центрована (left:0;right:0;margin:0 auto — той самий
     прийом, що .header) */
  .hero__content {
    position: static;
  }

  .hero__buttons {
    position: absolute;
    left: 0;
    right: 0;
    width: 336px;
    margin: 0 auto;
    bottom: 20px;
    z-index: 5;
    flex-direction: column;
  }

  /* На всю ширину (по сітці, margin 20px — вже забезпечено left/right
     на .hero__buttons вище), фіксована 48px-висота успадкована з базового
     .hero__btn без змін. Ширина 191px (десктоп/планшет) замінюється на
     100% */
  .hero__btn--primary {
    width: 100%;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 178: секція Services, права частина (Home)

   Ілюстрацію-квітку (.services__illustration-*, .services__tag) спершу тут
   навмисно не займали — додана нижче окремим фіксом (той самий принцип,
   що Tablet Portrait, Крок 157). Тайтл тут — не просто інший перенос рядків, а переписаний
   текст, тому окрема <h2> (.services__title--mobile, index.html), той
   самий прийом, що .faq-item__body--tablet (окрема <p> з переписаним
   текстом) — .services__title--desktop вимикається поруч.
   ========================================================================== */

@media (max-width: 767px) {

  /* Фікс: сітка — фіксована 336px (4×72+3×16), центрована (margin:0 auto)
     замість 100vw − 40px stretch (Крок 176-фікс) */
  .services__intro-grid,
  .services__panel-grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* 38px padding-top: CTA-кнопка Hero фіксована на bottom: 20px (нижній
     край = 100vh − 20px, було 12px); .services__intro природно
     починається одразу на 100vh (низ .hero) — 38px тут лишені без змін
     (не запитувані цим фіксом), тому проміжок між кнопкою й .services
     тепер 42px замість колишніх 50px (100vh − 20 + 42 = 100vh + 38) */
  .services__intro {
    padding-top: 38px;
  }

  /* Номер — у межах сітки, вирівняний по правому краю (остання, 4-та
     колонка). Лейбл (.services__label) лишається на колонці 1 без змін —
     той самий контент/стиль, що на планшетній версії, тут не згаданий */
  .services__index {
    grid-column: 4;
    justify-self: end;
  }

  /* Тайтл — на всю сітку (1/5, усі 4 колонки), 14px від лейбла. Стиль
     (Mob/H2, .dm-24-reg) прийшов прямо з класу в розмітці
     (.services__title--mobile), тут не дублюється */
  .services__title {
    grid-column: 1 / 5;
    margin-top: 14px;
  }

  .services__title--desktop {
    display: none;
  }

  .services__title--mobile {
    display: block;
  }

  /* Боді — той самий контент, DM Sans/14 Light замість .dm-desc, на всю
     сітку, 16px від тайтла */
  .services__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Табличка — на всю сітку (width:auto замість фіксованих 572px/326px,
     стретчиться в grid-area 1/5), 292px від боді-тексту. height:600px —
     фолбек/дизайнерський максимум (той самий прийом, що 844/720/778 у
     десктопі/tablet/tablet portrait) — РЕАЛЬНЕ значення й далі рахує
     js/services-table.js (додана лише нова бакет-константа під цей
     діапазон ширин, сам алгоритм гортання/гістерезису/таймінгів не
     змінено — Крок 178 explicitly просить залишити анімацію ідентичною) */
  .services-table-window {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 292px;
    height: 600px;
  }

  /* Фікс: той самий підхід, що на десктопі/Tablet Landscape/Tablet
     Portrait (активний чіп без нижнього строука, фрейм тайтла + лейбл,
     фрейм айтема Red Hat/12 Bold (tracking), лівий градієнтний строук
     на весь блок) — тут: фрейм тайтла 60px + .dm-20-reg (замість 62px/
     22px десктопу), фрейм айтема 56px (як на Tablet Portrait), пустий
     фрейм 40px (відмінність від 56px усюди інде). Патерн (.services-
     table__row--strokes, 40px) успадковано з базового правила без змін.
     Замінює попередній варіант (DM Sans/14 Light, 24px padding-left) —
     той стиль тепер вважається застарілим щодо узгодженої ревізії */
  .services__tag--active::after {
    display: none;
  }

  .services-table__row--heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 60px;
    padding: 0 24px;
  }

  .services-table__heading-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 20px;
    line-height: 28px;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--grey-100);
  }

  .services-table__heading-label {
    display: inline-block;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-50);
  }

  .services-table__row--item {
    height: 56px;
    padding: 0 0 0 24px;
    display: flex;
    align-items: center;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--grey-55);
  }

  .services-table__row--empty {
    height: 40px;
  }

  /* Фікс: лівий вертикальний строук по блоку (десктоп/Tablet Landscape/
     Tablet Portrait, вище) на Mobile не підходить — вимикається повністю,
     замінений горизонтальним строуком на .services-table-window нижче */
  .services-table__group::before {
    display: none;
  }

  /* Фікс: горизонтальний градієнтний строук зверху таблички — на відміну
     від вертикального (вище), тут статичний і ЗАВЖДИ присутній (не
     залежить від активного блоку), напрям — var(--primary-grad)
     горизонтальний (зліва направо), не var(--primary-grad-services)
     (вертикальний). Скоуплений на .services-table-window (сама видима
     "картка" з фіксованими межами на екрані), а не на .services-table
     (яку JS транслює transform'ом усередині вікна) — інакше строук
     їхав би разом зі скролом замість лишатись на верхньому пікселі */
  .services-table-window::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--primary-grad);
    z-index: 2;
    pointer-events: none;
  }

  /* Фон таблички — var(--color-background) (стиль "background") на всю
     табличку, якщо відсутній */
  .services-table {
    background-color: var(--color-background);
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — 550×550px,
     той самий rotate/mask/tag crossfade-механізм, що на десктопі/планшеті
     (js/services-illustration.js тут не чіпається). margin-top:32px —
     відступ від боді-тексту секції до верху ілюстрації (той самий
     grid-row:1, що й .services-table-window вище, свій незалежний
     відступ). Горизонталь: фрейм вирівняний по правому краю сітки (336px)
     з відступом 1px → margin-left = (336 − 1) − 550 = −215px. Ілюстрація
     лежить під табличкою (z-index нижче, той самий принцип, що в
     десктопі/планшеті) — оскільки табличка тут на всю сітку (grid-column:
     1/5, непрозорий фон вище) і починається нижче (292px), видима лише
     верхня частина ілюстрації, до того, як табличка її накриває */
  .services__illustration-stack {
    width: 550px;
    height: 550px;
    margin-top: 32px;
    margin-left: -215px;
  }

  .services__illustration-base,
  .services__illustration-mask {
    width: 550px;
    height: 550px;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Фікс: секція Trusted By (Home, index.html лише)

   Той самий "перші 8 логотипів, 2 ряди по 4" принцип, що Tablet Portrait
   (Крок 162), лише 72×72px клітинки/16px gutter (336px = 4×72+3×16, точно
   ширина мобільної сітки) замість 155×155/16px. js/services-table.js
   отримав відповідний guard (той самий принцип, що Крок 158, п.1 для
   Tablet Portrait) — inline marginTop тут не підставляється, formula
   розрахована на десктопну ілюстрацію/табличку, нерелевантну тут.

   Фікс: margin-top:64px нижче — 64px від нижнього краю ТАБЛИЧКИ Services
   (не ілюстрації — на мобільному ілюстрація відображається інакше й
   частково накрита табличкою, див. Фікс вище) до верху Trusted By.

   Набір із 8 видимих логотипів РОТУЄТЬСЯ кожні 7с через усі 16
   (js/trusted-by-rotate.js, розширено й на Tablet Portrait) — 8 фізичних
   клітинок (nth-child(n+9) ховаються) лишаються на тих самих позиціях,
   міняється лише їхній img src/alt (обидва варіанти, білий/чорний) на
   наступну групу з 8. Crossfade — .trusted-by__logo-wrap--fading
   (opacity+translateY(12px), 650ms var(--ease-smooth) — та сама
   тривалість/easing, що .scroll-reveal) на обгортці НАВКОЛО логотипів,
   не на самій клітинці (фрейм і його hover-фон лишаються статичними) —
   стара група гасне, JS міняє src/alt, поки невидима, нова проявляється
   вже з новим вмістом.

   about.html ділить ті самі BEM-класи (той самий факт, що вже
   задокументований для Крок 162) — усі правила нижче скоуплені через
   ".services + .trusted-by", той самий adjacent-sibling прийом, щоб не
   зачепити about.html (desktop-версія тут лишається, окремий крок
   пізніше). js/trusted-by-rotate.js так само шукає лише
   ".services ~ .trusted-by .trusted-by__logos" — не займає about.html.
   ========================================================================== */

@media (max-width: 767px) {

  /* Фікс: 64px від нижнього краю таблички Services до верху Trusted By
     (не ілюстрації — див. коментар вище) — тепер лише CSS-фолбек.
     js/services-table.js рахує ТУТ реальний inline marginTop динамічно
     (formula компенсує звис таблички за межу 100vh-панелі — фіксоване
     число тут давало РЕАЛЬНИЙ відступ менший за заявлений) */
  .services + .trusted-by {
    margin-top: 64px;
  }

  .services + .trusted-by .trusted-by__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Номер — колонка 4, вирівняний по правому краю (той самий принцип,
     що .services__index/.offices__index на мобільному) */
  .services + .trusted-by .trusted-by__index {
    grid-column: 4;
    justify-self: end;
  }

  .services + .trusted-by .trusted-by__logos {
    grid-column: 1 / 5;
    grid-row: 2;
    margin-top: 16px;
    grid-template-columns: repeat(4, 72px);
    grid-template-rows: repeat(2, 72px);
    gap: 16px;
  }

  .services + .trusted-by .trusted-by__logo-cell,
  .services + .trusted-by .trusted-by__logo {
    width: 72px;
    height: 72px;
  }

  /* Фікс: hover належить КЛІТИНЦІ (фрейму), не логотипу — pointer-events:
     none на самих <img> гарантує, що курсор завжди "проходить крізь" них
     до .trusted-by__logo-cell, тому :hover ніколи не може спрацювати на
     логотипі окремо від фрейма. Фон (::after) і так завжди на клітинці
     (нижче), логотип лише міняє колір (opacity білий/чорний) — це не
     чіпаємо, лише унеможливлюємо будь-яку двозначність щодо ЧИЙ саме
     :hover тут працює */
  .services + .trusted-by .trusted-by__logo {
    pointer-events: none;
  }

  /* Лише перші 8 логотипів (2 ряди по 4) фізично видимі — js/trusted-by-
     rotate.js ротує їхній ВМІСТ через усі 16, самі клітинки лишаються
     на місці */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(n + 9) {
    display: none;
  }

  /* Останній стовпець кожного ряду (4, 8) — права лінія групи вже
     всередині власного діапазону блока */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(4n)::after {
    right: 0;
  }

  /* Другий (останній) ряд (5–8) — нижня лінія групи вже всередині
     власного діапазону блока */
  .services + .trusted-by .trusted-by__logo-cell:nth-child(n + 5)::after {
    bottom: 0;
  }

  .services + .trusted-by .trusted-by__lines {
    background-size:
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      336px 1px,
      336px 1px,
      336px 1px,
      72px 1px,
      72px 1px,
      72px 1px,
      72px 1px;
    background-position:
      0px 0,
      72px 0,
      88px 0,
      160px 0,
      176px 0,
      248px 0,
      264px 0,
      right 0px top 0,
      0 0px,
      0 72px,
      left 0 bottom 0px,
      0px 88px,
      88px 88px,
      176px 88px,
      264px 88px;
  }

  /* Справжній фікс (замінює попередню, помилкову версію): crossfade
     живе на .trusted-by__logo-wrap (обгортка НАВКОЛО логотипів), а НЕ на
     .trusted-by__logo-cell (фрейм) — фрейм і його hover-фон (::after
     вище) лишаються повністю статичними, ніколи не отримують
     transform/opacity від ротації. opacity+translateY, той самий
     принцип/easing, що .scroll-reveal, лише менший transform (12px);
     клас-модифікатор і таймінг керуються з js/trusted-by-rotate.js */
  .services + .trusted-by .trusted-by__logo-wrap {
    will-change: opacity, transform;
    transition: opacity 650ms var(--ease-smooth), transform 650ms var(--ease-smooth);
  }

  .services + .trusted-by .trusted-by__logo-wrap--fading {
    opacity: 0;
    transform: translateY(12px);
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 179: секція Selected Work (Home)

   work.html перевикористовує ці самі класи карток (той самий факт, що вже
   задокументований для Tablet Landscape/Tablet Portrait, Крок 135/159) —
   усі спільні .work-card-правила нижче скоуплені під предком .selected-work.
   .selected-work__grid/__index/__title/__desc/__row3 унікальні лише для
   index.html, як і раніше, — без скоупу.

   Той самий "display: contents на обгортках" прийом, що Tablet Portrait
   (Крок 159): 5 .work-card + .see-all-work стають прямими дітьми
   .selected-work__grid у справжньому DOM-порядку, без патернів-заповнювачів,
   лише з іншими значеннями відступів/розмірів під мобільну сітку.
   ========================================================================== */

@media (max-width: 767px) {

  /* 70px від низу видимої частини таблички Services (600px, Крок 178) до
     верху лейбла Selected Work — та сама конвенція, що 206px (десктоп) /
     100px (Tablet Portrait): .services переходить у звичайний потік рівно
     там, де закінчується видиме вікно таблиці, тому це просто margin-top */
  .selected-work {
    margin-top: 70px;
  }

  /* Фікс: сітка — фіксована 336px, центрована, замість 100vw − 40px
     stretch (Крок 176-фікс) */
  .selected-work__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Фікс: лейбл успадковував grid-column:1 (72px) зі спільного правила
     (рядок ~1385) — "SELECTED WORK" туди не влазить і переносився на
     2 рядки. На всю ширину сітки (1/5, 336px), той самий фікс, що вже
     на Tablet Landscape (вище) і .about-approach__label/.how-we-work__label */
  .selected-work__label {
    grid-column: 1 / 5;
  }

  /* Номер — у межах сітки, вирівняний по правому краю (4-та колонка) —
     той самий принцип, що .services__index (Крок 178) */
  .selected-work__index {
    grid-column: 4;
    justify-self: end;
  }

  /* Тайтл — той самий стиль/відступи, що Services (Крок 178): на всю
     сітку, 14px від лейбла, Mob/H2 (.dm-24-reg). Контент (сам текст)
     той самий, що на планшетній версії — не рядок Services, тому клас
     у розмітці не чіпаємо, лише стиль. Фікс: ручний перенос на 2 рядки —
     .selected-work__title-break--mobile (прихований за замовчуванням,
     увімкнений лише тут) */
  .selected-work__title {
    grid-column: 1 / 5;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .selected-work__title-break--mobile {
    display: inline;
  }

  /* Боді — DM Sans/14 Light, 16px від тайтла, на всю сітку */
  .selected-work__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* "Розкриває" обгортки — той самий прийом, що Tablet Portrait (Крок 159) */
  .selected-work .selected-work__cards,
  .selected-work .selected-work__col-secondary,
  .selected-work .selected-work__row2,
  .selected-work .selected-work__row3 {
    display: contents;
  }

  /* Без патернів-заповнювачів (п.4) */
  .selected-work .selected-work__strokes,
  .selected-work .selected-work__pattern {
    display: none;
  }

  /* Кожен айтем — на всю ширину сітки. Специфічність двох класів
     (.selected-work + .work-card) вища за десктопні .work-card--primary/
     --secondary (по одному класу), тому одного правила досить для ОБОХ */
  .selected-work .work-card {
    grid-column: 1 / 5;
    width: 100%;
  }

  /* 32px від низу боді-тексту до верху ПЕРШОГО айтема (Hermes,
     work-card--primary — єдина картка з цим модифікатором) */
  .selected-work .work-card--primary {
    margin-top: 32px;
  }

  /* 24px між усіма рештою айтемів (усі --secondary в порядку DOM) —
     та сама відстань застосована й до SEE ALL OUR WORK нижче, як до
     наступного айтема в тому самому вертикальному стеку */
  .selected-work .work-card--secondary {
    margin-top: 24px;
  }

  /* Фото — власний оригінальний aspect-ratio кожного типу айтема (720:564
     великого/primary, 424:332 малого/secondary), а не фіксована px-висота —
     той самий прийом, що Tablet Portrait (Крок 159, п.6), width:100%
     успадкований з базового .work-card__image без змін */
  .selected-work .work-card--primary .work-card__image {
    aspect-ratio: 720 / 564;
    height: auto;
  }

  .selected-work .work-card--secondary .work-card__image {
    aspect-ratio: 424 / 332;
    height: auto;
  }

  /* Тайтл айтема — DM Sans/18 Reg (.dm-18-reg, tokens.css — уже існує,
     новий клас не потрібен) замість .dm-20-reg з розмітки */
  .selected-work .work-card__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 18px;
    line-height: 24px;
    letter-spacing: 0em;
  }

  /* Боді-текст айтема (теги) — DM Sans/14 Light замість .dm-16-light */
  .selected-work .work-card__body {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: відступ від низу боді-тексту до фрейму тегів — 20px (був 28px).
     .work-card__info має фіксовану висоту (не автоматичну), тому відступ —
     це просто "залишок" висоти нижче контенту; 122−8=114px дає рівно 20px
     замість 28px при тутешніх (зменшених) розмірах тайтла/боді вище */
  .selected-work .work-card__info {
    height: 114px;
  }

  /* Фікс: SEE ALL OUR WORK — з десктопної великої картки-плейсхолдера
     (424×520, тонкий border) стає секондарі-кнопкою. Текст/іконка (flex,
     align-items/justify-content:center, gap:10px) успадковані з
     .see-all-work — лишаються без змін, центрування вже було. На всю
     ширину сітки (336px), 48px, 24px від низу останнього айтема
     (Transcarent) */
  /* Фікс: нові стейти глобального .secondary-button (нижній градієнтний
     строук прибрано; hover/pressed — фон var(--grey-20); pressed —
     колір тексту var(--grey-additional-pressed); disabled — фон
     var(--grey-15) + колір var(--grey-additional-disabled)) — .see-all-work
     не є .secondary-button (десктопна велика картка-плейсхолдер має
     інший вигляд, той стиль тут не чіпаємо), тому стейти продубльовано
     тут з тими самими токенами, той самий підхід, що Tablet Portrait */
  .selected-work .see-all-work {
    grid-column: 1 / 5;
    width: 100%;
    height: 48px;
    margin-top: 24px;
    border: none;
    background: var(--grey-15);
    color: var(--grey-100);
    transition: background-color 300ms ease, color 300ms ease;
  }

  .selected-work .see-all-work::after {
    display: none;
  }

  .selected-work .see-all-work:hover {
    background: var(--grey-20);
  }

  .selected-work .see-all-work:active {
    background: var(--grey-20);
    color: var(--grey-additional-pressed);
  }

  .selected-work .see-all-work:disabled,
  .selected-work .see-all-work.is-disabled {
    background: var(--grey-15);
    color: var(--grey-additional-disabled);
  }
}

@media (max-width: 767px) {
  /* Hero боді-текст — 3-рядковий перенос замість 2-рядкового (той самий
     tablet-break прийом, що .footer__who-body-break--desktop/--mobile) */
  .work-hero__desc-break--desktop {
    display: none;
  }

  .work-hero__desc-break--mobile {
    display: inline;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 180: секція CTA з китом (Home)

   .cta (bare-клас) перевикористовується на about/contact/services/work.html
   (CTA-2, .cta--second, там своя окрема секція перед ним) — тому скоуп
   через суміжний селектор .selected-work + .cta, той самий прийом, що
   Tablet Portrait (Крок 160). .cta__btn теж спільний з CTA-2 (базове
   правило навмисно застосовує margin-top на ВСІХ сторінках, коментар вище) —
   84/107px-паддінг і калк-ширина тут навмисно перевизначені ЛИШЕ для кита
   (вищий пріоритет через 3-класовий скоуп-селектор), CTA-2 і решта
   .hero__btn--primary сайту лишаються на загальних мобільних значеннях
   (Крок 177: width:100%, padding-left:107px).
   ========================================================================== */

@media (max-width: 767px) {

  /* Фон — Фікс: власний мобільний ассет (image-set 1x/2x, whale-mobile.webp/
     @2x, 768×598), замість успадкованого десктопного whale-bg.webp,
     масштабованого через background-size. Fixed no-scale розмір 768×598
     (натуральний розмір ассета, без масштабування) — background-position:
     center top (центрування по горизонталі, той самий принцип, що
     .cta базове правило). margin-top: 32px — відступ від низу кнопки
     "See all our work" (Selected Work) до верху фону CTA (п.4); разом із
     padding-top: 64px (нижче) дає 32+64=96px відступу кнопка→тайтл CTA
     (п.5) */
  .selected-work + .cta {
    margin-top: 32px;
    height: 598px;
    padding-top: 64px;
    background-position: center top;
    background-repeat: no-repeat;
    background-size: 768px 598px;
    background-image: url("../assets/images/whale-mobile.webp");
    background-image: image-set(
      url("../assets/images/whale-mobile.webp") 1x,
      url("../assets/images/whale-mobile@2x.webp") 2x
    );
  }

  /* Тайтл — Mob/H1 (.dm-28-reg) замість десктопного .dm-h0 */
  .selected-work + .cta .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Тайтл у 3 рядки на Mobile (п.1): примусовий перенос усередині
     .cta__line--2 */
  .selected-work + .cta .cta__line-break--mobile {
    display: inline;
  }

  /* Кнопка — 32px від тайтла, на всю ширину сітки (фіксовані 336px, а не
     100vw − 40px stretch, Крок 176-фікс) — align-items: center на
     флекс-колонці .cta сам центрує 336px-вий блок, окремий margin:auto
     не потрібен. Фікс: асиметричний padding-left:83px (Крок 177,
     "eyeball"-хак під центрування ще ДО justify-content:center на
     .hero__btn) прибрано — лишається симетричний padding:14px 32px із
     базового .hero__btn, текст+іконка центруються ним по-справжньому */
  .selected-work + .cta .cta__btn {
    margin-top: 32px;
    width: 336px;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 181: секція Industries (Home)

   .industries/.industry-row перевикористані 1:1 на services.html
   (.industries--services) — скоуп через .cta + .industries, той самий
   прийом, що Tablet Portrait (Крок 161). Глобус (.industries__globe-*)
   свідомо НЕ займаємо — окремий крок пізніше (той самий принцип, що
   Services/Selected Work, Кроки 178/179).

   .industry-row/__content/__title/__tags/__divider/__illustration-wrap —
   структура/стилі ІДЕНТИЧНІ Tablet Portrait (Крок 161), скопійовані без
   змін: жоден із цих правил не посилається на 326px напряму (усі — 0/100%/
   right:0, вже фluid відносно власного батька), тому "розтягнути на всю
   сітку" зводиться лише до .industries__list (grid-column 1/3 → 1/5).
   ========================================================================== */

@media (max-width: 767px) {

  /* 358px від нижнього краю CTA-кнопки (Крок 180) до верху лейбла —
     НЕ від фону/секції CTA: секція (598px) значно вища за фактичний вміст
     (64 padding-top + 67.1875 тайтл + 32 + 48 кнопка = 211.1875px), тому
     "плаский" margin-top від низу секції дав би величезний зайвий проміжок.
     Перевірено headless Chrome (реальний рендер, DM Sans/Red Hat, з
     поправкою на початковий translateY(40px) .scroll-reveal-up — однаковий
     зсув на кнопці й лейблі, тому скасовується в різниці): фактичний
     проміжок від НИЗУ СЕКЦІЇ до лейбла — 386.8125px, тому щоб від НИЗУ
     КНОПКИ вийшло рівно 358px, потрібен від'ємний margin-top (кнопка не
     сягає низу секції, Industries починається ще до кінця фону CTA —
     той самий "хвіст перекриває наступну секцію" принцип, що в hero__bg) */
  .cta + .industries {
    margin-top: -28.8125px;
  }

  /* Фікс: сітка — фіксована 336px, центрована, замість 100vw − 40px
     stretch (Крок 176-фікс) */
  .cta + .industries .industries__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Лейбл/номер/тайтл/боді — той самий принцип, що Selected Work
     (Крок 179): номер вирівняний по правому краю сітки, тайтл на всю
     сітку +14px (Mob/H2, .dm-24-reg), боді +16px (DM Sans/14 Light).
     Контент (сам текст) — той самий, що на Tablet Portrait */
  .cta + .industries .industries__index {
    grid-column: 4;
    justify-self: end;
  }

  .cta + .industries .industries__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .cta + .industries .industries__desc {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: десктопний глобус (.industries__globe-stack, 786×786,
     margin-left:792px) досі не був прихований на Mobile ("окремий крок
     пізніше", коментар вище) — залишався в потоці 4-колонкової мобільної
     сітки (grid-column:1, той самий row:4, що мобільний scrolly-глобус
     нижче) зі своєю ДЕСКТОПНОЮ абсолютною геометрією, тому виїжджав
     далеко за правий край в'юпорта (right:~1605px при 390px-вому екрані)
     і саме це, а не сам горизонтальний скрол-фікс, було справжньою
     причиною overflow'у html — діагностовано через getBoundingClientRect()
     по всіх елементах сторінки */
  .cta + .industries .industries__globe-stack {
    display: none;
  }

  /* Sticky-глобус scrollytelling (Крок — Mobile Industries): обгортка, що
     раніше стояла на .industries__list (grid-column:1/5, 32px від боді),
     переїжджає на .industries__scrolly-mobile — тепер САМЕ вона прямий
     grid-дитина .industries__grid (явний grid-row:4, той самий рядок,
     що раніше займав .industries__list). Висоту (100vh + дистанція
     гортання) рахує js/industries-mobile-scrolly.js — стільки, скільки
     потрібно, щоб .industries__scrolly-mobile-sticky (position:sticky)
     встигла "проїхати" повз в'юпорт, поки список продивляється */
  .cta + .industries .industries__scrolly-mobile {
    display: block;
    grid-column: 1 / 5;
    grid-row: 4;
    margin-top: 32px;
  }

  /* Пінується (position:sticky, top:0) на весь в'юпорт, поки триває
     дистанція гортання, задана батьком (.industries__scrolly-mobile) —
     той самий принцип, що .services__sticky (Крок 29/157/178). Фікс:
     overflow:hidden ЗНЯТО — position:sticky сам є positioned-предком і
     задає containing block для .industries__globe-stack-mobile
     (position:absolute, дитина нижче), тому overflow:hidden саме ТУТ
     обрізав 563px-ву ілюстрацію по краях 336px-вої сітки-колонки.
     Вертикальне обрізання списку рядків і так забезпечує ВЛАСНИЙ
     overflow:hidden на .industries__list-window (нижче) — воно не
     залежало від overflow на цьому елементі. Горизонтальний "виліт"
     ілюстрації за межі в'юпорта безпечний і без нього — global
     overflow-x:clip на html/body (Фікс вище) вже глушить page-level
     скрол/скролбар від будь-якого ширшого за viewport контенту */
  .cta + .industries .industries__scrolly-mobile-sticky {
    display: block;
    position: sticky;
    top: 0;
    /* Фікс (Chrome mobile): 100vh — статична одиниця, порахована від
       НАЙБІЛЬШОГО можливого viewport (адресний рядок прихований), тому
       коли рядок ВИДИМИЙ (реальний viewport менший), ця sticky-панель
       вища за фактично видиму область — .industries__globe-stack-mobile
       (position:absolute; bottom:0 усередині неї) впирається в НИЖ панелі,
       а не в справжній низ екрана, тому й виглядала обрізаною/наполовину.
       100dvh — динамічна одиниця, браузер сам перераховує її на кожен
       show/hide адресного рядка, без JS. Рядок вище (100vh) — фолбек для
       браузерів без підтримки dvh, каскадом перекривається */
    height: 100vh;
    height: 100dvh;
  }

  /* Вікно списку — фіксована (JS-порахована) висота, overflow:hidden;
     .industries__list усередині рухається translateY (js), той самий
     принцип "вікно+контент-що-їде", що .services-table-window/.services-table */
  .cta + .industries .industries__list-window {
    display: block;
    position: relative;
    overflow: hidden;
  }

  /* Фікс: скидає успадкований десктопний margin-top:96px (базове правило
     .industries__list) — усередині sticky-вікна він зайвий, зсуває
     фактичний контент і ламає JS-розрахунок висоти скролу (windowHeight/
     scrollRange рахують чисту суму висот рядків, без цього margin).
     Фікс: БЕЗ transition на transform — js/industries-mobile-scrolly.js
     тепер пише позицію 1:1 за фактичним прогресом скролу на кожен тик
     (не квантує до activeIndex×step), тому окремий "доганяючий" transition
     більше не потрібен і лише додавав би відставання списку від пальця */
  .cta + .industries .industries__list {
    position: relative;
    margin-top: 0;
    /* Safari-фікс продуктивності, той самий принцип, що .services-table
       (styles.css:1849) — transform пишеться на кожен тик скролу
       (js/industries-mobile-scrolly.js), will-change заздалегідь
       промотує шар у compositor */
    will-change: transform;
  }

  /* Фрейм — фіксована висота 138px, той самий прийом/арифметика, що
     Tablet Portrait (Крок 161) */
  .cta + .industries .industry-row {
    height: 138px;
  }

  /* Фікс: .industry-row успадковує .scroll-reveal/.scroll-reveal-up
     (fade-in-on-scroll, js/reveal.js) з базової розмітки — усередині
     sticky-вікна, що рухається transform (не природним скролом),
     IntersectionObserver рядка може так і не отримати повторний
     callback після початкового (не intersecting) виміру, і рядок
     назавжди лишається opacity:0. Той самий edge-case, чому
     .services-table__row--item (аналогічний "рядок у sticky-вікні")
     свідомо НЕ має класу .scroll-reveal у розмітці. Тут клас лишається
     в HTML (спільна розмітка з десктопом/Tablet, де він працює штатно),
     тому нейтралізуємо ефект лише в цьому скоупі: завжди видимий,
     без залежності від .is-visible */
  .cta + .industries .industry-row.scroll-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .cta + .industries .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 25px;
  }

  /* Немає hover (сенсорний пристрій, п.5) — активний рядок керується
     ВИКЛЮЧНО скролом (js/industries-mobile-scrolly.js через .is-active),
     не :hover. Дефолт — приглушений (grey-50/grey-50/opacity:0.3, той
     самий "dim"-стан, що десктопний :has(:hover) на СУСІДНІХ рядках,
     Крок 124); .is-active — повна яскравість (grey-100/grey-60/opacity:1) */
  .cta + .industries .industry-row__title {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 16px;
    line-height: 24px;
    letter-spacing: 0.12em;
    color: var(--grey-50);
    transition: color 200ms ease;
  }

  .cta + .industries .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .cta + .industries .industry-row__tags {
    margin-top: 17px;
    flex-wrap: wrap;
    row-gap: 8px;
    color: var(--grey-50);
    transition: color 200ms ease;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: Cybersecurity/Proptech (nth-child(4)/(5)) мають лише 2 теги,
     і їхня сумарна ширина в один рядок (~334px) фізично влазить у
     336px контейнер — на відміну від інших айтемів (3 довших теги),
     тут flex-wrap природно НЕ переносить другий тег, і той впритул
     налазить під колонку ілюстрації-літери (right:0, width:40px).
     flex-basis:100% на останньому тезі форсує перенос незалежно від
     ширини; row-gap:8px (успадкований вище) дає той самий вертикальний
     відступ між рядками, що вже природно виходить в інших айтемів.
     Висота рядка (138px, .industry-row вище) НЕ збільшується — те саме
     глобальне значення вже вміщає 2 рядки тегів із запасом (перевірено
     на інших айтемах: низ контенту 114px при висоті рядка 138px) */
  .cta + .industries .industry-row:nth-child(4) .industry-row__tags span:last-child,
  .cta + .industries .industry-row:nth-child(5) .industry-row__tags span:last-child {
    flex-basis: 100%;
  }

  .cta + .industries .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .cta + .industries .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
    transition: background-color 200ms ease, opacity 200ms ease;
  }

  .cta + .industries .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  .cta + .industries .industry-row__divider {
    left: 0;
    right: 0;
  }

  .cta + .industries .industry-row__illustration {
    display: none;
  }

  .cta + .industries .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .cta + .industries .industry-row__illustration-wrap::before,
  .cta + .industries .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .cta + .industries .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .cta + .industries .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  /* Немає hover на сенсорному пристрої (п.5) — кросфейд керується
     .is-active (js/industries-mobile-scrolly.js за позицією скролу),
     не :hover */
  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .cta + .industries .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .cta + .industries .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }

  /* Fade-маски вікна списку (п.4) — той самий принцип, що
     .services-table-window__fade (Services scrollytelling): затемнюють
     верх/низ видимої області, показуючи, що там ще є рядки. Висота/
     видимість керує js/industries-mobile-scrolly.js через .is-visible/
     .is-hidden (той самий підхід, що js/services-table.js) */
  .cta + .industries .industries__list-window-fade {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    height: 56px;
    pointer-events: none;
    z-index: 2;
    transition: opacity 300ms ease;
  }

  .cta + .industries .industries__list-window-fade--top {
    top: 0;
    background: linear-gradient(to bottom, var(--color-background), transparent);
    opacity: 0;
  }

  .cta + .industries .industries__list-window-fade--top.is-visible {
    opacity: 1;
  }

  .cta + .industries .industries__list-window-fade--bottom {
    bottom: 0;
    background: linear-gradient(to top, var(--color-background), transparent);
    opacity: 1;
  }

  .cta + .industries .industries__list-window-fade--bottom.is-hidden {
    opacity: 0;
  }

  /* Sticky-глобус (фікс): ФІКСОВАНИЙ розмір 563×286 — НЕ масштабується
     під ширину в'юпорта (на відміну від попередньої full-bleed/
     aspect-ratio версії). Центрується горизонтально відносно ЕКРАНА
     (left:50%+margin-left:-281.5px, половина ширини 563px), а не сітки —
     якщо через це ілюстрація ширша за в'юпорт/сітку, вона НЕ обрізається
     (немає overflow:hidden на батьках по горизонталі, той самий принцип,
     що horizontal-overflow-glow на .body). 5 акцентних масок кросфейдять
     поверх базового шару (та сама логіка/атрибут data-active-globe, що
     десктопний .industries__globe-stack, js/industries-mobile-scrolly.js).
     Фікс (Chrome-баг): .scroll-reveal.scroll-reveal-up ЗНЯТО з розмітки —
     на десктопі/tablet той самий клас на .industries__globe-stack ок,
     бо елемент звичайний, у потоці. Тут же елемент position:absolute;
     bottom:0 усередині position:sticky-панелі — на час one-shot reveal-
     transition (.65s, translateY(40px)→none) бокс фізично зсунутий,
     тому bottom:0 "недоїжджав" до справжнього низу в'юпорта, поки
     transition не доанімується — саме це виглядало як "ілюстрація
     наполовину" (спрацьовує щоразу, бо sticky-панель для reveal.js
     виглядає як щойно з'явлений елемент кожен раз, коли скрол доходить
     до пінінгу) */
  .cta + .industries .industries__globe-stack-mobile {
    display: block;
    position: absolute;
    left: 50%;
    bottom: 0;
    margin-left: -281.5px;
    width: 563px;
    height: 286px;
    pointer-events: none;
  }

  .cta + .industries .industries__globe-mobile--base,
  .cta + .industries .industries__globe-mobile-accent {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  .cta + .industries .industries__globe-mobile-accent {
    opacity: 0;
    transition: opacity 450ms ease;
    /* Safari-фікс продуктивності, той самий принцип, що .services-table
       (styles.css:1849) — без will-change WebKit не промотує шар
       заздалегідь, перший repaint кросфейду відчувається як затримка */
    will-change: opacity;
  }

  .cta + .industries[data-active-globe='f'] .industries__globe-mobile-accent--f,
  .cta + .industries[data-active-globe='h'] .industries__globe-mobile-accent--h,
  .cta + .industries[data-active-globe='e'] .industries__globe-mobile-accent--e,
  .cta + .industries[data-active-globe='c'] .industries__globe-mobile-accent--c,
  .cta + .industries[data-active-globe='p'] .industries__globe-mobile-accent--p {
    opacity: 1;
  }

  /* Затемнюючий градієнт над ілюстрацією (п.3) — плавний перехід від
     низу вікна списку до зафіксованої ілюстрації знизу */
  .cta + .industries .industries__globe-mobile-fade {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 40px;
    background: linear-gradient(to top, var(--color-background), transparent);
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 182: секція Offices (Home)

   .offices (bare-клас) унікальний для index.html — жодного суміжного
   селектора-скоупу не потрібно (той самий факт, що вже підтверджений
   у Кроках 138/162 для попередніх breakpoint'ів).

   Фікс: .offices__marker/__line/__city-info РЕКАЛЬКУЛЬОВАНІ під новий
   тайтл (.dm-24-reg, line-height 130% = 31.2px) — успадковані з десктопу
   top:64/68/92px (виведені зі старого 52px line-height) сюди не підходять
   (7px тайтл→квадратик, 16px квадратик(строук)→лейбл, п.2 фіксу):
   marker top = 31.2 + 7 = 38.2; line/city-info top = 38.2 + 5 = 43.2 (по
   нижньому пікселю квадратика); city-info top = 43.2 + 16 = 59.2.
   .offices__line лишається єдиним HTML-елементом (спільним для London),
   але для New York/Kyiv (де своєї лінії нема в розмітці) додано ::after
   на кожному з них — той самий візуальний строук, той самий top (фікс
   п.3, "пропущені строуки").

   Замість флекс-рядка (десктоп) чи 2-рядкової вкладеної сітки (Tablet
   Portrait, Крок 162) — простий вертикальний стек: усі 3 міста один під
   одним (flex-direction: column), margin-left замінено на margin-top:32px
   між ними (п.5).

   Кнопка "MORE ABOUT US" (.offices__arrow-box) виходить із absolute-схеми
   (десктоп/tablet: 44×44 іконка-квадрат top:25/right:0, вирівняний з
   .offices__line) — стає нормальним потоковим блоком на всю ширину сітки
   з текстом (той самий стиль/клас .secondary-button, що й на "CLEAR
   FILTERS", work.html) — текст "More about us" у розмітці
   (.offices__arrow-text) прихований на всіх інших breakpoint'ах (база,
   styles.css вище) і показаний лише тут.
   ========================================================================== */

@media (max-width: 767px) {

  /* Фікс: 70px від нижнього краю ілюстрації-глобуса Industries (не від
     "природної" висоти секції) — .industries__scrolly-mobile тепер сам
     диктує висоту grid-row 4 (100vh + дистанція гортання, JS), і після
     відкріплення (unstick) її НИЖНІЙ край точно збігається з нижнім
     краєм ілюстрації (глобус — position:absolute; bottom:0 всередині
     100vh sticky-панелі, яка після unstick стає нижнім краєм самої
     обгортки) — тому звичайний margin-top тут дає рівно потрібний
     відступ, без JS-компенсації (стара від'ємна -32px була написана під
     попередню, ще не sticky-версію ілюстрації; було 40px) */
  .offices {
    margin-top: 70px;
  }

  .offices__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Номер — у межах сітки, вирівняний по правому краю (4-та колонка) —
     той самий принцип, що Services/Selected Work/Industries */
  .offices__index {
    grid-column: 4;
    justify-self: end;
  }

  /* Тайтл — той самий стиль/відступи, що Industries (Крок 181): на всю
     сітку, 14px від лейбла, Mob/H2 (.dm-24-reg). Контент — той самий,
     що на Tablet Portrait */
  .offices__title {
    grid-column: 1 / 5;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  /* Боді — DM Sans/14 Light, 16px від тайтла, на всю сітку */
  .offices__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Блок міст — на всю сітку, 32px від низу боді-тексту до верху London */
  .offices__cities {
    grid-column: 1 / 5;
    margin-top: 32px;
  }

  /* Вертикальний стек замість рядка (десктоп)/2-рядкової сітки (Tablet
     Portrait) — London/New York/Kyiv один під одним */
  .offices__titles {
    display: flex;
    flex-direction: column;
  }

  /* Фікс: min-height перераховано під новий (рекалькульований, попередній
     фікс) .offices__city-info top:59.2px замість успадкованих 170px
     (виведених зі старого top:92) — 170 лишало ~41px зайвого порожнього
     місця в кожному боксі ПОВЕРХ margin-top:32, тому візуальний відступ
     між боді-текстом одного міста й тайтлом наступного виходив ~73px
     замість 32px. 129.2 = 59.2 (city-info top) + 20 (сабтайтл) + 10
     (відступ) + 40 (боді, dm-14-light, 2 рядки×20 — однаково для всіх
     3 міст, перевірено headless Chrome) — точно під реальний вміст,
     без запасу, тому margin-top:32 тепер і є справжнім візуальним гепом */
  .offices__city {
    min-height: 129.2px;
  }

  /* Фікс: боді-текст айтемів (п.6) — London 1 рядок (перенос вимкнено),
     New York переписаний текст (окремий <p>, той самий прийом, що
     .services__title--desktop/--mobile), Kyiv 2 рядки (ручний перенос
     увімкнено) */
  .offices__body-break--desktop {
    display: none;
  }

  .offices__body-break--mobile {
    display: inline;
  }

  .offices__body--desktop {
    display: none;
  }

  .offices__body--mobile {
    display: block;
  }

  /* Фікс: London далі переносився на 2 рядки навіть з вимкненим
     .offices__body-break--desktop — успадкований width:276px (десктоп)
     замалий для "Strategy, client relationships, project leadership" в
     один рядок на dm-14-light. Той самий принцип "widen the box", що
     .hero__desc/.hero__title — розширюємо контейнер (виміряно: рядок
     потребує 304.8px, 318px лишає невеликий запас), а не зменшуємо
     шрифт. Скоуп лише на London (перший .offices__city у
     .offices__titles) — New York/Kyiv мають свій навмисний 2-рядковий
     перенос і не повинні розширюватись */
  .offices__titles .offices__city:first-child .offices__body {
    width: 318px;
  }

  /* Фікс: min-height:129.2px (базове, вище) калібрований під 2-рядковий
     боді-текст "без запасу" (129.2 = 59.2 city-info top + 20 сабтайтл +
     10 відступ + 40 боді). London тепер 1 рядок (20px, не 40) — без
     цього поправлення геп до New York зростав би до 52px замість 32px
     (зайві 20px "слеку" в тому самому фіксованому боксі). 109.2 =
     129.2 − 20, той самий "без запасу" принцип, скоуплений лише на
     London */
  .offices__titles .offices__city:first-child {
    min-height: 109.2px;
  }

  /* New York/Kyiv — 0 замість десктопних margin-left (173/197px),
     32px margin-top для вертикального гепу (п.5) замість горизонтального
     зсуву */
  .offices__city--ny,
  .offices__city--kyiv {
    margin-left: 0;
    margin-top: 32px;
  }

  /* Тайтл міста — Mob/H2 (.dm-24-reg) замість десктопного .dm-h1 */
  .offices__city-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  /* Фікс: 7px від тайтла (31.2px line-height) до квадратика */
  .offices__marker {
    top: 38.2px;
  }

  /* Фікс: строук по нижньому пікселю квадратика (top квадратика + 5px
     висоти) — London (єдиний, хто має цей HTML-елемент) */
  .offices__line {
    top: 43.2px;
  }

  /* Фікс: New York/Kyiv не мають власного .offices__line у розмітці —
     той самий візуальний строук через ::after, той самий top */
  .offices__city--ny::after,
  .offices__city--kyiv::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 43.2px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Фікс: 16px від строука до лейбла (сабтайтла) */
  .offices__city-info {
    top: 59.2px;
  }

  /* Лейбл міста (напр. "HEADQUARTERS") — Red Hat/14 SB (.rh-14-sb,
     tokens.css — уже існує, новий клас не потрібен) замість десктопного
     .rh-16-sb */
  .offices__subtitle {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0.12em;
  }

  /* Кнопка MORE ABOUT US — з absolute-іконки (44×44) стає нормальним
     потоковим full-width блоком, 32px від низу Kyiv. border-bottom
     (десктопне вирівнювання з .offices__line) тут не потрібен —
     .secondary-button дає власний фон/hover-стан.
     Фікс: текст+іконка центруються як ГРУПА (justify-content:center,
     gap:8px) замість асиметричного padding-left:105px */
  .offices__arrow-box {
    position: static;
    margin-top: 32px;
    width: 336px;
    height: 48px;
    justify-content: center;
    gap: 8px;
    border-bottom: none;
  }

  .offices__arrow-text {
    display: block;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 183: секція CTA-2 (Home)

   .cta--second перевикористовується на about/contact/services/work.html —
   скоуп через суміжний селектор .offices + .cta--second, той самий
   прийом, що Tablet Portrait (Крок 163). Матчиться лише на index.html.
   ========================================================================== */

@media (max-width: 767px) {

  /* 56px від низу кнопки "More about us" (Offices, Крок 182) до верху
     фону CTA-2. Фон — той самий cta2-bg.webp/@2x (успадкований, не
     перевизначається), fixed no-scale розмір 692×300 (1440:624 ratio
     збережене). Під фоном — 161px додаткового вільного простору (той
     самий фон секції) — сумарна висота секції = 300 + 161 = 461px */
  /* Фікс: 233px від верху фону до тайтла (362px на Tablet Portrait) —
     margin-top (56px, від низу кнопки "More about us") уже точний,
     без змін */
  /* Крок — 112px вільного простору ЗВЕРХУ і 40px ЗНИЗУ, щоб секція
     займала приблизно висоту в'юпорта: height +152 (461→613),
     background-position зсуває фон на 112px вниз (той самий прийом,
     що .work-hero/.work-hero__bg, Крок 141 — базовий .cta задає
     "center top", тут перевизначаємо), padding-top +112, щоб позиція
     тайтла відносно фону лишилась незмінною (233→345). Кнопка й далі
     йде за тайтлом у normal flow — margin-top:32px не чіпається */
  .offices + .cta--second {
    margin-top: 56px;
    height: 613px;
    padding-top: 345px;
    background-position: center 112px;
    background-size: 692px 300px;
  }

  /* Тайтл — Mob/H1 (.dm-28-reg) замість десктопного .dm-h0 */
  .offices + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Кнопка — 32px від тайтла, на всю ширину сітки (336px, а не 100%
     батька — .cta--second сама на всю ширину в'юпорта, тому без цього
     перевизначення .cta__btn успадкував би повну ширину екрана від
     сайт-вайд правила Кроку 177). Текст — "Begin a project"
     (.cta__btn-label--mobile, вимикає --desktop поруч); центрується
     через justify-content:center на базовому .hero__btn (Фікс) —
     асиметричний padding-left:101px, що імітував центрування, прибрано */
  .offices + .cta--second .cta__btn {
    margin-top: 32px;
    width: 336px;
  }

  .offices + .cta--second .cta__btn-label--desktop {
    display: none;
  }

  .offices + .cta--second .cta__btn-label--mobile {
    display: inline;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 184: Footer (сайт-вайд, той самий принцип
   скоупу, що Крок 140/164 — .footer__* класи без різниці між сторінками,
   тому звичайні селектори без adjacent-sibling)

   Арифметика вертикалі всередині .footer__body (від верху = 0), той
   самий принцип, що Tablet Portrait (Крок 164, height:433 виходить
   ідентичним числом попри інший gap патерн→нав (40 замість 48) — той
   гап впливає лише на позицію колонок, не на загальну висоту, яку
   визначає ЛИШЕ WHO WE ARE блок):
   патерн: 0–32
   vline top/height = 32/292 → низ vline = 324
   нав columns top = 32+40 = 72
   строук (::after) під vline: top 324, height 1
   WHO title top = 324+1+20 = 345, height 20
   WHO body top = 345+20+8 = 373, height 40 (2 рядки×20, dm-14-light)
   footer__body height = 373+40+20 = 433

   Горизонтальні строуки (п.2/5/8 — фікс, СКАСОВУЄ попередню full-bleed
   поведінку): тепер на ширину СІТКИ (336px, center), а не в'юпорта.
   .footer__line-a/.footer__line-b — звичайні grid-item (grid-column:1/5,
   успадковане зі спільного правила нижче), без додаткового
   width/margin-left їхня ширина сама по собі = ширині сітки. Для
   .footer__body::after (position: absolute відносно .footer__body, який
   теж дорівнює ширині сітки) — left:0; width:100%, той самий прийом,
   що .footer__pattern.
   ========================================================================== */

@media (max-width: 767px) {

  /* Фікс: 225px замінено на 64px — тепер той самий відступ, що на
     Desktop/Tablet Landscape/Tablet Portrait (база вище, main:has(...)
     + .footer{margin-top:64px}), тому окреме Mobile-перевизначення
     більше не потрібне — видалено, значення успадковується з бази */

  .footer__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .footer__top,
  .footer__line-a,
  .footer__body,
  .footer__line-b,
  .footer__bottom {
    grid-column: 1 / 5;
  }

  /* Лого + email — стек замість рядка (десктоп/tablet: flex row +
     space-between), 12px між ними (п.1) */
  .footer__top {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 12px;
  }

  /* 24px від email — фікс: на ширину сітки (336px, center), СКАСОВУЄ
     попередню full-bleed поведінку (п.2). grid-column:1/5 (спільне
     правило вище) вже дає ширину сітки без додаткового width/margin-left */
  .footer__line-a {
    margin-top: 24px;
  }

  .footer__body {
    height: 433px;
  }

  /* Патерн — на всю ширину СІТКИ (336px, .footer__body вже дорівнює
     ширині сітки на mobile), НЕ full-bleed на в'юпорт — той самий принцип,
     що тепер і горизонтальні строуки (.footer__line-a/-b, нижче).
     Висота (32px) — без змін, успадкована з бази */
  .footer__pattern {
    left: 0;
    width: 100%;
  }

  .footer__vline--1 {
    left: 105px;
    top: 32px;
    height: 292px;
  }

  /* Фікс: 27px від тексту "Operations" (останній айтем колонки 2), не
     ~23px, як було — зсунуто на 4px правіше (229→233px) */
  .footer__vline--2 {
    left: 233px;
    top: 32px;
    height: 292px;
  }

  .footer__vline--3 {
    display: none;
  }

  /* Контент колонок — той самий, що на Tablet Portrait (п.4): gap:20px */
  .footer__col {
    gap: 20px;
  }

  /* Фікс: айтеми навігації — Red Hat/12 Bold (.rh-12-bold, tokens.css,
     letter-spacing 6%), не .rh-12-bold-track з розмітки (13%, той самий
     клас, що й на десктопі/Tablet — тут навмисно перевизначається лише
     на Mobile) */
  .footer__label {
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.06em;
  }

  .footer__col--1 {
    left: 0;
    top: 72px;
  }

  /* Фікс: 16px від ЛІВОГО вертикального строука колонки (vline--1,
     left:105px вище), не 20px, як було */
  .footer__col--2 {
    left: 121px;
    top: 72px;
  }

  /* Фікс: 16px від ЛІВОГО вертикального строука колонки (vline--2,
     тепер left:233px вище — зсунуто разом з ним, щоб зберегти той
     самий 16px відступ), не 20px, як було */
  .footer__col--3 {
    left: 249px;
    top: 72px;
  }

  /* Строук під вертикальними строуками — фікс: на ширину сітки (336px),
     СКАСОВУЄ попередню full-bleed поведінку (п.5). .footer__body сам
     дорівнює ширині сітки, тому left:0+width:100% (той самий прийом, що
     .footer__pattern) */
  .footer__body::after {
    content: '';
    position: absolute;
    left: 0;
    top: 324px;
    width: 100%;
    height: 1px;
    background-color: var(--grey-15);
  }

  .footer__who {
    top: 345px;
  }

  .footer__who-body {
    margin-top: 8px;
  }

  /* Строук під боді-текстом — фікс: на ширину сітки (336px), СКАСОВУЄ
     попередню full-bleed поведінку (п.8). grid-column:1/5 (спільне
     правило вище) вже дає ширину сітки, додаткових властивостей не
     потрібно (той самий фікс, що .footer__line-a) */

  /* Копірайт + посилання — стек замість рядка (десктоп: space-between
     в один рядок), 16px від строука (п.8), 14px між копірайтом і
     рядком посилань (п.9) */
  .footer__bottom {
    flex-direction: column;
    align-items: flex-start;
    margin-top: 16px;
    gap: 14px;
  }

  /* Фікс: Terms of use одразу праворуч від Privacy policy, gap 28px
     (раніше — space-between на всю ширину сітки, розносило посилання
     по краях; після видалення Cookies policy зайве) */
  .footer__policies {
    gap: 28px;
  }

  /* 32px від рядка посилань до низу сторінки (п.10, фікс — було 88px) */
  .footer {
    padding-bottom: 32px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 185: меню-оверлей (глобально, всі сторінки)

   Номер сторінки в оверлеї — Red Hat/12 Bold (tracking) (.rh-12-bold-track,
   tokens.css); Red Hat/10 Bold видалено як окремий стиль (глобальна
   ревізія текстових стилів).

   .mobile-menu прихований за замовчуванням (той самий прийом, що
   .header__divider--logo, Крок 156) — розкривається лише в мобільному
   медіа-запиті нижче; header.js додатково гейтить клік через matchMedia,
   тому JS-toggle класу .is-open на інших breakpoint'ах ні на що не впливає.
   ========================================================================== */

.mobile-menu {
  display: none;
}

@media (max-width: 767px) {

  /* Фон на весь в'юпорт, під хедером (z-index:90 < .header, z-index:100,
     базовий CSS) — flex-колонка з двома проекційними "спейсерами" (той самий
     принцип, що .hero__spacer--top/--bottom, Крок 177, п.7): відсоток
     від висоти в'юпорта (292/812, 332/812), а не фіксований px, тому
     позиція фрейму навігації масштабується разом з висотою вікна.
     Контент (.mobile-menu__nav) лишається природної висоти між спейсерами.
     Фікс: та сама fade+translateY transition-анімація, що вже реалізована
     на Tablet Portrait — оверлей завжди display:flex у цьому breakpoint'і
     (не display:none, інакше transition на opacity/transform не
     запуститься), закритий стан invisible/non-interactive (opacity:0,
     pointer-events:none, visibility:hidden із затримкою — щоб фокус/клік
     не потрапляли в приховані посилання), 300ms var(--ease-smooth),
     симетрично для появи й закриття */
  .mobile-menu {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0;
    z-index: 90;
    background: var(--color-background);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-12px);
    transition: opacity 300ms var(--ease-smooth),
                transform 300ms var(--ease-smooth),
                visibility 0s 300ms;
  }

  .mobile-menu.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
    transition: opacity 300ms var(--ease-smooth),
                transform 300ms var(--ease-smooth);
  }

  .mobile-menu__spacer--top {
    height: 35.9606%;
  }

  .mobile-menu__spacer--bottom {
    height: 40.8867%;
  }

  /* Фрейм навігації — сітка 336px, центрована (той самий прийом, що
     .hero__buttons, Крок 177) */
  .mobile-menu__nav {
    width: 336px;
    margin: 0 auto;
  }

  /* align-items:center — центрує кожен фіксований фрейм (нижче) як єдиний
     блок усередині 336px-контейнера .mobile-menu__nav */
  .mobile-menu__list {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    list-style: none;
  }

  /* Фікс: той самий "fixed frame" прийом, що вже реалізований на Tablet
     Portrait — заміняє попередній flex(gap:6px)+justify-content:center
     підхід, де показ/приховування номера через display:none/block
     змінювало ШИРИНУ айтема, і центрування (justify-content:center на
     самому лінку) тоді зсувало текст по-різному залежно від active/
     inactive. Тепер: текст і номер — absolute всередині фрейму
     фіксованого розміру (per-item width, .mobile-menu__link--home/
     --work/--services/--about нижче), текст завжди на left:21px,
     колір/шрифт — БЕЗ ЗМІН (успадковані з .dm-24-reg/.rh-12-bold-track,
     застосованих у розмітці) */
  .mobile-menu__link {
    display: block;
    position: relative;
    height: 42px;
    color: var(--grey-50);
    text-decoration: none;
  }

  .mobile-menu__text {
    position: absolute;
    left: 21px;
    top: 0;
    white-space: nowrap;
  }

  .mobile-menu__link.is-active {
    color: var(--grey-100);
  }

  /* Ховер айтема — grey-60, лише для НЕактивної сторінки (:not(.is-active),
     активна лишається grey-100 навіть при наведенні) */
  .mobile-menu__link:hover:not(.is-active) {
    color: var(--grey-60);
  }

  /* Номер — рендериться завжди (opacity:0/visibility:hidden для
     неактивної сторінки, а не display:none) — місце під нього
     зарезервоване у фреймі завжди, тому текст не зсувається; top:0,
     right — per-item нижче; колір успадковує .mobile-menu__link(.is-active)
     без окремого правила */
  .mobile-menu__num {
    position: absolute;
    top: 0;
    opacity: 0;
    visibility: hidden;
  }

  .mobile-menu__link.is-active .mobile-menu__num {
    opacity: 1;
    visibility: visible;
  }

  /* Фіксовані розміри фреймів + відступ номера від правого краю —
     точні значення з дизайну (текст 21px зліва + gap 6px до номера +
     номер + right-відступ = ширина фрейму, для кожного айтема окремо,
     бо ширина тексту різна) */
  .mobile-menu__link--home {
    width: 108px;
  }

  .mobile-menu__link--home .mobile-menu__num {
    right: 8px;
  }

  .mobile-menu__link--work {
    width: 100px;
  }

  .mobile-menu__link--work .mobile-menu__num {
    right: 5px;
  }

  .mobile-menu__link--services {
    width: 137px;
  }

  .mobile-menu__link--services .mobile-menu__num {
    right: 1px;
  }

  .mobile-menu__link--about {
    width: 111px;
  }

  .mobile-menu__link--about .mobile-menu__num {
    right: 0;
  }

  /* Фікс: CTA "Contact" прибрано з меню-оверлею повністю (разом із
     відступом 20px від низу в'юпорта) — за завданням, той самий прийом,
     що Tablet Portrait вже застосовує до цього елемента (.mobile-menu__cta
     { display:none }, styles нижче) */
  .mobile-menu__cta {
    display: none;
  }

  /* Активний (відкритий) стан — той самий фон, що на hover (grey-15), але
     постійний, доки меню відкрите. Фікс: кнопка меню тепер сама по собі
     48×48-фрейм зі своїми border'ами (той самий прийом, що Tablet
     Portrait, вище) — окремий ::before-хак для фону активного стану
     більше не потрібен (раніше компенсував те, що кнопка була розміром
     лише під іконку, 22×22); тепер background-color просто на самій
     кнопці, як на Tablet Portrait */
  .header--menu-open .header__menu-btn {
    background-color: var(--grey-15);
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 186: Hero-секція (about.html)

   Сітка/хедер — без змін (спільні, Крок 176 + фікси). Фон — той самий
   ассет, що на десктопі/Tablet (image-set 1x/2x), без нового файлу:
   пропорційно зменшений до ширини 1000px (background-size: 1000px auto —
   висота рахується браузером від оригінального співвідношення сторін
   1920:900,auto не хардкодить 468.75px), зсув 251px від верху, center по
   горизонталі (той самий прийом, що Tablet Portrait, Крок 165, лише інші
   числа). Текстовий блок — той самий стиль/відступи, що Hero index.html
   (Крок 177): тайтл .dm-28-reg (mob/H1), 8px від лейбла; боді-текст
   DM Sans/14 Light (.dm-14-light), 16px від тайтла, ширина 336px (сітка)
   замість десктопних 955/437px. padding-top на .about-hero — 174px
   (фіксовано, не проекційно — на відміну від Hero index.html, за
   завданням) замість десктопних 170px */

@media (max-width: 767px) {

  .about-hero {
    padding-top: 174px;
  }

  .about-hero__bg {
    background-position: center 251px;
    background-size: 1000px auto;
  }

  .about-hero__title {
    margin-top: 8px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Перемикання розривів тайтла для Mobile (Крок 206) — вмикаємо власний
     3-рядковий "--mobile" розрив, вимикаємо успадкований 2-рядковий
     "--wide" (десктоп/Tablet Landscape/Tablet Portrait) */
  .about-hero__title-break--wide {
    display: none;
  }

  .about-hero__title-break--mobile {
    display: inline;
  }

  .about-hero__desc {
    margin-top: 16px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 187: секція Our Approach (about.html)

   Лейбл/номер/тайтл/боді — той самий принцип, що Selected Work (index.html,
   Крок 179, п.2): номер у межах сітки (колонка 4, justify-self:end),
   тайтл .dm-24-reg (Mob/H2), боді DM Sans/14 Light, обидва на всю ширину
   сітки (1/5). Лейбл лишається на колонці 1 без змін (той самий факт, що
   й у Кроку 179 — лише номер, не лейбл, "в межах сітки"). Текстовий
   контент не змінюємо — HTML спільний з десктопом/Tablet Portrait
   (Крок 166), лише стилі. Фікс: .about-approach__title має унаслідуваний
   unconditional width:586px (десктоп) — явно скидаємо на auto, інакше
   тайтл вилазить за межі 336px-сітки (той самий баг, який лишився
   непоміченим у .selected-work__title, Крок 179 — тут його не повторюємо).

   Метрики (about-stats) — той самий контент, що Tablet Portrait (Крок 166),
   але тепер один айтем на рядок (не 2×2): item--N/body--N чергуються по
   grid-row (1,2 / 3,4 / 5,6 / 7,8), кожен на всю ширину сітки, 32px між
   айтемами (margin-top на item--2/3/4). Формула маркер/строук — та сама,
   що Offices (index.html, Крок 182, фікс): тайтл-lh(31.2, dm-24-reg) + 7 =
   маркер-top(38.2); +5 (висота квадрата) = строук-top(43.2); +16 = боді-
   top. Боді — окремий grid-child (не вкладений в item), тому 16px
   виражені як margin-top НА БОДІ-ЕЛЕМЕНТІ, рахований від старту ЙОГО
   ВЛАСНОГО grid-row (який починається одразу після рядка тайтла, 31.2px):
   43.2+16-31.2=28px. Горизонтальний строук — не спільний .about-stats__line
   (той призначений для 1/2-рядкових розкладок вище, тут вимкнений), а
   власний ::after на КОЖНОМУ .about-stats__item (той самий "додати ::after
   там, де в HTML немає власного елемента лінії" прийом, що Крок 182,
   міста NY/Kyiv) */

@media (max-width: 767px) {

  .about-approach__grid,
  .about-stats__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Фікс: лейбл успадковував grid-column:1 (72px) зі спільного правила
     (рядок ~1298) — "OUR APPROACH" туди не влазить і переносився на
     2 рядки. На всю ширину сітки (1/5, 336px), той самий фікс, що вже
     на Tablet Landscape/Portrait (Крок 144/166) */
  .about-approach__label {
    grid-column: 1 / 5;
  }

  .about-approach__index {
    grid-column: 4;
    justify-self: end;
  }

  .about-approach__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .about-approach__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .about-approach__desc-break--mobile {
    display: inline;
  }

  .about-approach__pattern {
    grid-column: 1 / 5;
    margin-top: 10px;
  }

  .about-approach__extra {
    grid-column: 1 / 5;
    margin-top: 10px;
  }

  .about-approach__extra-break--desktop {
    display: none;
  }

  /* 40px від підтексту (п.4) — margin-top .about-stats рахується напряму
     від попереднього флекс-сиблінга (.about-approach), той самий прийом,
     що десктоп/Tablet Portrait, тому значення 1:1 */
  .about-stats {
    margin-top: 40px;
  }

  .about-stats__item--1 {
    grid-column: 1 / 5;
    grid-row: 1;
  }

  .about-stats__item--2 {
    grid-column: 1 / 5;
    grid-row: 3;
    margin-top: 32px;
  }

  .about-stats__item--3 {
    grid-column: 1 / 5;
    grid-row: 5;
    margin-top: 32px;
  }

  .about-stats__item--4 {
    grid-column: 1 / 5;
    grid-row: 7;
    margin-top: 32px;
  }

  /* Тайтл — Mob/H2 (.dm-24-reg) замість десктопного .dm-h0 (п.6) */
  .about-stats__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  /* Лейбл — значення .rh-12-bold-track (tokens.css), Red Hat/10 Bold
     видалено як окремий стиль (глобальна ревізія текстових стилів).
     Позиція (6px/2px) успадкована без змін */
  .about-stats__label {
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
  }

  /* Маркер — top перерахований під нову висоту тайтла (31.2 + 7 = 38.2,
     та сама формула, що Offices/Крок 182) */
  .about-stats__marker {
    top: 38.2px;
  }

  /* Горизонтальний строук — власний ::after на кожному айтемі, на всю
     ширину айтема (той самий, що ширина сітки, бо .about-stats__item
     розтягнутий по grid-column:1/5), top: 43.2px (38.2 + 5, нижній
     піксель квадрата) */
  .about-stats__item::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 43.2px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Спільна лінія (десктоп: рядок 1, Tablet Portrait: box-shadow-копія
     рядка 2) тут не потрібна — кожен айтем має власний ::after вище */
  .about-stats__line {
    display: none;
  }

  .about-stats__break--mobile {
    display: inline;
  }

  .about-stats__body--1 {
    grid-column: 1 / 5;
    grid-row: 2;
    margin-top: 28px;
  }

  .about-stats__body--2 {
    grid-column: 1 / 5;
    grid-row: 4;
    margin-top: 28px;
  }

  .about-stats__body--3 {
    grid-column: 1 / 5;
    grid-row: 6;
    margin-top: 28px;
  }

  .about-stats__body--4 {
    grid-column: 1 / 5;
    grid-row: 8;
    margin-top: 28px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 188: секція How We Work (about.html)

   Ілюстрацію-сферу (.how-we-work__sphere) свідомо НЕ додаємо в цьому кроці
   (той самий принцип, що Крок 178, "квітка" Services) — display:none,
   інакше 934×859px абсолютна картинка перекривала б табличку знизу.

   Лейбл/номер/тайтл/боді — той самий принцип, що Our Approach (Крок 187,
   п.1): номер у межах сітки (колонка 4, right), тайтл .dm-24-reg,
   14px/16px відступи. Ручний <br> у тайтлі ("Five practices built/to work
   as one") — той самий безумовний елемент розмітки, що вже на всіх
   breakpoint'ах (не tablet-конкретний клас), тут не чіпається. Фікс:
   .how-we-work__title має унаслідуваний unconditional width:586px
   (десктоп) — явно скидаємо на auto, той самий фікс, що
   .about-approach__title (Крок 187).

   Табличка (список практик) — той самий контент/стилі рядків (rh-12-bold-
   track назва, dm-14-light опис — уже прямо в розмітці, тут не
   дублюються), лише позиція: на всю ширину сітки (336px, margin-left:0
   замість правоколонкового зсуву) замість 342/444px "правого стовпця"
   Tablet Portrait.

   Фікс: .how-we-work__divider--bottom була винесена з потоку (position:
   absolute) виключно через конфлікт z-index зі сферою (Крок 145) — тут
   сфера прихована, тому конфлікту немає: повертаємо елемент у звичайний
   потік (grid-row:5, margin-top:18px від низу рядка OPERATIONS), той
   самий принцип "18px від тексту до строука", що Tablet Portrait
   (Крок 167-фікс), але без хардкодженого абсолютного top — розраховується
   природним чином через grid-flow */

@media (max-width: 767px) {

  /* 70px від низу останнього айтема метрик Our Approach (Крок 187) до
     верху лейбла — margin-top .how-we-work рахується напряму від
     попереднього флекс-сиблінга (.about-stats) */
  .how-we-work {
    margin-top: 70px;
  }

  .how-we-work__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  /* Фікс: той самий фікс, що .about-approach__label (Крок 187) */
  .how-we-work__label {
    grid-column: 1 / 5;
  }

  /* Фікс: .how-we-work__hline — декоративний строук на всю ширину
     сітки, 5px під рядком лейблів (успадкований з бази, розрахований
     під десктопну сітку) — не прихований раніше, бо на вузькій колонці
     лейблу (72px) губився в потоці; після розширення лейблу на всю
     ширину (п.1 вище) став видимим зайвим строуком поруч з лейблом.
     Прихований тим самим принципом, що сфера/extra (нижче) — ще не
     адаптований під мобільний макет */
  .how-we-work__hline {
    display: none;
  }

  .how-we-work__index {
    grid-column: 4;
    justify-self: end;
  }

  .how-we-work__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .how-we-work__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .how-we-work__sphere {
    display: none;
  }

  /* Фікс: строук (.how-we-work__divider--bottom) повертається на цьому
     breakpoint — раніше вважався "не адаптованим" і прибирався
     (display:none), ілюстрація йшла впритул до самого тексту "Operations".
     Тепер строук лишається в потоці (position:static, не absolute/JS-
     синхронізований, як на десктопі/планшетах — js/how-we-work.js
     пропускає його тут, бо перевіряє саме position:absolute), 17px від
     рядка OPERATIONS (той самий gap, що передає в JS для десктопу/
     планшетів), а ілюстрація йде впритул ДО СТРОУКА (0px, п.5 ТЗ) замість
     тексту. grid-row:5 — ФІКС: auto-placement НЕ розставляє строук/сферу/
     підтекст у порядку DOM тут (виміряно рендером: .how-we-work__vline
     лишається display:block/position:absolute на Mobile — навіть будучи
     "вийнятим" з потоку самим по собі, він, вочевидь, займає слот в
     auto-placement cursor і зсуває чергу, через що .how-we-work__extra
     авто-розставлявся ПОПЕРЕД строука/сфери замість після). Явні номери
     (список:4, строук:5, сфера:6, підтекст:7) прибирають цю залежність
     від auto-placement algorithm повністю */
  .how-we-work__divider--bottom {
    display: block;
    position: static;
    grid-column: 1 / 5;
    grid-row: 5;
    width: auto;
    margin-top: 17px;
  }

  /* Мобільна ілюстрація-сфера (.how-we-work__sphere-mobile,
     mobile-sphere.webp, окремий асет — не десктопна .how-we-work__sphere):
     margin-top:0 — впритул до строука вище (п.5 ТЗ). Фіксований розмір
     375×286px, НЕ масштабується залежно від ширини Mobile-в'юпорта
     (375–767px). justify-self:center центрує її В МЕЖАХ grid-area
     (col1/5, на всю ширину сітки) — оскільки сама .how-we-work__grid
     центрована на сторінці (margin:0 auto), це центрує ілюстрацію
     відносно сторінки, а не лише сітки; ширина 375px ширша за 336px-сітку,
     тому елемент навмисно виходить за межі колонок symmetричним overflow
     з обох боків — grid-item тут не обрізає overflow (той самий принцип,
     що й у десктопній сфері) */
  .how-we-work__sphere-mobile {
    display: block;
    grid-column: 1 / 5;
    grid-row: 6;
    justify-self: center;
    width: 375px;
    height: 286px;
    margin-top: 0;
  }

  /* Фікс (виявлено при реалізації Кроку 189): .how-we-work__extra
     (підтекст "Every project is led...") теж НЕ адаптований у цьому
     кроці (як і сфера) і успадковує grid-column:6/9 — за межами нової
     4-колонкової сітки. На відміну від .how-we-work__vline (просто йде
     за межі viewport, безпечно), тут ширина колонки авто-звужується до
     ~94px, і довгий текст переносився в 720px-високий стовпчик, який
     роздував висоту рядка 5 .how-we-work__grid — а через це й
     margin-top:70px .leadership (Крок 189, п.1), який рахується від
     низу цього самого флекс-сиблінга .how-we-work. Це виправлено:
     підтекст тепер на всю ширину сітки (1/5, 336px) замість
     успадкованої вузької колонки, тому більше не роздуває висоту
     рядка. margin-top 48→20px — тепер рахується від низу ілюстрації, а
     не строука (п.5 ТЗ). grid-row:7 — явний номер, той самий фікс, що
     .how-we-work__divider--bottom/__sphere-mobile вище (auto-placement
     ненадійний тут через .how-we-work__vline) */
  .how-we-work__extra {
    display: block;
    grid-column: 1 / 5;
    grid-row: 7;
    margin-top: 20px;
  }

  /* Секондарі-боді (.how-we-work__extra) отримує власний 8-рядковий
     розрив на Mobile — вимикаємо десктопний і вмикаємо --mobile */
  .how-we-work__extra-break--desktop {
    display: none;
  }

  .how-we-work__extra-break--mobile {
    display: inline;
  }

  /* Фікс: 50px від низу боді-тексту до верху таблички (було 32px).
     grid-row:4 — явний номер (той самий фікс, що строук/сфера/підтекст
     нижче — auto-placement ненадійний тут через .how-we-work__vline) */
  .how-we-work__list {
    grid-column: 1 / 5;
    grid-row: 4;
    margin-top: 50px;
  }

  .how-we-work__row {
    margin-left: 0;
  }

  .how-we-work__divider {
    margin-left: 0;
    width: auto;
  }

  /* Фікс: секондарі-боді → Trusted By, 64px. Раніше не перевизначався
     тут і мовчки успадковував десктопне значення (310px, вищий за
     специфічністю за загальний .trusted-by{margin-top}) — тепер
     явний override. Рахується напряму від низу .how-we-work__extra:
     about-hero завершується рівно тут (.how-we-work__extra-line —
     display:none на Mobile, не додає власної flow-висоти) */
  .about-hero + .trusted-by {
    margin-top: 64px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Фікс: секція Trusted By (about.html) — точна копія
   вже реалізованої версії з index.html (Крок-фікс "секція Trusted By,
   Mobile ≤767px"), лише замінено суміжний селектор на
   ".about-hero + .trusted-by" (структурний адрес about.html), той самий
   принцип, що вже застосований на Tablet Portrait (окремий крок вище).
   Позиція лейбла/номера — без змін відносно поточної реалізації about.html
   (номер — grid-column:4, justify-self:end, той самий принцип, що
   .how-we-work__index/.about-approach__index на цьому breakpoint; лейбл —
   базовий grid-column:1, unconditional white-space:nowrap уже дозволяє
   йому "виливатись" праворуч у вузькій колонці).

   4×72px клітинки/16px gutter (336px = 4×72+3×16, точно ширина мобільної
   сітки), лише перші 8 з 16 логотипів (2 ряди по 4), решта приховані.
   Ротація — той самий js/trusted-by-rotate.js/factory, що на Tablet
   Portrait (медіа-запит нижче розширено до "max-width:1023px", тому
   покриває обидва breakpoint об'єднано, як у index.html).
   ========================================================================== */

@media (max-width: 767px) {

  .about-hero + .trusted-by .trusted-by__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .about-hero + .trusted-by .trusted-by__index {
    grid-column: 4;
    justify-self: end;
  }

  .about-hero + .trusted-by .trusted-by__logos {
    grid-column: 1 / 5;
    grid-row: 2;
    margin-top: 16px;
    grid-template-columns: repeat(4, 72px);
    grid-template-rows: repeat(2, 72px);
    gap: 16px;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell,
  .about-hero + .trusted-by .trusted-by__logo {
    width: 72px;
    height: 72px;
  }

  /* Той самий фікс, що index.html: hover належить клітинці (фрейму), не
     логотипу — pointer-events:none на <img> гарантує, що курсор завжди
     "проходить крізь" них до .trusted-by__logo-cell */
  .about-hero + .trusted-by .trusted-by__logo {
    pointer-events: none;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(n + 9) {
    display: none;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(4n)::after {
    right: 0;
  }

  .about-hero + .trusted-by .trusted-by__logo-cell:nth-child(n + 5)::after {
    bottom: 0;
  }

  .about-hero + .trusted-by .trusted-by__lines {
    background-size:
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      1px 160px,
      336px 1px,
      336px 1px,
      336px 1px,
      72px 1px,
      72px 1px,
      72px 1px,
      72px 1px;
    background-position:
      0px 0,
      72px 0,
      88px 0,
      160px 0,
      176px 0,
      248px 0,
      264px 0,
      right 0px top 0,
      0 0px,
      0 72px,
      left 0 bottom 0px,
      0px 88px,
      88px 88px,
      176px 88px,
      264px 88px;
  }

  .about-hero + .trusted-by .trusted-by__logo-wrap {
    will-change: opacity, transform;
    transition: opacity 650ms var(--ease-smooth), transform 650ms var(--ease-smooth);
  }

  .about-hero + .trusted-by .trusted-by__logo-wrap--fading {
    opacity: 0;
    transform: translateY(12px);
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 189: секція Leadership (about.html)

   Trusted By поки не чіпаємо (окремий крок пізніше).

   Лейбл/номер/тайтл/боді — той самий принцип, що Крок 187/188. Текстовий
   контент тайтла — той самий, що на Tablet Portrait (ручний <br>,
   .leadership__title-break, увімкнений і тут, а не переписаний текст).

   Айтем картки — фундаментально інша компоновка (колонка: фото зверху,
   інфо-блок під ним, а не рядок фото+інфо поруч, як на десктопі/
   планшеті). Через це .leadership__content більше НЕ position:absolute
   з bottom-anchor (той трюк був потрібен лише для ФІКСОВАНОЇ висоти
   картки 590/382px, де довжина біо не повинна була зсувати позицію
   тайтла) — тут висота айтема auto (photo 396 + інфо, природна висота
   контенту), тому контент — звичайний потік (margin-top:24px від верху
   інфо-блоку, що само по собі = "від низу фото", бо інфо йде одразу
   після фото). .leadership__track отримує align-items:flex-start (не
   успадкований stretch), інакше різні за довжиною біо-тексти
   розтягували б усі картки до висоти найвищої, лишаючи порожній простір
   під тегами в коротших — замість цього кожна картка лишається рівно
   такою високою, як її власний контент; .leadership__clip підганяється
   під НАЙВИЩУ картку (виміряно рендером), коротші лишають видимий
   порожній простір знизу у вікні каруселі — прийнятно для мобільного
   вертикального стеку.

   .leadership__photo-stroke: рамка з 3 сторін лишається (стиль без змін,
   за завданням), але сторона БЕЗ рамки тепер НИЖНЯ (фото впритул до
   інфо-блоку знизу), а не права (фото більше не впритул до інфо-блоку
   праворуч, як на десктопі/планшеті) — той самий "3 сторони" принцип,
   повернутий на 90°.

   Ректангл-градієнт (п.6) і .leadership__end-pattern — обидва приховані:
   градієнт за явним завданням; end-pattern був калібрований під набагато
   ширше вікно каруселі за суму карток (десктоп 1542 vs 888×N) — тут
   вікно (336px) вужче за одну картку (320px), тому "хвіст"-патерн не
   застосовний і не згаданий у завданні.

   Карусель: 20px gap між айтемами (track), JS itemWidth() виправлено
   (offsetLeft-діфф двох сусідніх айтемів замість getBoundingClientRect
   першого) — інакше похибка в 20px накопичувалась би з кожним кліком.
   Кнопки гортання — той самий стиль, лише grid-column-фікс під нову
   4-колонкову сітку (той самий принцип, що Tablet Portrait, Крок 169) —
   margin-top:24px і justify-content:flex-end уже відповідають завданню
   без змін (успадковані з бази). */

@media (max-width: 767px) {

  /* 70px від низу таблички How We Work (Крок 188) до верху лейбла (п.1) */
  .leadership {
    margin-top: 70px;
  }

  .leadership__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .leadership__index {
    grid-column: 4;
    justify-self: end;
  }

  .leadership__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .leadership__title-break {
    display: inline;
  }

  .leadership__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* 32px від низу боді-тексту до верху першого айтема (п.3) */
  .leadership__viewport {
    grid-column: 1 / 5;
    margin-top: 32px;
  }

  /* Фікс (п.5 ТЗ, bug): width:336px обрізав ВСЕ, крім першого айтема
     (наступна картка виходила рівно за межу clip, 0px замість
     часткової видимості) — та сама помилка, якої НЕ було на
     десктопі/Tablet Portrait (там ширина clip 1542px, свідомо ширша
     за один айтем, і НЕ перевизначається на менших сітках, лише
     height, — див. коментар при .leadership__clip вище/в Tablet
     Portrait блоці). Прибрано width-override — успадковує ті самі
     1542px, чого достатньо для "хвоста" наступних карток; сторінка
     має overflow-x:clip на html/body (глобально), тому будь-який
     візуальний виступ за viewport безпечно обрізається без
     горизонтального скролу. Висота — фолбек до першого рендера
     (карта 1, Alexander, 629px); js/leadership-carousel.js
     перераховує height інлайн-стилем під РЕАЛЬНУ висоту поточного
     (активного) айтема при кожному кліку гортання (лише на
     мобільному, гейт через matchMedia) — інакше фіксована висота під
     найвищу картку (674px, Slava Boiko) лишає видиме порожнє місце
     під коротшими картками, і відступ до кнопок гортання (п.7 ТЗ,
     24px) роздувається на цю різницю */
  .leadership__clip {
    height: 629px;
    overflow: hidden;
  }

  .leadership__gradient {
    display: none;
  }

  /* Фікс (п.6 ТЗ): патерн косих ліній повертається після останньої
     картки ("The wider team") — раніше прихований, бо вужчий за
     картку clip (336px) не лишав для нього місця; тепер, коли clip
     ширший (успадковані 1542px, п.5 вище), той самий принцип, що
     десктоп/Tablet Portrait: ширина = залишок ширини сітки після
     одного айтема (336 − 320 = 16px), висота — виміряна рендером
     висота останньої картки ("The wider team", 375px) — фіксоване
     значення, той самий підхід, що .leadership__clip height fallback
     вище (немає CSS-способу "height: висота попереднього flex-
     сиблінга", тому виміряно один раз). margin-left:-20px скасовує
     успадкований .leadership__track gap:20px (застосовується
     рівномірно між УСІМА flex-дітьми, включно з цим патерном) — на
     десктопі track не має власного gap (айтеми впритул, 0px "сам
     собою"), тому тут потрібна компенсація, щоб той самий 0px-стик
     зберігся й на Mobile */
  .leadership__end-pattern {
    display: block;
    width: 16px;
    height: 600px;
    margin-left: -20px;
  }

  .leadership__track {
    align-items: flex-start;
    gap: 20px;
  }

  .leadership__item {
    flex-direction: column;
    width: 320px;
    height: auto;
  }

  .leadership__photo {
    width: 320px;
    height: 396px;
  }

  .leadership__photo-stroke {
    width: 320px;
    height: 396px;
    border-left: 1px solid var(--grey-15);
    border-top: 1px solid var(--grey-15);
    border-right: 1px solid var(--grey-15);
    border-bottom: none;
  }

  /* Фікс: .leadership__info успадковує border на ВСІХ 4 сторонах з бази
     (розрахований під фіксовану висоту 590px десктопу) — тепер, коли
     height:auto, border-bottom повертається (п.1 ТЗ: тег→строук на всю
     ширину картки, 6px) — раніше прибирався як "зайвий", тепер явно
     потрібен, лише з перерахованим (6px, не 7) відступом нижче */
  .leadership__info {
    width: 320px;
    height: auto;
  }

  /* Фікс: margin-left/top — 19px/23px, не 20/24 — .leadership__info має
     1px border (усі 4 сторони, база), а .leadership__content — прямий
     потоковий нащадок його content-box (не absolute, як у десктопі),
     тому 1px border-top/left рахується ДОДАТКОВО до margin і дає зайвий
     піксель у фактичному рендер-відступі; компенсовано, щоб реальна
     відстань фото→тайтл/край-айтема→тайтл дорівнювала точним 24px/20px
     (за завданням). margin-bottom:6px (п.1 ТЗ, тег→строук) — на відміну
     від margin-left/top, тут НЕ потрібна +1px компенсація: border-bottom
     малюється одразу за margin-bottom, тому відстань тег→строук
     дорівнює самому margin-bottom (6px), а не border не додається до
     вимірюваного проміжку */
  .leadership__content {
    position: static;
    width: 280px;
    margin-left: 19px;
    margin-top: 23px;
    margin-bottom: 6px;
  }

  .leadership__name {
    width: auto;
  }

  /* 8px від тайтла (п.1 ТЗ), замість успадкованого десктопного 16px */
  .leadership__bio {
    width: auto;
    margin-top: 8px;
  }

  /* Ручний перенос боді-текстів карток — вмикається тут, десктопний
     (unscoped, лише в картці "The wider team") вимикається */
  .leadership__bio-break--mobile {
    display: inline;
  }

  .leadership__bio-break--desktop {
    display: none;
  }

  /* 20px від боді-тексту, на всю ширину айтема (320px, п.4). margin-left:
     -20px — той самий "escape the content offset" прийом, що в десктопі
     (там -28px), лише перераховане під новий 20px відступ контенту */
  .leadership__hline {
    margin-top: 20px;
    margin-left: -20px;
    width: 320px;
  }

  /* "The wider team" — другий (нижній) рядок тегів: 10px текст-до-тексту
     (замість десктопних 14px), п.4 ТЗ. Той самий каскад, що десктоп
     (margin-top hline--tight + 1px висота строука + .leadership__tags
     margin-top:6px, успадкований з бази, без змін) = 10px тут потребує
     margin-top:3px (3+1+6=10) */
  .leadership__hline--tight {
    margin-top: 3px;
  }

  /* Тег→строук/строук→тег — 20px (той самий принцип, що Tablet Portrait,
     п.3 ТЗ), замість успадкованого десктопного 28px (там айтем ширший,
     464px інфо-блок) */
  .leadership__tags {
    gap: 20px;
  }

  /* Фікс (п.1 ТЗ): картка Alexander Kuzminets — прибрати строук одразу
     після останнього тега ("CHIEF EXECUTIVE OFFICER") */
  .leadership__track > .leadership__item:first-child .leadership__tag-divider:last-child {
    display: none;
  }

  /* Кнопки гортання — на всю ширину нової 4-колонкової сітки (той самий
     фікс, що Tablet Portrait, Крок 169) — justify-content:flex-end і
     margin-top:24px (п.7) успадковані з бази без змін */
  .leadership__nav {
    grid-column: 1 / 5;
  }

  /* Фікс (п.1 ТЗ) — "The wider team" (єдина картка з ДВОМА рядами тегів,
     тому найвища): запас по висоті, щоб обидва ряди тегів і всі строуки
     точно вміщались без обрізання. Стискаємо лише каскад ЦІЄЇ картки,
     не займаючи загальні 24/8/20/6/6/10/6px значення інших карток
     (виміряно рендером — там усе й так вміщається рівно, без запасу).
     Фікс селектора: :last-child НЕ спрацьовує тут — .leadership__end-pattern
     (окремий div, доданий попереднім фіксом, п.6) тепер справжній
     останній DOM-сиблінг у track, тому "остання картка" більше не є
     :last-child. :not(:has(~ .leadership__item)) коректно знаходить
     ОСТАННІЙ .leadership__item незалежно від того, що йде після нього
     (end-pattern чи щось інше в майбутньому), на відміну від хардкоду
     :nth-child(5):
     - боді→верхній строук тегів: 20px → 12px (:not(--tight) виключає
       ДРУГИЙ строук між рядами тегів — той лишається на власних 3px,
       щоб 10px текст-до-тексту між рядами тегів (п.4 попереднього фіксу)
       не зсунувся)
     - нижній ряд тегів→нижній строук картки (.leadership__content
       margin-bottom): 6px → 4px */
  .leadership__track > .leadership__item:not(:has(~ .leadership__item)) .leadership__hline:not(.leadership__hline--tight) {
    margin-top: 12px;
  }

  .leadership__track > .leadership__item:not(:has(~ .leadership__item)) .leadership__content {
    margin-bottom: 4px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 190: секція Offices (about.html)

   Той самий принцип, що index.html Offices (Крок 182): марк/строук
   рекалькульовані під новий тайтл (.dm-24-reg, line-height 130% = 31.2px):
   marker top = 31.2 + 7 = 38.2; line top = 38.2 + 5 = 43.2 (нижній піксель
   квадратика); city-info top = 43.2 + 16 = 59.2. Вертикальний стек замість
   рядка (десктоп) чи 2-рядкової абсолютної сітки (Tablet Portrait, Крок
   170) — той самий прийом, що Крок 182: .about-offices__titles —
   flex-column, margin-top:32px між містами замість margin-left/absolute
   top.

   На відміну від index.html Offices, about-offices має ДОДАТКОВІ елементи
   поза базовим рецептом тайтл→маркер→лейбл→боді (GMT-тег+строук під ним,
   строук під боді, вертикальний строук-розділювач між містами, косий
   патерн) — жоден з них не згаданий у завданні (лише патерн явно
   прибирається, п.8), тому всі приховані як ще не адаптовані під
   компактну мобільну картку (той самий принцип, що сфера/end-pattern/
   градієнт у Кроках 188/189).

   .about-offices__city min-height — виміряно рендером під найдовший
   боді-текст (Kyiv), єдине значення для всіх трьох міст (той самий
   принцип, що Крок 182, 129.2px там). */

@media (max-width: 767px) {

  /* 70px від низу кнопок гортання Leadership (Крок 189) до верху
     лейбла (п.1) */
  .about-offices {
    margin-top: 70px;
  }

  .about-offices__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .about-offices__index {
    grid-column: 4;
    justify-self: end;
  }

  .about-offices__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .about-offices__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* 32px від низу боді-тексту до верху London (п.3) */
  .about-offices__cities {
    grid-column: 1 / 5;
    margin-top: 32px;
    min-height: 0;
  }

  /* Фікс: margin-left:20px (успадкований з бази) зсував увесь стек
     міст на 20px правіше початку сітки (п.1 ТЗ) — прибрано, айтеми
     тепер починаються рівно з 0px */
  .about-offices__titles {
    display: flex;
    flex-direction: column;
    margin-left: 0;
  }

  /* Фікс: маркер успадковує left:-20px з бази (компенсація під
     margin-left:20px .titles вище, який тепер прибрано) — без цього
     маркер виїжджав би за межі сітки ліворуч. Той самий принцип, що
     Tablet Portrait (Крок 148-фікс) */
  .about-offices__marker {
    left: 0;
  }

  /* Виміряно рендером — усі 3 міста дають однакову висоту (243.2px,
     London/NY/Kyiv: 189.2px тайтл+боді + 54px GMT-блок нижче, п.2 ТЗ),
     бо перший <br> в боді-тексті Kyiv безумовний (не tablet-scoped),
     тому природний перенос синхронізований для всіх.
     align-self:flex-start (п.4 ТЗ, фікс лейбла країни) — .titles тут
     flex-column, дефолтне align-items:stretch розтягувало кожен
     .city на всю ширину сітки (336px); .about-offices__city-label
     позиціюється як left:calc(100% + 6px) відносно .city (containing
     block, position:relative, база), що коректно працює ЛИШЕ якщо
     .city сам "стискається" під ширину свого єдиного flow-нащадка —
     тайтла (як на десктопі, де рядкова розкладка природно дає це
     shrink-to-fit) — інакше лейбл завжди стрибав на "336+6px",
     виходячи за межі viewport незалежно від довжини назви міста */
  .about-offices__city {
    min-height: 243.2px;
    align-self: flex-start;
  }

  /* 32px між містами (п.7) замість десктопних кумулятивних margin-left */
  .about-offices__city--ny,
  .about-offices__city--kyiv {
    margin-left: 0;
    margin-top: 32px;
  }

  .about-offices__city-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .about-offices__marker {
    top: 38.2px;
  }

  /* .about-offices__line — єдиний HTML-елемент, position:absolute
     відносно .about-offices__cities (спільного контейнера, не окремого
     міста) — у рядковій розкладці (десктоп/планшет) це нормально, бо
     всі міста на тому самому top. У вертикальному стеку так вирівнюється
     лише з London (перше місто, top:0 відносно cities); New York/Kyiv
     потребують ВЛАСНОГО строука через ::after — той самий фікс, що
     .offices__city--ny/--kyiv (Крок 182) */
  .about-offices__line {
    top: 43.2px;
  }

  /* width:336px явно (замість right:0) — .about-offices__city--ny/--kyiv
     самі shrink-to-fit під ширину тайтла (align-self:flex-start вище),
     тому right:0 відносно НИХ давало ширину строука = ширині тайтла, а
     не сітки; той самий фікс, що вже застосований для contact.html
     (.contact-offices, той самий БЕМ-клас, Крок пізніше цього) */
  .about-offices__city--ny::after,
  .about-offices__city--kyiv::after {
    content: '';
    position: absolute;
    left: 0;
    width: 336px;
    top: 43.2px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Вертикальний строук-розділювач між містами — не застосовний до
     вертикального стеку (немає сусідніх колонок, які розділяти) */
  .about-offices__vline {
    display: none;
  }

  .about-offices__city-info {
    top: 59.2px;
  }

  /* Лейбл (напр. "Headquarters") — Red Hat/14 SB (значення .rh-14-sb,
     tokens.css — той самий токен, що вже перевикористаний у Кроці 182
     для index.html Offices) */
  .about-offices__subtitle {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0.12em;
  }

  /* margin-top:10px (п.6) уже успадкований з бази без змін */

  /* Ручний перенос боді-текстів айтемів міст (London/New York/Kyiv) —
     власний Mobile-набір розривів, відмінний від --desktop (вимикається
     тут) і --tablet/--portrait (вже прихований за замовчуванням, база
     вище). Той самий tablet-break прийом, що й в інших секціях.
     width: успадковані 293px замалі для найдовшого нового рядка
     ("client relationships, and coordinates delivery across", ~330px
     виміряно рендером) — браузер сам розбивав би ще один рядок поверх
     заданого <br> (той самий фікс, що .contact-offices__body--desktop);
     335px — з невеликим запасом, у межах 336px мобільної сітки */
  .about-offices__body {
    width: 335px;
  }

  .about-offices__body-break--desktop {
    display: none;
  }

  .about-offices__body-break--mobile {
    display: inline;
  }

  /* GMT-мітка (п.9 ТЗ, попередній фікс) — відновлена, та сама
     структура, що Tablet Portrait: строук над міткою → мітка → строук
     під міткою. .about-offices__gmt — РЕАЛЬНИЙ елемент на кожному
     місті (не спільний, на відміну від body-line/gmt-line нижче,
     які лишаються прихованими — по одному екземпляру на всю
     .cities), тому строуки додані через його власні ::before/::after
     замість клонування через містоспецифічні селектори. Позиція
     рахується від верху .about-offices__city (position:relative).
     left:21px (було 0, п.2 ТЗ) — звільняє місце зліва під новий
     строук+20px відступ (21 = 1px строука + 20px), той самий принцип,
     що вже є праворуч (.about-offices__gmt-divider, calc(100%+20px)
     відносно тегу).
     Фікс: спільний top (раніше 210.2px для всіх трьох) рахувався під
     висоту боді Kyiv (найдовший, 189.2px) — для London/New York (боді
     коротший, 169.2px, той самий текст по висоті в обох) це давало
     36px, не 16px, до строука. top тепер під London/New York (169.2 +
     16 + 1 + 4 = 190.2), Kyiv отримує власне перевизначення нижче */
  .about-offices__gmt {
    display: block;
    position: absolute;
    left: 21px;
    top: 190.2px;
  }

  /* Kyiv — довший боді (на 20px, own line count), той самий +16px
     відступ, порахований від ЙОГО фактичної висоти (189.2 + 16 + 1 + 4
     = 210.2) */
  .about-offices__city--kyiv .about-offices__gmt {
    top: 210.2px;
  }

  /* left:-21px (було 0) на обох горизонтальних строуках — компенсує
     зсув .about-offices__gmt на +21px (п.2 вище), щоб верхній/нижній
     строук фрейму й далі починався рівно на лівому краю сітки (0px),
     а не на 21px правіше */
  .about-offices__gmt::before {
    content: '';
    position: absolute;
    left: -21px;
    top: -5px;
    width: 336px;
    height: 1px;
    background-color: var(--grey-15);
  }

  /* Строук ПЕРЕД міткою (п.2 ТЗ) — дзеркальний до існуючого
     .about-offices__gmt-divider праворуч (той самий style/висота,
     успадковані з базового класу). left:-21px відносно зсунутого
     тегу (21px) = абсолютний 0 — рівно на лівому краю фрейму/сітки,
     20px відступу до тексту мітки виходить сам собою (21 − 1px
     ширина строука) */
  .about-offices__gmt-divider--before {
    display: block;
    left: -21px;
  }

  /* Строук на правому краю сітки (336px), в межах фрейму мітки —
     той самий стиль (1px, var(--grey-15)), та сама висота/top, що
     .about-offices__gmt-divider (29px, top:-5px відносно мітки,
     збігається з верхнім/нижнім строуком фрейму, :before/:after
     нижче). left:314px = 336 (правий край сітки) − 21 (зсув самої
     мітки, п.2 ТЗ) − 1 (власна ширина строука) */
  .about-offices__gmt-edge-line {
    display: block;
    position: absolute;
    left: 314px;
    top: -5px;
    width: 1px;
    height: 29px;
    background-color: var(--grey-15);
  }

  .about-offices__gmt::after {
    content: '';
    position: absolute;
    left: -21px;
    top: 24px;
    width: 336px;
    height: 1px;
    background-color: var(--grey-15);
  }

  .about-offices__gmt-line,
  .about-offices__body-line,
  .about-offices__extra-vline,
  .about-offices__pattern {
    display: none;
  }

  /* Фікс (п.4 ТЗ): лейбл країни повертається — корінь попереднього
     overflow-бага виправлено вище (.about-offices__city{align-self:
     flex-start}), тепер left:calc(100%+6px) (база) коректно рахується
     від РЕАЛЬНОЇ ширини тексту тайтла, а не від розтягнутого на всю
     сітку контейнера. Стиль — Red Hat/11 Bold (.rh-11-bold, tokens.css)
     замість успадкованого rh-12-bold-track (HTML-клас лишається
     спільним з іншими breakpoint, тут лише перевизначені властивості
     шрифту), колір grey-60 (десктопна база — grey-50, тут інший за
     завданням); top:2px — виміряно рендером під новий 24px/130%
     тайтл (десктопне -2px розраховане під більший dm-h1) */
  .about-offices__city-label {
    display: block;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 11px;
    line-height: 20px;
    letter-spacing: 0.07em;
    color: var(--grey-60);
    top: 2px;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 191: секція CTA-2 (about.html)

   Той самий готовий блок, що вже на index.html (.offices + .cta--second,
   Крок 183) — тут той самий набір значень, скоуплений через суміжний
   селектор .about-offices + .cta--second (той самий прийом, що вже
   використовується для цієї пари на десктопі/Tablet Landscape/Portrait,
   Крок 148/163), без змін (п.10 ТЗ). 56px від низу останнього айтема
   Offices (Kyiv, разом з GMT-міткою вище) до верху фону CTA-2 —
   margin-top рахується напряму від попереднього флекс-сиблінга
   (.about-offices), тому автоматично враховує нову висоту Kyiv після
   додавання GMT-блоку (п.9), без ручного перерахунку.
   about.html's CTA-2 button uses plain "BOOK A CONSULTATION" text (no
   .cta__btn-label--desktop/--mobile swap span — that pattern is
   index.html-only, per Крок 183), so no label-swap rule needed here.
   ========================================================================== */

@media (max-width: 767px) {

  /* Крок — 112px вільного простору ЗВЕРХУ і 40px ЗНИЗУ (той самий
     прийом, що .offices + .cta--second вище): height +152 (461→613),
     background-position зсуває фон на 112px вниз, padding-top +112
     (213→325), щоб позиція тайтла відносно фону лишилась незмінною */
  .about-offices + .cta--second {
    margin-top: 56px;
    height: 613px;
    padding-top: 325px;
    background-position: center 112px;
    background-size: 692px 300px;
  }

  .about-offices + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Фікс: асиметричний padding-left:101px прибрано — центрується через
     justify-content:center на базовому .hero__btn */
  .about-offices + .cta--second .cta__btn {
    margin-top: 32px;
    width: 336px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 191: Hero-секція (services.html)

   Сітка/хедер — без змін (спільні, Крок 176 + фікс сітки). Фон — той самий
   ассет, що на десктопі/Tablet (image-set 1x/2x), без нового файлу:
   пропорційно зменшений до ширини 720px (background-size: 720px auto —
   висота рахується браузером від оригінального співвідношення сторін
   1920:900, той самий прийом, що .about-hero, Крок 186, лише інші числа),
   зсув 383px від верху, center по горизонталі. Текстовий блок — той самий
   стиль/відступи, що Hero index.html/about.html (Крок 177/186): тайтл
   .dm-28-reg (mob/H1), 8px від лейбла; боді-текст DM Sans/14 Light
   (.dm-14-light), 16px від тайтла, ширина 336px (сітка). padding-top на
   .services-hero — 174px (фіксовано, той самий принцип, що about.html,
   Крок 186, п.4) замість десктопних 170px. Текстовий контент (ручні
   переноси тайтла) — той самий tablet-break прийом, що Tablet
   Landscape/Portrait (Крок 149/171): --title-break--desktop вимикається,
   --title-break--tablet вмикається */

@media (max-width: 767px) {

  .services-hero {
    padding-top: 174px;
  }

  .services-hero__image {
    background-position: center 383px;
    background-size: 720px auto;
  }

  .services-hero__title-break--desktop,
  .services-hero__title-break--tablet {
    display: none;
  }

  .services-hero__title-break--mobile {
    display: inline;
  }

  .services-hero__title {
    margin-top: 8px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Крок — боді-текст Hero повернуто в потік на Mobile (раніше був
     прибраний повністю, display:none). Стиль DM Sans/14 Light
     (.dm-14-light, tokens.css), значення продубльовані тут напряму —
     той самий прийом, що .services-hero__title вище (не через додавання
     класу в розмітку). 16px від тайтла (був 18px у десктопі) */
  .services-hero__desc {
    display: block;
    margin-top: 16px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Ручний перенос (3 рядки) — своя, окрема точка розриву, увімкнена
     лише тут, той самий прийом, що .services-hero__title-break--mobile */
  .services-hero__desc-break--mobile {
    display: inline;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 192: секція Services (scrollytelling-табличка,
   services.html)

   Тайтл+каунтер+строук — на всю нову сітку (336px), той самий принцип, що
   Крок 172 (668px), лише нові числа: тайтл .dm-24-reg (Mob/H2), строук
   12px від тайтла (15px у десктопі). Номер "I." — той самий елемент, що на
   десктопі/Tablet (left:740/342px), тут просто протилежний край рядка:
   right:0 у межах 336px-контейнера (bottom:3px — той самий фіксований
   офсет під базову лінію тайтла, не займаємо, ніде досі не перевизначався).

   Ілюстрацію-квітку (.services-hero__practices-illustration) спершу тут
   навмисно не займали — додана нижче окремим фіксом. Оскільки другої
   колонки під ілюстрацію тут нема (336px не вистачає лише на саму
   табличку), .services-hero__practices-window стає на всю сітку
   (margin-left:0, width:336px, той самий "single column" прийом, що
   .services-table на index.html, Крок 178) — .services-hero__practices-line
   (рейка, що на десктопі/Tablet відділяла ілюстрацію від вікна) утратила
   пару й ховається, її роль тепер бере на себе новий фон контейнера
   (п.3 ТЗ, var(--color-background) — той самий токен, що .services-table
   на index.html, Крок 178).

   Зазор до таблички: 290px (100px у Tablet Portrait). Видиме вікно: 600px
   (920px у Tablet Portrait) → sticky-панель: 890px (290+600). Той самий
   принцип, що Крок 172, п.7 ТЗ: JS-логіка (measure()/WINDOW_HEIGHT=800/
   PANEL_HEIGHT=928 у js/services-practices.js) свідомо НЕ чіпається —
   лишається неузгодженою з новими 600/890px, той самий "не читає CSS"
   прийом, синхронізація — окремий майбутній крок.

   Відступ між айтемами: 80px (той самий, що Tablet Portrait, п.3 ТЗ,
   140px у десктопі). Внутрішній лівий відступ тексту: 16px (=gutter,
   той самий принцип, що Крок 172). Нові стилі: тайтл айтема .dm-20-reg
   (22px reg у десктопі/Tablet), значення сервісів (.practice__frame-text)
   .dm-14-light (16px light у Tablet Portrait) — вертикальне центрування
   всередині 56px-фрейму лишається автоматичним (display:flex;
   align-items:center на .practice__frame, п.4 ТЗ), перерахунок
   паддінгів (як для .services-table__row--item на index.html, Крок 178)
   тут не потрібен. */

@media (max-width: 767px) {

  .services-hero__list-heading-inner {
    max-width: 336px;
  }

  .services-hero__list-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .services-hero__list-index {
    left: auto;
    right: 0;
  }

  .services-hero__list-stroke {
    width: 336px;
    margin: 12px auto 0;
  }

  .services-hero__practices {
    max-width: 336px;
  }

  .services-hero__practices-sticky {
    height: 890px;
    padding-top: 290px;
  }

  .services-hero__practices-line {
    display: none;
  }

  .services-hero__practices-window {
    margin-left: 0;
    width: 336px;
    height: 600px;
    background-color: var(--color-background);
  }

  /* 1:1 з index.html (.services-table__group::before, Крок 178) — лівий
     вертикальний градієнтний строук активної практики не підходить на
     Mobile, вимикається повністю, замінений горизонтальним нижче */
  .practice::before {
    display: none;
  }

  /* 1:1 з index.html (.services-table-window::before, Крок 178) —
     горизонтальний градієнтний строук зверху таблички: статичний і
     ЗАВЖДИ присутній (не залежить від активного блоку), напрям —
     var(--primary-grad) горизонтальний (зліва направо), не
     var(--primary-grad-services) (вертикальний, вимкнений вище).
     Скоуплений на .services-hero__practices-window (сама видима "картка"
     з фіксованими межами на екрані), а не на .services-hero__practices-list
     (яку JS транслює transform'ом усередині вікна) — інакше строук їхав
     би разом зі скролом замість лишатись на верхньому пікселі */
  .services-hero__practices-window::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--primary-grad);
    z-index: 2;
    pointer-events: none;
  }

  .services-hero__practices-list {
    width: 336px;
  }

  .practice {
    width: 336px;
  }

  .practice + .practice {
    margin-top: 80px;
  }

  .practice__head {
    padding-left: 16px;
  }

  .practice__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 20px;
    line-height: 28px;
    letter-spacing: 0.02em;
  }

  /* Базовий стиль боді/секондарі-боді — DM Sans/14 Light спільний старт
     (розмітка боді2 несе dm-15-light-italic — тут скасовано; Фікс-блок
     нижче повертає боді2 на власний 13px Light Italic, п.3 ТЗ, той самий
     "перевизначення пізніше в тому самому медіа-запиті" прийом, що вже в
     Кроці 192 нижче для .practice__frame-text) */
  .practice__body,
  .practice__body2 {
    margin-left: 16px;
    width: 320px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-style: normal;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: попередній bleed-хак (margin-left:-24px/width:336px на
     .practice__body(2).practice__body(2)--mobile) прибрано — він тягнув
     текст на 24px лівіше за тайтл/айтеми (0px замість 24px від краю
     таблички, п.1 ТЗ). Боді/боді2 лишаються на 288px, той самий контент-
     бокс, що .practice__frame нижче — margin-left:0/width:288px
     (Фікс-блок нижче) вирівнює їх з рештою тексту. Продукт: останні 2
     рядки боді-тексту тепер контролюються явним <br> (розмітка,
     services.html, п.7 ТЗ) замість природного переносу в 336px-боксі */

  .practice__frame {
    width: 336px;
  }

  .practice__frame-text {
    margin-left: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Повне оновлення боді/секондарі-боді 5 блоків (п.6-13 ТЗ) — окремий
     переписаний <p>-варіант на кожен, той самий "друга <p>" прийом, що
     вже в Operations' --tablet-landscape/--tablet-portrait */
  .practice__body--desktop,
  .practice__body2--desktop {
    display: none;
  }

  .practice__body--mobile,
  .practice__body2--mobile {
    display: block;
  }

  /* Фікс: ілюстрація-квітка додається на цьому breakpoint — той самий
     550×550px, що на index.html. top:32px — офсет від padding-edge
     панелі, виміряний від боді-тексту секції до верху ілюстрації.
     Горизонталь: фрейм вирівняний по правому краю сітки (336px) з
     відступом 1px → left = (336 − 1) − 550 = −215px */
  .services-hero__practices-illustration {
    top: 32px;
    left: -215px;
    width: 550px;
    height: 550px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 193: секція Our Commitments (services.html)

   Відступ від видимої частини Services (600px, Крок 192) до лейбла: 70px
   (той самий "приймаємо число з ТЗ напряму" принцип, що .about-offices,
   Крок 190, — без десктопної 348px-компенсації, бо там вона рахувала
   специфічний overflow ілюстрації services-практик, який тут не задіяний).

   Лейбл/номер/тайтл/боді — той самий рецепт, що Offices на about.html
   (Крок 190, п.2, що сам перевикористав Leadership): сітка 4×72/16,
   номер — колонка 4 (justify-self:end), тайтл .dm-24-reg (14px від
   лейбла), боді DM Sans/14 Light (16px від тайтла), обидва на всю сітку
   (grid-column:1/5). Контент/переноси — той самий, що Tablet Portrait
   (Крок 173 + Фікс): тайтл-брейк --portrait вмикається;
   боді-брейк --desktop вимикається, --portrait вмикається (--tablet
   лишається вимкненим за замовчуванням, тут не займається).

   Фрейми: 32px від низу боді до верху першого (п.3 ТЗ), 32px між собою
   (п.6 ТЗ), стовпчик на всю ширину сітки (336px, той самий "стовпчик
   замість ряду" прийом, що Tablet Portrait). Усередині кожного —
   ЗВИЧАЙНИЙ потік (на відміну від Tablet Portrait, де ілюстрація
   виносилась у правий верхній кут через position:absolute): ілюстрація
   зліва зверху (0px, п.4), тайтл 20px нижче (типографіка вже .dm-20-reg
   з розмітки, тут не дублюється), квадратик+строук 7px нижче тайтла
   (той самий ::after-на-квадратику прийом, що Tablet Portrait, лише
   строук на всю ширину фрейму, 336px), боді 16px нижче строука
   (типографіка вже .dm-14-light з розмітки). Старий спільний
   .our-commitments__line (один строук на всі 3 item, десктопний
   підхід) вимикається, той самий принцип, що Tablet Portrait.

   Ілюстрація: 124px завширшки (149px у десктопі), висота пропорційна
   тому самому співвідношенню 149:86, що в десктопному CSS-боксі —
   86×124/149 = 71.57px (не нативному 453:258 PNG, той самий "пропорційно
   від десктоп-версії" принцип, що фон Hero, Крок 191). */

@media (max-width: 767px) {

  .our-commitments {
    margin-top: 70px;
  }

  .our-commitments__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .our-commitments__index {
    grid-column: 4;
    justify-self: end;
  }

  .our-commitments__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .our-commitments__title-break--portrait {
    display: inline;
  }

  .our-commitments__desc {
    grid-column: 1 / 5;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .our-commitments__items {
    grid-column: 1 / 5;
    margin-top: 32px;
    display: flex;
    flex-direction: column;
    gap: 32px;
  }

  .our-commitments__item {
    width: 336px;
  }

  .our-commitments__illustration {
    width: 124px;
    height: 71.57px;
    background-size: 124px 71.57px;
  }

  .our-commitments__item-title {
    margin-top: 20px;
    width: 336px;
  }

  .our-commitments__item-marker {
    position: relative;
    margin-top: 7px;
  }

  .our-commitments__item-marker::after {
    content: '';
    position: absolute;
    left: 0;
    top: 4px;
    width: 336px;
    height: 1px;
    background-color: var(--grey-15);
  }

  .our-commitments__line {
    display: none;
  }

  .our-commitments__item-body {
    margin-top: 16px;
    width: 336px;
  }

  .our-commitments__item-body-break--desktop {
    display: none;
  }

  .our-commitments__item-body-break--portrait {
    display: inline;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 194: секція Industries (services.html)

   Лейбл/номер/тайтл/боді — той самий рецепт, що Our Commitments (Крок 193,
   п.2): сітка 4×72/16, номер — колонка 4 (justify-self:end), тайтл
   .dm-24-reg (14px від лейбла), боді DM Sans/14 Light (16px від тайтла),
   обидва на всю сітку. Контент/переноси — той самий, що Tablet Portrait
   (Крок 174 успадковує текст Tablet Landscape): боді-брейк --desktop
   вимикається, --portrait вмикається (той самий toggle, що робить
   Tablet-Portrait-медіа-запит для цього ж тексту — тут відтворений явно,
   бо той запит (768–1023px) не покриває mobile-діапазон).

   Фрейми — точна копія Кроку 181 (index.html mobile), скоуплена через
   .services-hero + .industries--services замість .cta + .industries (той
   самий принцип, що робить Крок 174 для Tablet Portrait): висота 138px,
   контент на всю ширину фрейму, тайтл Red Hat/16 SB, теги DM Sans/14 Light
   з переносом на 2-й рядок (flex-wrap+row-gap), літера-ілюстрація 40×50 у
   правому верхньому куті з crossfade на hover (nth-child F/H/E/C/P, ті самі
   tablet-ассети). Два фікси поверх Кроку 181 (не застосовувались раніше):
   .industry-row отримує фон var(--color-background) (той самий токен, що
   .services-hero__practices-window/.about-offices, Кроки 190/192); .industry-
   row__content замінює фіксований padding-top:25px на
   display:flex/flex-direction:column/justify-content:center — вирівнює
   тайтл+теги по вертикальному центру фрейму (стійко до переносу тегів на
   2 рядки), замість зафіксованого відступу зверху. */

@media (max-width: 767px) {

  /* 70px від низу останнього фрейму Our Commitments (Крок 193) до верху
     лейбла (п.1 ТЗ) */
  .services-hero + .industries--services {
    margin-top: 70px;
  }

  .services-hero + .industries--services .industries__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .services-hero + .industries--services .industries__index {
    grid-column: 4;
    justify-self: end;
  }

  .services-hero + .industries--services .industries__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .services-hero + .industries--services .industries__desc {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 16px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .services-hero + .industries--services .industries__desc-break--desktop {
    display: none;
  }

  /* Фікс: боді Industries на Mobile більше НЕ переюзає Tablet Portrait
     розподіл рядків — свій власний (--mobile нижче), тому --portrait
     тут вимкнений (раніше був display:inline) */
  .services-hero + .industries--services .industries__desc-break--portrait {
    display: none;
  }

  .services-hero + .industries--services .industries__desc-break--mobile {
    display: inline;
  }

  /* Фікс: десктопний глобус (.industries__globe-stack, 786×786,
     margin-left:792px, grid-row:4 — той самий рядок, що мобільний scrolly-
     глобус нижче) не був прихований на Mobile — 1:1 з тим самим фіксом на
     index.html (.cta + .industries), інакше залишається в потоці
     4-колонкової мобільної сітки зі своєю десктопною геометрією */
  .services-hero + .industries--services .industries__globe-stack {
    display: none;
  }

  /* Sticky-глобус scrollytelling — той самий прийом, що index.html
     (js/industries-mobile-scrolly.js); .industries__scrolly-mobile
     переймає grid-column/margin-top, що раніше стояли на .industries__list */
  .services-hero + .industries--services .industries__scrolly-mobile {
    display: block;
    grid-column: 1 / 5;
    grid-row: 4;
    margin-top: 32px;
  }

  /* Фікс: overflow:hidden ЗНЯТО — той самий фікс, що вже на index.html
     (styles.css:13599, .cta + .industries .industries__scrolly-mobile-
     sticky) — цей селектор його досі не отримав. position:sticky сам є
     positioned-предком для .industries__globe-stack-mobile (position:
     absolute, дитина нижче), тому overflow:hidden саме тут обрізав
     563px-ву ілюстрацію по краях вужчої сітки-колонки.
     100dvh — той самий Chrome-фікс, що index.html: 100vh статично
     дорівнює НАЙБІЛЬШОМУ можливому viewport (адресний рядок прихований),
     тому коли рядок видимий, ілюстрація (bottom:0 усередині цієї панелі)
     впиралась у низ ЦІЄЇ (завищеної) панелі, а не в справжній низ екрана */
  .services-hero + .industries--services .industries__scrolly-mobile-sticky {
    display: block;
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
  }

  .services-hero + .industries--services .industries__list-window {
    display: block;
    position: relative;
    overflow: hidden;
  }

  /* Фікс: скидає успадкований десктопний margin-top:96px (той самий
     фікс, що index.html). Без transition на transform — js/industries-
     mobile-scrolly.js (спільний з index.html скрипт) тепер пише позицію
     1:1 за прогресом скролу на кожен тик, окремий "доганяючий" transition
     тут лише додав би відставання */
  .services-hero + .industries--services .industries__list {
    position: relative;
    margin-top: 0;
    /* Safari-фікс продуктивності, той самий принцип, що .services-table
       (styles.css:1849) */
    will-change: transform;
  }

  .services-hero + .industries--services .industry-row {
    height: 138px;
  }

  /* Фікс: той самий edge-case, що index.html — .scroll-reveal усередині
     sticky-вікна, що рухається transform, може не отримати повторний
     IntersectionObserver callback і назавжди лишитись opacity:0 */
  .services-hero + .industries--services .industry-row.scroll-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .services-hero + .industries--services .industry-row__content {
    position: relative;
    z-index: 1;
    margin-left: 0;
    width: 100%;
    padding-top: 25px;
  }

  /* Немає hover (п.5) — активний рядок керується скролом (.is-active),
     дефолт приглушений (grey-50), той самий принцип, що index.html */
  .services-hero + .industries--services .industry-row__title {
    font-family: var(--font-red-hat);
    font-weight: 600;
    font-size: 16px;
    line-height: 24px;
    letter-spacing: 0.12em;
    color: var(--grey-50);
    transition: color 200ms ease;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__title {
    color: var(--grey-100);
  }

  .services-hero + .industries--services .industry-row__tags {
    margin-top: 17px;
    flex-wrap: wrap;
    row-gap: 8px;
    color: var(--grey-50);
    transition: color 200ms ease;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  /* Фікс: Cybersecurity/Proptech (nth-child(4)/(5)) мають лише 2 теги —
     природний flex-wrap НЕ переносить другий тег у 336px контейнері,
     1:1 з тим самим фіксом на index.html (.cta + .industries) */
  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__tags span:last-child,
  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__tags span:last-child {
    flex-basis: 100%;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__tags {
    color: var(--grey-60);
  }

  .services-hero + .industries--services .industry-row__dot {
    background-color: var(--grey-50);
    opacity: 0.3;
    transition: background-color 200ms ease, opacity 200ms ease;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__dot {
    background-color: var(--grey-60);
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row__divider {
    left: 0;
    right: 0;
  }

  .services-hero + .industries--services .industry-row__illustration {
    display: none;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap {
    position: absolute;
    z-index: 0;
    top: 12px;
    right: 0;
    width: 40px;
    height: 50px;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before,
  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40px;
    height: 50px;
    background-repeat: no-repeat;
    background-size: 40px 50px;
    transition: opacity 200ms ease 100ms;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::before {
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row__illustration-wrap::after {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::before {
    opacity: 0;
  }

  .services-hero + .industries--services .industry-row.is-active .industry-row__illustration-wrap::after {
    opacity: 1;
  }

  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/f-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(1) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/f-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/f-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/h-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(2) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/h-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/h-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/e-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(3) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/e-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/e-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/c-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(4) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/c-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/c-letter-tablet-hover.png") 1x
    );
  }

  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::before {
    background-image: url("../assets/images/p-letter-tablet.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet.png") 1x
    );
  }
  .services-hero + .industries--services .industry-row:nth-child(5) .industry-row__illustration-wrap::after {
    background-image: url("../assets/images/p-letter-tablet-hover.png");
    background-image: image-set(
      url("../assets/images/p-letter-tablet-hover.png") 1x
    );
  }

  /* Fade-маски вікна списку + sticky-глобус — той самий прийом, що
     index.html (js/industries-mobile-scrolly.js) */
  .services-hero + .industries--services .industries__list-window-fade {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    height: 56px;
    pointer-events: none;
    z-index: 2;
    transition: opacity 300ms ease;
  }

  .services-hero + .industries--services .industries__list-window-fade--top {
    top: 0;
    background: linear-gradient(to bottom, var(--color-background), transparent);
    opacity: 0;
  }

  .services-hero + .industries--services .industries__list-window-fade--top.is-visible {
    opacity: 1;
  }

  .services-hero + .industries--services .industries__list-window-fade--bottom {
    bottom: 0;
    background: linear-gradient(to top, var(--color-background), transparent);
    opacity: 1;
  }

  .services-hero + .industries--services .industries__list-window-fade--bottom.is-hidden {
    opacity: 0;
  }

  /* Фікс: фіксований розмір 563×286, не масштабується під ширину
     в'юпорта — той самий принцип, що index.html */
  .services-hero + .industries--services .industries__globe-stack-mobile {
    display: block;
    position: absolute;
    left: 50%;
    bottom: 0;
    margin-left: -281.5px;
    width: 563px;
    height: 286px;
    pointer-events: none;
  }

  .services-hero + .industries--services .industries__globe-mobile--base,
  .services-hero + .industries--services .industries__globe-mobile-accent {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  .services-hero + .industries--services .industries__globe-mobile-accent {
    opacity: 0;
    transition: opacity 450ms ease;
    /* Safari-фікс продуктивності, той самий принцип, що .services-table
       (styles.css:1849) */
    will-change: opacity;
  }

  .services-hero + .industries--services[data-active-globe='f'] .industries__globe-mobile-accent--f,
  .services-hero + .industries--services[data-active-globe='h'] .industries__globe-mobile-accent--h,
  .services-hero + .industries--services[data-active-globe='e'] .industries__globe-mobile-accent--e,
  .services-hero + .industries--services[data-active-globe='c'] .industries__globe-mobile-accent--c,
  .services-hero + .industries--services[data-active-globe='p'] .industries__globe-mobile-accent--p {
    opacity: 1;
  }

  .services-hero + .industries--services .industries__globe-mobile-fade {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 40px;
    background: linear-gradient(to top, var(--color-background), transparent);
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 195: секція FAQ (services.html)

   .faq/.faq__* унікальні для services.html — не скоуплені через суміжний
   селектор (той самий принцип, що Крок 153/175). Лейбл/номер/тайтл — той
   самий рецепт, що Industries (Крок 194, п.2): сітка 4×72/16, номер —
   колонка 4 (justify-self:end), тайтл .dm-24-reg (14px від лейбла); без
   боді-тексту (FAQ його не має). Тайтл "Common questions" лишається на
   успадкованому width:fit-content/white-space:nowrap (база) — короткий
   текст не переноситься на жодному брейкпоінті, той самий принцип, що
   Tablet Portrait (Крок 175, п.5 ТЗ).

   Акордеон — на всю ширину сітки (336px, п.4 ТЗ), той самий "0px, на всю
   ширину" прийом, що Крок 175 (668px): тайтл/боді = 336 − 24 (відступ до
   іконки) − 12 (іконка) = 300px (та сама формула, що 668−24−12=632).
   Розгортання/згортання/dim-ефект (js/faq-accordion.js, :has()-селектори
   в CSS) — логіка не залежить від ширини екрана, тут не чіпається (п.4 ТЗ).
   Відступ між айтемами — 24px, той самий, що в базі/усіх інших
   брейкпоінтах (.faq-item + .faq-item, не перевизначається тут).

   Контент — той самий, що на Tablet Portrait (п.4 ТЗ): tablet-break класи
   тайтла/боді вмикаються, десктопний боді-розрив і окрема <p>
   (.faq-item__body--desktop, айтем 4 "SaaS companies") ховаються, планшетна
   <p> (.faq-item__body--tablet) показується — той самий набір toggle, що
   Крок 153 (де ці класи вперше стають display:inline/block; Tablet Portrait
   лише успадковує їх у своєму діапазоні), тут відтворений явно, бо
   mobile-діапазон не покривається жодним із існуючих медіа-запитів.

   Нові стилі (п.5 ТЗ): тайтл — уже .dm-desc ("Description text" з
   tokens.css, коментар там-таки) прямо в розмітці (.faq-item__title), тут
   не дублюється. Боді — .dm-14-light (розмітка несе .dm-14-reg, weight 400;
   тут лише вага перевизначається на 300, розмір/lh/ls (14/20/0.02em) ті
   самі в обох токенах). */

@media (max-width: 767px) {

  .faq {
    margin-top: 70px;
  }

  .faq__grid {
    grid-template-columns: repeat(4, 72px);
    column-gap: 16px;
    max-width: 336px;
    margin: 0 auto;
  }

  .faq__index {
    grid-column: 4;
    justify-self: end;
  }

  .faq__title {
    grid-column: 1 / 5;
    width: auto;
    margin-top: 14px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .faq__list {
    grid-column: 1 / 5;
    margin-top: 32px;
  }

  .faq-item__row {
    width: 336px;
  }

  .faq-item__title {
    width: 300px;
  }

  .faq-item__body {
    width: 299px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .faq-item__stroke {
    width: 336px;
  }

  .faq-item__title-break--desktop {
    display: none;
  }

  /* Фікс: свій, мобільний тайтл-розрив замість переюзаного --tablet */
  .faq-item__title-break--tablet {
    display: none;
  }

  .faq-item__title-break--mobile {
    display: inline;
  }

  /* Фікс: боді-текст більше не переносить рядки вручну (п.4 ТЗ) — окрема
     <p> (.faq-item__body--mobile, слова ті самі, що вже в --portrait,
     без <br>) замість toggle існуючих --desktop/--tablet/--portrait
     розривів, природний word-wrap у межах 299px (вище) */
  .faq-item__body--desktop,
  .faq-item__body--tablet,
  .faq-item__body--portrait {
    display: none;
  }

  .faq-item__body--mobile {
    display: block;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Фікс: Services (внутрішній строук фрейму,
   вирівнювання строука під айтемами, стиль значень) + FAQ (CTA-2/Footer),
   services.html

   1. Внутрішній строук фрейму таблички (Крок 192, п.3): box-shadow inset
      замість border/outline — не займає layout-простір, тому контент-бокс
      лишається рівно 336×600 (той самий "не впливає на ширину/висоту"
      принцип, що дає чисті круглі числа нижче), лише малює 1px-лінію по
      контуру. padding:20px 24px + box-sizing:border-box рахує внутрішні
      паддінги контенту ВІД цього контуру: видима область для контенту —
      336−2×24=288px завширшки, 600−2×20=560px заввишки (WINDOW_HEIGHT=800
      у js/services-practices.js і далі не чіпається, той самий "не читає
      CSS" принцип, що вже в Кроці 192 — зменшення видимої зони через
      padding сюди не втручається).

   2. Вирівнювання строука під айтемами: .practice/.practice__frame
      звужуються з 336 до 288px (нова ширина контент-боксу з п.1) —
      .practice__head/.practice__body(2)/.practice__frame-text втрачають
      власний 16px-інсет (Крок 192): тепер увесь інсет від контуру дає
      ЛИШЕ padding вікна (п.1), тому текст і border-bottom-лінія фрейму
      починаються з ОДНІЄЇ й тієї самої точки (x:0 відносно звуженого
      288px-фрейму) — раніше лінія (фрейм, x:0 у старому 336px-боксі)
      стирчала на 16px лівіше за текст (x:16), звідси й "зайвий лівий
      відступ" у завданні.

   3. Стиль значень таблички: скасовує dm-14-light-перевизначення
      .practice__frame-text з Кроку 192 — розмітка й так уже несе клас
      .rh-12-bold-track ("Red Hat/12 Bold (tracking)", tokens.css) поряд
      із .practice__frame-text, тому явно повертаємо його властивості
      (пізніше правило в тому самому медіа-запиті, та сама специфічність —
      каскад віддає перевагу цьому).

   4. FAQ + CTA-2/Footer: .cta--second перевикористовується на
      about/contact/index/work.html — тут скоуп через .faq + .cta--second
      (FAQ іде прямо перед CTA-2 на services.html, той самий принцип, що
      Tablet Portrait, Фікс після Кроку 175/174). Той самий готовий блок,
      що вже на index.html (Крок 183): 56px від низу останнього FAQ-айтема
      (п.4 ТЗ, той самий принцип, що .offices + .cta--second) до верху
      фону CTA-2, 461/213/692×300, .cta__line — Mob/H1 (.dm-28-reg). Кнопка
      services.html несе просто "BOOK A CONSULTATION" (немає --desktop/
      --mobile label-спанів, той самий принцип, що about.html) — без
      label-swap правил, той самий набір значень (32/336/101), що
      index.html. Footer — сайт-вайд (Крок 184 + всі фікси), .footer__*
      класи однакові на всіх сторінках (звичайні селектори, без
      adjacent-sibling) — уже застосовується тут автоматично, без
      додаткових правил. */

@media (max-width: 767px) {

  /* Фікс: декоративний inset-строук по контуру вікна прибраний (п.4 ТЗ,
     наступний крок) — на Mobile фон таблички має бути без жодних строуків,
     box-sizing/padding лишаються (вони визначають видиму контент-зону,
     від якої й далі рахуються .practice/.frame нижче).
     Фікс: padding-top 20→24px (п.1 ТЗ — верх таблички → тайтл "Consulting"
     = 24px), padding-bottom лишається 20px (не в межах цього ТЗ) —
     вертикальний padding тепер асиметричний (24/20, не 20/20), тому явні
     top/bottom замість shorthand. Видима висота контенту звужується на
     +4px (336×556, було 560) — js/services-practices.js WINDOW_HEIGHT_MOBILE
     синхронізовано (556, було 560, той самий "не читає CSS" принцип, що
     й досі, лише перераховане значення) */
  .services-hero__practices-window {
    box-sizing: border-box;
    padding: 24px 24px 20px;
  }

  .services-hero__practices-list {
    width: 288px;
  }

  .practice {
    width: 288px;
  }

  /* Відступ останній айтем (чи секондарі боді-текст/зірка, якщо є) →
     тайтл наступного блоку — 48px (Фікс, замінює попередні 80px). Один
     margin-top на .practice+.practice працює однаково для блоків із
     секондарі боді-текстом (Product/Brand/Operations, чий останній
     видимий елемент — .practice__body2, без власного margin-bottom) і
     без нього (Consulting/Audit, останній елемент — .practice__frames) —
     в обох випадках це останній дочірній елемент articles, тому відступ
     рахується від нього автоматично, без окремих правил на кожен варіант */
  .practice + .practice {
    margin-top: 48px;
  }

  .practice__head {
    padding-left: 0;
  }

  .practice__body,
  .practice__body2 {
    margin-left: 0;
    width: 288px;
  }

  /* Секондарі боді-текст — власний стиль (п.3 ТЗ): DM Sans/13 Light
     Italic (.dm-13-light-italic, tokens.css), не 14px normal, як боді
     вище (пізніше правило в тому самому медіа-запиті, та сама
     специфічність — перебиває .practice__body2 у Кроці 192 вище) */
  .practice__body2 {
    font-size: 13px;
    font-style: italic;
    line-height: 18px;
  }

  /* Відступ боді → перший айтем — 24px (Фікс, замінює попередні 42px) */
  .practice__frames {
    margin-top: 24px;
  }

  /* Відступ останній айтем → іконка star.svg — 40px (Фікс, замінює
     попередні 56px) */
  .practice__body2-icon {
    margin-left: 0;
    margin-top: 40px;
  }

  /* Строук під айтемом — на всю ширину таблички (336px, п.4 ТЗ), а не
     288px контент-боксу: border-bottom (раніше на самому .practice__frame,
     тому обрізаний до 288px) замінено на ::after, що біжить -24px/+24px
     за межі 288px-фрейму — рівно до країв 336px-вікна (padding:20px 24px
     вище), не далі (overflow:hidden на вікні не обрізає). Сам .practice__
     frame (і його текст) лишається на 288px/24px-інсеті — без змін (п.4 ТЗ) */
  .practice__frame {
    position: relative;
    width: 288px;
    border-bottom: none;
  }

  .practice__frame::after {
    content: '';
    position: absolute;
    left: -24px;
    right: -24px;
    bottom: 0;
    height: 1px;
    background-color: var(--grey-15);
  }

  .practice__frame-text {
    margin-left: 0;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
  }

  /* Top/bottom градієнт таблички (п.6 ТЗ) — той самий принцип/елементи,
     що вже на Desktop/Tablet (Landscape/Portrait, styles.css вище,
     @media (min-width:768px)), лише додано для Mobile: JS (is-visible/
     is-hidden, js/services-practices.js) уже керує обома без width-гейту,
     бракувало лише CSS-увімкнення тут */
  .services-hero__practices-window__fade {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    height: 120px;
    pointer-events: none;
    transition: opacity 300ms ease;
  }

  .services-hero__practices-window__fade--top {
    top: 0;
    background: linear-gradient(to bottom, var(--color-background), transparent);
    opacity: 0;
  }

  .services-hero__practices-window__fade--top.is-visible {
    opacity: 1;
  }

  .services-hero__practices-window__fade--bottom {
    bottom: 0;
    background: linear-gradient(to bottom, transparent, var(--color-background));
    opacity: 1;
  }

  .services-hero__practices-window__fade--bottom.is-hidden {
    opacity: 0;
  }

  /* Крок — 112px вільного простору ЗВЕРХУ і 40px ЗНИЗУ (той самий
     прийом, що .offices + .cta--second, index.html): height +152
     (461→613), background-position зсуває фон на 112px вниз,
     padding-top +112 (213→325), щоб позиція тайтла відносно фону
     лишилась незмінною */
  .faq + .cta--second {
    margin-top: 56px;
    height: 613px;
    padding-top: 325px;
    background-position: center 112px;
    background-size: 692px 300px;
  }

  .faq + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Фікс: асиметричний padding-left:101px прибрано — центрується через
     justify-content:center на базовому .hero__btn */
  .faq + .cta--second .cta__btn {
    margin-top: 32px;
    width: 336px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 196: Hero-секція (work.html)

   Хедер — глобальний планшетний компонент (Крок 156), без змін. Сітка
   4×155/16, center, offset 0 (668px), фон/текст лишаються в normal flow
   full-bleed (як десктоп/Tablet Landscape), лише текстовий блок
   вирівнюється центровано в межах в'юпорта тим самим align-items:center,
   що вже задано в .work-hero.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Той самий ассет (image-set 1x/2x), CSS-масштабування до 1440×675
     (пропорція та сама, що в десктопі/Tablet Landscape: 1920:900 =
     1440:675 = 2.133). background-position зсуває фон на 104px вниз від
     верху секції (134px у Tablet Landscape) — center лишається по
     горизонталі. min-height = 104 (зсув) + 675 (висота фону) = 779px,
     той самий принцип, що в десктопі/Tablet Landscape */
  .work-hero {
    min-height: 779px;
  }

  .work-hero__image {
    background-position: center 104px;
    background-size: 1440px 675px;
  }

  /* Тайтл — Tablet/H1 (.dm-36-reg, tokens.css) замість десктопного .dm-h1,
     10px від лейбла (12px у десктопі) */
  .work-hero__title {
    margin-top: 10px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css) замість
     десктопного .dm-desc. margin-top:18px успадковується з десктопу
     без змін (той самий відступ від тайтла) */
  .work-hero__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 197: тайтл "Work" + фрейм пошуку/
   фільтрів + список робіт (work.html)

   Продовження Кроку 196 (Hero-секція). Сітка 4×155/16, center, offset 0
   (668px). Логіка фільтрів/сортування/пошуку/каунтера/empty-стану (JS) —
   без змін. Services/Industries/Sort/пошук лишаються ОДНИМ фреймом (не
   переносяться в окрему панель) — внутрішня верстка цього єдиного фрейму
   визначена нижче, у Кроці 198. Тут — лише структурні речі (заголовок,
   ширина/висота фрейму) і стек карток в один стовпчик (той самий рецепт,
   що Selected Work на index.html, Крок 159).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 302px від низу боді-тексту Hero до тайтла "Work" (304px у десктопі) */
  .work-hero__list-heading {
    margin-top: 302px;
  }

  /* Контейнер звужується до сітки 668px (той самий принцип, що Tablet
     Landscape — 908px): лівий край тексту зсувається до лівого краю сітки */
  .work-hero__list-heading-inner {
    max-width: 668px;
  }

  /* Тайтл — Tablet/H2 (.dm-30-reg, tokens.css) замість десктопного .dm-h2 */
  .work-hero__list-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  /* Каунтер — 6px від тайтла (10px у десктопі). Вирівнювання по верхньому
     краю тайтла успадковане з .work-hero__list-heading-inner
     (align-items:flex-start, той самий принцип, що Tablet Landscape) */
  .work-hero__list-count {
    margin-left: 6px;
  }

  /* Фрейм пошуку/фільтрів — звужується до сітки 668px, висота 52px
     (50px у десктопі). 24px від тайтла/каунтера успадковується з
     десктопу без змін (.work-hero__filters, margin-top:24px) */
  .work-hero__filters-inner {
    max-width: 668px;
  }

  .work-hero__filters-band {
    height: 52px;
  }

  /* Строук 2, пошук і фрейм-іконка фільтрів — уся внутрішня верстка
     єдиного фрейму (vline'и/групи фільтрів/іконка сортування/пошук)
     тепер визначена нижче, у Кроці 198. .work-hero__filters-toggle
     (стара іконка filters.svg, що відкривала окрему панель) тут більше
     не перевизначається — успадковує базовий display:none (styles.css,
     .work-hero__filters-toggle) і лишається прихованою на цьому
     breakpoint'і */

  /* 56px від низу фрейму пошуку/фільтрів до верху ПЕРШОГО айтема (Hermes),
     той самий рецепт, що Selected Work на index.html (Крок 159): display:
     contents "розкриває" обгортки рядів (.work-hero__row--1/--3,
     .selected-work__col-secondary, .selected-work__row2, спільні з
     index.html — тому скоуплені під .work-hero), картки стають прямими
     flex-дітьми .work-hero (уже flex-direction:column, align-items:center)
     у справжньому DOM-порядку: Hermes→Obviant→Clair→Aurelia→Transcarent */
  .work-hero__row--1,
  .work-hero__row--3,
  .work-hero .selected-work__col-secondary,
  .work-hero .selected-work__row2 {
    display: contents;
  }

  /* Без патернів-заповнювачів (той самий принцип, що Крок 159, п.5) */
  .work-hero .selected-work__strokes,
  .work-hero .selected-work__pattern {
    display: none;
  }

  /* Кожна картка — на всю ширину сітки (668px). Специфічність двох класів
     (.work-hero + .work-card--primary/--secondary) вища за десктопні
     однокласові правила */
  .work-hero .work-card--primary,
  .work-hero .work-card--secondary {
    width: 668px;
  }

  /* 56px від низу фрейму пошуку/фільтрів до верху першого айтема (Hermes).
     Раніше тут ще був transition:margin-top — потрібен був лише поки
     існувала окрема панель фільтрів (Крок 198, :has()-правило змінювало
     цей margin-top при відкритті). Без другого фрейму margin-top більше
     ніколи не змінюється динамічно, тому transition прибраний разом із
     самою логікою показу/ховання панелі */
  .work-hero .work-card--primary {
    margin-top: 56px;
  }

  /* 44px між усіма рештою айтемів (Obviant→Clair→Aurelia→Transcarent) */
  .work-hero .work-card--secondary {
    margin-top: 44px;
  }

  /* Transcarent (Ряд 3) — теж --primary, але НЕ перший айтем: 44px, як і
     решта (56px вище стосується лише Hermes) — вища специфічність
     (.work-hero__row--3 .work-card--primary) перебиває загальне
     .work-hero .work-card--primary */
  .work-hero__row--3 .work-card--primary {
    margin-top: 44px;
  }

  /* Фото — власний оригінальний aspect-ratio кожного типу айтема (720:564
     великого/primary, 424:332 малого/secondary), а не фіксована px-висота —
     той самий прийом, що Крок 159, п.6 */
  .work-hero .work-card--primary .work-card__image {
    aspect-ratio: 720 / 564;
    height: auto;
  }

  .work-hero .work-card--secondary .work-card__image {
    aspect-ratio: 424 / 332;
    height: auto;
  }

  /* CTA-2 — вже готова реалізація (Крок 163), скоуп через сусідній
     селектор .work-hero + .cta--second (той самий прийом, що .offices +
     .cta--second/.about-offices + .cta--second). 80px від низу останнього
     айтема робіт (Transcarent) до верху фону CTA-2. Footer — сайт-вайд,
     без різниці між сторінками (Крок 164), тому окремого правила тут не
     потрібно */
  .work-hero + .cta--second {
    margin-top: 80px;
    /* Фікс: 362/100px — той самий готовий блок, що .offices/.about-offices/
       .faq + .cta--second (index/about/services.html) */
    height: 628px;
    padding-top: 362px;
    background-size: 1440px 624px;
  }

  .work-hero + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Фікс: тайтл→кнопка — 32px, той самий готовий блок, що .offices +
     .cta--second .cta__btn (index.html) */
  .work-hero + .cta--second .cta__btn {
    margin-top: 32px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 198 (перероблено): Services/
   Industries/Sort/пошук — ОДИН фрейм, без окремої панелі (work.html)

   Раніше (Крок 198) Services/Industries/Sort розкривались нижче в окремій
   панелі по кліку на іконку filters.svg. Тепер цей другий фрейм і вся
   його логіка показу/ховання прибрані повністю — усе лишається в ОДНОМУ
   .work-hero__filters-band, лише переставлене зліва направо: All Services
   → vline1 → All Industries → vline3 (новий) → іконка сортування → vline2
   → пошук. .work-hero__filters-panel і .work-hero__filters-band стають
   flex-рядками (замість absolute-координат 1164px-сітки/display:contents),
   тому порядок/відступи керуються DOM-порядком + margin, а не px-offset'ами
   — той самий прийом, що вже був у старій панелі (Крок 198), просто тепер
   застосований до єдиного фрейму. Дропдаун-логіка самих трьох фільтрів
   (відкриття/закриття, viewport-aware позиціонування, вибір пункту,
   застосування до списку робіт) — та сама функція positionDropdownPanel
   і той самий обробник кліків, що на Tablet Landscape/десктопі, жодних
   змін у JS-логіці фільтрації/сортування/пошуку. .work-hero__filters-toggle
   (стара іконка-тригер) більше ніде в цьому breakpoint'і не показується.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Band — тепер flex-рядок (замість самого лише position:relative для
     absolute-дітей): усі прямі діти (.work-hero__filters-panel/
     .work-hero__filters-vline--2/.work-hero__filters-search) шикуються
     зліва направо в DOM-порядку, вертикально центровані на всю висоту
     52px */
  .work-hero__filters-band {
    display: flex;
    align-items: center;
  }

  /* Панель (обгортка Services/vline1/Industries/vline3/Sort у розмітці) —
     теж flex-рядок замість display:contents, на всю висоту фрейму. Більше
     НЕ окремий блок, що розкривається нижче — звичайний перший flex-item
     .work-hero__filters-band, починається рівно з лівого краю сітки */
  .work-hero__filters-panel {
    display: flex;
    align-items: center;
    height: 100%;
  }

  /* Скидає десктопні absolute-координати (left/top/right у px, прив'язані
     до 1164px-сітки) — усередині панелі всі три групи стають звичайними
     flex-дітьми (порядок і відступи через margin, а не px-координати).
     Фікс: flex-shrink:0 — без цього поява іконки clear у пошуку (справа
     в рядку) переповнювала 668px-фрейм на 1px, і flex-алгоритм стискав
     НАЙБЛИЖЧий "стискний" елемент (vline2, 1px→0px, Фікс нижче) замість
     того, щоб просто вийти за межі фрейму */
  .work-hero__filters-panel .work-hero__filter-group {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    height: 100%;
    flex-shrink: 0;
  }

  /* Фікс: без цього group.width = ширина ПОТОЧНОГО тексту (Consulting/
     Audit/Brand/...), тому вибір коротшого пункту зсував vline1 і все,
     що йде далі, ліворуч (текст+іконка — flex-пара з gap:8px, іконка й
     так завжди рівно 8px від тексту незалежно від min-width — це не
     чіпаємо). min-width = ширина НАЙДОВШОГО пункту переліку ("ALL
     SERVICES", .rh-11-bold 11px, виміряно рендером: 106.5px, +0.5px
     запас на субпіксельне округлення), тому group.width однаковий для
     БУДЬ-ЯКого вибраного пункту (для найдовшого — точно дорівнює
     контенту, для решти — min-width форсує box ширшим за контент,
     лишаючи порожній хвіст після іконки замість зсуву vline1) */
  .work-hero__filter-group--services {
    min-width: 107px;
  }

  /* Той самий фікс, найдовший пункт — "ALL INDUSTRIES" (119.28px
     виміряно, +0.7px запас) */
  .work-hero__filter-group--industries {
    min-width: 120px;
  }

  /* Строук після Services — 38px від іконки дропдауна Services
     (margin-left), 16px до тексту Industries (margin-right на самому
     строуку) — той самий "margin, не px-координата" прийом, що в старій
     панелі, нові відступи за ТЗ */
  .work-hero__filters-vline--1 {
    position: static;
    flex-shrink: 0;
    margin-left: 38px;
    margin-right: 16px;
  }

  /* Строук після Industries, перед іконкою сортування — новий елемент
     (work.html), яких раніше в цьому фреймі не було (на десктопі/Tablet
     Landscape між Industries і Sort окремого строука немає). Стилі лише
     тут: сам клас більше ніде не використовується, тому без базового
     unconditional-правила — flex-item блокується автоматично (flex
     children завжди block-level, навіть <span>), width/height
     застосовуються без явного display:block */
  .work-hero__filters-vline--3 {
    width: 1px;
    height: 100%;
    background-color: var(--grey-15);
    flex-shrink: 0;
    margin-left: 25px;
    margin-right: 16px;
  }

  /* Sort — більше НЕ притискається до правого краю (margin-left:auto) і
     НЕ звужується до окремого 53×52px фрейму з border-left — тепер
     звичайний flex-item панелі одразу після vline3, розділювачі — самі
     vline-елементи (vline3 зліва, vline2 справа), не бордер. Лейбл
     "Sort by:"/значення "Date"/стрілка лишаються прихованими, показана
     лише іконка Sort.svg — та сама заміна, що вже була */
  .work-hero__filter-group--sort [data-sort-static-label],
  .work-hero__filter-group--sort .work-hero__filter-value,
  .work-hero__filter-group--sort .work-hero__filter-arrow {
    display: none;
  }

  .work-hero__filter-sort-icon {
    display: block;
  }

  /* Фікс: активний колір іконки сортування, поки дропдаун відкритий —
     .is-open вже додає/знімає JS (work-filters.js, той самий клас, що й
     Services/Industries). Іконка — <img> з жорстко зашитим stroke="#7E7E7E"
     (grey-50) у самому SVG-файлі (не currentColor), тому перефарбування
     через CSS filter: brightness() — той самий прийом і той самий
     множник, що вже використаний для цієї ж іконки на Mobile (styles.css,
     .work-hero__filter-group--sort.is-open .work-hero__filter-sort-icon):
     238/126 = 1.889 (grey-50 → grey-100) */
  .work-hero__filter-group--sort.is-open .work-hero__filter-sort-icon {
    filter: brightness(1.889);
  }

  /* Фікс: дропдаун сортування — лівий край БОКСА (не тексту) збігається
     з лівим краєм строука зліва від іконки сортування (vline3, між
     Industries і Sort), а не з іконкою. vline3 — margin-right:16px +
     власна ширина 1px = 17px ліворуч від іконки, тому left:-17px
     відносно .work-hero__filter-group--sort (position:relative, left
     його власного боксу = лівий край іконки, група щільно обгортає
     лише її) */
  .work-hero__filter-group--sort .work-hero__filter-dropdown {
    left: -17px;
    right: auto;
  }

  /* Строук після іконки сортування, перед пошуком — той самий елемент,
     що на десктопі розділяв Sort/Search (там — absolute, тут просто
     скидається в static і отримує ті самі margin-відступи, що решта
     vline'ів фрейму: 66px від іконки сортування, 20px до іконки пошуку).
     Прямий child .work-hero__filters-band (не .work-hero__filters-panel) —
     другий flex-item рядка, одразу після панелі. flex-shrink:0 — той
     самий фікс, що на vline1/vline3/групах фільтрів (Фікс вище) */
  .work-hero__filters-vline--2 {
    position: static;
    flex-shrink: 0;
    margin-left: 66px;
    margin-right: 20px;
  }

  /* Пошук — більше не absolute (left:888px/right:0 у десктопі, або
     left:0/right:53px у старій верстці), а звичайний flex-item, третій і
     останній у .work-hero__filters-band, одразу після vline2. Іконка/
     input/clear (кольори, gap:6px, ширина 200px, поведінка clear) — усі
     без змін, успадковані з базового .work-hero__filters-search.
     Фікс: flex-shrink:0 — без цього поява іконки clear (при введенні
     тексту в пошук) стискала цей блок і зсувала суму (icon+input) на
     кілька px ліворуч замість того, щоб просто дати блоку розширитись
     праворуч (жоден інший елемент фрейму цим не зачіпається) */
  .work-hero__filters-search {
    position: static;
    flex-shrink: 0;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 199: empty-стан (work.html)

   Ілюстрація — ТОЙ САМИЙ файл, що на десктопі (empty.webp/@2x, не
   окремий Tablet Portrait-файл), лише CSS-масштабований до 764×480
   (пропорція 868:545 = 764:480 збережена, без спотворення). 56px до
   ілюстрації; текстовий блок — 420px від фільтрів = top:364px (420−56)
   усередині .work-empty, left:132px від початку сітки (ліворуч,
   align-items:flex-start успадковується з бази).
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  /* 56px від низу фрейму пошуку/фільтрів до верху ілюстрації. Раніше тут
     ще був transition:margin-top — потрібен був лише поки існувала окрема
     панель фільтрів (Крок 198, :has()-правило змінювало цей margin-top
     при відкритті). Без другого фрейму margin-top більше ніколи не
     змінюється динамічно, тому transition прибраний разом із самою
     логікою показу/ховання панелі */
  .work-empty {
    width: 668px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 56px;
    height: 506px;
  }

  /* Той самий файл empty.webp/@2x, що на десктопі — лише зменшений
     розмір (868×545 → 764×480, той самий 868:545 ratio). Фікс: left:
     -48px (замість успадкованого десктопного 148px) — ілюстрація
     (764px) ширша за сітку (668px), тому центрується відносно сітки з
     рівномірним виходом за межі: (764 − 668) / 2 = 48px з кожного боку,
     без обрізання */
  .work-empty__bg {
    left: -48px;
    width: 764px;
    height: 480px;
  }

  .work-empty__image {
    background-size: 764px 480px;
  }

  /* 420px від фільтрів до текстового блоку = 364px усередині .work-empty
     (420 − 56), left:132px від початку сітки */
  .work-empty__content {
    top: 364px;
    left: 132px;
  }

  /* Боді-текст — DM Sans/16 Light (.dm-16-light, tokens.css), той самий
     рецепт, що Tablet Landscape, замість десктопного .dm-17-light */
  .work-empty__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 200 + фікс: Header — фрейм кнопки
   меню (hover/активний стани) + меню-оверлей (глобально, всі сторінки)

   .mobile-menu — та сама розмітка/елемент, що вже перевикористовує Mobile
   (Крок 185): один спільний DOM-вузол на всіх 5 сторінках, header.js тепер
   гейтить клік через matchMedia(max-width:1023px) замість лише 767px
   (Крок 200, js/header.js). Увесь вигляд тут — з нуля (жоден Mobile-
   рецепт не успадковується автоматично, бо той увесь визначений усередині
   ВЛАСНОГО @media (max-width:767px)), лише СТРУКТУРА/ЛОГІКА (текст+номер,
   6px, top-align, is-active/номер) свідомо повторює Mobile — стилі (шрифти,
   позиція) свої, за завданням.

   На відміну від Mobile тут немає ні CTA "Contact" у оверлеї, ні
   спейсерів-проекцій — навігація просто center/center у флекс-контейнері
   на весь в'юпорт.

   Фікс: кнопка меню тепер сама по собі 48×48-фрейм зі своїми border'ами
   (styles вище, у блоці Крок 157/200) — окремий ::before-хак для фону
   активного стану більше не потрібен (раніше компенсував те, що кнопка
   була розміром лише під іконку, 22×22); тепер background-color просто
   на самій кнопці, як і на hover. Іконка закритого стану — x-mark.svg,
   22×22 (той самий розмір, що іконка "menu"). Оверлей отримав
   fade+translateY transition замість миттєвого display:none↔flex. */

@media (min-width: 768px) and (max-width: 1023px) {

  /* Активний (відкритий) стан — той самий фон, що на hover (grey-15),
     але постійний, доки меню відкрите; :hover продовжує діяти незалежно
     (візуально однаковий колір, конфлікту немає) */
  .header--menu-open .header__menu-btn {
    background-color: var(--grey-15);
  }

  /* Оверлей завжди в DOM/лейауті в цьому breakpoint'і (display:flex,
     не display:none — інакше transition на opacity/transform не
     запуститься), закритий стан — invisible/non-interactive
     (opacity:0, pointer-events:none, visibility:hidden з затримкою,
     щоб фокус/клік не потрапляли в приховані посилання). Легкий
     translateY(-12px)→0 + fade, 300ms var(--ease-smooth) (той самий
     easing, що scroll-reveal) — симетрично для появи й закриття,
     visibility перемикається миттєво при відкритті й із затримкою
     (transition-delay) при закритті, після завершення fade-out */
  .mobile-menu {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: 90;
    background: var(--color-background);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-12px);
    transition: opacity 300ms var(--ease-smooth),
                transform 300ms var(--ease-smooth),
                visibility 0s 300ms;
  }

  .mobile-menu.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
    transition: opacity 300ms var(--ease-smooth),
                transform 300ms var(--ease-smooth);
  }

  /* Спейсери й CTA "Contact" тут не використовуються (за завданням) —
     навігація сама по собі центрована батьківським флексом вище */
  .mobile-menu__spacer--top,
  .mobile-menu__spacer--bottom,
  .mobile-menu__cta {
    display: none;
  }

  .mobile-menu__list {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    list-style: none;
  }

  /* Фікс: фрейм фіксованого розміру на айтем (не content-driven, як
     раніше) — заміняє попередній flex(gap:6px)-підхід, де показ/приховування
     номера через display:none/block змінювало ШИРИНУ айтема (номер не
     займав місця, коли прихований), а align-items:center на списку вище
     тоді центрував кожен айтем по-різному залежно від того, активна
     сторінка чи ні — текст візуально "стрибав" між станами. Тепер: текст
     і номер — absolute всередині фрейму фіксованого розміру (per-item
     width, .mobile-menu__link--home/--work/--services/--about нижче),
     тому позиція тексту (left:21px) і зарезервоване місце під номер
     незмінні незалежно від active/inactive */
  .mobile-menu__link {
    display: block;
    position: relative;
    height: 48px;
    color: var(--grey-50);
    text-decoration: none;
  }

  /* Текст — Tablet/H2 (.dm-30-reg, tokens.css) замість мобільного
     .dm-24-reg, 21px від лівого краю фрейму, top-align (top:0) */
  .mobile-menu__text {
    position: absolute;
    left: 21px;
    top: 0;
    white-space: nowrap;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  .mobile-menu__link.is-active {
    color: var(--grey-100);
  }

  /* Ховер айтема — grey-60, лише для НЕактивної сторінки (:not(.is-active),
     активна лишається grey-100 навіть при наведенні) */
  .mobile-menu__link:hover:not(.is-active) {
    color: var(--grey-60);
  }

  /* Номер — Red Hat/12 Bold (tracking) (.rh-12-bold-track, tokens.css),
     top-align (top:0), right — per-item нижче. Рендериться завжди
     (opacity:0/visibility:hidden для
     неактивної сторінки, а не display:none) — місце під нього
     зарезервоване у фреймі завжди, тому текст не зсувається; колір
     успадковує .mobile-menu__link(.is-active) без окремого правила */
  .mobile-menu__num {
    position: absolute;
    top: 0;
    opacity: 0;
    visibility: hidden;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 12px;
    line-height: 20px;
    letter-spacing: 0.13em;
  }

  .mobile-menu__link.is-active .mobile-menu__num {
    opacity: 1;
    visibility: visible;
  }

  /* Фіксовані розміри фреймів + відступ номера від правого краю —
     точні значення з дизайну (текст 21px зліва + gap 6px до номера +
     номер + right-відступ = ширина фрейму, для кожного айтема окремо,
     бо ширина тексту різна) */
  .mobile-menu__link--home {
    width: 124px;
  }

  .mobile-menu__link--home .mobile-menu__num {
    right: 7px;
  }

  .mobile-menu__link--work {
    width: 114px;
  }

  .mobile-menu__link--work .mobile-menu__num {
    right: 1px;
  }

  .mobile-menu__link--services {
    width: 162px;
  }

  .mobile-menu__link--services .mobile-menu__num {
    right: 0;
  }

  .mobile-menu__link--about {
    width: 130px;
  }

  .mobile-menu__link--about .mobile-menu__num {
    right: 0;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 201 (перероблено): структура списку робіт +
   пошук/фільтри — ДВА ЗАВЖДИ ВИДИМІ фрейми (work.html)

   Раніше (Крок 201/203/205-фікс) фільтри/сортування ховались в окремій
   панелі, що розкривалась по кліку на іконку filters.svg (той самий
   принцип, що мав Tablet Portrait до свого рефакторингу). Тепер — два
   ЗАВЖДИ видимі фрейми один під одним (0px між ними), той самий
   "display:contents/flex + .is-open" механізм більше не використовується
   на ЖОДНОМУ breakpoint'і (TP вже прибрав його раніше) — сама іконка
   filters.svg (.work-hero__filters-toggle) відтепер ніде не показується,
   ХТО зберігає HTML/JS: .work-hero__filters-toggle/-panel лишаються в
   розмітці (мертві на всіх активних breakpoint'ах), клас .is-open і сама
   кнопка просто ніколи більше не отримують стилів показу.

   1. Список робіт — той самий "display:contents на обгортках" прийом, що
      Selected Work на index.html (Крок 179): усі 5 карток стають прямими
      flex-дітьми .work-hero, однакового розміру (336px), один під одним.

   2. Фрейм 1 (пошук) — .work-hero__filters-search, тепер САМОДОСТАТНІЙ
      бокс на всю ширину сітки (336px, 52px висоти, власні border-top/
      -bottom), а не частина спільного рядка з іконкою-тригером. order:-1
      у flex-column .work-hero__filters-band ставить його візуально ПЕРШИМ
      (у DOM він і далі йде ПІСЛЯ .work-hero__filters-panel, як на решті
      breakpoint'ів — не чіпаємо спільну розмітку, лише порядок рендеру).

   3. Фрейм 2 (Services/Industries/Sort) — .work-hero__filters-panel,
      теж самодостатній бокс (336px, 52px, власні border-top/-bottom),
      більше не absolute/opacity-керована панель. Внутрішня структура —
      та сама, що вже була в старій "розкривній" версії (vline 22/20px,
      gap лейбл→іконка 8px, фрейм сортування 53×52px з border-left) —
      ці числа НЕ змінювались, лише спосіб показу (завжди, не по кліку).

   4. Фіксовані позиції (Фікс, той самий принцип, що вже реалізований на
      Tablet Portrait): .work-hero__filter-group--services/--industries
      отримують min-width під найдовший можливий пункт переліку — інакше
      вибір коротшого варіанту зсував би vline1/фрейм сортування ліворуч.

   5. JS-логіка — без змін: js/work-filters.js не має жодного matchMedia-
      гейту, дропдаун-логіка (viewport-aware позиціонування, вибір пункту,
      застосування до списку робіт) — та сама функція positionDropdownPanel
      і той самий обробник кліків, що на решті breakpoint'ів.
   ========================================================================== */

@media (max-width: 767px) {

  /* 346px від низу боді-тексту Hero до тайтла "Work" (Крок 202, п.4 ТЗ —
     точне значення, замінює попереднє наближення 64px) */
  .work-hero__list-heading {
    margin-top: 346px;
  }

  .work-hero__list-heading-inner {
    max-width: 336px;
  }

  /* Тайтл — Mob/H2 (.dm-24-reg), той самий рецепт, що
     .selected-work__title на index.html (Крок 179) */
  .work-hero__list-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 130%;
    letter-spacing: 0em;
  }

  .work-hero__list-count {
    margin-left: 6px;
  }

  /* 20px від низу тайтла "Work"/каунтера до верху фрейму пошуку/фільтрів
     (24px база/Tablet Portrait) — Крок 203, п.1 ТЗ */
  .work-hero__filters {
    margin-top: 20px;
  }

  /* Фрейм пошуку/фільтрів — звужується до сітки 336px, той самий
     52px, що Tablet Portrait */
  .work-hero__filters-inner {
    max-width: 336px;
  }

  /* Band — flex-column: два самодостатні фрейми (пошук, фільтри/сортування)
     стають прямими flex-дітьми, стековані вертикально, 0px між ними
     (order нижче ставить пошук першим візуально). height:auto замість
     фіксованого 52px — фактична висота тепер природна сума двох 52px-боксів
     (104px), кожен зі своїм border-top/-bottom (нижче) */
  .work-hero__filters-band {
    display: flex;
    flex-direction: column;
    height: auto;
  }

  /* Спільні верхній/нижній строуки більше не потрібні — кожен із двох
     фреймів нижче має ВЛАСНІ border-top/-bottom (де вони стикаються,
     border фрейму 1 і border фрейму 2 просто збігаються в одну лінію) */
  .work-hero__filters-line--top,
  .work-hero__filters-line--bottom {
    display: none;
  }

  /* Строук 2 (десктопний розділювач Sort/Search) не потрібен — на Mobile
     пошук більше не сусід Sort у спільному рядку (окремий Фрейм 1) */
  .work-hero__filters-vline--2 {
    display: none;
  }

  /* ФРЕЙМ 1 — лише пошук: самодостатній бокс 336×52px. order:-1
     переносить його візуально ПЕРШИМ у flex-column (DOM-порядок — той
     самий, що на решті breakpoint'ів, не чіпаємо). gap:4px/padding-
     right:10px — та сама позиція/стиль пошуку, що вже була на цьому
     breakpoint'і (Крок 203, п.2 ТЗ), лише position:static замість
     absolute (більше нема сусіда-іконки праворуч, що обмежував ширину).
     Фікс: лише border-top — нижній строук прибраний, бо 0px нижче йде
     Фрейм 2 (.work-hero__filters-panel) з ВЛАСНИМ border-top, тому
     другий border-bottom тут був зайвим (дублював той самий рядок) */
  .work-hero__filters-search {
    position: static;
    order: -1;
    width: 336px;
    height: 52px;
    box-sizing: border-box;
    flex-shrink: 0;
    border-top: 1px solid var(--grey-15);
    gap: 4px;
    padding-right: 10px;
  }

  /* ФРЕЙМ 2 — Services/Industries/Sort: теж самодостатній бокс 336×52px,
     власні border-top/-bottom (замінюють колишні opacity/position:absolute/
     transition — фрейм тепер завжди в потоці, завжди видимий). Внутрішня
     верстка (vline 22/20px, gap 8px, фрейм сортування 53×52px) — та сама,
     що в старій "розкривній" версії, не змінена */
  .work-hero__filters-panel {
    display: flex;
    align-items: center;
    width: 336px;
    height: 52px;
    box-sizing: border-box;
    flex-shrink: 0;
    border-top: 1px solid var(--grey-15);
    border-bottom: 1px solid var(--grey-15);
  }

  /* Скидає десктопні absolute-координати — усередині фрейму 2 всі три
     групи стають звичайними flex-дітьми. flex-shrink:0 — той самий фікс,
     що вже застосований на Tablet Portrait (без нього довший текст міг
     би стискати сусідні елементи замість фіксованих позицій, п.3 ТЗ) */
  .work-hero__filters-panel .work-hero__filter-group {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    height: 100%;
    flex-shrink: 0;
  }

  /* Текст "All Services"/"All Industries" → іконка-стрілка: 8px, той
     самий gap, що база .work-hero__filter */
  .work-hero__filters-panel .work-hero__filter {
    gap: 8px;
  }

  /* Фікс: без цього group.width = ширина ПОТОЧНОГО тексту, тому вибір
     коротшого пункту зсував би vline1/фрейм сортування ліворуч (той
     самий фікс, що вже реалізований на Tablet Portrait). min-width —
     ширина НАЙДОВШОГО пункту переліку (той самий .rh-11-bold 11px шрифт,
     що на Tablet Portrait — виміряні значення ідентичні: "ALL SERVICES"
     106.5px, "ALL INDUSTRIES" 119.28px, +трохи запасу) */
  .work-hero__filter-group--services {
    min-width: 107px;
  }

  .work-hero__filter-group--industries {
    min-width: 120px;
  }

  /* Строук між Services і Industries — 22px від стрілки Services, 20px
     до тексту Industries */
  .work-hero__filters-vline--1 {
    position: static;
    flex-shrink: 0;
    margin-left: 22px;
    margin-right: 20px;
  }

  /* Sort — фрейм 53×52px у самому кінці (margin-left:auto притискає його
     до правого краю Фрейму 2, який дорівнює правому краю сітки, 336px) —
     border-left замінює vline, іконка Sort.svg 20×20 з відступом 15px
     від правого краю */
  .work-hero__filter-group--sort {
    margin-left: auto;
    width: 53px;
    flex-shrink: 0;
    border-left: 1px solid var(--grey-15);
  }

  .work-hero__filter-group--sort [data-sort-static-label],
  .work-hero__filter-group--sort .work-hero__filter-value,
  .work-hero__filter-group--sort .work-hero__filter-arrow {
    display: none;
  }

  .work-hero__filter--sort {
    width: 100%;
    height: 100%;
    justify-content: flex-end;
    padding-right: 15px;
  }

  .work-hero__filter-sort-icon {
    display: block;
  }

  /* Дропдаун сортування — вирівнюється по ПРАВОМУ краю сітки (336px):
     .work-hero__filter-group--sort сам вже впритул до правого краю
     Фрейму 2 (margin-left:auto, п.2 ТЗ), тому right:0 відносно групи
     автоматично дає right:336px відносно сітки — саме те, що вимагає
     п.5 ТЗ (на відміну від Tablet Portrait, де Sort посеред рядка і
     дропдаун вирівнюється по строуку зліва від іконки, не по сітці) */
  .work-hero__filter-group--sort .work-hero__filter-dropdown {
    left: auto;
    right: 0;
  }

  /* Активний стан фрейму сортування, поки відкритий його власний
     дропдаун: ЛИШЕ іконка Sort.svg перефарбовується у grey-100 (фон
     фрейму НЕ змінюється — Фікс, work.html Mobile). Іконка — <img> з
     жорстко зашитим stroke="#7E7E7E" (grey-50) у самому SVG-файлі (не
     currentColor), тому перефарбування через CSS filter: brightness() —
     множник 238/126 = 1.889 (grey-50 → grey-100) */
  .work-hero__filter-group--sort.is-open .work-hero__filter-sort-icon {
    filter: brightness(1.889);
  }

  /* Список робіт — той самий "display:contents на обгортках" прийом, що
     Tablet Portrait/Selected Work Mobile (Крок 179): картки стають
     прямими flex-дітьми .work-hero у справжньому DOM-порядку */
  .work-hero__row--1,
  .work-hero__row--3,
  .work-hero .selected-work__col-secondary,
  .work-hero .selected-work__row2 {
    display: contents;
  }

  /* Без патернів-заповнювачів (той самий принцип, що Крок 179, п.4) */
  .work-hero .selected-work__strokes,
  .work-hero .selected-work__pattern {
    display: none;
  }

  /* Кожна картка — на всю ширину сітки (336px) */
  .work-hero .work-card--primary,
  .work-hero .work-card--secondary {
    width: 336px;
  }

  /* 32px від низу фрейму 2 (фільтри/сортування) до верху першого айтема
     (Hermes) — той самий орієнтир, що Selected Work Mobile (Крок 179).
     Раніше тут ще був transition:margin-top — потрібен був лише поки
     існувала окрема панель, що розкривалась (:has()-правило нижче
     міняло цей margin-top при відкритті). Без другого фрейму, що
     ховається, margin-top більше ніколи не змінюється динамічно, тому
     transition прибраний разом із самою логікою показу/ховання панелі */
  .work-hero .work-card--primary {
    margin-top: 32px;
  }

  /* 24px між рештою айтемів (Obviant→Clair→Aurelia→Transcarent) — той
     самий орієнтир, що Selected Work Mobile (Крок 179) */
  .work-hero .work-card--secondary {
    margin-top: 24px;
  }

  /* Transcarent (Ряд 3) — теж --primary, але не перший айтем: 24px, як
     і решта (вища специфічність перебиває загальне правило вище) */
  .work-hero__row--3 .work-card--primary {
    margin-top: 24px;
  }

  /* Фото — власний оригінальний aspect-ratio кожного типу айтема, а не
     фіксована px-висота — той самий прийом, що Tablet Portrait/Крок 179 */
  .work-hero .work-card--primary .work-card__image {
    aspect-ratio: 720 / 564;
    height: auto;
  }

  .work-hero .work-card--secondary .work-card__image {
    aspect-ratio: 424 / 332;
    height: auto;
  }

  /* Фікс: боді-текст айтема — DM Sans/14 Light (.dm-14-light) замість
     успадкованого .dm-16-light з розмітки — той самий стиль, що вже
     застосований до .work-card__body на index.html (Selected Work
     Mobile, Крок 179), тут раніше не було відповідного перевизначення */
  .work-hero .work-card__body {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

}

/* ==========================================================================
   MOBILE (375–767px) — Крок 202: Hero-секція (work.html)

   На відміну від about-hero/services-hero (Крок 186/191, які просто
   масштабують ДЕСКТОПНИЙ ассет через background-size:auto), тут — окремий
   мобільний файл (work-bg-mobile.webp/@2x, 1000×469) через image-set,
   fixed background-size:1000px 469px (без auto) — за прямою вказівкою ТЗ.
   Текстовий блок — той самий стиль/відступи, що інші Mobile Hero
   (Крок 177/186/191): тайтл .dm-28-reg (mob/H1), 8px від лейбла;
   боді-текст DM Sans/14 Light (.dm-14-light), 16px від тайтла, ширина
   336px (сітка). padding-top на .work-hero — 174px (фіксовано, той
   самий принцип, що about.html/services.html) замість десктопних 170px.
   Лейбл/тайтл-контент (HTML) — без змін, лише перестилюємо.
   ========================================================================== */

@media (max-width: 767px) {

  .work-hero {
    padding-top: 174px;
  }

  .work-hero__image {
    background-position: center 251px;
    background-size: 1000px 469px;
    background-image: url("../assets/images/work-bg-mobile.webp");
    background-image: image-set(
      url("../assets/images/work-bg-mobile.webp") 1x,
      url("../assets/images/work-bg-mobile@2x.webp") 2x
    );
  }

  .work-hero__title {
    margin-top: 8px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  .work-hero__desc {
    margin-top: 16px;
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 204: секція CTA-2 + Footer (work.html)

   .cta--second перевикористовується на index/about/services/work.html —
   скоуп через суміжний селектор .work-hero + .cta--second, той самий
   прийом, що вже застосований на index.html (.offices + .cta--second,
   Крок 183) і services.html (.faq + .cta--second, Крок 193): 56px від
   низу останнього айтема робіт (або empty-стану) до верху фону CTA-2,
   фон 692×300 (fixed, успадкований, не перевизначається), висота секції
   461px (300 фону + 161 вільного простору), тайтл Mob/H1 (.dm-28-reg).
   Кнопка work.html несе просто "BOOK A CONSULTATION" (немає --desktop/
   --mobile label-спанів у розмітці, той самий принцип, що about.html/
   services.html) — без label-swap правил, той самий набір значень
   (32/336/101), що index.html.

   Footer — сайт-вайд (Крок 184 + всі фікси), .footer__* класи однакові
   на всіх сторінках (звичайні селектори, без adjacent-sibling) — уже
   застосовується тут автоматично, без додаткових правил.
   ========================================================================== */

@media (max-width: 767px) {

  /* Крок — 112px вільного простору ЗВЕРХУ і 40px ЗНИЗУ (той самий
     прийом, що .offices + .cta--second, index.html): height +152
     (461→613), background-position зсуває фон на 112px вниз,
     padding-top +112 (213→325), щоб позиція тайтла відносно фону
     лишилась незмінною */
  .work-hero + .cta--second {
    margin-top: 56px;
    height: 613px;
    padding-top: 325px;
    background-position: center 112px;
    background-size: 692px 300px;
  }

  .work-hero + .cta--second .cta__line {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* Фікс: асиметричний padding-left:101px прибрано — центрується через
     justify-content:center на базовому .hero__btn */
  .work-hero + .cta--second .cta__btn {
    margin-top: 32px;
    width: 336px;
  }
}

/* ==========================================================================
   MOBILE (≤767px) — Крок 205: empty-стан (work.html)

   Сітка 336px (4×72+3×16), center, offset 0. Ілюстрація (550×226,
   empty-mobile.webp/@2x) ширша за сітку — центрується відносно неї,
   вихід за межі порівну з обох боків: (550−336)/2=107px, left:-107px
   відносно .work-empty. 92px від фрейму пошуку/фільтрів до ілюстрації —
   margin-top на .work-empty (той самий принцип, що десктоп/tablet).
   Текстовий блок — 0px gap від низу ілюстрації (тайтл/боді/кнопка одразу
   під ілюстрацією), left:0 (на відміну від десктопу/tablet, де текст
   зсунутий праворуч від ілюстрації — тут вони вертикально складені).
   14px тайтл→боді, 32px боді→кнопка — уже базові значення
   .work-empty__desc/__btn margin-top, тут не перевизначаються. Кнопка —
   .secondary-button (глобальні стейти вже застосовуються, окремого
   перевизначення тут не потрібно), ширина лишається базовою 166px.
   height .work-empty — виміряно рендером під реальний контент (той самий
   принцип, що десктоп/tablet: 226 ілюстрація + тайтл + 14 + боді(2 рядки)
   + 32 + 48 кнопка) */
@media (max-width: 767px) {

  /* Раніше тут ще був transition:margin-top — потрібен був лише поки
     існувала окрема панель фільтрів, що розкривалась (:has()-правило
     міняло цей margin-top при відкритті). Без другого фрейму, що
     ховається, margin-top більше ніколи не змінюється динамічно, тому
     transition прибраний разом із самою логікою показу/ховання панелі */
  .work-empty {
    width: 336px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 92px;
    height: 428px;
  }

  .work-empty__bg {
    left: -107px;
    width: 550px;
    height: 226px;
  }

  .work-empty__image {
    background-size: 550px 226px;
    background-image: url("../assets/images/empty-mobile.webp");
    background-image: image-set(
      url("../assets/images/empty-mobile.webp") 1x,
      url("../assets/images/empty-mobile@2x.webp") 2x
    );
  }

  .work-empty__content {
    top: 226px;
    left: 0;
  }

  .work-empty__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 20px;
    line-height: 28px;
    letter-spacing: 0.02em;
  }

  .work-empty__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .work-empty__desc-break--mobile {
    display: inline;
  }

}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 208: Hero-фон (contact.html)

   Той самий ассет (image-set 1x/2x contact-bg-desktop.webp/@2x.webp), лише
   CSS-масштабування — той самий принцип "fixed, no scale", що вже
   застосований до інших Hero-фонів сайту. Розмір і зсув ідентичні Tablet
   Landscape (Крок 155): 1440×810, 0px від верху секції — на цьому кроці
   міняється лише фон, контент Hero (тайтл/форма/etc.) під планшет-портрет
   ще не адаптований.
   ========================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-hero {
    min-height: 810px;
  }

  .contact-hero__image {
    background-position: center top;
    background-size: 1440px 810px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — Крок 208: Hero-фон (contact.html)

   Той самий ассет (image-set 1x/2x contact-bg-desktop.webp/@2x.webp), CSS-
   масштабування до 880×495, зсув 24px від верху секції (background-position:
   center 24px) — на цьому кроці міняється лише фон, контент Hero під mobile
   ще не адаптований.
   ========================================================================== */

@media (max-width: 767px) {

  .contact-hero {
    min-height: 519px;
  }

  .contact-hero__image {
    background-position: center 24px;
    background-size: 880px 495px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — фікс: Hero-контент (тайтл/боді/форма), contact.html

   Сітка: 4 колонки × 72px + 3 gutter × 16px = 336px, center, offset 0.
   Тайтл — .dm-28-reg (Mob/H1, tokens.css), той самий текст ("Contact"),
   що на десктопі/tablet. Боді — .dm-14-light, з власним mobile-переносом
   (--break--mobile/--desktop toggle вище, база тексту не міняється).
   Відступи тайтл→боді (16px) і боді→форма (36px тут, а не успадковані
   48px з десктопу) — прямі значення з ТЗ.

   Форма — та сама розмітка/логіка (валідація, EmailJS, анти-спам,
   localStorage-чернетка, viewport-aware дропдауни, авто-ріст textarea) —
   ЄДИНА зміна тут: ширина полів/кнопки/дропдаун-панелі 336px замість
   фіксованих 448px, успадкованих з десктопу (форма ніколи не мала
   окремого правила під ширину Tablet Portrait/Landscape, лишалась на
   448px — тут вперше отримує власну mobile-ширину, на всю сітку) */

@media (max-width: 767px) {

  .contact-hero {
    padding-top: 156px;
  }

  .contact-hero__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  .contact-hero__desc {
    width: 336px;
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0em;
  }

  .contact-hero__desc-break--desktop {
    display: none;
  }

  .contact-hero__desc-break--mobile {
    display: inline;
  }

  .contact-form {
    margin-top: 36px;
    width: 336px;
  }

  .form-field,
  .form-field__value,
  .form-field__stroke,
  .form-field__dropdown-panel,
  .contact-form__submit {
    width: 336px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — фікс: секція метрик (contact-stats), contact.html

   Той самий принцип, що Our Approach (about.html, мобільний фікс метрик):
   один айтем на рядок, на всю ширину сітки (336px), 32px між айтемами.
   Текстовий контент — без змін.

   ФІКС попередньої ітерації: .contact-stats__item отримував явний
   width:336px — це ламало горизонтальну формулу лейбла
   (left:calc(100% + 6px) відносно айтема, Крок 75) — зі стретчнутим на
   336px айтемом лейбл їхав на 336+6px замість "6px правіше тайтла".
   Тепер айтем лишається shrink-to-fit (як на десктопі, ширина = ширина
   ТАЙТЛА, єдиного flow-контенту) — для цього .contact-stats__titles
   отримує align-items:flex-start (скасовує дефолтний stretch, який
   інакше й без явного width розтягнув би айтем на всю ширину
   flex-column контейнера). Ширина 336px, де вона дійсно потрібна
   (строук/боді, обидва вже position:absolute — не залежать від ширини
   айтема-контейнера) — задається їм напряму (left:0;width:336px),
   а не через right:0 (який рахувався б від вузького айтема).

   Формула (та сама, що Our Approach, Мob/H2 dm-24-reg замість
   унаслідуваного .dm-h0): тайтл-lh(31.2 = 24×130%) + 7 = маркер-top
   (38.2px); +5 (висота квадрата) = строук-top (43.2px); +16 = боді-top
   (59.2px).

   Лейбл — .red-hat-10-bold (tokens.css, відновлений як виняток САМЕ для
   цього місця) + text-transform:uppercase, замість успадкованого
   rh-12-bold-track (десктоп) — Tablet Portrait тим часом звужував його
   до 11px лише у своєму медіа-запиті (768–1023px), тут не діє.
   Позиція лейбла (6px/2px) — та сама формула, що на десктопі,
   перевизначати не потрібно.

   .contact-stats__line (спільна лінія під усіма трьома маркерами в
   рядку) — тут не підходить (айтеми вже не в один рядок): вимикається,
   замінюється власним ::after на КОЖНОМУ айтемі (той самий прийом, що
   .about-stats__item::after).

   .contact-stats__item — min-height:79.2px (= боді-top 59.2 + один
   рядок боді-тексту 20px, dm-14-light; усі три боді-тексти вміщуються
   в один рядок на 336px) — без явної висоти flex-колонка стискала б
   кожен айтем до самого тайтла (31.2px, єдиного flow-контенту), і
   наступний айтем (margin-top:32px) наліз би на абсолютно позиційований
   боді-текст попереднього.

   .contact-stats margin-top:88px — відступ від CTA-кнопки форми
   (.contact-form не має власного padding знизу, тому нижній край форми
   збігається з нижнім краєм кнопки) до тайтла першого айтема метрики.

   .contact-form__submit — justify-content:center уже задано на базовому
   рівні (Крок 116, діє на всіх breakpoint'ах), тут лише перепідтверджено
   явно для Mobile */

@media (max-width: 767px) {

  .contact-stats {
    margin-top: 88px;
  }

  .contact-stats__grid {
    max-width: 336px;
    margin: 0 auto;
  }

  .contact-stats__titles {
    flex-direction: column;
    align-items: flex-start;
    width: 336px;
    margin: 0 auto;
  }

  .contact-stats__item {
    position: relative;
    min-height: 94px;
  }

  .contact-stats__item--2,
  .contact-stats__item--3 {
    margin-left: 0;
    margin-top: 32px;
  }

  /* Фікс: тайтл метрики — DM Sans/H2 ДЕСКТОПНИЙ (.dm-h2: 40px/46px),
     а НЕ mob/H2 (.dm-24-reg, 24px/130%, попередня ітерація) — виняток
     за завданням. Marker/stroke/body-top перераховані під нову
     line-height (46px, фіксовані px, не %): 46+7=53 (маркер);
     53+5=58 (строук); 58+16=74 (боді); +20(один рядок боді)=94
     (min-height айтема) */
  .contact-stats__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 40px;
    line-height: 46px;
    letter-spacing: 0em;
  }

  .contact-stats__label {
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 10px;
    line-height: 10px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
  }

  .contact-stats__marker {
    top: 53px;
  }

  .contact-stats__line {
    display: none;
  }

  .contact-stats__item::after {
    content: "";
    position: absolute;
    left: 0;
    width: 336px;
    top: 58px;
    height: 1px;
    background-color: var(--grey-15);
  }

  .contact-stats__body {
    top: 74px;
    width: 336px;
  }

}

/* ==========================================================================
   MOBILE (375–767px) — фікс: секція Offices (contact.html)

   Структура/геометрія кожного айтема міста (тайтл→маркер 7px,
   маркер→строук 5px висоти квадрата, строук→лейбл 16px, лейбл→боді
   10px, боді→строук 16px, строук→GMT 4px, GMT→нижній строук 4px,
   вертикальні строуки зліва/справа від GMT-мітки на всю висоту між
   двома горизонтальними строуками) — УСЕ це вже задане спільними
   (не сторінко-скоупленими) правилами .about-offices__* у Мobile-блоці
   about.html (Крок 190) і застосовується тут автоматично, оскільки
   contact.html ділить ті самі BEM-класи. Єдиним, що бракувало —
   HTML-елемент .about-offices__gmt-divider--before (вертикальний
   строук ЗЛІВА від GMT-тексту) був відсутній у розмітці contact.html
   (є лише в about.html) — доданий у розмітку (3 міста) окремо від
   цього CSS-фіксу.

   Боді-тексти айтемів міст — нові --mobile-варіанти (точні ручні
   переноси за ТЗ, п.5), додані в розмітку поряд з --desktop/--tablet/
   --portrait; тут лише перемикається видимість: --desktop (єдиний
   видимий за замовчуванням на Mobile — ніщо досі його не ховало)
   вимикається, --mobile вмикається. Секційний боді-текст (не по
   містах, "Three offices...") — п.3 ТЗ — вже показує --desktop-варіант
   із ТОЧНО потрібними трьома рядками (нічого не приховує його на
   Mobile) і вже стилізований під Mobile через .about-offices__desc
   (about.html, Крок 190, той самий unscoped-принцип) — окремого
   правила не потрібно */

@media (max-width: 767px) {

  .contact-offices__body--desktop {
    display: none;
  }

  .contact-offices__body--mobile {
    display: block;
    width: 336px;
  }
}

/* ==========================================================================
   MOBILE (375–767px) — фікс: відступи навколо фрейму GMT-мітки +
   ширина строука під квадратиком, Offices (contact.html)

   Фрейм GMT-мітки (мітка + строуки над/під + вертикальні строуки
   зліва/справа) — САМ по собі (:before/:after на .about-offices__gmt,
   .about-offices__gmt-divider/--before) успадкований з about.html
   (Крок 190) БЕЗ ЗМІН — внутрішня геометрія (29px висота, 4px відступи
   мітка↔строуки) НЕ чіпається. Змінюється лише ЙОГО ПОЗИЦІЯ: about.html
   калібрував top:210.2px (мітка) під СВІЙ 5-рядковий боді-текст (боді
   закінчувався на 189.2px, +16=205.2 верхній строук фрейму). У
   contact.html боді-текст коротший (4/3 рядки, --mobile-варіанти вище,
   закінчується на 169.2px) — з успадкованим top:210.2 проміжок
   боді→фрейм виходив 36px замість заданих 16px.

   Новий верхній строук фрейму = 169.2 (низ боді, London/NY, 4 рядки) +
   16 = 185.2px; фрейм зсувається ЦІЛКОМ на ту саму дельту (205.2−185.2
   = 20px вище): мітка top 210.2−20=190.2px (внутрішні :before/:after/
   дивайдери — відносні до мітки, рухаються разом, без окремих правил).

   .about-offices__city min-height — успадковані 243.2px теж калібровані
   під about.html (нижній строук фрейму на 234.2px + запас) — тут
   нижній строук фрейму тепер на 190.2+24+1(власна висота строука)=
   215.2px, тому min-height теж 215.2px: наступний айтем
   (margin-top:32px, успадковано) рахує свій відступ від флоу-нижнього
   краю АЙТЕМА (=min-height), тому лише точний min-height дає РЕАЛЬНИЙ
   32px від низу фрейму до наступного айтема (а не 32 + залишок від
   старих 243.2px).

   Строук під квадратиком (NY/Kyiv) — .about-offices__city--ny::after/
   --kyiv::after успадковують right:0 (відносно САМОГО айтема, який на
   Mobile shrink-to-fit під ширину тайтла, Крок 190) — тому ширина
   строука дорівнювала ширині тайтла ("New York"/"Kyiv"), а не сітці.
   Явний width:336px (замість right:0) — той самий фікс, що
   .contact-stats__item::after (попередній Крок). London використовує
   ІНШИЙ елемент (.about-offices__line, спільний, position:absolute
   відносно .about-offices__cities, а не окремого айтема) — вже коректні
   336px, без змін.

   Kyiv — ОКРЕМА формула: його --mobile боді-текст лише 3 рядки (60px,
   попередній Крок, п.5 ТЗ), а не 4, як London/New York (169.2px низ
   боді) — тому низ боді в Kyiv на 149.2px. Загальна формула (виведена з
   about.html): gmt-top = боді-низ + 21 (16 заданий відступ + 5 висота
   квадрата-строука). Kyiv: 149.2+21=170.2px (мітка), min-height =
   170.2+24+1(власна висота строука)=195.2px (той самий принцип, що
   London/New York вище, 24 = висота мітки 20 + 4px заданий відступ до
   нижнього строука фрейму). Специфічність селектора та сама (2 класи),
   тому правило розміщене ПІСЛЯ загального — виграє порядком каскаду */

@media (max-width: 767px) {

  .contact-offices .about-offices__gmt {
    top: 190.2px;
  }

  .contact-offices .about-offices__city {
    min-height: 215.2px;
  }

  .contact-offices .about-offices__city--kyiv .about-offices__gmt {
    top: 170.2px;
  }

  .contact-offices .about-offices__city--kyiv {
    min-height: 195.2px;
  }

  .contact-offices .about-offices__city--ny::after,
  .contact-offices .about-offices__city--kyiv::after {
    right: auto;
    width: 336px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 209: Hero-контент + секція метрик
   (contact.html)

   Hero: тайтл .dm-30-reg (Tablet/H2), боді .dm-16-light — той самий текст,
   що в десктопі/Tablet Landscape. Відступи тайтл→боді (16px) і боді→форма
   (48px) уже збігаються з десктопними значеннями (без окремого
   перевизначення) — перевизначається лише padding-top (224px, той самий
   принцип, що Tablet Landscape, Крок 155). Форма (Крок 210-фікс) НЕ
   адаптується під ширину сітки Tablet Portrait — переноситься 1:1 з
   Tablet Landscape (фіксовані десктопні 448px, без окремого правила).

   Метрики: той самий контент, що вже є в розмітці (Tablet Landscape,
   Крок 155-фікс не чіпав текст, лише офіси) — новий тайтл-стиль
   .dm-36-reg (Tablet/H1) і лейбл-стиль .rh-11-bold, з новою вертикальною
   геометрією під менший тайтл: маркер/лінія/боді порахувані від
   line-height 42px замість десктопних 60px, той самий принцип "N px нижче
   тайтла", що вже задає десктопні значення (71=60+11, 75=71+5-1,
   100=75+1+24) — тут 53=42+11, 57=53+5-1, 82=57+1+24.

   Горизонтальні офсети айтемів 2/3 задані від ПРАВОГО КРАЮ ЛЕЙБЛА
   (не тайтла, як у десктопі/Tablet Landscape) — оскільки лейбл лишається
   position:absolute й не впливає на flow-ширину айтема (та сама техніка,
   що в десктопі, коментар вище), margin-left на .contact-stats__item--2/
   --3 порахований як 6px (офсет лейбла від тайтла) + виміряна рендером
   ширина лейбла попереднього айтема + заданий проміжок (71px/89px) */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-hero {
    padding-top: 224px;
  }

  .contact-hero__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 30px;
    line-height: 36px;
    letter-spacing: 0em;
  }

  .contact-hero__desc {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 16px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* Фікс: форма НЕ адаптується під ширину сітки Tablet Portrait —
     переноситься 1:1 з Tablet Landscape (сама лишається без окремого
     перевизначення в жодному з двох breakpoint'ів, успадковує
     фіксовані десктопні 448px, той самий принцип, що Hero-контент
     work.html/about.html/services.html, Крок 141/143/149) */

  /* Ширина секції метрик: 668px замість десктопних 1164px, той самий
     принцип, що Tablet Landscape (908px) */
  .contact-stats__grid {
    max-width: 668px;
  }

  /* Айтем 1 починається з лівого краю сітки (0px), той самий фікс, що
     Tablet Landscape (прибирає центрування margin:0 auto) */
  .contact-stats__titles {
    margin: 0;
  }

  .contact-stats__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* 6px правіше правого краю тайтла (той самий горизонтальний офсет, що
     в десктопі), по ВЕРХНЬОМУ краю тайтла (top:0) замість десктопних
     2px */
  .contact-stats__label {
    top: 0;
    font-family: var(--font-red-hat);
    font-weight: 700;
    font-size: 11px;
    line-height: 20px;
    letter-spacing: 0.07em;
  }

  .contact-stats__marker {
    top: 53px;
  }

  .contact-stats__line {
    top: 57px;
  }

  .contact-stats__body {
    top: 82px;
  }

  /* 145px = 6 (офсет лейбла від тайтла 1) + виміряна ширина лейбла
     "PRODUCTS" при .rh-11-bold (~67.8px) + 71 (заданий проміжок) */
  .contact-stats__item--2 {
    margin-left: 145px;
  }

  /* 168px = 6 (офсет лейбла від тайтла 2) + виміряна ширина лейбла
     "OF CLIENTS" при .rh-11-bold і white-space:nowrap (~72.5px) + 89
     (заданий проміжок) */
  .contact-stats__item--3 {
    margin-left: 168px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 210: відступи CTA→метрики,
   метрики→Offices (contact.html)

   Айтеми міст (London/New York/Kyiv) на цьому breakpoint НЕ
   перевизначаються — Крок 210 (одноколонковий стек, попередня ітерація)
   відкачено повністю, секція знову успадковує готовий 2-колонковий/
   2-рядковий грід-макет .about-offices__* з about.html (Крок 170), той
   самий принцип, що вже задокументовано в Кроці 76 (contact.html ділить
   БЕМ-класи, увесь блок підхоплюється автоматично, без окремих правил).

   Тут перевизначаються лише два вертикальні відступи: .contact-stats
   margin-top — гейт CTA-кнопка форми→тайтл "300+" (фікс: 80px, було
   128px; форма не має власного padding знизу, тому нижній край
   .contact-form збігається з нижнім краєм кнопки, і margin-top напряму
   дає потрібний гейт — той самий принцип, що встановлений формулою
   title-top=item-top у Кроці 209). .contact-offices margin-top — гейт
   .contact-stats__body→лейбл "OFFICES" (102px, п.3 ТЗ), перевизначає
   успадкований margin-top:120px з about.html (Крок 170, та сама
   специфічність 0,1,0 — вигравaє через порядок каскаду, це правило
   пізніше у файлі). */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-stats {
    margin-top: 80px;
  }

  .contact-offices {
    margin-top: 64px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 211: 4 внутрішні відступи айтемів
   міст, секція Offices (contact.html)

   Структура міст лишається ПОВНІСТЮ успадкованою з about.html (Крок 170,
   2-колонковий/2-рядковий грід) — тут перевизначаються ЛИШЕ 4 вертикальні
   відступи всередині кожного айтема, скоуплені під .contact-offices, щоб
   не зачепити about.html. Ліве вирівнювання тайтла й боді-тексту (20px)
   уже узгоджене в успадкованій структурі (title/city-info/subtitle/body
   лишаються на тому самому лівому краю кожного міста, London/Kyiv:20px,
   New York:0px своєї колонки) — окремого правила не потрібно.

   Ланцюжок відступів (від верху свого .about-offices__city):
   - маркер: 54px = 42 (line-height тайтла) + 12 (заданий відступ)
   - верхній строук: 58px = 54 (верх маркера) + 5 (висота) - 1 (нижній
     піксель квадратика, той самий принцип, що скрізь на сайті) —
     перевизначає успадковані 70px, той самий top, що подає власний
     box-shadow-клон для ряду 2 (Kyiv, +437px, значення офсету
     клону не чіпається — це вертикальна відстань між рядами, не один
     із 4 заданих відступів)
   - city-info (лейбл+боді): 156px = 58 + 98 (заданий відступ)
   - строук над GMT: ІНДИВІДУАЛЬНИЙ відступ від низу боді-тексту
     кожного айтема (див. наступний блок, фікс — 24px для London/
     5 рядків, 44px для New York/Kyiv/4 рядки), а не єдине значення
     на всі три

   GMT-мітка й строук під нею — див. наступний блок (фікс) */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-offices .about-offices__marker {
    top: 54px;
  }

  .contact-offices .about-offices__line {
    top: 58px;
  }

  .contact-offices .about-offices__city-info {
    top: 156px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — фікс: індивідуальний відступ
   боді-текст→строук (London 24px vs New York/Kyiv 44px) + вертикальні
   строуки до правильної висоти, секція Offices (contact.html)

   Нижній горизонтальний строук під GMT — ОДНА й та сама фіксована
   локальна позиція (343px від верху свого .about-offices__city) для
   всіх трьох айтемів, тому весь ланцюжок під ним рахується від
   довшого (5-рядкового) London-тексту, а тоді перевіряється, що
   коротший (4-рядковий) NY/Kyiv-текст дає рівно 44px до того самого
   строука (різниця 44-24=20px = точно один рядок dm-14-light,
   line-height:20px, tokens.css — тому й співпадає):

   city-info:156 + 24 (rh-16-sb, один рядок сабтайтла) + 10
   (margin-top боді) = 190 (верх боді-тексту, спільний для всіх трьох)
   - London, 5 рядків × 20px = 100 → низ тексту 290; +24 (заданий
     відступ) = 314px (строук над GMT)
   - New York/Kyiv, 4 рядки × 20px = 80 → низ тексту 270; +44 (заданий
     відступ) = 314px (той самий строук — підтверджує, що 24/44 і
     є правильна пара значень)
   - GMT: 314 + 1 (висота строука) + 4 (заданий відступ) = 319px
   - нижній строук: 319 + 20 (line-height, .rh-11-bold) + 4 (заданий
     відступ) = 343px

   .about-offices__body-line/.about-offices__gmt/.about-offices__gmt-line —
   спільні елементи ряду 1 (London+New York), тому одне й те саме
   значення коректно обслуговує обидва міста (44px для NY виходить
   автоматично з різниці в довжині тексту, без окремого правила).
   Kyiv (ряд 2) — власні копії (::before/::after) на ту саму локальну
   позицію (314/343), бо його текст теж 4-рядковий, як у NY.

   Вертикальні строуки (.about-offices__vline/.about-offices__extra-vline/
   .about-offices__city--ny::after) — раніше лишались на успадкованих
   top:70/height:287 (about.html), тоді як маркер/верхній строук уже
   зсунуті на 54/58px (Крок 211) — тепер вирівняні строго між квадратиком
   і нижнім строуком: top:58px (= верх .about-offices__line, той самий
   принцип, що скрізь на сайті — вертикаль стартує на тому самому top,
   що горизонтальна лінія під маркером), height:286px = (343 + 1 нижній
   піксель строука) - 58

   Патерн похилих ліній (.about-offices__pattern, справа від Kyiv) —
   той самий проміжок (верхній/нижній строуки Kyiv), але БЕЗ 1px
   нахлесту, який навмисно є у vline (патерн — заливка, не лінія, тому
   впритул, а не внахлест): top:59px (= нижній край верхнього строука,
   58+1), height:284px = 343 (верх нижнього строука) - 59 */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-offices .about-offices__body-line {
    top: 314px;
  }

  .contact-offices .about-offices__city--kyiv::before {
    top: 314px;
  }

  .contact-offices .about-offices__gmt {
    top: 319px;
  }

  .contact-offices .about-offices__gmt-line {
    top: 343px;
  }

  .contact-offices .about-offices__city--kyiv::after {
    top: 343px;
  }

  .contact-offices .about-offices__vline,
  .contact-offices .about-offices__extra-vline,
  .contact-offices .about-offices__city--ny::after {
    top: 58px;
    height: 286px;
  }

  .contact-offices .about-offices__pattern {
    top: 59px;
    height: 284px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — фікс: відступи до/після рядка Kyiv (80px)

   .about-offices__city--kyiv{top:437px} (about.html) розраховувався під
   старий нижній строук ряду 1 (356) — з новим (343, фікс вище) відступ
   від низу ряду 1 (343+1=344) до тайтла Kyiv виріс до 93px. Піднімаємо
   ряд 2 цілком (усі діти Kyiv — position:absolute відносно самого
   .city--kyiv, тому зсув одного top переносить їх groupою, без окремих
   правок): 344 + 80 (заданий відступ) = 424px.

   .about-offices__line{box-shadow} — це клон строука під квадратиком
   для ряду 2 (та сама лінія, box-shadow-копія замість другого елемента),
   офсет клону мусить збігатися з top самого .city--kyiv (той самий
   принцип, що в about.html, коментар "той самий зсув, що
   .about-offices__city--kyiv{top:...}") — тому теж 424px.

   .about-offices__cities{min-height} — визначає нижню межу секції
   (діти — position:absolute, тому висота контейнера рахується лише
   звідси); формула та сама, що в about.html (Крок 170): top Kyiv (424)
   + власний нижній край контенту Kyiv (344, той самий локальний
   строук/GMT-ланцюжок, що й ряд 1, — фікс вище) = 768px. Це і дає
   рівно 80px від строука під Kyiv до CTA-2 (готове правило
   .about-offices + .cta--second{margin-top:80px}, не потребує змін) */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-offices .about-offices__city--kyiv {
    top: 424px;
  }

  .contact-offices .about-offices__line {
    box-shadow: 0 424px 0 0 var(--grey-15);
  }

  .contact-offices .about-offices__cities {
    min-height: 768px;
  }
}

/* ==========================================================================
   TABLET PORTRAIT (768–1023px) — Крок 212: секція Offices — фікс
   боді-текстів (--portrait не показувався!) + 2 нові відступи +
   боді-тексти айтемів міст (contact.html)

   ДІАГНОСТИКА (чому боді-текст секції не змінювався у двох попередніх
   спробах): .contact-offices__desc--portrait існував у розмітці з
   ПРАВИЛЬНИМ текстом ще з Кроку 209, але базове правило (Крок 209,
   ~стр. 8054) ховає його за замовчуванням (display:none, той самий
   прийом, що --tablet) — а показати його для 768–1023px мало ЦЕ правило,
   якого не існувало в жодному з попередніх Кроків 209–211. Тому на
   екрані весь час малювався --desktop варіант (він ніколи не мав
   display:none для цього діапазону, лишався видимим за замовчуванням) —
   підтверджено рендером getComputedStyle: --desktop було "block",
   --portrait було "none". Не JS, не специфічність/!important, не
   дублікат розмітки — простий пропущений toggle. Той самий баг був і в
   .contact-offices__body--desktop/--portrait (боді-тексти міст) —
   виправлено тут же, разом з новими текстами п.4 ТЗ (--portrait для
   кожного міста, замість того щоб і далі показувати --desktop). */

@media (min-width: 768px) and (max-width: 1023px) {

  .contact-offices__desc--desktop,
  .contact-offices__body--desktop {
    display: none;
  }

  .contact-offices__desc--portrait,
  .contact-offices__body--portrait {
    display: block;
  }

  /* Той самий фікс, що .contact-offices__body--desktop (Крок 76-фікс,
     стр. 8068): рядок New York "...US time zones —" ширший за
     успадковані 293px, без цього браузер сам переносив би "—" на
     новий рядок поверх заданого <br> */
  .contact-offices__body--portrait {
    width: 312px;
  }

  /* Відступ лейбл→тайтл секції: 20px (26px у десктопі) */
  .contact-offices .about-offices__title {
    margin-top: 20px;
  }

  /* Відступ боді-текст секції→тайтли міст: 96px (перевизначає
     успадковані 80px з about.html, Крок 170) */
  .contact-offices .about-offices__cities {
    margin-top: 96px;
  }

  /* Лівий відступ боді-тексту від вертикального строука айтема — 20px.
     London/Kyiv уже на 20px (vline:0, city-info:20, успадковано без
     змін) — фіксується лише New York, де about.html (Крок 170) тримає
     vline на -16px відносно .city--ny (межа колонки), а city-info на
     0px (гейт лише 16px); тайтл зсувається разом з city-info, щоб
     лишитись на тому самому лівому краю, що й боді-текст */
  .contact-offices .about-offices__city--ny .about-offices__city-info {
    left: 4px;
  }

  .contact-offices .about-offices__city--ny .about-offices__city-title {
    margin-left: 4px;
  }

  /* Той самий фікс, що city-info вище — GMT-мітка New York успадковувала
     left:0 з about.html (Крок 170), даючи лише 16px відступу від строука
     (-16px), а не 20px. left:4px = той самий лівий край, що city-info,
     тепер вирівнює GMT з боді-текстом цього айтема */
  .contact-offices .about-offices__city--ny .about-offices__gmt {
    left: 4px;
  }
}

/* ==========================================================================
   Крок 213 — privacy-policy.html, Desktop (≥1280px)
   Крок 214 (фікс) — перебудовано на єдину sticky-панель (той самий
   принцип, що .services__sticky, js/services-table.js): title+дати+
   строук+ліва навігація+права колонка контенту ТЕПЕР усі всередині
   ОДНІЄЇ position:sticky панелі (.privacy__pin), а не окремого
   position:fixed блоку + окремого потокового контенту, як було раніше.
   Причина переходу: v1 (position:fixed) робила ліву панель "вічно
   зафіксованою" — вона нависала б над футером назавжди, щойно
   догортали контент, і строук лівої панелі не мав природної точки
   зупинки. Sticky-панель натомість природньо "відпускається" рівно
   там, де закінчується .privacy__pin-wrapper — а висота wrapper
   (js/privacy-pin.js) підібрана так, щоб це відпускання збігалось з
   моментом, коли контент праворуч повністю прогорнутий, і одразу після
   переходило у звичайний скрол сторінки до футера.

   Права колонка контенту — вікно фіксованої (JS-обчисленої) висоти з
   overflow:hidden; текст усередині рухає js/privacy-pin.js через
   transform: translateY(), синхронізовано з тим самим page-скролом,
   що тримає sticky-панель "на місці" (та сама техніка, що
   .services-table у js/services-table.js) — тому перехід "внутрішній
   скрол контенту → скрол сторінки" безшовний за конструкцією: це
   ОДИН БЕЗПЕРЕРВНИЙ page-скрол увесь час, лише по-різному
   інтерпретований (то як transform контенту, то як звичайний скрол),
   а не два окремі механізми, що треба вручну "передавати" один одному.

   Вертикальний строук лівої навігації (.privacy__nav-vline) — Фікс:
   раніше (top:0;bottom:0 відносно .privacy__nav-outer, розтягнутого
   грідом до висоти .privacy__content-window) він закінчувався рівно на
   низу sticky-панелі — тобто на межі .privacy__pin-wrapper, ПЕРЕД
   50px-вим margin-top футера, а не на самому першому строукові футера
   (.footer__line-a) усередині нього. Тепер top:0 (без bottom) + height,
   яку рахує js/privacy-pin.js через offsetTop-ланцюжок (той самий
   принцип, що js/how-we-work.js: суто static-flow позиція, ігнорує
   sticky-зсув і page-скрол) — vline тягнеться РІВНО до .footer__line-a,
   незалежно від фактичного вмісту лівої навігації. */

.privacy {
  position: relative;
  width: 100%;
  background-color: var(--color-background);
}

/* Плаваюча кнопка-список + попап-панель навігації — ЛИШЕ Tablet Portrait
   (768–1023px, styles.css нижче, .privacy__popup-toggle{display:flex}/
   .privacy__popup-panel.is-open{display:flex}); за замовчуванням
   приховані на всіх інших breakpoint (Desktop/Tablet Landscape мають
   ліву навігацію в сітці, їм ця кнопка не потрібна) */
.privacy__popup-toggle,
.privacy__popup-panel {
  display: none;
}

/* Висота — JS (js/privacy-pin.js): природна висота .privacy__head-row
   (тайтл+дати, звичайний скрол) + висота .privacy__pin, поки він
   пришпилений + повна незрізана висота контенту праворуч
   (.privacy__content.scrollHeight, "внутрішній" скрол після замикання).
   Це водночас і висота "тайтл ще скролиться звичайно", і "панель
   пришпилена", і висота "потім природньо відпускається" — розписано в
   коментарі вище файлу */
.privacy__pin-wrapper {
  position: relative;
  /* flow-root: без цього margin/border колапс дитини (.privacy__head-row
     чи .privacy__pin) міг би "просочитись" ВГОРУ крізь wrapper і крізь
     .privacy, зсувши всю секцію вниз на зайву відстань (виміряно
     Puppeteer раніше саме на такому кейсі: margin-top:202px єдиної
     дитини .privacy__pin давав .privacy top=202 замість 0). flow-root
     заводить новий block formatting context — блокує колапс, не
     займаючи власної overflow-поведінки (на відміну від overflow:hidden,
     який зламав би sticky-позиціювання нащадка) */
  display: flow-root;
}

/* Фікс — тайтл+дати БІЛЬШЕ НЕ всередині .privacy__pin: звичайний
   (не-sticky) .privacy__head-row іде ПЕРЕД панеллю, скролиться геть
   разом зі сторінкою. .privacy__pin природньо йде одразу за ним (без
   margin-top-трюка, на відміну від Кроку 214) — тому має ЗВИЧАЙНУ
   (не-sticky) точку старту одразу під тайтлом, і "замикається" лише
   коли скрол доносить цю природну позицію до top:78px (= нижня межа
   хедера, .header { top:18px + height:60px }, styles.css) */
.privacy__pin {
  position: sticky;
  top: 78px;
  z-index: 10;
}

/* Fade-маска над зоною хедера (0–112px від верху viewport, HTML —
   body-рівня елемент одразу після </header>, не всередині .privacy —
   position:fixed, тому не залежить від скролу самого блоку). Поки
   .privacy__head-row (тайтл+дати) ще скролиться звичайно й
   наближається до хедера знизу, він проходить крізь цю зону.
   Фікс: .header--scrolled (styles.css, header.js SCROLL_THRESHOLD:10px —
   вмикається майже одразу з початку скролу) робить .header__nav
   (opacity:0) і фон САМОГО .header прозорими в середній частині — лише
   .header__brand (лого) і CONTACT лишаються власними непрозорими
   боксами скраю. Тобто вже за 10px скролу хедер сам по собі НЕ ховає
   нічого, що проходить під ним у середній зоні — це і є вся причина,
   чому потрібна ця маска. Тому градієнт непрозорий БЛИЖЧЕ ДО ВЕРХУ
   viewport (0px, там, де хедер фізично лежить і куди тайтл рухається),
   прозорий ближче до низу зони (112px, ще виразно НИЖЧЕ хедера, де
   тайтл усе ще звичайний, немаскований) — так тайтл гасне ПОКИ ще
   під хедером, а не з'являється знову, щойно заходить глибше в зону.
   Фікс: висота зони — 112px (~28% менше за попередні 156px, а не
   78px і не 156px): на 78px тайтл лишався видимим ще на половині
   проходження під хедером; на 156px, навпаки, зникав ще ДО того, як
   фізично досягав нижньої межі хедера (78px) — "мертва зона" одразу
   під хедером. При ТИХ САМИХ % для стопів градієнта (opaque 0–70%,
   fade 70–100%) 112px дає opaque-плато 0–78px — тобто тайтл стає
   ПОВНІСТЮ непрозорим/невидимим САМЕ на 78px, рівно нижній межі
   хедера (.privacy__pin{top}), без "запасу" в жоден бік. Сам
   HEADER_BOTTOM/pinStart-механіка "замикання" строука
   (js/privacy-pin.js, top:78px) — БЕЗ ЗМІН, ця маска суто візуальна
   й ніяк на неї не впливає.
   z-index:50 — між хедером (100, лишається зверху) і рештою контенту
   сторінки (.privacy__pin z-index:10). Після "замикання" .privacy__pin
   ніщо з панелі більше не заходить у цю зону, тому окремого
   is-visible/JS-тогла не потрібно — маска завжди змонтована, просто
   порожня над уже закріпленим вмістом */
.privacy__head-fade {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 112px;
  z-index: 50;
  background: linear-gradient(to bottom, var(--color-background) 0%, var(--color-background) 70%, transparent 100%);
  pointer-events: none;
}

.privacy__grid {
  display: grid;
  grid-template-columns: repeat(8, 128px);
  column-gap: 20px;
  max-width: 1164px;
  margin: 0 auto;
}

/* 202px — реальний (не sticky-трюк) відступ від верху сторінки до
   тайтла "Privacy Policy", той самий, що раніше давав старий
   .privacy__pin{margin-top:202px} "заодно" (бо той трюк форсував
   pinStart=0 САМЕ через рівність margin-top і top-обмеження). Тепер
   .privacy__head-row — звичайний потоковий блок ПЕРЕД .privacy__pin
   (Фікс), тому цей відступ живе тут явно й самостійно, а
   .privacy__pin більше не потребує власного margin-top узагалі —
   js/privacy-pin.js (measure()) читає це значення через
   getComputedStyle, а не дублює його як окрему хардкод-константу */
.privacy__head-row {
  margin-top: 202px;
}

/* height — JS (js/privacy-pin.js, measure()), п.7 ТЗ: 204px від низу
   контенту праворуч до футера. Простий block-рівня сіблінг ОДРАЗУ ПІСЛЯ
   .privacy__grid, усередині .privacy__pin (єдина дитина якого раніше
   була сама .privacy__grid) — додає свою висоту НАПРЯМУ до рендер-висоти
   pin (pin.getBoundingClientRect().height), без grid-розміщення. Це
   штовхає низ pin (а отже й низ .privacy__pin-wrapper, і футер услід за
   ним) ГЛИБШЕ за низ .privacy__content-window/.privacy__nav-outer, не
   зачіпаючи жодного з них самих — на відміну від першої (хибної) спроби
   роздути .privacy__pin-wrapper напряму: то однаково зсувало і низ
   вікна контенту, і футер, лишаючи проміжок між ними НЕЗМІННИМ (204px
   ніяк не досягався) */
.privacy__footer-gap-spacer {
  height: 0;
  /* Фікс — явний transparent: цей елемент НЕ має власного background-
     color вже й до цього (лишався б transparent за CSS-дефолтом навіть
     без цього рядка — перевірено getComputedStyle, завжди
     rgba(0,0,0,0)), але явна декларація документує, що це навмисно
     "невидимий" spacer, а не забутий/успадкований колір */
  background: transparent;
}

.privacy__head {
  grid-column: 1 / -1;
  grid-row: 1;
  position: relative;
  background-color: var(--color-background);
}

.privacy__title {
  color: var(--grey-100);
}

/* Лейбл дати вирівняний по нижньому краю тайтла (висота .privacy__head
   дорівнює висоті самого тайтла, оскільки .privacy__date-row — absolute
   і не впливає на потік), зі зсувом 4px вище цього вирівнювання */
.privacy__date-row {
  position: absolute;
  right: 0;
  bottom: 4px;
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.privacy__updated {
  color: var(--grey-50);
  text-transform: uppercase;
}

.privacy__date {
  color: var(--grey-60);
  text-transform: uppercase;
}

/* grid-row:1 (не 2) — Фікс: цей строук тепер у ВЛАСНІЙ .privacy__grid
   всередині .privacy__pin, окремій від тайтлу/дат
   (.privacy__head-row); margin-top:20px і далі дає той самий 20px
   відступ від низу тайтла, бо margin грід-айтема НЕ колапсує з
   контейнером (.privacy__grid) — відступ лишається "всередині" першого
   рядка нового грід, а не між .privacy__head-row і .privacy__pin */
.privacy__hr {
  grid-column: 1 / -1;
  grid-row: 1;
  display: block;
  margin-top: 20px;
  height: 1px;
  background-color: var(--grey-15);
}

/* Фікс: висота — тепер теж JS (js/privacy-pin.js, measure(), той самий
   min(доступне у viewport, натуральна висота списку) принцип, що
   .privacy__content-window) — раніше nav-outer завжди мав height:auto
   і "безкоштовно" розтягувався грідом до висоти content-window; коли
   список навігації став довшим за самé вікно (13 айтемів), його
   природний контент почав переростати доступну висоту viewport без
   жодного обмеження. display:flex — щоб внутрішній .privacy__nav
   (єдина in-flow дитина; vline/fade-top/fade-bottom — position:absolute,
   поза потоком) міг через flex:1 заповнити РІВНО (висота nav-outer −
   76px верхнього відступу), не зазіхаючи на цей відступ */
/* Фікс — прибрано background-color: var(--color-background), що раніше
   тут стояв: у поточній sticky-панель архітектурі (Крок 214+) nav-outer
   живе у ВЛАСНІЙ грід-колонці, ніколи не перетинається з контентом
   праворуч, і sticky (top:78/72/68px) фізично НЕ дає йому зайти вище
   цієї межі — тобто нічого чужого ніколи не "проходить" під ним чи не
   зупиняється в тій самій прямокутній зоні (перевірено виміром
   getBoundingClientRect() під час скролу від 0 до "замикання": top
   монотонно спадає до 99px і застрягає там, ніколи не заходить у
   0–97px зону .privacy__head-fade). Це був vestige зі старої v1
   position:fixed-архітектури (Крок 213, задокументовано в пам'яті —
   там ОДИН фіксований блок на всю ширину справді ховав контент, що
   проходив під ним), не прибраний при переході на Крок 214. Значення
   й так завжди дорівнювало кольору сторінки (rgb(17,17,17) в обох
   випадках, перевірено попіксельно) — видалення не змінює жодного
   пікселя, лише прибирає непотрібний "прямокутник кольору фону" саме
   там, де раніше стояв bottom-fade (і де він тепер прибраний повністю) */
.privacy__nav-outer {
  grid-column: 1 / 3;
  grid-row: 2; /* Фікс: 2, не 3 — тайтл-рядок винесено в окрему .privacy__grid (.privacy__head-row) */
  display: flex;
  flex-direction: column;
  position: relative;
  height: 500px; /* фолбек до першого виміру JS, той самий принцип, що content-window */
  /* Той самий compositing-фікс, що .privacy__content-window (styles.css,
     коментар там) — той самий sticky-lock тригер (.privacy__pin{top}),
     той самий клас WebKit-repaint-бага */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

/* height — JS (js/privacy-pin.js, measure()): точна відстань від верху
   vline до .footer__line-a (rect-diff відносно .privacy__pin, безпечний
   для sticky-піддерева — див. коментар біля syncNavVline). height:100% —
   фолбек до першого виміру JS (той самий принцип, що
   .privacy__content-window height:500px) */
.privacy__nav-vline {
  position: absolute;
  top: 0;
  right: 0;
  width: 1px;
  height: 100%;
  background-color: var(--grey-15);
}

/* Фікс: 76px відступу від hr до першого айтема тепер margin-top (а не
   padding-top) — .privacy__nav сам став СКРОЛЬОВАНИМ (overflow-y:auto,
   висота — JS, flex:1 від nav-outer), а margin, на відміну від padding,
   лишається ПОЗА скрольованою областю: цей відступ — частина "решти
   структури лівої колонки", яка не повинна скролитись разом з айтемами
   (п.4 ТЗ). min-height:0 — класичний flexbox-фікс: без нього flex-item
   з overflow не може стиснутись менше своєї природної (нескороченої)
   висоти вмісту, і overflow-y:auto ефективно ніколи не спрацював би.
   scrollbar-width/-ms-overflow-style/::-webkit-scrollbar — той самий
   прийом, що .form-field--textarea .form-field__value: ховає ВІЗУАЛЬНИЙ
   скролбар (17px власного скролбара впритул до vline праворуч виглядав
   би зламано на 276px-вій колонці), сам скрол лишається робочим.
   data-lenis-prevent у розмітці (не тут) — щоб Lenis не перехоплював
   wheel над цим елементом і не скролив сторінку замість панелі */
/* Фікс: position:relative — .privacy__nav сам по собі був position:static,
   тому offsetParent усіх .privacy__nav-item "пробивав" його наскрізь до
   .privacy__nav-outer (найближчий ПОЗИЦІОНОВАНИЙ предок), а це давало
   item.offsetTop, що включає зайві 76px (margin-top вище) ПОВЕРХ
   реальної позиції айтема в межах СКРОЛЬОВАНОГО вмісту .privacy__nav.
   js/privacy-nav.js (ensureNavItemVisible) рахує цільовий scrollTop
   САМЕ як item.offsetTop — з offsetParent=nav-outer це завжди було на
   76px забагато, тому скрол ВГОРУ до "introduction" (має бути
   scrollTop:0) застрягав на scrollTop:76 (айтем лишався не до кінця
   видимим) — скрол ВНИЗ "працював" лише тому, що завищена ціль просто
   клампилась браузером до максимуму скролу. position:relative тут
   робить .privacy__nav САМ найближчим позиціонованим предком — тепер
   offsetTop коректно відносний до 0 у верху скрольованого вмісту */
.privacy__nav {
  position: relative;
  margin-top: 76px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  display: flex;
  flex-direction: column;
}

.privacy__nav::-webkit-scrollbar {
  display: none;
}

/* Крок — .privacy__nav-content: окрема "content"-обгортка айтемів,
   потрібна лише для Lenis (wrapper: .privacy__nav / content: цей div,
   js/privacy-nav-lenis.js) — сама .privacy__nav лишається "wrapper"
   (overflow-y:auto, як і раніше), а offsetParent айтемів для
   js/privacy-nav.js не змінюється (цей div не позиціонований, тому
   .privacy__nav і далі найближчий позиціонований предок) */
.privacy__nav-content {
  display: flex;
  flex-direction: column;
}

/* top-fade лівої панелі — той самий принцип, що .privacy__content-fade-top
   (градієнт фон→прозорий), лише висота менша (32px, не 56px) —
   пропорційно висоті самих айтемів (50–77px), а не висоті цілого рядка
   тексту. is-visible керується js/privacy-pin.js за scrollTop
   .privacy__nav (реальний overflow-скрол, на відміну від контенту
   праворуч, де прогрес рахується з transform). Bottom-fade прибрано
   навмисно (Фікс) — текст лівої панелі тепер обривається знизу БЕЗ
   градієнта, лише верхній fade лишився */
.privacy__nav-fade-top {
  position: absolute;
  top: 76px;
  left: 0;
  right: 1px; /* Фікс: -1px — щоб градієнт не заходив на .privacy__nav-vline (right:0, 1px) праворуч */
  height: 32px;
  z-index: 1;
  background: linear-gradient(to bottom, var(--color-background), transparent);
  pointer-events: none;
  opacity: 0;
  transition: opacity 300ms ease;
}

.privacy__nav-fade-top.is-visible {
  opacity: 1;
}

/* Фікс: висота фрейму раніше трималась на голому min-height:50px без
   жодного вертикального padding — для 1-рядкового тексту (26px, dm-desc)
   це давало ті самі 50px (24px "повітря", розподілене flex-центруванням
   навколо тексту), але для 2-рядкового (52px) те саме "повітря" зникало
   майже до нуля (природна content-висота вже сама перевищувала 50px), і
   фрейм ставав непропорційно тісним. Тепер padding:12px 20px замінює
   min-height як основне джерело висоти — той самий 12px зверху/знизу
   зберігається НЕЗАЛЕЖНО від кількості рядків (1 рядок: 12+26+12=50px,
   як і раніше; 2 рядки: 12+52+12=76px; 3+ рядки — пропорційно далі),
   тобто фрейм реально росте під контент, а не застряє на 50px.
   min-height:50 лишається підстраховкою (той самий 50px floor, що й
   раніше, просто тепер зайвий для 1-рядкових айтемів).
   Фікс: flex-shrink:0 — .privacy__nav (батько) щойно став
   height-обмеженим flex-контейнером (JS-висота + overflow-y:auto,
   ліва панель тепер скролиться, п.4 ТЗ); без цього флексбокс-дефолт
   (flex-shrink:1) для explicit min-height (на відміну від автоматичного
   min-height:auto/min-content, яке flex захищає від стиснення завжди)
   стискав 2-рядкові айтеми НАЗАД до 50px, обрізаючи другий рядок під
   строуком — той самий клас багу, що описаний вище про "фрейм застряг
   на 50px", але тепер від flex-shrink, а не від min-height */
.privacy__nav-item {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  width: 100%;
  min-height: 50px;
  padding: 12px 20px 12px 0;
  border-bottom: 1px solid var(--grey-15);
  color: var(--grey-55);
  text-decoration: none;
  /* Плавний перехід активного стану (Крок 214) — той самий easing, що
     .scroll-reveal (--ease-smooth), але значно коротша тривалість
     (250ms, не 650ms — це миттєва micro-interaction, не в'їзд секції) */
  transition: color 250ms var(--ease-smooth);
}

/* Іконка тепер завжди в DOM (не display:none/block, як у Кроці 213) —
   display не анімується, тому активний стан плавно "розкриває" її
   через width/margin-right/opacity одночасно: неактивний — 0/0/0
   (текст стоїть впритул зліва, 0px відступу, як і раніше), активний —
   12/6/1 (сама іконка 12×12; 6px до тексту).
   Фікс — колір ЗАВЖДИ var(--grey-100), незалежно від стану: раніше
   .privacy__nav-icon був <img src="star.svg">, а CSS color на <img> не
   впливає на растеризований SVG-контент — колір був буквально вшитий у
   файл (stroke="#B6B6B6" = var(--grey-60), той самий нюанс, що
   задокументований біля .practice__body2-icon). Тепер — <span> +
   mask-image (той самий прийом, що .footer__blog-icon): background-color
   і є видимий колір іконки, форма приходить лише з маски. Inline
   data-URI (не url("assets/images/star.svg")) — той самий CORS-на-file://
   фікс, що вже задокументований біля .footer__blog-icon: зовнішній
   mask-imageファйл блокується браузером на file://-протоколі (подвійний
   клік по HTML, без локального сервера), inline data-URI фетчу не
   робить узагалі. stroke='%23fff' у масці (не реальний колір) —
   -webkit-mask-image за замовчуванням luminance-based, тьмяний stroke
   дав би частково прозору маску */
.privacy__nav-icon {
  display: block;
  flex-shrink: 0;
  width: 0;
  height: 12px;
  margin-right: 0;
  opacity: 0;
  overflow: hidden;
  background-color: var(--grey-100);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath d='M4.33398 8V5.39995L5.33398 4.76387M7.47912 1.82991L5.33398 3.6666V4.76387M7.72214 5.8475L5.33398 4.76387' stroke='%23fff'/%3E%3Cpath d='M3.72168 0V2.60005L2.72168 3.23613M0.576541 6.17009L2.72168 4.3334V3.23613M0.333526 2.1525L2.72168 3.23613' stroke='%23fff'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath d='M4.33398 8V5.39995L5.33398 4.76387M7.47912 1.82991L5.33398 3.6666V4.76387M7.72214 5.8475L5.33398 4.76387' stroke='%23fff'/%3E%3Cpath d='M3.72168 0V2.60005L2.72168 3.23613M0.576541 6.17009L2.72168 4.3334V3.23613M0.333526 2.1525L2.72168 3.23613' stroke='%23fff'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  transition: width 250ms var(--ease-smooth),
              margin-right 250ms var(--ease-smooth),
              opacity 250ms var(--ease-smooth);
}

.privacy__nav-item.is-active {
  color: var(--grey-100);
}

.privacy__nav-item.is-active .privacy__nav-icon {
  width: 12px;
  margin-right: 6px;
  opacity: 1;
}

/* Фікс — п.6 ТЗ: hover на будь-якому айтемі (активному чи ні) — колір
   тексту var(--grey-60), той самий transition:color 250ms, що вже є на
   .privacy__nav-item. Розміщено ПІСЛЯ .is-active навмисно: однакова
   специфічність (0,2,0 в обох), тому порядок у файлі вирішує каскад —
   якщо колись перенесеш це правило вище .is-active, hover на активному
   айтемі перестане працювати. Іконка НЕ підпорядкована .color (mask +
   background-color, не currentColor) — тому лишається var(--grey-100)
   і під час hover, як і вимагає п.4 */
.privacy__nav-item:hover {
  color: var(--grey-60);
}

/* Коли текст айтема займає 2 рядки — іконка більше НЕ центрується по
   вертикалі відносно фрейму (align-items:center на .privacy__nav-item
   вище), а стоїть на фіксованому відступі від верху фрейму. Клас
   .privacy__nav-item--wrapped ставить js/privacy-nav.js (виміряно
   реальну висоту тексту — >1 рядка, оскільки CSS сам по собі не може
   визначити кількість рядків переносу). align-self:flex-start прибирає
   іконку з центрування, margin-top додає решту відступу ПОВЕРХ
   padding-top фрейму (12px, .privacy__nav-item).
   Фікс: підтверджено вимірюванням (getBoundingClientRect() у Puppeteer)
   — з margin-top:9px реальний відступ був РІВНО 21px (12+9), як і
   задумувалось раніше. Тепер підняли ще на 2px вище: margin-top:7px →
   12+7=19px */
.privacy__nav-item--wrapped .privacy__nav-icon {
  align-self: flex-start;
  margin-top: 7px;
}

/* Вікно контенту — фіксована (JS-обчислена) висота, overflow:hidden;
   .privacy__content усередині рухається через transform: translateY()
   (js/privacy-pin.js), а не через власний скрол/скролбар цього
   елемента — тому scroll-chaining/scroll-lock тут не потрібні: це один
   і той самий page-скрол від початку до кінця, лише по-різному
   інтерпретований (детальний коментар на початку секції) */
/* -webkit-transform:translateZ(0) — форсує власний GPU compositing layer
   для цього overflow:hidden вікна. Це відомий клас WebKit/Safari-бага
   (Lenis свідомо ВІДКЛЮЧЕНИЙ на Safari, js/smooth-scroll.js isSafari —
   там працює нативний scroll+rAF шлях): sticky-предок (.privacy__pin),
   що "замикається" (top:78/72/68px) саме в момент, коли з'являється
   fadeTop.is-visible, змушує WebKit перерахувати clip/paint цього
   нащадка — і в рідкісних випадках Safari на один кадр показує
   непроклаптований прямокутник фону контейнера замість негайного
   правильного repaint. Форсоване власне compositing-шар (як і
   .privacy__content{will-change:transform} уже робить для контенту
   праворуч) усуває цей клас бага незалежно від причини — перевірено, що
   не впливає на жодну наявну поведінку (розмір/позиція/overflow-кліп
   лишаються тими самими) */
.privacy__content-window {
  grid-column: 3 / span 5;
  grid-row: 2; /* Фікс: 2, не 3 — тайтл-рядок винесено в окрему .privacy__grid (.privacy__head-row) */
  position: relative;
  margin-top: 80px;
  overflow: hidden;
  height: 500px; /* фолбек до першого виміру JS */
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

/* З'являється, лише коли контент усередині вікна вже почав "виїжджати"
   за верхню межу (progress > 0, js/privacy-pin.js) — на самому початку
   (перший рядок Introduction) затіняти нічого */
.privacy__content-fade-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 56px;
  z-index: 1;
  background: linear-gradient(to bottom, var(--color-background), transparent);
  pointer-events: none;
  opacity: 0;
  transition: opacity 300ms ease;
}

.privacy__content-fade-top.is-visible {
  opacity: 1;
}

.privacy__content {
  width: 720px;
  will-change: transform;
}

.privacy__section-title {
  color: var(--grey-100);
}

.privacy__section + .privacy__section {
  margin-top: 80px;
}

.privacy__section-title + .privacy__text {
  margin-top: 24px;
}

.privacy__subtitle {
  margin-top: 40px;
  color: var(--grey-100);
}

.privacy__subtitle + .privacy__text {
  margin-top: 16px;
}

.privacy__text {
  color: var(--grey-60);
}

.privacy__text p + p {
  margin-top: 16px;
}

.privacy__text a {
  color: inherit;
  text-decoration: underline;
}

.privacy__list {
  list-style: none;
  margin-top: 16px;
}

.privacy__list li {
  position: relative;
  padding-left: 16px;
}

.privacy__list li + li {
  margin-top: 4px;
}

.privacy__list li::before {
  content: "\2022";
  position: absolute;
  left: 0;
  top: 0;
}

.privacy__list + p {
  margin-top: 16px;
}

/* Фікс: точні переноси рядків боді-текстів на Tablet Landscape
   (1024–1279px), звірені з PDF, відрізняються від Desktop — тому,
   як і .faq-item__body--desktop/--tablet (services.html), окремий,
   переписаний-на-нові-точки-розриву .privacy__text-блок на кожну
   секцію, а не просто <br>-класи всередині одного блоку (list-и теж
   мають власні розриви на TL, дублювати лише окремі <li> було б
   крихкіше за margin/сусідні-селектори). --tablet-landscape вимкнений
   за замовчуванням, вмикається нижче в медіа-запиті 1024–1279px */
.privacy__text--tablet-landscape {
  display: none;
}

/* Той самий прийом, для Tablet Portrait (768–1023px) — власний,
   третій розподіл рядків, звірений з PDF */
.privacy__text--tablet-portrait {
  display: none;
}

/* Той самий прийом, для Mobile (≤767px) — четвертий, останній
   розподіл рядків, звірений з PDF (список "Information you provide
   directly" тепер теж дублюється в усі 4 варіанти — раніше лишався
   спільним, бо текст був однаковий на Desktop/TL/TP, але на Mobile
   отримав власний розрив в останньому пункті) */
.privacy__text--mobile {
  display: none;
}

/* ==========================================================================
   Крок — privacy-policy.html, TABLET LANDSCAPE (1024–1279px)

   Сітка: 8 колонок × 96px + 7 gutter × 20px = 908px, center, offset 0
   (той самий принцип, що .grid-overlay__row вище). Уся ЛОГІКА й
   ПОВЕДІНКА сторінки — та сама, що на Desktop (≥1280px, розлогий
   коментар над .privacy вище): структура, ліва навігація зі scrollspy,
   "замикання" строука під хедером при скролі, fade-маска над хедером,
   top/bottom fade лівої панелі й контенту, авто-скрол лівої панелі,
   окремий Lenis-інстанс лівої панелі (js/privacy-nav-lenis.js), hover,
   примусові 2-рядкові переноси (HTML <br>, ширини не стосується),
   іконка star.svg — ніщо з цього нижче не перевизначається. Змінюються
   ЛИШЕ розміри/відступи, перераховані під нову ширину сітки й новий
   .header (styles.css, TABLET (1024–1279px) — Крок 132: top:20px +
   height:52px = 72px, не 78px):
   - ліва колонка (навігація) 328px = 3 колонки (96×3+20×2)
   - права колонка (контент) 560px = 5 колонок (96×5+20×4)
   - тайтл "Privacy Policy" від верху сторінки — 170px, не 202px
   - контент → футер — 144px, не 204px
   js/privacy-pin.js і js/privacy-nav.js самі читають нову геометрію
   (HEADER_BOTTOM — живий вимір .header; CONTENT_FOOTER_GAP/
   ACTIVATION_LINE — вже breakpoint-обізнані), окремих JS-змін під цей
   media query не потрібно.
   ========================================================================== */
@media (min-width: 1024px) and (max-width: 1279px) {
  .privacy__grid {
    grid-template-columns: repeat(8, 96px);
    max-width: 908px;
  }

  /* Перемикач Desktop/TL боді-блоків (комент біля .privacy__text--
     tablet-landscape вище) — --desktop лишається в DOM (прихований),
     тому margin-top від .privacy__section-title/.privacy__subtitle
     (styles.css, суміжний селектор "+") не долітає до --tablet-
     landscape напряму; перевизначаємо тут же */
  .privacy__text--desktop {
    display: none;
  }

  .privacy__text--tablet-landscape {
    display: block;
  }

  .privacy__section-title + .privacy__text--desktop + .privacy__text--tablet-landscape {
    margin-top: 24px;
  }

  .privacy__subtitle + .privacy__text--desktop + .privacy__text--tablet-landscape {
    margin-top: 16px;
  }

  .privacy__head-row {
    margin-top: 170px;
  }

  /* terms-of-service.html — власний відступ тайтла від верху (Крок),
     відрізняється від privacy-policy.html на цьому breakpoint.
     .privacy--terms — модифікатор на кореневій .privacy-секції (лише
     terms-of-service.html), той самий "compound-selector scoping"
     прийом, що вже задокументований в інших місцях кодбази для
     розрізнення сторінок зі спільними BEM-класами */
  .privacy--terms .privacy__head-row {
    margin-top: 154px;
  }

  /* top:72px = .header{top:20px+height:52px} на цьому breakpoint
     (styles.css, TABLET (1024–1279px) — Крок 132) — той самий принцип,
     що десктопний top:78px, під нову висоту хедера */
  .privacy__pin {
    top: 72px;
  }

  /* Той самий градієнт (0%/70%/100%, styles.css вище), лише висота
     зони перерахована під новий HEADER_BOTTOM: opaque-плато має
     закінчуватись РІВНО на 72px (0.7 × 103 ≈ 72), як на десктопі
     0.7 × 112 = 78 */
  .privacy__head-fade {
    height: 103px;
  }

  .privacy__nav-outer {
    grid-column: 1 / 4;
  }

  .privacy__content-window {
    grid-column: 4 / span 5;
  }

  .privacy__content {
    width: 560px;
  }
}

/* ==========================================================================
   Крок — privacy-policy.html, TABLET PORTRAIT (768–1023px)

   Сітка: 4 колонки × 155px + 3 gutter × 16px = 668px, center, offset 0
   (той самий принцип, що .grid-overlay__row вище). НЕМАЄ лівої панелі
   навігації взагалі на цьому breakpoint — .privacy__nav-outer нижче
   просто display:none (розмітка та сама, HTML не дублюється); контент
   займає ВСЮ ширину сітки. "Lock"-механіка тайтла/строука (fade-маска
   над хедером, sticky-замикання строука під хедером, top/bottom fade
   контенту, внутрішній скрол contentWindow) — ТА САМА, що на Desktop/
   Tablet Landscape (розлогий коментар над .privacy вище), лише під
   новий .header{top:20px+height:48px=68px} (styles.css, TABLET
   PORTRAIT — Крок 156) — js/privacy-pin.js сам читає це живим виміром,
   окремих JS-змін під цю "lock"-частину не потрібно. Ліва навігація/
   scrollspy/окремий Lenis-інстанс (js/privacy-nav.js,
   js/privacy-nav-lenis.js) самі рано виходять на цьому breakpoint
   (window.innerWidth < 1024) — нічого синхронізувати.

   Типографіка — Tablet/H1 (.dm-36-reg) для головного тайтла, Tablet/H3
   (.dm-24-reg-h3, tokens.css) для тайтлів контентних секцій, замість
   десктопних .dm-h1/.dm-h3 — перевизначено НАПРЯМУ на компонентних
   класах (.privacy__title/.privacy__section-title), той самий прийом,
   що .hero__title на інших сторінках (не через заміну класів у HTML). */
@media (min-width: 768px) and (max-width: 1023px) {
  .privacy__grid {
    grid-template-columns: repeat(4, 155px);
    max-width: 668px;
    column-gap: 16px;
  }

  /* Перемикач Desktop/TP боді-блоків (комент біля .privacy__text--
     tablet-landscape/--tablet-portrait, styles.css вище) */
  .privacy__text--desktop {
    display: none;
  }

  .privacy__text--tablet-portrait {
    display: block;
  }

  .privacy__section-title + .privacy__text--desktop + .privacy__text--tablet-landscape + .privacy__text--tablet-portrait {
    margin-top: 24px;
  }

  .privacy__subtitle + .privacy__text--desktop + .privacy__text--tablet-landscape + .privacy__text--tablet-portrait {
    margin-top: 16px;
  }

  .privacy__head-row {
    margin-top: 200px;
  }

  /* terms-of-service.html — власний відступ тайтла (Крок), той самий
     .privacy--terms scoping прийом, що Tablet Landscape вище */
  .privacy--terms .privacy__head-row {
    margin-top: 184px;
  }

  /* top:68px = .header{top:20px+height:48px} на цьому breakpoint — той
     самий принцип, що top:78px (десктоп)/top:72px (Tablet Landscape) */
  .privacy__pin {
    top: 68px;
  }

  /* Той самий градієнт (0%/70%/100%), висота перерахована під новий
     HEADER_BOTTOM: opaque-плато закінчується РІВНО на 68px
     (0.7 × 97 ≈ 68) */
  .privacy__head-fade {
    height: 97px;
  }

  /* Немає лівої навігації на цьому breakpoint (п.3 ТЗ) — той самий HTML,
     просто не рендериться. js/privacy-pin.js (measure()) сам пропускає
     вимір/синхронізацію цього блока, коли він приховано
     (navOuter.offsetParent === null) */
  .privacy__nav-outer {
    display: none;
  }

  /* Контент — на всю ширину сітки (4 колонки), а не 3/span5 (десктоп)
     чи 4/span5 (Tablet Landscape), бо лівої колонки більше немає взагалі */
  /* Фікс: 48px, не 80px (базове .privacy__content-window{margin-top},
     styles.css вище) — відступ від строука до тайтла ПЕРШОЇ секції
     ("Introduction"). Живий вимір (js/privacy-pin.js, rect-diff від
     .privacy__pin) сам підхоплює це нове значення без жодних JS-змін —
     усі похідні розрахунки (windowTop/scrollRange/fade) вже завжди
     читали цей margin-top з CSS, а не дублювали його константою */
  .privacy__content-window {
    grid-column: 1 / -1;
    margin-top: 48px;
  }

  .privacy__content {
    width: 668px;
  }

  /* Tablet/H1 (.dm-36-reg, tokens.css) замість десктопного .dm-h1 —
     значення скопійовані напряму (той самий прийом, що .hero__title) */
  .privacy__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 36px;
    line-height: 42px;
    letter-spacing: 0em;
  }

  /* Tablet/H3 (.dm-24-reg-h3, tokens.css) замість десктопного .dm-h3 —
     тайтли контентних секцій (Introduction, ...), помітно менші за
     головний тайтл сторінки вище */
  .privacy__section-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 24px;
    line-height: 30px;
    letter-spacing: 0em;
  }

  /* 64px, не 80px — відступ між секціями контенту (п.6 ТЗ) */
  .privacy__section + .privacy__section {
    margin-top: 64px;
  }

  /* 36px, не 40px — відступ тайтл секції → сабтайтл (п.6 ТЗ) */
  .privacy__subtitle {
    margin-top: 36px;
  }

  /* Крок — плаваюча кнопка-список (немає лівої навігації в сітці на
     цьому breakpoint, styles.css вище). left:50%+translateX(-334px) —
     той самий "центр сітки мінус половина ширини" принцип, що дає
     лівий край 668px-вої сітки (334 = 668/2), без окремого
     position:fixed-wrapper. bottom:32px — від низу viewport, ЗАВЖДИ
     видима під час скролу (position:fixed, не залежить від
     .privacy__pin/сторінки). z-index:90 — над контентом (.privacy__pin
     z-index:10) і маскою хедера (50), під самим хедером (100) */
  .privacy__popup-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    left: 50%;
    transform: translateX(-334px);
    bottom: 32px;
    width: 52px;
    height: 52px;
    background-color: var(--grey-15);
    border: 1px solid var(--grey-15);
    padding: 0;
    cursor: pointer;
    z-index: 90;
    /* Плавна зміна фону відкритий/закритий стан (.is-open нижче) — той
       самий короткий 250ms easing, що вже є на .privacy__nav-item.
       opacity/transform-transition (появи на завантаженні І зникнення
       біля футера) — див. compound-правило .scroll-reveal нижче: цей
       базовий transition НЕ включає opacity/transform навмисно, інакше
       однакова специфічність (0,1,0) з .scroll-reveal перебила б його
       transition цілком (shorthand не мерджиться між правилами) */
    transition: background-color 250ms var(--ease-smooth);
  }

  /* Кнопка-список бере участь у тій самій page-load reveal-анімації, що
     решта сайту (Фікс) — АЛЕ вже має власний transform (translateX(-334px)
     для горизонтального центрування, position:fixed) і власний opacity/
     transition (fade біля футера, .privacy__popup-toggle--hidden нижче).
     Base .scroll-reveal/.scroll-reveal-up/.scroll-reveal.is-visible
     (styles.css, унизу файлу специфічність 0,1,0/0,1,0/0,2,0) сама по
     собі або програла б каскад (translateX загубився б, кнопка "стрибнула"
     б у неправильну горизонтальну позицію), або виграла б і замінила
     transform ЦІЛКОМ (втратили б translateX(-334px) назавжди після
     .is-visible). Той самий compound-селектор прийом, що
     .cta-button.scroll-reveal/.see-all-work.scroll-reveal (styles.css,
     початок файлу) — тут для transform, а не лише transition: обидва
     стани (до/після появи) явно зберігають translateX(-334px) */
  .privacy__popup-toggle.scroll-reveal {
    transition:
      opacity .65s var(--ease-smooth) var(--reveal-delay, 0s),
      transform .65s var(--ease-smooth) var(--reveal-delay, 0s),
      background-color 250ms var(--ease-smooth);
  }

  .privacy__popup-toggle.scroll-reveal.scroll-reveal-up {
    transform: translateX(-334px) translateY(40px);
  }

  .privacy__popup-toggle.scroll-reveal.is-visible {
    transform: translateX(-334px);
  }

  /* Кнопка накладалась би на футер — плавно ховаємо (п.3 ТЗ). pointer-events:
     none — щоб невидима (але й досі position:fixed, у DOM) кнопка не ловила
     кліки/hover, поки прозора. Compound-селектор (0,2,0) — та сама
     специфічність, що .scroll-reveal.is-visible (вище), тому мусить
     стояти ПІЗНІШЕ в каскаді, щоб перебивати opacity:1 вже після того,
     як завантажувальна reveal-анімація завершилась і юзер доскролив до
     футера */
  .privacy__popup-toggle.privacy__popup-toggle--hidden {
    opacity: 0;
    pointer-events: none;
  }

  /* Hover (закритий стан) — той самий колір, що й активний стан нижче,
     як прев'ю; коли панель відкрита, .is-open перебиває hover (однакова
     специфічність, але .is-open стоїть нижче в каскаді) */
  .privacy__popup-toggle:hover {
    background-color: var(--grey-20);
  }

  /* Активний стан (панель відкрита, п.5 ТЗ) — фон var(--grey-20) */
  .privacy__popup-toggle.is-open {
    background-color: var(--grey-20);
  }

  /* Іконка кнопки-списку — та сама mask-image + background-color техніка,
     що .privacy__nav-icon/.footer__blog-icon (styles.css): <img src=list.svg>
     баке колір ПРЯМО у файл (stroke="#EEEEEE"/"#B6B6B6" = var(--grey-100)/
     var(--grey-60)), тому CSS color на <img> не подіяв би — а активний стан
     (п.4 ТЗ) вимагає точно var(--grey-additional-pressed) (#C2C2C2), якого
     немає в жодному з двох файлів. mask-image замість <img> дає повний
     контроль кольору через background-color для обох станів. Inline
     data-URI (не url("assets/images/list.svg")) — той самий CORS-на-file://
     фікс, що вже задокументований біля .privacy__nav-icon: зовнішній
     mask-image файл блокується браузером на file://-протоколі, inline
     data-URI фетчу не робить узагалі. Форма за замовчуванням — list.svg
     (3 горизонтальні риски), stroke='%23fff' у масці (не реальний колір,
     той самий luminance-mask нюанс, що й .privacy__nav-icon) */
  .privacy__popup-toggle-icon {
    display: block;
    width: 22px;
    height: 22px;
    background-color: var(--grey-100);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M3.66699 7H18.792M3.66699 11H18.792M3.66699 14.9985H11.2295' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M3.66699 7H18.792M3.66699 11H18.792M3.66699 14.9985H11.2295' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
  }

  /* Активний стан (панель відкрита, п.4 ТЗ) — форма x-mark.svg (заміна
     clear2.svg), колір var(--grey-additional-pressed), замість дефолтної
     list.svg форми/var(--grey-100). x-mark.svg — 22×22, той самий розмір,
     що дефолтний стан (list.svg) — окремого перевизначення width/height
     більше не потрібно. stroke='%23fff' у масці (не реальний колір, той
     самий luminance-mask нюанс, що й дефолтний стан вище) */
  .privacy__popup-toggle.is-open .privacy__popup-toggle-icon {
    background-color: var(--grey-additional-pressed);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M5.5 16.5L16.5 5.5M5.5 5.5L16.5 16.5' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M5.5 16.5L16.5 5.5M5.5 5.5L16.5 16.5' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  /* Панель — 8px НАД кнопкою: bottom = 32 (відступ кнопки) + 52
     (висота кнопки) + 8 = 92px. Той самий горизонтальний принцип, що
     й кнопка (лівий край сітки).
     Фікс (п.1 ТЗ) — плавна поява/зникнення: display:none НЕ може
     анімуватись CSS-transition (миттєвий стрибок), тому панель тепер
     ЗАВЖДИ display:flex і керується opacity+transform+visibility. Той
     самий transform-collision принцип, що вже задокументований для
     .privacy__popup-toggle (styles.css) — панель ТЕЖ має власний
     translateX(-334px) для горизонтального центрування, тому і
     закритий, і відкритий стан явно повторюють його поруч із
     translateY. visibility:hidden (не лише opacity:0) — щоб закрита
     панель НЕ ловила фокус/клік/screen reader (те, що раніше давав
     display:none) — transition-delay на visibility (0s, затримка =
     тривалість fade-out) тримає її "visible" ПОКИ триває сам fade-out,
     і миттєво ховає лише в самому кінці; при відкритті затримка 0,
     visible одразу */
  .privacy__popup-panel {
    display: flex;
    flex-direction: column;
    position: fixed;
    left: 50%;
    bottom: 92px;
    width: 335px;
    height: 580px;
    background-color: var(--grey-5);
    border: 1px solid var(--grey-20);
    overflow-y: auto;
    z-index: 90;
    opacity: 0;
    visibility: hidden;
    transform: translateX(-334px) translateY(12px);
    transition: opacity 250ms var(--ease-smooth), transform 250ms var(--ease-smooth), visibility 0s linear 250ms;
  }

  .privacy__popup-panel.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateX(-334px);
    transition: opacity 250ms var(--ease-smooth), transform 250ms var(--ease-smooth), visibility 0s linear 0s;
  }

  /* Обгортка айтемів — потрібна лише для Lenis (wrapper: .privacy__popup-panel/
     content: цей div, js/privacy-popup-nav-lenis.js), той самий принцип, що
     .privacy__nav-content для лівої панелі */
  .privacy__popup-panel-content {
    display: flex;
    flex-direction: column;
  }

  /* Відступ 24px зліва для контенту (текст, іконка star.svg) кожного
     айтема навігації ВСЕРЕДИНІ попап-панелі (п.1 ТЗ) — .privacy__nav-item
     сама по собі спільна з лівою десктопною панеллю (padding:12px 20px
     12px 0, без лівого відступу там, де немає власного бічного gutter'а),
     тому скоуплено через .privacy__popup-panel-предка, а не змінено
     базове правило (не чіпає Desktop/Tablet Landscape) */
  .privacy__popup-panel .privacy__nav-item {
    padding-left: 24px;
  }

  /* star.svg — 10×10px на цьому breakpoint (п.4 ТЗ), не 12×12
     (Desktop/Tablet Landscape, базове правило) — той самий "неактивний
     width:0 → активний width:N" механізм, лише height/N перевизначені */
  .privacy__nav-icon {
    height: 10px;
  }

  .privacy__nav-item.is-active .privacy__nav-icon {
    width: 10px;
  }

  /* Кастомний скролбар (п.6 ТЗ) — видимий (на відміну від
     .privacy__nav, де скролбар навмисно ПРИХОВАНИЙ, styles.css вище):
     4px (без змін), колір повзунка var(--grey-20), трек прозорий,
     квадратні кути (border-radius:0 — webkit інакше скруглює кінці
     повзунка залежно від системної теми), впритул до правого краю
     (::-webkit-scrollbar завжди притиснутий до внутрішнього краю
     border-box без додаткового відступу — на .privacy__popup-panel
     немає padding-right, який міг би відсунути його від краю).
     scrollbar-width/-color — той самий стиль для Firefox (Firefox не
     підтримує border-radius на своєму скролбарі окремо — thin-варіант
     і так рендериться прямокутним) */
  .privacy__popup-panel {
    scrollbar-width: thin;
    scrollbar-color: var(--grey-20) transparent;
  }

  .privacy__popup-panel::-webkit-scrollbar {
    width: 4px;
  }

  .privacy__popup-panel::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 0;
  }

  .privacy__popup-panel::-webkit-scrollbar-thumb {
    background-color: var(--grey-20);
    border-radius: 0;
  }
}

/* ==========================================================================
   Крок — privacy-policy.html, MOBILE (≤767px)

   Сітка: 4 колонки × 72px + 3 gutter × 16px = 336px, center, offset 0
   (той самий принцип, що Tablet Portrait/.grid-overlay__row вище). Уся
   ЛОГІКА й ПОВЕДІНКА — ПОВНІСТЮ ІДЕНТИЧНА Tablet Portrait (розлогий
   коментар над тим блоком вище): немає лівої панелі навігації в сітці
   (.privacy__nav-outer{display:none}, той самий HTML), "lock"-механіка
   тайтла/строука під хедером, fade-маска над хедером, top-fade контенту,
   кнопка-список 52×52px + попап-панель з внутрішнім Lenis-скролом і
   кастомним скролбаром — усе те саме, лише під новий .header{top:20px+
   height:48px=68px} (styles.css, MOBILE — Крок 176), який ЗБІГАЄТЬСЯ з
   Tablet Portrait (той самий top/height), тому pin{top}/head-fade{height}
   нижче — ті самі числа, не нові.

   js/privacy-pin.js сам читає нову геометрію (HEADER_BOTTOM — живий вимір
   .header; CONTENT_FOOTER_GAP тепер має 4-й, mobile-бакет — 96px, п.7 ТЗ).
   js/privacy-popup-nav.js/js/privacy-popup-nav-lenis.js — guard
   (window.innerWidth > 1023) розширено з Tablet-Portrait-only
   (768–1023) на ≤1023 (тобто тепер і Mobile), інших JS-змін не треба —
   js/privacy-nav.js/js/privacy-nav-lenis.js (десктопна ліва панель) і так
   вже виходять при window.innerWidth < 1024, що включає Mobile. */
@media (max-width: 767px) {
  .privacy__grid {
    grid-template-columns: repeat(4, 72px);
    max-width: 336px;
    column-gap: 16px;
  }

  /* Перемикач Desktop/TL/TP/Mobile боді-блоків (комент біля
     .privacy__text--tablet-landscape/--tablet-portrait/--mobile,
     styles.css вище) */
  .privacy__text--desktop {
    display: none;
  }

  .privacy__text--mobile {
    display: block;
  }

  .privacy__section-title + .privacy__text--desktop + .privacy__text--tablet-landscape + .privacy__text--tablet-portrait + .privacy__text--mobile {
    margin-top: 24px;
  }

  .privacy__subtitle + .privacy__text--desktop + .privacy__text--tablet-landscape + .privacy__text--tablet-portrait + .privacy__text--mobile {
    margin-top: 16px;
  }

  /* 202px (п.2 ТЗ) — на відміну від Tablet Portrait (200px), це власне
     мобільне значення з ТЗ, не передрук сусіднього breakpoint */
  .privacy__head-row {
    margin-top: 202px;
  }

  /* terms-of-service.html — власний відступ тайтла (Крок), той самий
     .privacy--terms scoping прийом, що Tablet Landscape/Portrait вище */
  .privacy--terms .privacy__head-row {
    margin-top: 160px;
  }

  /* Фікс (п.2 ТЗ) — на Desktop/Tablet Portrait тайтл і лейбли дати
     стоять В ОДИН РЯДОК (.privacy__date-row — position:absolute,
     вирівняний по нижньому краю тайтла, right:0; working, бо грід
     достатньо широкий, щоб тайтл зліва й лейбл справа не перекривались).
     На 336px-вій мобільній сітці "Privacy Policy" (28px) + "UPDATED
     JULY 30, 2026" разом ширші за сітку — ТЗ прямо вимагає СТОВПЧИК
     (тайтл, 56px, лейбли), тому тут лейбл-рядок переведений з
     position:absolute у звичайний потік (margin-top:56px замість
     bottom:4px). .privacy__head тепер природньо росте під ОБИДВА
     елементи (раніше — лише під тайтл, бо date-row не впливав на потік)
     — .privacy__head-row.offsetHeight (js/privacy-pin.js) сам підхоплює
     нову висоту без жодних JS-змін.
     Фікс (п.4 ТЗ) — justify-content:flex-start (не flex-end): лейбли
     "Updated"+дата тепер по ЛІВОМУ краю сітки (той самий 0px, що й
     тайтл вище), а не по правому. Сам flex-контейнер (.privacy__date-row)
     і так уже займає повну ширину грід-колонки (звичайний block-рівня
     flex-елемент), тому зміна лише в тому, з якого краю починають
     вирівнюватись діти — flex-start і є CSS-дефолтом для justify-content,
     але лишений явним для симетрії з попереднім flex-end і читабельності */
  .privacy__date-row {
    position: static;
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: 12px;
    margin-top: 56px;
  }

  /* DM Sans/14 Semibold (.dm-14-semibold, tokens.css — НОВИЙ клас, п.2 ТЗ)
     замість .dm-16-semibold (розмітка) — виділені слова/фрази в боді-
     тексті. Той самий "перевизначити напряму на утиліті-класі в @media"
     прийом, що .privacy__title/.privacy__section-title/.privacy__subtitle/
     .privacy__text вище — не чіпає розмітку, не впливає на Desktop/Tablet
     Landscape/Tablet Portrait (там .dm-16-semibold лишається 16/24/600) */
  .dm-16-semibold {
    font-family: var(--font-dm-sans);
    font-weight: 600;
    font-size: 14px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* 12px, не 20px (базове .privacy__hr, styles.css вище) — відступ від
     лейблів дати до великого горизонтального строука (п.2 ТЗ) */
  .privacy__hr {
    margin-top: 12px;
  }

  /* top:68px = .header{top:20px+height:48px} на цьому breakpoint —
     збігається з Tablet Portrait (той самий .header), той самий принцип,
     що top:78px (десктоп)/top:72px (Tablet Landscape) */
  .privacy__pin {
    top: 68px;
  }

  /* Той самий градієнт (0%/70%/100%), та сама висота, що Tablet Portrait
     (той самий HEADER_BOTTOM=68px): opaque-плато закінчується РІВНО на
     68px (0.7 × 97 ≈ 68) */
  .privacy__head-fade {
    height: 97px;
  }

  /* Немає лівої навігації на цьому breakpoint (той самий HTML, що й
     Tablet Portrait) — js/privacy-pin.js (measure()) сам пропускає
     вимір/синхронізацію цього блока, коли він приховано
     (navOuter.offsetParent === null) */
  .privacy__nav-outer {
    display: none;
  }

  /* Контент — на всю ширину сітки (4 колонки), як на Tablet Portrait.
     32px (п.3 ТЗ) — відступ від великого горизонтального строука до
     тайтла ПЕРШОЇ секції ("Introduction"). Живий вимір (js/privacy-pin.js,
     rect-diff від .privacy__pin) сам підхоплює це нове значення без
     жодних JS-змін */
  .privacy__content-window {
    grid-column: 1 / -1;
    margin-top: 32px;
  }

  .privacy__content {
    width: 336px;
  }

  /* Mob/H1 (.dm-28-reg, tokens.css) замість Tablet/H1 (.dm-36-reg) —
     значення скопійовані напряму (той самий прийом, що .privacy__title
     на Tablet Portrait) */
  .privacy__title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 28px;
    line-height: 120%;
    letter-spacing: -0.01em;
  }

  /* DM Sans/22 Reg (.dm-22-reg, tokens.css) замість Tablet/H3
     (.dm-24-reg-h3) — тайтли контентних секцій (Introduction, ...) */
  .privacy__section-title {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 22px;
    line-height: 26px;
    letter-spacing: 0.02em;
  }

  /* DM Sans/18 Reg (.dm-18-reg, tokens.css) замість десктопного
     dm-20-reg (розмітка) — той самий "перевизначити напряму на
     компонентному класі" прийом, тепер і для типографіки сабтайтла (на
     Tablet Portrait перевизначався лише margin-top, шрифт лишався
     dm-20-reg — тут п.1 ТЗ прямо вимагає новий розмір).
     margin-top:32px (п.4 ТЗ) — той самий флет-рул покриває ОБИДВА
     випадки з ТЗ ("тайтл→сабтайтл" і "боді-текст→сабтайтл"), бо це
     безумовний margin-top на самому .privacy__subtitle, а не
     сусід-залежний селектор — спрацьовує однаково незалежно від того,
     що стоїть перед сабтайтлом (той самий принцип, що вже на
     Desktop/Tablet Portrait, де це теж один флет-рул) */
  .privacy__subtitle {
    font-family: var(--font-dm-sans);
    font-weight: 400;
    font-size: 18px;
    line-height: 24px;
    letter-spacing: 0em;
    margin-top: 32px;
  }

  /* DM Sans/14 Light Body (.dm-14-light-body, tokens.css — НОВИЙ клас,
     п.1 ТЗ) замість dm-16-light-body (розмітка) — той самий
     "перевизначити напряму на компонентному класі" прийом.
     .privacy__section-title + .privacy__text (24px) і
     .privacy__subtitle + .privacy__text (16px, styles.css вище) — уже
     збігаються зі значеннями п.4 ТЗ на цьому breakpoint, окремого
     перевизначення тут не треба */
  .privacy__text {
    font-family: var(--font-dm-sans);
    font-weight: 300;
    font-size: 14px;
    line-height: 22px;
    letter-spacing: 0em;
  }

  /* 48px, не 80px (п.4 ТЗ) — відступ між секціями контенту */
  .privacy__section + .privacy__section {
    margin-top: 48px;
  }

  /* Плаваюча кнопка-список — той самий "центр сітки мінус половина
     ширини" принцип, що Tablet Portrait, лише під нову ширину сітки:
     left:50%+translateX(-168px), 168 = 336/2 (не 334 = 668/2, Tablet
     Portrait) — дає лівий край 336px-вої сітки. Решта (bottom:32px,
     52×52px, z-index:90, кольори/transition) — БЕЗ ЗМІН (п.6 ТЗ) */
  .privacy__popup-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    left: 50%;
    transform: translateX(-168px);
    bottom: 32px;
    width: 52px;
    height: 52px;
    background-color: var(--grey-15);
    border: 1px solid var(--grey-15);
    padding: 0;
    cursor: pointer;
    z-index: 90;
    transition: background-color 250ms var(--ease-smooth);
  }

  /* Той самий transform-collision принцип, що Tablet Portrait
     (styles.css, коментар там) — тут лише translateX(-168px) замість
     -334px, решта (тривалості/easing) без змін */
  .privacy__popup-toggle.scroll-reveal {
    transition:
      opacity .65s var(--ease-smooth) var(--reveal-delay, 0s),
      transform .65s var(--ease-smooth) var(--reveal-delay, 0s),
      background-color 250ms var(--ease-smooth);
  }

  .privacy__popup-toggle.scroll-reveal.scroll-reveal-up {
    transform: translateX(-168px) translateY(40px);
  }

  .privacy__popup-toggle.scroll-reveal.is-visible {
    transform: translateX(-168px);
  }

  .privacy__popup-toggle.privacy__popup-toggle--hidden {
    opacity: 0;
    pointer-events: none;
  }

  .privacy__popup-toggle:hover {
    background-color: var(--grey-20);
  }

  .privacy__popup-toggle.is-open {
    background-color: var(--grey-20);
  }

  /* Та сама mask-image + background-color техніка, що Tablet Portrait —
     список.svg, 22×22px, БЕЗ ЗМІН (п.6 ТЗ) */
  .privacy__popup-toggle-icon {
    display: block;
    width: 22px;
    height: 22px;
    background-color: var(--grey-100);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M3.66699 7H18.792M3.66699 11H18.792M3.66699 14.9985H11.2295' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M3.66699 7H18.792M3.66699 11H18.792M3.66699 14.9985H11.2295' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
  }

  /* Активний стан — x-mark.svg, var(--grey-additional-pressed), 22×22px
     (те саме, що дефолтний стан), та сама inline data-URI маска, що
     Tablet Portrait */
  .privacy__popup-toggle.is-open .privacy__popup-toggle-icon {
    background-color: var(--grey-additional-pressed);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M5.5 16.5L16.5 5.5M5.5 5.5L16.5 16.5' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cpath d='M5.5 16.5L16.5 5.5M5.5 5.5L16.5 16.5' stroke='%23fff' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  /* Панель — той самий вертикальний принцип (8px над кнопкою, bottom:92px)
     і ті самі 335×580px, що Tablet Portrait (п.6 ТЗ, БЕЗ ЗМІН) — лише
     translateX(-168px) замість -334px для горизонтального центрування
     під нову ширину сітки */
  .privacy__popup-panel {
    display: flex;
    flex-direction: column;
    position: fixed;
    left: 50%;
    bottom: 92px;
    width: 335px;
    height: 580px;
    background-color: var(--grey-5);
    border: 1px solid var(--grey-20);
    overflow-y: auto;
    z-index: 90;
    opacity: 0;
    visibility: hidden;
    transform: translateX(-168px) translateY(12px);
    transition: opacity 250ms var(--ease-smooth), transform 250ms var(--ease-smooth), visibility 0s linear 250ms;
  }

  .privacy__popup-panel.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateX(-168px);
    transition: opacity 250ms var(--ease-smooth), transform 250ms var(--ease-smooth), visibility 0s linear 0s;
  }

  .privacy__popup-panel-content {
    display: flex;
    flex-direction: column;
  }

  .privacy__popup-panel .privacy__nav-item {
    padding-left: 24px;
  }

  .privacy__nav-icon {
    height: 10px;
  }

  .privacy__nav-item.is-active .privacy__nav-icon {
    width: 10px;
  }

  /* Кастомний скролбар — БЕЗ ЗМІН (п.6 ТЗ): 4px, var(--grey-20),
     border-radius:0, впритул до правого краю, той самий, що Tablet
     Portrait */
  .privacy__popup-panel {
    scrollbar-width: thin;
    scrollbar-color: var(--grey-20) transparent;
  }

  .privacy__popup-panel::-webkit-scrollbar {
    width: 4px;
  }

  .privacy__popup-panel::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 0;
  }

  .privacy__popup-panel::-webkit-scrollbar-thumb {
    background-color: var(--grey-20);
    border-radius: 0;
  }
}

