/* Стили главной страницы Whoopy.
   Вынесены из <style> в index.html 04.08.2026, когда у сайта появилась
   английская версия: иначе те же 770 строк лежали бы копией в en/index.html,
   и любая правка вида требовала бы делать её дважды — а второй раз рано или
   поздно забывается. Внутренние страницы живут на своём page.css. */

:root{
  --u:8px;
  --bg:#FFFFFF;          /* белый и только белый — решение Саши 31.07.2026 */
  --ink:#111111;         /* заголовки и подписи */
  --ink2:#3A3A3A;        /* пояснения — тёмные, не серые: мелкого серого на сайте нет */
  --line:#E6E6E2;
  --mark:#B4231F;
  /* шкала радиусов: 8 мелкое · 16 картинка · 100 пилюля. Других не заводим.
     Шкала прозрачности: .35 фоновое · .6 тихое · .75 второстепенное · .88 почти основное.
     Шкала времени: .25s короткое · .45s движение вещи · .75s появление.
     Числа обязаны быть выводимы из шкалы — подобранное «по месту» и есть то,
     по чему опытный глаз узнаёт конструктор */
  --r:16px;
  --r-s:8px;
  /* системный моно остаётся только запасным — на случай, если PT Mono не дойдёт */
  --font-mono:'PT Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --sh:0 2px 6px rgba(17,17,17,.05), 0 14px 34px rgba(17,17,17,.08);
  --sh-up:0 3px 8px rgba(17,17,17,.06), 0 18px 38px rgba(17,17,17,.10);
  --ease:cubic-bezier(.2,.7,.2,1);

  /* Свет вместо персонажей (решение Саши 03.08.2026). До этого по разделам
     летали наши роботы — Boofy, Pixy, Lumi; на странице они читались стикерами,
     и детскость шла не от выражения лица, а от самого жанра персонажа.
     Теперь у раздела не житель, а свет: он так же метит раздел цветом,
     но ничего не изображает.

     Палитра спокойная (его же слово: «зелёные, синий, фиолетовый») и ПОСЧИТАНА:
     у всех насыщенность 48% и светлота 64%, различие только по тону. Порядок:
     фиолетовый с синим → зелёный → синий → фиолетовый, к двери свет гаснет;
     соседние разделы никогда не одного тона.

     Два правила, купленные ошибками. Первое: цвета задаются компонентами, а не
     hex, потому что градиент к `transparent` идёт через ПРОЗРАЧНЫЙ ЧЁРНЫЙ и
     даёт грязно-серый ободок. Второе: для света цвет берут насыщеннее, чем
     кажется нужным, — альфа приглушит сама. Прошлая палитра была на глаз
     (62 / 18 / 15, разброс вчетверо), и серо-синий раздел не светился вовсе:
     у серого при 30% альфы нечему светиться. Тогда же в этом комментарии
     стояла непроверенная фраза «одной насыщенности» — ложь в коде опаснее
     плохого числа, потому что в следующий раз я поверю ей сама. */
  --tone:17,17,17;
  /* Свет первого экрана. Было три холодных приглушённых тона — Саша сказал
     «выглядят как синяки», и он прав: синяк это и есть слабонасыщенный
     сине-фиолетовый. Лечится двумя вещами сразу — поднять насыщенность
     (78–82% вместо 48%) и обязательно увести один круг в ТЁПЛУЮ сторону.
     Три холодных пятна остаются синяком при любой яркости; тёплый розовый
     рядом с ними мгновенно читается как свет, а не как ушиб.
     03.08.2026, второй круг: «ещё более выраженные цвета». Тон и светлота
     каждого пятна оставлены прежними — поднята только насыщенность,
     с ~80% до 90% (тот же приём, что уже сработал в первом круге, доведённый
     дальше). Непрозрачность слоёв градиента увеличена отдельно, ниже у orb. */
  --violet:208,110,247;  /* H 283 S 90 · орхидея, главный круг */
  --blue-2:90,194,246;   /* H 200 S 90 · небесный, второй круг */
  --warm:248,130,189;    /* H 330 S 90 · тёплый розовый, третий */
  --yellow:246,218,81;   /* H 50 S 90 · жёлтый, четвёртый, добавлен 04.08.2026 */
  --made:119,207,166;    /* H 152 · зелёный — где собирают */
  --clients:119,171,207; /* H 205 · синий — снаружи, где покупатели */
  --social:187,119,207;  /* H 286 · фиолетовый — где говорят */
}
*{margin:0;padding:0;box-sizing:border-box}
/* clip, а не hidden: у секций больше нет своей обрезки (иначе свет рубился
   по границе прямой линией), и пятна выходят за правый край. hidden на body
   тут не держит — прокрутку выпускает корневой элемент. clip обрезает,
   но, в отличие от hidden, не делает из элемента контейнер прокрутки
   и потому не ломает position:sticky внутри */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip}
body{
  background:var(--bg);color:var(--ink);
  font-family:'Onest',system-ui,sans-serif;
  line-height:1.35;-webkit-font-smoothing:antialiased;overflow-x:clip;
}
/* Зерно на всю страницу — 3% поверх всего.
   Это то, чего не хватало прежним градиентам: чистый CSS-градиент опознаётся
   мгновенно, потому что в природе не бывает идеально гладкого перехода.
   Зерно рисует сам браузер фильтром SVG — не картинка, не библиотека, ~200 байт.
   baseFrequency .9 даёт мелкое зерно бумаги; крупнее читается как грязь */
