/* ═══════════════════════════════════════════════════════════════════
   Версия 3 — примерка стиля jasonfaber.ca/about на содержание Максима.
   Файлы v1 (site.css) и v2 (site2.css) не тронуты.

   Снято с оригинала (Webflow-CSS jason-faber-consulting.webflow.shared.css):
     фон страницы    #EEF5F5   --white-smoke
     тёмный          #0E2B2F   --dark-slate-grey: текст, шапка, первый экран,
                               таймлайн, тёмные карточки, тёмная кнопка
     терракота       #DB9365   --dark-salmon: подчёркивание в заголовке,
                               точки и заливка линии таймлайна, текстовые
                               ссылки, оранжевая карточка
     бирюза          #73CFD0   --medium-turquoise: иконки, синяя карточка,
                               синяя кнопка, ховер тёмной кнопки
     серый текст     rgba(14,43,47,.6);  приглушённый белый rgba(255,255,255,.6)
     линии           rgba(14,43,47,.1) на светлом, rgba(255,255,255,.3 / .1) на тёмном

     Satoshi (у него self-hosted woff2, у нас Fontshare), всё начертанием 500:
       body 16/24 · h1 72/100% · h2 52/120% · h3 40/120% · h4 32/140%
       h5 24/140% · h6 20/120% · large-text 20/150% · medium-text 18/160%
       подпись секции (.title) 24/120% серым · eyebrow 14 капсом, .05em
       большая цифра 120 (в карточке) и 72 (в метриках)
     Адаптив: ≤991 body 15, h1 56, h2 44, h3 36, h4 28, h5 22
              ≤767 body 14, h1 48, h2 36, h3 32, h4 24, h5 20 · ≤479 h1 42

     Контейнер 1360 + поля 40 (≤991: 32, ≤767: 24, ≤479: 16)
     Секция 120/120 (≤991: 100), большая секция 140, футер 80/120
     Сетки: split 2 колонки, зазор 64; three-column 16×60; panels 16
     Карточки: радиус 30, паддинг 40 (≤479: радиус 20, паддинг 24)
     Картинки: радиус 30 (corners) и 20 (smaller-corners)
     Кнопки: радиус 8, паддинг 16×24; иконочная 24×32; ховер — внутренняя тень
     Ссылки без подчёркивания; акцентные — терракотой; в заголовке слово
     выделено терракотовой плашкой снизу (у него svg-прямоугольник фоном)

   Иллюстрации, фото, SVG-графика, логотип и тексты оригинала не использованы.

   Цвета (03.09, шестая правка) вынесены в переменные на :root — ни одного
   литерала ниже по файлу. Действующая палитра описана следующим блоком; от
   jasonfaber в ней не осталось ни одного значения, снята только структура
   переменных. Запасные схемы переопределяют те же переменные в themes-2026.css
   через html[data-theme="…"]. Заглушки иллюстраций и иконки в HTML красятся
   классами (.g-a / .g-b / .g-ink, .ph-a / .ph-b / .ph-ink / .ph-text,
   .card__icon) — заливка задаётся здесь, а не атрибутом fill.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Палитра: «Мята на бежевом», примерка 05.09.2026 ─────────────────
   Референс: nominal.so/our-platform. Схема, которая сменила «Лайм на белом»
   (supadupa.nl): та строилась на одном ярком цвете и тёмном хвойном, эта —
   на двух почти неразличимых бежевых холстах, одном мятном акценте
   и почти чёрных чернилах. Приёмы супадупы (свечение обложки, вторая пара
   в середине страницы, тон-в-тон на тёмном) в комментариях ниже помечены
   отдельно: часть из них схема сохранила, часть отменила.

   Замер computed styles живой страницы nominal.so (те же две выборки, что
   делались по супадупе: цвета фонов по площади и по числу узлов, цвет текста,
   заливки svg, цвета рамок):
     холст          #FDFFF8   body, тёплый почти-белый с зеленцой
     полоса         #F3F7EB   девять узлов, зеленоватый беж — вторая плоскость
     волосяная      #E0EADD   83 узла — единственная линия на всём сайте
     мята           #B2EEDC   плашка выделенной строки таблицы
     яркая мята     #5ADEB7   рамка карточки, плитка под иконкой
     барвинок       #B5C4F5   вторая тинтованная карточка
     сливочный      #F9EBA6   третья
     холодный серый #EAEFF2   четвёртая, единственная не тёплая
     чернила        #151414   156 узлов текста и самая большая тёмная плоскость
     приглушённый   #5A5A5A (47 узлов) и #767676 (22)
     тёмная кнопка  #30363C

   ── Что здесь холст, а что акцент ────────────────────────────────
   У nominal ярких цветов пять, и все пять — размером с плашку: строка
   таблицы, рамка, плитка 40×40 под иконкой. Ни один не выходит на площадь.
   Площадь держат два бежевых, отличающиеся друг от друга на 1.08 по яркости:
   #FDFFF8 и #F3F7EB — глаз читает их не как «два цвета», а как свет и тень
   одного листа. Поэтому здесь ровно та же раскладка, что была у лайма, но
   с заменой белого на тёплый и серого на зеленоватый:
     холст     #FDFFF8, секции без модификатора
     полоса    #F3F7EB, через секцию (правило на #how / #work / #experience / #toolkit)
     карточки  белые #FFFFFF с волосяной обводкой — на бежевой полосе белый
               лист читается листом, на холсте его держит обводка
     мята      плашки, миниатюры кейсов, кнопка обложки, панель отзыва
     чернила   обложка, блок опыта, тёмные плашки тегов
   Разница с лаймовой редакцией одна и принципиальная: там акцент был
   единственным и кричащим (лайм #D3F773 на 12% высоты), здесь акцентов пять
   и все приглушённые. Отсюда «мягче и нейтральнее».

   ── Приёмы, которые схема отменила ───────────────────────────────
   Тон-в-тон на тёмном (лайм на хвойном) снят: у nominal на чёрном лежит
   тот же тёплый почти-белый #FDFFF8, что и на холсте, — то есть ровно
   классическая выворотка. Поэтому --panel-dark-ink здесь холст, а не мята:
   мята на чернилах даёт 11.0 и формально прошла бы, но она вернула бы
   ту самую «цветную» ноту, ради ухода от которой схема и менялась.

   Свечение подвала (радиальное пятно под футером) и вуаль под шапкой
   (тёмный градиент на высоту меню) убраны по прямой просьбе — правила
   .footer--full и .navbar::before ниже по файлу. Вместе с вуалью пришлось
   опустить верхнее свечение обложки: оно и было причиной вуали — самой
   яркой частью приходилось ровно на строку меню. Теперь пятно начинается
   ниже шапки, и меню лежит на ровных чернилах без всякой подложки.

   Вторая пара в середине страницы (у лайма — умбра с оранжевым текстом)
   сохранена, но развёрнута: вместо тёмного поля с цветным текстом —
   светлое мятное поле с обычными чернилами, 14.15. Это единственная
   цветная плоскость страницы крупнее плашки, и она же — тот самый
   «мятный блок».

   Контраст на #FDFFF8 и на #F3F7EB: текст 18.24 / 16.91 · приглушённый
   5.14 / 5.01 · --accent-text 7.15 / 6.62 · --icon 7.15 / 6.62.
   На чернилах: холст 18.24 · приглушённый холст 9.73 · мята 11.0.
   Чернила на плашках: мята 14.15 · барвинок 10.66 · сливочный 15.29 ·
   холодный серый 15.87 · яркая мята 11.0.
   Волосяная #E0EADD: на холсте 1.23, на полосе 1.14 — линия, а не штрих. */

:root {
  /* Пять замеренных тинтов nominal вынесены именами: ниже роли ссылаются
     на них, а не на литералы, и видно, что роль берёт цвет референса,
     а не подобранный на глаз. */
  --mint:              #B2EEDC;   /* мятная плоскость: панель отзыва, плашки, слоты кейсов */
  --mint-bright:       #5ADEB7;   /* яркая мята: кнопка обложки, точки и линия таймлайна, наведение */
  --peri:              #B5C4F5;   /* барвинок */
  --butter:            #F9EBA6;   /* сливочный */
  --cool:              #EAEFF2;   /* холодный серый: единственный не тёплый тинт */
  /* базовые */
  --bg:                #FDFFF8;                    /* холст страницы */
  --bg-alt:            #F3F7EB;                    /* вторая полоса: секции через одну, правило ниже по файлу */
  --ink:               #151414;                    /* основной текст: 18.24 на холсте */
  --muted:             rgba(21, 20, 20, .62);      /* приглушённый: .62 даёт #6D6D6B — ровно между замеренными #5A5A5A и #767676 */
  --accent:            var(--mint-bright);         /* декор: заливка таймлайна, точки сцены, наведение на пункт меню, кнопка обложки */
  --accent-text:       #14634B;                    /* текстовый акцент: единственный цвет схемы, которого у nominal нет.
                                                      Мята на бежевом даёт 1.29 и текстом быть не может; взята она же,
                                                      уведённая в тень до 7.15 на холсте и 6.62 на полосе */
  --accent-2:          var(--peri);                /* барвинок: плашка тега, вторая заливка иконок кейсов */
  /* тёмные панели: шапка, первый экран, блок опыта, мобильное меню */
  --panel-dark:        var(--ink);
  --panel-dark-ink:    var(--bg);   /* классическая выворотка холстом, см. «приёмы, которые схема отменила» */
  --panel-dark-muted:  rgba(253, 255, 248, .72);   /* 9.73 */
  --panel-dark-faint:  rgba(253, 255, 248, .62);
  --panel-ring:        none;                       /* рамка тёмных панелей (inset box-shadow), нужна только тёмной теме */
  /* Светлые карточки: кейсы, панель практики. Белые, а не холст: холст сам тёплый,
     и карточка обязана отличаться от полосы, на которой лежит. Обводка волосяная,
     цветом линии — у nominal рамка карточки ровно такая. */
  --card:              #FFFFFF;
  --card-ring:         inset 0 0 0 1px var(--line);
  /* линии */
  --line:              #E0EADD;                    /* замер: единственная линия на всём референсе, 83 узла */
  --line-on-dark:      rgba(253, 255, 248, .28);
  --line-on-dark-faint: rgba(253, 255, 248, .14);
  /* плоские заглушки иллюстраций и иконки */
  --illus-a:           var(--mint-bright);         /* крупная заливка. Значение на :root работает на графике обложки,
                                                      то есть на чернилах: 11.0. Девять кейсов ниже переопределяют пару сами */
  --illus-b:           var(--peri);                /* второй цвет, там же: 10.7 на чернилах */
  --illus-ink:         var(--panel-dark);          /* тёмные фигуры */
  --illus-text:        var(--ink);                 /* подпись id в заглушке */
  --illus-bg:          var(--mint);                /* фон слота под иллюстрацию в карточке кейса; девять карточек ниже меняют тинт */
  --icon:              var(--accent-text);         /* иконки «How I work»: лежат на полосе, 6.62 */
  /* акцентные заливки — отдельными переменными, чтобы тема могла подставить градиент */
  --tl-fill:           var(--mint-bright);         /* заливка линии таймлайна: полоса цвета на бежевом читается сменой тона, а не яркости */
  --dot-bg:            var(--panel-dark);          /* точка таймлайна: фон и обводка */
  --dot-border:        var(--mint-bright);
  --focus:             var(--accent-text);         /* фокус-рамка: барвинок на холсте даёт 1.7 и рамкой быть не может */
  /* кнопки */
  --btn-primary-bg:    var(--mint-bright);         /* кнопка первого экрана (.btn--blue): яркая мята на чернилах, 11.0 */
  --btn-primary-ink:   var(--ink);
  --btn-primary-hover: rgba(0, 0, 0, .1);
  --btn-dark-bg:       var(--panel-dark);          /* тёмная кнопка, Close в карточках, кружки соцсетей */
  --btn-dark-ink:      var(--panel-dark-ink);
  --btn-dark-hover:    rgba(90, 222, 183, .28);
  /* Светлая кнопка: Get in touch в шапке, Download CV в подвале. Холодный серый явно,
     а не var(--card): карточки белые, и на тёплом холсте подвала белая кнопка исчезла бы.
     Это же значение — фон наведения светлых управляющих элементов ниже по файлу. */
  --btn-light-bg:      var(--cool);
  --btn-light-ink:     var(--ink);
  --btn-light-hover:   rgba(21, 20, 20, .12);
  /* прочее */
  --photo-bg:          rgba(255, 255, 255, .06);   /* подложка портрета, пока картинка не загрузилась */
  /* затемнение под крупным планом кадра. Второй строкой — тон тёмной панели темы, чтобы слой
     не выпадал из палитры; первая остаётся браузерам без color-mix */
  --scrim:             rgba(0, 0, 0, .88);
  --scrim:             color-mix(in srgb, var(--panel-dark) 92%, transparent);
  /* плашка под рисованным портретом первого экрана: лежит на чернилах обложки */
  --illus-plate:       var(--mint);
  /* Вордмарк в шапке — холстом, тем же почти-белым, что и текст на тёмных панелях.
     Исходник (vector.svg на Tilda CDN) залит сплошным #dfdfdf, поэтому brightness(0)
     гасит его в чёрный, а цепочка выводит из чёрного нужный тон. Цепочка не подобрана
     на глаз: матрицы feColorMatrix и feComponentTransfer из filter-effects-1 посчитаны,
     результат ровно #FDFFF8. Пересчитать под другой цвет:
     python3 solve-logo-filter.py "#RRGGBB". Альфа-канал фильтры не трогают,
     сглаживание знака не страдает. */
  --logo-filter:       brightness(0) invert(.541) sepia(.285) saturate(.288) hue-rotate(37.7deg) brightness(1.644) contrast(1.12);
  /* Логотипы сервисов — ровно та же механика, что на действующем kottov.net (Tilda-блок t595):
     в покое grayscale(100%) при opacity .5, на наведении цвет и полная непрозрачность.
     В тёмной схеме цвет не возвращается — там знак только светлеет, см. site3-themes.css. */
  --tools-filter:       grayscale(1);              /* ряд логотипов сервисов, покой */
  --tools-filter-hover: none;                      /*                        наведение */
  --tools-ink:          .7;   /* на бежевой полосе знак при .5 проваливается */
  --tools-ink-hover:    1;
  --sans: 'Satoshi', 'Helvetica Neue', Arial, sans-serif;

  /* ── скругления: одна шкала на всю страницу и на все ширины ──
     04.09.2026. До этого радиусы разъехались: тёмная панель отзыва 30, а точно такой же
     тёмный блок опыта прямо под ней 20 — рядом это читалось как ошибка вёрстки. На телефоне
     те же панели получали то 20 (медиазапрос ≤479), то 28 (app-режим ≤767, стоит в файле ниже
     и перебивал первый) — то есть значение на 375 px зависело от порядка правил, а не от замысла.
     Теперь чисел четыре, они лежат здесь, и ниже по файлу нет ни одного литерала радиуса.
     Ширина экрана радиус больше не меняет: в iOS у карточки на 6.7″ и на 4.7″ углы одинаковые —
     от размера экрана меняется содержимое, а не оправа. */
  --r-panel:   28px;   /* панели во всю ширину, крупные картинки (.corners), плавающие плашки */
  --r-block:   20px;   /* картинки поменьше (.smaller-corners) */
  --r-thumb:   14px;   /* миниатюры кейсов, превью галереи, карточки сцены первого экрана */
  --r-control: 999px;   /* кнопки и фокус-рамки; на телефоне кнопки становятся капсулами */

  /* ── внутренние поля крупных панелей ──
     Одно число на все три: отзыв, опыт, независимая практика. Было 48/56, 72/80 и 48/60,
     а на телефоне блок опыта оставался с полем 80 сверху при 20 у соседей. */
  --panel-pad: 56px 60px;

  /* ── наезд панели независимой практики под блок опыта ──
     05.09.2026. Практика — та же история занятости, поэтому она не отдельная плашка
     через зазор, а лист, задвинутый под тёмный блок: верхний край уходит под него,
     наружу выходят только углы. Число — насколько глубоко заходит; оно же добавляется
     полем внутрь, чтобы текст стоял от нижнего края тёмного блока на обычном --panel-pad.
     Одно на все ширины и заведомо больше --r-panel: радиус от экрана не зависит, и если
     наезд окажется меньше радиуса, скруглённый угол светлой панели вылезет из-под тёмной. */
  --practice-tuck: 44px;

  /* ── кейсы: вынос подложки раскрытой полосы и сторона квадрата в плёнке ──
     04.09.2026. Раскрытая запись перестала растить миниатюру и вместо этого проявляет
     под собой карточный фон. Вынос — насколько подложка выходит за колонку текста
     влево и вправо: на телефоне он равен полю контейнера, и панель доходит до краёв
     экрана. Кадры плёнки — квадраты одной стороны, чтобы лента читалась сеткой. */
  --case-bleed: 28px;
  --case-shot:  380px;
}

/* ── русская версия набрана Manrope ──
   04.09.2026. У Satoshi нет кириллицы: на site3-ru.html каждая русская буква уходила
   в первый фолбэк — Helvetica Neue. Он в системе есть только начертанием Medium, поэтому
   заголовок первого экрана выглядел жирнее и уже английского, а в строке
   «…менеджер в AdTech.» рядом стояли две разные гарнитуры сразу.
   Manrope — тот же класс: геометрический гротеск с широкими просветами, но с полной
   кириллицей и латиницей, поэтому русская страница набрана им целиком, без смеси.
   Сравнение кандидатов (Manrope, Onest, Golos Text, Inter Tight, Nunito Sans)
   на том же заголовке — _probe-fonts.html.
   Селектор html[lang="ru"] (0-1-1) специфичнее :root (0-1-0) и перебивает --sans.
   Сам файл шрифта подключён только на русской странице — ссылка в HEAD_NOTE['ru']
   в lang-strings.py, английская и сербская его не грузят. */
html[lang="ru"] { --sans: 'Manrope', 'Helvetica Neue', Arial, sans-serif; }
/* Ступень «на русской и сербской версиях заголовок первого экрана набирается 60,
   а не 72» снята 05.09.2026 вместе со старым заголовком «Product & Project Manager
   in AdTech»: там русская строка на общем кегле рассыпалась на четыре строки.
   У обложки строки разбиты вручную и кегль считается от ширины окна (clamp … 8.2vw …),
   поэтому число одно на все три языка. Правило было специфичнее клампа (.hero h1
   против .hero__h1) и молча возвращало русской и сербской странице 60 px. */

* { box-sizing: border-box; }
/* scroll-padding-top = высота плавающей шапки вместе с её полями: без него якорь #work уезжает под плашку */
html { scroll-behavior: smooth; scroll-padding-top: 100px; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 500; }
h1 { font-size: 72px; line-height: 1;   margin-bottom: 32px; }
h2 { font-size: 52px; line-height: 1.2; margin-bottom: 40px; }
h3 { font-size: 40px; line-height: 1.2; margin-bottom: 24px; }
h4 { font-size: 32px; line-height: 1.4; margin-bottom: 20px; }
h5 { font-size: 24px; line-height: 1.4; margin-bottom: 10px; }
h6 { font-size: 20px; line-height: 1.2; margin-bottom: 10px; }
p  { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

/* ── общие ── */
/* Поле контейнера объявлено переменной, а не числом в padding: его должны знать
   и потомки. Блоку, которому надо выйти в обрез экрана (веер работ на телефоне),
   иначе пришлось бы держать у себя копию этих 40/32/24/16 и ловить рассинхрон
   при каждой правке. Переменная наследуется, поэтому потомок всегда получает
   ровно то поле, которое победило в каскаде на текущей ширине. */
.container { --pad: 40px; max-width: 1360px; margin: 0 auto; padding: 0 var(--pad); position: relative; }
.section { padding: 96px 0; }
.large-section { padding: 120px 0; }

/* ── полосы через секцию ───────────────────────────────────────────
   Ритм страницы держит не линия между блоками, а смена плоскости: белый холст
   и серая полоса через одну. Секции в разметке прозрачные, фон раньше держал body —
   поэтому красим сами секции, а белый остаётся значением по умолчанию.

   Почему серым помечены именно эти четыре:
     #how + #work идут подряд и красятся в ОДНУ полосу — у .quiet верхнее поле
     снято (padding-top: 0), и разный фон дал бы шов ровно по надписи «Cases»;
     #experience — там тёмный блок опыта и белая панель практики, и панели нужен
     фон, от которого она отличается;
     #toolkit — ряд логотипов сервисов: серая полоса под строкой логотипов
     это обычный приём, а не исключение.
   Отдельных линий-разделителей между секциями нет и не нужно: граница полосы
   уже разделяет, линия поверх неё была бы вторым разделителем на один стык. */
#how, #work, #experience, #toolkit { background: var(--bg-alt); }

/* Шов под панелью отзыва. У #testimonials полей нет вовсе, и нижний край умбряной
   панели совпадал с нижним краем секции: при лаймовом холсте это было не видно —
   фон по обе стороны шва один, — а на белом панель приклеивалась к краю серой полосы
   #experience. Сверху та же история с другого конца: подпись «Testimonials» начиналась
   в 12 px под швом и читалась как подпись серой полосы.
   48 снизу вместе с верхним полем #experience (96) дают 144 — панель стоит на белом. */
#testimonials { padding: 72px 0 48px; }

.title { color: var(--muted); font-size: 24px; line-height: 1.2; margin-bottom: 32px; }
.title.white { color: var(--panel-dark-faint); }
.large-text  { font-size: 20px; line-height: 1.5; }
.medium-text { font-size: 18px; line-height: 1.6; }
.opacity-white { color: var(--panel-dark-muted); }
.opacity-dark  { color: var(--muted); }
.eyebrow { color: var(--muted); letter-spacing: .05em; text-transform: uppercase; font-size: 14px; }

.centered { max-width: 600px; margin: 0 auto; text-align: center; }
.limit { max-width: 480px; }
.limit-medium { max-width: 530px; }
.limit-large  { max-width: 740px; }
.limit-small  { max-width: 370px; }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 50px 64px; }
.space-top { margin-top: 40px; }
.space-top-large { margin-top: 80px; }
.corners { border-radius: var(--r-panel); overflow: hidden; }
.smaller-corners { border-radius: var(--r-block); overflow: hidden; }
.orange-link { color: var(--accent-text); }
.orange-link:hover { opacity: .75; }

/* Плашка под словом (.underlined, приём оригинала jasonfaber) снята 05.09.2026.
   К этому моменту она осталась ровно в одном месте на всю страницу — под «AdTech.»
   в заголовке подвала — а приём, который встречается один раз, читается не как
   система, а как забытый кусок чужого макета. Вместе с классом убраны переменная
   --underline и обёртка <span> в index / ru / sr. Сам --accent остался: он держит
   точки таймлайна, звёздочку в подвале и наведение на пункт меню. */

/* ── кнопки ──
   04.09.2026 у всех вариантов одни поля и одна высота. Было четыре разных набора:
   тёмная 24/32, синяя 18/26, тихая 14/22, белая 16/24 — и в блоке контактов «Get in touch»
   рядом с «Download CV» стояла на 16 px выше соседки. Различает варианты цвет, а не размер;
   размер задан один раз здесь. Высота 56 — минимальный удобный тап и в macOS, и в iOS. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border-radius: var(--r-control); padding: 16px 24px; min-height: 56px;
  font: inherit; cursor: pointer; border: 0; text-align: center;
  transition: box-shadow .2s;
  box-shadow: inset 0 2px 5px 50px transparent;
}
.btn--white { background: var(--btn-light-bg); color: var(--btn-light-ink); }
.btn--white:hover { box-shadow: inset 0 2px 5px 50px var(--btn-light-hover); }
.btn--dark { background: var(--btn-dark-bg); color: var(--btn-dark-ink); }
.btn--dark:hover { box-shadow: inset 0 0 5px 50px var(--btn-dark-hover); }
/* синяя кнопка в разметке сейчас не встречается: правило оставлено вместе с переменными
   --btn-primary-*, чтобы вернуть заливку одному действию, не собирая вариант заново */
.btn--blue { background: var(--btn-primary-bg); color: var(--btn-primary-ink); }
.btn--blue:hover { box-shadow: inset 0 2px 5px 50px var(--btn-primary-hover); }
/* тихая кнопка: контур вместо заливки. Сайт-визитка, а не продающая страница —
   зазывать читателя заливкой на каждом экране незачем. Заливку оставляем одному
   действию в блоке контактов, всё остальное говорит вполголоса. */
.btn--quiet {
  background: transparent; color: var(--panel-dark-ink);
  box-shadow: inset 0 0 0 1px var(--line-on-dark);
}
.btn--quiet:hover { box-shadow: inset 0 0 0 1px var(--line-on-dark), inset 0 0 5px 50px rgba(255, 255, 255, .08); }
/* контурная на светлом: «Show more cases» под списком работ. --quiet рассчитана на тёмную
   панель (--panel-dark-ink) и на светлой секции пропала бы. Заливка при наведении — --card,
   тот же приём, что у наведения на полосу кейса: поверхность, а не новый цвет. */
.btn--outline { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
/* Налив на наведении — холодный белый явно, а не var(--card): карточки стали белыми,
   и на белой секции белый налив не виден вовсе. Те же три места ниже: стрелки ленты
   кадров и стрелки веера работ. */
.btn--outline:hover { box-shadow: inset 0 0 0 1px var(--line), inset 0 0 5px 50px var(--btn-light-bg); }
/* кнопка-раскрывашка: тот же знак, что у «Case details» и у «Details» в опыте —
   плюс в свёрнутом виде, тире в раскрытом. Знак берётся из состояния aria-expanded,
   которое кнопка и так держит: второго источника правды под иконку не заводим.
   Крестик сюда не подходит — на сайте он нигде не встречается, а в общем словаре
   интерфейсов значит «закрыть, убрать с глаз», а не «свернуть обратно к пяти». */
.btn--fold::after { content: '+'; font-size: 22px; line-height: 1; }
.btn--fold[aria-expanded="true"]::after { content: '\2013'; }
.btn svg { width: 18px; height: 18px; flex: none; }

/* ── шапка: плавающая плашка ──
   Закреплена при прокрутке и не прилеплена к краю экрана: сама .navbar — прозрачный
   слой во всю ширину, а видимая плашка это .navbar__grid — скруглённая, шириной
   контейнера, с полями от краёв окна.
   fixed, а не sticky: панель лежит ПОВЕРХ контента, и первый экран уходит тёмным
   фоном под неё до самого верха. Со sticky над первым экраном оставалась бы светлая
   полоса фона страницы, а на ней пропадал бы белый логотип. Высоту компенсирует
   padding-top первого экрана.
   Вверху страницы плашки не видно: логотип и меню лежат прямо на тёмном первом
   экране, стекло и тень проявляются при прокрутке, по классу .is-stuck.
   Меню-шторка на планшете позиционируется absolute от .navbar__grid (у .container
   есть position: relative), поэтому ложится ровно по ширине плашки. */
.navbar {
  color: var(--panel-dark-ink);
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  padding: 12px 0;
  background: transparent;
}
/* вертикальные поля 8: кнопка «Get in touch» высотой 60 иначе торчит за края
   плашки, у которой высота считалась по логотипу (56) */
.navbar__grid {
  /* насколько видимая плашка вжата внутрь бокса контейнера; на телефоне обнуляется */
  --plaque-inset: var(--pad);
  /* воздух от края плашки до логотипа и языков; заведомо меньше --r-panel не берём */
  --plaque-air: 24px;
  display: grid; grid-template-columns: 1fr 1.5fr 1fr; align-items: center;
  padding-top: 8px; padding-bottom: 8px;
  background: transparent;
}
/* ── ширина плашки: ровно колонка контента ──
   05.09.2026. Плашка рисовалась фоном самого .navbar__grid, то есть по боксу
   .container вместе с его полем --pad. На 1440 это 40…1400 при колонке контента
   80…1360: скруглённые углы выходили за все блоки страницы на 40 px и читались
   как ошибка вёрстки, а не как приём. Теперь фон вынесен в ::before, вжатый внутрь
   на те же --pad — края плашки садятся ровно на колонку, а логотип и языки уходят
   внутрь на --plaque-air. Поля заданы отдельным правилом .container.navbar__grid:
   у шортката .container внутри медиазапросов та же специфичность и он стоит ниже
   по файлу, поэтому одноклассовое правило он бы перебил. */
.container.navbar__grid {
  padding-left: calc(var(--plaque-inset) + var(--plaque-air));
  padding-right: calc(var(--plaque-inset) + var(--plaque-air));
}
.navbar__grid::before {
  content: ''; position: absolute; z-index: -1;
  top: 0; bottom: 0; left: var(--plaque-inset); right: var(--plaque-inset);
  border-radius: var(--r-panel);
  transition: background .25s ease, box-shadow .25s ease;
}
.navbar.is-stuck .navbar__grid::before {
  background: color-mix(in srgb, var(--panel-dark) 72%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18), inset 0 0 0 1px var(--line-on-dark-faint);
}
/* ── прогресс чтения залит в саму плашку шапки ──
   Страница разбора кейса — 13 000 px и шесть актов, ориентира «где я» не было
   вообще. Отдельная полоска в самом верху окна читалась бы как элемент браузера,
   поэтому прогресс встроен в плашку меню: мягкая мятная заливка прочитанной
   части. Яркая кромка 3 px по нижнему краю снята 09.10.2026 по просьбе: полоса
   кричала громче меню, отметкой хватает края самой заливки.
   Долю в --read пишет скрипт страницы; класс has-progress вешает он же, поэтому
   без скрипта и на коротких страницах плашка остаётся обычной.
   Слой ::after, а не ::before: ::before держит стекло и тень, и рисовать заливку
   поверх него надо более поздним псевдоэлементом при том же z-index. */
.navbar.has-progress .navbar__grid::after {
  content: ''; position: absolute; z-index: -1;
  top: 0; bottom: 0; left: var(--plaque-inset); right: var(--plaque-inset);
  border-radius: var(--r-panel);
  opacity: 0; transition: opacity .25s ease;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--mint-bright) 15%, transparent) 0 calc(var(--read, 0%) - 32px),
      transparent var(--read, 0%));
}
/* Показывается вместе со стеклом: на первом экране плашки не видно, и полоса
   висела бы на обложке сама по себе */
