/* ЛОНГХАУС — «Кино». Общая таблица стилей. */

/* ---------- шрифты ---------- */
@font-face{font-family:'Inter Tight';font-style:normal;font-display:swap;font-weight:100 900;
  src:url('../fonts/inter-tight-cyrillic-wght-normal.woff2') format('woff2-variations');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Inter Tight';font-style:normal;font-display:swap;font-weight:100 900;
  src:url('../fonts/inter-tight-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;}
@font-face{font-family:'Playfair Display';font-style:normal;font-display:swap;font-weight:400 900;
  src:url('../fonts/playfair-display-cyrillic-wght-normal.woff2') format('woff2-variations');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Playfair Display';font-style:normal;font-display:swap;font-weight:400 900;
  src:url('../fonts/playfair-display-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+2000-206F,U+20AC,U+2122;}

/* ---------- токены ---------- */
:root{
  --ink:#0d0d0e;
  --ink-soft:#5b5b5e;
  --paper:#ffffff;
  --fog:#dcdbd8;
  --fog-2:#eceae6;
  --night:#0a0a0b;
  --clay:#a4693a;
  --line:rgba(13,13,14,.14);
  --line-dark:rgba(255,255,255,.16);
  --sans:'Inter Tight',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --serif:'Playfair Display',Georgia,'Times New Roman',serif;

  /* ==================== ЕДИНАЯ СЕТКА КОНТЕНТА (LAYOUT-STANDARDS §1.А) ====================
     ОДИН max-width на весь сайт + плавный боковой отступ. Никаких ступенчатых
     контейнеров по брейкпоинтам — именно они дают «прыжки» ширины.
     Контейнер: min(1280px, 92vw).
     --pad — тот же самый жёлоб, вычисленный явно, чтобы ПОЛНОШИРИННЫЕ элементы
     (шапка, фикс-акты, подписи на медиа, горизонтальный трек) вставали ровно
     на левую границу контейнера. Замеры отступа:
     360:14.4  390:15.6  414:16.6  768:30.7  834:33.4  1024:41  1280:51.2
     1440:80   1680:200  1920:320  2560:640
     ===================================================================================== */
  --grid-max:1280px;
  --grid-fluid:92vw;
  --grid-gut:max(4vw, calc((100vw - var(--grid-max)) / 2));
  --grid-measure:80ch;
  --pad:var(--grid-gut);
  --header-h:72px;
  --ease:cubic-bezier(.22,.61,.36,1);
}
@media (max-width:760px){:root{--header-h:60px}}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--fog);color:var(--ink);
  font-family:var(--sans);font-weight:380;font-size:17px;line-height:1.6;
  letter-spacing:.005em;overflow-x:hidden;
  overflow-x:clip; /* clip не создаёт скролл-контейнер на body (иначе колесо конфликтует с Lenis) */
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit}
h1,h2,h3,h4{margin:0;font-weight:200;letter-spacing:-.03em;line-height:.96;text-wrap:balance}
/* Никаких автопереносов и разрывов слова посреди строки на всём сайте:
   слово либо целиком на строке, либо строка ужимается по кеглю (см. .hline).
   `hyphens:manual` оставляет работать только явный мягкий перенос U+00AD. */
html,body,h1,h2,h3,h4,p,li,td,th,figcaption,blockquote,label,button,a{
  -webkit-hyphens:manual;hyphens:manual;word-break:normal;overflow-wrap:normal}
p{margin:0 0 1em}
p:last-child{margin-bottom:0}
::selection{background:var(--ink);color:#fff}
:focus-visible{outline:2px solid var(--clay);outline-offset:3px}
/* высота шапки живёт ТОЛЬКО в --header-h, якоря считаются от неё */
[id]{scroll-margin-top:calc(var(--header-h) + 24px)}

/* ---------- типографика ---------- */
.d1{font-size:clamp(44px,8.4vw,150px)}
.d2{font-size:clamp(36px,6.2vw,104px)}
.d3{font-size:clamp(29px,4vw,62px)}
/* лид под заголовком: 52–62ch (LAYOUT-STANDARDS §5) */
.lead{font-size:clamp(17px,1.35vw,22px);line-height:1.5;font-weight:360;color:var(--ink-soft);max-width:56ch;text-wrap:pretty}
.eyebrow{font-size:12px;letter-spacing:.22em;text-transform:uppercase;font-weight:500;color:var(--ink-soft)}
.eyebrow--light{color:rgba(255,255,255,.62)}
.num{font-variant-numeric:tabular-nums;font-weight:150;letter-spacing:-.045em}
/* .12em считались от СОБСТВЕННОГО кегля (0.3em родителя) — отбивка выходила
   0.036em родителя, и «8недель» / «48лет» читались слитно */
.unit{font-size:.3em;font-weight:400;letter-spacing:0;margin-left:.45em;vertical-align:baseline}
.on-dark{color:#fff}
.on-dark .lead,.on-dark .eyebrow{color:rgba(255,255,255,.66)}

/* ---------- шапка ---------- */
.hdr{
  position:fixed;inset:0 0 auto 0;z-index:900;height:var(--header-h);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 var(--pad);
  color:var(--ink);
  transition:background .45s var(--ease),color .35s var(--ease),box-shadow .45s var(--ease),backdrop-filter .45s;
}
.hdr::before{
  content:"";position:absolute;inset:0;z-index:-1;opacity:0;
  background:rgba(255,255,255,.9);backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:0 1px 0 var(--line);transition:opacity .45s var(--ease);
}
.hdr.is-stuck::before{opacity:1}
.hdr.is-dark{color:#fff}
.hdr.is-dark::before{background:rgba(12,12,13,.82);box-shadow:0 1px 0 var(--line-dark)}
.logo{display:flex;align-items:center;gap:11px;font-weight:500;letter-spacing:.16em;font-size:13px;text-transform:uppercase}
.logo svg{width:30px;height:26px;flex:none;overflow:visible}
.logo svg *{stroke:currentColor;fill:none;stroke-width:1.4;vector-effect:non-scaling-stroke}
.nav{display:flex;align-items:center;gap:clamp(14px,2vw,34px)}
.nav a{font-size:14px;font-weight:400;position:relative;padding:6px 0;opacity:.82;transition:opacity .3s}
.nav a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .45s var(--ease)}
.nav a:hover{opacity:1}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1);transform-origin:left}
.nav a[aria-current="page"]{opacity:1;font-weight:500}
.hdr__cta{display:flex;align-items:center;gap:10px}

.btn{
  display:inline-flex;align-items:center;gap:12px;
  background:var(--ink);color:#fff;padding:14px 20px;font-size:14px;font-weight:450;
  letter-spacing:.01em;border:1px solid var(--ink);cursor:pointer;
  transition:background .4s var(--ease),color .4s var(--ease),transform .4s var(--ease);
  position:relative;overflow:hidden;
}
.btn::before{content:"";position:absolute;inset:0;z-index:0;background:var(--clay);
  transform:scaleY(0);transform-origin:bottom;transition:transform .45s var(--ease)}
.btn:hover::before,.btn:focus-visible::before{transform:scaleY(1);transform-origin:top}
.btn span{position:relative;z-index:1}
.btn svg{width:15px;height:15px;flex:none;position:relative;z-index:1;transition:transform .45s var(--ease)}
.btn svg *{stroke:currentColor;fill:none;stroke-width:1.6}
.btn:hover{transform:translateY(-2px)}
.btn:hover svg{transform:translate(3px,-3px)}
.btn:hover,.btn:focus-visible{color:#fff;border-color:var(--clay)}

/* микрокопирайт под кнопкой — снимает тревогу перед кликом */
.cta-note{margin:0;font-size:13px;line-height:1.45;color:var(--ink-soft);max-width:min(100%,540px);display:flex;gap:8px;align-items:flex-start}
.cta-note svg{width:14px;height:14px;flex:none;margin-top:3px;color:var(--clay)}
.cta-note svg *{fill:none;stroke:currentColor;stroke-width:1.7}
.on-dark .cta-note,.slab--night .cta-note,.foot .cta-note{color:rgba(255,255,255,.72)}
.on-dark .cta-note svg,.slab--night .cta-note svg,.foot .cta-note svg{color:#c98f5c}
.btn--ghost{background:transparent;color:inherit;border-color:currentColor}
.on-dark .btn{background:#fff;color:var(--ink);border-color:#fff}
.on-dark .btn--ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.55)}
.on-dark .btn:hover,.on-dark .btn:focus-visible{color:#fff;border-color:var(--clay)}
.btn--lg{padding:18px 26px;font-size:15px}

/* бургер */
.burger{display:none;width:44px;height:44px;align-items:center;justify-content:center;background:none;border:0;cursor:pointer}
.burger i{display:block;width:22px;height:1.4px;background:currentColor;position:relative;transition:background .3s}
.burger i::before,.burger i::after{content:"";position:absolute;left:0;width:22px;height:1.4px;background:currentColor;transition:transform .4s var(--ease)}
.burger i::before{top:-7px}.burger i::after{top:7px}
.is-menu .burger i{background:transparent}
.is-menu .burger i::before{transform:translateY(7px) rotate(45deg)}
.is-menu .burger i::after{transform:translateY(-7px) rotate(-45deg)}
.mobmenu{
  position:fixed;inset:0;z-index:880;background:var(--night);color:#fff;
  display:flex;flex-direction:column;justify-content:center;gap:6px;padding:0 var(--pad);
  clip-path:inset(0 0 100% 0);transition:clip-path .7s var(--ease);pointer-events:none;
}
.is-menu .mobmenu{clip-path:inset(0);pointer-events:auto}
.mobmenu a{font-size:clamp(30px,9vw,52px);font-weight:200;letter-spacing:-.03em;opacity:0;transform:translateY(24px);transition:opacity .5s var(--ease),transform .6s var(--ease)}
.is-menu .mobmenu a{opacity:1;transform:none}
.is-menu .mobmenu a:nth-child(1){transition-delay:.18s}
.is-menu .mobmenu a:nth-child(2){transition-delay:.24s}
.is-menu .mobmenu a:nth-child(3){transition-delay:.30s}
.is-menu .mobmenu a:nth-child(4){transition-delay:.36s}
.is-menu .mobmenu a:nth-child(5){transition-delay:.42s}
.mobmenu__foot{margin-top:38px;font-size:15px;color:rgba(255,255,255,.6);opacity:0;transition:opacity .5s .5s}
.is-menu .mobmenu__foot{opacity:1}
@media (max-width:900px){
  .nav{display:none}
  .burger{display:flex}
  .hdr__cta .btn{display:none}
}

/* ---------- штора перехода ----------
   ВАЖНО: штора никогда не показывается при ЗАГРУЗКЕ страницы (это давало чёрную
   вспышку). Она скрыта по visibility и включается только при уходе на другую
   страницу — класс .is-on ставит JS. */
.curtain{position:fixed;inset:0;z-index:9990;background:var(--night);transform:translateY(100%);
  pointer-events:none;visibility:hidden;will-change:transform}
.curtain.is-on{visibility:visible}
.curtain__mark{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);opacity:0}
.curtain__mark svg{width:52px;height:44px;overflow:visible}
.curtain__mark svg *{stroke:#fff;fill:none;stroke-width:1.2;vector-effect:non-scaling-stroke}

/* ---------- фиксированная сцена ----------
   ПРАВКА 06.08 (фидбэк владельца): раньше здесь жили СЕМЬ чёрно-белых кадров
   макета, которые «камера» кроссфейдила и одновременно двигала (scale/translate/
   brightness). В середине каждого кроссфейда на экране висели ДВА полупрозрачных
   макета сразу — это и есть те «ужасные наложения одной картинки с другой»
   (скрин 114508, фото 03.08 15-05-43). Кроссфейд, зум и панорамирование убраны
   целиком: сцена — ОДИН статичный кадр (scene-05), фон и заполнитель под
   текстовыми секциями и статичный разделитель между ними (референс 12-16-19).
   Кадр чб-чертежа scene-03 (фото 03.08 15-05-43) на сайте больше не используется. */
.stage{position:fixed;inset:0;z-index:-1;overflow:hidden;background:var(--fog);pointer-events:none}
.stage__frames{position:absolute;inset:0}
.stage__frame{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:1}
.stage__vig{position:absolute;inset:0;background:radial-gradient(120% 90% at 50% 45%,transparent 45%,rgba(0,0,0,.16) 100%)}
/* Зерно плёнки. mix-blend-mode:multiply на полноэкранном слое поверх постоянно
   движущегося стека кадров заставляет композитор на каждом кадре вычитывать
   подложку и пересмешивать её: замер на планшете 768×1024 давал 31 fps против
   55 fps без этого слоя (сам слой при этом статичен). Тот же зернистый шум
   отдаём обычным наложением с подобранной непрозрачностью — рисунок зерна
   сохраняется, backdrop-read исчезает. Эффект остаётся на всех ширинах. */
.stage__grain{position:absolute;inset:0;opacity:.1;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");}

/* ---------- текстовые акты ----------
   ПРАВКА 06.08 (фидбэк «скролл стрёмный, на текстовых секциях приходится очень
   долго скроллить»): раньше каждый акт был position:fixed и «висел» ровно
   столько, сколько тянулся его спейсер — 110dvh, 200dvh, 260dvh и даже 400dvh.
   Одних спейсеров на главной набиралось ~1470dvh: пятнадцать высот экрана
   прокрутки под пять текстовых блоков. Теперь акт — ОБЫЧНАЯ секция в потоке,
   спейсеры выключены, прокрутка на телефоне и десктопе самая обычная. */
.spacer,.anchor{display:none}

.act{
  position:relative;z-index:3;
  width:min(52ch,44vw);max-width:calc(100% - var(--pad)*2);
  margin:0 auto 0 var(--pad);
  padding:clamp(54px,8.5vh,112px) 0;
  display:flex;flex-direction:column;justify-content:center;
  opacity:1;pointer-events:auto;
}
.act .d1{font-size:clamp(38px,6.4vw,112px)}
/* текст акта лежит поверх кадра сцены — берём тон чуть плотнее для запаса по AA */
.act .lead,.act .cta-note{max-width:none;color:#4b4b4e}
/* Подложка акта. Горизонтальный градиент даёт РОВНОЕ плато 0.94 под всем
   текстом (гарантирует AA поверх кадра сцены), а вертикальная маска растворяет
   его сверху и снизу — без видимой полосы и без стыка с соседним блоком. */
.act::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  top:0;bottom:0;left:calc(var(--pad) * -1);right:-26%;
  background:linear-gradient(90deg,rgba(233,232,229,.95) 0%,rgba(233,232,229,.94) 68%,rgba(233,232,229,.55) 86%,rgba(233,232,229,0) 100%);
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 14%,#000 86%,transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 14%,#000 86%,transparent 100%)}
.act--right::before{left:-26%;right:calc(var(--pad) * -1);
  background:linear-gradient(270deg,rgba(233,232,229,.95) 0%,rgba(233,232,229,.94) 68%,rgba(233,232,229,.55) 86%,rgba(233,232,229,0) 100%)}
@supports not (mask-image:linear-gradient(#000,#000)){
  .act::before{background:radial-gradient(88% 72% at 26% 50%,rgba(233,232,229,.96),rgba(233,232,229,.94) 58%,rgba(233,232,229,0) 100%)}
  .act--right::before{background:radial-gradient(88% 72% at 74% 50%,rgba(233,232,229,.96),rgba(233,232,229,.94) 58%,rgba(233,232,229,0) 100%)}
}
.act--right{margin-left:auto;margin-right:var(--pad);text-align:right}
.act--right .lead{margin-left:auto}

/* Статичный разделитель: полоса, сквозь которую видно ОДИН неподвижный кадр
   сцены. Работает и как «текст выше — картинка — следующие слайды»
   (референс 12-16-19), и как воздух между двумя текстовыми актами. */
.stageband{position:relative;z-index:1;height:clamp(170px,32dvh,360px);pointer-events:none}
@media (max-width:760px){.stageband{height:clamp(150px,26dvh,260px)}}

/* ---------- полноэкранный герой ---------- */
.act--hero{
  width:auto;max-width:none;margin:0;
  padding:calc(var(--header-h) + 7dvh) var(--pad) 7dvh;
  min-height:100dvh;justify-content:center;
}
/* Подложка героя. ПРАВКА 06.08: к вертикальному градиенту добавлен ЛЕВЫЙ —
   заголовок и лид стоят у левого края, и им нужен гарантированный контраст
   с кадром под ними (сейчас это макет, после подмены файла — видео с дрона:
   src не меняется, подложка одинаково работает и со светлым, и с тёмным). */
/* left/right строго 0. Раньше стояло -100vw «с запасом на всякий случай»: пока
   акт был position:fixed, вылет за экран никуда не считался. После переноса
   актов в поток (правка 06.08) тот же вылет стал РЕАЛЬНОЙ шириной документа —
   scrollWidth вырастал до 2880 px при экране 1440. Горизонтальной полосы не
   появлялось только потому, что body{overflow-x:clip} её прячет, но ширина
   документа врала всем, кто её читает (ScrollTrigger, поиск по странице,
   мобильные браузеры при зуме). Сам герой и так во всю ширину — 0 достаточно. */
/* ПРАВКА 12.08: mask-image:none оставлял у плашки РЕЗКИЙ нижний край — при
   прокрутке через первый экран поперёк кадра сцены шла прямая линия. Маска
   возвращена, но только снизу (сверху плашка обязана доходить до шапки). */
.act--hero::before{
  top:0;bottom:0;left:0;right:0;
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 calc(100% - clamp(90px,12vh,170px)),transparent 100%);
  mask-image:linear-gradient(180deg,#000 0%,#000 calc(100% - clamp(90px,12vh,170px)),transparent 100%);
  background:
    linear-gradient(90deg,rgba(236,234,230,.80) 0%,rgba(236,234,230,.74) 30%,rgba(236,234,230,.46) 62%,rgba(236,234,230,.18) 86%,rgba(236,234,230,.06) 100%),
    linear-gradient(180deg,rgba(236,234,230,.26) 0%,rgba(236,234,230,.42) 34%,rgba(236,234,230,.50) 70%,rgba(236,234,230,.30) 100%)}
/* На тёмном кадре (герой поверх видео) тот же приём, но плашка тёмная */
.act--hero.on-dark::before{
  background:
    linear-gradient(90deg,rgba(8,9,10,.72) 0%,rgba(8,9,10,.62) 32%,rgba(8,9,10,.34) 64%,rgba(8,9,10,.10) 88%,rgba(8,9,10,0) 100%),
    linear-gradient(180deg,rgba(8,9,10,.42) 0%,rgba(8,9,10,.18) 38%,rgba(8,9,10,.52) 100%)}
.hero-title{margin:0;font-weight:200;letter-spacing:-.045em;line-height:.9;width:100%;text-wrap:nowrap}
.fitline{display:block;white-space:nowrap;font-size:clamp(40px,12.5vw,240px)}
.fitline+.fitline{margin-top:.02em}
/* Укороченная вторая строка (data-fit-scale) живёт чуть ниже: её кегль меньше,
   поэтому .02em дают всего пару пикселей, и выносной хвост «у» верхней строки
   почти касается «ж» нижней. Отступ в em — чтобы воздух масштабировался вместе
   с заголовком на любой ширине. */
/* ПРАВКА 12.08 (фидбэк Карины): подпись должна стоять ВПЛОТНУЮ под «Лонгхаус»,
   а воздух — уйти ВНИЗ, к следующему блоку. Было .16em над подписью и
   clamp(24px,3vw,46px) под всем заголовком; стало .04em сверху (подпись
   прижата к слову) и увеличенный отступ у .hero-foot. */
.fitline[data-fit-scale]{margin-top:.04em}
.hero-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:clamp(20px,3vw,56px);flex-wrap:wrap;margin-top:clamp(40px,4.8vw,76px)}
.hero-foot .lead{max-width:44ch;margin:0;flex:1 1 300px}
.hero-cta{display:flex;flex-direction:column;gap:12px;align-items:stretch;flex:0 1 auto}
.hero-cta__row{display:flex;gap:12px;flex-wrap:wrap}
.hero-cta .cta-note{max-width:100%}
@media (max-width:900px){
  .hero-foot{flex-direction:column;align-items:flex-start}
  /* в КОЛОНКЕ flex-basis считается по ВЫСОТЕ: `flex:1 1 300px` давал под лидом
     дыру в 300 px и выдавливал кнопки за экран. Basis auto безопасен в обеих осях. */
  .hero-foot .lead{flex:1 1 auto;width:100%}
}
/* узкий телефон: освобождаем высоту под заголовок — микрокопию несёт липкая кнопка */
@media (max-width:480px){
  .act--hero .cta-note{display:none}
  .act--hero .lead{font-size:15px;line-height:1.45}
  .act--hero .btn--lg{padding:13px 16px;font-size:13.5px}
  .act--hero .hero-cta__row{width:100%}
  .act--hero .hero-cta__row .btn{flex:1 1 100%;justify-content:space-between}
}
/* короткие ландшафтные экраны: заголовок не должен выдавливать кнопки */
@media (max-height:600px) and (orientation:landscape){
  .act--hero .cta-note{display:none}
  .act--hero .eyebrow{margin-bottom:6px!important}
  .hero-foot{margin-top:12px;gap:12px 20px;flex-direction:row;align-items:flex-end}
  .act--hero .lead{font-size:14px;line-height:1.4;max-width:34ch}
  .btn--lg{padding:11px 16px;font-size:13px}
}

@media (max-width:900px){
  .act{width:calc(100% - var(--pad)*2)}
  .act--hero{width:auto}
  /* на десктопе акт сам узкий (44vw), на планшете он во всю ширину —
     без капа строка лида доходила до 110 символов (WCAG 1.4.8: <= 80) */
  .act .lead{max-width:62ch}
  .act--right{margin-left:var(--pad);margin-right:auto;text-align:left}
  .act--right .lead{margin-left:0}
  .act::before,.act--right::before{left:calc(var(--pad) * -1);right:calc(var(--pad) * -1);
    background:linear-gradient(90deg,rgba(233,232,229,.95) 0%,rgba(233,232,229,.94) 74%,rgba(233,232,229,.86) 100%)}
  /* Герой на телефоне занимает ВСЮ ширину, поэтому вынос подложки на -pad с
     каждой стороны — это ровно 2×pad лишней ширины документа. Возвращаем 0
     и здесь: правило выше по общности его перекрывает. */
  .act--hero::before{left:0;right:0}
}

/* подсказка скролла */
.scrollhint{position:fixed;left:50%;bottom:26px;z-index:3;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}
.scrollhint svg{width:14px;height:20px}
.scrollhint svg *{stroke:currentColor;fill:none;stroke-width:1.3}
/* На коротком ландшафте подсказка ложилась ровно на кнопки героя. Правило стоит
   ПОСЛЕ базового `.scrollhint{display:flex}` намеренно: медиазапрос не повышает
   специфичность, и объявленное раньше `display:none` проигрывало по порядку. */
@media (max-height:600px) and (orientation:landscape){.scrollhint{display:none}}
/* Подсказка стоит position:fixed и в потоке НЕ участвует — значит место под
   собой герой обязан зарезервировать САМ, иначе на низком ландшафтном экране
   (1280x651 — реальный экран клиентки, 1366x640) она ложится на микрокопию под
   кнопками. --hint-space = высота подсказки (46) + её отступ от низа (26,
   на узких — 12, см. `.scrollhint{bottom:12px}` ниже) + воздух (14).
   Почему padding, а не margin: у акта min-height:100dvh и justify-content:center,
   и ровно этот padding-bottom читает fitLines() при расчёте потолка по высоте —
   резерв под подсказку сразу входит в бюджет заголовка, а не спорит с ним. */
:root{--hint-space:86px}
@media (max-width:900px){:root{--hint-space:72px}}
#act-hero{padding-bottom:max(7dvh,var(--hint-space))}
/* Подсказки нет — резерв не нужен (порядок правил важен: специфичность равная) */
@media (max-height:600px) and (orientation:landscape){#act-hero{padding-bottom:7dvh}}
@media (prefers-reduced-motion:reduce){#act-hero{padding-bottom:7dvh}}

/* ---------- плиты ---------- */
.slab{position:relative;z-index:4;background:var(--paper);padding:clamp(64px,10vw,150px) var(--pad)}
.slab--night{background:var(--night);color:#fff}
.slab--fog{background:var(--fog-2)}
/* flush = медиа во всю плиту, без цветных полос сверху/снизу */
.slab--flush{padding:0}
/* мягкий вход тёмной плиты после светлой фиксированной сцены */
.slab--fadein::before{content:"";position:absolute;left:0;right:0;top:-14vh;height:14vh;
  background:linear-gradient(180deg,rgba(10,10,11,0),rgba(10,10,11,.55) 55%,var(--night));pointer-events:none}
/* единый контейнер: один max-width + плавный жёлоб (LAYOUT-STANDARDS §1.А) */
.wrap{width:min(var(--grid-max),var(--grid-fluid));max-width:min(var(--grid-max),var(--grid-fluid));
  margin-left:auto;margin-right:auto;padding-left:0;padding-right:0}

/* ---------- медиа-блоки ---------- */
/* ПРАВКА 12.08: тот же «обрубок», что и у .stillshot — потолок 980 px оставлял
   белую полосу на высоких экранах. dvh→svh + подняты границы. */
.fullshot{position:relative;height:clamp(480px,94vh,1120px);height:clamp(480px,94svh,1120px);overflow:hidden}
.fullshot img{width:100%;height:100%;object-fit:cover}
/* Скрим кадра. Вертикального градиента не хватало: текст лежит в нижней ЛЕВОЙ
   части, а самая светлая зона снимка (закатное солнце сквозь панораму) попадала
   ровно туда — белый текст «плавился». Добавлен ГОРИЗОНТАЛЬНЫЙ слой: плотный
   слева, полностью прозрачный справа, поэтому правая половина кадра остаётся
   нетронутой и картинка не превращается в тёмную заливку. */
.fullshot__scrim{position:absolute;inset:0;background:
  radial-gradient(96% 84% at 16% 80%,
    rgba(4,5,6,.90) 0%,rgba(4,5,6,.86) 30%,rgba(4,5,6,.66) 52%,
    rgba(4,5,6,.34) 72%,rgba(4,5,6,.10) 88%,rgba(4,5,6,0) 100%),
  linear-gradient(180deg,rgba(0,0,0,.30) 0%,rgba(0,0,0,.06) 38%,rgba(0,0,0,.44) 100%)}
/* на узком экране текст занимает всю ширину кадра — пятно шире и выше */
@media (max-width:900px){
  .fullshot__scrim{background:
    radial-gradient(150% 92% at 34% 78%,
      rgba(4,5,6,.90) 0%,rgba(4,5,6,.86) 34%,rgba(4,5,6,.70) 58%,
      rgba(4,5,6,.40) 78%,rgba(4,5,6,.12) 92%,rgba(4,5,6,0) 100%),
    linear-gradient(180deg,rgba(0,0,0,.30) 0%,rgba(0,0,0,.08) 34%,rgba(0,0,0,.46) 100%)}
}
/* ПРАВКА 12.08: текст поднят — под ним теперь идёт полоса растворения кадра
   в цвет следующей секции (см. «мягкие стыки»), и на прежних 38-80 px он бы
   в неё попадал. */
.fullshot__txt{position:absolute;z-index:3;left:var(--pad);right:var(--pad);bottom:clamp(100px,10vw,160px);color:#fff}
.fullshot__txt .lead{color:rgba(255,255,255,.88)}

.duo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,5vw,96px);align-items:center}
.duo--wide{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr)}
@media (max-width:900px){.duo,.duo--wide{grid-template-columns:minmax(0,1fr)}}
.reveal-img{overflow:hidden;position:relative}
.reveal-img img{width:100%;height:100%;object-fit:cover}

/* карточки интерьеров */
.trio{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2vw,30px)}
@media (max-width:900px){.trio{grid-template-columns:minmax(0,1fr)}}
.roomcard figure{margin:0;overflow:hidden;position:relative;aspect-ratio:4/5;background:var(--fog)}
.roomcard img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease)}
.roomcard:hover img,.roomcard:active img{will-change:transform}
.roomcard:hover img{transform:scale(1.05)}
.roomcard figcaption{padding:16px 0 0;font-size:15px;color:var(--ink-soft);line-height:1.45}
.roomcard h3{font-size:21px;font-weight:400;letter-spacing:-.02em;margin-bottom:6px;color:var(--ink)}
.on-dark .roomcard h3{color:#fff}

/* цифры поверх сцены */
/* Спейсеры выключены (см. «текстовые акты»), поэтому воздух вокруг цифр
   задаётся собственными отступами блока, а не пустым экраном сверху. */
.figures{position:relative;z-index:1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;padding:clamp(56px,13dvh,150px) var(--pad) clamp(56px,14dvh,160px);align-items:end;min-height:0;pointer-events:none}
/* подложка под цифрами — они лежат прямо на кадре сцены */
/* ПРАВКА 12.08: подложка обрывалась на .9 ровно по нижней границе блока — поперёк
   кадра сцены шла видимая линейка. Хвост доведён обратно до прозрачного, теперь
   плашка растворяется в кадр с обеих сторон. */
.figures::before{content:"";position:absolute;inset:auto 0 0 0;height:78%;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(233,232,229,0),rgba(233,232,229,.72) 34%,rgba(233,232,229,.9) 62%,rgba(233,232,229,.72) 84%,rgba(233,232,229,0))}
/* верх блока цифр упирался в плиту --fog-2 прямой линией — растворяем и его */
.slab--fog + .figures::after{content:"";position:absolute;left:0;right:0;top:0;height:clamp(64px,9vh,140px);z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,var(--fog-2) 0%,rgba(236,234,230,.78) 20%,rgba(236,234,230,.42) 44%,rgba(236,234,230,.14) 70%,rgba(236,234,230,0) 100%)}
.figures .fig{will-change:opacity,transform}
.fig__n{font-size:clamp(52px,8.6vw,148px);font-weight:150;letter-spacing:-.05em;line-height:.9}
.fig__c{font-size:14px;color:#4b4b4e;margin-top:10px;letter-spacing:.02em}
@media (max-width:900px){.figures{grid-template-columns:minmax(0,1fr);gap:34px;padding-bottom:clamp(48px,10dvh,120px)}}

/* ---------- БЛОК «ПЛАН И ЦИФРЫ» ----------
   ПРАВКА 06.08 (фидбэк «убрать анимацию наложения блоков»): здесь был
   закреплённый на 3 экрана 3D-подъём камеры — карточка стартовала наклонённой
   rotateX(−58°) (скошенная трапеция на фото 11-41-17) и по дороге проявляла
   план ПОВЕРХ макета маской, то есть две картинки одновременно висели одна на
   другой. Блок с видео сверху при этом ещё не успевал уйти. Пин, перспектива и
   маска убраны: видеоблок проходит целиком, ЗАТЕМ обычной прокруткой приходит
   готовый план с ценой и плитками (фото 11-42-24). */
/* overflow снят с секции и перенесён на __inner (правка 12.08): при overflow:hidden
   секция обрезала полосу растворения предыдущего кадра (видеопауза на главной
   обрывалась о плиту прямой линией). Клипить нужно только карточку плана. */
.planact{position:relative;z-index:4;background:var(--fog-2);height:100dvh;min-height:600px}
.planact__inner{position:absolute;inset:0;overflow:hidden;display:flex;align-items:center;justify-content:center}
.planact__card{position:relative;width:min(74vw,900px);aspect-ratio:16/10;overflow:hidden}
.planact__card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.planact__data{position:absolute;inset:0;padding:calc(var(--header-h) + 4vh) var(--pad) 6vh;display:flex;flex-direction:column;justify-content:space-between;pointer-events:none}
.pl-price{opacity:0}
.pl-price .eyebrow{margin-bottom:8px}
.pl-price .num{font-size:clamp(38px,7vw,116px);display:block;line-height:.9}
.pl-tiles{display:flex;gap:16px;align-self:flex-end;flex-wrap:wrap;justify-content:flex-end}
.pl-tile{opacity:0;width:clamp(180px,22vw,268px);aspect-ratio:1/.82;padding:20px;display:flex;flex-direction:column;justify-content:space-between;background:var(--paper)}
.pl-tile--dark{background:var(--night);color:#fff}
.pl-tile svg{width:20px;height:20px;align-self:flex-end}
.pl-tile svg *{stroke:currentColor;fill:none;stroke-width:1.3}
.pl-tile .num{font-size:clamp(28px,3.4vw,50px)}
.pl-tile b{font-weight:400;font-size:13px;letter-spacing:.02em;opacity:.62;display:block}
@media (max-width:760px){
  .planact__card{width:88vw}
  /* align-self:flex-start схлопывал ленту плиток до fit-content, и `width:50%`
     считалось от неё же — цифра «120–180 м²» вылезала за плитку на 16 px.
     stretch возвращает плиткам полную ширину колонки. */
  .pl-tiles{align-self:stretch;justify-content:flex-start;width:100%}
  .pl-tile{width:calc(50% - 8px);padding:14px}
}

/* ---------- статичный полноэкранный кадр ----------
   Замена «вырастающему» медиа (data-grow): без закрепления и без зума по
   скроллу — только лёгкий параллакс. Кадр берём с запасом по высоте (126 %),
   чтобы при сдвиге ±9 % не оголялся край. */
/* ПРАВКА 12.08: было height:clamp(420px,86dvh,900px) — кадр упирался в жёсткий
   потолок 900 px, и на экране 1080+ под ним оставалась белая полоса в 150-190 px
   («блок обрывается, белый кусок внизу мешается», фидбэк владельца). Стало
   min-height почти в экран (svh, а не dvh — не скачет при показе/скрытии панелей
   мобильного браузера) с запасом по верхней границе. Низ и верх кадра дополнительно
   растворяются в цвет соседней секции — см. блок «мягкие стыки» в конце файла. */
.stillshot{position:relative;z-index:4;min-height:clamp(480px,96vh,1160px);min-height:clamp(480px,96svh,1160px);overflow:hidden;background:var(--night)}
.stillshot__bg{position:absolute;inset:0}
.stillshot img{position:absolute;top:-13%;left:0;width:100%;height:126%;object-fit:cover}

/* SVG-планировка */
.blueprint{width:100%;height:auto;display:block}
.blueprint path,.blueprint line,.blueprint rect,.blueprint circle,.blueprint polyline{fill:none;stroke:var(--ink);stroke-width:1.2;vector-effect:non-scaling-stroke}
.blueprint .hatch{stroke-width:.6;opacity:.45}

/* ---------- анонс следующего раздела (полоса между плитой и лентой) ----------
   Приём стандартный для тёмных лендингов: волосяная линия во всю колонку +
   надзаголовок вразрядку + одна крупная строка. Полоса не «новая секция», а
   шапка следующей: у ленты .hscroll кадры центрированы по высоте, и её первые
   ~150 px пустые — заголовок стоит ровно над ними и закрывает провал. */
.nextup{position:relative;z-index:4;background:var(--night);color:#fff;
  padding:clamp(26px,3vw,46px) var(--pad) clamp(22px,2.6vw,40px)}
.nextup__in{border-top:1px solid var(--line-dark);padding-top:clamp(20px,2.2vw,32px)}
.nextup .eyebrow{margin:0 0 12px}
.nextup h2{margin:0}
/* плита, за которой сразу идёт анонс: полный нижний отступ здесь дал бы ту же
   пустоту, что и раньше, только выше полосы */
.slab--tight-b{padding-bottom:clamp(28px,3.2vw,52px)}

/* ---------- горизонтальный скролл ---------- */
.hscroll{position:relative;z-index:4;background:var(--night);color:#fff;overflow:hidden;height:100dvh}
.hscroll__track{display:flex;height:100%;align-items:center;gap:clamp(16px,2.4vw,40px);padding:0 var(--pad);will-change:transform}
/* margin:0 обязателен. .hpanel — это <figure>, и браузерный дефолт
   `margin:1em 40px` никто не гасил: между кадрами вместо жёлоба 34 px вставало
   40+34+40 = 114 px чёрной дыры (видно на видео ревьюера), а вертикальные 1em
   съезжали кадр вниз относительно текстовой колонки .hintro. Плюс дистанция
   ленты считалась без правого margin — последний кадр не доезжал. */
.hpanel{margin:0;flex:none;width:min(72vw,760px);height:min(66dvh,620px);position:relative;overflow:hidden;background:#141416}
.hpanel img{width:100%;height:100%;object-fit:cover;opacity:.9}
/* тёмная подложка под подписью — иначе белый текст тонет в светлых кадрах */
.hpanel::after{content:"";position:absolute;left:0;right:0;bottom:0;height:58%;pointer-events:none;
  background:linear-gradient(180deg,rgba(8,8,9,0),rgba(8,8,9,.55) 48%,rgba(8,8,9,.88))}
.hpanel__cap{position:absolute;left:24px;right:24px;bottom:22px;z-index:1}
.hpanel__cap h3{font-size:clamp(20px,2vw,30px);font-weight:300;margin-bottom:6px;color:#fff}
.hpanel__cap p{font-size:14px;color:rgba(255,255,255,.82);margin:0}
.hintro{flex:none;width:min(46vw,520px);padding-right:24px}
/* Телефон и планшет: лента остаётся ГОРИЗОНТАЛЬНОЙ и закреплённой, как на
   десктопе. Меняются только размеры кадров и жёлоб — чтобы в поле зрения был
   один кадр целиком и край следующего (подсказка «здесь ещё есть»). */
@media (max-width:900px){
  .hscroll__track{gap:14px}
  .hpanel{width:min(78vw,460px);height:min(54dvh,440px)}
  .hpanel__cap{left:18px;right:18px;bottom:18px}
  .hintro{width:min(86vw,500px);padding-right:10px}
}
@media (max-width:560px){
  .hpanel{width:82vw;height:min(50dvh,400px)}
  .hintro{width:88vw}
}

/* ---------- trust / гарантии ---------- */
.quad{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--line)}
.quad>div{background:var(--paper);padding:clamp(24px,2.6vw,40px);min-height:230px;display:flex;flex-direction:column;gap:14px}
.slab--night .quad{background:var(--line-dark)}
.slab--night .quad>div{background:var(--night)}
.quad h3{font-size:19px;font-weight:400;letter-spacing:-.01em}
.quad p{font-size:14.5px;color:var(--ink-soft);margin:0}
/* телефон и почта в карточках контактов — самостоятельные действия, тап-цель 41 px */
.quad p a{display:inline-block;padding:10px 0;margin:-10px 0}
.slab--night .quad p{color:rgba(255,255,255,.62)}
.ic{width:28px;height:28px}
.ic *{fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round}
@media (max-width:1000px){.quad{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* в одну колонку min-height:230px превращался в пустую дыру под каждым текстом */
@media (max-width:560px){.quad{grid-template-columns:minmax(0,1fr)}.quad>div{min-height:0}}

/* цитата */
.quote{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(28px,5vw,80px);align-items:center}
.quote img{width:100%;aspect-ratio:4/5;object-fit:cover}
.quote blockquote{margin:0;font-family:var(--serif);font-style:italic;font-weight:400;font-size:clamp(23px,2.7vw,44px);line-height:1.24;letter-spacing:-.02em}
.quote cite{display:block;margin-top:26px;font-style:normal;font-size:14px;color:var(--ink-soft);letter-spacing:.02em}
@media (max-width:900px){.quote{grid-template-columns:minmax(0,1fr)}}

/* ---------- формы ---------- */
.form{display:grid;gap:18px;max-width:520px}
.field{position:relative;display:flex;flex-direction:column;gap:7px}
.field label{font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft)}
.on-dark .field label{color:rgba(255,255,255,.6)}
.field input,.field textarea,.field select{
  font:inherit;font-size:16px;color:inherit;background:transparent;
  border:0;border-bottom:1px solid var(--line);padding:11px 0;border-radius:0;
  transition:border-color .35s var(--ease);width:100%;
}
.on-dark .field input,.on-dark .field textarea,.on-dark .field select{border-bottom-color:var(--line-dark)}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-bottom-color:var(--clay)}
.field textarea{resize:vertical;min-height:92px}
.field.is-bad input{border-bottom-color:#b4402f}
.err{font-size:12.5px;color:#b4402f;min-height:1em}
.on-dark .err{color:#ee8b7c}
.consent{display:flex;gap:11px;align-items:flex-start;font-size:13px;color:var(--ink-soft);line-height:1.45}
.on-dark .consent{color:rgba(255,255,255,.6)}
.consent input{margin-top:3px;accent-color:var(--clay);width:16px;height:16px;flex:none}
.formdone{display:none;gap:14px;align-items:center;font-size:17px}
.formdone svg{width:30px;height:30px;flex:none}
.formdone svg *{fill:none;stroke:var(--clay);stroke-width:1.6;stroke-linecap:round;stroke-dasharray:60;stroke-dashoffset:60}
.form.is-done .formdone{display:flex}
.form.is-done .form__body{display:none}

/* ---------- подвал ---------- */
.foot{position:relative;z-index:4;background:var(--night);color:#fff;padding:clamp(56px,7vw,110px) var(--pad) 34px}
/* Последняя колонка («Офис и завод») шире прочих: в равных долях адрес
   «Вологодская обл., Сокол, Заводская, 1» ломался, и номер дома срывался
   на отдельную строку. Ширины подобраны так, чтобы оба адреса стояли в одну
   строку от 1200 px; ниже колонки перестраиваются и вопрос снимается. */
.foot__grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.8fr) minmax(0,.95fr) minmax(0,1.3fr);gap:clamp(24px,2.4vw,44px)}
@media (max-width:900px){.foot__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.foot__grid{grid-template-columns:minmax(0,1fr)}}
.foot h4{font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.62);font-weight:500;margin-bottom:16px}
.foot ul{list-style:none;margin:0;padding:0;display:grid;gap:10px;font-size:15px}
.foot a{color:rgba(255,255,255,.78);transition:color .3s}
.foot a:hover{color:#fff}
/* крупный CTA-заголовок подвала: 14–16ch даёт плакатный ритм (§5) */
.foot__big{font-size:clamp(26px,3.4vw,52px);font-weight:200;letter-spacing:-.03em;line-height:1.02;margin-bottom:24px;max-width:16ch}
.foot__bot{margin-top:clamp(40px,5vw,74px);padding-top:22px;border-top:1px solid var(--line-dark);display:flex;flex-wrap:wrap;gap:14px 30px;justify-content:space-between;font-size:12.5px;color:rgba(255,255,255,.64)}
.credits{font-size:12px;color:rgba(255,255,255,.56);margin-top:10px;max-width:min(70ch,var(--grid-measure))}
.foot__cta{display:flex;flex-direction:column;gap:12px;align-items:flex-start}

/* ---------- каталог проектов ---------- */
.filters{display:flex;flex-wrap:wrap;gap:10px;margin:34px 0 8px}
.chip{padding:10px 18px;font-size:14px;border:1px solid var(--line);background:transparent;cursor:pointer;transition:background .35s var(--ease),color .35s var(--ease),border-color .35s}
.chip:hover{border-color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink)}
.filters__note{font-size:14px;color:var(--ink-soft);margin:18px 0 0}
.grid-proj{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.2vw,34px);margin-top:38px}
@media (max-width:1000px){.grid-proj{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.grid-proj{grid-template-columns:minmax(0,1fr)}}
.pcard{position:relative;display:flex;flex-direction:column;background:var(--paper);transition:transform .55s var(--ease),box-shadow .55s var(--ease)}
.pcard:hover{transform:translateY(-6px);box-shadow:0 24px 60px -30px rgba(0,0,0,.5)}
.pcard__ph{overflow:hidden;aspect-ratio:16/11;background:var(--fog)}
.pcard__ph img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease)}
.pcard:hover .pcard__ph img{transform:scale(1.06)}
.pcard__b{padding:20px 20px 24px;display:flex;flex-direction:column;gap:12px;flex:1}
.pcard h3{font-size:25px;font-weight:300;letter-spacing:-.02em}
.pcard__meta{display:flex;flex-wrap:wrap;gap:8px 16px;font-size:13.5px;color:var(--ink-soft)}
.pcard__meta span{display:inline-flex;align-items:center;gap:6px}
.pcard__meta svg{width:15px;height:15px}
.pcard__meta svg *{fill:none;stroke:currentColor;stroke-width:1.3}
.pcard__price{margin-top:auto;display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:14px;border-top:1px solid var(--line)}
.pcard__price b{font-size:22px;font-weight:400;letter-spacing:-.02em}
.pcard__price i{font-style:normal;font-size:12.5px;color:var(--ink-soft)}
.pcard.is-hidden{display:none}

/* внутренние hero страниц.
   Высота (правка 12.08): было 76dvh — на 1920×1080 это 821 px при экране 1080,
   кадр обрывался посреди вьюпорта, а под ним оставалась ~150 px белая полоса до
   заголовка следующей секции («обрубок»). Стало 92svh: экран занят почти
   целиком, а оставшаяся полоска работает подсказкой, что ниже есть контент.
   svh (а не dvh/vh) — чтобы на мобильном с ВЫДВИНУТЫМИ панелями браузера
   первый экран не оказался выше вьюпорта и не срезал низ текста; min-height
   не мешает секции расти, если контент выше. vh-строка — фолбэк для движков
   без svh. */
/* ПРАВКА 12.08 (фидбэк владельца «резкий срез блока» / «белая полоса внизу»):
   92svh оставляли под кадром видимую белую полосу в 8 % экрана — она читалась
   не как «ниже есть контент», а как обрубленный блок. Герой доведён до низа
   вьюпорта (100svh; vh-строка — фолбэк для движков без svh), а стык со
   следующей плитой размывается градиентом — см. «мягкие стыки» в конце файла.
   Нижний паддинг увеличен: лид должен стоять ВЫШЕ полосы затухания. */
.phero{position:relative;z-index:4;min-height:100vh;min-height:100svh;display:flex;align-items:flex-end;padding:calc(var(--header-h) + 8dvh) var(--pad) clamp(104px,13vh,180px);overflow:hidden;background:var(--night);color:#fff}
/* Отступ следующей секции сразу под первым экраном: обычные 150 px здесь
   читались как пустота, а не как воздух. Секции ниже по странице свой
   ритм сохраняют. */
.phero + .slab{padding-top:clamp(40px,4.6vw,80px)}
/* Телефон/планшет в АЛЬБОМНОЙ: высота окна ~390-520 px, и заголовок с лидом
   физически не влезают — тянуть секцию до 92svh тут бессмысленно (min-height
   всё равно перебивается контентом) и вредно. Снимаем минимум и поджимаем
   воздух сверху/снизу, чтобы первый экран был как можно ближе к высоте окна
   и ничего не срезалось. То же пороговое значение и та же логика, что у
   существующего правила для #act-hero чуть выше. */
@media (max-height:520px) and (orientation:landscape){
  .phero{min-height:0;padding-top:calc(var(--header-h) + 3dvh);padding-bottom:clamp(22px,4vh,40px)}
  .phero--tall{min-height:0}
  .phero + .slab{padding-top:clamp(28px,4vw,48px)}
}
.phero__bg{position:absolute;inset:0}
/* Запас по высоте под параллакс. Было 112 % при top:-6 %: амплитуда data-parallax
   (yPercent ±8 от высоты САМОЙ картинки = ±9 % высоты секции) уводила кадр так,
   что снизу или сверху оголялась полоса подложки в ~3 % — ещё один «срез».
   120 % при top:-10 % перекрывают ход в обе стороны с запасом. */
.phero__bg img{width:100%;height:120%;object-fit:cover;opacity:.56;position:absolute;top:-10%;left:0}
.phero__bg::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(8,8,9,.66),rgba(8,8,9,.28) 45%,rgba(8,8,9,.86))}
/* Полновысотный вариант hero-блока (только projects.html RU/EN, правка 06.08).
   Было: секция 76dvh, и широкое фото дома влезало в неё узкой обрезанной лентой,
   которая просвечивала ровно за строками подзаголовка. Стало: высота в экран,
   кадр виден целиком как нормальный блок. Статично, без зума и пина.

   Затемнение — по образцу hero longhouse-2: кадр показываем почти в полную силу
   (лес и фактура остаются живыми), а вуаль деликатная и работает там, где лежит
   текст — слева и снизу. Промежуточный вариант с монотонным градиентом до .97
   был отклонён владельцем («блок прям чёрный стал»). */
.phero--tall{min-height:100vh;min-height:100svh}
.phero--tall .phero__bg img{opacity:.94}
/* ПРАВКА 12.08: за героем на projects.html сразу идёт ВТОРОЕ фото — стык двух
   кадров нельзя растворить в плоский цвет, поэтому оба сводятся к общей почти
   чёрной ноте: низ героя доводится до .90, а верх .stillshot стартует с неё же
   и раскрывается вниз (см. `.phero + .stillshot::before`). */
.phero--tall .phero__bg::after{background:
  linear-gradient(90deg,rgba(8,9,10,.66) 0%,rgba(8,9,10,.46) 34%,rgba(8,9,10,.16) 64%,rgba(8,9,10,0) 88%),
  linear-gradient(180deg,rgba(8,9,10,.34) 0%,rgba(8,9,10,.1) 34%,rgba(8,9,10,.26) 60%,rgba(8,9,10,.50) 82%,rgba(8,9,10,.62) 92%,rgba(8,9,10,.90) 100%)}
.phero__c{position:relative;width:min(var(--grid-max),var(--grid-fluid));max-width:min(var(--grid-max),var(--grid-fluid));margin-left:auto;margin-right:auto}
.phero .lead{color:rgba(255,255,255,.74)}
.crumbs{font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.72);margin-bottom:22px}
/* тап-цель крошки: отрицательный margin гасит прирост высоты, вёрстка не едет */
.crumbs a{display:inline-block;padding:9px 0;margin:-9px 0}
.crumbs a:hover{color:#fff}

/* этапы / таймлайн */
.steps{display:grid;gap:0;margin-top:44px;border-top:1px solid var(--line)}
.step{display:grid;grid-template-columns:88px minmax(0,1fr) minmax(0,1.1fr);gap:clamp(14px,2.4vw,40px);padding:clamp(22px,2.6vw,38px) 0;border-bottom:1px solid var(--line);align-items:start}
.step__n{font-size:14px;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.step h3{font-size:clamp(21px,2vw,30px);font-weight:300;letter-spacing:-.02em}
.step p{font-size:15px;color:var(--ink-soft);margin:0}
@media (max-width:820px){.step{grid-template-columns:52px minmax(0,1fr)}.step p{grid-column:1/-1}}

/* аккордеон */
.acc{border-top:1px solid var(--line);margin-top:36px}
.acc__it{border-bottom:1px solid var(--line)}
.acc__h{width:100%;display:flex;align-items:center;justify-content:space-between;gap:20px;padding:24px 0;background:none;border:0;cursor:pointer;text-align:left;font-size:clamp(18px,1.9vw,26px);font-weight:300;letter-spacing:-.02em}
/* Крутим ВНУТРЕННИЙ path, а не сам <svg>: повёрнутый на 45° элемент 20×20
   получает бокс 28,3×28,3 и вылезал на 4 px за правый край кнопки
   (ЗА-РОДИТЕЛЯ-ВПРАВО + ТЕКСТ-ОБРЕЗАН на всех аккордеонах). */
.acc__h svg{width:20px;height:20px;flex:none}
.acc__h svg *{fill:none;stroke:currentColor;stroke-width:1.2}
.acc__h svg path{transform-box:fill-box;transform-origin:center;transition:transform .5s var(--ease)}
.acc__it.is-open .acc__h svg path{transform:rotate(45deg)}
/* закрытая панель не просто обрезана по высоте, а невидима: иначе её списки
   геометрически лежали поверх следующих заголовков (НАЛЕЗАНИЕ-ТЕКСТА)
   и оставались доступны скринридеру и табу */
.acc__p{overflow:hidden;height:0;visibility:hidden}
.acc__it.is-open .acc__p{visibility:visible}
.acc__p>div{padding:0 0 26px;max-width:min(70ch,var(--grid-measure));color:var(--ink-soft);font-size:15.5px}
.on-dark .acc,.slab--night .acc{border-top-color:var(--line-dark)}
.on-dark .acc__it,.slab--night .acc__it{border-bottom-color:var(--line-dark)}
.on-dark .acc__p>div,.slab--night .acc__p>div{color:rgba(255,255,255,.68)}
.acc__p ul{margin:12px 0 0;padding-left:18px;display:grid;gap:7px}

/* цифры-счётчики строкой */
.statline{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,3vw,46px)}
@media (max-width:900px){.statline{grid-template-columns:repeat(2,minmax(0,1fr))}}
.stat__n{font-size:clamp(40px,5.4vw,84px);font-weight:150;letter-spacing:-.05em;line-height:.94}
.stat__c{font-size:14px;color:var(--ink-soft);margin-top:10px;max-width:22ch}
.on-dark .stat__c{color:rgba(255,255,255,.6)}

/* карта-заглушка.
   Схема лежит фоном с `cover`, а не отдельным <svg preserveAspectRatio="slice">:
   при узком экране слайс растягивал внутренние <rect>/<path> до 893 px, и они
   вылезали за вьюпорт (обрезались, но геометрия ломалась). Фон кадрируется
   браузером и ничего наружу не выносит. */
.mapbox{position:relative;aspect-ratio:16/8;background:var(--fog-2) center/cover no-repeat;overflow:hidden;border:1px solid var(--line)}
.mapbox__art{position:absolute;inset:0;background:center/cover no-repeat;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 500'%3E%3Crect width='1000' height='500' fill='%23eceae6'/%3E%3Cg stroke='rgba(13,13,14,.1)' stroke-width='1' fill='none'%3E%3Cpath d='M0 90 H1000 M0 180 H1000 M0 270 H1000 M0 360 H1000 M0 450 H1000'/%3E%3Cpath d='M110 0 V500 M250 0 V500 M390 0 V500 M530 0 V500 M670 0 V500 M810 0 V500 M950 0 V500'/%3E%3C/g%3E%3Cpath d='M120 300 C200 200 320 160 430 190 C520 214 560 180 640 200 C740 224 820 200 900 240 L900 420 L120 420 Z' fill='rgba(13,13,14,.06)' stroke='rgba(13,13,14,.22)' stroke-width='1.4'/%3E%3Cpath d='M290 250 C360 210 430 250 470 230' fill='none' stroke='rgba(164,105,58,.55)' stroke-width='1.4' stroke-dasharray='6 6'/%3E%3Cpath d='M290 250 C420 300 620 300 760 260' fill='none' stroke='rgba(164,105,58,.55)' stroke-width='1.4' stroke-dasharray='6 6'/%3E%3C/svg%3E")}
.mapbox__pin{position:absolute;transform:translate(-50%,-100%);display:flex;flex-direction:column;align-items:center;gap:6px;font-size:12.5px;letter-spacing:.06em}
.mapbox__pin i{width:11px;height:11px;border-radius:50%;background:var(--clay);box-shadow:0 0 0 6px rgba(164,105,58,.2);display:block;order:2}
@media (max-width:700px){.mapbox{aspect-ratio:4/5}}

/* сертификаты */
.certs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(14px,2vw,26px);margin-top:38px}
@media (max-width:900px){.certs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.cert{border:1px solid var(--line);padding:26px 22px;display:flex;flex-direction:column;gap:12px;min-height:190px}
/* Было: hyphens:auto + break-word — «лесопользо-вание» рвалось посреди слова.
   Слово рвать нельзя (правка владельца), поэтому на узком экране карточки
   встают в одну колонку, и длинному слову хватает ширины целиком. */
.cert b{font-size:17px;font-weight:400}
@media (max-width:560px){.cert{padding:20px 16px;min-height:0}.certs{grid-template-columns:minmax(0,1fr)}}
.cert p{font-size:13.5px;color:var(--ink-soft);margin:0}
.on-dark .cert,.slab--night .cert{border-color:var(--line-dark)}
.on-dark .cert p,.slab--night .cert p{color:rgba(255,255,255,.66)}

/* прочее */
.rule{height:1px;background:var(--line);border:0;margin:0}
.on-dark .rule,.slab--night .rule{background:var(--line-dark)}
.stack-sm>*+*{margin-top:14px}
.stack>*+*{margin-top:clamp(20px,2.4vw,34px)}
/* запас под выносные элементы — иначе overflow:hidden срезает «д», «ц», «у» */
.split-line{display:block;overflow:hidden;padding-bottom:.1em;margin-bottom:-.1em}

/* ---------- строки заголовка задаём МЫ, а не метрики шрифта ----------
   Раньше строки крупных заголовков считал SplitType по фактической раскладке.
   Он отрабатывает сразу после парсинга, а веб-шрифт (font-display:swap)
   приезжает позже — строки разбивались по метрикам СИСТЕМНОГО шрифта.
   На macOS/iOS фолбэк (SF) заметно уже Inter Tight, поэтому после подмены
   шрифта строка переставала влезать: «Панорама / во / всю длину»,
   «Большая / идея / на скромном пятн…», «Автономный / контур».
   Теперь каждая строка — отдельный .hline с white-space:nowrap, а JS
   подгоняет КЕГЕЛЬ так, чтобы самая длинная строка влезла в контейнер.
   Разбиение больше не зависит ни от шрифта, ни от момента его загрузки. */
.hline{display:block;white-space:nowrap}
/* аварийный клапан: если даже на минимальном кегле строка не влезает
   (сверхузкий экран / огромный системный шрифт) — разрешаем обычный перенос
   по словам, но по-прежнему без разрыва слова и без дефисов */
[data-lines].is-loose .hline{white-space:normal}
.hline:empty{display:none}
.tolist{display:grid;gap:12px;list-style:none;margin:0;padding:0;font-size:15.5px;color:var(--ink-soft)}
.tolist li{display:flex;gap:12px;align-items:flex-start}
.tolist svg{width:16px;height:16px;flex:none;margin-top:4px;color:var(--clay)}
.tolist svg *{fill:none;stroke:currentColor;stroke-width:1.6}

.topbtn{position:fixed;right:20px;bottom:20px;z-index:850;width:46px;height:46px;display:flex;align-items:center;justify-content:center;background:var(--ink);color:#fff;border:0;cursor:pointer;opacity:0;pointer-events:none;transition:opacity .4s var(--ease),transform .4s var(--ease)}
.topbtn.is-on{opacity:1;pointer-events:auto}
.topbtn:hover{transform:translateY(-3px)}
.topbtn svg{width:16px;height:16px}
.topbtn svg *{fill:none;stroke:currentColor;stroke-width:1.5}

/* ---------- тач: те же микровзаимодействия, но по касанию ----------
   Единственный эффект, у которого на телефоне НЕТ прямого аналога, — ховер.
   Он не отключается, а переезжает на касание: JS вешает .is-tap и держит его
   не меньше длительности той же самой анимации на десктопе (см. site.js),
   :active оставлен вторым путём — на случай выключенного JS.
   Набор эффектов и их параметры идентичны ховер-версии. */
@media (hover:none){
  /* серую системную вспышку заменяем нашей же анимацией */
  a,button,.pcard,.roomcard,.chip{-webkit-tap-highlight-color:transparent}

  .btn:active::before,.btn.is-tap::before{transform:scaleY(1);transform-origin:top}
  .btn:active,.btn.is-tap{transform:translateY(-2px);color:#fff;border-color:var(--clay)}
  .btn:active svg,.btn.is-tap svg{transform:translate(3px,-3px)}
  .on-dark .btn:active,.on-dark .btn.is-tap{color:#fff;border-color:var(--clay)}

  .pcard:active,.pcard.is-tap{transform:translateY(-6px);box-shadow:0 24px 60px -30px rgba(0,0,0,.5)}
  .pcard:active .pcard__ph img,.pcard.is-tap .pcard__ph img{transform:scale(1.06)}

  .roomcard:active img,.roomcard.is-tap img{transform:scale(1.05);will-change:transform}

  .chip:active,.chip.is-tap{border-color:var(--ink)}
  .nav a:active,.nav a.is-tap{opacity:1}
  .nav a:active::after,.nav a.is-tap::after{transform:scaleX(1);transform-origin:left}
  .foot a:active,.foot a.is-tap,.crumbs a:active,.crumbs a.is-tap{color:#fff}
  .topbtn:active,.topbtn.is-tap{transform:translateY(-3px)}
  .acc__h:active,.acc__h.is-tap{opacity:.7}
  .logo svg{transition:transform .45s var(--ease)}
  .logo.is-tap svg{transform:translateY(-2px)}
  .mobmenu a{transition:opacity .5s var(--ease),transform .6s var(--ease),color .3s}
  .mobmenu a.is-tap{color:var(--clay)}
}

/* reduced motion.
   Акты и коронный блок и без того лежат в потоке (правка 06.08) — здесь
   осталось только погасить остаточную анимацию и развернуть горизонтальную
   ленту в обычную прокрутку. */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .act{opacity:1!important;transform:none!important}
  .curtain{display:none}
  .scrollhint{display:none}
  .figures .fig{opacity:1}
  .planact{height:auto;min-height:0;padding:10dvh 0}
  .planact__inner{position:relative;inset:auto;flex-direction:column;gap:24px}
  .planact__data{position:relative;inset:auto;padding:24px var(--pad)}
  .pl-price,.pl-tile{opacity:1!important}
  .hscroll{height:auto;padding:8dvh 0}
  .hscroll__track{overflow-x:auto;transform:none!important}
}

/* ---------- мобильная липкая кнопка «лёгкого входа» ---------- */
.stickycta{position:fixed;left:0;right:0;bottom:0;z-index:860;display:none;
  padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px));
  background:rgba(255,255,255,.94);backdrop-filter:blur(12px) saturate(1.2);
  box-shadow:0 -1px 0 var(--line),0 -14px 34px -22px rgba(0,0,0,.5);
  transform:translateY(110%);transition:transform .45s var(--ease)}
.stickycta.is-on{transform:none}
.stickycta a{display:flex;width:100%;justify-content:center;padding:14px 16px}
.stickycta small{display:block;text-align:center;font-size:11.5px;color:var(--ink-soft);margin-top:6px;line-height:1.35}
@media (max-width:900px){
  /* тап-цели: логотип и пункты подвала — самостоятельные ссылки, им нужно >= 40 px */
  .logo{min-height:44px}
  .foot ul{gap:2px}
  .foot li{min-height:40px;display:flex;align-items:center}
  .foot li>a{display:flex;align-items:center;align-self:stretch;width:100%}
  .stickycta{display:block}
  .topbtn{bottom:calc(108px + env(safe-area-inset-bottom,0px));width:40px;height:40px;right:12px;opacity:0;}
  .topbtn.is-on{opacity:.88}
  .foot{padding-bottom:calc(96px + env(safe-area-inset-bottom,0px))}
  .scrollhint{bottom:12px}
}
.is-menu .stickycta{transform:translateY(110%)}

/* ---------- добивки ---------- */
.is-menu .hdr{color:#fff}
.is-menu .hdr::before{opacity:0}
@media (max-width:760px){
  .pl-tile .num{font-size:clamp(20px,5.4vw,30px);white-space:nowrap}
  .pl-tile{padding:12px;aspect-ratio:1/.9}
  .planact__data{padding:calc(var(--header-h) + 2vh) var(--pad) 4vh}
  .pl-price .num{font-size:clamp(30px,9vw,52px)}
}
/* липкая кнопка «лёгкого входа» занимает низ экрана — плитки закреплённого
   блока «дом → план» уезжали под неё */
@media (max-width:900px){
  .planact__data{padding-bottom:calc(104px + env(safe-area-inset-bottom,0px))}
}

/* ---------- Загрузочная заставка ЛОНГХАУС (добавлена 31.07 по решению
   владельца: фон загрузки страниц несёт имя компании, а не пустую плиту) --- */
.boot{
  position:fixed;inset:0;z-index:9995;background:var(--ink);
  display:grid;place-items:center;pointer-events:none;
  transition:opacity .6s cubic-bezier(.22,1,.36,1),visibility .6s;
}
.boot.is-done{opacity:0;visibility:hidden}
.boot__word{
  color:var(--paper);font-weight:280;
  font-size:clamp(24px,3.6vw,50px);letter-spacing:.36em;padding-left:.36em;
  display:inline-flex;text-transform:uppercase;
}
.boot__word i{
  font-style:normal;opacity:0;transform:translateY(12px);
  animation:lhBootIn .65s cubic-bezier(.22,1,.36,1) forwards;
}
.boot__word i:nth-child(1){animation-delay:.06s}
.boot__word i:nth-child(2){animation-delay:.13s}
.boot__word i:nth-child(3){animation-delay:.20s}
.boot__word i:nth-child(4){animation-delay:.27s}
.boot__word i:nth-child(5){animation-delay:.34s}
.boot__word i:nth-child(6){animation-delay:.41s}
.boot__word i:nth-child(7){animation-delay:.48s}
.boot__word i:nth-child(8){animation-delay:.55s}
/* девятая буква нужна английской версии: LONGHOUSE (9) против ЛОНГХАУС (8).
   На RU-страницах правило просто не находит элемент. */
.boot__word i:nth-child(9){animation-delay:.62s}
@keyframes lhBootIn{to{opacity:1;transform:translateY(0)}}
@media (prefers-reduced-motion: reduce){
  .boot{transition:none}
  .boot__word i{animation:none;opacity:1;transform:none}
}

/* ══════════════ МЯГКИЕ СТЫКИ ПОЛНОЭКРАННЫХ КАДРОВ (правка 12.08) ══════════════
   ФИДБЭК: «блоки резко обрываются», «белая полоса внизу блока», «срез — так не
   должно быть». Секция с фоновым фото упиралась в соседнюю плиту прямой линейкой:
   на стыке фото/белое это читается как обрубленная картинка, а не как переход.

   РЕЦЕПТ (единый по всему сайту, применён ко всем полноэкранным кадрам):
   1) высота кадра — гибкая, почти в экран (min-height + svh), без жёсткого потолка;
   2) поверх последних ~13 % высоты лежит полоса, растворяющая фото в ЦВЕТ
      СОСЕДНЕЙ секции. Цвет обязан совпадать с фоном соседа — иначе на месте
      одного шва появляется второй.
   ГДЕ ЖИВЁТ ПОЛОСА: нижняя — в ::before СЛЕДУЮЩЕЙ секции, вынесенном вверх
   отрицательным top. Так цвет градиента берётся из фона той же самой секции,
   и рассинхрона «градиент до #fff, а плита #eceae6» не бывает по построению.
   Верхняя — в ::before самого кадра, с цветом ПРЕДЫДУЩЕЙ секции.
   Обе полосы pointer-events:none и не участвуют в раскладке. */
:root{
  --seam:clamp(88px,13vh,190px);      /* растворение низа кадра */
  --seam-top:clamp(64px,9vh,140px);   /* растворение верха кадра */
}
/* короткий ландшафт: экран 400-520 px, полоса в 13vh съела бы текст */
@media (max-height:560px) and (orientation:landscape){
  :root{--seam:clamp(48px,9vh,80px);--seam-top:clamp(40px,7vh,64px)}
}

/* ---------- НИЗ КАДРА → следующая плита ---------- */
.phero + .slab::before,
.stillshot + .slab::before,
.slab--flush + .slab::before{
  content:"";position:absolute;left:0;right:0;top:calc(var(--seam) * -1);height:var(--seam);
  z-index:5;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(255,255,255,0) 0%,rgba(255,255,255,.05) 30%,rgba(255,255,255,.20) 52%,
    rgba(255,255,255,.50) 72%,rgba(255,255,255,.83) 88%,var(--paper) 100%)}
/* та же полоса, но в тон --fog-2 (#eceae6) */
.phero + .slab--fog::before,
.stillshot + .slab--fog::before,
.slab--flush + .slab--fog::before,
.phero + .planact::before,
.stillshot + .planact::before,
.slab--flush + .planact::before{
  content:"";position:absolute;left:0;right:0;top:calc(var(--seam) * -1);height:var(--seam);
  z-index:5;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(236,234,230,0) 0%,rgba(236,234,230,.05) 30%,rgba(236,234,230,.20) 52%,
    rgba(236,234,230,.50) 72%,rgba(236,234,230,.83) 88%,var(--fog-2) 100%)}
/* и в тон --night (#0a0a0b) */
.phero + .slab--night::before,
.stillshot + .slab--night::before,
.slab--flush + .slab--night::before{
  background:linear-gradient(180deg,
    rgba(10,10,11,0) 0%,rgba(10,10,11,.05) 30%,rgba(10,10,11,.20) 52%,
    rgba(10,10,11,.50) 72%,rgba(10,10,11,.83) 88%,var(--night) 100%)}
/* .slab--fadein уже несёт собственную (более длинную) полосу входа в тёмное —
   не даём общему правилу её перебить */
.slab--fadein::before{top:-14vh;height:14vh;z-index:5;
  background:linear-gradient(180deg,rgba(10,10,11,0),rgba(10,10,11,.55) 55%,var(--night))}

/* ---------- ВЕРХ КАДРА ← предыдущая плита ---------- */
.slab + .stillshot::before,
.slab + .slab--flush .fullshot::before{
  content:"";position:absolute;left:0;right:0;top:0;height:var(--seam-top);
  z-index:2;pointer-events:none;
  background:linear-gradient(180deg,
    var(--paper) 0%,rgba(255,255,255,.83) 14%,rgba(255,255,255,.50) 32%,
    rgba(255,255,255,.20) 54%,rgba(255,255,255,.05) 76%,rgba(255,255,255,0) 100%)}
.slab--fog + .stillshot::before,
.slab--fog + .slab--flush .fullshot::before{
  background:linear-gradient(180deg,
    var(--fog-2) 0%,rgba(236,234,230,.83) 14%,rgba(236,234,230,.50) 32%,
    rgba(236,234,230,.20) 54%,rgba(236,234,230,.05) 76%,rgba(236,234,230,0) 100%)}
/* кадр сразу за героем (projects.html): оба блока — фото, поэтому продлеваем
   вниз тёмную вуаль героя, а не заливаем светлым */
.phero + .stillshot::before{
  content:"";position:absolute;left:0;right:0;top:0;height:calc(var(--seam-top) * 1.9);
  z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(8,9,10,.90) 0%,rgba(8,9,10,.72) 18%,rgba(8,9,10,.46) 42%,rgba(8,9,10,.20) 68%,rgba(8,9,10,0) 100%)}
/* .slab--fadein доводит светлую сцену до --night, но следом идёт СНИМОК, который
   светлее чистого #0a0a0b — на границе оставалась ступенька. Продлеваем ноту
   ночи внутрь кадра, как на стыке двух фото в projects.html. */
.slab--fadein .fullshot::before{content:"";position:absolute;left:0;right:0;top:0;
  height:calc(var(--seam-top) * 1.6);z-index:2;pointer-events:none;
  background:linear-gradient(180deg,var(--night) 0%,rgba(10,10,11,.78) 22%,rgba(10,10,11,.44) 50%,rgba(10,10,11,.16) 76%,rgba(10,10,11,0) 100%)}
/* текст кадра обязан лежать ВЫШЕ обеих полос */
.fullshot__scrim{z-index:1}

/* ---------- надзаголовок вместо хлебных крошек ----------
   Крошки «Главная — Раздел» сняты по правке владельца 12.08: в шапке и так есть
   активный пункт меню, а тире с дублем «Главная» читалось как служебная строка.
   Остался чистый eyebrow в стиле сайта (uppercase, разрядка), без тега h*. */
.phero .eyebrow{color:rgba(255,255,255,.66);margin:0 0 clamp(14px,1.8vw,24px)}

/* ---------- 12.08.2026 — правки по фидбэку владельца (мобильные CTA) ----------
   1) Кнопка в подвале сливалась с фоном. Подвал тёмный (.foot{background:var(--night)}),
      но правило белой кнопки было написано только для .on-dark — в подвале .btn
      оставалась чернильной на почти чёрном. Даём подвалу тот же контраст.
   2) На телефоне одиночная CTA-кнопка стояла узкой полосой, прижатой влево.
      Единый приём по сайту: на узком экране кнопка тянется во всю ширину колонки —
      так же, как липкая кнопка внизу экрана. */
.foot .btn{background:#fff;color:var(--ink);border-color:#fff}
.foot .btn--ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.55)}
.foot .btn:hover,.foot .btn:focus-visible{color:#fff;border-color:var(--clay)}

@media (max-width:600px){
  .hero-cta,.hero-cta__row,.foot__cta,.cta{width:100%}
  .hero-cta>div{width:100%}
  .hero-cta .btn,.foot__cta>.btn,.cta>.btn,.form__body>.btn{
    width:100%;flex:1 1 100%;justify-content:space-between}
}

/* ════════════════════════════════════════════════════════════════════════════
   ЗАКОН ВЛАДЕЛЬЦА 13.08: ФОТО-БЛОК НА ТЕЛЕФОНЕ = ПОЛНЫЙ ЭКРАН
   Дословно: «если я говорю сделать блоки больше — сделай БОЛЬШЕ, чтобы ОДИН
   БЛОК закрывал площадь экрана телефона — одна прокрутка колеса».

   ЧТО БЫЛО (замер 390×844, 13.08):
     .fullshot  — 793 px (94 % экрана): 94svh оставляли снизу полосу чужой
                  секции в 6 % высоты. Главная (2 кадра) и «О компании».
     .stillshot — 810 px (96 %). «Проекты» и «Технология».
     .vidpause  — 675 px (80 %): видеопауза на главной, инлайновая высота
                  clamp(360px,80dvh,860px).

   ЧТО СТАЛО: ровно 100 svh у всех трёх — кадр закрывает экран телефона
   целиком, соседняя секция в него не заглядывает. svh, а не dvh: при
   выдвижении/сворачивании панелей мобильного браузера высота не скачет и
   кадр не режется. Первой строкой — vh-фолбэк для движков без svh.

   .vidpause — высота задана в разметке инлайном, перебить её можно только
   !important; сам инлайн НЕ удалён — он остаётся фолбэком для десктопа,
   альбома и движков без svh.

   Границы: max-width:900px + portrait — телефоны и планшет в портрете.
   Десктоп и альбомный телефон (там своё правило
   @media (max-height:560px) and (orientation:landscape)) не затронуты.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px) and (orientation:portrait){
  .fullshot{height:100vh;height:100svh}
  .stillshot{min-height:100vh;min-height:100svh}
  .vidpause{height:100vh !important;height:100svh !important}
}