body::after{
  content:'';position:fixed;inset:0;z-index:9;pointer-events:none;opacity:.032;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
a{color:inherit;text-decoration:none}
.wrap{max-width:1180px;margin:0 auto;padding:0 calc(var(--u)*4);position:relative;z-index:2}

/* ── Верх страницы: два прозрачных островка ────────────────── */
/* Была сплошная плашка во всю ширину с подложкой и линией снизу. Саша:
   «верхнюю часть сделай просто прозрачными островками» — и он прав: полоса
   отрезала верхушку страницы и наезжала на тёмные карточки прямоугольником.
   Теперь сама полоса ничего не рисует, а стеклянные только двое: имя слева
   и дверь справа. Между ними страница видна насквозь.
   Пункты меню убраны целиком (его же слово): это были якоря внутрь одной
   страницы, а не разделы сайта — человек жал и не понимал, куда попал. */
/* Была transform:translateY(-100%) — в Safari внутри .bar-in лежат островки
   с backdrop-filter, а backdrop-filter внутри трансформируемого родителя
   рендерится в WebKit мимо своего контейнера: половина островка застревала
   обрезанным полукругом, пока .bar ехала за экран. Проверила гипотезу —
   верна, дело именно в паре transform+backdrop-filter. Лечение — прятать
   не трансформом, а прозрачностью: .bar остаётся на месте, только гаснет.
   Лёгкий сдвиг на .bar-in не завела: она такой же родитель backdrop-filter
   элементов, и баг вернулся бы тем же путём */
.bar{
  position:fixed;top:0;left:0;right:0;z-index:50;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .45s var(--ease),visibility 0s linear .45s;
}
.bar.show{
  opacity:1;visibility:visible;pointer-events:auto;
  transition:opacity .45s var(--ease);
}
.bar-in{
  max-width:1180px;margin:0 auto;padding:calc(var(--u)*2) calc(var(--u)*4);
  display:flex;align-items:center;font-size:15px;
}
/* общий рецепт островка: стекло, а не заливка */
.brand,.nav .write,.nav .lang{
  -webkit-backdrop-filter:blur(16px) saturate(1.4);
  backdrop-filter:blur(16px) saturate(1.4);
  background:rgba(255,255,255,.62);
  border:1px solid rgba(17,17,17,.06);
  border-radius:100px;
}
/* имя вместо картинки робота: логотипом теперь работает само слово.
   Робот был последней мультяшной вещью на странице — ушёл следом за своими */
.brand{
  display:flex;align-items:center;font-weight:500;font-size:17px;
  padding:8px 20px;letter-spacing:-.01em;
}
.nav{margin-left:auto;display:flex;align-items:center;gap:10px}
.nav .write{
  padding:8px 20px;
  transition:background .25s var(--ease), color .25s var(--ease);
}
.nav .write:hover{background:var(--ink);color:#fff;border-color:var(--ink)}
/* Переключатель языка (04.08.2026, просьба Саши — сайт на двух языках).
   Стоит слева от двери и намеренно тише неё: язык выбирают один раз и
   мимоходом, а «Написать» — то, ради чего страница вообще есть. Моноширинный,
   как все служебные метки на сайте, и две буквы вместо флага: флаг обозначает
   страну, а не язык, и для русского это каждый раз спор */
.nav .lang{
  padding:8px 14px;font-family:'PT Mono',monospace;font-size:13px;
  color:var(--ink2);letter-spacing:.02em;
  transition:background .25s var(--ease), color .25s var(--ease);
}
.nav .lang:hover{background:var(--ink);color:#fff;border-color:var(--ink)}

/* ── Оглавление точками сбоку ─────────────────────────────── */
/* По слову Саши: «сбоку сайта сделай как точками оглавление — просто точка
   и всё». Никаких подписей: точка показывает, где ты, и даёт перепрыгнуть.
   Подпись появляется только при наведении — тому, кто целится мышью, она
   нужна, а остальным мешала бы. На узком экране столбик уходит совсем:
   там прокрутка пальцем и такая навигация лишняя. */
.dots{
  position:fixed;right:calc(var(--u)*3);top:50%;transform:translateY(-50%);
  z-index:40;display:flex;flex-direction:column;gap:calc(var(--u)*2);
  opacity:0;transition:opacity .45s var(--ease);pointer-events:none;
}
.dots.show{opacity:1;pointer-events:auto}
/* Точке нужна та же защита контраста, что и плашкам сверху, — и по той же
   причине: она fixed и плывёт поверх всей прокрутки, в том числе поверх
   цветных пятен разделов, где нейтральный серый теряется быстрее всего.
   У плашек это стекло с блюром, здесь дешевле — белый ореол кольцом:
   на любом фоне под точкой оказывается светлая подложка её же размера */
.dots a{
  position:relative;width:5px;height:5px;border-radius:50%;
  background:rgba(17,17,17,.30);
  box-shadow:0 0 0 3px rgba(255,255,255,.55);
  transition:background .25s var(--ease), transform .25s var(--ease);
}
.dots a:hover{background:rgba(17,17,17,.45);transform:scale(1.3)}
.dots a.on{background:var(--ink)}
/* подпись выезжает влево от точки только под курсором */
.dots a::after{
  content:attr(data-t);position:absolute;right:16px;top:50%;
  transform:translateY(-50%);white-space:nowrap;
  font-size:13px;color:var(--ink2);
  opacity:0;transition:opacity .25s var(--ease);pointer-events:none;
}
.dots a:hover::after{opacity:1}

/* ── Первый экран: только вывеска ─────────────────────────── */
.hero{
  position:relative;min-height:100svh;isolation:isolate;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:calc(var(--u)*10) calc(var(--u)*4);
}
/* Свет первого экрана: три круга, и они дышат — по слову Саши, «чтобы данные
   круги то появлялись, то исчезали». Здесь свет нужнее всего: страница
   открывается белым листом с одной строкой, и без него это читалось не как
   тишина, а как «ещё не загрузилось».
   Почему три, а не один: одиночный круг остаётся узнаваемой фигурой из
   редактора, сколько его ни размывай. Три разного размера, под разными углами
   и с РАЗНЫМИ периодами дыхания (17 / 23 / 29 с — простые числа, чтобы циклы
   не сходились и рисунок никогда не повторялся) дают то, чего глаз не может
   предсказать. Дышит только прозрачность и лёгкий сдвиг: размер не трогаем,
   иначе получается пульс, а не свет. */
.orbs{position:absolute;inset:0;z-index:-1;pointer-events:none}
.orb{position:absolute;border-radius:50%;will-change:opacity,transform}
.orb.o1{
  width:clamp(560px,64vw,1080px);height:clamp(300px,32vw,540px);
  right:-14%;top:-6%;
  background:radial-gradient(50% 50% at 50% 50%,
              rgba(var(--violet),.52) 0%,rgba(var(--violet),.38) 24%,
              rgba(var(--violet),.20) 46%,rgba(var(--violet),.07) 64%,
              rgba(var(--violet),0) 78%);
  animation:breathe-a 17s var(--ease) infinite;
}
.orb.o2{
  width:clamp(380px,44vw,760px);height:clamp(240px,26vw,440px);
  left:-10%;bottom:6%;
  /* было .49/.33/.16 — на белом фоне голубой и розовый гаснут заметно
     быстрее фиолетового при ОДНОЙ и той же альфе (у них выше светлота
     на глаз, контраст с белым слабее). Подняты сильнее, чем фиолетовый,
     чтобы читаться наравне, а не по одинаковым цифрам в коде */
  background:radial-gradient(50% 50% at 50% 50%,
              rgba(var(--blue-2),.66) 0%,rgba(var(--blue-2),.48) 24%,
              rgba(var(--blue-2),.27) 46%,rgba(var(--blue-2),.09) 64%,
              rgba(var(--blue-2),0) 78%);
  animation:breathe-b 23s var(--ease) infinite;
}
.orb.o3{
  width:clamp(260px,30vw,520px);height:clamp(180px,20vw,340px);
  right:14%;bottom:18%;
  /* было .46/.23 — то же лечение, что у голубого, плюс своя причина: пятно
     физически меньше двух других (клякса под тёплый акцент, а не заливка),
     поэтому даже при равной альфе с violet/blue-2 занимает меньше площади
     экрана и теряется первым */
  background:radial-gradient(50% 50% at 50% 50%,
              rgba(var(--warm),.68) 0%,rgba(var(--warm),.48) 26%,
              rgba(var(--warm),.26) 48%,rgba(var(--warm),0) 76%);
  animation:breathe-c 29s var(--ease) infinite;
}
/* Четвёртый круг, 04.08.2026 — по слову Саши «добавь ещё жёлтый». Встал в
   пустой верхний левый угол (три прежних занимали верх-право, низ-лево,
   низ-право): так четыре пятна не складываются в симметричную рамку по
   углам, а лежат по диагонали разной высоты. Держится подальше от центра,
   где строка заголовка, — контраст текста после добавления проверен.
   Период 37s — не делится ни на один из 17/23/29, четыре цикла расходятся
   ещё дольше, чем три. Жёлтый на белом гаснет быстрее всех тонов (ниже
   контраст со светлым фоном при равной насыщенности), поэтому у его
   градиента альфа выше, чем у любого из трёх соседей: .74 на пике против
   .66 у самого яркого из старых (blue-2). Нижняя точка дыхания — не ниже
   .40, тем же приёмом, что уже лечил warm: иначе пятно не тускнеет, а
   пропадает с экрана между вдохами */
.orb.o4{
  width:clamp(320px,36vw,620px);height:clamp(200px,22vw,380px);
  left:-10%;top:34%;
  background:radial-gradient(50% 50% at 50% 50%,
              rgba(var(--yellow),.74) 0%,rgba(var(--yellow),.54) 24%,
              rgba(var(--yellow),.30) 46%,rgba(var(--yellow),.12) 64%,
              rgba(var(--yellow),0) 78%);
  animation:breathe-d 37s var(--ease) infinite;
}
@keyframes breathe-a{
  0%,100%{opacity:.30;transform:rotate(-17deg) translate(0,0)}
  50%     {opacity:1;  transform:rotate(-13deg) translate(-26px,18px)}
}
@keyframes breathe-b{
  0%,100%{opacity:1;   transform:rotate(9deg) translate(0,0)}
  50%     {opacity:.26;transform:rotate(6deg) translate(22px,-16px)}
}
/* нижняя точка дыхания была .14 — на трети цикла тёплое пятно практически
   пропадало с экрана, а не только тускнело. Поднята до .40: пятно всё ещё
   дышит, но не исчезает совсem между вдохами */
@keyframes breathe-c{
  0%,100%{opacity:.60; transform:rotate(4deg) translate(0,0)}
  38%     {opacity:.40;transform:rotate(-2deg) translate(-14px,-10px)}
  72%     {opacity:.95;transform:rotate(7deg) translate(10px,12px)}
}
@keyframes breathe-d{
  0%,100%{opacity:.42; transform:rotate(6deg) translate(0,0)}
  50%     {opacity:.95;transform:rotate(11deg) translate(18px,-14px)}
}
/* было text-wrap:balance — при печати .swap менялась длина последнего слова,
   balance на каждую букву пересчитывал разбивку заново, и в Safari строка
   скакала с двух рядов на три (кадр 02). Разбивка теперь задана рукой —
   но первый заход (br перед самим .swap) промахнулся мимо смысла: «Этой
   компанией управляет» тянулось почти во всю ширину, а короткое слово
   болталось под ним отдельной строкой — вес фразы уехал в служебные слова.
   Возврат 04.08.2026: перенос стоит после «компанией», а не перед .swap.
   Вторая строка — «управляет» и меняющееся слово вместе, одним нерасторжимым
   куском (.lockline, white-space:nowrap ниже): что бы ни печаталось внутри
   .swap, эта строка не разобьётся сама и не потянет за собой первую —
   значит и во время печати, и между «второй мозг» и «ИИ» строк ровно две */
h1{
  font-size:clamp(38px,6.6vw,92px);font-weight:500;line-height:1.03;
  letter-spacing:-.035em;
  margin-bottom:calc(var(--u)*5);
}
/* ширина выведена из самой длинной фазы — «управляет второй мозг» — а не
   подобрана: меньше она обрежет строку клипом по html{overflow-x:clip},
   больше — вернёт разбалансированный вид, от которого ушли. Проверена на
   2000 / 1440 / 390px в обеих фазах */
.lockline{white-space:nowrap;max-width:100%}
.lead{font-size:20px;line-height:1.5;max-width:620px;margin:0 auto;color:var(--ink2)}
.scroll-hint{
  position:absolute;bottom:calc(var(--u)*5);left:50%;transform:translateX(-50%);
  width:1px;height:44px;background:var(--line);overflow:hidden;
}
.scroll-hint::after{
  content:'';position:absolute;inset:0;background:var(--ink);
  animation:flow 2.6s var(--ease) infinite;
}
@keyframes flow{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}

/* ── Раздел ───────────────────────────────────────────────── */
/* Фон разделов больше не заливается тоном. Раньше кремовый, серо-голубой и
   розоватый шли тремя полосами подряд — три переключения тона за один проход
   для сделки на 300 тысяч. Теперь фон один, белый по всей странице, а раздел
   метит только свет и пунктирная черта над ним */
/* overflow у секции больше нет: он рубил свет ровно по её границе, и на стыке
   разделов была видна резкая прямая линия обрыва — Саша поймал это первым
   («вот такого обрезания не должно быть»). Свет должен перетекать через
   границу, иначе он не свет, а прямоугольная заливка.
   От горизонтальной прокрутки страницу держит overflow-x:hidden на body */
/* было 12u — раздел «Что сделали» при прокрутке не помещался в экран целиком
   (заголовок с подзаголовком уезжали за верх, тёмная карточка со схемой не
   влезала). 10u экономит 32px без потери воздуха между разделами */
.sec{
  position:relative;padding:calc(var(--u)*10) 0;
}
/* Линий между разделами нет — убраны по слову Саши 03.08.2026 («давай без
   такой линии»). Пробовала пунктир в 10% силы: даже такой слабый, он режет
   страницу на полосы, а свет как раз должен перетекать из раздела в раздел.
   Границу теперь отмечает только смена тона света — и этого хватает */
/* Свет раздела. Это не круг с прозрачностью, каким было прежнее свечение
   (оно стояло на .07 и попросту не читалось, работая фоном для робота).
   Собран из трёх вещей, и каждая обязательна:
     · эллипс, а не круг — растянут по горизонтали и повёрнут, поэтому
       у пятна нет узнаваемой «круглой» границы конструктора;
     · многоступенчатое затухание вместо двух точек — оно и убирает кольца
       на мягком переходе, которые вылезают у дешёвых матриц;
     · зерно поверх всей страницы (см. body::after) — без него любое большое
       пятно читается как заливка из редактора, с ним как свет на бумаге.

   Мягкости добивалась через filter:blur(38px), и вид был тот же — но браузер
   на этом душится: пятно шириной под 1200 px он перерисовывает на каждый кадр
   прокрутки. У меня на съёмке кадра renderer просто перестал отвечать.
   Клиент открывает сайт не на моей машине, поэтому blur убран совсем:
   плавность собрана самим градиентом и стоит ноль. */
.sec::after{
  content:'';position:absolute;pointer-events:none;z-index:0;
  width:clamp(620px,72vw,1180px);height:clamp(320px,34vw,600px);border-radius:50%;
  right:var(--glow-x,-14%);top:var(--glow-y,4%);
  background:radial-gradient(50% 50% at 50% 50%,
              rgba(var(--tone),.34) 0%,rgba(var(--tone),.26) 22%,
              rgba(var(--tone),.15) 44%,rgba(var(--tone),.06) 62%,
              rgba(var(--tone),0) 78%);
  transform:rotate(var(--glow-r,-14deg));
}
/* пятно каждого раздела стоит в своём месте и под своим углом: одинаковое
   положение читалось бы как повторяющаяся плашка, а не как свет */
.sec.made{--tone:var(--made);--shot:#181310;--glow-y:-4%;--glow-r:-16deg}
.sec.clients{--tone:var(--clients);--shot:#12171A;--glow-y:18%;--glow-r:9deg}
/* у этого раздела воздуха меньше прочих: содержимое ужато вдвое, а обёртка
   оставалась прежней — раздел по-прежнему занимал почти экран за счёт одних
   отступов. Полегчал контент — должна полегчать и рамка */
.sec.social{--tone:var(--social);--shot:#171215;--glow-y:-2%;--glow-r:-7deg;
            padding:calc(var(--u)*9) 0}
/* Свет входит слева через раздел: строго по очереди, справа-слева-справа-слева.
   Если пятна встают с одной стороны подряд, прокрутка читается как одна и та же
   картинка, повторённая дважды. Сторона привязана к ПОЗИЦИИ в странице, а не к
   разделу, — поэтому при перестановке разделов 03.08.2026 (соцсети и клиенты
   поменялись местами) стороны переехали вслед за ними. */
.sec.social::after{right:auto;left:-22%}
/* Свет вернулся сюда 03.08.2026, когда раздел из текстового стал витринным.
   Логика прежняя — «к двери страница затихает», — но затихать должен подвал,
   а не раздел с двумя карточками продукта: без света он единственный
   выпадал из системы, где каждый раздел окрашен своим тоном.
   Взят фиолетовый первого экрана: страница им открывается и им же
   закрывается, а между ними зелёный, синий и сиреневый. Пятно слабее
   остальных (альфа .26 против .34) и уведено влево-вниз — к двери. */
/* верхний отступ ужат с 16u — на 900px высоты «Что делаем» вместе с двумя
   карточками продукта не помещался: заголовок и вывеска съедали лишнее */
.sec.about{--tone:var(--violet);--shot:#141017;--glow-y:24%;--glow-r:11deg;
           padding:calc(var(--u)*11) 0 calc(var(--u)*10)}
.sec.about::after{right:auto;left:-20%;opacity:.76}

.head{margin-bottom:calc(var(--u)*5);max-width:760px;position:relative}
h2{font-size:clamp(26px,3vw,40px);font-weight:500;letter-spacing:-.025em;line-height:1.12}
/* Номера разделов (01, 02, …) стояли здесь до 03.08.2026 — приём с ode.com.
   Сняты по слову Саши: «номер тут не нужен». Он прав по существу: нумерация
   работает у ode, потому что там страница и правда читается как оглавление
   каталога. У нас пять разделов, каждый со своим светом и заголовком —
   порядок и так очевиден, а цифра добавляла страницу-документ туда,
   где должна быть витрина. */
.head .sub{display:block;margin-top:calc(var(--u)*1.5);font-size:18px;color:var(--ink2);line-height:1.45}

/* Здесь жили реплики роботов («Boofy — это я собирал…») и сами летающие
   фигуры: шесть картинок по разделам и трое у двери в подвале.
   Убраны 03.08.2026 целиком. Реплика от первого лица оказалась сильнее
   всех остальных сигналов детскости — сильнее цвета и размера вместе:
   на странице, где решают про 300 тысяч, за читателя вдруг начинал
   говорить мультяшный персонаж. Роботы остаются персонажами компании
   и живут в соцсетях; на продающей странице их больше нет.
   Картинки лежат в assets/ — они ещё понадобятся, но не здесь */

/* ── Вещь: картинка, а под ней отдельным блоком подпись ───── */
/* карточки-контейнера нет: на белом живут сама картинка и текст под ней */
.thing{display:block}
.shot{
  position:relative;border-radius:var(--r);overflow:hidden;
  background:var(--shot,#131313);
  transition:transform .45s var(--ease), box-shadow .45s var(--ease);
  box-shadow:var(--sh);
}
a.thing:hover .shot{transform:translateY(-6px);box-shadow:var(--sh-up)}
/* 4/3 держалось, пока диаграмма стояла в колонке рядом с двумя малыми: так
   их высоты сходились. Теперь она во всю ширину, и 4/3 дало бы 825 px высоты —
   схема утонула бы в пустой миллиметровке */
.shot.big{aspect-ratio:4/3}
/* было 16/9 — на первом экране прокрутки схема вместе с заголовком раздела
   не влезала в высоту окна. Содержимое схемы (ядро, вилка, 4 ячейки, вынос)
   свободно живёт и при более низкой карточке */
.row .shot.big{aspect-ratio:2/1}
.shot.sm{aspect-ratio:16/9}
.shot.light{background:#F0F0EC}
/* «место ждёт» — тот же пунктир, что у каркасов отделов в схеме и у
   заглушки в «Кому сделали»: толщина 1px, альфа .32. Заменяет подпись
   словами там, где вещь честно не готова */
.thing.pending .shot{border:1px dashed rgba(255,255,255,.32)}
/* внутри подписи было четыре разных зазора одной роли — 12, 5, 10, 11 px,
   ни одного повтора: подгонка по месту, а не шкала. Сведено к двум шагам */
.cap{margin-top:12px}          /* подпись отдельным блоком и очень близко */
.cap h3{font-size:20px;font-weight:500;line-height:1.25;letter-spacing:-.015em}
.thing.small .cap h3{font-size:17px}
/* .cap .st снят 04.08.2026 вместе с последним местом, где он стоял в
   разметке (карточки держали лишний, четвёртый ряд текста) — правило
   осталось только правилом, живого .st на странице больше нет */
.cap .desc{margin-top:var(--u);font-size:16px;color:var(--ink2);line-height:1.45;max-width:52ch}
/* прямой вход внутрь вещи: покупателю нужен не пересказ, а сама переписка.
   Стрелка отъезжает при наведении — единственное место, где карточка зовёт внутрь */
.cap .more{margin-top:calc(var(--u)*1.5);font-size:16px;color:var(--ink);display:inline-flex;align-items:center;gap:7px}
.cap .more::after{content:'→';transition:transform .25s var(--ease)}
a.thing:hover .cap .more::after{transform:translateX(4px)}

/* шаг 28px — как на внутренних страницах (page.css), чтобы клетка была
   одним и тем же чертежом на всём сайте, а не двумя похожими */
.grid-bg{
  position:absolute;inset:0;
  background-image:
    linear-gradient(rgba(255,255,255,.06) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 1px);
  background-size:28px 28px;
}
.shot.light .grid-bg{
  background-image:
    linear-gradient(rgba(17,17,17,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(17,17,17,.05) 1px,transparent 1px);
}

/* Раскладка была «главное и два рядом»: диаграмма слева, робот и Minecraft
   колонкой справа. Целевой покупатель и маркетолог независимо назвали это
   потерей: раздел должен доказывать «мы построили работающее», а половину
   ширины в нём занимали два «показывать пока нечего». Покупатель дословно:
   «подумал, ребята распыляются, не сфокусированы».
   Теперь доказательство идёт первым и во всю ширину, а разработки в работе —
   ниже, отдельным рядом и вдвое мельче. Со страницы они не уходят: это
   единственное место, где видно, что мы вообще изобретаем, — но они больше
   не спорят с главным. */
.row{display:block}
.row .side{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:calc(var(--u)*3);max-width:62%;margin-top:calc(var(--u)*7);
}

/* схема второго мозга — чертёж вместо фотографии, которой не существует */
.dia{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
     padding:calc(var(--u)*4);gap:0}
.d-core{
  background:#fff;color:#111;border-radius:var(--r-s);
  padding:calc(var(--u)*1.5) calc(var(--u)*2);font-size:14px;font-weight:500;
}
.d-core span{display:block;font-size:14px;color:#3A3A3A;font-weight:400;margin-top:4px;line-height:1.35}
/* вилка от ядра к отделам — чертёж, а не набор плашек */
.d-fork{height:24px;position:relative;flex:none}
.d-fork::before{content:'';position:absolute;left:50%;top:0;width:1px;height:12px;background:rgba(255,255,255,.3)}
.d-fork::after{content:'';position:absolute;left:12.5%;right:12.5%;top:12px;height:1px;background:rgba(255,255,255,.3)}
.d-row{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--u)}
.d-c{
  position:relative;
  border:1px solid rgba(255,255,255,.18);border-radius:var(--r-s);
  padding:calc(var(--u)*1.5);font-size:14px;color:rgba(255,255,255,.74);
  line-height:1.32;min-height:112px;display:flex;flex-direction:column;
}
.d-c::before{content:'';position:absolute;left:50%;top:-12px;width:1px;height:12px;background:rgba(255,255,255,.3)}
.d-c u{display:block;text-decoration:none;font-size:13px;opacity:.75;margin-top:5px;line-height:1.35}
/* Правила .d-out / .d-ext (ветка «наружу вынесен один: Пудра») удалены
   05.08.2026 вместе с самим блоком — разметки, которая их звала, больше нет. */
.d-c.on{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.3);color:#fff}
/* пунктир «место ждёт» — один язык на всю страницу: толщина 1px, альфа .32,
   тот же приём, что у заглушки в разделе «Кому сделали» */
.d-c.off{border-style:dashed;border-color:rgba(255,255,255,.32)}
.d-c i{font-style:normal;font-size:14px;opacity:.88;margin-top:auto;display:flex;align-items:center;gap:6px}
/* число файлов памяти — настоящее, посчитано по папкам. Это и есть ответ на
   вопрос «чем ваш специалист отличается от чата с промптом»: у чата памяти нет.
   У каркасов честный ноль — цифра говорит внятнее слова «каркас» */
.mem{
  display:block;margin-top:7px;font-style:normal;
  font-family:var(--font-mono);
  /* трекинг обнулён: −0.02em подгонялся под системный моноширинный.
     У PT Mono буквы и так расставлены широко — отрицательный трекинг их сжимал */
  font-size:12px;letter-spacing:0;color:rgba(255,255,255,.6);
}
.mem.dark{color:#6A6A6A;margin-top:6px}
.d-c.on i::before{
  content:'';width:5px;height:5px;border-radius:50%;background:#fff;flex:none;
  animation:pulse 3.2s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:1}}

/* чертёжные картинки: главное — состояние словом, чертёж в фоне */
.blueprint{position:absolute;inset:0;display:flex;align-items:flex-start;justify-content:center;padding-top:5%}
.blueprint svg{width:66%;height:auto;stroke:rgba(255,255,255,.2);fill:none;stroke-width:1.2;
               stroke-linecap:round;stroke-linejoin:round}
.state-big{
  position:absolute;left:calc(var(--u)*3);bottom:calc(var(--u)*3);right:calc(var(--u)*3);
  color:#fff;font-size:clamp(21px,2.3vw,28px);font-weight:500;
  letter-spacing:-.02em;line-height:1.12;
}
.state-big em{
  display:block;font-style:normal;font-size:15px;font-weight:400;
  color:rgba(255,255,255,.8);margin-top:7px;letter-spacing:0;
}

/* диалог Пудры */
.chat{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
      gap:var(--u);padding:calc(var(--u)*3) calc(var(--u)*3.5)}
.msg{border-radius:var(--r-s);padding:calc(var(--u)*1.5) calc(var(--u)*2);font-size:14px;
     max-width:82%;line-height:1.35}
.msg.them{background:#fff;color:var(--ink);align-self:flex-start;border:1px solid var(--line)}
.msg.us{background:#111;color:#fff;align-self:flex-end}
/* строка ввода с мигающим курсором: одна живая чёрточка делает статичный
   макет разговором, который идёт прямо сейчас. Приём подсмотрен у Raycast
   (курсор в мокапе окна), у нас он поставлен туда, где идёт настоящая работа */
.typeline{
  position:absolute;left:calc(var(--u)*3);right:calc(var(--u)*3);bottom:calc(var(--u)*2.5);
  display:flex;align-items:center;border-top:1px solid rgba(17,17,17,.12);padding-top:11px;
}
.cursor{width:0;height:16px;border:1px solid #111;border-radius:1px;animation:blink 1.1s step-end infinite}
@keyframes blink{50%{opacity:0}}

/* ── Кейсы лентой вбок ────────────────────────────────────── */
/* лента гибкая, а не сеткой равных колонок: сделанное занимает главную площадь,
   а оставленное место — узкую полосу сбоку. Поровну они делились ровно до тех пор,
   пока пустых мест было два; с одним такая делёжка отдавала половину экрана пустоте */
.rail{
  display:flex;
  gap:calc(var(--u)*3);overflow-x:auto;scroll-snap-type:x mandatory;
  margin:0 calc(var(--u)*-4);padding:calc(var(--u)*1) calc(var(--u)*4) calc(var(--u)*3);
  scrollbar-width:none;align-items:start;
}
.rail::-webkit-scrollbar{display:none}
.rail > *{scroll-snap-align:start;flex:1 1 340px;min-width:300px}
/* в ленте карточка шире, поэтому и ниже: 4/3 при ширине 757 давало 568 px,
   и разговор тонул в пустой миллиметровке */
.rail .shot.big{aspect-ratio:16/10}
/* Кегль и поля в ленте пересчитаны 04.08.2026 под три карточки в ряд.
   Были 15px/76%/padding*3 — от времён, когда в ленте стояла одна широкая
   карточка на 685 px. При ширине 380 px реплики стали переноситься по три
   строки, и разговор не влезал в рамку: замер показал 261 px содержимого
   в коробке 223. Теперь 14px, поля шире по горизонтали, реплика длиннее
   в строку — 3 реплики укладываются с запасом */
.rail .chat{padding:calc(var(--u)*2) calc(var(--u)*2.5);gap:6px}
.rail .msg{font-size:14px;max-width:88%}

/* Здесь жили стили заглушки (.thing.blank, .ghost) — пустой карточки «Здесь
   встанет второй» с посчитанной высотой .71. Сняты 04.08.2026 вместе с самой
   заглушкой: работ в разделе стало три, оставленное место заполнилось. Код
   ушёл следом за разметкой, а не остался ждать — мёртвые правила потом
   принимаются за действующие. Расчёт высоты, если заглушка когда-нибудь
   вернётся, лежит в «Кадры 0.11/index-до-снятия-робота-и-minecraft.html». */

/* График смен — тот же чертёж, что и остальные схемы: строка на позицию,
   столбец на день, закрытая смена заливкой. Пустая рамка — смена, на которую
   человек не выходит; одна ячейка светлее (.fix) — та, что специалист закрыл
   последней. Слов на схеме нет: она читается как график, а не как объяснение */
.shift{
  position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
  gap:7px;padding:calc(var(--u)*3) calc(var(--u)*3.5);
}
.sh-row{display:grid;grid-template-columns:52px repeat(7,1fr);gap:6px;align-items:center}
.sh-row b{
  font-family:'PT Mono',monospace;font-weight:400;font-size:12px;
  color:rgba(255,255,255,.55);
}
/* Разница между закрытой и пустой сменой сначала была .13 против рамки — на
   тёмном фоне глаз их не различал, и график читался как ровная сетка вместо
   расписания. Пустая ячейка теперь пунктирная и почти без заливки (тот же
   язык незанятого места, что у .step.later и каркасов отделов), закрытая —
   вдвое светлее прежнего */
.sh-row i{
  display:block;height:22px;border-radius:5px;
  border:1px dashed rgba(255,255,255,.22);
}
.sh-row i.on{background:rgba(255,255,255,.26);border:1px solid rgba(255,255,255,.34)}
.sh-row i.fix{background:rgba(255,255,255,.62);border:1px solid rgba(255,255,255,.72)}
.sh-head span{
  font-family:'PT Mono',monospace;font-size:11px;text-align:center;
  color:rgba(255,255,255,.4);
}

/* ── Соцсети ──────────────────────────────────────────────── */
/* Раздел ужат: был экран в полный рост с четырьмя высокими карточками и
   списками планов на будущее — и стоял прямо перед дверью. Маркетолог назвал
   его единственной мёртвой зоной страницы: весь текст в будущем времени, ни
   одного довода написать, а разгон к двери в этом месте должен нарастать.
   Убирать раздел целиком не стала — человеку правда полезно знать, где нас
   читать. Вместо этого у каждого канала осталось по одной строке вместо трёх,
   и карточки из 4/5 стали квадратными: экран ужался почти вдвое */
.four{display:grid;grid-template-columns:repeat(4,1fr);gap:calc(var(--u)*3)}
.four .shot{aspect-ratio:1}
/* превью канала: пока не фото, а макет — снимки встанут сюда, когда каналы оживут */
.chan{position:absolute;inset:0;display:flex;flex-direction:column;padding:calc(var(--u)*2.5);gap:10px;color:#fff}
.chan-top{display:flex;align-items:center;gap:10px}
.chan-ava{width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.14);
          display:flex;align-items:center;justify-content:center;flex:none;color:#fff}
.chan-ava svg{width:19px;height:19px}
.chan-name{font-size:15px;font-weight:500}
/* у каждой площадки макет по её собственному устройству: четыре одинаковые
   плашки читались как одна заглушка, размноженная четыре раза */
/* список прибит к верху, а не отцентрован по свободной высоте: у карточек
   разное число пунктов, и при центрировании первая чёрточка Telegram начиналась
   на ~35 px выше, чем у Max — соседи одного ряда стояли вразнобой */
.chan-body{flex:1;display:flex;flex-direction:column;justify-content:flex-start;
           padding-top:var(--u);min-height:0}
/* вместо имитации чужой ленты — план работы канала.
   Судьи независимо назвали макеты единственным местом, где сайт «повеял
   агентством»: нарисованная лента изображает присутствие, которого нет */
.plan{list-style:none;display:flex;flex-direction:column;gap:9px}
.plan li{
  position:relative;padding-left:16px;font-size:14px;line-height:1.4;
  color:rgba(255,255,255,.78);
}
.plan li::before{
  content:'';position:absolute;left:0;top:8px;width:5px;height:1px;
  background:currentColor;opacity:.6;
}
.chan-state{margin-top:auto;font-size:17px;font-weight:500;line-height:1.2;padding-top:calc(var(--u)*2)}
.chan-state em{display:block;font-style:normal;font-size:15px;font-weight:400;
               color:rgba(255,255,255,.8);margin-top:5px}
/* Instagram — единственная площадка с двумя профилями сразу. Второй ряд
   получает ту же пунктирную рамку и ту же альфа .32, что у карточек-заглушек
   (.thing.pending, d-c.off) — один язык «место ждёт» на всю страницу,
   а не текст вроде «профиля пока нет» */
.chan-state.ig{display:flex;flex-direction:column;gap:calc(var(--u)*1.5)}
.ig-row b{display:block;font-weight:500}
.ig-row em{display:block;font-style:normal;font-size:15px;font-weight:400;
           color:rgba(255,255,255,.8);margin-top:5px}
.ig-row.ig-pending{
  padding-top:calc(var(--u)*1.5);border-top:1px dashed rgba(255,255,255,.32);
  opacity:.6;
}

/* ── О компании ───────────────────────────────────────────── */
.about-in{max-width:820px;margin:0 auto;text-align:center}
/* заголовок раздела здесь работает меткой, а вывеской — строка под ним:
   та же роль, что у номера «04», только словом */
.about-in h2{font-size:20px;font-weight:400;color:var(--ink2);letter-spacing:0}
.signboard{
  margin:calc(var(--u)*2) auto calc(var(--u)*5);
  font-size:clamp(30px,4.2vw,56px);font-weight:500;
  letter-spacing:-.03em;line-height:1.08;text-wrap:balance;
}
.about-in .lead{font-size:19px;max-width:660px}
.about-in .lead + .lead{margin-top:calc(var(--u)*2)}
/* Две карточки продукта. Ряд из двух, а не из трёх-четырёх, — потому что
   продукта ровно два; сетка на четыре с двумя пустыми местами выглядела бы
   недоделанной, а вымышленный третий продукт мы не рисуем.
   Подписи под ними выровнены по левому краю, хотя блок текста над ними —
   по центру: карточка читается как вещь с этикеткой, а центрированный
   абзац в три строки под картинкой распадается на лесенку. */
.two{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:calc(var(--u)*4);margin-top:calc(var(--u)*6);text-align:left;
}
/* было 4/3 — на 900px высоты раздел «Что делаем» с вывеской и текстом над
   карточками уже не помещался целиком */
.two .shot{aspect-ratio:16/10}

/* ── Подвал ───────────────────────────────────────────────── */
/* В подвале света нет, и это решение, а не забывчивость. Пробовала поставить
   нейтральное пятно под дверью — серое свечение на белом читается не как свет,
   а как грязь на экране: у света обязан быть цвет, иначе это тень.
   Цветное же пятно у самой двери спорило с ней за внимание.
   Страница кончается тишиной — так и надо. */
footer{
  position:relative;overflow:hidden;text-align:center;
  /* нижний отступ ужат с 12 до 8 единиц: он держал подпись авторства,
     а после её снятия страница кончалась полосой пустоты в 100 px */
  padding:calc(var(--u)*14) 0 calc(var(--u)*8);
}
.door{
  display:inline-block;border:1px solid var(--ink);border-radius:100px;
  padding:calc(var(--u)*2) calc(var(--u)*6);font-size:20px;
  transition:background .25s var(--ease), color .25s var(--ease);
}
.door:hover{background:var(--ink);color:#fff}

/* ── Появление вылетом ────────────────────────────────────── */
html.js .rev{opacity:0;transform:translateY(34px);
     transition:opacity .75s var(--ease), transform .75s var(--ease);
     transition-delay:var(--d,0s)}
/* ⚠️ Префикс html.js обязателен: скрытие выше стоит на html.js .rev, и без
   такого же префикса показ весит меньше — .in навешивается, но не работает. */
html.js .rev.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html.js .rev{opacity:1;transform:none;transition:none}
  .scroll-hint::after,.d-c.on i::before,.cursor,.orb{animation:none}
  html{scroll-behavior:auto}
}

/* ── Адаптив ──────────────────────────────────────────────── */
@media (max-width:1000px){
  .four{grid-template-columns:repeat(2,1fr)}
  /* свет на узком экране слабее: пятно занимает бо́льшую долю экрана,
     и в прежней силе начинало забивать текст */
  .sec::after{opacity:.72}
  .orb{opacity:.7}
}
@media (max-width:900px){
  .sec{padding:calc(var(--u)*12) 0}
  .row .side{max-width:none}
}
@media (max-width:640px){
  /* .lockline держит «управляет + меняющееся слово» одной нерасторжимой
     строкой (nowrap) — выше 640px это ничем не грозит, там свободной ширины
     с запасом. На узком телефоне тот же фиксированный низ клампа (38px)
     уже не даёт строке ужаться, и «управляет второй мозг» перестаёт влезать —
     а html{overflow-x:clip} режет лишнее молча, метрика «прокрутка вбок» из
     site-check в этом случае врёт нулём (я поймала это iframe-тестом на
     320px: scrollWidth = innerWidth, а строка при этом обрезана). Лечение —
     собственный, более низкий пол у клампа для этой ширины: цифры выведены
     из вписывания самой длинной фазы («управляет второй мозг») в 320px
     с запасом ~10px, а не подобраны на глаз */
  h1{font-size:clamp(18px,7.3vw,38px)}
  .wrap{padding:0 calc(var(--u)*3)}
  .sec{padding:calc(var(--u)*10) 0}
  .head{margin-bottom:calc(var(--u)*5)}
  .rail > *{flex:0 0 86%}
  .rail > .thing.blank{flex:0 0 62%}
  .dots{display:none}
  .four{grid-template-columns:1fr;gap:calc(var(--u)*4)}
  .four .shot{aspect-ratio:16/10}
  .two{grid-template-columns:1fr;gap:calc(var(--u)*5)}
  .two .shot{aspect-ratio:16/10}
  /* схема складывается в два ряда — вчетвером им тесно.
     усики от вилки при этом убираем: во втором ряду они указывали в пустоту */
  .dia{padding:calc(var(--u)*3);gap:6px}
  .d-row{grid-template-columns:repeat(2,1fr);gap:6px}
  .d-c{min-height:58px}
  .d-c::before{display:none}
  .d-fork{height:16px}
  .d-fork::after{left:25%;right:25%}
}

/* ── Заголовок, который сам себя перепечатывает ────────────── */
/* «второй мозг» стирается по буквам и на его месте печатается «ИИ»,
   потом обратно. Никакого оформления: то же начертание, тот же цвет —
   человек видит не эффект, а как одно слово оказывается другим.
   Ширину держим невидимой распоркой, иначе строка прыгает при каждой букве */
/* строка живёт по ширине текущего слова и центрируется вместе со всей строкой.
   Пробовала держать ширину невидимой распоркой по длинному слову — на коротком
   «ИИ» между «управляет» и «ИИ» зияла дыра в полстроки. Пусть лучше строка
   сжимается за словом: это и есть ощущение печати */
.swap{display:inline;white-space:nowrap}
.swap .hold{display:none}
.caret{
  display:inline-block;width:.055em;height:.78em;background:currentColor;
  vertical-align:-.07em;margin-left:.06em;animation:blink 1.06s step-end infinite;
}
@media (prefers-reduced-motion:reduce){.caret{animation:none;opacity:0}}

/* ── Куда ходили ─────────────────────────────────────────────
   Раздел заведён 04.09.2026. Тон взят от «Где мы» — оба про то,
   как компания показывается наружу; свой цвет заводить не стала,
   палитра и так на пределе. Карточка одна и лежит в две колонки:
   фото вертикальное (4:5, как в ленте), подпись рядом. Лентой
   .rail не делаю — при одной карточке flex растянул бы фото на
   всю ширину, и вертикальный кадр вырос бы на два экрана. */
.sec.went{--tone:var(--social);--shot:#121417;--glow-y:12%;--glow-r:-9deg}
.trip{
  display:grid;
  grid-template-columns:minmax(0,300px) minmax(0,1fr);
  gap:calc(var(--u)*5);
  align-items:center;
}
.trip-shot{aspect-ratio:4/5}
.trip-shot img{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;display:block;
}
.trip-cap{margin-top:0;max-width:52ch}
/* дата отдельной строкой под названием: в подписи это единственное
   место, где число обязано читаться сразу — раздел про «когда» */
.cap .when{margin-top:calc(var(--u)*.75);font-size:15px;color:var(--ink2)}

@media (max-width:900px){
  .trip{grid-template-columns:1fr;gap:calc(var(--u)*3)}
  .trip-shot{max-width:300px}
}

/* Кадр на телефоне ужат по слову Саши 04.09: раздел занимал почти весь
   экран, а «Куда ходили» — заметка, а не витрина.
   260px — примерно две трети ширины телефона: разница с текстом теперь
   крупная и читается как решение. Промежуточные 340px давали щель в
   26px — ни выравнивания, ни отличия, только вид случайной ошибки. */
@media (max-width:640px){
  .trip-shot{max-width:260px}
}