.navbar.has-progress.is-stuck .navbar__grid::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .navbar.has-progress .navbar__grid::after { transition: none; }
}

/* ── вуали под шапкой больше нет (05.09.2026, вместе со схемой «Мята на бежевом») ──
   Была: тёмный градиент в прозрачность на высоту 128 px, гаснущий при прокрутке.
   Заводился он ради одного — верхнее свечение обложки самой яркой частью приходилось
   ровно на строку меню, и светлый текст меню ложился на светлое пятно.
   Снят по просьбе: градиент читался как отдельная плашка поверх ровной обложки.
   Вместо него причина убрана в корне — верхнее пятно .hero::before ниже по файлу
   опущено под шапку, и меню лежит на ровных чернилах без всякой подложки.
   При прокрутке по-прежнему работает стекло .is-stuck. */
.brand { padding: 16px 0; display: inline-flex; align-items: center; }
/* wordmark с действующего kottov.net (110×23 в его шапке): светлая версия #dfdfdf выбелена фильтром до чистого белого.
   viewBox обоих SVG 500×103, знак занимает всю ширину, полей нет: 24px высоты дают 117px ширины.
   Ширина задана явно, а не auto: без сети картинка не грузится, и auto растягивал бокс до колонки грида (366×103). */
.brand__logo { display: block; height: 24px; width: 117px; max-width: 117px; object-fit: contain; object-position: left center; filter: var(--logo-filter); }
.nav-menu { display: flex; justify-content: center; align-items: center; gap: 36px; }
.nav-link { color: var(--panel-dark-ink); padding: 16px 0; display: inline-block; transition: color .2s; }
.nav-link:hover { color: var(--accent); }
.nav-menu .btn { display: none; }
.nav-right { display: flex; justify-content: flex-end; align-items: center; gap: 10px; }
.menu-btn { display: none; background: none; border: 0; padding: 18px 0 18px 18px; cursor: pointer; }
.menu-btn i { display: block; height: 2px; width: 20px; background: var(--panel-dark-ink); margin: 4px 0; }
.menu-btn i:nth-child(2) { width: 10px; margin-left: auto; }

/* ── переключатель языков: EN · RU · SR между меню и кнопкой; активный жирнее и белым, остальные приглушённые.
   На ≤991 уходит из шапки в бургер-меню (.lang--menu). Полоса .lang-note под шапкой — только при ?lang=ru / ?lang=sr. ── */
.lang { display: inline-flex; align-items: center; gap: 6px; margin-right: 14px; font-size: 14px; letter-spacing: .05em; white-space: nowrap; }
.lang a { color: var(--panel-dark-muted); padding: 8px 2px; transition: color .2s; }
.lang a:hover { color: var(--panel-dark-ink); }
.lang a.is-active { color: var(--panel-dark-ink); font-weight: 700; }
.lang__sep { color: var(--panel-dark-faint); }
.lang--menu { display: none; }
.lang-note { background: var(--btn-light-bg); color: var(--btn-light-ink); font-size: 14px; line-height: 1.4; padding: 10px 40px; text-align: center; }
.lang-note[hidden] { display: none; }

/* ── первый экран: обложка одной фразой (05.09.2026) ──────────────────────
   Перенесено из чернового _preview-hero-upsunday.html, замеры и разбор
   референсов остались там же в шапке файла. Композиция — upsunday.co,
   свечения — supadupa.nl/nl, тот же сайт, откуда снята палитра lime.

   Что было до: тёмный экран в две колонки — заголовок «Product & Project
   Manager in AdTech», интро в два абзаца, три канала связи, стрелка вниз
   и сцена справа (портрет на диске с карточками Recommendation и Taxonomy).
   Всё это снято: у референса первый экран — ОДНА фраза и больше ничего,
   и половина кадра под ней пустая. Разметку убрали из index.html целиком
   (она осталась в _backup-2026-09-04/), а правила ниже по файлу оставлены:
   возврат — вернуть разметку в секцию .hero, CSS править не придётся.

   Куда делось содержимое: три канала связи и так стоят в блоке контактов,
   рекомендация и дерево категорий разобраны в кейсах. Из страницы пропало
   только предложение «I work inside an advertising platform…» — оно
   осталось в <meta name="description"> и в блоке «How I work».

   100svh, а не vh: в мобильных браузерах vh считает экран без адресной
   строки, и нижний край фразы уезжает под неё. min-height, а не height:
   русский заголовок на невысоком ноутбуке растит экран, а не обрезается. */
.hero {
  --hero-pad-b: 96px;
  min-height: 100svh; display: grid; align-items: center;
  padding: 132px 0 var(--hero-pad-b);
  background: var(--panel-dark); color: var(--panel-dark-ink);
  position: relative; overflow: hidden; isolation: isolate;
}
/* width: 100% обязателен, иначе контейнер сжимается по самой длинной строке.
   У .container стоит margin: 0 auto, а автополя у grid-элемента отменяют stretch —
   колонка схлопывается до max-content. Фраза от этого центрируется как надо,
   но text-align: center внутри узкого блока — совпадение, а не раскладка,
   и на сербской версии блок вышел 669 px при окне 1440. */
.hero > .container { width: 100%; }

/* ── свечения обложки ──
   Геометрия по замеру supadupa (доли от вьюпорта 1280×720): у них это две
   картинки из Figma с feGaussianBlur, вывезенные на CDN. Свои ассеты тянуть
   с чужого домена нельзя, а форма пятна в размытии не читается — поэтому
   здесь радиальные градиенты с blur по тем же координатам.

   ::before — верхнее, по центру сверху: эллипс уведён выше края кадра, поэтому
   видна только нижняя дуга. ::after — левое, от середины экрана вниз.

   blur(30px) вместо их stdDeviation=25: у них размытие считается в координатах
   SVG (viewBox 907 при отрисовке в 960), то есть на экране крупнее номинала.

   05.09.2026, схема «Мята на бежевом». Геометрия обоих пятен прежняя, изменился
   цвет — и это прямое следствие снятой вуали под шапкой (см. .navbar выше).
   Было: сплошной холст. На хвойной обложке это читалось светом, на чернилах —
   серым туманом, а строка меню, набранная тем же холстом, ложилась прямо
   в ядро пятна (стоп 58% при closest-side, то есть средние 58% высоты бокса,
   у верхнего пятна это −21…9% высоты обложки). Ровно ради этого места и заводилась
   вуаль.
   Стало: яркая мята 30 и 26% плотности. Ядро верхнего пятна даёт #2A5145,
   холст на нём 8.82 — меню читается на самой светлой точке свечения без всякой
   подложки, и вуаль больше не нужна. Заодно пятно перестало быть серым:
   на чернилах мята под тридцатью процентами читается глубоким зелёным свечением,
   то есть акцентом схемы, а не выцветшим белым.
   z-index −1 плюс isolation на секции: пятна ложатся на заливку, но остаются
   под текстом и не всплывают над шапкой. */
.hero::before, .hero::after { content: ""; position: absolute; z-index: -1; pointer-events: none; }
.hero::before {
  top: -32%; left: 15%; width: 62%; height: 52%;
  background: radial-gradient(closest-side ellipse at 50% 50%,
              color-mix(in srgb, var(--mint-bright) 30%, transparent) 0%,
              color-mix(in srgb, var(--mint-bright) 30%, transparent) 58%,
              color-mix(in srgb, var(--mint-bright) 16%, transparent) 76%,
              transparent 100%);
  filter: blur(30px);
}
.hero::after {
  top: 46%; left: -30%; width: 74%; height: 104%;
  background: radial-gradient(closest-side ellipse at 46% 44%,
              color-mix(in srgb, var(--mint-bright) 26%, transparent) 0%,
              color-mix(in srgb, var(--mint-bright) 26%, transparent) 56%,
              color-mix(in srgb, var(--mint-bright) 14%, transparent) 76%,
              transparent 100%);
  filter: blur(30px);
}

/* Кромки в белый (.up-tail из черновика) здесь нет: у supadupa тёмный блок
   обрывается в белый фон страницы, а у нас под обложкой идёт лаймовая полоса
   тегов — обрывать тёмное в лайм значит показать шов, которого в оригинале нет. */

/* ── фраза ──
   Кегль подобран по самой длинной строке: она доходит почти до края контейнера
   (1280 при max-width 1360 и полях 40), и блок читается плакатом, а не абзацем.
   line-height .92 и трекинг −.035em: у upsunday строки почти касаются, и именно
   эта плотность делает фразу объектом.
   text-wrap: balance не ставим — строки разбиты вручную через <br>, потому что
   плашки должны попасть в конкретные места строк.
   Кегль классом, а не .hero h1: правило .hero h1 { font-size: 56px } на 992–1199
   было специфичнее клампа и гасило его. Оно снято вместе со старым заголовком. */
.hero__h1 {
  margin: 0; text-align: center; color: var(--panel-dark-ink);
  font-weight: 900;
  font-size: clamp(var(--cover-min, 30px), var(--cover-step, 8.2vw), var(--cover-max, 122px));
  line-height: .92; letter-spacing: -.035em;
}

/* ── кегль по языкам ──
   Кламп задан переменными, потому что длина самой длинной строки в трёх языках разная,
   а строки здесь разбиты вручную: перенести слово, чтобы уместиться, фраза не может.
   Замер при кегле 118 и контейнере 1280: английская «is automated.» с рядом карточек
   занимает 1055, сербская «automatizovana.» — 1223, русская «автоматизирована.» — 1385.
   На общем кегле русская строка не помещалась, и ряд карточек уезжал на свою строку —
   посреди фразы висела полоска из трёх картинок.
   Поэтому у русской и сербской версий свой шаг и свои границы: строка по-прежнему
   доходит почти до края контейнера, то есть плакат остаётся плакатом, но не рвётся.
   Причина та же, по которой у старого заголовка первого экрана русский набирался 60
   против английских 72 — только считается теперь от ширины окна, а не числом.
   Нижняя граница тоже своя: на 375 при общих 30 px русская строка вылезала за поля. */
/* 10.10.2026: русский заголовок сменился на «Рутина — машине. Решения — мне.», длинного
   «автоматизирована.» в нём больше нет, и русская строка уже английской. Свой урезанный
   кламп ей больше не нужен — набирается общим, как английская. */
html[lang="sr"] .hero__h1 { --cover-min: 28px; --cover-step: 7.9vw; --cover-max: 118px; }

/* ── медиа-плашка внутри строки ──
   Высота в em, чтобы плашка масштабировалась вместе с кеглем. .74em — высота
   строчной буквы Satoshi: выше плашка распирает межстрочное расстояние, ниже —
   теряется между слов. vertical-align −.06em сажает её на оптическую середину
   строки: по baseline она встаёт слишком высоко, по middle — проваливается. */
.mm {
  display: inline-block; vertical-align: -.06em;
  height: .74em; border-radius: .16em; overflow: hidden;
  margin: 0 .1em; background: rgba(255, 255, 255, .1);
}
.mm img { display: block; width: 100%; height: 100%; object-fit: cover; }
.mm--wide { width: 1.55em; }
.mm--sq   { width: .78em; }

/* Ряд из трёх карточек внахлёст — как в образце: не общая подложка с зазорами,
   а три отдельные карточки, у каждой своя белая рамка, и они заезжают одна
   на другую. Рамка не декор: без неё в наложении не видно, где кончается одна
   карточка и начинается следующая. Порядок перекрытия лесенкой, как сдвинутая
   стопка слайдов; нахлёст .17em при ширине .78em — примерно пятая часть. */
.mm-row {
  display: inline-flex; align-items: center;
  vertical-align: -.06em; margin: 0 .1em; height: .84em;
}
.mm-row .mm {
  margin: 0; height: 100%; position: relative;
  border-radius: .17em; background: #ECECEC;
  box-shadow: 0 0 0 .026em #FFFFFF;   /* тонкая рамка: толстая читалась как паспарту */
}
.mm-row .mm + .mm { margin-left: -.17em; }
.mm-row .mm:nth-child(1) { z-index: 1; }
.mm-row .mm:nth-child(2) { z-index: 2; }
.mm-row .mm:nth-child(3) { z-index: 3; }

/* В карточках — три объёмных знака площадок: Яндекс, Google Ads, Meta Ads.
   Ровно те кабинеты, где рутина и автоматизируется, поэтому карточки стоят
   при слове automated и говорят предметно. Плоские логотипы инструментов
   пробовались и сняты: на белом фоне стопка превращалась в ряд иконок,
   а у Директа и Метрики знак вообще один и тот же.

   Кадр задан фоном, а не <img>: связка object-position + transform: scale
   не давала попасть в точку — object-position двигает кадр, scale тянет его
   от центра бокса, и они спорят. background-size задаёт увеличение (175%,
   чтобы знак заполнил карточку и поля снимка ушли за край),
   background-position — точку самого снимка. */
.mm-row .mm { background-repeat: no-repeat; background-size: 175%; background-position: center 42%; }
.mm-row .mm--ya     { background-image: url(hero-cards/yandex.webp); }
.mm-row .mm--google { background-image: url(hero-cards/google-ads.webp); }
.mm-row .mm--meta   { background-image: url(hero-cards/meta-ads.webp); }

/* Портрет: у исходника кадр по колено (800×1405), в плашке нужна голова —
   object-position тянет кадр вверх, scale подрезает поля. Подложка светлая:
   у иллюстрации вырезанный фон и чёрный контур, на тёмном фигура и линии
   тонут. Тот же приём, что диск .scene__disc под портретом на прежнем экране. */
.mm--face { background: var(--panel-dark-ink); }
/* 05.09.2026 кадр отпущен: было scale(1.5) при 4% — подбородок стоял ровно на нижней
   кромке плашки, а макушка на верхней, и голова читалась зажатой в коробке. 1.28 при 3%
   оставляет воздух под подбородком и заводит в кадр воротник.
   Панорама по прокрутке: окно плашки едет вниз по рисунку, и пока обложка уходит вверх,
   в нём успевает показаться рубашка. Стартовый кадр 3%, конечный 12% — и не больше:
   на 18% глаза уже срезаются верхней кромкой, и в плашке остаётся одна борода.
   Ход задаёт скрипт (--face-y в index.html, рядом с остальными слушателями прокрутки),
   а не animation-timeline: scroll(): таймлайны прокрутки в Safari появились только
   в 26-й, а этот сайт смотрят с айфона. Значение по умолчанию здесь же, поэтому без
   скрипта плашка стоит в стартовом кадре — исправленном, а не в прежнем зажатом. */
.mm--face img { object-position: 50% var(--face-y, 3%); transform: scale(1.28); transform-origin: 50% 8%; }

/* Рисованная стрелка вместо слова — у upsunday она оранжевая и от руки.
   Здесь тот же жест на фирменном алом: на хвойном он даёт 3.73 — для текста
   мало, для декоративной линии достаточно.
   Высота .84em: на низкой полосе петля схлопывается в пятно и читается кляксой.
   Выше поднимать нельзя — inline-block выше строки раздвинет межстрочное
   расстояние, а строки здесь стоят вплотную (line-height .92). Поэтому
   крупность добрана не боксом, а обрезкой viewBox по самому рисунку. */
.mm-arrow { display: inline-block; vertical-align: -.08em; width: 1.8em; height: .84em; margin: 0 .08em; }
.mm-arrow svg { display: block; width: 100%; height: 100%; fill: none; stroke: var(--accent); stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }

/* ── правила снятого первого экрана ─────────────────────────────────────────
   Ниже до конца блока — стили двухколоночного экрана, который стоял здесь
   до 05.09.2026: интро, три канала связи, стрелка вниз, сцена с портретом
   и карточками. В разметке их больше нет. Оставлены целиком, как и правила
   снятых раньше .hero__graph, .hero__meta и .metrics: возврат — заменой
   содержимого секции .hero, без правки CSS. */
.hero .split { grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
/* stretch, а не start от .split: колонка тянется на высоту сцены, и только тогда
   стрелка внизу (margin-top: auto) действительно уезжает к нижней кромке */
.hero__text { display: flex; flex-direction: column; gap: 24px; align-self: stretch; }
.hero__lede { max-width: 530px; }
.hero__lede p { color: var(--panel-dark-muted); }
/* .hero__meta — строка «Белград, Сербия · открыт к ролям» — снята с первого экрана
   03.09.2026: город есть в блоке контактов и в футере, а «открыт к ролям» — заголовок
   того же блока. Правило оставлено на случай возврата. */
.hero__meta { margin-top: 16px; color: var(--panel-dark-muted); }
.hero__cta { margin-top: 16px; }
/* три канала связи вместо одной кнопки «Get in touch» */
.hero__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 32px; }
.hero__actions .btn svg { fill: currentColor; }
/* стрелка вниз: кольцо в контур шапки-кнопки и подпись рядом.
   margin-top: auto прижимает её к низу колонки, align-self: start — чтобы ссылка
   была шириной по содержимому, а не во всю колонку (иначе клик ловит пустое место) */
.hero__scroll {
  display: inline-flex; align-items: center; gap: 14px;
  margin-top: auto; align-self: start; padding-top: 32px;
  color: var(--panel-dark-muted); font-size: 15px; line-height: 1.4;
  transition: color .2s;
}
.hero__scroll:hover { color: var(--panel-dark-ink); }
.hero__scroll i {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1px var(--line-on-dark);
  transition: box-shadow .2s, transform .2s;
}
.hero__scroll:hover i { box-shadow: inset 0 0 0 1px var(--line-on-dark), inset 0 0 5px 50px rgba(255, 255, 255, .08); }
/* стрелка нарисована линией, а не заливкой: тот же приём, что у иконок нижней панели разделов */
.hero__scroll svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* короткий кивок вниз раз в три секунды: подсказка должна попасться на глаза,
   но не дёргаться под текстом всё время чтения. Отключается ниже вместе с остальной анимацией */
@keyframes hero-nudge { 0%, 78%, 100% { transform: translateY(0); } 87% { transform: translateY(4px); } }
.hero__scroll i { animation: hero-nudge 3s ease-in-out infinite; }
.hero__scroll:hover i { animation: none; transform: translateY(3px); }
.hero__graph { max-width: 339px; }
.hero__graph svg { width: 100%; height: auto; display: block; }
/* плоский график: полигоны — основной цвет иллюстраций, конечная точка — второй, «дырки» — тёмные фигуры */
.hero__graph .g-a { fill: var(--illus-a); }
.hero__graph .g-b { fill: var(--illus-b); }
.hero__graph .g-ink { fill: var(--illus-ink); }
/* ── сцена первого экрана: рисованный портрет и плоская графика вокруг ──
   03.09.2026, вариант B из hero-variants.html. Раньше здесь была рамка .hero__photo
   с кадрированием фотографии (cover + позиция 50/30); теперь портрет с прозрачным фоном
   стоит на диске, а вокруг разложены карточка, дерево и точечная сетка.
   Ширина сцены 470 = 300 фигуры плюс поля под карточки, которые заезжают на неё с боков.
   Высота 540 задана явно, а не пропорцией: дети абсолютные, содержимого в потоке нет. */
/* Все размеры внутри сцены заданы через множитель --s: дети позиционированы абсолютно,
   их не подхватит ни проценты, ни сетка. Адаптив меняет одно число, а не двадцать правил.
   Кегли подписей на карточках из масштаба выведены: при --s .85 они ушли бы в 11 px. */
/* ── сцена первого экрана: рисованный портрет и плоская графика вокруг ──
   Вариант B из hero-variants.html. Версия с городом на фоне (portrait-city.svg)
   пробовалась 03.09.2026 и отменена: композиция не про его работу. Файл остался
   в illustrations/hero/ вместе с исходником illustrations/download.svg.

   Все размеры внутри сцены заданы через множитель --s: дети позиционированы абсолютно,
   их не подхватит ни проценты, ни сетка. Адаптив меняет одно число, а не двадцать правил.
   Кегли подписей на карточках из масштаба выведены: при --s .84 они ушли бы в 11 px.
   overflow: hidden — чтобы диск и фигура обрезались по одной линии: у иллюстрации
   кадр кончается на бедре, и без общего низа этот срез читался бы как брак. */
/* Отрицательный нижний margin ровно на нижний отступ первого экрана: без него сцена
   обрывалась на 56 px выше края тёмной панели и срез фигуры с диском повисал в воздухе —
   читался не как кадрирование, а как брак. Теперь линия среза = граница экрана,
   обрезает её overflow: hidden у .hero. */
.hero__scene { --s: 1; position: relative; justify-self: end; overflow: hidden;
               width: calc(470px * var(--s)); height: calc(527px * var(--s));
               margin-bottom: calc(-1 * var(--hero-pad-b)); }

/* фигура: пропорция файла 800×1405, поэтому 300 по ширине дают 527 высоты — почти вся сцена */
.hero__scene img {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: calc(300px * var(--s)); height: auto; display: block; z-index: 2;
}
/* Диск 400 при фигуре 300: 300 накрывали только бёдра, и брюки ниже круга уходили
   в фон. Круг спущен на 70 под нижнюю кромку сцены — она его срезает по той же
   линии, что и фигуру, поэтому оба низа совпадают */
.scene__disc {
  position: absolute; left: 50%; bottom: calc(-70px * var(--s)); transform: translateX(-50%);
  width: calc(400px * var(--s)); height: calc(400px * var(--s));
  border-radius: 999px; background: var(--illus-plate); z-index: 1;
}
/* карточки: белая — рекомендация, акцентная — дерево категорий. Обе заезжают на фигуру */
.scene__card {
  position: absolute; z-index: 3; width: calc(196px * var(--s));
  padding: calc(12px * var(--s)) calc(14px * var(--s));
  border-radius: calc(var(--r-thumb) * var(--s)); background: var(--card); color: var(--ink);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .25);
}
.scene__card b { display: block; font-size: 13px; line-height: 1.3; margin-bottom: 6px; }
.scene__card span { display: block; font-size: 12px; line-height: 1.35; color: var(--muted); }
.scene__card--rec { left: 0; top: calc(30px * var(--s)); }
/* вторая карточка отличается фоном: два одинаковых белых прямоугольника на сцене
   читались как один интерфейс, а это две разные вещи из его работы.
   Фон здесь --bg, а не --accent, как было в прежней палитре. Алый тёмный: на нём
   текст карточки падал до 3.21, полоски дерева до 2.71, а точки дерева пропадали
   совсем — они красятся тем же --accent, что и фон, и давали контраст 1.00.
   На лайме текст возвращается к 11.49, полоски примерно к 7, точки видны. */
.scene__card--tax { right: 0; bottom: calc(52px * var(--s)); width: calc(178px * var(--s));
                    background: var(--bg); }
.scene__card--tax span { color: var(--ink); opacity: .75; }
/* дерево внутри карточки: заливки классами через переменные темы, без атрибутов fill */
.scene__tree { width: calc(96px * var(--s)); height: calc(79px * var(--s)); margin: 2px 0 8px; }
.scene__tree .t-bar { fill: var(--illus-ink); opacity: .75; }
.scene__tree .t-dot { fill: var(--accent); }

/* Сцена растёт вместе с высотой окна: на 1440×900 фигура в исходном размере висела бы
   в нижней трети пустой обложки. Ступени стоят ПОСЛЕ базового правила .hero__scene —
   иначе его `--s: 1` перебивает их по порядку в файле, и масштаб молча не меняется.
   Потолок 1.16 упирается не в высоту, а в ширину: контейнер шире 1360 не становится,
   каждые +0.1 масштаба забирают 47 px у текстовой колонки, и уже на 1.24 заголовок
   первого экрана ломается с двух строк на три (проверено на 1920×1080). Поэтому третьей
   ступени для высоких экранов нет: на них фигура просто стоит на нижней кромке обложки.
   Нижняя граница 1360 — ширина, на которой контейнер выходит на свой максимум: на 1280
   в текстовой колонке остаётся 628 px, и заголовок ломается на три строки уже при 1.08. */
@media (min-width: 1360px) and (min-height: 780px) { .hero__scene { --s: 1.08; } }
@media (min-width: 1360px) and (min-height: 880px) { .hero__scene { --s: 1.16; } }

/* полоса из трёх чисел — нижняя кромка первого экрана */
.metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px 16px; margin-top: 40px; }
.metric { border-top: 1px solid var(--line-on-dark); padding-top: 24px; }
.metric__n { font-size: 52px; line-height: 1.2; margin-bottom: 8px; }
.metric .opacity-white { font-size: 15px; line-height: 1.4; }

/* ── How I work: три принципа одной полосой ──
   04.09.2026: липкая колонка, схемы 3:2 и абзацы «In practice» сняты, блок сжат
   до одной полосы — хайрлайн сверху, номер, принцип, строка. Разметка та же, что у
   «Same market, four seats» на первом экране, только линия светлая (--line): у блока
   не появляется собственного оформления, он берёт готовое с этой же страницы.
   Прежние варианты живыми лежат в how-variants.html, разбор — в HOW-BLOCK-OPTIONS.md. */
/* заголовок мельче, чем у Work и Testimonials (56 px): блок стал самым лёгким на
   странице, и с общим кеглем он спорил бы за внимание с идущим следом списком кейсов */
#how .centered { max-width: 760px; }   /* 600 у .centered рвёт строку на «role.» */
#how .centered h2 { font-size: 40px; margin-bottom: 0; }
.principles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; margin-top: 48px; }
.principle { border-top: 1px solid var(--line); padding-top: 24px; }
.principle__n { display: block; margin-bottom: 14px; }
.principle h4 { font-size: 24px; line-height: 1.3; margin-bottom: 12px; }
.principle p { font-size: 17px; line-height: 1.6; color: var(--muted); }
/* иконки 44 px сняты 03.09.2026 вместе с переходом на схемы: столбики, стрелка и три
   кружка подошли бы любому пункту и любому чужому сайту. Правило оставлено на случай возврата */
.card__icon { width: 44px; height: 44px; display: block; fill: var(--icon); }

/* ── таймлайн ── */
/* position/z-index — чтобы тёмный блок лежал ПОВЕРХ панели практики, которая идёт следом
   по потоку и без этого перекрывала бы его снизу */
/* Текстовый акцент внутри тёмного блока — яркая мята, а не её тень.
   05.09.2026. --accent-text (#14634B) подобран под светлые плоскости, где он даёт
   6.6…7.2; на чернилах у него 2.34, и «Since July 2026», годы под катом и «Details»
   на тёмном поле проваливались. Роль переопределена на самом блоке, поэтому правила
   .role__since / .fold__toggle / .tl__years ниже трогать не нужно — они уже читают
   --accent-text и на светлых секциях остаются прежними. Яркая мята на чернилах 11.0. */
.timeline-block { --accent-text: var(--mint-bright); position: relative; z-index: 2; background: var(--panel-dark); color: var(--panel-dark-ink); border-radius: var(--r-panel); padding: var(--panel-pad); box-shadow: var(--panel-ring); }
.timeline-block h2 { margin-bottom: 32px; }
/* четыре позиции на одном рынке — над таймлайном, внутри тёмного блока */
.eyebrow.white { color: var(--panel-dark-faint); }
.seats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.seat { border-top: 1px solid var(--line-on-dark); padding-top: 20px; }
.seat__label { font-size: 24px; line-height: 1.4; }
.seat__years { margin-top: 4px; }
.seats__note { margin-top: 24px; max-width: 740px; }
.timeline { position: relative; margin-top: 48px; }
/* правая колонка ролей шире левой (1.4fr), иначе списки набирались в 464px и тянули секцию за 3400px */
.tl { position: relative; z-index: 2; display: grid; grid-template-columns: 1fr 40px 1.4fr; gap: 40px; margin-bottom: 32px; }
.tl:last-of-type { margin-bottom: 0; }
.tl__left { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; }
.tl__org { text-align: left; }
.tl__org .medium-text { margin-bottom: 14px; }
.tl__logo { height: 22px; width: auto; filter: brightness(0) invert(1); opacity: .7; }
/* оптическое выравнивание: при общей высоте 22px площадь заливки расходилась в 2.9 раза
   (fh 970px² против complete 331px²), логотипы читались как разные по весу.
   Высота гасит разницу в массе, opacity добивает остаток — до ~1.4 раза. */
.tl__logo[data-logo="fh"] { height: 20px; opacity: .64; }
.tl__logo[data-logo="yandex"] { height: 21px; opacity: .66; }
.tl__logo[data-logo="dorado"] { height: 22px; opacity: .68; }
.tl__logo[data-logo="noroot"] { height: 24px; opacity: .75; }
.tl__logo[data-logo="complete"] { height: 26px; opacity: .8; }
.tl__year { position: sticky; top: 100px; font-size: 24px; line-height: 1.4; white-space: nowrap; text-align: right; }
.tl__center { display: flex; justify-content: center; align-items: flex-start; padding-top: 11px; }
.tl__dot { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--dot-border); background: var(--dot-bg); flex: none; }
.tl__right { max-width: 580px; }
.role__since { color: var(--accent-text); font-size: 14px; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 8px; }
.role h5 { margin-bottom: 8px; }
/* свёрнутая запись: под названием роли одна-две фразы выжимки; буллеты целиком — под катом (.fold__body) */
.role__summary { margin: 0; color: var(--panel-dark-muted); font-size: 16px; line-height: 1.5; }
.role ul { color: var(--panel-dark-muted); font-size: 17px; line-height: 1.6; padding: 12px 0 0 18px; list-style: disc; }
.role li { margin-bottom: 8px; }
.role + .role { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--line-on-dark-faint); }
/* линия стоит по центру колонки точек, а не на 50%: колонки 1fr / 40px / 1.4fr с зазором 40 — центр = (100% − 40 − 2×40) / 2.4 + 40 + 20 */
.tl__line { position: absolute; top: 0; bottom: 0; left: calc((100% - 120px) / 2.4 + 60px); width: 2px; margin-left: -1px; background: var(--line-on-dark-faint); }
.tl__fill { width: 100%; height: 0; background: var(--tl-fill); }

/* ── независимая практика: белая панель, задвинутая под тёмный блок опыта ──
   Зазор 16px снят 05.09.2026: практика — часть той же трудовой истории, а не соседний
   сюжет. Отрицательное поле сверху уводит край под тёмный блок, наружу остаются только
   углы — панель читается как второй лист в стопке. Тот же вынос возвращается полем
   внутрь (.practice-panel > .split), иначе текст поднимался бы к самому краю. */
.practice-panel { position: relative; z-index: 1; background: var(--card); border-radius: var(--r-panel); padding: var(--panel-pad); margin-top: calc(var(--practice-tuck) * -1); box-shadow: var(--card-ring); }
.practice-panel > .split { padding-top: var(--practice-tuck); }
.practice-panel .title { margin-bottom: 20px; }
.practice-panel h3 { margin-bottom: 16px; }
.practice__eyebrow { color: var(--accent-text); font-size: 14px; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 16px; }
.practice__sub { color: var(--muted); font-size: 20px; line-height: 1.5; }
.practice__summary { margin: 0; }
.bullets { list-style: disc; padding: 16px 0 0 20px; }
.bullets li { margin-bottom: 10px; }

/* ── кейсы: карточки-раскрывашки, 3 / 2 / 1 колонки ──
   Карточка — белая панель радиусом 30 и паддингом 40, как его .panel.
   Слот под иллюстрацию: 4:3, радиус 20 (его smaller-corners), фон smoke;
   на 1440 это 336×252, на планшете до 375×281, на телефоне 375 — 295×221.
   Свёрнутое: иллюстрация, номер, название-результат h4, строка-подзаголовок.
   Раскрытое: вступление + блоки роль / challenge / solution / results + «Close».
   Тело раскрытия — общие классы .fold__body / .fold__inner (блок «раскрывашка» ниже). */
/* ── кейсы: девять горизонтальных полос на всю ширину, а не сетка карточек.
      В покое полоса показывает номер, миниатюру, название-результат и подзаголовок;
      по клику раскрывается вниз. Колонка миниатюры задана как max-content.
      04.09.2026: миниатюра больше не растёт при раскрытии. Она ничего не сообщает —
      это тот же рисунок, только крупнее, — а голова из-за него становилась вдвое
      выше своего текста, и справа от картинки оставалось пустое поле. Раскрытие
      теперь показывает себя поверхностью, а не размером: см. блок ниже. ── */
/* замыкающая линия списка висит на последней записи, а не на самом списке: раскрытая
   запись гасит свои линии одним правилом, и под открытой последней карточкой не остаётся
   висящей черты (иначе понадобился бы :has на .cases) */
.cases { display: grid; grid-template-columns: 1fr; gap: 0; margin-top: 64px; }
.case-card { position: relative; background: none; border-radius: 0; border-top: 1px solid var(--line); box-shadow: none; scroll-margin-top: 24px; }
.case-card:last-child { border-bottom: 1px solid var(--line); }

/* ── свёрнутый список: пять записей и кнопка ──
   Классы ставит скрипт внизу site3.html — без него на странице все девять, как раньше.
   Замыкающую линию в свёрнутом виде держит пятая запись (.is-cut): последняя (09)
   спрятана, и её :last-child-линия не видна. Раскрытая пятая гасит линию тем же
   правилом, что и раскрытая последняя, — иначе под открытой панелью висела бы черта. */
.cases.is-collapsed .case-card.is-extra { display: none; }
.cases.is-collapsed .case-card.is-cut:not(.is-open) { border-bottom: 1px solid var(--line); }
/* ссылка на каталог /cases/ под карточками (13.09.2026). Набрана ссылкой, а не кнопкой:
   кнопка «Show more cases» рядом с ней снята 12.10.2026 вместе с аккордеоном */
.cases__all { display: flex; justify-content: center; margin-top: 48px; }
.cases__all a {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--accent-text); font-weight: 700; text-decoration: none;
}
.cases__all a:hover { text-decoration: underline; }

/* ── витрина кейсов: карточки-ссылки (12.10.2026) ──
   Сетка в две колонки, первая карточка на всю ширину. Обложка — тинт записи
   (--illus-bg из [data-illo]) с цифрой результата слева сверху и фигурой из
   illustrations.js справа снизу: та же фигура, что в строке каталога, только
   крупнее и прижата к нижнему краю — столбцы стоят на основании, спикер
   выглядывает из-за кромки. Вся карточка — ссылка; наведение чуть поднимает
   фигуру и гасит подпись перехода, как у строки каталога.
   Цифра — плакатным кеглем, табличными знаками: набег цифр (motion.js)
   перерисовывает её на лету, и подпись под ней не должна дрожать.
   Слот .case-card__illo переопределён внутри карточки: в строке каталога это
   миниатюра 132 px, здесь — часть обложки без своего фона и скругления. */
.case-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 24px; margin-top: 64px; }
.case-tile { min-width: 0; }
.case-tile--wide { grid-column: 1 / -1; }
.case-tile__link { display: block; color: inherit; text-decoration: none; border-radius: var(--r-block); }
.case-tile__link:focus-visible { outline: 2px solid var(--focus); outline-offset: 6px; }
.case-tile__cover {
  position: relative; overflow: hidden; aspect-ratio: 3 / 2;
  border-radius: var(--r-block); background: var(--illus-bg);
  padding: clamp(20px, 2.4vw, 32px);
}
.case-tile--wide .case-tile__cover { aspect-ratio: 21 / 9; }
.case-tile .case-card__illo {
  position: absolute; right: 0; bottom: 0; top: auto; width: 56%; aspect-ratio: 4 / 3;
  border-radius: 0; background: none; margin: 0;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1);
}
.case-tile--wide .case-card__illo { width: 36%; }
.case-tile__link:hover .case-card__illo { transform: translateY(-6px); }
/* Цифре отдано 60% ширины: «20 дней» на 46% ломалось на две строки. С фигурой
   справа снизу текст не спорит — он стоит сверху, фигура занимает нижние 63% высоты */
.case-tile__result { position: relative; z-index: 1; margin: 0; max-width: 60%; color: var(--ink); }
.case-tile--wide .case-tile__result { max-width: 52%; }
.case-tile__result b {
  display: block; font-size: clamp(44px, 5.4vw, 84px); font-weight: 900;
  line-height: .95; letter-spacing: -.035em; font-variant-numeric: tabular-nums;
}
.case-tile__result span {
  display: block; margin-top: 12px; font-size: clamp(15px, 1.3vw, 18px); font-weight: 600;
  line-height: 1.35; max-width: 22ch; opacity: .78;
}
.case-tile__body { padding: 18px 4px 0; }
.case-tile__field { margin: 0; font-size: 18px; line-height: 1.5; }
.case-tile__meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px;
  margin-top: 12px; font-size: 14px; color: var(--muted);
}
.case-tile__year { font-variant-numeric: tabular-nums; letter-spacing: .02em; white-space: nowrap; }
.case-tile__tags { display: flex; flex-wrap: wrap; gap: 0 8px; }
.case-tile__cta {
  margin-left: auto; color: var(--accent-text); font-weight: 700; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 8px; transition: opacity .2s;
}
.case-tile__cta::after { content: '\2192'; font-size: 20px; line-height: 1; }
.case-tile__link:hover .case-tile__cta { opacity: .75; }
@media (max-width: 991px) {
  .case-grid { gap: 32px 20px; }
  .case-tile__result { max-width: 56%; }
  .case-tile__cta { margin-left: 0; flex-basis: 100%; }
}
@media (max-width: 767px) {
  .case-grid { grid-template-columns: 1fr; gap: 32px; margin-top: 48px; }
  .case-tile--wide .case-tile__cover { aspect-ratio: 3 / 2; }
  .case-tile--wide .case-card__illo { width: 56%; }
  .case-tile__result, .case-tile--wide .case-tile__result { max-width: 60%; }
  .case-tile__result b { font-size: clamp(40px, 11vw, 56px); }
  .case-tile__result span { font-size: 15px; }
  .case-tile__field { font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .case-tile .case-card__illo, .case-tile__cta { transition: none; }
  .case-tile__link:hover .case-card__illo { transform: none; }
}

/* ── чем показываем, что полоса раскрыта ──
   Под записью проявляется карточный фон (--card, у всех пяти схем он отличается от фона
   страницы) со скруглением панели: список остаётся списком, а открытая запись читается
   отдельной карточкой — приём из Material 3 и GOV.UK, где раскрытая секция меняет
   поверхность, а не размер элементов внутри.
   Подложка нарисована псевдоэлементом с выносом за колонку текста, поэтому при раскрытии
   не сдвигается ни один пиксель содержимого: только проявляется фон. По вертикали она,
   наоборот, кончается на 12 px выше низа записи — раскрыть можно сразу несколько, и без
   этого зазора две панели подряд слипались бы, оставляя на стыке защип от скруглений.
   Сверху зазора нет: там поле головы и так 20 px, а отними ещё — миниатюра прижмётся
   к скруглению угла.
   Волосяные линии вокруг раскрытой записи гасим: свои две — правилом на ней самой,
   верхнюю у следующей — соседним селектором (она рисуется поверх подложки).
   Плюс два тихих признака: знак «+» уже меняется на «–», а номер записи получает
   акцентный тон, тот же, что у «Case details». */
.case-card::before {
  content: ''; position: absolute; z-index: 0; inset: 0 calc(var(--case-bleed) * -1) 12px;
  border-radius: var(--r-panel); background: var(--card); box-shadow: var(--card-ring);
  opacity: 0; transition: opacity .3s ease; pointer-events: none;
}
.case-card > * { position: relative; z-index: 1; }
/* наведение на закрытую полосу подсвечивает её той же подложкой вполсилы — видно, что
   кликается вся строка, а не одна ссылка. Только там, где курсор настоящий: на тачскрине
   :hover залипает после тапа */
@media (hover: hover) {
  .case-card:hover::before { opacity: .35; }
}
.case-card.is-open::before { opacity: 1; }
.case-card.is-open { border-color: transparent; }
.case-card.is-open + .case-card { border-top-color: transparent; }
.case-card.is-open .case-card__n { color: var(--accent-text); }
.case-card__head {
  display: grid; grid-template-columns: 40px max-content minmax(0, 1fr) max-content auto;
  grid-template-areas: "n illo title year cta" "n illo field year cta";
  gap: 6px 28px; align-items: center; padding: 20px 0; cursor: pointer; outline: none;
}
.case-card__head:focus-visible { box-shadow: inset 0 0 0 2px var(--focus); border-radius: var(--r-control); }
.case-card__head:hover .case-card__cta { opacity: .75; }
.case-card__illo {
  grid-area: illo; position: relative; aspect-ratio: 4 / 3; width: 132px; margin-bottom: 0;
  border-radius: var(--r-thumb); overflow: hidden; background: var(--illus-bg);
}
.case-card__illo > * { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Иллюстрация вставляется инлайном (illustrations.js), а не через <img>: внутрь <img>
   переменные темы не доходят, и на graphite с cobalt подложка осталась бы светлой.
   Заливка и обводка разведены по классам — один класс с fill залил бы контуры,
   потому что presentation attribute fill="none" слабее любого правила CSS. */
.case-card__il .il-a    { fill: var(--illus-a); }
.case-card__il .il-b    { fill: var(--illus-b); }
.case-card__il .il-ink  { fill: var(--illus-ink); }
.case-card__il .il-line { fill: var(--illus-text); }
.case-card__il .st-a    { fill: none; stroke: var(--illus-a); }
.case-card__il .st-b    { fill: none; stroke: var(--illus-b); }
.case-card__il .st-ink  { fill: none; stroke: var(--illus-ink); }
.case-card__il .st-line { fill: none; stroke: var(--illus-text); }

/* ── своя пара цветов у каждой из девяти иконок ───────────────────────
   05.09.2026. До этого все девять миниатюр красились одной парой --illus-a / --illus-b
   (умбра и алый), и ряд кейсов читался одним пятном: разными были только фигуры.
   Ленту тегов ниже по странице держат пять заливок (.tag--dark / --umber / --blue /
   --amber / --light) — иконки берут те же цвета, чтобы обе части страницы звучали
   одной палитрой, а не двумя.

   Литералов здесь нет: роли собираются из переменных темы, поэтому три примерочные
   схемы (themes-2026.css) подставят в иконки свои цвета сами.
   12.10.2026: селектор стал [data-illo] без .case-card — те же пары цветов
   читают карточки-ссылки главной (.case-tile) и строки каталога (.case-row).

   05.09.2026, схема «Мята на бежевом». Раскладка ролей перевёрнута, и вот почему.
   При лайме слот у всех девяти был одного цвета (лаймовый), а разными были заливки:
   цвет держали фигуры. Здесь так не выходит — из пяти тинтов референса четыре
   светлые и между собой почти не спорят (мята 14.15, барвинок 10.66, сливочный 15.29,
   холодный серый 15.87 — все относительно чернил), то есть крупной заливкой на светлом
   слоте ни один из них не читается: барвинок на мяте даёт 1.33, сливочный на ней же 1.08.
   Поэтому теперь цвет держит СЛОТ, а фигуры на нём — две тёмные: чернила и тень мяты.
   Это ровно приём nominal: у них тинтованная плитка с чёрной графикой поверх.
     --illus-bg   тинт слота, свой у каждой записи — он и даёт ленте цвет
     --illus-a    крупная заливка: чернила (на светлых тинтах 10.66…15.87) или тень мяты
     --illus-b    вторая фигура: вторая из этой же пары
     --illus-ink  детали ПОВЕРХ a или b — везде холст: деталь вырезана в тёмной фигуре,
                  тот же приём, что у плашек первого экрана
   Пятая плитка ленты — яркая мята: она единственная из тинтов достаточно насыщена,
   чтобы стоять рядом с четырьмя пастельными и не выпасть (чернила на ней 11.0,
   тень мяты 4.71). Порядок тинтов подобран так, чтобы соседние записи не совпадали. */
[data-illo="case-01"] { --illus-bg: var(--mint);        --illus-a: var(--panel-dark);  --illus-b: var(--accent-text); --illus-ink: var(--bg); }
[data-illo="case-02"] { --illus-bg: var(--peri);        --illus-a: var(--accent-text); --illus-b: var(--panel-dark);  --illus-ink: var(--bg); }
[data-illo="case-03"] { --illus-bg: var(--butter);      --illus-a: var(--panel-dark);  --illus-b: var(--accent-text); --illus-ink: var(--bg); }
[data-illo="case-04"] { --illus-bg: var(--mint-bright); --illus-a: var(--panel-dark);  --illus-b: var(--accent-text); --illus-ink: var(--bg); }
[data-illo="case-05"] { --illus-bg: var(--cool);        --illus-a: var(--accent-text); --illus-b: var(--panel-dark);  --illus-ink: var(--bg); }
[data-illo="case-06"] { --illus-bg: var(--mint);        --illus-a: var(--accent-text); --illus-b: var(--panel-dark);  --illus-ink: var(--bg); }
[data-illo="case-07"] { --illus-bg: var(--butter);      --illus-a: var(--accent-text); --illus-b: var(--panel-dark);  --illus-ink: var(--bg); }
[data-illo="case-08"] { --illus-bg: var(--peri);        --illus-a: var(--panel-dark);  --illus-b: var(--accent-text); --illus-ink: var(--bg); }
[data-illo="case-09"] { --illus-bg: var(--mint-bright); --illus-a: var(--accent-text); --illus-b: var(--panel-dark);  --illus-ink: var(--bg); }
/* заглушка слота (рисует скрипт): большой круг и пилюля — основной цвет, кружок — второй, плашка — тёмный, подпись — текст */
.case-card__ph .ph-a { fill: var(--illus-a); }
.case-card__ph .ph-b { fill: var(--illus-b); }
.case-card__ph .ph-ink { fill: var(--illus-ink); }
.case-card__ph .ph-text { fill: var(--illus-text); }
.case-card__n { grid-area: n; margin-bottom: 0; }
/* в две-три колонки резервируем две строки под название и подзаголовок — ряды остаются ровными */
.case-card h4 { grid-area: title; margin-bottom: 0; min-height: 0; align-self: end; }
.case-card__field { grid-area: field; color: var(--muted); font-size: 18px; line-height: 1.5; min-height: 0; align-self: start; }
/* ── год кейса ──
   Своя колонка между текстом и «Case details»: список читается индексом, у каждой
   строки есть дата. Говорит вполголоса — тон подзаголовка, кегль подписи: год отвечает
   на вопрос «когда», а обещание строки держит название. Цифры табличные и nowrap,
   чтобы диапазоны 2013–2018 стояли в колонку и не переносились по тире. */
.case-card__year {
  grid-area: year; align-self: center; justify-self: end;
  color: var(--muted); font-size: 15px; letter-spacing: .02em;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.case-card__cta { grid-area: cta; margin-top: 0; color: var(--accent-text); display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; transition: opacity .2s; }
.case-card__cta::after { content: '+'; font-size: 22px; line-height: 1; }
.case-card.is-open .case-card__cta::after { content: '\2013'; }
/* Ширину держат сами куски, а не общая колонка: текст и блоки роли остаются в мере
   чтения (900), а плёнка кадров идёт во всю ширину раскрытой панели — иначе справа
   от неё оставалось бы пустое поле подложки на треть карточки. */
.case-card__content { padding: 4px 0 36px 68px; }
.case-card__content > .medium-text { padding-top: 0; max-width: 900px; }
.case-card__details { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 32px; margin-top: 28px; max-width: 900px; }
.case-card__block h6 { margin-bottom: 10px; }
/* пункты внутри блока: маркер — короткое тире того же тона, что и текст, без буллетов */
.case-card__list { list-style: none; display: grid; gap: 8px; }
.case-card__list li { position: relative; padding-left: 18px; font-size: 17px; line-height: 1.5; }
.case-card__list li::before { content: '–'; position: absolute; left: 0; opacity: .5; }

/* ══ РАСКРЫТИЕ КЕЙСА ПО СКЕЛЕТУ (CASE-INSIDE-SPEC.md) ═══════════════════
   Закрытая полоса заявляет результат, раскрытие показывает доказательство.
   Скелет один на все кейсы, переменная часть — фигура; типов фигур пять,
   не девять, иначе секция превращается в зоопарк.
       1 · трение — одно предложение, крупно, с акцентной чертой слева.
           Единственное место, где кейс говорит, что было не так.
       2 · фигура — устройство решения вместо семи буллетов.
       3 · кадры — сноска «вот это правда было», блок необязательный.
       4 · цифры — только там, где число есть и его можно наружу.
       5 · моя часть — одна строка с тегами вместо списка «Role».
   Левый отступ 68px даёт родитель .case-card__content, здесь его нет.
   Кейсы переезжают на скелет по одному: у кого нет записи в CASE_INSIDE,
   тот остаётся на старых четырёх списках .case-card__details. */
.cx { max-width: 1000px; padding-top: 4px; }
.cx__friction {
  font-size: 21px; line-height: 1.5; max-width: 720px; margin-bottom: 32px;
  padding-left: 18px; border-left: 3px solid var(--accent);
}
.cx__figure { margin: 0 0 32px; }
.cx__caption { font-size: 14px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; }

/* цифры результата: карточка появляется только там, где число можно наружу */
.cx__nums { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 28px; }
.cx__num {
  background: var(--card); box-shadow: var(--card-ring); border-radius: var(--r-thumb);
  padding: 16px 22px; min-width: 150px;
}
.cx__num b { display: block; font-size: 34px; line-height: 1.1; font-weight: 500; letter-spacing: -.02em; }
.cx__num span { display: block; font-size: 14px; line-height: 1.4; color: var(--muted); margin-top: 6px; }
/* пометка вместо числа — там, где цифра под NDA */
.cx__num--flat b { color: var(--accent-text); }

/* моя часть одной строкой вместо списка из пяти буллетов */
.cx__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 10px; font-size: 15px; color: var(--muted); }
.cx__meta b { color: var(--ink); font-weight: 500; }
.cx__tag { background: var(--bg-alt); border-radius: 999px; padding: 4px 12px; font-size: 14px; color: var(--ink); }

/* Вход на страницу с разбором метода. Стоит последней строкой раскрытия, после
   «моей части»: сначала доказательство целиком, потом предложение копнуть глубже.
   Есть не у каждого кейса — рисуется, только если в CASE_INSIDE задано more. */
/* Вход на отдельную страницу с разбором. Раньше был текстовой ссылкой и терялся
   в конце раскрытия — читатель дочитывал карточку и не понимал, что есть
   продолжение. Теперь это кнопка тех же пропорций, что «Связаться» в подвале:
   единственное действие в карточке и должно выглядеть как действие. */
.cx__more {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 24px; border-radius: var(--r-control); padding: 15px 24px; min-height: 54px;
  font-size: 15px; font-weight: 700; text-decoration: none;
  background: var(--btn-dark-bg); color: var(--btn-dark-ink);
  transition: box-shadow .2s;
  box-shadow: inset 0 2px 5px 50px transparent;
}
.cx__more:hover { box-shadow: inset 0 0 5px 50px var(--btn-dark-hover); }
.cx__more span { transition: transform .15s; }
.cx__more:hover span { transform: translateX(3px); }

/* ── фигура A · поток: перестроил устройство, а не крутил ручки ── */
.fg-flow { display: grid; grid-template-columns: minmax(0,200px) 40px minmax(0,1fr); gap: 20px; align-items: center; }
.fg-flow__col { display: grid; gap: 8px; }
.fg-box {
  background: var(--card); box-shadow: var(--card-ring); border-radius: 12px;
  padding: 12px 14px; font-size: 15px; line-height: 1.35;
}
.fg-box--dim { background: var(--bg-alt); box-shadow: none; color: var(--muted); }
.fg-box--sum { background: var(--panel-dark); color: var(--panel-dark-ink); box-shadow: none; }
.fg-arrow { display: grid; place-items: center; color: var(--muted); font-size: 22px; }
.fg-flow__right { display: grid; grid-template-columns: 1fr 32px minmax(0,180px); gap: 12px; align-items: center; }
.fg-flow__branches { display: grid; gap: 8px; }
.fg-brace { border-left: 1px solid var(--line); height: 100%; margin-left: 15px; }

/* ── фигура B · дельта: метрика до и после.
   Длина полосы — пропорция «было / стало», сама метрика подписана справа ── */
.fg-bars { display: grid; gap: 18px; max-width: 620px; }
.fg-bar__label { font-size: 15px; margin-bottom: 8px; display: flex; justify-content: space-between; gap: 16px; }
.fg-bar__label i { font-style: normal; color: var(--muted); }
.fg-bar__track { display: grid; gap: 5px; }
.fg-bar__row { display: grid; grid-template-columns: 62px 1fr; align-items: center; gap: 12px; font-size: 13px; color: var(--muted); }
.fg-bar__fill { height: 14px; border-radius: 7px; background: var(--bg-alt); }
.fg-bar__fill i { display: block; height: 100%; border-radius: 7px; background: var(--line); }
.fg-bar__row--now { color: var(--ink); }
.fg-bar__row--now .fg-bar__fill i { background: var(--accent); }

/* ── фигура C · шаги: метод, что чему предшествует ── */
.fg-steps { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; max-width: 900px; }
.fg-step { position: relative; padding: 0 16px 0 0; }
.fg-step::before { content: ''; display: block; height: 2px; background: var(--line); margin-bottom: 14px; }
.fg-step:first-child::before { background: var(--accent); }
.fg-step__n {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--panel-dark); color: var(--panel-dark-ink); font-size: 12px; margin-bottom: 10px;
}
.fg-step b { display: block; font-size: 16px; font-weight: 500; line-height: 1.3; margin-bottom: 6px; }
.fg-step span { display: block; font-size: 14px; line-height: 1.45; color: var(--muted); }

/* ── фигура D · масштаб: количество, которое видно ── */
.fg-dots { display: flex; align-items: flex-end; gap: 32px; flex-wrap: wrap; }
.fg-dots__grid { display: grid; grid-template-columns: repeat(20, 12px); gap: 6px; }
.fg-dots__grid i { width: 12px; height: 12px; border-radius: 50%; background: var(--accent); display: block; }
.fg-dots__grid i.is-seed { background: var(--panel-dark); }
.fg-dots__legend { display: grid; gap: 10px; font-size: 15px; }
.fg-dots__legend div { display: flex; align-items: center; gap: 10px; color: var(--muted); }
.fg-dots__legend b { width: 12px; height: 12px; border-radius: 50%; display: block; }

/* ── кадры: полоса квадратов под фигурой ──
   Квадрат, а не широкий кадр: широкий требует разглядывания и начинает спорить
   с фигурой за внимание, квадрат читается меткой «вот это правда было».
   В полосе не больше пяти, остальные листаются в крупном плане — крупный план
   тот же общий lightbox, что и у галереи старых кейсов. */
.ev { margin-bottom: 28px; }
.ev__cap { font-size: 14px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }
.ev__cap i { font-style: normal; opacity: .7; }
.ev__strip {
  display: flex; gap: 10px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none; padding-bottom: 4px;
}
.ev__strip::-webkit-scrollbar { display: none; }
.ev__shot {
  flex: 0 0 auto; width: 104px; height: 104px; padding: 0; border: 0; cursor: zoom-in;
  border-radius: var(--r-thumb); overflow: hidden; background: var(--bg-alt);
  scroll-snap-align: start; box-shadow: var(--card-ring); transition: transform .18s;
}
.ev__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev__shot:hover { transform: translateY(-2px); }
.ev__shot:focus-visible { box-shadow: 0 0 0 2px var(--focus); outline: none; }

@media (max-width: 900px) {
  .fg-flow, .fg-flow__right { grid-template-columns: 1fr; }
  .fg-steps { grid-auto-flow: row; gap: 18px; }
  .fg-dots__grid { grid-template-columns: repeat(10, 12px); }
}
/* ── «Close» внизу раскрытой панели ──
   До 04.09.2026 это была тёмная кнопка .btn слева под текстом: единственный тяжёлый
   элемент внутри лёгкой панели, и стоял он не там, где кейс открывали. Теперь оба
   триггера набраны одинаково — терракота, знак справа, тот же кегль: «Case details +»
   в голове открывает, «Close –» внизу закрывает. Вторая подпись прижата к правому краю
   панели, ровно под знаком в голове: взгляд закрывает кейс там же, где открыл.
   width: fit-content нужен рядом с margin-left: auto — inline-flex сам вправо не уедет.
   Обнуляем ещё и браузерный вид <button>: шрифт, рамку, фон, поля. */
.case-card__close {
  margin: 32px 0 0 auto; width: fit-content;
  display: flex; align-items: center; gap: 8px;
  padding: 0; border: 0; background: none; font: inherit; line-height: inherit;
  color: var(--accent-text); white-space: nowrap;
  cursor: pointer; outline: none; transition: opacity .2s;
}
.case-card__close::after { content: '\2013'; font-size: 22px; line-height: 1; }
.case-card__close:hover { opacity: .75; }
.case-card__close:focus-visible { box-shadow: 0 0 0 2px var(--focus); border-radius: 4px; }

/* ── галерея внутри раскрытого кейса: лента квадратных кадров ──
   Кадры сняты с живого kottov.net (case-media.js) и приходят кто во что горазд:
   широкие дашборды, скриншоты страниц, вертикальные экраны телефона. До 04.09.2026
   лента держала одну высоту, а ширину слайда отдавала пропорции кадра — ряд выходил
   рваным. Временно (кадры будут перерисованы в едином стиле) все слайды приведены
   к квадрату --case-shot и кадрируются object-fit: cover — лента читается сеткой.
   Кроп прижат к левому верхнему углу (object-position 0% 30%): у широкого дашборда
   слева заголовок и первые цифры, у обложки кейса — набранный текст; центр резал их
   с обеих сторон. Целиком, без кропа, кадр открывается в крупном плане по клику.
   Прокрутка нативная, со снапом по левому краю кадра: свайп на телефоне, стрелки
   и колесо на десктопе. Полосу прокрутки прячем — навигация читается по стрелкам
   и счётчику, они же держат фокус с клавиатуры.
   Радиус — --r-thumb, тот же, что у превью в блоке Design work и у миниатюры кейса. */
.case-gallery { margin-top: 28px; }
.case-gallery__track {
  display: flex; gap: 12px; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none;
}
.case-gallery__track::-webkit-scrollbar { display: none; }
.case-gallery__slide { flex: 0 0 auto; scroll-snap-align: start; }
/* max-width: none снимает общее правило img { max-width: 100% } — иначе широкий кадр
   упёрся бы в ширину ленты и квадрат бы поехал */
.case-gallery__slide img {
  display: block; width: var(--case-shot); height: calc(var(--case-shot) * 1.25); max-width: none;
  object-fit: cover; object-position: 50% 0%;
  border-radius: var(--r-thumb); background: var(--illus-bg);
}
.case-gallery__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 16px; }
.case-gallery__count { font-variant-numeric: tabular-nums; }
.case-gallery__arrows { display: flex; gap: 8px; }
.case-gallery__arrow {
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-size: 18px; line-height: 1; cursor: pointer;
  color: var(--ink); background: none; border: 1px solid var(--line);
  transition: background-color .2s, opacity .2s;
}
.case-gallery__arrow:hover:not(:disabled) { background: var(--btn-light-bg); }
.case-gallery__arrow:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus); }
.case-gallery__arrow:disabled { opacity: .35; cursor: default; }
/* сам кадр — кнопка: открывает крупный план и берётся с клавиатуры. Обёртка не должна
   ничего добавлять к картинке, поэтому у неё нет ни полей, ни фона, ни рамки */
/* волосяная рамка: раскрытая полоса стала светлой панелью, и светлый скриншот
   на ней теряет край — без рамки кадр расплывается в подложку */
.case-gallery__shot {
  display: block; padding: 0; border: 0; background: none; font: inherit;
  cursor: zoom-in; border-radius: var(--r-thumb); outline: none;
  box-shadow: 0 0 0 1px var(--line);
}
.case-gallery__shot:focus-visible { box-shadow: 0 0 0 2px var(--focus); }
.case-gallery__shot img { transition: opacity .2s; }
.case-gallery__shot:hover img { opacity: .88; }

/* ── крупный план кадра: слой поверх страницы ──
   Один слой на всю страницу, его наполняет скрипт. Картинка показывается оригиналом с Tilda
   и вписывается в экран целиком — вертикальный скриншот телефона и широкий дашборд одинаково
   помещаются. Кнопки лежат по краям поверх затемнения; на телефоне стрелки уезжают вниз,
   иначе они накрывают саму картинку на узком экране. */
html.is-locked, html.is-locked body { overflow: hidden; }
.lightbox[hidden] { display: none; }
.lightbox {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
  gap: 24px; padding: 24px; background: var(--scrim);
  /* размытие, а не только затемнение: под 92% сквозь слой ещё читались вордмарк и меню,
     а рядом со скриншотом дашборда любой различимый текст спорит с ним за внимание */
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
/* картинка — сжимаемый элемент строки: min-width: 0 и max-width: 100% дают ей ужаться
   под стрелки, а не выдавить их за края экрана. Высота auto — пропорция держится сама */
.lightbox__img {
  min-width: 0; max-width: min(100%, 1600px); max-height: 86vh; width: auto; height: auto;
  object-fit: contain; border-radius: var(--r-block);
}
.lightbox__close, .lightbox__arrow {
  flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; line-height: 1; cursor: pointer; outline: none;
  color: var(--panel-dark-ink); background: none; border: 1px solid var(--line-on-dark);
  transition: background-color .2s, opacity .2s;
}
.lightbox__arrow { font-size: 20px; }
.lightbox__close { position: absolute; top: 24px; right: 24px; font-size: 24px; }
.lightbox__close:hover, .lightbox__arrow:hover:not(:disabled) { background: var(--line-on-dark-faint); }
.lightbox__close:focus-visible, .lightbox__arrow:focus-visible { box-shadow: 0 0 0 2px var(--focus); }
.lightbox__arrow:disabled { opacity: .3; cursor: default; }
.lightbox__count { position: absolute; left: 0; right: 0; bottom: 24px; text-align: center; color: var(--panel-dark-muted); }
/* «Close» внутри раскрытого кейса — единственная кнопка меньше основной шкалы:
   она стоит в потоке текста, а не в ряду призывов. Тап 44 — нижняя граница по HIG */
.btn--small { padding: 12px 20px; min-height: 44px; font-size: 15px; }

/* ── раскрывашка: одна механика на кейсы (.case-card) и опыт (.tl, .practice-panel) ──
   Контейнер получает .is-open от скрипта; голова/триггер — role=button с aria-expanded, клик, Enter и Space.
   Тело — grid-строка 0fr → 1fr (высота анимируется без замера), содержимое свёрнутого visibility:hidden,
   чтобы не табалось. Триггер «Details / Hide» в опыте набран как case-card__cta: терракота, плюс / минус. */
.fold__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .35s ease; }
.fold__inner { overflow: hidden; min-height: 0; visibility: hidden; transition: visibility 0s linear .35s; }
.is-open .fold__body { grid-template-rows: 1fr; }
.is-open .fold__inner { visibility: visible; transition-delay: 0s; }
.fold__toggle { display: inline-flex; align-items: center; gap: 8px; margin-top: 10px; color: var(--accent-text); cursor: pointer; outline: none; transition: opacity .2s; }
.fold__toggle:hover { opacity: .75; }
.fold__toggle:focus-visible { box-shadow: 0 0 0 2px var(--focus); border-radius: 4px; }
.fold__toggle::after { content: '+'; font-size: 22px; line-height: 1; }
.is-open .fold__toggle::after { content: '\2013'; }
.fold__close, .is-open .fold__open { display: none; }
.is-open .fold__close { display: inline; }

/* ── отзывы: одна широкая тёмная панель на всю ширину контейнера, в его манере (радиус 30):
   слева 2/3 — цитата 28px, справа 1/3 — источник, имя, роль, логотип.
   Две панели в ряд — модификатор .panels--pair ниже (12.10.2026). ── */
.panels { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 64px; }
.panel {
  display: grid; grid-template-columns: 2fr 1fr; gap: 32px 64px; align-items: end;
  border-radius: var(--r-panel); padding: var(--panel-pad); background: var(--panel-dark); color: var(--panel-dark-ink);
  box-shadow: var(--panel-ring);
}
/* Панель отзыва — единственное место, где поле меняет цвет целиком, и единственная
   цветная плоскость страницы крупнее плашки. Переменные переопределены на самом
   элементе, поэтому правила .panel выше трогать не нужно — они уже читают
   --panel-dark и --panel-dark-ink.
   05.09.2026: приём сохранён, но вывернут. Было тёмное поле с цветным текстом
   (умбра #5A2900 с оранжевым, 5.61) — стало светлое мятное с обычными чернилами,
   14.15. Тот самый «мятный блок»: в схеме «Мята на бежевом» тёмного на странице
   и так две плоскости подряд — обложка и блок опыта, — и третья тёмная панель
   между ними отдыха не давала. Мята его даёт и заодно показывает акцент схемы
   размером больше плашки. */
.panel--quote {
  --panel-dark:         var(--mint);
  --panel-dark-ink:     var(--ink);
  --panel-dark-muted:   rgba(21, 20, 20, .68);     /* 7.09 на мяте */
  --panel-dark-faint:   rgba(21, 20, 20, .60);     /* 5.63 */
  --line-on-dark:       rgba(21, 20, 20, .20);
  --line-on-dark-faint: rgba(21, 20, 20, .14);
}
/* висячая кавычка: text-indent уводит « влево ровно на ширину padding-left — кавычка висит,
   но остаётся внутри панели (на 1024 без запаса она вылезала за край: scrollWidth > clientWidth) */
.panel__quote { margin: 0; font-size: 28px; line-height: 1.4; text-indent: -.42em; padding-left: .42em; }
.panel__meta { display: flex; flex-direction: column; gap: 10px; border-left: 1px solid var(--line-on-dark-faint); padding-left: 32px; }
.panel__source { color: var(--panel-dark-faint); font-size: 14px; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 6px; }
.quote-user { display: flex; flex-direction: column; gap: 2px; font-size: 18px; line-height: 1.5; }
.quote-user b { font-weight: 700; font-size: 20px; }
/* PNG чёрный на прозрачном, слово WHITE — вывороткой внутри плашки: brightness(0) заливал плашку сплошным,
   слово пропадало; invert(1) без brightness переворачивает цвета и сохраняет выворотку */
.panel__logo { height: 40px; width: auto; max-width: 160px; margin-top: 14px; align-self: flex-start; filter: invert(1); opacity: .92; }
/* На мятной панели инверсия не нужна: знак и так чёрный на прозрачном, и после
   мятной заливки поля он читается как есть. С invert(1) он стал бы белым на светлом. */
.panel--quote .panel__logo { filter: none; }
/* ── две панели в ряд (12.10.2026): вторая рекомендация — клиент кейса 08 ──
   Подпись уходит под цитату и отделяется линией сверху, цитата набрана мельче:
   28 px на половине ширины давали по четыре слова в строке. На ≤991 панели
   встают в одну колонку, подпись остаётся под цитатой. */
.panels--pair { grid-template-columns: 1fr 1fr; gap: 24px; }
.panels--pair .panel { grid-template-columns: 1fr; gap: 28px; align-content: start; align-items: start; }
.panels--pair .panel__quote { font-size: 22px; line-height: 1.45; }
.panels--pair .panel__meta { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-on-dark-faint); padding-top: 24px; }
@media (max-width: 991px) { .panels--pair { grid-template-columns: 1fr; } }

/* ── background: строка регалий, образование в двух регистрах, языки строкой ── */
.list__label { margin-bottom: 16px; }
.list { border-bottom: 1px solid var(--line); }
.list__row { display: grid; grid-template-columns: 64px 1fr; gap: 16px; padding: 20px 0; border-top: 1px solid var(--line); align-items: baseline; }
.list__y { color: var(--muted); }
.list__w { font-size: 20px; line-height: 1.3; }
.list__s { color: var(--muted); margin-top: 4px; }
/* курсы стоят рядом с университетскими документами и не должны весить столько же */
.list--minor .list__w { font-size: 17px; }
.list--minor .list__row { padding: 14px 0; }

/* строка регалий: единственное место блока, которое читается за секунду.
   Разделитель — терракотовая точка, тем же приёмом, что «·» в строке первого экрана. */
/* 1120, а не 980: на 980 английская строка ломается на три строки, на 1120 встаёт в две.
   Русская и сербская длиннее и остаются трёхстрочными — это нормально, основная версия английская. */
/* 32, а не 30: 30 стоял между ступенями 32 и 28 и отличался от соседнего h4 на два
   пиксела — разницу такого размера глаз не читает как иерархию, только как расхождение */
.creds { max-width: 1120px; font-size: 32px; line-height: 1.35; margin-bottom: 12px; }
.creds i { font-style: normal; color: var(--accent-text); padding: 0 6px; }
.creds__note { color: var(--muted); margin-bottom: 56px; }
/* два регистра: слева два университетских документа, справа пять курсов */
.regs { display: grid; grid-template-columns: 1.15fr 1fr; gap: 0 80px; align-items: start; }
/* языки строкой, а не колонкой: в .split справа оставалось 380 px пустоты */
.langs-block { margin-top: 48px; padding-top: 32px; border-top: 1px solid var(--line); }
.langs { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 20px; }
.langs__item { font-size: 20px; line-height: 1.4; }
.langs__item span { color: var(--muted); }
.langs__item + .langs__item::before { content: '·'; color: var(--accent-text); margin-right: 20px; }

.quiet { padding-top: 0; }
/* дизайн-работы: собственная секция, одна строка из пяти мелких превью.
   Раскладка действующих index/ru/sr; в примерке _preview-themes-2026.html
   на её месте веер (.fan ниже), поэтому правила оставлены обе. */
.gallery { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }
.gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: top; border-radius: var(--r-thumb); }

/* ── дизайн-работы веером ────────────────────────────────────────────────────
   Приём снят с supadupa.nl/workshops (блок «Discover our projects») — того же
   сайта, с которого взята схема lime, см. REFERENCES-COLOR-2026-09-05.md.
   Стопка вертикальных карточек: активная стоит прямо по центру, соседи
   выглядывают из-под неё повёрнутыми и уменьшёнными, дальние — сильнее.

   Геометрия не подобрана на глаз, а снята с живой страницы референса
   (правила .flick-group__item в их таблице стилей):
       ±1 — сдвиг 25%, поворот 10°, масштаб .90, приглушение кадра до .75
       ±2 — сдвиг 45%, поворот 15°, масштаб .80, приглушение кадра до .50
   Сдвиг и поворот идут в этом порядке: сначала translate, потом rotate —
   иначе карточка уезжает по наклонной оси и веер разваливается.

   Формат карточки 2:3, а не прежние 4:3. Все пять работ — скриншоты лендингов
   высотой от 1814 до 5430 px (самая длинная 1440×5430, отношение 0.27):
   в кадре 4:3 от такой страницы оставалась одна шапка, вертикальный кадр
   держит первый экран целиком.

   Место в веере задаёт JS атрибутом data-p (0, ±1, ±2 или hidden), поэтому
   адаптив остаётся здесь: на телефоне те же атрибуты получают другие значения,
   а скрипт об этом не знает. */
.fan {
  /* Ширина карточки — калибр всего блока: от неё считаются и высота веера, и разлёт
     соседей (край второй карточки отходит от центра примерно на её же ширину).
     Потолок 390 px держит веер в пределах двух третей экрана по высоте: у референса
     стопка занимает 60vh, выше этого блок начинает спорить с первым экраном. */
  --fan-w: clamp(230px, 28vw, 390px);
  position: relative;
  height: calc(var(--fan-w) * 1.62);   /* высота активной карточки (1.5w) плюс просвет под наклон соседей */
  touch-action: pan-y;                 /* горизонтальный жест забираем на листание, вертикальный оставляем странице */
}
.fan__item {
  position: absolute; top: 0; left: 50%;
  width: var(--fan-w); margin-left: calc(var(--fan-w) / -2);
  transition: transform .7s cubic-bezier(.16, 1, .3, 1);
}
.fan__item[data-p="0"]      { transform: none;                                        z-index: 4; }
.fan__item[data-p="1"]      { transform: translate( 25%, 1%) rotate( 10deg) scale(.9); z-index: 3; }
.fan__item[data-p="-1"]     { transform: translate(-25%, 1%) rotate(-10deg) scale(.9); z-index: 3; }
.fan__item[data-p="2"]      { transform: translate( 45%, 5%) rotate( 15deg) scale(.8); z-index: 2; }
.fan__item[data-p="-2"]     { transform: translate(-45%, 5%) rotate(-15deg) scale(.8); z-index: 2; }
/* работы дальше второй с краю в веере не участвуют: лежат в стопке под активной.
   Пяти работам такое место не достаётся, правило держит шестую и следующие */
.fan__item[data-p="hidden"] { transform: scale(.75); opacity: 0; pointer-events: none; z-index: 1; }

/* Карточка — кнопка целиком, а не картинка с кнопкой внутри: у неактивной
   действие «показать эту работу», у активной — «открыть крупный план».
   Кнопка в кнопке недопустима, поэтому пилюля внизу справа — не элемент
   управления, а подпись к действию самой карточки; текст для скринридера
   лежит в aria-label и переписывается вместе со сменой активной. */
/* font: inherit обязателен: .fan-card — это <button>, а форменным элементам браузер
   ставит свой шрифт, и он не наследуется. Без этой строки весь блок «Design work» —
   подпись работы и пилюля «View full size» — набирался Arial 400, единственным местом
   на сайте не тем шрифтом и не тем начертанием. На глаз это не ловится: подпись лежит
   на скриншоте, белым по затемнению, и разницу видно только замером computed styles. */
.fan-card {
  position: relative; display: block; width: 100%; aspect-ratio: 2 / 3;
  font: inherit;
  padding: 0; border: 0; margin: 0; overflow: hidden; cursor: pointer;
  background: var(--panel-dark); color: var(--panel-dark-ink);
  border-radius: var(--r-panel);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .16);
  -webkit-user-select: none; user-select: none;
}
.fan-card:focus-visible { outline: none; box-shadow: 0 10px 30px rgba(0, 0, 0, .16), 0 0 0 3px var(--focus); }
.fan-card__img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; transition: opacity .3s; }
/* Подпись лежит на скриншоте, а скриншоты светлые: без затемнения снизу текст
   пропадает. Затемнение начинается с двух третей высоты и набирает силу только
   к самому низу — иначе тень съедает половину работы, ради показа которой
   карточка и стоит. */
.fan-card::after {
  content: ''; position: absolute; inset: 62% 0 0; pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--scrim) 82%);
}
.fan-card__title {
  position: absolute; left: 24px; right: 24px; bottom: 24px; z-index: 1;
  /* 20, а не 22: 22 не стоит ни на одной ступени шкалы (52 / 40 / 32 / 24 / 20),
     а подпись работы — это ровно h6-уровень, тот же, что заголовок карточки кейса */
  font-size: 20px; line-height: 1.2; text-align: left;
  transition: opacity .3s;
}
.fan-card__cta {
  position: absolute; right: 20px; bottom: 20px; z-index: 2;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; border-radius: 999px;
  background: var(--panel-dark-ink); color: var(--panel-dark);
  /* 500, а не 600: на всей странице ровно одно текстовое начертание — 500,
     и 600 здесь был единственным исключением. line-height числом, а не normal:
     это была единственная строка на странице без заданного интерлиньяжа */
  font-size: 15px; line-height: 1.2; font-weight: 500; white-space: nowrap;
  /* пилюля есть только у активной карточки: у референса она так же выезжает снизу */
  opacity: 0; transform: translateY(50%);
  transition: opacity .4s cubic-bezier(.625, .05, 0, 1), transform 1s cubic-bezier(.16, 1, .3, 1);
}
.fan__item[data-p="0"] .fan-card__cta { opacity: 1; transform: none; }
/* У активной карточки подпись поднимается над пилюлей, а не ужимается по ширине:
   пилюля с текстом «View full size» занимает половину нижнего края, и подпись
   рядом с ней ломалась бы на три строки. */
.fan__item[data-p="0"] .fan-card__title { bottom: 76px; }
/* приглушение кадра по удалению от центра — как у референса */
.fan__item[data-p="1"] .fan-card__img,
.fan__item[data-p="-1"] .fan-card__img { opacity: .75; }
.fan__item[data-p="2"] .fan-card__img,
.fan__item[data-p="-2"] .fan-card__img { opacity: .5; }
.fan__item:not([data-p="0"]) .fan-card__title { opacity: .8; }

/* строка под веером: слева номер, справа стрелки. Вид повторяет ленту кадров
   в карточке кейса — на странице уже есть этот элемент, заводить второй облик
   для той же задачи незачем */
.fan__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 28px; }
.fan__count { font-variant-numeric: tabular-nums; }
.fan__arrows { display: flex; gap: 8px; }
.fan__arrow {
  width: 44px; height: 44px; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--ink); border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-size: 18px; transition: background .2s;
}
.fan__arrow:hover { background: var(--btn-light-bg); }
.fan__arrow:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus); }
/* инструменты: бегущая строка логотипов на фоне страницы, без плашки.
   Знаки бледно-серые: пятнадцать чужих палитр подряд перетягивают на себя внимание,
   а блок здесь фоновый — он идёт сразу за языками и просто добирает фактуру.

   --tool-cap — высота прописной буквы в подписи логотипа. Это калибр всего ряда:
   в файлах logos/*.svg прописная равна 100 единицам холста, поэтому одна переменная
   задаёт единый кегль подписей и на десктопе, и на телефоне. */
.tools { --tool-cap: 16px; overflow: hidden; }
/* края ленты гасим маской, иначе логотип обрывается на границе контейнера */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 96px, #000 calc(100% - 96px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 96px, #000 calc(100% - 96px), transparent);
}
/* лента — два одинаковых ряда подряд; сдвиг ровно на -50% ширины ленты приводит
   второй ряд туда, где стоял первый, поэтому шов не виден и цикл замкнут */
.marquee__track { display: flex; width: max-content; animation: tools-marquee 40s linear infinite; }
.marquee__row { display: flex; align-items: center; gap: 56px; padding-right: 56px; }
@keyframes tools-marquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
.tools:hover .marquee__track { animation-play-state: paused; }
/* --h пишет скрипт инлайном: во сколько раз холст файла выше прописной буквы.
   Ширину не задаём — она приходит из пропорций самого SVG */
.tool {
  display: block; flex: none; width: auto;
  height: calc(var(--tool-cap) * var(--h, 1.34));
  filter: var(--tools-filter); opacity: var(--tools-ink);
  transition: filter .25s ease, opacity .25s ease;
}
/* наведение на знак: лента встаёт (правило .tools:hover выше) и логотип оживает в цвете */
.tool:hover { filter: var(--tools-filter-hover); opacity: var(--tools-ink-hover); }
/* ── полоса тегов под первым экраном ──
   Две дорожки навстречу друг другу. Ширина у них не контейнерная, а во весь экран:
   полоса и должна уходить за края кадра, как у референса.

   Цвет плашек берётся только из переменных темы, поэтому полоса переезжает вместе
   со схемой. Пары «фон + чернила» выбраны по контрасту, а не на глаз:
     хвойный + лайм  11.49 · умбра + лайм 5.19 · синий + белый 5.33
     оранжевый + чернила 6.52 · холодный белый + чернила выше 12
   Оранжевый на умбре (приём тон-в-тон из шапки файла) здесь не годится: 2.94. */
.tags { padding: 56px 0 8px; overflow: hidden; }
.tags__row { overflow: hidden; }
.tags__row + .tags__row { margin-top: 12px; }
/* края гасим той же маской, что у ленты логотипов: иначе таблетка обрывается срезом */
.tags__row {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 64px, #000 calc(100% - 64px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 64px, #000 calc(100% - 64px), transparent);
}
.tags__track { display: flex; width: max-content; animation: tags-marquee 56s linear infinite; }
/* нижняя лента едет назад и медленнее: с одинаковой скоростью в одну сторону
   две дорожки читаются как одна строка, разрезанная пополам */
.tags__track--back { animation-direction: reverse; animation-duration: 68s; }
.tags__group { display: flex; align-items: center; gap: 12px; padding-right: 12px; }
@keyframes tags-marquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
.tags:hover .tags__track { animation-play-state: paused; }
.tag {
  display: inline-flex; align-items: center; flex: none; white-space: nowrap;
  border-radius: var(--r-control); padding: 14px 28px;
  font-size: clamp(15px, 1.35vw, 20px); line-height: 1.2; font-weight: 500;
}
/* Пять заливок ленты — это ровно пять тинтов референса плюс чернила. Классы сохранили
   исторические имена (--umber, --blue, --amber), потому что на них стоит разметка всех
   трёх языковых версий; цвет за именем теперь другой, и он в комментарии.
   Чернила на светлых тинтах: мята 14.15 · барвинок 10.66 · сливочный 15.29 ·
   холодный серый 15.87. Холст на тёмных: чернила 18.24 · тень мяты 7.15. */
.tag--dark  { background: var(--panel-dark);  color: var(--panel-dark-ink); }   /* чернила */
.tag--umber { background: var(--accent-text); color: var(--panel-dark-ink); }   /* тень мяты — вторая тёмная плашка */
.tag--blue  { background: var(--accent-2);    color: var(--ink); }              /* барвинок; чернила, а не выворотка: белый на нём даёт 1.7 */
.tag--amber { background: var(--butter);      color: var(--ink); }              /* сливочный; отвязан от --tl-fill: заливка таймлайна ушла в мяту */
.tag--light { background: var(--cool);        color: var(--ink); }              /* холодный серый: белая плашка на тёплом холсте пропала бы */

/* ── About: одна фраза плакатным кеглем, проявляется по скроллу ──
   Приём supadupa.nl, замер их живой страницы: цвет один и тот же (у них #163300 —
   ровно наш --ink), разница только в прозрачности, 1 против .2. Ни второго цвета,
   ни градиента, ни background-clip.

   Кегль на ступень мельче обложки (там clamp … 8.2vw … 122px): фраза должна читаться
   как продолжение обложки, а не спорить с ней за первый план. Верхнее поле снято —
   под блоком уже стоит полоса тегов со своими 56px, и .section добавлял бы к ним ещё 96.

   Ширина ограничена 20 словами в строку через max-width в em: на широком мониторе
   строка длиной в 1280px читается плохо даже плакатным кеглем.

   Стартовое состояние здесь ПОЛНОЙ краской, а не приглушённое. Приглушает буквы
   скрипт, и только после того, как разобрал фразу на span'ы. Значит без JS и при
   prefers-reduced-motion (скрипт в этом случае не запускается) страница показывает
   обычную читаемую фразу, а не пятно на 22% прозрачности. */
.about { padding: 72px 0 96px; }
.about__stmt {
  margin: 0; max-width: 17em;
  color: var(--ink); font-weight: 900;
  font-size: clamp(26px, 5vw, 74px); line-height: 1.06; letter-spacing: -.03em;
  text-wrap: pretty;
}
/* буквы — обычные inline-span: на перенос строк не влияют, поэтому строка
   по-прежнему рвётся только по пробелам и слово не разъезжается пополам.
   transition нет намеренно: прозрачность привязана к позиции скролла,
   и любое сглаживание превратилось бы в отставание от пальца. */
.about__c { display: inline; }

/* с выключенной анимацией лента превращается в обычный ряд с прокруткой пальцем/колесом */
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .marquee__row + .marquee__row { display: none; }
  /* то же самое для полосы тегов: дорожки стоят, лишняя копия группы убрана */
  .tags__track { animation: none; }
  .tags__row { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .tags__group + .tags__group { display: none; }
  /* строка подвала остаётся крупной и обрезанной краями экрана, но стоит на месте */
  .footer__marquee-track { animation: none; }
  .footer__marquee-group + .footer__marquee-group { display: none; }
  /* веер по-прежнему переключается, но карточки встают на новые места без проезда */
  .fan__item, .fan-card__cta, .fan-card__img { transition: none; }
}

/* ── контакт и футер ── */
.button-stack { display: flex; gap: 8px; margin-top: 32px; flex-wrap: wrap; }
.footer { padding: 64px 0 96px; }
.footer__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* подвальный wordmark мельче шапочного (117×24) и приглушён до плотности соседей
   по служебной строке: адрес и копирайт идут в --muted, логотип в полную силу
   перевешивал бы ряд, который стоит под разделителем и по смыслу служебный */
.footer__logo { display: block; height: 24px; width: 117px; max-width: 117px; object-fit: contain; object-position: left center; }
/* в футере два wordmark: тёмный оригинал (kottov-logo.svg) по умолчанию, светлый (vector.svg, как в шапке) — для тёмной темы */
.footer__logo--light { display: none; }
.footer__about { margin-top: 24px; }
.socials { display: flex; gap: 8px; margin-top: 32px; }
.social {
  width: 40px; height: 40px; border-radius: 50%; background: var(--btn-dark-bg); color: var(--btn-dark-ink);
  display: flex; align-items: center; justify-content: center; transition: background .2s;
}
/* знак наследует цвет кружка: одна заливка на все пять схем, без отдельных файлов */
.social svg { width: 17px; height: 17px; fill: currentColor; }
/* тень мяты, а не --accent: знак в кружке набран холстом, и на яркой мяте он дал бы 1.5 */
.social:hover { background: var(--accent-text); }
.footer__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 6rem; }
.footer__col { display: grid; gap: 16px; align-content: start; }
.footer-link { font-weight: 700; display: block; transition: opacity .2s; }
.footer-link:hover { opacity: .66; }
/* <address> браузер по умолчанию рисует курсивом — гасим, чтобы строка адреса
   не выбивалась из колонки контактов; ссылки там не курсивные */
.footer__addr { font-style: normal; }

/* ── подвал 2026: контакт и футер одним блоком ───────────────────────────────
   05.09.2026, приём supadupa.nl: заголовок, ряд крупных контактов и тонкая
   служебная строка. Классы новые и пока работают только в _preview-themes-2026.html —
   правила прежнего подвала выше не тронуты, index.html / ru.html / sr.html стоят на них.
   Модификатор .footer--full нужен потому, что подвал теперь начинает свой экран
   и берёт верхнее поле секции (120), а не подвала (64). */
/* Свечения в подвале больше нет (05.09.2026, вместе со схемой «Мята на бежевом»).
   Было: радиальное пятно --footer-glow (#E2FAA6) по центру блока — вывернутый наизнанку
   приём обложки, чтобы страница заканчивалась цветом, а не пустым листом.
   Снято по просьбе вместе с вуалью под шапкой. В лаймовой схеме пятно было нужно:
   холст там был чистый белый, и без него подвал обрывался в пустоту. Здесь холст
   сам тёплый (#FDFFF8), а над подвалом стоит бежевая полоса #F3F7EB — переход
   от полосы к холсту сам по себе даёт ту границу, ради которой заводилось свечение.
   Переменная --footer-glow удалена из :root: других мест у неё не было. */
.footer--full { padding-top: 0; position: relative; overflow: hidden; }

/* ── бегущая строка ──
   Кегль привязан к ширине окна: 12.5vw дают ровно 180 px на 1440, как в оригинале,
   а clamp не даёт строке ни рассыпаться на телефоне, ни расти дальше на большом мониторе.
   Трек едет на половину своей ширины: группы в нём две и одинаковые, поэтому в конце
   цикла вторая оказывается ровно там, где была первая, и склейка не читается. */
.footer__marquee { overflow: hidden; padding: 128px 0 48px; }
.footer__marquee-track { display: flex; width: max-content; animation: footer-marquee 26s linear infinite; }
/* кегль задан на группе, а не на словах: от него же считаются gap и звезда в em.
   Когда он стоял на span, .3em брались от 16 px родителя и звезда липла к тексту */
.footer__marquee-group {
  display: flex; align-items: center; gap: .26em; padding-right: .26em;
  font-size: clamp(56px, 12.5vw, 180px); line-height: 1;
}
.footer__marquee-group > span {
  font-weight: 700; letter-spacing: -.02em; white-space: nowrap; color: var(--ink);
}
/* звезда лежит на холсте подвала: яркая мята дала бы 1.66 и растворилась, поэтому её тень */
.footer__star { width: .3em; height: .3em; flex: none; fill: var(--accent-text); }
@keyframes footer-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* заголовок, подпись и кнопки — по центру; контакты ниже остаются по левому краю */
.footer__lead { max-width: 740px; margin: 0 auto; text-align: center; padding-top: 40px; }
.footer__lead .button-stack { justify-content: center; }

/* колонки по содержимому, а не равные доли: при равных на 1280 «+381 69 26 00 406»
   не влезал в свои 276 px и переносился на вторую строку. Ряд разводится по краям */
.footer__contacts {
  display: grid; grid-template-columns: repeat(4, max-content);
  justify-content: space-between; gap: 32px; margin-top: 72px;
}
/* подпись и значение — две строки грида, поэтому ссылка именно grid, а не inline-flex:
   правило тапов 44 pt ниже по файлу её обходит, иначе обе строки склеились бы в одну */
.footer-contact { display: grid; gap: 8px; align-content: start; transition: opacity .2s; }
.footer-contact:hover { opacity: .66; }
/* значение ростом с h4 — это самая крупная строка подвала после заголовка.
   nowrap: номер и почта — единые опознаваемые строки, разрыв посередине их ломает */
.footer-contact__value { font-size: 32px; line-height: 1.2; white-space: nowrap; }

.footer__bottom {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 16px 32px; margin-top: 96px; padding-top: 32px; border-top: 1px solid var(--line);
  font-size: 14px; line-height: 1.5; color: var(--muted);
}
/* .footer__mark — ссылка «наверх»: в покое держится наравне с --muted (.76),
   на ховере выходит в полную плотность, чтобы читалась как кликабельная */
.footer__mark { flex: none; opacity: .7; transition: opacity .2s; }
.footer__mark:hover, .footer__mark:focus-visible { opacity: 1; }
.footer__meta { display: flex; flex-wrap: wrap; gap: 8px 32px; }
/* Ссылка на страницу ставок стоит в служебной строке рядом с адресом и копирайтом,
   а не в меню: прайс нужен тем, кто уже дочитал до конца, и не должен ловить внимание
   на первом экране. Кегль и цвет — как у соседей по строке, подчёркивание только на ховере */
.footer__rates { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; transition: border-color .2s; }
.footer__rates:hover, .footer__rates:focus-visible { border-bottom-color: currentColor; }
.plate { padding: 24px 0 40px; font-size: 13px; line-height: 1.5; color: var(--muted); border-top: 1px solid var(--line); }

/* ── адаптив: те же три порога, что у оригинала, плюс промежуточный 1199 для первого экрана ── */
/* Ступень 992–1199 держала кегль заголовка и масштаб сцены. Обложка 05.09.2026
   считает кегль от ширины окна (clamp … 8.2vw …), отдельная ступень ей не нужна,
   и правило .hero h1 { font-size: 56px } снято: оно было специфичнее клампа. */
@media (min-width: 992px) and (max-width: 1199px) {
  .hero__scene { --s: .84; }   /* правило снятой сцены, оставлено вместе с остальными */
  /* на 1024 правая треть шапки (270px) не вмещает языки + кнопку: боковые колонки по содержимому, меню в остатке */
  .navbar__grid { grid-template-columns: auto 1fr auto; }
  .nav-menu { gap: 28px; }
}

@media (max-width: 991px) {
  /* поля панелей и ритм секций едут одним числом на каждую ступень, а не правилом на блок */
  :root { --panel-pad: 40px; --case-shot: 320px; }
  body { font-size: 15px; }
  h1 { font-size: 56px; } h2 { font-size: 44px; } h3 { font-size: 36px; }
  h4 { font-size: 28px; } h5 { font-size: 22px; } h6 { font-size: 18px; }
  .container { --pad: 32px; padding: 0 var(--pad); }
  .section { padding: 80px 0; }
  .large-section { padding: 104px 0; }
  .title { font-size: 22px; }
  .large-text { font-size: 19px; } .medium-text { font-size: 17px; }
  .space-top { margin-top: 36px; } .space-top-large { margin-top: 72px; }
  .split { grid-template-columns: 1fr; }
  .regs { grid-template-columns: 1fr; gap: 48px; }
  .creds { font-size: 24px; }

  .navbar__grid { display: flex; justify-content: space-between; align-items: center; }
  /* меню-шторка под закреплённой шапкой: ровно на остаток экрана, со своим скроллом.
     dvh, а не vh: в мобильных браузерах vh не учитывает адресную строку, и низ меню обрезался. */
  /* шторка выпадает из-под плашки, повторяет её скругление и ширину;
     absolute считается от .navbar__grid — у .container есть position: relative */
  .nav-menu {
    display: none; position: absolute; top: calc(100% + 8px);
    left: var(--plaque-inset); right: var(--plaque-inset);
    background: color-mix(in srgb, var(--panel-dark) 94%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .18), inset 0 0 0 1px var(--line-on-dark-faint);
    border-radius: var(--r-panel);
    flex-direction: column; align-items: flex-start;
    padding: 24px 32px 32px; gap: 0;
    max-height: calc(100dvh - 140px); overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav-menu.is-open { display: flex; }
  .nav-link { display: block; font-size: 18px; padding: 12px 0; }
  .nav-menu .btn { display: inline-flex; margin-top: 24px; }
  .nav-right .btn { display: none; }
  .menu-btn { display: block; }
  /* языки уходят в бургер вместе с меню */
  .nav-right .lang { display: none; }
  .lang--menu { display: inline-flex; margin: 12px 0 0; font-size: 16px; }
  .lang-note { padding: 10px 32px; }

  /* 104, а не 40: плашка шапки вынута из потока (fixed) и на планшете занимает 82 px —
     при отступе 40 заголовок первого экрана заезжал под логотип. Ниже 768 верхний отступ
     считает блок app-режима от собственной высоты шапки, здесь он задан числом */
  .hero { padding: 104px 0 var(--hero-pad-b); }
  .hero .split { grid-template-columns: 1fr; }
  .hero__text { gap: 0; }
  .hero__graph { display: none; }   /* декоративный график под интро на планшете и телефоне не показываем */
  /* стрелка «ниже есть контент» нужна там, где первый экран занимает кадр целиком.
     На одной колонке следующий блок и так начинает выглядывать из-под сцены */
  .hero__scroll { display: none; }
  .hero__actions { margin-top: 28px; }
  .hero__scene { --s: .84; justify-self: start; }
  .metrics { margin-top: 48px; }
  /* на планшете три принципа в строку становятся слишком узкими: колонка на 220 px рвёт
     заголовок по слогам. Раскладываем в две колонки, третий занимает всю ширину */
  .principles { grid-template-columns: 1fr 1fr; gap: 32px; margin-top: 48px; }
  .principle h4 { font-size: 22px; }
  /* на планшете колонка «организация | год» складывается в столбик, иначе название рвётся по слову */
  .tl__left { flex-direction: column; justify-content: flex-start; align-items: flex-end; gap: 16px; }
  .tl__org { text-align: right; }
  .tl__logo { margin-left: auto; }
  .panel { grid-template-columns: 1fr; gap: 28px; }
  .panel__meta { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-on-dark-faint); padding-top: 24px; }
  .case-card__head { grid-template-columns: 32px max-content minmax(0, 1fr) max-content auto; gap: 6px 20px; }
  .case-card__illo { width: 110px; }
  .case-card__year { font-size: 14px; }
  .case-card__content { padding-left: 52px; }
  .gallery { grid-template-columns: repeat(3, 1fr); }
  /* веер: на планшете карточка держится за долю ширины экрана, а не за 360 px потолка */
  .fan { --fan-w: min(38vw, 320px); }
  .tools { --tool-cap: 14px; }
  .marquee__row { gap: 44px; padding-right: 44px; }
  .tags { padding-top: 44px; }
  .tag { padding: 12px 22px; }
  .footer__grid { grid-template-columns: 1fr; gap: 60px; }
  .footer__cols { margin-top: 0; }
  .footer-link { font-size: 20px; }
  /* четыре контакта в ряд на планшете уже не помещаются — встают 2×2, колонки поровну */
  .footer__contacts { grid-template-columns: repeat(2, 1fr); gap: 40px 32px; }
  .footer-contact__value { font-size: 28px; }
}

@media (max-width: 767px) {
  /* вынос подложки равен полю контейнера на телефоне — а оно здесь 20, его ставит блок
     app-режима ниже по файлу (max(20px, env(safe-area-inset-*))), а не правило .container
     из этого блока. Раскрытая запись доходит до краёв экрана, как карточка в iOS-списке;
     при безопасном крае шире 20 она просто остаётся внутри него, вбок ничего не вылезает.
     Кадр плёнки — 72 vw, чтобы за ним всегда выглядывал следующий: на телефоне это
     единственный признак, что ленту можно листать */
  :root { --panel-pad: 28px 24px; --case-bleed: 20px; --case-shot: min(72vw, 320px); }
  body { font-size: 14px; }
  h1 { font-size: 48px; } h2 { font-size: 36px; } h3 { font-size: 32px; }
  h4 { font-size: 24px; } h5 { font-size: 20px; } h6 { font-size: 17px; }
  .container { --pad: 24px; padding: 0 var(--pad); }
  .section { padding: 64px 0; }
  .large-section { padding: 88px 0; }
  .title { font-size: 19px; margin-bottom: 24px; }
  .large-text { font-size: 18px; } .medium-text { font-size: 16px; }
  .space-top { margin-top: 32px; } .space-top-large { margin-top: 64px; }
  .split { gap: 16px; }
  .nav-menu { padding: 24px; }
  .hero { --hero-pad-b: 48px; padding: 40px 0 var(--hero-pad-b); }
  /* На телефоне общее правило .btn { width: 100% } растянуло бы три канала связи
     в столбик на 190 px высоты и увело фигуру за нижний край. Здесь они сворачиваются
     до кружков со знаками — той же капсулой, что .socials в футере; подпись убрана
     из кадра, но не из разметки: имя ссылки берётся из aria-label */
  .hero__actions .btn {
    width: 48px; height: 48px; padding: 0; border-radius: 50%;
  }
  .hero__actions .btn span { display: none; }
  .hero__actions .btn svg { width: 19px; height: 19px; }
  /* на телефоне сцена сворачивается до фигуры на диске: карточки с подписями в 12 px
     на ширине 375 не читаются, а масштабировать их дальше некуда. Смысл, который они
     несут, на телефоне и так дублируют карточки «How I work» экраном ниже.
     Сцена ужимается до ширины фигуры — иначе слева осталось бы поле под снятые карточки */
  .hero__scene { --s: .72; width: calc(300px * var(--s)); }
  .scene__card { display: none; }
  /* полоса чисел столбиком: число и подпись в одну строку — три строки не выше прежней сетки 2×2 */
  .metrics { grid-template-columns: 1fr; gap: 0; margin-top: 40px; }
  .metric { display: flex; align-items: baseline; gap: 16px; padding: 14px 0; }
  .metric__n { font-size: 32px; margin-bottom: 0; flex: none; min-width: 6.5ch; }
  .metric .opacity-white { font-size: 13px; line-height: 1.4; }
  .seats { grid-template-columns: 1fr 1fr; }
  .seat__label { font-size: 20px; }
  /* телефон: принципы столбиком, линия сверху у каждого остаётся — она и делит список */
  .principles { grid-template-columns: 1fr; gap: 28px; margin-top: 40px; }
  .principle h4 { font-size: 21px; }
  .principle p { font-size: 16px; }
  .panels { margin-top: 48px; }
  .panel { gap: 24px; }
  /* отступление от шкалы оригинала: наша цитата вдвое длиннее его, на телефоне 21px */
  .panel__quote { font-size: 21px; line-height: 1.45; }
  .quote-user { font-size: 16px; }
  .quote-user b { font-size: 18px; }
  .tl { grid-template-columns: 80px 20px 1fr; gap: 16px; }
  .tl__left { flex-direction: column; justify-content: flex-start; align-items: flex-end; gap: 20px; }
  .tl__org { text-align: right; }
  .tl__logo { margin-left: auto; }
  .tl__year { font-size: 18px; white-space: normal; }
  .tl__line { left: 106px; }
  .role__summary, .role ul { font-size: 16px; }
  /* телефон: миниатюра остаётся маленькой и в раскрытой полосе — на такой ширине
     текст важнее картинки, а «Case details» уезжает на свою строку под подзаголовок */
  .case-card__head {
    grid-template-columns: 28px max-content minmax(0, 1fr);
    grid-template-areas: "n illo title" "n illo field" "cta cta year";
    gap: 4px 16px; padding: 18px 0;
  }
  .case-card__illo { width: 96px; }
  .case-card__cta { justify-self: start; margin-top: 10px; }
  /* «Case details» на телефоне уехал к левому краю — «Close» едет за ним:
     держим их в одной колонке, иначе пара перестанет читаться как одна пара */
  .case-card__close { margin-left: 0; }
  /* на телефоне год уходит в нижнюю строку к «Case details», по правому краю:
     своей колонки на такой ширине нет, а строкой ниже он бы съел ещё один ряд */
  .case-card__year { margin-top: 10px; font-size: 14px; }
  .case-card__content { padding: 0 0 28px; }
  .case-card__details { grid-template-columns: 1fr; gap: 20px; }
  .case-card__field { font-size: 16px; }
  /* на телефоне лента листается пальцем, стрелки не нужны — остаётся счётчик */
  .case-gallery__arrows { display: none; }
  /* в крупном плане стрелки уходят под картинку: по краям узкого экрана они накрыли бы её саму.
     Картинка встаёт первой строкой (order), стрелки переносятся сами, счётчику оставлено поле снизу */
  .lightbox { flex-wrap: wrap; align-content: center; gap: 16px; padding: 16px 16px 64px; }
  .lightbox__img { order: -1; max-height: 66vh; }
  .lightbox__close { top: 16px; right: 16px; }
  .lightbox__count { bottom: 20px; }
  .gallery { grid-template-columns: 1fr 1fr; }
  /* Веер на телефоне. Карточка занимает почти всю ширину, поэтому вторая пара
     соседей за экран уже не помещается — остаётся по одному с каждой стороны,
     и сдвинуты они сильнее (28% вместо 25%), чтобы из-под активной торчал
     видимый край, а не полоска в три пикселя. Листается пальцем, стрелки
     убраны — тем же решением, что и в ленте кадров кейса выше. */
  /* Клип-бокс во всю ширину экрана. overflow: clip стоял на .fan, а .fan лежит
     внутри .container с полем --pad — и соседние карточки обрезались не по краю
     экрана, а по краю колонки, оставляя вдоль обоих бортов полосу фона и видимую
     вертикальную линию среза. Приём требует обратного: карточка должна уходить
     в обрез. Отрицательное поле в размер --pad расширяет .fan до краёв экрана,
     клип уезжает туда же. Центр не сдвигается: поле симметричное, а .fan__item
     позиционируется от left: 50% своего родителя. Строка со счётчиком (.fan__bar)
     лежит рядом, а не внутри, и своё поле сохраняет. */
  .fan { --fan-w: 66vw; overflow: clip; margin-left: calc(var(--pad) * -1); margin-right: calc(var(--pad) * -1); }
  .fan__item[data-p="1"]  { transform: translate( 28%, 1%) rotate( 8deg) scale(.88); }
  .fan__item[data-p="-1"] { transform: translate(-28%, 1%) rotate(-8deg) scale(.88); }
  .fan__item[data-p="2"], .fan__item[data-p="-2"] { transform: scale(.75); opacity: 0; pointer-events: none; z-index: 1; }
  .fan__arrows { display: none; }
  /* На телефоне подпись и пилюля занимают нижнюю треть карточки, а не полосу
     у кромки, поэтому затемнение начинается выше — иначе подпись ложится
     на светлый кусок скриншота и пропадает */
  .fan-card::after { inset: 45% 0 0; }
  .fan-card__title { font-size: 18px; left: 16px; right: 16px; bottom: 16px; }
  .fan__item[data-p="0"] .fan-card__title { right: 16px; bottom: 68px; }
  .fan-card__cta { left: 16px; right: 16px; bottom: 16px; justify-content: center; }
  /* На 375 лента уже, поэтому и растушёвка краёв уже: 96 px маски съедали
     половину видимого окна и логотип успевал показаться только наполовину. */
  .marquee {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
            mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
  }
  .tools { --tool-cap: 13px; }
  .marquee__row { gap: 34px; padding-right: 34px; }
  /* полоса тегов: маска уже, шаг мельче, плашки ниже — на 375 иначе в кадр
     помещается две с половиной таблетки и лента читается как обрывок */
  .tags { padding: 32px 0 4px; }
  .tags__row {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
            mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
  }
  .tags__row + .tags__row { margin-top: 8px; }
  .tags__group { gap: 8px; padding-right: 8px; }
  .tag { padding: 10px 18px; }
  /* Языки: на 375 три пункта в строку не встают, разделитель-точка повисает
     в начале строки. Поэтому на телефоне — столбик, без разделителей. */
  .langs { flex-direction: column; gap: 10px; }
  .langs__item { font-size: 17px; }
  .langs__item + .langs__item::before { content: none; }
  .footer-link { font-size: 16px; }
  /* на телефоне контакты идут столбиком: 2×2 при поле 20 обрезали бы почту и номер */
  .footer__marquee { padding: 64px 0 24px; }
  .footer__lead { padding-top: 24px; }
  .footer__contacts { grid-template-columns: 1fr; gap: 32px; margin-top: 56px; }
  .footer-contact__value { font-size: 26px; }
  .footer__bottom { margin-top: 64px; }
}

@media (max-width: 479px) {
  /* радиусов и полей панелей здесь больше нет: они лежат в шкале на :root и одинаковы
     на всех ширинах. Прежние правила (панель 20, картинки 20/16, опыт 80/20) всё равно
     не работали — их перебивал блок app-режима ниже по файлу */
  h1 { font-size: 42px; }
  .creds { font-size: 21px; }
  .container { --pad: 16px; padding: 0 var(--pad); }
  .nav-menu { padding: 16px; }
  .case-card__head { gap: 4px 12px; }
  .case-card__illo { width: 84px; }
  .panel__logo { height: 32px; }
  /* на узком экране колонка «организация · год» переезжает над роли, линия уходит к левому краю */
  .tl { grid-template-columns: 20px 1fr; gap: 12px 16px; }
  .tl__center { grid-column: 1; grid-row: 1 / span 2; }
  .tl__left { grid-column: 2; grid-row: 1; flex-direction: column; align-items: flex-start; gap: 12px; }
  .tl__org { text-align: left; }
  .tl__logo { margin-left: 0; }
  .tl__year { position: static; text-align: left; }
  .tl__right { grid-column: 2; grid-row: 2; }
  .tl__line { left: 10px; }
  .btn { width: 100%; }
  .button-stack { flex-direction: column; }
  .footer__cols { grid-template-columns: 1fr; gap: 40px; }
  /* 375: «+381 69 26 00 406» в 26 px не влезает в строку при поле 16 */
  .footer-contact__value { font-size: 22px; }
}

/* ═══════════════════════════════════════════════════════════════════
   APP-РЕЖИМ НА ТЕЛЕФОНЕ (≤767)
   ───────────────────────────────────────────────────────────────────
   Страница на узком экране ведёт себя как приложение iOS: стеклянная
   закреплённая шапка, нижняя панель разделов под большой палец вместо
   бургера, капсульные кнопки, тапы не мельче 44 pt, безопасные края.

   Блок стоит последним в файле и переопределяет предыдущие медиазапросы.
   На планшете (768–991) остаётся прежний бургер: панель разделов там
   не нужна, до низа экрана большой палец не дотягивается.

   Перенос на Tilda: и шапка, и панель — обычные Zero Block с fixed;
   backdrop-filter поддерживается всеми мобильными браузерами, где
   открывают сайт, при отсутствии поддержки остаётся плотный фон.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* высоты закреплённых слоёв — на них считаются отступы контента и якорей */
  --app-head-h: 56px;
  --app-tabbar-h: 56px;
}

/* панель разделов и стеклянные слои живут только на телефоне */
.tabbar { display: none; }

@media (max-width: 767px) {

  /* ── шапка: плавающая стеклянная плашка ──
     Сама .navbar остаётся прозрачным sticky-контейнером (так не нужен fixed
     и компенсация высоты), а плашка — это .navbar__grid: скруглённая,
     с отступом от краёв, контент виден вокруг неё и просвечивает под ней.
     Вверху страницы плашки нет вовсе: логотип и языки лежат прямо на тёмном
     первом экране. Стекло проявляется при прокрутке, по классу .is-stuck —
     так же, как панель материализуется в iOS.
     color-mix, а не литерал: иначе graphite и cobalt получили бы чужой фон. */
  .navbar {
    /* fixed, а не sticky: панель должна лежать поверх контента, а первый экран —
       уходить тёмным фоном под неё до самого верха. Со sticky над первым экраном
       оставалась светлая полоса фона страницы, и белый логотип на ней пропадал. */
    position: fixed; left: 0; right: 0; top: 0;
    background: transparent;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    padding: 8px 12px;
    padding-top: calc(env(safe-area-inset-top) + 8px);
    box-shadow: none;
  }
  /* высота панели компенсируется отступом первого экрана — он единственный,
     кто стоит под ней при загрузке */
  .hero { padding-top: calc(var(--app-head-h) + env(safe-area-inset-top) + 28px); }
  /* служебная полоса «версия готовится» в app-режиме не показывается:
     языки и так в шапке, а светлая плашка под прозрачной панелью съедала логотип */
  .lang-note { display: none !important; }
  .navbar.is-stuck { box-shadow: none; }
  /* в app-режиме плашка и есть плавающая капсула с отступом 12 от краёв экрана:
     вжимать её внутрь ещё раз не надо, ::before ложится на весь бокс */
  .navbar__grid {
    --plaque-inset: 0px;
    min-height: var(--app-head-h);
    padding: 0 16px;
    background: transparent;
  }
  .container.navbar__grid {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
  .navbar.is-stuck .navbar__grid::before {
    background: color-mix(in srgb, var(--panel-dark) 72%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .18), inset 0 0 0 1px var(--line-on-dark-faint);
  }
  .brand { padding: 8px 0; }

  /* бургер и меню-шторка уступают место нижней панели */
  .menu-btn, .nav-menu { display: none !important; }
  .nav-right .btn { display: none; }
  /* языки возвращаются в шапку: они узкие и в app-режиме это единственный
     контрол справа, бургера рядом больше нет */
  .nav-right .lang { display: inline-flex; margin-right: 0; }
  /* по высоте тап уже 44, по ширине было 28 — палец на «RU» между двумя соседями
     промахивался. 8 px по бокам дают 36 и не ломают шапку: логотип 117 + языки 130 из 335 */
  .nav-right .lang a { min-height: 44px; display: inline-flex; align-items: center; padding: 0 8px; }

  /* якорь не должен уезжать под плавающую шапку: её высота плюс верхний отступ */
  html { scroll-padding-top: calc(var(--app-head-h) + env(safe-area-inset-top) + 20px); }

  /* место под плавающую панель: её высота, отступ снизу и полоска жестов */
  body { padding-bottom: calc(var(--app-tabbar-h) + max(12px, env(safe-area-inset-bottom)) + 12px); }

  /* ── нижняя панель разделов: плавающая капсула ──
     Оторвана от краёв, скруглена, стеклянная — контент проходит под ней и
     виден в зазорах. Четыре раздела, иконка над подписью, активный подсвечен
     акцентом темы. Тап 44 pt по высоте, полоска жестов iPhone учтена
     через max(12px, env(safe-area-inset-bottom)). */
  .tabbar {
    display: grid; grid-template-columns: repeat(4, 1fr);
    position: fixed; z-index: 60;
    left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right));
    bottom: max(12px, env(safe-area-inset-bottom));
    border-radius: var(--r-panel);
    background: color-mix(in srgb, var(--bg) 72%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .16), inset 0 0 0 1px var(--line);
  }
  .tab {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; min-height: var(--app-tabbar-h); padding: 6px 4px 8px;
    color: var(--muted); text-decoration: none;
    font-size: 10px; line-height: 1.1; letter-spacing: .01em; text-align: center;
    -webkit-tap-highlight-color: transparent;
    transition: color .15s ease;
  }
  .tab svg { width: 24px; height: 24px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
  .tab.is-active { color: var(--accent-text); }
  .tab:active { opacity: .55; }
  .tab:focus-visible { outline: 2px solid var(--focus); outline-offset: -4px; border-radius: var(--r-block); }

  /* ── капсульные контролы ──
     В iOS кнопка — капсула: радиус равен половине высоты. Тап не мельче 44. */
  .btn {
    border-radius: 999px; min-height: 48px; padding: 12px 24px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .social { width: 44px; height: 44px; }

  /* Кейс на телефоне — не карточка, а строка списка: своей рамки и фона нет,
     полосы разделяет линия. Радиусы панелей, картинок и миниатюр здесь больше
     не переопределяются: одна шкала на :root работает на всех ширинах. */

  /* ── тапы 44 pt на всём, что нажимается ── */
  .fold__toggle, .case-card__cta, .case-card__close { min-height: 44px; align-items: center; }
  .fold__toggle, .case-card__cta { display: inline-flex; }
  .case-card__head { cursor: pointer; -webkit-tap-highlight-color: transparent; }
  /* .footer-contact исключён: он сам грид из подписи и значения, а inline-flex
     поставил бы обе строки в один ряд. Высоту 44 он и так перебирает вдвое */
  .footer a:not(.footer-contact), #contact a:not(.footer-contact) { min-height: 44px; display: inline-flex; align-items: center; }

  /* безопасные края экрана (альбомная ориентация, «чёлка» сбоку) */
  .container { --pad: max(20px, env(safe-area-inset-left)); padding-left: var(--pad); padding-right: max(20px, env(safe-area-inset-right)); }

  /* ── активный раздел: подложка-капсула внутри панели, как в актуальной iOS ──
     Заливка берётся из акцента темы, поэтому работает во всех пяти схемах. */
  .tab { margin: 6px 4px; border-radius: var(--r-block); min-height: 44px; padding: 4px; }
  .tab.is-active { background: color-mix(in srgb, var(--accent) 16%, transparent); }
  .tab:focus-visible { outline-offset: 0; border-radius: var(--r-block); }

  /* ── отклик на касание ──
     В iOS элемент отвечает на палец: чуть проседает и гаснет. Без этого
     страница на телефоне ощущается «мёртвой», даже если выглядит правильно. */
  .btn, .case-card__head, .fold__toggle, .case-card__close, .social {
    transition: transform .12s ease, opacity .12s ease;
    -webkit-tap-highlight-color: transparent;
  }
  .btn:active, .case-card__head:active, .fold__toggle:active, .case-card__close:active, .social:active {
    transform: scale(.975); opacity: .82;
  }

  /* уважаем системную настройку «уменьшить движение» */
  @media (prefers-reduced-motion: reduce) {
    .btn, .case-card__head, .fold__toggle, .case-card__close, .social, .navbar__grid::before { transition: none; }
    .btn:active, .case-card__head:active, .fold__toggle:active, .case-card__close:active, .social:active { transform: none; }
  }
}

/* ═══════════════════════════════════════════════════════════════════
   ДОСТУПНОСТЬ И СИСТЕМНЫЕ НАСТРОЙКИ
   Требования WCAG 2.2 и европейского акта о доступности: страница должна
   работать с клавиатуры и уважать настройки, выставленные в системе.
   ═══════════════════════════════════════════════════════════════════ */

/* ссылка «к содержимому»: невидима мышью, первая по Tab, обходит меню */
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; }
.skip-link:focus {
  left: 12px; top: 12px; padding: 12px 20px;
  background: var(--btn-light-bg); color: var(--btn-light-ink);
  border-radius: 999px; box-shadow: 0 8px 24px rgba(0, 0, 0, .2);
}

/* «Уменьшить движение» в системе: гасим и плавную прокрутку по якорям —
   иначе переход по меню превращается в долгий проезд через всю страницу */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* «Уменьшить прозрачность» в системе: стеклянные слои становятся плотными.
   Настройка есть и в iOS, и в macOS, и включают её как раз те, кому размытие
   мешает читать — оставлять стекло в этом случае нельзя. */
@media (prefers-reduced-transparency: reduce) {
  .navbar.is-stuck .navbar__grid::before {
    background: var(--panel-dark);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .tabbar {
    background: var(--bg);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  /* крупный план кадра: вместо размытия страницы под ним — сплошная подложка */
  .lightbox {
    background: var(--panel-dark);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}

/* системная цветовая схема: браузер красит по ней полосы прокрутки и поля.
   Тёмной объявлена только graphite, остальные четыре светлые. */
:root { color-scheme: light; }
html[data-theme="graphite"] { color-scheme: dark; }


/* ══════════════════════════════════════════════════════════════════════════════
   СТРАНИЦЫ РАЗБОРА КЕЙСОВ (.dd — deep dive)
   Спека — CASE-02-DEEPDIVE-SPEC.md. Раньше эти правила лежали инлайном в
   case-conf-ru.html; со второй такой страницей (case-ecom-ru.html) копия начала
   бы расходиться, поэтому блок перенесён сюда — как и требовала спека.
   Токены живут под .dd, а не в :root: иначе они перебили бы шапку и подвал.
   ══════════════════════════════════════════════════════════════════════════ */
/* ── страница разбора кейса ───────────────────────────────────────────────────
   Спека — CASE-02-DEEPDIVE-SPEC.md, фактура — CASE-02-CONF-FACTS.md.
   Устроена как страница ставок: локальные токены живут под .dd, а не в :root,
   иначе они перебили бы шапку и подвал из styles.css. Префикс dd__ (deep dive)
   выбран, чтобы не пересечься с .cx__ раскрытия кейса и с фигурами .fg-.
   Ширину и боковые поля держит сайтовый .container: левый край страницы
   совпадает с логотипом в шапке и адресом в подвале.

   Правило страницы: показываем метод, не показываем данные. Ни одного процента,
   чека и доли категории в разметке быть не должно — проверять при каждой правке. */
.dd{
  --line-dd:#E0EADD; --card-dd:#fff; --bg-alt-dd:#F3F7EB;
  --ink-dd:#151414; --muted-dd:rgba(21,20,20,.62); --accent-dd:#14634B;
  --mint-dd:#B2EEDC; --mint-bright-dd:#5ADEB7;
  /* Барвинок и сливочный были только на главной (иллюстрации карточек, теги),
     а на странице разбора из пяти тинтов Nominal работали два с половиной.
     Отсюда и ощущение одноцветной простыни: мятой красилось всё подряд, и она
     перестала что-либо значить. Теперь цвет на странице разбора закреплён за
     смыслом: мята — то, что сделали мы и что стало после коммита; барвинок —
     чужие данные, ответы людей в опросе; сливочный — то, что обещано, но ещё
     не сделано. Холодный серый остаётся состоянием «до». */
  --peri-dd:#B5C4F5; --butter-dd:#F9EBA6;
  --r-panel:28px; --r-block:20px;
  color:var(--ink-dd);
  /* шапка на десктопе position:fixed высотой 96px, поэтому первый экран
     отодвигается вниз вручную. На ≤767 она становится sticky и место занимает сама */
  padding-top:136px; padding-bottom:96px;
}
/* 40px не хватало: .navbar.is-stuck остаётся position:fixed и на узких экранах,
   высота 72px, и ссылка «К кейсам» уезжала под шапку */
@media(max-width:767px){ .dd{padding-top:96px} }

.dd a{color:var(--accent-dd)}
.dd p{margin:0 0 16px}
.dd .muted{color:var(--muted-dd)}

/* ── шапка страницы ── */
/* Возврат стоит над заголовком, а не в подвале: страница глубокая, читатель
   должен видеть выход раньше, чем начнёт спускаться */
.dd__back{display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:700;text-decoration:none;margin-bottom:28px}
.dd__back:hover{text-decoration:underline}
.dd__eyebrow{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--muted-dd);margin-bottom:14px}
.dd h1{font-size:clamp(38px,6.6vw,84px);font-weight:900;line-height:.98;letter-spacing:-.03em;margin:0 0 24px}
.dd__lead{font-size:clamp(18px,1.7vw,24px);line-height:1.35;color:var(--ink-dd);max-width:34ch;margin:0;font-weight:500}

/* Первый экран в две колонки. Одноколоночный вариант читался как страница
   документа: узкая полоса текста у левого края и пустая правая половина.
   Слева — кто и о чём, справа — оговорка про данные: она нужна рядом
   с заголовком, а не абзацем ниже. Ниже 900 колонки складываются */
.dd__hero{display:grid;grid-template-columns:1.25fr .75fr;gap:clamp(28px,5vw,72px);align-items:end}
@media(max-width:900px){ .dd__hero{grid-template-columns:1fr;align-items:start;gap:28px} }

/* Оговорка про метод стоит сразу рядом с заголовком, а не в подвале: она снимает
   вопрос «а можно ли это вообще показывать» до того, как он возникнет, и сама
   по себе говорит о том, как человек обращается с чужими данными */
.dd__note{background:var(--mint-dd);border-radius:var(--r-block);padding:24px 26px;font-size:15px;line-height:1.5}
.dd__note b{display:block;font-weight:900;margin-bottom:8px}

/* ── обложка с фотографией ──
   Кейс обезличен, и без картинки первый экран читался как служебная записка.
   Кадр выбран под текст: слева пустая тёмная плоскость кухни, справа техника.
   Логотип бренда с панели убран — клиента мы не называем */
.dd__photo{
  position:relative;border-radius:var(--r-panel);overflow:hidden;
  background:#0E0D0D;color:#fff;margin-bottom:28px;
  min-height:clamp(300px,40vw,500px);display:flex;align-items:flex-end;
}
.dd__photo__bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:72% center}
/* Градиент, а не ровное затемнение: справа кадр остаётся живым, слева
   уплотняется почти до чёрного, чтобы белый заголовок читался без подложки */
.dd__photo::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(100deg,rgba(14,13,13,.95) 0%,rgba(14,13,13,.9) 30%,rgba(14,13,13,.6) 54%,rgba(14,13,13,.15) 78%,rgba(14,13,13,0) 100%);
}
/* Ширина задана явно, а не через max-width: как flex-элемент блок схлопывался
   до самого длинного слова заголовка и текст рвался на строки по одному слову */
.dd__photo__in{position:relative;z-index:1;padding:clamp(26px,4vw,56px);flex:0 0 auto;width:min(62%,720px)}
/* Кадр кейса platform собран из вертикального среза входа: смысловая часть —
   подсвеченная вывеска — стоит в правой трети, а левые две трети дорисованы
   затемнением под текст. Общий object-position (72% на десктопе, 64% на
   телефоне) рассчитан на кадр, у которого субъект занимает всю правую половину,
   и на узком экране наводится в заливку — обложка превращается в пустой
   прямоугольник. Модификатор сдвигает фокус к правому краю; на десктопе он ни
   на что не влияет, там кадр по ширине помещается целиком. */
.dd__photo--edge .dd__photo__bg{object-position:88% center}
.dd__photo .dd__eyebrow{color:rgba(255,255,255,.66)}
/* На обложке заголовок мельче, чем был на белой странице во всю ширину:
   в колонке на 62% ширины кегль 84px рвал его на строки по одному слову */
.dd__photo h1{color:#fff;font-size:clamp(32px,4.4vw,58px);line-height:1.02;margin-bottom:20px}
.dd__photo .dd__lead{color:rgba(255,255,255,.86);font-size:clamp(16px,1.25vw,19px);max-width:46ch}
/* На узком экране кадр уже не помещается рядом с текстом: фото уходит
   в фоновую текстуру, читаемость важнее картинки */
@media(max-width:1000px){
  .dd__photo{min-height:0}
  .dd__photo__bg{object-position:64% center}
  .dd__photo::after{background:linear-gradient(180deg,rgba(14,13,13,.7) 0%,rgba(14,13,13,.9) 50%,rgba(14,13,13,.96) 100%)}
  /* Было просто width:auto, и обложка ломала страницу на телефоне: при
     flex:0 0 auto блок переставал сжиматься и вставал по самой длинной
     строке заголовка — 610px в вёрстке шириной 375. Дальше эту ширину
     подхватывал .container, и обрезано оказывалось всё, а не только
     обложка. Теперь блок сжимаемый, а min-width:0 снимает автоминимум
     флекс-элемента, из-за которого он всё равно не пролез бы. */
  .dd__photo__in{width:auto;flex:1 1 auto;min-width:0}
  /* градиент стал вертикальным, разворачивать больше нечего: текст
     возвращается влево, иначе короткий эйброу повис бы у правого края */
}

/* ── кто клиент ──
   Имя не называется, поэтому профиль бизнеса собран отдельным блоком:
   без него читатель не понимает, о ком вообще речь */
.dd__who{margin-top:36px;background:var(--card-dd);border-radius:var(--r-panel);
  padding:clamp(24px,3vw,36px);box-shadow:var(--shadow-dd)}
.dd__who h2{font-size:clamp(22px,2.4vw,30px);margin-bottom:16px}
.dd__who p{max-width:68ch;font-size:17px;line-height:1.6;margin-bottom:0}

/* ── отрыв карточек от холста ──
   Холст страницы #FDFFF8 и карточки #FFFFFF отличаются на глаз почти ничем,
   а вся граница между ними — волосяная линия. Полотно читалось одинаково
   тёплым сверху донизу. Мягкая тень возвращает карточкам слой: белое
   становится белым, а не просто другим оттенком того же листа */
.dd{--shadow-dd:0 1px 2px rgba(21,20,20,.05),0 14px 30px -18px rgba(21,20,20,.22)}
.dd__chart,.dd__fc,.dd__pollcard,.dd__step,.dd__arch__col{box-shadow:inset 0 0 0 1px var(--line-dd),var(--shadow-dd)}
/* Главные числа кейса — тоже карточка, а не строка с линейками поверх холста */
.dd__nums{background:var(--card-dd);border-radius:var(--r-panel);box-shadow:var(--shadow-dd);
  padding:clamp(20px,2.4vw,30px) clamp(24px,3vw,34px);border-top:0}
.dd__num{padding:6px 24px 6px 0}

/* ── секции ── */
/* Волосяная линия сверху вместо одних отступов: девять блоков подряд без
   разделителей сливались в сплошную простыню */
.dd section{margin-top:64px;padding-top:40px;border-top:1px solid var(--line-dd)}
.dd h2{font-size:clamp(26px,3.4vw,42px);font-weight:900;letter-spacing:-.02em;line-height:1.04;margin:0 0 24px;max-width:22ch;display:flex;gap:16px;align-items:baseline}
/* номер главы: страница читается как рассказ по шагам, а не как список разделов */
.dd__h2n{flex:0 0 auto;display:inline-flex;align-items:center;gap:10px;font-size:.44em;font-weight:900;color:var(--accent-dd);letter-spacing:0;font-variant-numeric:tabular-nums}
.dd h3{font-size:18px;font-weight:900;margin:0 0 14px}

/* ── обложка: мотивы категории ────────────────────────────────────────────────
   Восемь контурных силуэтов на тёмной плоскости, ровным строем. Стоит между
   первым экраном и строкой чисел — на месте, где у обычной статьи была бы
   фотография. Строй, а не россыпь: разбросанные значки читались бы как клипарт,
   а ряд одинаковых карточек — как каталожная плашка, что теме и соответствует.
   Символы лежат в спрайте внутри страницы (см. <symbol id="m-*">). */
.dd__cover{
  margin-top:clamp(32px,4.5vw,56px);background:var(--panel-dark);border-radius:var(--r-panel);
  padding:clamp(26px,3.6vw,46px) clamp(22px,3.2vw,42px);
  display:grid;grid-template-columns:repeat(8,1fr);gap:clamp(14px,2.4vw,34px);align-items:center;
}
@media(max-width:900px){ .dd__cover{grid-template-columns:repeat(4,1fr)} }
.dd__cover__i{display:block;width:100%;height:auto;aspect-ratio:1;color:var(--mint-bright-dd)}
/* через один приглушаем: ровный ряд одинаковой яркости выглядит как таблица
   значков, лёгкий разнобой — как composed-обложка */
.dd__cover__i:nth-child(2n){color:var(--panel-dark-ink);opacity:.5}

/* Значок у номера главы: та же линия, что в обложке, только мелко —
   тема проходит через страницу, а не остаётся в шапке */
.dd__h2i{flex:0 0 auto;width:clamp(24px,2.4vw,32px);height:clamp(24px,2.4vw,32px);color:var(--accent-dd)}
/* проза уже контейнера: строка длиннее ~70 знаков перестаёт читаться */
.dd__body{max-width:68ch;font-size:17px;line-height:1.6}

/* ── три источника ── */
/* Одинаковая форма у трёх карточек — часть аргумента: видно, что источники
   подбирались по одному правилу, а не собирались как получится */
.dd__sources{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:8px}
@media(max-width:991px){ .dd__sources{grid-template-columns:1fr} }
.dd__src{background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:30px 28px;display:flex;flex-direction:column}
.dd__src__n{font-size:13px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--accent-dd);margin-bottom:12px}
.dd__src dl{margin:0;font-size:15px;line-height:1.55}
.dd__src dt{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd);margin-top:18px}
.dd__src dt:first-child{margin-top:0}
.dd__src dd{margin:6px 0 0}

/* ── длинный блок про опрос ── */
/* Подзаголовки внутри блока, а не отдельные секции: это один сюжет,
   разбитый на шаги, и дробить его на равные с остальными разделы нельзя */
.dd__sub{font-size:20px;font-weight:900;margin:36px 0 14px;letter-spacing:-.01em}
.dd__sub:first-child{margin-top:0}
/* Крупная цитата вместо тонированной плашки: это поворотная мысль страницы,
   и по размеру она должна отличаться от соседнего абзаца, а не только фоном */
.dd__key{margin:36px 0;padding-left:clamp(20px,2.4vw,32px);border-left:3px solid var(--mint-bright-dd);
  font-size:clamp(19px,1.7vw,25px);line-height:1.35;font-weight:500;max-width:46ch;letter-spacing:-.01em}
.dd__key b{font-weight:900}

/* Вывод, который человек забирает с собой. Тёмная плашка — единственная
   на странице, поэтому работает как точка, а не как оформление */
/* Единственная тёмная плоскость страницы и единственное место во всю ширину:
   после неё читатель должен помнить одну фразу, а не абзац */
.dd__lesson{margin-top:40px;background:var(--panel-dark);color:var(--panel-dark-ink);border-radius:var(--r-panel);
  padding:clamp(30px,4.5vw,64px);font-size:clamp(21px,2.6vw,38px);line-height:1.18;font-weight:500;letter-spacing:-.02em}
.dd__lesson b{font-weight:900}

/* ── что бы сделал иначе ── */
.dd__redo{display:grid;gap:16px;margin-top:8px;max-width:68ch;padding:0;list-style:none}
.dd__redo li{background:var(--card-dd);border-radius:var(--r-block);box-shadow:inset 0 0 0 1px var(--line-dd);padding:22px 24px;font-size:16px;line-height:1.55}
.dd__redo b{display:block;font-weight:900;margin-bottom:6px}

/* ── подвал страницы ── */
.dd__foot{margin-top:72px;padding-top:28px;border-top:1px solid var(--line-dd);max-width:68ch;font-size:15px;line-height:1.6;color:var(--muted-dd)}
.dd__foot a{font-weight:700}

/* ── добавлено для case-ecom-ru: полоса цифр, факты, шаги, таблица, теги ──
   Кейс 01 доказывает себя числами (в относительных величинах), кейсу 02 числа
   показывать нельзя. Поэтому набор ниже используется только там, где он уместен. */

/* Четыре плитки, а не две: у кейса два разных доказательства — эффективность
   и доверие клиента к бюджету, плюс выручка как внешняя проверка */
/* Была строка с жирной линией сверху. После того как блок стал карточкой
   (правило .dd__nums выше), линия осталась висеть поперёк скруглённого верха
   и читалась как приклеенная: у карточки границы нет, а сверху полоса. Убрана.
   Колонки разделяет не border ячейки во всю высоту, а волосяная линия
   с отступом сверху и снизу — она не упирается в края карточки. */
.dd__nums{display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin-top:clamp(40px,6vw,72px)}
@media(max-width:900px){ .dd__nums{grid-template-columns:repeat(2,1fr);row-gap:26px} }
@media(max-width:520px){ .dd__nums{grid-template-columns:1fr} }
/* Отступ с обеих сторон, а не только справа: до 13.09.2026 левый был нулевой,
   и число соседней колонки («16», «3 недели») вставало вплотную к разделителю.
   Крайние колонки прижаты к краям карточки, иначе её падинг удвоился бы */
.dd__num{position:relative;padding:8px 30px 4px}
.dd__num:first-child{padding-left:0}
.dd__num:last-child{padding-right:0}
.dd__num:not(:last-child)::before{content:"";position:absolute;right:0;top:6px;bottom:6px;width:1px;background:var(--line-dd)}
@media(max-width:900px){
  /* в две колонки первой в ряду становится каждая нечётная — левый отступ
     снимаем с неё, а разделитель убираем у чётной, она последняя в ряду */
  .dd__num:nth-child(2n+1){padding-left:0}
  .dd__num:nth-child(2n){padding-right:0}
  .dd__num:nth-child(2n)::before{display:none}
}
@media(max-width:520px){
  .dd__num{padding-left:0;padding-right:0}
  .dd__num::before{display:none}
}
.dd__num__v{font-size:clamp(34px,3.8vw,52px);font-weight:900;letter-spacing:-.03em;line-height:1;margin-bottom:12px}
/* Полоска под числом: кратности сравниваются глазом, а не чтением цифр.
   Ширина задана инлайном в долях самого большого множителя (×10 — 100%) */
.dd__num__bar{height:6px;border-radius:999px;background:var(--bg-alt-dd);margin:2px 30px 16px 0;overflow:hidden}
.dd__num__bar i{display:block;height:100%;border-radius:999px;background:var(--mint-bright-dd)}
.dd__num--peak .dd__num__bar i{background:var(--ink-dd)}
.dd__num__l{font-size:14px;line-height:1.45;color:var(--muted-dd);max-width:26ch}

/* Факты о клиенте: подпись сверху мелко, значение снизу — как контакты в подвале */
.dd__facts{display:grid;grid-template-columns:repeat(3,1fr);gap:26px 32px;margin-top:8px}
@media(max-width:820px){ .dd__facts{grid-template-columns:repeat(2,1fr)} }
@media(max-width:520px){ .dd__facts{grid-template-columns:1fr} }
.dd__fact__k{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd);margin-bottom:6px}
.dd__fact__v{font-size:16px;line-height:1.5}
/* Пять силуэтов над перечислением категорий: то, что делает клиент, видно
   раньше, чем прочитан список. Те же знаки стоят в разделителях актов —
   страница получает один сквозной мотив вместо случайной иконки на линии */
.dd__made{display:flex;gap:10px;margin:2px 0 10px;color:var(--accent-dd)}
.dd__made svg{width:26px;height:26px;flex:0 0 auto}

/* Нумерация своя, а не ol: цифра здесь часть оформления — крупная, в кружке,
   слева от блока, а не перед первой строкой текста */
.dd__steps{display:grid;gap:14px;margin-top:8px;max-width:76ch}
.dd__step{display:grid;grid-template-columns:auto 1fr;gap:18px;align-items:start;background:var(--card-dd);border-radius:var(--r-block);box-shadow:inset 0 0 0 1px var(--line-dd);padding:22px 24px}
.dd__step__n{width:38px;height:38px;border-radius:50%;background:var(--mint-dd);display:grid;place-items:center;font-weight:900;font-size:15px}
.dd__step h3{margin-bottom:8px}
.dd__step p:last-child{margin-bottom:0}
.dd__step ul{margin:0;padding-left:20px}
.dd__step li{margin-bottom:8px;line-height:1.55}
.dd__step li:last-child{margin-bottom:0}

/* Абсолютных сумм в таблице нет и быть не может: показываем кратность
   к периоду «до», приняв его за единицу */
.dd__tbl{width:100%;max-width:68ch;border-collapse:collapse;margin-top:8px;font-size:15px}
.dd__tbl th,.dd__tbl td{text-align:left;padding:14px 16px;border-bottom:1px solid var(--line-dd)}
.dd__tbl th{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd)}
.dd__tbl td:not(:first-child){font-weight:700;white-space:nowrap}
.dd__tbl tr:last-child td{border-bottom:0}
.dd__tbl .dd__win{font-weight:900}

.dd__list{max-width:68ch;font-size:17px;line-height:1.6;padding-left:22px;margin:0 0 16px}
.dd__list li{margin-bottom:10px}

.dd__tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px}
.dd__tag{background:var(--bg-alt-dd);border-radius:999px;padding:8px 15px;font-size:14px;font-weight:500}

/* ── добавлено для case-conf-ru: кадры, хронология, воронка, «было — стало» ──
   Кейсу 02 нельзя показывать числа рынка, поэтому доказательством работают
   не плитки с процентами, а форма самой работы: сколько шагов, за сколько дней,
   что отсеялось. Компоненты общие, кейс 01 может брать их же. */

/* Полоса кадров. Тёмная подложка под картинкой, а не светлая: слайды доклада
   свёрстаны на чёрном, и белая рамка вокруг них выглядела бы обрезкой.
   Крупного плана здесь нет намеренно — страница показывает фактуру, а не
   предлагает вчитываться в слайд */
.dd__shots{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:8px}
/* Полоса кадров сразу под карточкой записи слипалась с ней: у обеих был
   отступ в 8px, рассчитанный на соседство с заголовком, а не друг с другом */
.dd__video + .dd__shots{margin-top:20px}
@media(max-width:900px){ .dd__shots{grid-template-columns:repeat(2,1fr)} }
@media(max-width:520px){ .dd__shots{grid-template-columns:1fr} }
.dd__shot{margin:0;border-radius:14px;overflow:hidden;background:var(--panel-dark)}
.dd__shot img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
/* 22px, а не 14: подпись под полосой кадров липла к картинкам и выглядела
   их частью. Столько же держит подпись под схемами — расстояние одно на все */
.dd__cap{font-size:13px;color:var(--muted-dd);margin:22px 0 0;line-height:1.5}


/* ── запись выступления ──
   Встроенного плеера здесь нет и не будет: ролик помечен возрастным
   ограничением, и YouTube отказывается отдавать его в iframe — вместо видео
   приходит серая заглушка «Sorry, this content is age-restricted». Поэтому
   блок сделан карточкой-ссылкой: постер, знак play и подпись, клик уводит
   на YouTube, где человек проходит проверку возраста. Побочная выгода —
   страница не тянет плеерные скрипты и не ставит чужие куки.
   Постер — тот же кадр записи, что на обложке страницы, только из shots/. */
.dd__video{
  display:block;position:relative;margin-top:8px;
  border-radius:var(--r-panel);overflow:hidden;background:var(--panel-dark);
  line-height:0;text-decoration:none;
}
.dd__video img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
/* Затемнение слабое: кадр и так тёмный, сильная вуаль превратила бы постер
   в серое пятно. Его задача — вытянуть мятный знак и подпись */
.dd__video::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(14,13,13,0) 40%,rgba(14,13,13,.78) 100%);
}
.dd__video__mark{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1;
  width:clamp(64px,7vw,84px);aspect-ratio:1;border-radius:50%;
  background:var(--mint-bright-dd);display:grid;place-items:center;
  transition:transform .2s;
}
.dd__video__mark svg{width:36%;height:36%;fill:var(--ink-dd);margin-left:8%}
.dd__video:hover .dd__video__mark,
.dd__video:focus-visible .dd__video__mark{transform:translate(-50%,-50%) scale(1.07)}
.dd__video:focus-visible{outline:3px solid var(--mint-bright-dd);outline-offset:3px}
.dd__video__label{
  position:absolute;left:clamp(16px,3vw,28px);right:clamp(16px,3vw,28px);
  bottom:clamp(14px,2.4vw,22px);z-index:1;
  color:#fff;font-size:15px;font-weight:700;line-height:1.35;
}
/* Оговорка про возраст — тем же блоком, но тише: она предупреждение,
   а не приглашение, и спорить с самой ссылкой ей незачем */
.dd__video__note{display:block;margin-top:4px;font-size:13px;font-weight:400;color:rgba(255,255,255,.74)}
@media(prefers-reduced-motion:reduce){ .dd__video__mark{transition:none} }

/* ── ноутбук с живой прокруткой ──
   Лендинг 2018 года — страница 1356×2824, то есть в семь экранов высотой.
   Резать её на плитки значило показывать те куски, которые я сам выбрал;
   вместо этого она лежит целиком внутри экрана ноутбука, и читатель
   прокручивает её сам. Рамка собрана дивами, а не картинкой-макетом:
   картинка потребовала бы второго файла под тёмную тему и не тянулась бы
   по ширине контейнера.

   Прокрутка нативная и включена сразу, без скрипта и без клика: блок занимает
   меньше половины экрана, и перехват колёсика на нём не стоит отдельной
   ступеньки для читателя. overscroll-behavior намеренно не трогаем — на
   умолчании докрутка до низа продолжает листать страницу, так что запереться
   внутри нельзя. */
.dd__laptop{margin:24px 0 0}
/* Ширина ноутбука задана тремя ограничениями сразу, и каждое зачем-то нужно:
   100% — не вылезти из колонки; calc(62vh*1.6) — влезть по высоте в экран
   целиком, вместе с подставкой; 760px — потолок по резкости. Снимок лендинга
   шириной 1356px: на экране с двойной плотностью он остаётся чётким примерно
   до 700 CSS-пикселей, а растянутый во всю колонку (около 1100) заметно
   мылится. Множитель 1.6 — пропорция экрана 16:10, то есть ноутбучная;
   прежние 16:9 во всю ширину читались телевизором, а не ноутбуком. */
.dd__laptop__lid{
  width:min(100%, calc(62vh * 1.6), 760px);margin-inline:auto;
  background:linear-gradient(180deg,#3a3737,#242222);
  border-radius:16px 16px 8px 8px;padding:clamp(10px,1.1vw,16px);
  box-shadow:0 30px 70px rgba(0,0,0,.28),inset 0 1px 0 rgba(255,255,255,.10);
}
/* Глазок камеры над экраном: две детали, по которым рамка читается ноутбуком,
   а не просто тёмным прямоугольником, — этот кружок и подставка ниже */
.dd__laptop__cam{height:10px;display:flex;align-items:center;justify-content:center}
.dd__laptop__cam i{width:5px;height:5px;border-radius:50%;background:#4c4848;display:block}
.dd__laptop__lid{position:relative}
.dd__laptop__scroll{
  aspect-ratio:16/10;overflow-y:auto;
  -webkit-overflow-scrolling:touch;background:#fff;border-radius:4px;
  scrollbar-width:thin;scrollbar-color:#c9cfd4 transparent;
}
.dd__laptop__scroll:focus-visible{outline:2px solid var(--accent-dd,#5ADEB7);outline-offset:2px}
.dd__laptop__scroll::-webkit-scrollbar{width:8px}
.dd__laptop__scroll::-webkit-scrollbar-thumb{background:#c9cfd4;border-radius:8px}
.dd__laptop__scroll img{display:block;width:100%;height:auto}
/* Подставка шире крышки — иначе силуэт читается монитором, а не ноутбуком */
.dd__laptop__base{
  width:min(100%, calc(62vh * 1.6), 760px);margin-inline:auto;height:clamp(10px,1vw,14px);
  transform:scaleX(1.055);
  background:linear-gradient(180deg,#2b2828,#151313);
  border-radius:0 0 10px 10px;position:relative;
}
.dd__laptop__base::after{
  content:'';position:absolute;left:50%;top:0;transform:translateX(-50%);
  width:14%;height:4px;background:#0d0c0c;border-radius:0 0 4px 4px;
}
@media(max-width:700px){
  /* На телефоне 16:10 от узкой колонки даёт окно высотой пальца в два —
     прокручивать в нём нечего. Пропорцию отпускаем и задаём высоту явно */
  .dd__laptop__scroll{aspect-ratio:auto;height:clamp(280px,48vh,400px)}
  .dd__laptop__base{transform:scaleX(1.035)}
}

/* ── ноутбук в липкой сцене (кейс 05) ──
   У кейса 03 лендинг высотой в семь экранов, и читатель крутит его сам внутри
   рамки. У кейса 05 страница высотой в двадцать: своя прокрутка внутри такого
   окна — это отдельная работа, которую никто делать не станет, и половина
   лендинга останется непросмотренной. Поэтому здесь ноутбук останавливается
   в центре экрана и лендинг едет внутри от прокрутки страницы: читатель
   проходит через всю работу, не выбирая, листать её или нет.

   Сцена — .dd__scene, её высоту ставит page.js: высота липкого блока плюс
   разгон в data-screens экранов. Длина 4 экрана выбрана Максимом 13.09.2026:
   получается 1.7× к скорости скролла, это читаемо; на двух экранах — 3.5×
   и мельтешение.

   Без скрипта (и при prefers-reduced-motion) класс is-scene не появляется,
   и блок остаётся обычным ноутбуком кейса 03 с нативной прокруткой внутри.
   Отсюда же запрет на loading="lazy" у картинки: в режиме сцены слой
   абсолютный и лежит внутри overflow:hidden, Chrome считает его невидимым
   и не грузит вовсе — картинка не появляется никогда. Проверено на стенде
   _preview-mvp-laptop.html. */
.dd__scene{position:relative;margin-top:28px}
.dd__scene__in{position:sticky;top:max(104px,9vh)}
.dd__scene .dd__laptop{margin-top:0}
.dd__scene .dd__laptop__scroll{position:relative}
.dd__scene.is-scene .dd__laptop__scroll{overflow:hidden}
/* top/left, а не inset:0 — при inset высота тянется до контейнера, картинка
   теряет пропорцию и ехать внутри становится нечему */
.dd__scene.is-scene .dd__laptop__scroll img{position:absolute;top:0;left:0;will-change:transform}
/* Полоса по нижней кромке экрана: без неё длинная прокрутка читается как
   зависшая анимация — непонятно, сколько ещё ехать */
.dd__scene__prog{position:absolute;left:0;bottom:0;height:3px;width:0;background:var(--mint-bright-dd)}
@media(max-width:767px){ .dd__scene__in{top:max(84px,6vh)} }

/* Хронология. Главный рассказ кейса — три недели от отказа до чистых данных,
   и он читается датами, а не абзацем. Поворотный день помечен крупной точкой:
   это единственное место, где решение приняли не по процессу */
.dd__time{margin-top:8px;max-width:76ch}
.dd__ev{display:grid;grid-template-columns:104px 26px 1fr}
.dd__ev__d{font-size:13px;font-weight:700;color:var(--muted-dd);padding-top:1px}
.dd__ev__r{position:relative}
.dd__ev__r i{display:block;width:11px;height:11px;border-radius:50%;background:var(--panel-dark);margin:5px auto 0;position:relative;z-index:1}
.dd__ev__r::before{content:"";position:absolute;left:50%;top:6px;bottom:0;width:2px;margin-left:-1px;background:rgba(21,20,20,.16)}
.dd__ev:last-child .dd__ev__r::before{display:none}
.dd__ev__b{padding:0 0 30px 18px;font-size:16px;line-height:1.55}
.dd__ev__b b{display:block;font-weight:900;margin-bottom:4px}
.dd__ev--turn .dd__ev__r i{width:17px;height:17px;margin-top:2px;background:var(--mint-bright-dd);box-shadow:0 0 0 4px var(--mint-dd)}
@media(max-width:560px){
  .dd__ev{grid-template-columns:64px 22px 1fr}
  .dd__ev__d{font-size:12px}
  .dd__ev__b{font-size:15px;padding-left:12px}
}

/* Воронка выборки. Две полосы, а не круговая диаграмма: разница между
   собранным и чистым здесь маленькая, и именно это надо показать честно —
   отсеялось немного, но отсеялось по правилу */
.dd__funnel{margin-top:8px;max-width:60ch;display:grid;gap:18px}
.dd__fbar__h{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin-bottom:8px}
.dd__fbar__h span{font-size:14px;color:var(--muted-dd)}
.dd__fbar__h b{font-size:26px;font-weight:900;letter-spacing:-.02em}
.dd__fbar__t{height:14px;border-radius:999px;background:var(--bg-alt-dd);overflow:hidden}
.dd__fbar__t i{display:block;height:100%;border-radius:999px;background:var(--panel-dark)}
.dd__fbar--keep .dd__fbar__t i{background:var(--mint-bright-dd)}
.dd__cut{margin:0;padding-left:20px;font-size:15px;line-height:1.55;color:var(--muted-dd)}
.dd__cut li{margin-bottom:6px}

/* «Было — стало» по слайду. Две колонки одинакового веса: решение спорное,
   и подавать его односторонне нечестно — у отвергнутого варианта было
   настоящее достоинство, точность */
.dd__vs{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:8px}
@media(max-width:820px){ .dd__vs{grid-template-columns:1fr} }
.dd__vs>div{border-radius:var(--r-panel);padding:26px 24px;font-size:16px;line-height:1.55}
.dd__vs>div p:last-child{margin-bottom:0}
.dd__vs__was{background:var(--bg-alt-dd)}
.dd__vs__now{background:var(--mint-dd)}
.dd__vs__k{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd);margin-bottom:10px}

/* ── сторителлинг на странице разбора: акты, переходы, графики, опрос ──
   Добавлено для case-ecom-ru. Страница длинная, и без ритма она читается как
   отчёт. Акт — крупная цифра над заголовком, переход — одна фраза во всю
   ширину между блоками. Оба элемента ничего не украшают: они держат сюжет. */

/* Номер акта сидит в мятной капсуле: строка «АКТ 04 · Отдача» набором ничем
   не отличалась от подписи к схеме, и начало новой главы приходилось искать */
.dd__act{display:flex;align-items:center;gap:12px;margin-bottom:16px}
.dd__act__n{font-size:12px;font-weight:900;letter-spacing:.08em;color:var(--accent-dd);
  background:var(--mint-dd);border-radius:999px;padding:6px 12px}
.dd__act__t{font-size:13px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted-dd)}

/* Фраза-переход между актами. Без кавычек и курсива: это не цитата,
   а авторский голос, и он должен звучать как утверждение */
.dd__hook{margin:56px 0 0;max-width:24ch;font-size:clamp(24px,3.4vw,38px);font-weight:900;line-height:1.12;letter-spacing:-.02em}
.dd__hook--wide{max-width:34ch}

/* ── кривая роста ──
   Столбики нормированы к максимальному месяцу, подписей значений нет и быть
   не может: показываем форму кривой, а не суммы. Высота задаётся инлайном —
   это данные, а не оформление, поэтому им место в разметке. */
.dd__chart{margin-top:28px;background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:clamp(22px,3vw,32px)}
.dd__chart__cap{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd);margin-bottom:22px}
.dd__bars{display:flex;align-items:flex-end;gap:3px;height:190px}
.dd__bar{flex:1;min-width:0;background:var(--cool);border-radius:4px 4px 0 0;transition:height .2s}
/* месяцы после перестройки — акцентом; месяц запуска — тёмный, он точка отсчёта */
.dd__bar--after{background:var(--mint-bright-dd)}
.dd__bar--start{background:var(--ink-dd)}
.dd__chart__axis{display:flex;justify-content:space-between;margin-top:12px;font-size:12px;font-weight:700;color:var(--muted-dd)}
.dd__chart__axis span:nth-child(2){color:var(--ink-dd)}
.dd__chart__legend{display:flex;flex-wrap:wrap;gap:16px;margin-top:18px;font-size:13px;color:var(--muted-dd)}
.dd__chart__legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:7px;vertical-align:-1px}

/* ── результаты опроса ──
   Горизонтальные полосы: сравниваются доли внутри одного вопроса, а не
   вопросы между собой, поэтому каждая группа замкнута в свою карточку. */
.dd__poll{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:8px}
@media(max-width:900px){ .dd__poll{grid-template-columns:1fr} }
.dd__pollcard{background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:26px 24px}
.dd__pollcard h3{font-size:16px;font-weight:900;margin:0 0 4px}
.dd__pollcard__q{font-size:13px;line-height:1.45;color:var(--muted-dd);margin-bottom:18px}
.dd__row{display:grid;grid-template-columns:1fr 44px;gap:10px;align-items:center;margin-bottom:11px}
.dd__row:last-child{margin-bottom:0}
.dd__row__lab{font-size:14px;line-height:1.35}
.dd__row__track{height:7px;border-radius:999px;background:var(--bg-alt-dd);margin-top:6px;overflow:hidden}
/* Опрос красится барвинком, а не мятой: мята на странице значит «наш результат
   после коммита», а это ответы 700 человек — входные данные, а не отдача.
   Ключевая строка остаётся чернилами: это ответ, ради которого опрос заказывали */
.dd__row__fill{display:block;height:100%;border-radius:999px;background:var(--peri-dd)}
.dd__row--key .dd__row__fill{background:var(--ink-dd)}
.dd__row__val{font-size:15px;font-weight:900;text-align:right}

/* Одиночная цифра строкой — там, где число само по себе и есть вывод.
   Слева мятная кромка: плашка на светло-зелёном отличалась от холста почти
   ничем и терялась между абзацами, а рамку сюда ставить нельзя — блок должен
   читаться врезкой, а не карточкой */
.dd__stat{position:relative;display:grid;grid-template-columns:auto 1fr;gap:20px;align-items:baseline;margin-top:26px;padding:22px 26px 22px 30px;background:var(--bg-alt-dd);border-radius:var(--r-block);max-width:68ch;overflow:hidden}
.dd__stat::before{content:"";position:absolute;left:0;top:0;bottom:0;width:5px;background:var(--mint-bright-dd)}
/* Цифры опроса — барвинком, как и его полосы: это не наш результат, а замер */
.dd__stat--poll::before{background:var(--peri-dd)}
.dd__stat__v{font-size:clamp(30px,4vw,42px);font-weight:900;line-height:1;letter-spacing:-.02em}
.dd__stat__l{font-size:15px;line-height:1.5}

/* Доли от одного целого: полоса — весь расход, залитая часть — поиск.
   Строкой «43% → 21%» это читалось как «на поиск стали тратить вдвое меньше»,
   хотя в деньгах поиск вырос: уменьшилась его доля. Две полосы одной длины
   показывают именно долю и снимают ошибку чтения */
.dd__stat--share{align-items:center;gap:26px}
@media(max-width:560px){ .dd__stat--share{grid-template-columns:1fr;gap:18px} }
.dd__share{display:grid;gap:14px;width:clamp(190px,26vw,260px)}
.dd__share__row{display:grid;grid-template-columns:66px 1fr;gap:12px;align-items:center}
.dd__share__row b{font-size:clamp(24px,2.6vw,30px);font-weight:900;letter-spacing:-.03em;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--muted-dd)}
.dd__share__row--now b{color:var(--ink-dd)}
.dd__share__t{height:16px;border-radius:999px;background:#fff;box-shadow:inset 0 0 0 1px var(--line-dd);overflow:hidden}
/* Тот же холодный тон, что у столбиков «до» на кривой роста в акте 01,
   и та же яркая мята у «после»: цвет по всей странице значит одно и то же */
.dd__share__t i{display:block;height:100%;border-radius:999px;background:#C3D2DA}
.dd__share__row--now .dd__share__t i{background:var(--mint-bright-dd)}

/* ── инфографика продажи прогноза (case-ecom-ru, акты 01–04) ──
   Сюжет кейса — не «настроили рекламу», а «убедили собственника вложиться».
   Значит центральные элементы страницы: стена (ровная линия расхода),
   цепочка прогноза и размер коммита. Всё в относительных величинах. */

/* Цепочка прогноза: звенья со стрелками. На узком экране разворачивается
   в столбик, стрелки поворачиваются вниз через ::after */
.dd__chain{display:flex;flex-wrap:wrap;align-items:stretch;gap:10px;margin-top:8px}
.dd__link{flex:1 1 140px;min-width:0;position:relative;background:var(--card-dd);border-radius:var(--r-block);box-shadow:inset 0 0 0 1px var(--line-dd);padding:18px 16px}
.dd__link--out{background:var(--mint-dd);box-shadow:none}
.dd__link__n{font-size:11px;font-weight:700;letter-spacing:.08em;color:var(--muted-dd);margin-bottom:8px}
.dd__link__t{font-size:15px;font-weight:900;line-height:1.25}
.dd__link__s{font-size:12px;line-height:1.4;color:var(--muted-dd);margin-top:6px}

/* Два сценария прогноза — крупная кратность и подпись под ней */
.dd__scen{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin-top:20px;max-width:68ch}
@media(max-width:640px){ .dd__scen{grid-template-columns:1fr} }
.dd__scen__card{border-radius:var(--r-panel);padding:26px 24px;background:var(--bg-alt-dd)}
.dd__scen__card--hi{background:var(--panel-dark);color:var(--panel-dark-ink)}
.dd__scen__k{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;opacity:.7;margin-bottom:10px}
.dd__scen__v{font-size:clamp(34px,5vw,52px);font-weight:900;line-height:1;letter-spacing:-.02em}
.dd__scen__l{font-size:14px;line-height:1.45;margin-top:10px;opacity:.75}

/* Рычаг: во сколько раз выросло обязательство. Одна цифра во всю ширину —
   это поворотная точка кейса, и она не должна делить место ни с чем */
.dd__lever{margin-top:28px;background:var(--mint-bright-dd);border-radius:var(--r-panel);padding:clamp(28px,4vw,44px);display:grid;grid-template-columns:auto 1fr;gap:clamp(20px,4vw,44px);align-items:center}
@media(max-width:640px){ .dd__lever{grid-template-columns:1fr;gap:16px} }
.dd__lever__v{font-size:clamp(56px,10vw,110px);font-weight:900;line-height:.9;letter-spacing:-.04em}
.dd__lever__l{font-size:clamp(16px,2vw,19px);line-height:1.45;font-weight:500}

/* Разбивка коммита: одна полоса на сто процентов, доли подписаны снизу */
.dd__split{margin-top:26px;max-width:68ch}
.dd__split__bar{display:flex;height:44px;border-radius:12px;overflow:hidden}
.dd__split__seg{display:grid;place-items:center;font-size:14px;font-weight:900;color:var(--panel-dark-ink)}
.dd__split__seg--a{background:#151414}
.dd__split__seg--b{background:#3E7F6B}
.dd__split__seg--c{background:#5ADEB7;color:var(--ink-dd)}
.dd__split__key{display:flex;flex-wrap:wrap;gap:18px;margin-top:14px;font-size:13px;color:var(--muted-dd)}
.dd__split__key i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:7px;vertical-align:-1px}

/* ── график брендового спроса (case-ecom-ru, акт 06) ──

/* Брендовый спрос: слева сравнение кварталов, справа помесячная динамика.
   Столбики от нуля — разница честно выглядит скромно, и это правильно:
   плюс восемнадцать процентов к спросу на бренд не должны рисоваться взлётом. */
.dd__brand{display:grid;grid-template-columns:220px 1fr;gap:28px;margin-top:8px;background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:clamp(22px,3vw,32px)}
@media(max-width:820px){ .dd__brand{grid-template-columns:1fr;gap:34px} }
.dd__brand__cap{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-dd);margin-bottom:18px}
.dd__qoq{display:flex;align-items:flex-end;gap:16px;height:170px}
.dd__qoq__col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;height:100%}
.dd__qoq__v{font-size:13px;font-weight:900;margin-bottom:6px;text-align:center}
.dd__qoq__bar{border-radius:6px 6px 0 0;background:var(--cool)}
.dd__qoq__col--after .dd__qoq__bar{background:var(--mint-bright-dd)}
.dd__qoq__lab{font-size:11px;color:var(--muted-dd);text-align:center;margin-top:8px;line-height:1.3}
/* Крупный вариант той же гистограммы — для кейса platform. Там замеров всего
   три, и число под каждым это и есть сюжет (50 → 102 → 120), поэтому подпись
   значения набрана дисплейным кеглем, а не служебными 13px квартальной
   гистограммы кейса 01, где столбиков двенадцать и читается форма, а не цифры. */
.dd__qoq--lg{height:260px;gap:clamp(14px,4vw,44px)}
.dd__qoq--lg .dd__qoq__v{font-size:clamp(26px,3.4vw,40px);letter-spacing:-.03em;line-height:1;margin-bottom:12px}
.dd__qoq--lg .dd__qoq__lab{font-size:13px;margin-top:12px}
/* Третий замер сделан уже без автора: по палитре страницы это чужие данные,
   а не наш результат, поэтому барвинок, а не мята */
.dd__qoq__col--other .dd__qoq__bar{background:var(--peri-dd)}
.dd__delta{display:inline-block;margin-top:14px;font-size:26px;font-weight:900;color:var(--accent-dd)}
/* полоса месяцев: последние три помечены — на них пришлись медийные флайты */
.dd__months{display:flex;align-items:flex-end;gap:6px;height:170px}
.dd__month{flex:1;border-radius:4px 4px 0 0;background:var(--cool)}
.dd__month--flight{background:var(--mint-bright-dd)}
.dd__months__axis{display:flex;justify-content:space-between;margin-top:10px;font-size:11px;font-weight:700;color:var(--muted-dd)}
.dd__months__note{margin-top:12px;font-size:13px;line-height:1.45;color:var(--muted-dd)}

/* ── перерисованные слайды проекта (case-ecom-ru) ──
   Раньше здесь стояли скриншоты презентации. Растр на странице выглядит
   вставкой из другого документа: свой шрифт, своя палитра, нечитаемо на
   телефоне и не масштабируется. Поэтому все три схемы собраны разметкой —
   тем же шрифтом и теми же цветами, что остальная страница. */

/* Таймлайн сделки: точки на общей линии, под каждой — срок и что произошло.
   Сетка на шесть колонок, шагов четыре, поэтому сплошная линия во всю ширину
   уезжала на две пустые колонки вправо и висела в воздухе. Линию рисует не
   контейнер, а сам шаг: отрезок от своей точки до следующей. У последнего
   шага отрезка нет — линия кончается ровно там, где кончаются события,
   сколько бы их ни было. */
.dd__tl{position:relative;display:grid;grid-template-columns:repeat(6,1fr);gap:14px;margin-top:8px;padding-top:26px}
@media(max-width:860px){
  .dd__tl{grid-template-columns:1fr;padding-top:0;padding-left:26px;gap:20px}
}
.dd__tl__step{position:relative}
.dd__tl__step:not(:last-child)::before{content:"";position:absolute;left:6px;top:-16px;width:calc(100% + 14px);height:2px;background:var(--line-dd)}
@media(max-width:860px){
  .dd__tl__step:not(:last-child)::before{left:-21px;top:8px;width:2px;height:calc(100% + 20px)}
}
.dd__tl__dot{position:absolute;top:-21px;left:0;width:12px;height:12px;border-radius:50%;background:var(--mint-bright-dd);box-shadow:0 0 0 4px var(--bg)}
@media(max-width:860px){ .dd__tl__dot{top:2px;left:-26px} }
/* Последний шаг — медиаплан на год вперёд: он обещан, но на момент рассказа
   ещё не сделан. Серая точка читалась как «выключено», сливочная — как «впереди» */
.dd__tl__step--plan .dd__tl__dot{background:var(--butter-dd)}
.dd__tl__when{font-size:12px;font-weight:900;letter-spacing:.04em;text-transform:uppercase;color:var(--muted-dd);margin-bottom:8px}
.dd__tl__what{font-size:14px;line-height:1.4}
.dd__tl__what + .dd__tl__what{margin-top:8px;padding-top:8px;border-top:1px solid var(--line-dd)}

/* Прогноз: три сценария, столбик — состав месячного бюджета в долях базового.
   Абсолютных сумм нет: слайд для собственника был в рублях, на странице
   те же пропорции без денег. */
.dd__fc{margin-top:8px;background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:clamp(22px,3vw,32px)}
.dd__fc__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,3vw,32px);align-items:end}
.dd__fc__col{display:flex;flex-direction:column;justify-content:flex-end}
.dd__fc__out{margin-bottom:14px;text-align:center}
.dd__fc__out b{display:block;font-size:clamp(20px,2.6vw,30px);font-weight:900;line-height:1;letter-spacing:-.02em}
.dd__fc__out span{display:block;font-size:12px;line-height:1.35;color:var(--muted-dd);margin-top:6px}
.dd__fc__stack{display:flex;flex-direction:column-reverse;border-radius:8px;overflow:hidden}
.dd__fc__seg{display:grid;place-items:center;font-size:12px;font-weight:700}
.dd__fc__seg--base{background:var(--cool);color:var(--ink-dd)}
.dd__fc__seg--perf{background:#3E7F6B;color:#fff}
.dd__fc__seg--media{background:var(--mint-bright-dd);color:var(--ink-dd)}
.dd__fc__name{margin-top:12px;text-align:center;font-size:14px;font-weight:900}
.dd__fc__key{display:flex;flex-wrap:wrap;gap:18px;margin-top:22px;font-size:13px;color:var(--muted-dd)}
.dd__fc__key i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:7px;vertical-align:-1px}

/* Схема размещения: три колонки — от товарных групп к кампаниям.
   Новое помечено мятным, как было на исходной схеме зелёным. */
.dd__arch{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:8px}
@media(max-width:860px){ .dd__arch{grid-template-columns:1fr} }
.dd__arch__col{background:var(--card-dd);border-radius:var(--r-panel);box-shadow:inset 0 0 0 1px var(--line-dd);padding:22px 20px}
.dd__arch__h{font-size:12px;font-weight:900;letter-spacing:.06em;text-transform:uppercase;color:var(--muted-dd);margin-bottom:14px}
.dd__arch__grp{margin-bottom:16px}
.dd__arch__grp:last-child{margin-bottom:0}
.dd__arch__t{font-size:14px;font-weight:900;margin-bottom:8px}
.dd__arch__s{font-size:12px;line-height:1.45;color:var(--muted-dd);margin-bottom:8px}
.dd__arch__list{display:flex;flex-wrap:wrap;gap:6px}
.dd__arch__i{font-size:12px;line-height:1.3;background:var(--bg-alt-dd);border-radius:8px;padding:6px 10px}
.dd__arch__i--new{background:var(--mint-dd);font-weight:700}
.dd__arch__key{margin-top:16px;font-size:13px;color:var(--muted-dd)}
.dd__arch__key i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:7px;vertical-align:-1px;background:var(--mint-dd)}

/* ── схематичная техника: обложка, разделители актов, водяной знак ──
   Страница длинная и почти без картинок. Контурные силуэты встроенной техники
   дают ей предметность и режут полотно на части, не отвлекая: тонкая линия,
   цвет текста, приглушённая непрозрачность. Категория, а не марка — кейс
   обезличен, узнаваемый силуэт конкретного бренда его бы выдал. */

/* Полоса на обложке: шесть силуэтов в ряд под вводной плашкой */
.dd__glyphs{display:flex;flex-wrap:wrap;gap:clamp(18px,4vw,40px);margin-top:36px;color:var(--ink-dd);opacity:.28}
.dd__glyphs svg{width:clamp(38px,5vw,54px);height:auto;flex:0 0 auto}

/* Разделитель между актами: линия — знак — линия.
   Секции рисуют себе границу сверху (.dd section), и после разделителя их
   было видно две: линия со знаком, через 36px — ещё одна, во всю ширину.
   Граница у секции сразу за разделителем погашена: линия остаётся одна.
   Знак был 34px при opacity .4 и читался пятном на линии; теперь это жетон
   на мятной заливке в акцентном цвете — он и держит ритм глав. */
.dd__div{display:flex;align-items:center;gap:20px;margin-top:88px;color:var(--accent-dd)}
.dd__div::before,.dd__div::after{content:"";flex:1;height:1px;background:var(--line-dd)}
.dd__div svg{width:26px;height:26px;flex:0 0 auto;padding:13px;box-sizing:content-box;
  border-radius:50%;background:var(--mint-dd)}
.dd__div + section{margin-top:44px;padding-top:0;border-top:0}
@media(max-width:600px){
  .dd__div{margin-top:64px;gap:14px}
  .dd__div svg{width:22px;height:22px;padding:11px}
  .dd__div + section{margin-top:32px}
}

/* ── смена тира в финале ──
   Две ступени: левая ниже и холодная, правая выше и мятная. Высота здесь
   не данные, а положение — тир, в котором клиент числился у платформы,
   поэтому подписей значений нет и быть не должно */
.dd__tier{display:grid;grid-template-columns:1fr auto 1fr;gap:clamp(14px,2.5vw,26px);
  align-items:end;margin-top:32px;max-width:68ch}
@media(max-width:600px){ .dd__tier{grid-template-columns:1fr;align-items:stretch;gap:12px} }
.dd__tier__box{position:relative;overflow:hidden;border-radius:var(--r-panel);
  padding:22px 24px;display:grid;gap:6px}
.dd__tier__box--from{background:var(--cool);padding-bottom:22px}
.dd__tier__box--to{background:var(--mint-dd);padding-top:38px;padding-bottom:30px}
@media(max-width:600px){ .dd__tier__box--to{padding-top:22px} }
.dd__tier__k{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted-dd)}
.dd__tier__t{font-size:clamp(18px,2.2vw,24px);font-weight:900;letter-spacing:-.02em;line-height:1.1}
/* Стрелка стоит на уровне текста левой ступени, а не по центру блока:
   по центру она повисала между двумя разными высотами и читалась случайной */
.dd__tier__arrow{align-self:center;color:var(--accent-dd);padding-bottom:18px}
.dd__tier__arrow svg{width:26px;height:26px;display:block}
@media(max-width:600px){
  .dd__tier__arrow{justify-self:center;padding:0;transform:rotate(90deg)}
}
/* Тот же водяной знак, что в плашке с ×5: силуэт уходит за правый край */
.dd__tier__mark{position:absolute;right:-14px;bottom:-18px;width:110px;height:auto;
  color:var(--ink-dd);opacity:.12;pointer-events:none}
@media(max-width:600px){ .dd__tier__mark{display:none} }

/* Водяной знак в плашке с крупной цифрой: силуэт уходит за правый край */
.dd__lever{position:relative;overflow:hidden}
.dd__lever__mark{position:absolute;right:-18px;bottom:-24px;width:190px;height:auto;color:var(--ink-dd);opacity:.13;pointer-events:none}
@media(max-width:640px){ .dd__lever__mark{display:none} }

/* ═════════ страница-каталог кейсов (/cases/) ═════════════════════════════════
   13.09.2026. Полный список всех девяти работ с фильтром по направлению.
   Строка списка повторяет полосу блока Work на главной — тот же слот с
   иллюстрацией, то же название крупным, тот же период справа, — но раскрытия
   у неё нет: каталог отправляет либо на страницу разбора, либо никуда.
   Поэтому классы свои (.case-row), а .case-card остаётся на статье ради двух
   вещей: волосяных линий списка и пары цветов иллюстрации (--illus-*), которые
   уже разведены по девяти записям селектором .case-card[data-illo]. */
.cases-page { padding-top: 136px; padding-bottom: 96px; }
/* на ≤767 шапка становится ниже, но остаётся fixed — ссылка возврата уезжала под неё */
@media (max-width: 767px) { .cases-page { padding-top: 96px; } }
.cases-page .dd__back { color: var(--accent-text); }
/* заголовок держит узкую меру и ломается на три строки, лид под ним шире:
   у плакатного кегля и у текста мера чтения разная */
.cases-page__lead h1 {
  font-size: clamp(34px, 5.2vw, 64px); font-weight: 900;
  line-height: 1.02; letter-spacing: -.025em; margin: 0 0 18px; max-width: 16ch;
}
.cases-page__lead p { max-width: 46ch; margin: 0; }

/* ── лента фильтра ──
   Таблетки, а не табы: таб обещает, что за ним отдельная витрина, а здесь
   фильтр только сужает один и тот же список. Активная — чернилами, как кнопка
   подвала; остальные холодным серым, тем же, что пятая плашка ленты тегов.
   Число набрано табличными цифрами и стоит после подписи вполголоса: оно
   говорит, сколько записей останется, до того как по чипу нажали. */
.cases-filter {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 40px 0 8px;
}
.case-chip {
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  padding: 11px 20px; border-radius: var(--r-control);
  background: var(--cool); color: var(--ink);
  font-size: 15px; font-weight: 700; line-height: 1.2;
  text-decoration: none; transition: background .15s, color .15s;
}
.case-chip:hover { background: var(--mint); }
.case-chip.is-on { background: var(--panel-dark); color: var(--panel-dark-ink); }
.case-chip.is-on:hover { background: var(--panel-dark); }
.case-chip__n { font-weight: 500; font-variant-numeric: tabular-nums; opacity: .55; }
.case-chip:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

/* ── строка каталога ──
   Замыкающая линия висит на самом списке, а не на последней записи: фильтр
   прячет записи через hidden, и линия у :last-child пропадала бы вместе с ней. */
.cases.case-rows { margin-top: 28px; border-bottom: 1px solid var(--line); }
.cases.case-rows .case-card:last-child { border-bottom: 0; }
.case-row__head {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr) max-content auto;
  grid-template-areas:
    "illo title year cta"
    "illo field year cta"
    "illo lede  year cta"
    "illo tags  year cta";
  gap: 6px 28px; align-items: center; padding: 22px 0;
  color: inherit; text-decoration: none;
}
.case-row__head:focus-visible { box-shadow: inset 0 0 0 2px var(--focus); border-radius: var(--r-control); }
.case-row .case-card__illo { grid-area: illo; }
.case-row__title {
  grid-area: title; margin: 0;
  font-size: clamp(22px, 2.2vw, 30px); font-weight: 900;
  letter-spacing: -.02em; line-height: 1.15;
}
.case-row .case-card__field { grid-area: field; }
/* Короткое описание (12.10.2026): что сделано и что вышло, два-три предложения.
   До этого жило в раскрытии на главной; аккордеон снят, и у записей без
   разбора это единственный текст. Стоит у всех девяти, чтобы список не делился
   на два сорта. */
.case-row__lede { grid-area: lede; margin: 4px 0 2px; font-size: 15px; line-height: 1.5; color: var(--muted); max-width: 72ch; }
.case-row .case-card__year { grid-area: year; }
/* Теги стоят тихо: это не пять цветных плашек ленты первого экрана, а подпись
   к строке. Разделитель — точка между соседними, чтобы два тега не слиплись
   в одно словосочетание. */
.case-row__tags { grid-area: tags; display: flex; flex-wrap: wrap; gap: 0 8px; }
.case-tag {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted);
}
.case-tag + .case-tag::before { content: '·'; margin-right: 8px; opacity: .6; }
.case-row__cta {
  grid-area: cta; color: var(--accent-text); font-weight: 700;
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  transition: opacity .2s;
}
.case-row__cta::after { content: '\2192'; font-size: 20px; line-height: 1; }
.case-row__head:hover .case-row__cta { opacity: .75; }
/* Запись без разбора никуда не ведёт: гасим и подложку наведения, и указатель —
   иначе строка обещает переход, которого нет */
.case-row.is-plain:hover::before { opacity: 0; }
.case-row.is-plain .case-row__head { cursor: default; }
/* ── строка без разбора раскрывается на месте (12.10.2026) ──
   Голова — кнопка, подложка наведения возвращается, подпись «Show details»
   с плюсом/минусом, как у «Details» в опыте. Внутри — лента кадров (.ev, та же,
   что была в раскрытии на главной) и четыре списка (.case-card__details).
   Левое поле — ширина миниатюры плюс зазор колонки, чтобы текст встал под
   названием; на ≤991 миниатюра мельче и поле снимается. */
.case-row.has-fold .case-row__head { cursor: pointer; }
.case-row.has-fold:hover::before { opacity: .35; }
.case-row.has-fold.is-open::before { opacity: 1; }
.case-row__cta--fold::after { content: '+'; font-size: 22px; line-height: 1; }
.is-open .case-row__cta--fold::after { content: '\2013'; }
.case-row__inside { padding: 4px 0 32px 160px; }
.case-row__inside .ev { margin: 8px 0 0; }
.case-row__inside .case-card__details { margin-top: 24px; }
.case-row__inside .case-card__block h6 { font-size: 15px; }
@media (max-width: 991px) { .case-row__inside { padding-left: 0; } }
@media (max-width: 767px) { .case-row__inside { padding-bottom: 24px; } .case-row__inside .case-card__details { grid-template-columns: 1fr; gap: 20px; } }

.cases-page__note {
  margin-top: 28px; color: var(--muted); font-size: 16px; max-width: 70ch;
}
.cases-page__note a { color: var(--accent-text); }

@media (max-width: 991px) {
  .case-row__head {
    grid-template-columns: max-content minmax(0, 1fr);
    grid-template-areas:
      "illo title"
      "illo field"
      "lede lede"
      "tags tags"
      "year cta";
    gap: 8px 20px;
  }
  /* миниатюра прижата к верху: рядом с ней название и поле занимают до пяти
     строк, и по центру она повисала посреди текста */
  .case-row .case-card__illo { align-self: start; }
  .case-row .case-card__year { justify-self: start; }
  .case-row__cta { justify-self: end; }
  .case-row__tags { margin-top: 6px; }
}
@media (max-width: 767px) {
  .case-row .case-card__illo { width: 88px; }
  .cases-filter { gap: 8px; margin-top: 32px; }
  .case-chip { padding: 9px 16px; font-size: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════
   ПЛАШКА «ЕСТЬ ВЕРСИЯ НА ВАШЕМ ЯЗЫКЕ»
   Разметку собирает lang-suggest.js, там же вся логика и объяснение,
   кому и когда она показывается. Здесь только вид.

   Почему не полоса во всю ширину сверху и не модальное окно по центру:
   и то и другое перебивает первый экран, ради которого человек пришёл.
   Это не согласие на куки и не платный доступ — это подсказка, и вести
   она себя должна как подсказка: угол экрана, контент виден целиком,
   закрывается одним движением и больше не возвращается.

   Левый нижний угол, а не правый: справа на телефоне живут кнопки
   браузера и «наверх», а на десктопе взгляд после первого экрана уходит
   влево к тексту. На телефоне плашка становится листом во всю ширину
   и встаёт над панелью разделов, а не поверх неё.
   ═══════════════════════════════════════════════════════════════════ */

.langbar {
  position: fixed; z-index: 70;
  left: max(20px, env(safe-area-inset-left));
  bottom: max(20px, env(safe-area-inset-bottom));
  width: min(380px, calc(100vw - 40px));
  display: grid; gap: 10px;
  padding: 18px 20px;
  border-radius: var(--r-panel);
  background: var(--card);
  box-shadow: var(--card-ring), 0 18px 44px rgba(0, 0, 0, .18);
  /* появление: плашка выезжает снизу и проявляется. До .is-open она
     сдвинута и прозрачна, но уже в потоке — иначе переход не с чего начать */
  opacity: 0; transform: translateY(14px);
  transition: opacity .22s ease, transform .22s ease;
}
.langbar.is-open { opacity: 1; transform: none; }

/* Шапка плашки: знак, заголовок и крестик одной строкой. Знак и крестик стоят
   здесь, а не колонками всей карточки, чтобы текст и кнопки шли во всю ширину:
   иначе на 380 px под кнопки остаётся 254, и пара «Да, перейти» + «Остаться на
   английском» разваливается на две строки, а карточка вырастает вдвое. */
.langbar__head { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; }

/* знак: тот же стиль, что у иконок разделов — штрих 1.7 без заливки */
.langbar__icon {
  display: grid; place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--r-thumb);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent-text);
}
.langbar__icon svg {
  width: 18px; height: 18px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}

.langbar__title { margin: 0; font-size: 16px; font-weight: 700; line-height: 1.25; letter-spacing: -.01em; }
.langbar__text  { margin: 0; font-size: 14px; line-height: 1.45; color: var(--muted); }

.langbar__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
/* кнопки в плашке мельче страничных: карточка 380 px, и пара кнопок по 56
   съела бы её половину. Вариант .btn--small в файле уже есть, заводить
   третий размер незачем */
.langbar__actions .btn { font-size: 14px; padding: 10px 16px; min-height: 40px; }

/* крестик: то же значение, что у закрытия карточки кейса — «убрать с глаз» */
.langbar__close {
  display: grid; place-items: center;
  width: 30px; height: 30px; margin-right: -6px;
  padding: 0; border: 0; border-radius: var(--r-control);
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.langbar__close svg {
  width: 16px; height: 16px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round;
}
.langbar__close:hover { background: var(--btn-light-bg); color: var(--ink); }
.langbar__close:focus-visible,
.langbar .btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Телефон: лист во всю ширину над панелью разделов. Панель закреплена внизу
   и высотой --app-tabbar-h, поэтому плашка поднимается ровно на неё —
   иначе накрыла бы навигацию, которой человек и пользуется, чтобы уйти */
@media (max-width: 767px) {
  .langbar {
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    width: auto;
    bottom: calc(var(--app-tabbar-h) + max(12px, env(safe-area-inset-bottom)) + 12px);
  }
  .langbar__actions .btn { flex: 1 1 auto; }
}

/* «уменьшить движение» в системе: плашка появляется без выезда */
@media (prefers-reduced-motion: reduce) {
  .langbar { transition: opacity .01s linear; transform: none; }
}


/* ── крупный план кадра на страницах разбора ──
   Полоса кадров показывает факт, крупный план даёт рассмотреть: слайд
   доклада, вывеску на фасаде, снимок зала. Слой один на страницу, собирает
   и наполняет его page.js. Фон почти непрозрачный: кадры разной яркости,
   и на полупрозрачном фоне светлый слайд сливался бы с текстом под ним. */
.dd-lb{
  position:fixed;inset:0;z-index:120;display:none;
  align-items:center;justify-content:center;
  padding:clamp(16px,4vw,56px);
  background:rgba(14,13,13,.94);
}
.dd-lb.is-on{display:flex}
.dd-lb__img{max-width:100%;max-height:100%;display:block;border-radius:10px;object-fit:contain}
.dd-lb__x,.dd-lb__nav{
  position:absolute;border:0;cursor:pointer;color:#fff;
  background:rgba(255,255,255,.12);border-radius:999px;
  display:grid;place-items:center;line-height:1;
  transition:background .15s;
}
.dd-lb__x:hover,.dd-lb__nav:hover{background:rgba(255,255,255,.22)}
.dd-lb__x:focus-visible,.dd-lb__nav:focus-visible{outline:2px solid var(--mint-bright-dd);outline-offset:2px}
.dd-lb__x{top:clamp(12px,2vw,22px);right:clamp(12px,2vw,22px);width:44px;height:44px;font-size:26px}
.dd-lb__nav{top:50%;transform:translateY(-50%);width:48px;height:48px;font-size:20px}
.dd-lb__nav--prev{left:clamp(8px,1.6vw,20px)}
.dd-lb__nav--next{right:clamp(8px,1.6vw,20px)}
.dd-lb__n{position:absolute;bottom:clamp(12px,2vw,22px);left:0;right:0;text-align:center;
  color:rgba(255,255,255,.7);font-size:13px;font-variant-numeric:tabular-nums}
/* На телефоне стрелки съедали бы кадр по бокам: листаем кнопками внизу
   не нужно — хватает счётчика и закрытия, кадры листаются свайпом страницы */
@media(max-width:520px){ .dd-lb__nav{width:40px;height:40px;opacity:.9} }

/* Кадр в полосе теперь кликабельный — курсор и лёгкий отклик говорят об этом */
.dd__shot.is-zoomable{cursor:zoom-in}
.dd__shot.is-zoomable img{transition:transform .25s}
.dd__shot.is-zoomable:hover img{transform:scale(1.03)}
.dd__shot.is-zoomable:focus-visible{outline:3px solid var(--mint-bright-dd);outline-offset:3px}
@media(prefers-reduced-motion:reduce){
  .dd__shot.is-zoomable img{transition:none}
  .dd__shot.is-zoomable:hover img{transform:none}
}


/* ── Кейс-инфографика (.ig): короткий текст, каждый акт — вывод и схема.
   Впервые на кейсе ecom, 09.10.2026. Каркас общий, чтобы переносить на остальные разборы ── */
.ig{--gap:clamp(16px,2vw,24px);padding-bottom:40px}
.ig .dd__photo h1{max-width:16ch}
.ig-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap);margin-top:var(--gap)}
.ig-kpi{background:var(--card);border-radius:var(--r-panel,24px);box-shadow:inset 0 0 0 1px var(--line);padding:22px 24px}
.ig-kpi--dark{background:var(--panel-dark);color:var(--panel-dark-ink);box-shadow:none}
.ig-kpi__v{font-size:clamp(40px,4.6vw,64px);font-weight:900;letter-spacing:-.04em;line-height:.95}
.ig-kpi--dark .ig-kpi__v{color:var(--mint-bright)}
.ig-kpi__v--t{font-size:clamp(26px,2.6vw,36px);letter-spacing:-.02em;line-height:1.05}
.ig-kpi__k{font-size:14px;line-height:1.35;margin-top:10px;color:var(--muted)}
.ig-kpi--dark .ig-kpi__k{color:var(--panel-dark-muted)}
.ig-note{font-size:13px;color:var(--muted);margin:14px 2px 0}
.ig-client{display:grid;grid-template-columns:auto 1fr 1fr 1fr 1fr;gap:var(--gap);align-items:center;margin-top:40px;padding:22px 26px;border-radius:var(--r-panel,24px);background:var(--bg-alt)}
.ig-client__icons{display:flex;gap:6px;color:var(--accent-text)}
.ig-client__icons svg{width:30px;height:30px}
.ig-client b{display:block;font-size:12px;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);margin-bottom:4px}
.ig-client span{font-size:15px;font-weight:700;line-height:1.3}
.ig-nav{position:sticky;top:84px;z-index:5;display:flex;gap:6px;flex-wrap:wrap;margin:48px 0 0;padding:8px;border-radius:999px;background:rgba(253,255,248,.88);backdrop-filter:blur(10px);box-shadow:inset 0 0 0 1px var(--line);width:max-content;max-width:100%}
.ig-nav a{font-size:13px;font-weight:700;text-decoration:none;color:var(--ink);padding:8px 14px;border-radius:999px;display:flex;gap:8px;align-items:center}
.ig-nav a i{font-style:normal;color:var(--muted);font-variant-numeric:tabular-nums}
.ig-nav a.is-on{background:var(--panel-dark);color:var(--panel-dark-ink)}
.ig-nav a.is-on i{color:var(--mint-bright)}
.ig section{margin-top:88px;scroll-margin-top:150px}
.ig-act{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent-text);margin-bottom:12px}
.ig h2{font-size:clamp(28px,3.6vw,46px);font-weight:900;letter-spacing:-.025em;line-height:1.02;margin:0 0 14px;max-width:26ch;display:block}
.ig-lead{font-size:18px;line-height:1.5;max-width:56ch;margin:0 0 32px}
.ig-grid{display:grid;gap:var(--gap)}
.ig-g2{grid-template-columns:1fr 1fr}.ig-g3{grid-template-columns:repeat(3,1fr)}.ig-g21{grid-template-columns:1.6fr 1fr}
.ig-card{background:var(--card);border-radius:var(--r-panel,24px);box-shadow:inset 0 0 0 1px var(--line);padding:26px}
.ig-card--mint{background:var(--mint);box-shadow:none}.ig-card--peri{background:var(--peri);box-shadow:none}.ig-card--butter{background:var(--butter);box-shadow:none}
.ig-card--dark{background:var(--panel-dark);color:var(--panel-dark-ink);box-shadow:none}
.ig-cap{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);margin-bottom:18px}
.ig-card--dark .ig-cap{color:var(--panel-dark-faint)}
.ig-big{font-size:clamp(44px,5vw,72px);font-weight:900;letter-spacing:-.04em;line-height:.95}
.ig-small{font-size:14px;line-height:1.4;margin-top:10px}
/* bars */
.ig-bars{display:flex;align-items:flex-end;gap:5px;height:220px}
.ig-bars span{flex:1;border-radius:5px 5px 2px 2px;background:var(--cool)}
.ig-bars span.p{background:#C9D3D8}.ig-bars span.l{background:var(--ink)}.ig-bars span.a{background:var(--mint-bright)}
.ig-axis{display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-top:8px}
.ig-zones{display:grid;grid-template-columns:8fr 4fr 1fr 11fr;gap:5px;margin-top:14px;font-size:12px;font-weight:700;line-height:1.25}
.ig-zones div{border-top:3px solid var(--cool);padding-top:8px}
.ig-zones div:nth-child(2){border-color:#C9D3D8}.ig-zones div:nth-child(3){border-color:var(--ink)}.ig-zones div:nth-child(4){border-color:var(--mint-bright)}
/* vs */
.ig-vs{display:grid;grid-template-columns:1fr auto 1fr;gap:14px;align-items:stretch}
.ig-vs__x{align-self:center;font-weight:900;font-size:22px;color:var(--muted)}
.ig-who{font-size:20px;font-weight:900;margin-bottom:12px}
.ig-li{list-style:none;padding:0;margin:0;font-size:15px;line-height:1.4;display:grid;gap:8px}
.ig-li li{display:flex;gap:10px}.ig-li li::before{content:"–";color:var(--muted)}
.ig-li--ok li::before{content:"✓";color:var(--accent-text);font-weight:900}
/* timeline */
.ig-tl{display:grid;grid-template-columns:repeat(4,1fr);margin-top:40px;position:relative}
.ig-tl::before{content:"";position:absolute;left:0;right:0;top:7px;height:2px;background:var(--mint-bright)}
.ig-tl div{position:relative;padding-top:28px;padding-right:16px;font-size:14px;line-height:1.35}
.ig-tl div::before{content:"";position:absolute;top:0;left:0;width:16px;height:16px;border-radius:50%;background:var(--panel-dark);box-shadow:0 0 0 3px var(--mint-bright)}
.ig-tl b{display:block;font-size:12px;letter-spacing:.07em;text-transform:uppercase;color:var(--accent-text);margin-bottom:4px}
/* meter */
.ig-meter{height:14px;border-radius:99px;background:var(--cool);overflow:hidden;margin:16px 0 8px}
.ig-meter span{display:block;height:100%;background:var(--ink);border-radius:99px}
/* funnel */
.ig-funnel{display:grid;gap:8px}
.ig-funnel div{margin:0 auto;border-radius:14px;padding:16px 20px;display:flex;justify-content:space-between;gap:16px;align-items:center;font-size:15px;width:100%}
.ig-funnel b{font-size:17px}
.ig-funnel small{font-size:13px;opacity:.8;text-align:right}
/* chain */
.ig-chain{display:flex;align-items:stretch;gap:0;flex-wrap:wrap}
.ig-chain div{flex:1;min-width:120px;background:var(--cool);padding:18px 26px 18px 30px;font-weight:700;font-size:15px;clip-path:polygon(0 0,calc(100% - 16px) 0,100% 50%,calc(100% - 16px) 100%,0 100%,16px 50%);margin-right:-10px}
.ig-chain div:first-child{clip-path:polygon(0 0,calc(100% - 16px) 0,100% 50%,calc(100% - 16px) 100%,0 100%);border-radius:14px 0 0 14px;padding-left:22px}
.ig-chain div:last-child{background:var(--mint-bright);margin-right:0}
.ig-chain small{display:block;font-weight:500;font-size:12px;color:var(--muted);margin-top:2px}
/* two futures */
.ig-fut{display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:end;height:300px;padding:0 10%}
.ig-fut__col{display:flex;flex-direction:column;justify-content:flex-end;height:100%;text-align:center}
.ig-fut__v{font-size:clamp(28px,3vw,40px);font-weight:900;letter-spacing:-.03em;line-height:1.1}
.ig-fut__s{font-size:12px;color:var(--muted);margin-bottom:10px}
.ig-fut__stack{display:flex;flex-direction:column;border-radius:12px;overflow:hidden;font-size:12px;font-weight:700}
.ig-fut__stack span{display:flex;align-items:center;justify-content:center}
.ig-fut__l{font-weight:700;font-size:14px;margin-top:10px}
.ig-legend{display:flex;gap:18px;flex-wrap:wrap;font-size:12px;color:var(--muted);margin-top:16px}
.ig-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:-1px}
/* split */
.ig-split{display:flex;height:64px;border-radius:14px;overflow:hidden;font-weight:900;font-size:18px}
.ig-split span{display:flex;align-items:center;padding:0 16px}
.ig-split__l{display:flex;font-size:13px;margin-top:10px;color:var(--muted)}
/* steps */
.ig-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap);counter-reset:s}
.ig-step{position:relative;border-radius:var(--r-panel,24px);padding:24px}
.ig-step__n{width:34px;height:34px;border-radius:50%;background:var(--panel-dark);color:var(--mint-bright);display:grid;place-items:center;font-weight:900;margin-bottom:16px}
.ig-step b{display:block;font-size:19px;margin-bottom:6px}
.ig-step p{font-size:14px;line-height:1.45;margin:0}
.ig-step:not(:last-child)::after{content:"→";position:absolute;right:calc(var(--gap) * -1);top:28px;width:var(--gap);text-align:center;font-weight:900;color:var(--muted)}
/* delta */
.ig-delta{display:flex;align-items:center;gap:18px;line-height:1.05;margin-bottom:14px;flex-wrap:wrap}
.ig-delta__a{font-size:clamp(36px,4vw,54px);font-weight:900;letter-spacing:-.03em;color:var(--muted);text-decoration:line-through;text-decoration-thickness:3px}
.ig-delta__ar{font-size:30px;font-weight:900}
.ig-delta__b{font-size:clamp(36px,4vw,54px);font-weight:900;letter-spacing:-.03em}
/* hbars */
.ig-hb{display:grid;gap:10px}
.ig-hb div{display:grid;grid-template-columns:1fr 46px;gap:10px;align-items:center;font-size:14px}
.ig-hb div>span{position:relative;padding:7px 10px;border-radius:8px;overflow:hidden;z-index:0}
.ig-hb div>span::before{content:"";position:absolute;inset:0;width:var(--w);background:var(--cool);z-index:-1;border-radius:8px}
.ig-hb div.hl>span::before{background:var(--mint-bright)}
.ig-hb em{font-style:normal;font-weight:900;text-align:right;font-variant-numeric:tabular-nums}
.ig-q{font-size:13px;color:var(--muted);margin:-8px 0 16px;line-height:1.4}
/* dots */
.ig-dots{display:grid;grid-template-columns:repeat(20,1fr);gap:5px;max-width:360px}
.ig-dots i{aspect-ratio:1;border-radius:50%;background:var(--line-on-dark-faint);box-shadow:inset 0 0 0 1px var(--line-on-dark)}
.ig-dots i.on{background:var(--mint-bright);box-shadow:none}
.ig-dots i.half{background:var(--peri);box-shadow:none}
/* changes */
.ig-chg{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.ig-chg div{border-top:3px solid var(--ink);padding-top:16px}
.ig-chg b{display:block;font-size:18px;margin-bottom:6px}
.ig-chg p{font-size:14px;line-height:1.45;margin:0;color:var(--muted)}
.ig-chg__ic{font-size:22px;margin-bottom:10px}
/* stairs */
.ig-stairs{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap);align-items:end}
.ig-stairs div{border-radius:var(--r-panel,24px);padding:24px;font-weight:900;font-size:22px;display:flex;flex-direction:column;justify-content:flex-end}
.ig-stairs small{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;opacity:.7;margin-bottom:6px}
.ig-quote{font-size:clamp(22px,2.4vw,32px);font-weight:900;line-height:1.2;letter-spacing:-.015em;max-width:30ch;margin:0}
/* цитата клиента (12.10.2026, dorado): абзацами, текстовым кеглем, подпись под ней */
.ig-quote--client{font-size:clamp(17px,1.5vw,20px);font-weight:500;line-height:1.5;letter-spacing:0;max-width:64ch}
.ig-quote--client p{margin:0 0 14px}
.ig-quote--client p:last-child{margin:0}
.ig-who{margin-top:18px;display:flex;flex-direction:column;gap:2px;font-size:15px}
.ig-who b{font-size:16px}
.ig-who span{color:var(--muted)}
.ig-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.ig-tags span{font-size:13px;font-weight:700;padding:7px 12px;border-radius:999px;background:var(--cool)}
.ig details{margin-top:var(--gap);border-radius:var(--r-panel,24px);box-shadow:inset 0 0 0 1px var(--line);padding:18px 24px;background:var(--card)}
.ig summary{cursor:pointer;font-weight:700;font-size:15px}
.ig details[open] summary{margin-bottom:16px}
.ig-arch{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;font-size:14px;line-height:1.45}
.ig-arch h4{margin:0 0 8px;font-size:15px}
.ig-arch ul{margin:0;padding-left:18px}
.ig-arch .new{background:var(--mint);border-radius:6px;padding:0 4px}
/* map: «возражение → блок на странице», строки с иконкой. Впервые на mvp */
.ig-map{display:grid;gap:10px}
.ig-map__h,.ig-map__r{display:grid;grid-template-columns:44px minmax(0,1fr) 28px minmax(0,1.3fr);gap:18px;align-items:center}
.ig-map__h{padding:0 24px;font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.ig-map__r{padding:18px 24px;border-radius:18px;background:var(--card);box-shadow:inset 0 0 0 1px var(--line)}
.ig-map__ic{color:var(--accent-text)}.ig-map__ic svg{width:38px;height:38px;display:block}
.ig-map__q{font-weight:900;font-size:clamp(18px,1.7vw,22px);line-height:1.2;letter-spacing:-.01em}
.ig-map__ar{font-weight:900;font-size:22px;color:var(--muted);text-align:center}
.ig-map__a b{display:block;font-size:16px;margin-bottom:3px}
.ig-map__a span{font-size:14px;line-height:1.4;color:var(--muted)}
.ig-li b{font-weight:900}
/* ноутбук-сцена (.dd__scene) внутри .ig: липнет ниже липкого оглавления */
.ig .dd__scene{margin-top:var(--gap)}
.ig .dd__scene__in{top:max(150px,14vh)}
.ig-foot{margin-top:72px;font-size:13px;line-height:1.55;color:var(--muted);max-width:80ch;border-top:1px solid var(--line);padding-top:20px}
/* добавлено на кейсе platform: 5 точек таймлайна, 3 столбика, макет кнопок, переключатель */
.ig-tl--5{grid-template-columns:repeat(5,1fr)}
.ig-fut--3{grid-template-columns:repeat(3,1fr);padding:0 4%}
.ig-btns{display:flex;gap:10px;flex-wrap:wrap;margin:4px 0 6px}
.ig-btn{display:inline-flex;align-items:center;padding:11px 18px;border-radius:999px;font-weight:700;font-size:14px;line-height:1.2}
.ig-btn--p{background:var(--mint-bright);color:var(--ink)}
.ig-btn--o{box-shadow:inset 0 0 0 2px var(--ink);color:var(--ink)}
.ig-btn__n{font-size:11px;font-weight:900;margin-right:8px;opacity:.55}
.ig-seg{display:inline-flex;padding:4px;border-radius:999px;box-shadow:inset 0 0 0 1px var(--line);margin-bottom:16px}
.ig-seg span{padding:7px 18px;border-radius:999px;font-weight:900;font-size:14px}
.ig-seg span.on{background:var(--panel-dark);color:var(--mint-bright)}
.ig-shots{margin-top:var(--gap)}
.ig-card--dark .ig-li li::before{color:var(--mint-bright)}
.ig-shots .dd__shots{grid-template-columns:repeat(3,1fr);margin-top:0}
.ig .dd__laptop{margin-top:0}
@media (max-width:900px){
 .ig-kpis{grid-template-columns:1fr 1fr}.ig-client{grid-template-columns:1fr 1fr}.ig-client__icons{grid-column:1/-1}
 .ig-g2,.ig-g3,.ig-g21,.ig-steps,.ig-chg{grid-template-columns:1fr}
 .ig-step:not(:last-child)::after{display:none}
 .ig-vs{grid-template-columns:1fr}.ig-vs__x{justify-self:center}
 .ig-tl{grid-template-columns:1fr 1fr;row-gap:20px}.ig-tl::before{display:none}
 .ig-nav{top:72px;flex-wrap:nowrap;overflow-x:auto;border-radius:18px}
 .ig-fut{padding:0}.ig-bars{gap:2px;height:160px}.ig-zones{font-size:10px}
 .ig-arch{grid-template-columns:1fr}
 .ig-tl--5{grid-template-columns:1fr 1fr}.ig-fut--3{padding:0;gap:12px}
 .ig-shots .dd__shots{grid-template-columns:1fr}
 .ig-map__h{display:none}.ig-map__r{grid-template-columns:32px 1fr;gap:6px 14px}.ig-map__ic svg{width:30px;height:30px}
 .ig-map__ar{display:none}.ig-map__a{grid-column:2}
 .ig .dd__scene__in{top:max(130px,12vh)}
}

/* добавлено на кейсе conf: 6 точек таймлайна с отказом и поворотом, «не даёт», проекционный вопрос */
.ig-tl--6{grid-template-columns:repeat(6,1fr)}
.ig-tl .is-no::before{background:var(--bg);box-shadow:0 0 0 3px var(--muted)}
.ig-tl .is-no b{color:var(--muted)}
.ig-tl .is-hl::before{background:var(--mint-bright);box-shadow:0 0 0 3px var(--panel-dark)}
.ig-tl .is-hl{font-weight:700}
.ig-li--no{margin-top:8px}
.ig-li--no li{color:var(--muted)}.ig-li--no li::before{content:"✕";color:var(--muted);font-weight:900}
.ig-src{color:var(--muted);border-top:1px solid var(--line);padding-top:12px;margin-top:16px}
.ig-big--t{font-size:clamp(34px,3.8vw,52px)}
.ig-kpi__v--long{font-size:clamp(28px,4.6vw,64px);white-space:nowrap}
.ig-plus{font-size:.4em;letter-spacing:0;font-weight:700;color:var(--muted)}
.ig-ask{display:grid;gap:6px;margin-bottom:6px}
.ig-ask__a{font-size:clamp(20px,2vw,26px);font-weight:700;color:var(--muted);text-decoration:line-through;text-decoration-thickness:2px}
.ig-ask__ar{font-size:22px;font-weight:900}
.ig-ask__b{font-size:clamp(26px,2.8vw,38px);font-weight:900;letter-spacing:-.02em;line-height:1.1}
.ig-hb--wide div{grid-template-columns:1fr 56px}
.ig-chg--2{grid-template-columns:1fr 1fr}
.ig-split--txt span{font-size:15px;line-height:1.25}
@media (max-width:900px){ .ig-tl--6{grid-template-columns:1fr 1fr} .ig-chg--2{grid-template-columns:1fr} .ig-split--txt{flex-direction:column;height:auto}.ig-split--txt span{width:100%!important;padding:14px 16px} }

/* ── проявление блоков при прокрутке (motion.js, приём с dorado.expert) ──
   Атрибут data-reveal ставит скрипт и только блокам ниже первого экрана; класс
   js-reveal — тоже он, поэтому без скрипта правило не срабатывает и страница
   остаётся целиком видимой. Подъём короткий, 24 px: дальше блок читался бы
   прилетающим, а не проявляющимся. Под «Уменьшить движение» скрипт не запускается
   вовсе, правило ниже — страховка. */
.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .7s cubic-bezier(.2, .7, .3, 1), transform .7s cubic-bezier(.2, .7, .3, 1);
  transition-delay: var(--reveal-d, 0ms);
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ── добавлено на кейсе dorado (10.10.2026): линия по годам, кадры живого сайта,
   полоса первых экранов, сравнение с конкурентами точками ──
   График рисует build-case-dorado.py из CSV и вставляет в страницу готовым SVG:
   цвета берутся отсюда, через классы, чтобы фигура жила в той же палитре. */
.ig-line{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 -6px}
.ig-line svg{display:block;width:100%;min-width:680px;height:auto;font-family:inherit}
.ig-line .g{stroke:var(--line);stroke-width:1;stroke-dasharray:3 4}
.ig-line .band{fill:var(--bg-alt)}
.ig-line .area{fill:var(--mint);opacity:.55}
.ig-line .rise{fill:none;stroke:var(--mint-bright);stroke-width:9;stroke-linecap:round;stroke-linejoin:round;opacity:.75}
.ig-line .ln{fill:none;stroke:var(--ink);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
.ig-line .gap{fill:none;stroke:var(--muted);stroke-width:2;stroke-dasharray:4 5}
.ig-line .pt{fill:var(--card);stroke:var(--ink);stroke-width:2}
.ig-line .pt--hl{fill:var(--mint-bright);stroke:var(--ink);stroke-width:2.5}
.ig-line .site{stroke:var(--ink);stroke-width:1.5}
.ig-line text{font-size:13px;fill:var(--muted)}
.ig-line .t-site{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;fill:var(--ink)}
.ig-line .t-note{font-size:13px;font-weight:700;fill:var(--ink)}
.ig-line .t-rise{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;fill:var(--accent-text)}
.ig-line .t-y{font-size:12px}
.ig-legend i.ln{background:var(--ink);height:3px;vertical-align:3px;width:16px}
.ig-legend i.rise{background:var(--mint-bright)}
.ig-legend i.gap{background:none;border-top:2px dashed var(--muted);height:0;width:16px;vertical-align:3px;border-radius:0}

/* Кадры живого сайта. Тот же .dd__shots — ради крупного плана из page.js,
   но без обрезки в 16:9: интерфейс по краю обрезанным не читается, а подложка
   светлая — кадры белые, тёмная рамка вокруг них смотрелась бы паспарту */
.ig-frames{display:grid;gap:var(--gap);margin-top:0}
.ig-frames--2{grid-template-columns:1fr 1fr}
.ig-frames--21{grid-template-columns:1.55fr 1fr}
.ig-frames--4{grid-template-columns:repeat(4,1fr)}
.ig-frames--1{grid-template-columns:1fr}
.ig-frames .dd__shot{background:var(--card);box-shadow:inset 0 0 0 1px var(--line);border-radius:18px}
.ig-frames .dd__shot img{aspect-ratio:auto;object-fit:fill;height:auto}
.ig-fr{display:flex;flex-direction:column;gap:12px;min-width:0}
.ig-fr__cap{font-size:14px;line-height:1.45;color:var(--muted);margin:0;max-width:62ch}
.ig-fr__cap b{color:var(--ink)}
.ig-fr__k{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--accent-text)}
.ig-frames + .ig-frames{margin-top:calc(var(--gap) * 1.6)}

/* Сравнение «у конкурентов — у нас»: 14 точек на строку, по одной на сайт */
.ig-cmp{display:grid;gap:4px}
.ig-cmp__r{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) 120px;gap:20px;align-items:center;padding:14px 0;border-top:1px solid var(--line)}
.ig-cmp__h{border-top:0;padding-top:0;font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.ig-cmp__t{font-weight:700;font-size:16px;line-height:1.3}
.ig-cmp__t small{display:block;font-weight:500;font-size:13px;color:var(--muted);margin-top:2px}
.ig-cmp__d{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.ig-cmp__d i{width:14px;height:14px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--muted);opacity:.55}
.ig-cmp__d i.on{background:var(--ink);box-shadow:none;opacity:1}
.ig-cmp__d em{font-style:normal;font-weight:900;font-size:15px;margin-left:8px;font-variant-numeric:tabular-nums}
.ig-cmp__us{justify-self:end;background:var(--mint-bright);border-radius:999px;padding:8px 16px;font-weight:900;font-size:16px;white-space:nowrap}

/* Две полосы долей одна под другой, подпись слева */
.ig-split2{display:grid;grid-template-columns:150px 1fr;gap:12px 18px;align-items:center}
.ig-split2__k{font-size:14px;font-weight:700;line-height:1.25}
.ig-split2__k small{display:block;font-weight:500;font-size:12px;color:var(--muted)}
.ig-split2 .ig-split{height:52px;font-size:15px}
.ig-split2 .ig-split span{padding:0 10px;white-space:nowrap;overflow:hidden}

@media (max-width:900px){
 .ig-frames--2,.ig-frames--21{grid-template-columns:1fr}
 .ig-frames--4{grid-template-columns:1fr 1fr}
 .ig-cmp__r{grid-template-columns:1fr auto;gap:10px}
 .ig-cmp__d{grid-column:1/-1;grid-row:2}
 .ig-cmp__h{display:none}
 .ig-split2{grid-template-columns:1fr}
 .ig-split2 .ig-split{font-size:11px;height:44px}
 .ig-split2 .ig-split span{padding:0 6px;text-overflow:ellipsis}
}
/* подпись пункта оглавления не переносится: «17 лет» рвалось на две строки */
.ig-nav a{white-space:nowrap}
