/* ============================================================
   Белый лист, Arial Narrow, чёрные кнопки. Цвет дают голова и работы.
   ============================================================ */

/* Arial Narrow есть на Mac и на Windows с Office. Остальным (телефоны, Linux) отдаём свободный шрифт
   с теми же пропорциями: Arimo, сжатый по ширине до 82% — ровно как Arial Narrow относительно Arial. */
@font-face{ font-family:'Arimo Narrow PN'; font-weight:400; font-display:block; src:url('../assets/fonts/narrow-cyrillic-400.woff2') format('woff2'); unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face{ font-family:'Arimo Narrow PN'; font-weight:700; font-display:block; src:url('../assets/fonts/narrow-cyrillic-700.woff2') format('woff2'); unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face{ font-family:'Arimo Narrow PN'; font-weight:400; font-display:block; src:url('../assets/fonts/narrow-latin-400.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Arimo Narrow PN'; font-weight:700; font-display:block; src:url('../assets/fonts/narrow-latin-700.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face{ font-family:'Arimo Narrow PN'; font-weight:400; font-display:block; src:url('../assets/fonts/narrow-latin-ext-400.woff2') format('woff2'); unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face{ font-family:'Arimo Narrow PN'; font-weight:700; font-display:block; src:url('../assets/fonts/narrow-latin-ext-700.woff2') format('woff2'); unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
/* Roboto — кнопки и тексты. Переменный шрифт: два файла (кириллица и латиница) на все насыщенности. Лицензия OFL — assets/fonts/OFL-Roboto.txt */
@font-face{ font-family:'Roboto PN'; font-weight:100 900; font-display:swap; src:url('../assets/fonts/roboto-cyrillic.woff2') format('woff2'); unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }
@font-face{ font-family:'Roboto PN'; font-weight:100 900; font-display:swap; src:url('../assets/fonts/roboto-latin.woff2') format('woff2'); unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }

:root{
  --u:min(1vw, 1.5vh);                 /* единица макета: 1% ширины, но не больше 1,5% высоты — на широких экранах всё считается от высоты */
  /* ---- значения по умолчанию — в css/tokens.css (шрифты, отступы, кнопки, цвета). Админка кладёт поверх множители: ---- */
  --k-title:1; --k-text:1; --k-btn:1;   /* размер заголовков, текста, кнопок — множители (100% в админке = как в tokens.css) */
  --r-btn:.5; --r-card:.12;             /* скругления — доля высоты: у кнопки .5 — капсула */
  /* ---- производные ---- */
  --fg:var(--ink);                      /* текст/основной: текст, логотип, обводка */
  --mute:var(--mute-l);                 /* текст/вторичный */
  --on-fg:var(--paper);                 /* текст на кнопке, залитой цветом текста (наведение на контурную) */
  --glow:var(--glow-light);             /* свечение выбранной карточки */
  --line:rgba(0,0,0,.14);
  --pill:rgba(0,0,0,.07);
  --ease:cubic-bezier(.2,.9,.2,1);
  --spring:cubic-bezier(.18,1.32,.32,1);
  --pad-top:12px;                        /* уточняется скриптом: на главной шапка просторная, внутри сайта — компактная */
  --btn-h:calc(var(--button-height) * var(--k-btn));
  --btn-fs:calc(var(--button-fs) * var(--k-btn));
  --btn-px:calc(var(--button-px) * var(--k-btn));
  --corner:clamp(120px, calc(var(--u) * 19), 380px);       /* кружок с головой в каталоге и кейсе */
  --corner-r:var(--pad-x);                                  /* его отступ справа — по правому краю кнопок шапки */
  --corner-b:clamp(12px, calc(var(--u) * 1.6), 36px);
  --hdr:96px;                            /* высота шапки — уточняется скриптом */
  --fw:240px;                            /* ширина папки; задаётся там, где папка стоит */
  color-scheme:light;
  /* зерно: бумага полароида, плёнка снимка, затемнение под карточкой */
  --noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1.7 -.5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* в кейсе голова не должна мешать чтению: кружок меньше и прижат к краю (в каталоге головы нет, кружок там же — погасший) */
body[data-view="case"],body[data-view="work"]{ --corner:clamp(96px, calc(var(--u) * 11), 200px); --corner-r:clamp(12px, calc(var(--u) * 2), 40px); }
/* тёмный фон проекта в каталоге и в шапке кейса: интерфейс становится белым */
body[data-tone="dark"]{ --fg:var(--ink-dark); --on-fg:var(--ink); --mute:rgba(244,246,246,.7); --mute:color-mix(in srgb, var(--ink-dark) 70%, transparent); --line:rgba(255,255,255,.26); --pill:rgba(255,255,255,.18); --glow:var(--ink-dark); }
/* Стекло дока (Figma: «Панель (телефон)»): панель кнопок, кружок архива и кружок головы — одной подложкой везде.
   На ровном фоне (главная, каталог) — основной цвет на 10%; где под доком едет содержимое (кейс, архив) — матовое
   светлое стекло с размытием. Объявлено на body: там же тон фона меняет --fg */
body{ --dock-bg:color-mix(in srgb, var(--fg) 10%, transparent); --dock-fx:none; --dock-ring:none; }
body[data-view="case"],body[data-view="archive"]{ --dock-bg:color-mix(in srgb, var(--paper) 72%, transparent); --dock-fx:blur(20px) saturate(1.6); --dock-ring:inset 0 0 0 1px color-mix(in srgb, var(--fg) 8%, transparent); }

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{ margin:0; background:var(--paper); color:var(--fg); font:var(--w-text) calc(var(--fs-body) * var(--k-text))/var(--lh-body) var(--font-text); -webkit-font-smoothing:antialiased; transition:color .35s; }
body[data-view="hero"]{ overflow:hidden; height:100vh; height:100dvh; }
a{ color:inherit; }
img{ max-width:100%; }
button{ font:inherit; color:inherit; }
[hidden]{ display:none !important; }
.visually-hidden{ position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
:focus-visible{ outline:2px solid var(--fg); outline-offset:3px; }
.skip-link{ position:fixed; left:16px; top:-64px; z-index:100; padding:10px 18px; border-radius:999px; background:#000; color:#fff; text-decoration:none; transition:top .2s; }
.skip-link:focus{ top:16px; }
.noscript{ position:fixed; inset:auto 16px 16px; z-index:70; padding:16px; background:#000; color:#fff; border-radius:16px; }
/* Текст страницы для поисковиков и посетителей без JavaScript (js/seo.js). Со скриптами его нет: сайт убирает блок сразу,
   а до того он скрыт (браузер, который не знает про (scripting), прячет его как текст для экранного диктора) */
.seo-static{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
@media (scripting: enabled){ .seo-static{ display:none; } }
@media (scripting: none){
  body[data-view]{ overflow:visible; height:auto; }
  .hero{ position:static; }
  .stage,.loader,.burst,.brainph,.veil,.subs,.arch-btn,.topbar,.logo,.pol-a11y,.skip-link{ display:none !important; }
  .noscript{ position:static; max-width:720px; margin:0 auto 48px; }
  .seo-static{ position:static; width:auto; height:auto; overflow:visible; clip-path:none; white-space:normal; box-sizing:border-box; max-width:760px; margin:0 auto; padding:40px 20px 48px; }
  .seo-static h1{ font-family:var(--font); font-weight:400; font-size:clamp(36px, 7vw, 64px); line-height:1.02; margin:28px 0 16px; text-wrap:balance; }
  .seo-static h2{ font-family:var(--font); font-weight:400; font-size:clamp(26px, 4vw, 36px); line-height:1.08; margin:44px 0 12px; }
  .seo-static h3{ font:inherit; font-weight:500; margin:24px 0 4px; }
  .seo-static p,.seo-static li{ max-width:68ch; }
  .seo-static nav{ color:var(--mute); }
  .seo-static figure{ margin:24px 0; }
  .seo-static img{ display:block; height:auto; border-radius:16px; }
  .seo-static dl{ display:grid; grid-template-columns:max-content 1fr; gap:6px 20px; }
  .seo-static dt{ color:var(--mute); }
  .seo-static dd{ margin:0; }
}

/* ---------- фон «в стиле проекта» ---------- */
.bg{ position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.bg-layer{ position:absolute; inset:0; isolation:isolate; opacity:0; transition:opacity .6s ease; background-color:var(--c,#fff); }
.bg-layer.is-on{ opacity:1; }
/* размытая обложка проекта поверх его цвета. На тёмном фоне она только затемняет цвет, на светлом — только высветляет:
   так белый (или чёрный) текст интерфейса остаётся читаемым, какой бы ни была картинка */
.bg-layer::before{ content:''; position:absolute; inset:0; background:var(--img, none) center/cover no-repeat; opacity:.62; mix-blend-mode:multiply; }   /* картинка уже размыта (js/theme.js) — без filter */
.bg-layer[data-tone="light"]::before{ mix-blend-mode:screen; opacity:.5; }
.bg-layer::after{ content:''; position:absolute; inset:0; background:radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(0,0,0,.2)); }
.bg-layer[data-tone="light"]::after{ background:radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(255,255,255,.3)); }

/* полоски цвета страницы у верхнего и нижнего края (js/tint.js): по ним Safari 26 на iPhone красит полосы над страницей
   и под ней. 12 px — чтобы закрыть точку в 8 px от края, где Safari ищет цвет, и не считаться рамкой (≤ 10 px).
   Видны только на iPhone и iPad: там их закрывают строка состояния и панель браузера. Под затемнением полароида (z 64) */
.tint{ position:fixed; left:0; right:0; z-index:63; height:12px; pointer-events:none; display:none; }
.tint--top{ top:0; }
.tint--bottom{ bottom:0; }
@supports (-webkit-touch-callout: none){ @media (orientation:portrait){ .tint{ display:block; } } }      /* в ландшафте на iPhone строки состояния нет — полоска была бы видна */

/* ---------- шапка: логотип по центру, кнопки справа ---------- */
.topbar{ position:fixed; inset:0 0 auto 0; z-index:40; display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:16px; min-height:var(--hdr); padding:var(--pad-top) var(--pad-x) 0; pointer-events:none; color:var(--fg); }
body:not([data-view="hero"]) .topbar{ padding-bottom:var(--pad-bot, var(--pad-top)); }      /* --pad-bot: в каталоге шапка снизу плотнее (js/app.js, layout) */
.topbar > *{ pointer-events:auto; }
/* в кейсе под шапкой подложка, чтобы текст и картинки не просвечивали при прокрутке: цвета проекта над его шапкой, белая — над листом */
.topbar::before{ content:''; position:absolute; inset:0; z-index:-1; pointer-events:none; opacity:0; background:var(--bar-bg, rgba(255,255,255,.9)); -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px); transition:opacity .3s; }
body[data-view="case"].is-scrolled .topbar::before,body[data-view="archive"].is-scrolled .topbar::before{ opacity:1; }
/* в каталоге шапка без подложки: логотип и кнопки лежат прямо на фоне проекта */
.topbar-side{ grid-column:1; justify-self:start; display:flex; gap:2px; }
/* Логотип — свой слой. На главной он лежит под головой (z-index ниже сцены): голова может его перекрывать,
   когда её тянут вверх или она подпрыгивает. Внутри сайта он часть шапки и стоит над содержимым. Место задаёт скрипт. */
.logo{ position:fixed; z-index:0; left:calc(50% - var(--logo-w,27vw) / 2); top:var(--logo-y, var(--pad-top)); display:flex; justify-content:center; align-items:center; width:var(--logo-w,27vw); text-decoration:none; color:var(--fg); transition:color .45s ease; }
body:not([data-view="hero"]) .logo{ z-index:42; }
.logo-mark{ display:block; width:100%; aspect-ratio:var(--logo-ar, 393/95); visibility:hidden; background:currentColor; -webkit-mask:var(--logo-url) center/contain no-repeat; mask:var(--logo-url) center/contain no-repeat; }
.logo.is-ready .logo-mark{ visibility:visible; }      /* до загрузки содержимого на месте логотипа пусто, а не чёрная плашка */
.logo.is-text .logo-mark{ font-family:var(--font); aspect-ratio:auto; background:none; -webkit-mask:none; mask:none; font-size:calc(var(--logo-w,27vw) * .15); line-height:1; text-align:center; white-space:nowrap; }
.is-switching .topbar{ transition:min-height .5s var(--ease), padding .5s var(--ease); }
.is-switching .logo{ transition:width .5s var(--ease), left .5s var(--ease), top .5s var(--ease); }
.topnav{ grid-column:3; justify-self:end; display:flex; align-items:center; gap:var(--gap-btn); }
.is-switching .topnav{ transition:transform .5s var(--ease); }
/* кнопки (Figma: «Кнопка»): Основная — тёмная на любом фоне; Контур — обводка 1 px цветом текста; Светлая; Маленькая */
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:.5em; height:var(--btn-h); padding:0 var(--btn-px); border:0; border-radius:calc(var(--btn-h) * var(--r-btn)); background:var(--btn-bg); color:var(--btn-fg); font:var(--w-btn) var(--btn-fs)/1 var(--font-text); text-decoration:none; white-space:nowrap; cursor:pointer; transition:background-color .2s, color .2s, box-shadow .2s, transform .12s; -webkit-tap-highlight-color:transparent; touch-action:manipulation; }
.btn:active{ transform:scale(.97); }      /* кнопка отвечает на нажатие — на телефоне наведения нет, это единственный отклик */
.btn--line{ background:transparent; color:var(--fg); box-shadow:inset 0 0 0 var(--button-stroke) currentColor; }
.btn--light{ background:var(--btn-light-bg); color:var(--btn-light-fg); }
.btn--sm{ height:calc(var(--button-sm-height) * var(--k-btn)); padding:0 calc(var(--button-sm-px) * var(--k-btn)); }
/* наведение — только там, где оно есть: на телефоне :hover «залипает» после касания, и кнопка остаётся перекрашенной */
@media (hover:hover){
  .btn:hover{ background:color-mix(in srgb, var(--btn-bg) 82%, #fff); }
  .btn.btn--line:hover{ background:var(--fg); color:var(--on-fg); }
  .btn.btn--light:hover{ background:color-mix(in srgb, var(--btn-light-bg) 85%, var(--ink)); }
}
/* голова говорит про кнопку и смотрит на неё — кнопка один раз «кивает» в ответ (js/app.js, pointAtWork) */
.btn.is-nudge{ animation:nudge 1.1s var(--ease) 1; }
@keyframes nudge{ 0%,72%,100%{ transform:none; } 18%{ transform:scale(1.07); } 36%{ transform:scale(.98); } 54%{ transform:scale(1.03); } }
.no-cv [data-cv]{ display:none !important; }
/* до 1280 px три кнопки с крупным логотипом в одну строку не помещаются: на кнопке просто «CV» */
@media (max-width:1279px){ .cv-pre{ display:none; } }
/* лайки выключены (админка → «Лайки»): ни кнопки, ни сердечек на карточках */
.no-likes [data-like],.no-likes .cat-like{ display:none !important; }
/* «Звук» — только если включён в админке; «К голове» — только в каталоге на телефоне; в каталоге «Все работы» не нужна */
.no-sound [data-sound]{ display:none !important; }
.topnav [data-home]{ display:none; }
body[data-view="work"] .topnav [data-t="allWork"]{ display:none; }
/* «Звук»: когда включён, рядом с надписью три столбика; они пляшут, пока голова говорит */
.btn--toggle .eq{ display:none; align-items:flex-end; gap:2px; height:.7em; }
.btn--toggle[aria-pressed="true"] .eq{ display:inline-flex; }
.eq i{ display:block; width:3px; height:100%; background:currentColor; border-radius:1px; transform-origin:50% 100%; transform:scaleY(.4); will-change:transform; }
.eq i:nth-child(2){ transform:scaleY(.8); animation-delay:-.3s; } .eq i:nth-child(3){ transform:scaleY(.55); animation-delay:-.6s; }
.is-speaking .eq i{ animation:eq .9s ease-in-out infinite; }
@keyframes eq{ 0%,100%{ transform:scaleY(.35); } 50%{ transform:scaleY(1); } }
.lang{ display:inline-flex; align-items:center; height:var(--btn-h); padding:0 .45em; border:0; background:none; font:var(--w-btn) var(--btn-fs)/1 var(--font-text); color:var(--mute); cursor:pointer; }
.lang[aria-pressed="true"]{ color:var(--fg); text-decoration:underline; text-underline-offset:.2em; text-decoration-thickness:1px; }

/* ---------- голова ---------- */
.stage{ position:fixed; top:0; left:0; width:100%; height:100%; z-index:1; -webkit-tap-highlight-color:transparent; transition:top .7s var(--ease), left .7s var(--ease), width .7s var(--ease), height .7s var(--ease), border-radius .7s var(--ease); }
.stage canvas{ display:block; width:100% !important; height:100% !important; }
/* каталог и кейс: сцена сжимается в кружок в углу; серый диск проявляется, когда она уже почти доехала */
.stage.is-corner,.corner-probe{ top:calc(100% - var(--corner) - var(--corner-b)); left:calc(100% - var(--corner) - var(--corner-r)); width:var(--corner); height:var(--corner); }
.stage.is-corner{ border-radius:50%; overflow:hidden; background:var(--dock-bg); -webkit-backdrop-filter:var(--dock-fx); backdrop-filter:var(--dock-fx); box-shadow:var(--dock-ring); z-index:35;
  transition:top .7s var(--ease), left .7s var(--ease), width .7s var(--ease), height .7s var(--ease), border-radius .7s var(--ease), background-color .25s linear .4s, opacity .35s ease; }
/* каталог: головы нет — кружок гаснет; из каталога в кейс он проявляется на своём месте в углу. Реплик и «Звука» в каталоге тоже нет */
body[data-view="work"] .stage{ opacity:0; visibility:hidden; pointer-events:none;
  transition:top .7s var(--ease), left .7s var(--ease), width .7s var(--ease), height .7s var(--ease), border-radius .7s var(--ease), opacity .25s ease, visibility 0s linear .25s; }
body[data-view="work"] .subs,body[data-view="work"] [data-sound]{ display:none !important; }
.corner-probe{ position:fixed; visibility:hidden; pointer-events:none; }   /* двойник кружка: по нему голова знает, куда лететь */
.no-webgl .stage{ display:none; }
.glasses-layer{ position:fixed; inset:0; z-index:55; width:100%; height:100%; pointer-events:none; }   /* снятые очки рисуются поверх размытия — резкими */
/* сюда попадает только сообщение, если содержимое сайта не загрузилось; обычная загрузка — без текста и процентов */
.loader{ font-family:var(--font); position:fixed; inset:0; z-index:5; display:grid; place-content:center; gap:4px; padding:0 24px; text-align:center; font-size:clamp(17px, calc(var(--u) * 1.6), 28px); line-height:1.2; pointer-events:none; }
body:not([data-view="hero"]) .loader{ display:none; }
/* Пока качается 3D-движок, на месте мозга — розовое размытое пятно: оно «дышит», а когда движок готов, на его месте
   проступает настоящий мозг (с него начинается сборка головы). Место и размер — доли от рамки головы (--ph-*, их считает раскладка). */
.brainph{ position:fixed; inset:0; z-index:1; pointer-events:none; transition:opacity .3s ease; }
.brainph.is-out{ opacity:0; }
.brainph i{ position:absolute; left:calc(var(--ph-x, 35vw) + var(--ph-w, 30vw) * .5); top:calc(var(--ph-y, 20vh) + var(--ph-h, 40vw) * .28);
  width:calc(var(--ph-w, 30vw) * .66); height:calc(var(--ph-w, 30vw) * .5); margin:calc(var(--ph-w, 30vw) * -.25) 0 0 calc(var(--ph-w, 30vw) * -.33);
  border-radius:50% 50% 46% 46% / 58% 58% 42% 42%; filter:blur(calc(var(--ph-w, 30vw) * .055));
  background:radial-gradient(ellipse at 42% 34%, #ffa6d0 0, #ff63ab 44%, #e23f8c 76%, #bf2a73 100%);
  animation:ph-in .45s ease both, ph-breathe 1.3s ease-in-out .45s infinite alternate; }
@keyframes ph-in{ from{ opacity:0; transform:scale(.6); } to{ opacity:.7; transform:scale(1); } }
@keyframes ph-breathe{ from{ opacity:.7; transform:scale(1); } to{ opacity:.5; transform:scale(1.06); } }
.no-webgl .brainph,.is-preview .brainph{ display:none; }

/* ---------- главный экран ---------- */
.hero{ position:fixed; inset:0; z-index:10; pointer-events:none; }
.burst{ position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }   /* слой под головой: в полёте работы проходят за ней */
.art{ position:absolute; left:0; top:0; display:block; max-width:none; object-fit:contain; transform-origin:50% 50%; filter:drop-shadow(0 14px 22px rgba(0,0,0,.16)) drop-shadow(0 2px 4px rgba(0,0,0,.12)); }
.art.is-print{ border-radius:10px; }
.folders{ position:fixed; inset:0; z-index:14; pointer-events:none; }
.folders .gf{ position:absolute; left:var(--x); top:var(--y); transform:translate(-50%,-50%) rotate(var(--tilt,0deg)); pointer-events:auto; cursor:grab; touch-action:none; transition:transform .55s var(--spring); }
.folders .gf.is-open{ transform:translate(-50%,-50%) rotate(0deg) scale(1.04); z-index:2; }
.folders .gf.is-dragging{ transform:translate(-50%,-50%) rotate(calc(var(--tilt,0deg) * .4)) scale(1.07); transition:transform .25s var(--ease); cursor:grabbing; z-index:3; }
.folders .gf.is-dragging .gf-ground{ opacity:.55; transform:translateY(34%) scale(1.12); }

/* ---------- папка: матовое стекло, внутри работы; при наведении они выезжают ---------- */
.gf{ --gf-back:#D5D9DF; --gf-back2:#C9CED6; --gf-glass:246,247,250; display:block; width:var(--fw); color:var(--fg); text-decoration:none; font-family:var(--font); font-size:clamp(15px, calc(var(--fw) * .078), 26px); line-height:1.12; user-select:none; -webkit-user-select:none; -webkit-user-drag:none; -webkit-tap-highlight-color:transparent; }
.gf:focus-visible{ outline:none; }
.gf:focus-visible .gf-body{ outline:2px solid var(--fg); outline-offset:6px; border-radius:8% / 10%; }
.gf-body{ position:relative; display:block; aspect-ratio:400/318; }
.gf-ground{ position:absolute; left:6%; right:6%; bottom:-7%; height:20%; border-radius:50%; background:rgba(0,0,0,.2); filter:blur(calc(var(--fw) * .045)); opacity:.75; transition:opacity .4s, transform .4s; }
.gf-back{ position:absolute; left:7.5%; right:5%; top:0; bottom:10%; border-radius:6% / 8%; background:linear-gradient(180deg, var(--gf-back), var(--gf-back2)); box-shadow:inset 0 1px 0 rgba(255,255,255,.5); }
/* работы внутри папки — карточки одного размера; закрытая папка прячет их за стеклом и обрезает всё, что выше стенки */
.gf-items{ position:absolute; inset:0; display:block; clip-path:inset(21% 3% 4% 3% round 5%); transition:clip-path .5s var(--ease); }
.gf-item{ position:absolute; left:50%; top:50%; display:block; width:40%; height:auto; max-width:none; aspect-ratio:4/5; object-fit:cover; border:calc(var(--fw) * .016) solid #fff; border-radius:calc(var(--fw) * .05); background:#fff;
  transform:translate(-50%,-50%) translate(calc(var(--fw) * var(--x0,0)), calc(var(--fw) * var(--y0,.05))) rotate(var(--r0,0deg)) scale(.8);
  transition:transform .6s var(--spring) calc(var(--i,0) * 45ms); box-shadow:0 calc(var(--fw) * .012) calc(var(--fw) * .04) rgba(0,0,0,.2); }
.gf-item.is-cut{ object-fit:contain; background:#F1F2F4; padding:calc(var(--fw) * .02); }      /* вырезанная картинка (без фона) — на светлой подложке */
.gf-item.s-l{ --x0:-.13; --y0:.06; --r0:-5deg; --i:1; }
.gf-item.s-c{ --x0:.02; --y0:.03; --r0:2deg; --i:0; }
.gf-item.s-r{ --x0:.15; --y0:.07; --r0:6deg; --i:2; }
.gf-front{ position:absolute; left:0; right:0; top:6.3%; bottom:0; display:block; clip-path:url(#gf-front); transform-origin:50% 100%; transition:transform .55s var(--spring);
  background:linear-gradient(180deg, rgba(var(--gf-glass),.8), rgba(var(--gf-glass),.6)); -webkit-backdrop-filter:blur(calc(var(--fw) * .05)) saturate(1.4); backdrop-filter:blur(calc(var(--fw) * .05)) saturate(1.4); }
.gf-front::after{ content:''; position:absolute; left:9%; right:9%; bottom:8%; height:5.5%; border-top:1px solid rgba(255,255,255,.95); border-bottom:1px solid rgba(255,255,255,.95); box-shadow:0 1px 0 rgba(0,0,0,.05), inset 0 1px 0 rgba(0,0,0,.05); }   /* «губа» папки */
.gf-edge{ position:absolute; left:0; right:0; top:6.3%; bottom:0; width:100%; height:93.7%; overflow:visible; pointer-events:none; transform-origin:50% 100%; transition:transform .55s var(--spring); }
.gf-edge path{ fill:none; vector-effect:non-scaling-stroke; }
.gf-edge .e1{ stroke:rgba(0,0,0,.1); stroke-width:1.5px; }
.gf-edge .e2{ stroke:rgba(255,255,255,.9); stroke-width:1px; transform:translateY(1px); }
.gf-sticker{ position:absolute; display:block; width:23%; height:auto; filter:drop-shadow(1.5px 0 0 #fff) drop-shadow(-1.5px 0 0 #fff) drop-shadow(0 1.5px 0 #fff) drop-shadow(0 -1.5px 0 #fff) drop-shadow(0 2px 3px rgba(0,0,0,.22)); }
.gf-sticker:nth-of-type(1){ left:15%; top:46%; transform:rotate(-7deg); }
.gf-sticker:nth-of-type(2){ right:12%; top:27%; transform:rotate(9deg); }
.gf-title{ display:block; margin-top:.75em; text-align:center; text-wrap:balance; }
.gf-pill{ display:table; margin:.5em auto 0; padding:.26em .8em .3em; border-radius:999px; background:var(--pill); color:var(--mute); font-size:.78em; line-height:1.1; white-space:nowrap; }
/* открытая папка: стенка откидывается, работы выезжают веером */
.gf.is-open .gf-items,.gf--auto:hover .gf-items,.gf--auto:focus-visible .gf-items{ clip-path:inset(-160% -60% 4% -60%); }
.gf.is-open .gf-front,.gf.is-open .gf-edge,.gf.is-open .gf-ghost,.gf--auto:hover .gf-front,.gf--auto:hover .gf-edge,.gf--auto:hover .gf-ghost,.gf--auto:focus-visible .gf-front,.gf--auto:focus-visible .gf-edge,.gf--auto:focus-visible .gf-ghost{ transform:perspective(calc(var(--fw) * 3)) rotateX(-13deg); }
.gf.is-open .s-l,.gf--auto:hover .s-l,.gf--auto:focus-visible .s-l{ transform:translate(-50%,-50%) translate(calc(var(--fw) * -.43), calc(var(--fw) * .03)) rotate(-14deg); }
.gf.is-open .s-c,.gf--auto:hover .s-c,.gf--auto:focus-visible .s-c{ transform:translate(-50%,-50%) translate(calc(var(--fw) * -.04), calc(var(--fw) * -.34)) rotate(3deg); }
.gf.is-open .s-r,.gf--auto:hover .s-r,.gf--auto:focus-visible .s-r{ transform:translate(-50%,-50%) translate(calc(var(--fw) * .44), calc(var(--fw) * -.06)) rotate(10deg); }
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){ .gf-front{ background:rgba(var(--gf-glass),.94); } }
/* Телефон и планшет: стекло папки не размывает «всё, что под ним» (backdrop-filter). Это самый дорогой эффект на
   телефоне — лента папок с ним прокручивается рывками, — и в Safari такое стекло мигает, когда рядом что-то меняется
   (например, печатается реплика головы). Матовость собрана иначе, а выглядит так же:
   — под стеклом лежит размытый двойник нутра папки: задняя стенка и те же работы (.gf-ghost, разметка — js/folders.js).
     Он обрезан по контуру стекла и откидывается вместе с ним; работы в нём — те же .gf-item, их двигают те же
     правила: папка раскрывается — «тени» за стеклом едут следом;
   — настоящие стенка и работы под стеклом не рисуются: их видно только там, где стекла нет (контуры ниже повторяют
     его край с язычком слева, с небольшим заходом под стекло). Закрытая папка — работ не видно, только тени;
     раскрытая — работы выезжают из-за края и по бокам. */
.gf-ghost{ display:none; }
.is-touch .gf-front{ -webkit-backdrop-filter:none; backdrop-filter:none; }
.is-touch .gf-ghost{ display:block; position:absolute; left:0; right:0; top:6.3%; bottom:0; overflow:hidden; overflow:clip; clip-path:url(#gf-front); pointer-events:none; transform-origin:50% 100%; transition:transform .55s var(--spring); }
.is-touch .gf-ghost-in{ position:absolute; left:0; right:0; top:-6.724%; height:106.724%; filter:blur(calc(var(--fw) * .05)) saturate(1.4); }
.is-touch .gf-body > .gf-back{ clip-path:polygon(0 0, 100% 0, 100% 21.67%, 50.29% 21.67%, 46.06% 19.56%, 42.86% 15%, 39.66% 10.44%, 35.43% 8.33%, 0 8.33%); }
.is-touch .gf-items,.is-touch .gf.is-open .gf-items,.is-touch .gf--auto:hover .gf-items,.is-touch .gf--auto:focus-visible .gf-items{
  clip-path:polygon(-60% -160%, 160% -160%, 160% 96%, 99% 96%, 99% 26%, 97.5% 21.3%, 94% 19.5%, 51.5% 19.5%, 47.8% 17.6%, 45% 13.5%, 42.2% 9.4%, 38.5% 7.5%, 6% 7.5%, 2.5% 9.6%, 1% 14%, 1% 96%, -60% 96%); transition:none; }

/* ---------- субтитры: просто текст под головой ---------- */
.subs{ position:fixed; z-index:60; left:var(--subs-x,50%); top:var(--subs-y,80%); width:var(--subs-bw,64vw); transform:translateX(-50%); margin:0; text-align:center; pointer-events:none;
  font:400 var(--subs-size, var(--fs-subs))/var(--lh-narrow) var(--font); text-wrap:balance; color:var(--fg); }
.subs-line{ margin:0; }
/* на главной строка переносится между предложениями, а не посреди фразы (пока предложение помещается целиком) */
body[data-view="hero"] .subs-line .s{ display:inline-block; max-width:100%; }
body[data-view] .subs-line.is-loose .s{ display:inline; }      /* длинная реплика не влезла в свои строки целыми предложениями (js/subtitles.js, _fit) */
/* реплика гаснет целиком: прозрачность меняется у всего блока субтитров (у него слой один и постоянный) */
.subs{ will-change:opacity; }
.subs.is-out{ opacity:0; transition:opacity .45s var(--ease); }
/* слово не рвётся при переносе; буквы проявляются по одной (место под всю реплику занято сразу). Проявляются через
   visibility и цвет, а не через opacity: прозрачность с переходом у каждой буквы — это отдельный слой на букву,
   два десятка слоёв в секунду; от такой чехарды в Safari мигает матовое стекло по соседству. */
.w{ display:inline-block; white-space:pre; }
.subs-line .c{ visibility:hidden; }
.subs-line .c.is-on,.subs-line .w.is-on .c{ visibility:visible; animation:c-in .09s linear; }
@keyframes c-in{ from{ color:transparent; } }
.is-touch .subs-line .c.is-on,.is-touch .subs-line .w.is-on .c{ animation:none; }      /* на телефоне буква появляется сразу: меньше перерисовок */
/* в каталоге и кейсе реплики стоят слева от кружка с головой, по его центру */
body:not([data-view="hero"]) .subs{ left:auto; right:calc(var(--corner-r) + var(--corner) + clamp(12px, calc(var(--u) * 1.8), 36px)); top:auto; bottom:calc(var(--corner-b) + var(--corner) * .5); width:fit-content; max-width:min(calc(var(--u) * 30), calc(100vw - var(--corner) - var(--corner-r) - 60px)); transform:translateY(50%); text-align:left; font-size:clamp(16px, calc(var(--u) * 1.65), 32px); }
body[data-view="case"] .subs-line,body[data-view="archive"] .subs-line{ display:inline-block; padding:.45em .7em; border-radius:.7em; background:rgba(255,255,255,.88); color:#000; -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px); box-shadow:0 1px 0 rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.08); }
body[data-view="case"] .subs-line:empty,body[data-view="archive"] .subs-line:empty{ display:none; }
.is-preview .subs,.is-preview .loader{ display:none; }
/* предпросмотр в админке: вместо головы — её силуэт, чтобы расставлять папки */
.is-preview[data-view="hero"] .hero::before{ content:''; position:fixed; left:var(--ph-x); top:var(--ph-y); width:var(--ph-w); height:var(--ph-h); border-radius:48% 48% 50% 50% / 40% 40% 60% 60%; background:#ECECEF; }

/* Плашка «наклон телефона» (iPhone/iPad): светлая, чтобы не спорить с чёрными кнопками. Появляется сразу, вместе со страницей.
   На телефоне стоит над кнопками, раскладка оставляет под неё место (--tip, js/app.js). */
.tip{ position:fixed; z-index:45; left:50%; bottom:max(20px, env(safe-area-inset-bottom)); transform:translateX(-50%); display:flex; align-items:center; gap:8px; width:max-content; max-width:calc(100vw - 20px); padding:4px 4px 4px 14px; border-radius:999px; background:#EEEEF0; color:#000; font:400 14px/1.2 var(--font-text); white-space:nowrap; pointer-events:auto; transition:opacity .25s ease, transform .25s var(--ease); animation:tip-in .35s var(--ease); }
.tip.is-out{ opacity:0; transform:translateX(-50%) translateY(8px); pointer-events:none; }
@keyframes tip-in{ from{ opacity:0; transform:translateX(-50%) translateY(8px); } }
.tip-text{ min-width:0; white-space:normal; text-wrap:balance; line-height:1.12; }      /* на узком экране текст встаёт в две строки, а не обрезается */
.tip-ico{ width:20px; height:20px; flex:none; }
.tip-btn{ flex:none; min-height:40px; padding:0 16px; border:0; border-radius:999px; background:#000; color:#fff; font:400 14px/1 var(--font-text); cursor:pointer; -webkit-tap-highlight-color:transparent; touch-action:manipulation; transition:transform .12s; }
.tip-btn:active{ transform:scale(.96); }
.tip-close{ flex:none; width:40px; height:40px; border:0; border-radius:50%; background:transparent; color:#555; font:400 22px/1 var(--font); cursor:pointer; -webkit-tap-highlight-color:transparent; }

/* «без очков»: всё размыто; отверстия — точно по линзам (clip-path задаёт скрипт) */
.veil{ position:fixed; inset:0; z-index:50; pointer-events:none;
  -webkit-backdrop-filter:blur(calc(var(--blur,0) * 1px)); backdrop-filter:blur(calc(var(--blur,0) * 1px));
  background-color:rgba(255,255,255,calc(var(--blind,0) * .05));
  box-shadow:inset 0 0 22vmin rgba(0,0,0,calc(var(--blind,0) * .045)); }
/* мутное стекло: поверх размытия — лёгкое зерно (и чуть «молока» выше). В линзах зерна нет — там отверстия */
.veil::after{ content:''; position:absolute; inset:0; opacity:calc(var(--blind,0) * .3);
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1.7 -.5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0/220px 220px; }

/* ---------- пасхалка: заплёванный экран (js/spit.js) ----------
   Слой лежит поверх страницы, но под субтитрами: реплики головы остаются читаемыми. Клики пропускает. */
.spit{ position:fixed; inset:0; z-index:58; pointer-events:none; overflow:hidden; }
/* один слой размытия на все кляксы: сквозь слюну страница видна чуть мутной; контур задаёт скрипт (clip-path) */
.spit-blur{ position:absolute; inset:0; -webkit-backdrop-filter:blur(3px) saturate(1.08) brightness(1.02); backdrop-filter:blur(3px) saturate(1.08) brightness(1.02); }
.spit-gl{ position:absolute; inset:0; width:100%; height:100%; }
.spit.is-wiping{ transform:translateY(55%); opacity:0; transition:transform .8s cubic-bezier(.5,0,.85,.4), opacity .8s ease-in; }

/* проверка на телефоне: адрес …/?diag */
.diag{ position:fixed; z-index:90; left:6px; top:calc(6px + env(safe-area-inset-top)); max-width:calc(100vw - 12px); margin:0; padding:6px 8px; border-radius:8px; background:rgba(0,0,0,.82); color:#fff; font:400 11px/1.35 ui-monospace,Menlo,Consolas,monospace; white-space:pre-wrap; pointer-events:none; }
/* ползунки эффекта присутствия — там же, в ?diag */
.tune{ position:fixed; z-index:91; left:6px; right:6px; bottom:calc(var(--bar, 0px) + var(--tip, 0px) + 8px); display:grid; gap:2px; padding:6px 10px; border-radius:10px; background:rgba(0,0,0,.82); color:#fff; font:400 11px/1.3 ui-monospace,Menlo,Consolas,monospace; }
.tune label{ display:grid; grid-template-columns:96px 1fr; align-items:center; gap:8px; }
.tune input{ width:100%; height:32px; margin:0; accent-color:#fff; }

/* экраны сменяются мягко */
@keyframes view-in{ from{ opacity:0; } to{ opacity:1; } }
@keyframes say-in{ from{ opacity:0; transform:translateY(6px) scale(.92); } }
.catalog:not([hidden]),.case:not([hidden]),.hero:not([hidden]) .folders{ animation:view-in .4s ease both; }

/* ---------- каталог: проекты лентой, выбранный — крупно (js/catalog.js) ----------
   Слои снизу вверх: фон проекта (цвет, картинка или видео) → его визуал → лента карточек → градиент снизу → текст.
   Размеры ленты (--cw, --ch, --cb, --cpad) задаёт скрипт; --strip-top — где кончается лента. */
html.is-cat,html.is-cat body{ overflow:hidden; height:100%; overscroll-behavior:none; background-color:var(--cat-c, var(--paper)); }
html.is-cat .site-footer{ display:none; }
.catalog{ position:relative; z-index:20; }
.cat{ position:fixed; inset:0; overflow:hidden; touch-action:none; -webkit-user-select:none; user-select:none; color:var(--fg); }
.cat.is-dragging,.cat.is-dragging .cat-card{ cursor:grabbing; }
.cat-bg,.cat-hero,.cat-fade{ position:absolute; inset:0; pointer-events:none; }
/* фон проекта: цвет ставит скрипт каждый кадр, пока едет лента (--cat-c, js/catalog.js → place) — смена плавная, без скачка;
   картинка или видео фона, если они есть у проекта, лежат поверх цвета двумя слоями и сменяются наплывом */
.cat-bg{ background-color:var(--cat-c, var(--paper)); }
.cat-bg-l{ position:absolute; inset:0; overflow:hidden; opacity:0; transition:opacity .7s var(--ease); }
.cat-bg-l.is-on{ opacity:1; }
.cat-bg-m{ position:absolute; inset:0; display:block; width:100%; height:100%; object-fit:cover; animation:bg-in 1.6s var(--ease) both; }
@keyframes bg-in{ from{ transform:scale(1.08); } }
/* визуал проекта: место и размер — из админки (в долях экрана), появляется с мягкой пружинкой и чуть «дышит» */
.cat-hero{ z-index:0; }
.cat-hero-l{ position:absolute; inset:0; transition:opacity .35s ease, transform .45s var(--ease); }
.cat-hero-l.is-out{ opacity:0; transform:scale(1.035); }
.cat-hero-m{ position:absolute; transform:translate(-50%,-50%); }
/* появление — как на страницах Apple: без пружинки, плавно всплывает и встаёт; дальше стоит спокойно (движение — в самом видео) */
.cat-hero-l.is-in .cat-hero-m{ animation:hero-in 1.1s cubic-bezier(.28,.11,.32,1) both; }
@keyframes hero-in{ from{ opacity:0; transform:translate(-50%,-46%) scale(.95); } }
.cat-hero-media{ display:block; width:100%; height:100%; object-fit:contain; filter:drop-shadow(0 28px 56px rgba(0,0,0,.2)); }
/* предпросмотр в админке: визуал двигают мышью, колёсико — размер */
.cat-hero-m.is-edit{ pointer-events:auto; cursor:grab; outline:2px dashed currentColor; outline-offset:8px; }
.cat-hero-m.is-moving{ cursor:grabbing; }
/* …и пунктиром — где текст проекта: туда визуал лучше не ставить */
.cat.is-edit-hero .cat-info-in{ outline:1px dashed currentColor; outline-offset:10px; }

/* текст выбранного проекта (Figma: «Проект в каталоге», Компьютер): у левого поля, под шапкой */
.cat-info{ position:absolute; z-index:3; left:var(--cpad); top:calc(var(--hdr) + var(--sp-30)); width:min(calc(100vw - var(--cpad) * 2), 600px); bottom:calc(var(--strip-top, 300px) + var(--sp-20)); pointer-events:none; }
.cat-info-in{ position:absolute; left:0; top:0; width:100%; pointer-events:auto; }
/* прежний текст уходит быстро, новый входит следом, лесенкой — строки не наслаиваются друг на друга */
.cat-info-in.is-out{ opacity:0; transform:translateY(-10px); transition:opacity .14s ease, transform .22s var(--ease); pointer-events:none; }
.cat-info-in.is-in > *{ animation:info-in .6s cubic-bezier(0,0,.5,1) .1s both; }
.cat-info-in.is-in > :nth-child(2){ animation-delay:.15s; }
.cat-info-in.is-in > :nth-child(3){ animation-delay:.2s; }
.cat-info-in.is-in > :nth-child(4){ animation-delay:.25s; }
@keyframes info-in{ from{ opacity:0; transform:translateY(20px); } }
.cat-logo{ display:none; margin:0; }       /* логотип проекта картинкой — только на телефоне */
.cat-logo img{ display:block; max-width:238px; max-height:95px; width:auto; height:auto; margin:0 auto; }
.cat-title{ max-width:538px; margin:0; font:var(--w-title) calc(var(--fs-cat-title) * var(--k-title))/var(--lh-narrow) var(--font); letter-spacing:var(--tr-title); text-wrap:balance; }
.cat-sum{ max-width:452px; margin:var(--sp-15) 0 0; color:var(--mute); font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); text-wrap:pretty; }
.cat-acts{ display:flex; align-items:center; gap:8px; margin-top:var(--sp-30); }
/* кнопка-лайк (Figma: «Кнопка-лайк») — круглая, подложка — основной цвет на 20% */
.btn--icon{ width:var(--btn-h); padding:0; background:color-mix(in srgb, var(--fg) 20%, transparent); color:var(--fg); }
.btn--icon .heart{ width:46%; height:46%; fill:none; stroke:currentColor; stroke-width:1.5; overflow:visible; transition:fill .2s, stroke .2s; }
.btn--icon[aria-pressed="true"] .heart{ fill:var(--heart); stroke:var(--heart); }
.btn--icon.is-pop .heart{ animation:heart-pop .55s var(--spring); }
@keyframes heart-pop{ 35%{ transform:scale(1.5); } }
@media (hover:hover){ .btn.btn--icon:hover{ background:color-mix(in srgb, var(--fg) 30%, transparent); } }
/* лента карточек (Figma: «Карточка проекта»). Выбранная — крупнее, у левого поля, со свечением; прошлые уходят
   за левый край целиком. Размер, сдвиг, обрезку сверху и скругление каждой карточки ставит скрипт (js/catalog.js, place) */
.cat-strip{ position:absolute; z-index:2; left:0; right:0; bottom:var(--cb); height:var(--cah); }
.cat-card{ position:absolute; left:0; bottom:0; width:var(--caw); height:var(--cah); padding:0; border:0; background:none; cursor:pointer;
  transform-origin:0 100%; will-change:transform; -webkit-tap-highlight-color:transparent; }
/* свечение (Figma: стиль «Свечение карточки», 0 1 132): у самой карточки и едет вместе с ней; яркость — по тому, насколько
   карточка уже встала на место выбранной (скрипт ставит opacity). Цвет — свой у проекта или по тону его фона */
.cat-card-glow{ position:absolute; left:0; right:0; bottom:0; top:var(--crop, 0px); border-radius:var(--cr, 56px); pointer-events:none;
  box-shadow:0 1px var(--glow-blur) var(--card-glow, var(--glow-light)); }
.cat-card-m{ position:absolute; left:0; right:0; bottom:0; top:var(--crop, 0px); overflow:hidden; border-radius:var(--cr, 56px); background:color-mix(in srgb, var(--fg) 12%, transparent); }
.cat-card-media{ display:block; width:100%; height:100%; object-fit:cover; pointer-events:none; }
/* то, что выглядывает за край карточки (Figma: лапы свиньи свисают через край): та же картинка, что под ней, — без обрезки
   по скруглению. Картинка карточки встаёт по центру своего блока, поэтому и слой поверх — с той же середины (--crop / 2) */
.cat-card-over{ position:absolute; z-index:1; left:0; top:calc(var(--crop, 0px) / 2); display:block; width:100%; height:auto; max-width:none; pointer-events:none; }
.cat-card:focus-visible{ outline:none; }
.cat-card:focus-visible .cat-card-m{ box-shadow:0 0 0 3px var(--fg); }
/* сердечко на карточке — только там, где посетитель сам поставил лайк */
.cat-like{ position:absolute; z-index:1; top:calc(var(--crop, 0px) + 14px); right:14px; display:grid; place-items:center; width:36px; aspect-ratio:1; border-radius:50%; background:rgba(255,255,255,.95); box-shadow:0 4px 14px rgba(0,0,0,.18); }
.cat-like .heart{ width:56%; height:56%; fill:var(--heart); }
.cat-like.is-pop{ animation:heart-pop .55s var(--spring); }
/* кнопка видео выбранного проекта (как у Apple): пауза / воспроизвести / повторить, кольцо — сколько проиграно */
.cat-play{ position:absolute; z-index:4; right:var(--cpad); bottom:calc(var(--strip-top, 300px) + var(--sp-20)); width:44px; aspect-ratio:1; padding:0; border:0; border-radius:50%;
  background:color-mix(in srgb, var(--fg) 20%, transparent); color:var(--fg); cursor:pointer; -webkit-backdrop-filter:blur(14px) saturate(1.4); backdrop-filter:blur(14px) saturate(1.4); transition:background-color .2s, transform .12s; -webkit-tap-highlight-color:transparent; }
.cat-play svg{ position:absolute; inset:0; width:100%; height:100%; }
.cat-play-i{ fill:currentColor; }
.cat-play-ring circle{ fill:none; stroke:currentColor; stroke-width:1.6; stroke-dasharray:100; stroke-dashoffset:calc(100 - var(--k, 0) * 100); transform:rotate(-90deg); transform-origin:50% 50%; transition:stroke-dashoffset .3s linear; }
.cat-play[data-state="replay"] .cat-play-ring circle{ opacity:0; }
.cat-play:active{ transform:scale(.94); }
.cat-play:focus-visible{ outline:2px solid var(--fg); outline-offset:3px; }
@media (hover:hover){ .cat-play:hover{ background:color-mix(in srgb, var(--fg) 30%, transparent); } }
/* телефон: точки (Figma: «Точки») — выбранный проект капсулой 30×8, остальные 8×8 на 20%; точка — кнопка */
.cat-dots{ position:absolute; z-index:4; left:0; right:0; bottom:var(--dots-b, 26px); display:none; justify-content:center; align-items:center; height:24px; color:var(--fg); pointer-events:none; }      /* ряд во всю ширину не мешает свайпу — нажимаются только сами точки */
.cat-dot{ display:grid; place-items:center; height:24px; padding:0 2.5px; border:0; background:none; color:inherit; cursor:pointer; pointer-events:auto; -webkit-tap-highlight-color:transparent; }
.cat-dot i{ display:block; width:8px; height:8px; border-radius:4px; background:color-mix(in srgb, currentColor 20%, transparent); transition:width .35s var(--ease), background-color .35s; }
.cat-dot.is-active i{ width:30px; background:currentColor; }
.cat-dot.is-edge i{ transform:scale(.66); }
.cat-dot.is-far{ display:none; }
.cat-dot:focus-visible{ outline:none; }
.cat-dot:focus-visible i{ outline:2px solid currentColor; outline-offset:3px; }
/* снизу визуал уходит в цвет проекта (Figma: «Градиент цвета проекта»): карточки и текст лежат на чистом цвете.
   Это тот же цвет фона под маской-градиентом: он меняется вместе с фоном, кадр в кадр, и полосы другого цвета не бывает */
.cat-fade{ z-index:1; top:auto; height:calc(var(--strip-top, 300px) + 60px); background-color:var(--cat-c, transparent);
  -webkit-mask-image:linear-gradient(to bottom, transparent, #000 170px); mask-image:linear-gradient(to bottom, transparent, #000 170px); }
.cat.is-btn-light{ --btn-bg:var(--btn-light-bg); --btn-fg:var(--btn-light-fg); }
.cat .empty{ position:absolute; z-index:3; left:var(--cpad); top:42%; margin:0; font-family:var(--font); font-size:calc(var(--fs-h2) * var(--k-title)); }

/* ---------- кейс (Figma: блоки «Кейс / …») ----------
   Как страница продукта Apple: обложка-карточка цвета проекта → факты → главы по одной мысли. Ширина — 1206 (--case-w),
   по центру; каждая глава мягко всплывает, когда доезжает до экрана (.rv → .is-in, один раз) */
.case{ position:relative; z-index:20; color:var(--fg); overflow-x:clip; }      /* визуал обложки может выйти за край карточки, но не за край экрана */
.case-in,.case-top{ width:min(var(--case-w), calc(100% - var(--pad-x) * 2)); margin:0 auto; }
.case-top{ padding-top:calc(var(--hdr) + var(--sp-50)); }
/* обложка: цвет проекта, скругление 56; визуал справа может выходить за край карточки */
.cover-card{ position:relative; display:flex; flex-direction:column; justify-content:flex-start; min-height:0; aspect-ratio:1206 / 593; border-radius:var(--radius-card); background:var(--cc, var(--tile)); color:var(--cf, var(--fg)); }
.cover-text{ position:relative; z-index:2; width:min(57%, 683px); padding:0 0 var(--sp-40) var(--sp-40); }
.cover-title{ margin:0; outline:none; font:var(--w-title) calc(clamp(48px, 6.4vw, 104px) * var(--k-title))/1 var(--font); letter-spacing:var(--tr-title); text-wrap:balance; }
.cover-title:not(:has(img)){ padding-top:var(--sp-40); }
.cover-logo{ display:block; width:auto; max-width:min(100%, 683px); max-height:min(261px, 20vw); height:auto; }      /* высокий логотип не разрастается: потолок — высота логотипа «Свои деньги» в макете */
.cover-lead{ max-width:643px; margin:var(--sp-10) 0 0; font-weight:var(--w-lead); font-size:calc(var(--fs-lead) * var(--k-text)); line-height:var(--lh-lead); text-wrap:pretty; }
.cover-visual{ position:absolute; z-index:1; right:-4.5%; top:6.6%; width:50.3%; aspect-ratio:1; pointer-events:none; }
.cover-visual img,.cover-visual video{ display:block; width:100%; height:100%; object-fit:contain; }
/* факты (Figma: «Кейс / Факты»): тот же цвет, 4 в ряд, по центру */
.facts-card{ position:relative; z-index:2; display:grid; grid-template-columns:repeat(var(--n,4), minmax(0,1fr)); gap:var(--sp-20); margin:var(--sp-20) 0 0; padding:var(--sp-60) var(--sp-80); border-radius:var(--radius-card); background:var(--cc, var(--tile)); color:var(--cf, var(--fg)); text-align:center; }
.fact{ display:flex; flex-direction:column; align-items:center; justify-content:flex-end; gap:var(--sp-5); margin:0; min-width:0; }
.fact dd{ order:-1; margin:0; font:var(--w-title) calc(var(--fs-fact) * var(--k-title))/var(--lh-narrow) var(--font); text-wrap:balance; }
.fact dd.is-long{ font-size:calc(var(--fs-fact) * .6 * var(--k-title)); }
.fact dd img{ display:block; height:calc(var(--fs-fact) * 1.15); width:auto; max-width:100%; }
.fact dt{ font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); opacity:var(--cfo, .7); }      /* --cfo: 1, если на цвете проекта 70% бледнее 4,5:1 (js/case.js) */
/* итоги: цифры и «суть в трёх абзацах» — сразу под фактами, для того, кто читает 30 секунд */
.case-results{ display:grid; grid-template-columns:repeat(var(--n,3),minmax(0,1fr)); gap:var(--sp-20); margin-top:var(--sp-100); text-align:center; }
.result-v{ margin:0; font:var(--w-title) calc(var(--fs-cat-title) * 1.15 * var(--k-title))/1 var(--font); letter-spacing:var(--tr-title); white-space:nowrap; }
.result-l{ margin:var(--sp-10) auto 0; color:var(--mute); max-width:16em; line-height:var(--lh-body); }
.case-tldr{ display:grid; grid-template-columns:repeat(var(--n,3),minmax(0,1fr)); gap:var(--sp-40); margin-top:var(--sp-60); }
.case-tldr h2{ margin:0 0 var(--sp-10); font:400 calc(var(--fs-body) * var(--k-text))/var(--lh-body) var(--font-text); color:var(--mute); }
.case-tldr p{ margin:0; font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); text-wrap:pretty; }
/* главы: между главами — 120, заголовок главы и её картинка держатся вместе (40) */
.case-blocks{ margin-top:var(--sp-120); }
.case-blocks > .blk + .blk{ margin-top:var(--sp-120); }
.case-blocks > .blk-text + :is(.blk-image,.blk-tiles,.blk-video,.blk-compare,.blk-metrics,.blk-palette,.blk-steps){ margin-top:var(--sp-40); }
.blk{ margin:0; min-width:0; }
/* заголовок главы (Figma: «Кейс / Заголовок раздела»): узкий 40 + текст 20/125% на 70% */
.sec-title,.blk h2{ margin:0 0 var(--sp-20); font:var(--w-title) calc(var(--fs-h2) * var(--k-title))/var(--lh-narrow) var(--font); letter-spacing:var(--tr-title); text-wrap:balance; }
.prose{ color:var(--mute); }
.prose p{ margin:0 0 var(--sp-15); font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); text-wrap:pretty; }
.prose p:last-child{ margin-bottom:0; }
.blk-text{ max-width:700px; }
.blk-text.is-center{ max-width:533px; margin-left:auto; margin-right:auto; text-align:center; }
.blk-text.is-center h2:last-child{ margin-bottom:0; }
.blk figcaption,.tile figcaption{ margin-top:var(--sp-15); color:var(--mute); font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); text-wrap:pretty; }
.blk > figcaption{ text-align:center; }
/* плитки (Figma: «Кейс / Плитка»): скругление 56, заглушка — основной цвет на 10% */
.blk-image img{ display:block; width:100%; height:auto; border-radius:var(--radius-card); }
.blk-image.has-bg .frame{ display:grid; place-items:center; padding:clamp(20px, 5vw, 70px); border-radius:var(--radius-card); background:var(--tile, color-mix(in srgb, var(--ink) 10%, transparent)); }
.blk-image.has-bg img{ width:auto; max-width:100%; max-height:min(76vh, 760px); border-radius:0; filter:drop-shadow(0 18px 30px rgba(0,0,0,.16)); }
.blk-image.has-bg img.is-sized{ width:min(100%, calc(var(--w) * 1px), calc(min(76vh, 760px) * var(--w) / var(--h))); height:auto; max-height:none; aspect-ratio:var(--w) / var(--h); }
.blk--text{ max-width:700px; margin-left:auto; margin-right:auto; }
.blk--full{ width:100vw; margin-left:calc(50% - 50vw); }
.blk--full img,.blk--full .frame,.blk--full video,.blk--full .cmp{ border-radius:0 !important; }
.blk-gallery{ display:grid; grid-template-columns:repeat(var(--cols,3),minmax(0,1fr)); gap:var(--sp-20); }
.tile{ margin:0; min-width:0; }
.tile-box{ position:relative; aspect-ratio:1; border-radius:var(--radius-card); background:var(--tile, color-mix(in srgb, var(--ink) 10%, transparent)); overflow:hidden; }
.tile-box img,.tile-box video{ position:absolute; left:9%; top:9%; width:82%; height:82%; max-width:none; object-fit:contain; filter:drop-shadow(0 14px 24px rgba(0,0,0,.14)); }
.tile-box.is-cover img,.tile-box.is-cover video{ left:0; top:0; width:100%; height:100%; object-fit:cover; filter:none; }
/* серая плашка — место под картинку (Figma: серые прямоугольники в макете кейса); надпись — что сюда встанет */
.tile-box.is-ph{ display:grid; place-items:center; padding:var(--sp-20); }
.tile-ph{ max-width:24em; color:var(--mute); font-size:calc(var(--fs-caption) * var(--k-text)); line-height:1.35; text-align:center; text-wrap:balance; }
.blk-image.is-ph .tile-box{ aspect-ratio:1206 / 593; }
/* формы плиток: телефон 330×574 — по два с воздухом; карточка 287×363 с подписью — по три по центру */
.blk-gallery.shape-phone{ grid-template-columns:repeat(var(--cols,2), minmax(0, 330px)); justify-content:space-evenly; }
.shape-phone .tile-box{ aspect-ratio:330 / 574; }
.blk-gallery.shape-card{ grid-template-columns:repeat(var(--cols,3), minmax(0, 287px)); justify-content:center; }
.shape-card .tile-box{ aspect-ratio:287 / 363; }
.shape-card figcaption{ text-align:left; }
/* «Идея и лесенка» (Figma: макет «Свои деньги», глава «Идея»): текст сверху слева, три плитки растут вправо */
.blk-idea{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); column-gap:var(--sp-60); align-items:end; }
.idea-text{ grid-area:1 / 1 / 2 / 3; align-self:start; max-width:452px; }
.idea-step{ grid-row:1; margin:0; }
.idea-step .tile-box{ aspect-ratio:379 / 181; }
.idea-step:nth-of-type(2) .tile-box{ aspect-ratio:379 / 280; }
.idea-step:nth-of-type(3) .tile-box{ aspect-ratio:379 / 549; }
/* «Картинка и текст»: телефон с одной стороны, глава — с другой */
.blk-split{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); align-items:center; gap:var(--sp-60); }
.blk-split.side-right .split-media{ order:2; }
.split-media{ margin:0; display:flex; justify-content:center; }
.split-media .tile-box{ width:100%; }
.split-media.shape-phone .tile-box{ width:min(100%, 330px); aspect-ratio:330 / 574; }
.split-text{ max-width:452px; }
.split-text .sec-title{ margin-bottom:var(--sp-20); }
/* метрики (Figma: «Кейс / Метрика»): цифра крупно — или кружок-иконка, если цифры ещё нет */
.blk-metrics{ display:grid; grid-template-columns:repeat(var(--n,3),minmax(0, 258px)); justify-content:space-evenly; gap:var(--sp-40) var(--sp-20); }
.metric{ margin:0; display:flex; flex-direction:column; gap:var(--sp-20); }
.metric-v{ margin:0; font:var(--w-title) calc(var(--fs-cat-title) * var(--k-title))/1 var(--font); }
.metric-i{ display:block; width:64px; height:64px; }
.metric-i circle{ fill:none; stroke:currentColor; stroke-width:3; }
.metric-l{ margin:0; color:var(--mute); font-size:calc(var(--fs-body) * var(--k-text)); line-height:var(--lh-body); }
.blk-metrics.has-title{ display:block; }
.blk-metrics.has-title > h2{ text-align:center; margin-bottom:var(--sp-60); }
.blk-metrics.has-title > .metrics-row{ display:grid; grid-template-columns:repeat(var(--n,3),minmax(0, 258px)); justify-content:space-evenly; gap:var(--sp-40) var(--sp-20); }
/* финал главы со ссылками (Figma, Прототип): по центру, маленькие кнопки контуром */
.blk-links{ max-width:533px; margin-left:auto; margin-right:auto; text-align:center; }
.links-row{ display:flex; flex-wrap:wrap; justify-content:center; gap:var(--sp-20); margin-top:var(--sp-30); }
.blk-quote{ max-width:900px; margin-left:auto; margin-right:auto; text-align:center; }
.blk-quote blockquote{ margin:0; font-family:var(--font); font-size:calc(var(--fs-h2) * var(--k-title)); line-height:var(--lh-narrow); text-wrap:balance; }
.blk-quote blockquote p{ margin:0 0 .5em; } .blk-quote blockquote p:last-child{ margin:0; }
.blk-quote figcaption{ margin-top:var(--sp-20); }
.blk-steps{ max-width:700px; }
.blk-steps ol{ margin:0; padding:0; list-style:none; counter-reset:step; }
.blk-steps li{ display:grid; grid-template-columns:2.2em 1fr; gap:0 var(--sp-10); padding:var(--sp-15) 0; border-top:1px solid var(--line); counter-increment:step; }
.blk-steps li::before{ content:counter(step); color:var(--mute); font-family:var(--font); font-size:calc(var(--fs-h2) * .6); line-height:1.2; }
.blk-steps h3{ margin:0; font:var(--w-title) calc(var(--fs-h2) * .6 * var(--k-title))/1.2 var(--font); }
.blk-steps p{ grid-column:2; margin:var(--sp-5) 0 0; color:var(--mute); line-height:var(--lh-body); text-wrap:pretty; }
.blk-palette ul{ display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:var(--sp-10); margin:0; padding:0; list-style:none; }
.blk-palette li{ display:flex; flex-direction:column; justify-content:flex-end; min-height:clamp(120px, 16vw, 220px); padding:var(--sp-15); border-radius:var(--radius-card); background:var(--sw); color:var(--sw-fg); font-size:.9em; line-height:1.3; }
.blk-palette li span:last-child{ opacity:.75; }
.blk-video video{ display:block; width:100%; height:auto; border-radius:var(--radius-card); background:#000; }
/* до/после: ползунок двигает границу */
.cmp{ position:relative; overflow:hidden; border-radius:var(--radius-card); background:#eee; touch-action:pan-y; }
.cmp img{ display:block; width:100%; height:auto; }
.cmp-after{ position:absolute; inset:0; clip-path:inset(0 0 0 var(--at,50%)); }
.cmp-after img{ width:100%; height:100%; object-fit:cover; }
.cmp-tag{ position:absolute; top:16px; padding:.2em .7em .25em; border-radius:999px; background:rgba(0,0,0,.6); color:#fff; font-family:var(--font); font-size:.85em; line-height:1.2; pointer-events:none; }
.cmp-tag--a{ left:16px; } .cmp-tag--b{ right:16px; }
.cmp-bar{ position:absolute; top:0; bottom:0; left:var(--at,50%); width:2px; margin-left:-1px; background:#fff; box-shadow:0 0 0 1px rgba(0,0,0,.15); pointer-events:none; }
.cmp-bar::after{ content:''; position:absolute; left:50%; top:50%; width:40px; height:40px; margin:-20px; border-radius:50%; background:#fff; box-shadow:0 2px 10px rgba(0,0,0,.25); }
.cmp input{ position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:ew-resize; }
.cmp input:focus-visible + .cmp-bar::after{ outline:2px solid #000; outline-offset:2px; }
.case-tags{ display:flex; flex-wrap:wrap; justify-content:center; gap:var(--sp-10); margin:var(--sp-120) 0 0; padding:0; list-style:none; }
.case-tags li{ display:inline-flex; align-items:center; height:36px; padding:0 var(--sp-15); border-radius:999px; background:color-mix(in srgb, var(--fg) 7%, transparent); color:var(--mute); font:400 calc(var(--fs-body) * .8) / 1 var(--font-text); }
.case-end{ display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:var(--sp-60); margin-top:var(--sp-120); padding:0 0 var(--sp-120); }
/* визитка в конце кейса: кружок под голову (она перелетает сюда из угла, js/app.js — dockIn) и контакты */
.vcard{ --vh:clamp(150px, calc(var(--u) * 17), 250px); position:relative; display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:clamp(24px, calc(var(--u) * 4), 60px);
  padding:clamp(24px, calc(var(--u) * 4), 60px); border-radius:var(--radius-card); background:var(--tile, color-mix(in srgb, var(--ink) 6%, var(--paper))); }
.vcard-head{ position:relative; width:var(--vh); height:var(--vh); }
.vcard-ph{ position:absolute; inset:0; border-radius:50%; background:var(--dock-bg); box-shadow:var(--dock-ring); }
.vcard-kicker{ margin:0 0 var(--sp-10); color:var(--mute); text-wrap:balance; }
.vcard-name{ margin:0; font:var(--w-title) calc(var(--fs-h2) * 1.25 * var(--k-title))/1.02 var(--font); letter-spacing:var(--tr-title); }
.vcard-role{ margin:var(--sp-5) 0 0; color:var(--mute); }
.vcard-acts{ display:flex; flex-wrap:wrap; gap:var(--sp-15); margin-top:var(--sp-25); }
.vcard-links{ margin:var(--sp-15) 0 0; color:var(--mute); font-size:var(--fs-caption); }
.vcard-links a{ color:inherit; text-decoration-thickness:1px; text-underline-offset:.2em; }
/* голова в визитке: сцена переехала в кружок и прокручивается вместе со страницей */
.vcard-head > .stage.is-dock{ position:absolute; z-index:1; inset:0; top:0; left:0; width:100%; height:100%; border-radius:50%; overflow:hidden; background:var(--dock-bg); -webkit-backdrop-filter:none; backdrop-filter:none; box-shadow:var(--dock-ring); opacity:1; visibility:visible; transition:none; }
/* реплика головы в визитке — облачко на месте подводки «Есть похожая задача?»: растёт вверх от её нижнего края, в поле карточки,
   и ничего не сдвигает. Хвостик смотрит на голову. Пока голова не заговорила, облачка нет; договорила — реплика остаётся */
.vcard-top{ position:relative; }
.vcard-top:empty{ display:none; }
.vcard-say{ position:absolute; z-index:2; left:-.15em; bottom:var(--sp-10); width:max-content; max-width:min(100%, 24em); padding:.5em .8em .55em; border-radius:.8em; background:#fff; color:#000;
  font:400 clamp(16px, calc(var(--u) * 1.35), 20px)/1.2 var(--font); text-align:left; box-shadow:0 1px 0 rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.12);
  transform-origin:0 100%; transition:opacity .3s var(--ease), transform .45s cubic-bezier(.34,1.5,.5,1); }
.vcard-say::after{ content:''; position:absolute; right:100%; bottom:.9em; border:8px solid transparent; border-right-color:#fff; border-left-width:0; }
.vcard:not(.is-said) .vcard-say{ opacity:0; transform:scale(.85); pointer-events:none; }
.vcard.is-said .vcard-kicker{ visibility:hidden; }
.vcard-say .subs-line,body[data-view="case"] .vcard-say .subs-line{ display:block; margin:0; padding:0; border-radius:0; background:none; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none; animation:none; }
body[data-view] .vcard-say .subs-line::after{ display:none; }
.confetti{ position:fixed; inset:0; z-index:37; width:100%; height:100%; pointer-events:none; }
/* «Реплика головы» — точка между блоками: на экране её нет, расстояния между блоками не меняются */
.case-blocks > .blk.blk-say{ height:1px; margin:0 0 -1px; padding:0; opacity:0; pointer-events:none; }
.case-blocks > .blk + .blk.blk-say{ margin-top:0; }
.case-blocks > .blk-text + .blk-say + :is(.blk-image,.blk-tiles,.blk-video,.blk-compare,.blk-metrics,.blk-palette,.blk-steps){ margin-top:var(--sp-40); }
.case-next{ padding:calc(var(--u) * 6) calc(var(--corner) * .5 + var(--u) * 4) 0 0; }
.case-next .gf{ --fw:clamp(200px, 20vw, 300px); margin:0 auto; }
/* появление при прокрутке — один раз, как у Apple: 0,6 с, без пружины */
.js-rv .rv{ opacity:0; transform:translateY(30px); transition:opacity .6s cubic-bezier(0,0,.5,1), transform .8s cubic-bezier(0,0,.5,1); }
.js-rv .rv.is-in{ opacity:1; transform:none; }
.cover-card.rv .cover-visual{ transform:scale(.94); transition:transform 1.4s cubic-bezier(.28,.11,.32,1) .1s; }
.cover-card.rv.is-in .cover-visual{ transform:none; }
.site-footer{ position:relative; z-index:20; display:flex; flex-wrap:wrap; gap:var(--sp-10) var(--sp-30); padding:var(--sp-20) var(--pad-x) var(--sp-40); background:var(--paper); color:var(--mute-l); font-size:var(--fs-caption); line-height:1.4; }
body:not([data-view="case"]) .site-footer{ display:none; }


/* ---------- полароид (js/polaroid.js) и архив полароидов (js/archive.js); Figma: «Полароид», «Архив» ----------
   Карточка — как настоящий полароид: бумага с холодным отливом, квадратное окно с фото, широкое поле снизу под подпись.
   Всё внутри неё задано в долях её ширины (единицы cqw), поэтому одна и та же карточка годится для редактора,
   сетки архива и кружка «Архив». Наклейки и их места — в долях карточки (x, y от 0 до 1). */
.pc{ position:relative; display:block; width:100%; aspect-ratio:281/341; margin:0; padding:0; border:0; border-radius:1.4% / 1.15%;
  background:linear-gradient(180deg, #E1E2EA 0%, #E6E7EE 68%, #EBEDF1 100%); color:#1D1D1F; text-align:center; container-type:inline-size;
  box-shadow:0 1px 1px rgba(20,22,40,.16), 0 3px 8px rgba(20,22,40,.12), 0 18px 34px rgba(20,22,40,.14); -webkit-tap-highlight-color:transparent; }
.pc::before{ content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none; background:var(--noise) 0 0/160px 160px; opacity:.32; mix-blend-mode:multiply; }
.pc::after{ content:''; position:absolute; left:.6%; right:.6%; bottom:0; height:1.5px; border-radius:50%; background:rgba(66,70,168,.4); pointer-events:none; }   /* синеватый нижний край, как в макете */
/* окно с фото стоит на месте само, а не в потоке */
.pc-photo{ position:absolute; left:6cqw; right:6cqw; top:6cqw; display:block; aspect-ratio:1; overflow:hidden; background:#2A3030; }
/* блик и зерно поверх фото — еле заметные: плёнку чувствуешь, но снимок остаётся чистым */
.pc-photo::after{ content:''; position:absolute; inset:0; z-index:2; pointer-events:none; mix-blend-mode:soft-light; opacity:.2;
  background:linear-gradient(128deg, rgba(255,255,255,.18) 0%, rgba(255,255,255,0) 36%), var(--noise) 0 0/140px 140px;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.08), inset 0 1px 2px rgba(0,0,0,.1); }
.pc-shot{ display:block; width:100%; height:100%; object-fit:cover; -webkit-user-drag:none; }
/* Подпись — в белом поле под фото (от низа фото, 94cqw, до низа карточки), по центру. Кегль один на любую длину:
   самая длинная подпись (56 знаков) встаёт ровно в две строки; длиннее двух строк редактор не пускает */
.pc-capbox{ position:absolute; z-index:1; left:6cqw; right:6cqw; top:95cqw; bottom:2cqw; display:flex; align-items:center; justify-content:center; }
.pc-cap{ display:block; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; width:100%; max-height:calc(2 * 1.15em); margin:0; padding:0; overflow:hidden;
  font:400 14px/1.15 var(--font); font-size:var(--capfs, 6.2cqw); color:#1D1D1F; overflow-wrap:anywhere; text-wrap:balance; }
.pc-stks{ position:absolute; z-index:3; inset:0; pointer-events:none; }
.pc-stk{ position:absolute; display:block; width:30%; height:auto; aspect-ratio:1; transform:translate(-50%,-50%) rotate(var(--r,0deg)); object-fit:contain; -webkit-user-drag:none; user-select:none; }
.pc-stk img{ display:block; width:100%; height:100%; object-fit:contain; pointer-events:none; -webkit-user-drag:none; user-select:none; }

/* съёмка: рамка видоискателя вокруг головы на время отсчёта и вспышка */
.pol-finder{ position:fixed; z-index:62; pointer-events:none; color:var(--fg); animation:finder-in .35s var(--ease) both; }
.pol-finder i{ position:absolute; width:13%; height:13%; border:0 solid currentColor; }
.pol-finder i:nth-child(1){ left:0; top:0; border-width:3px 0 0 3px; border-top-left-radius:14px; }
.pol-finder i:nth-child(2){ right:0; top:0; border-width:3px 3px 0 0; border-top-right-radius:14px; }
.pol-finder i:nth-child(3){ left:0; bottom:0; border-width:0 0 3px 3px; border-bottom-left-radius:14px; }
.pol-finder i:nth-child(4){ right:0; bottom:0; border-width:0 3px 3px 0; border-bottom-right-radius:14px; }
.pol-finder b{ position:absolute; right:4%; top:4%; width:12px; height:12px; border-radius:50%; background:#FF3B30; animation:rec 1s steps(2, jump-none) infinite; }
@keyframes finder-in{ from{ opacity:0; transform:scale(1.06); } }
@keyframes rec{ 50%{ opacity:.15; } }
.pol-flash{ position:fixed; inset:0; z-index:75; background:#fff; pointer-events:none; animation:pol-flash .8s cubic-bezier(.2,.6,.3,1) forwards; }
@keyframes pol-flash{ from{ opacity:.96; } to{ opacity:0; } }

/* редактор: затемнение, карточка, наклейки по бокам, окно с репликой и кнопками */
.pol{ position:fixed; inset:0; z-index:70; overflow:hidden; touch-action:none; -webkit-user-select:none; user-select:none; color:var(--ink-dark); }
.pol-scrim{ position:fixed; inset:0; z-index:64; background:rgba(29,29,31,.78); -webkit-backdrop-filter:blur(10px) saturate(.9); backdrop-filter:blur(10px) saturate(.9); opacity:0; transition:opacity .45s ease; }
.pol-scrim::after{ content:''; position:absolute; inset:0; background:var(--noise) 0 0/220px 220px; opacity:.1; }
.pol-scrim.is-in{ opacity:1; }
.pol-scrim.is-out{ opacity:0; transition-duration:.55s; }
.pol-stage{ position:absolute; inset:0; transform:translateY(var(--kb, 0px)); transition:transform .3s var(--ease); }
.pol-card{ position:absolute; z-index:2; width:var(--cw, 281px); transform:translate(-50%,-50%) rotate(8deg); perspective:1600px; }
.pol-turn{ position:relative; transform-style:preserve-3d; }
.pol-front,.pol-back{ -webkit-backface-visibility:hidden; backface-visibility:hidden; }
.pol-back{ position:absolute; inset:0; transform:rotateY(180deg); border-radius:1.4% / 1.15%; background:linear-gradient(150deg, rgba(255,255,255,.1), rgba(255,255,255,0) 45%), #1C1D20;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08), 0 18px 34px rgba(0,0,0,.3); }
/* проявка: снимок медленно проступает из тёмной мути. Только прозрачностью — её браузер ведёт без перерисовок,
   и реплика в окне печатается ровно (фильтр-размытие на фото дёргал печать) */
.pc-dev{ position:absolute; inset:0; z-index:1; background:#1F2829; opacity:.96; pointer-events:none; will-change:opacity; transition:opacity 2.8s cubic-bezier(.4,.1,.4,1); }
.pol.is-dev .pc-dev{ opacity:0; }
/* подпись пишется прямо на карточке */
textarea.pc-cap{ display:block; -webkit-line-clamp:none; max-height:none; height:auto; resize:none; border:0; border-radius:0; background:transparent; outline:none; text-align:center; caret-color:#1D1D1F;
  -webkit-user-select:text; user-select:text; touch-action:manipulation; }
textarea.pc-cap::placeholder{ color:#1D1D1F; opacity:.4; }
.pc--edit .pc-stk{ margin:0; padding:0; border:0; background:none; pointer-events:auto; cursor:pointer; -webkit-tap-highlight-color:transparent; }      /* приклеенная — отклеивается нажатием */
.pc--edit .pc-stk:focus-visible{ outline:2px dashed #1D1D1F; outline-offset:2px; border-radius:22%; }
.pol.is-dragging,.pol.is-dragging *{ cursor:grabbing !important; }
/* палитра наклеек: появляются по очереди и чуть покачиваются */
.pol-pal{ position:absolute; z-index:3; inset:0; pointer-events:none; }      /* наклейки — поверх всего: карточки, окна, логотипа */
.pol-st{ position:absolute; left:var(--x); top:var(--y); width:var(--s); height:var(--s); margin:0; padding:0; border:0; border-radius:50%; background:none; pointer-events:auto; cursor:grab; touch-action:none;
  opacity:0; transform:translate(-50%,-50%) scale(.3); transition:transform .45s var(--spring), opacity .25s ease; transition-delay:calc(var(--i, 0) * 45ms); -webkit-tap-highlight-color:transparent; }
.pol-st img{ display:block; width:100%; height:100%; object-fit:contain; pointer-events:none; animation:st-bob 3.4s ease-in-out infinite; animation-delay:calc(var(--i, 0) * -.43s); }
.pol.is-up .pol-st{ opacity:1; transform:translate(-50%,-50%) scale(1); }
@media (hover:hover){ .pol.is-up .pol-st:hover{ transform:translate(-50%,-50%) scale(1.12) rotate(-6deg); transition-delay:0s; } }
.pol-st:focus-visible{ outline:2px solid var(--ink-dark); outline-offset:4px; }
/* наклейку тащат: она приподнята; над другой наклейкой — бледнеет (туда не приклеится); приклеенная в палитре не видна */
.pol.is-up .pol-st.is-held{ z-index:2; transition:transform .14s var(--ease), filter .14s; transition-delay:0s; transform:translate(-50%,-50%) scale(1.08) rotate(-4deg); filter:drop-shadow(0 12px 14px rgba(0,0,0,.35)); cursor:grabbing; }
.pol-st.is-held img,.pol-st.is-flying img{ animation-play-state:paused; }
/* над карточкой наклейка уже такая, какой ляжет: её размер на карточке и наклон карточки; над другой наклейкой — бледнеет */
.pol.is-up .pol-st.is-held.is-over{ transform:translate(-50%,-50%) rotate(calc(8deg + var(--r, 0deg))) scale(var(--k, 1)); filter:drop-shadow(0 3px 5px rgba(0,0,0,.3)); }
.pol.is-up .pol-st.is-blocked{ opacity:.45; }
.pol .pol-st.is-flying{ z-index:3; transition:none; }
.pol .pol-st.is-used{ visibility:hidden; opacity:0; pointer-events:none; transition:none; }
.pol.is-dev .pol-st{ transition-delay:0s; }          /* очередь — только при появлении; дальше наклейки отзываются сразу */
.pol.is-out .pol-st{ opacity:0; transform:translate(-50%,-50%) scale(.6); transition-delay:0s; }
@keyframes st-bob{ 0%,100%{ transform:translateY(0) rotate(0deg); } 50%{ transform:translateY(-4%) rotate(2.5deg); } }
/* окно с репликой (Figma: 518×184, радиус 56, поле 30, кнопки «Перефоткать» / «Сохранить») */
.pol-dlg{ position:absolute; z-index:1; left:50%; bottom:max(20px, 5vh); display:flex; flex-direction:column; align-items:center; gap:20px; padding:30px; border-radius:var(--radius-card); background:var(--paper); color:var(--ink);
  opacity:0; transform:translate(-50%, 24px); transition:opacity .35s ease, transform .5s var(--ease); outline:none; }
.pol.is-up .pol-dlg{ opacity:1; transform:translate(-50%, 0); }
.pol.is-out .pol-dlg{ opacity:0; transform:translate(-50%, 24px); transition-duration:.25s; }
/* реплика в окне — обычным абзацем во всю ширину окна: без переноса строки после каждого предложения (как на главной)
   и без выравнивания строк по длине — иначе текст стоит узкой колонкой посреди широкого окна */
.pol-say{ width:100%; min-height:calc(var(--dfs, 24px) * 1.15 * 2); font:400 var(--dfs, 24px)/1.15 var(--font); text-align:center; text-wrap:pretty; will-change:opacity; contain:paint; }      /* свой слой, как у субтитров: буквы печатаются без перерисовки размытого фона */
.pol-say .subs-line{ margin:0; }
body[data-view] .pol-say .subs-line .s{ display:inline; }
.pol-acts{ display:flex; justify-content:center; gap:20px; }
.pol-acts .btn{ min-width:135px; --fg:var(--ink); --on-fg:var(--paper); }
.pol.is-busy .pol-acts .btn{ pointer-events:none; opacity:.6; }
.pol-x{ position:absolute; z-index:4; top:var(--pad-top, 30px); right:var(--pad-x); display:grid; place-items:center; width:var(--btn-h); height:var(--btn-h); padding:0; border:0; border-radius:50%; background:transparent; color:var(--ink-dark);
  box-shadow:inset 0 0 0 1px currentColor; cursor:pointer; opacity:0; transition:opacity .3s ease, background-color .2s, color .2s; }
.pol-x svg{ width:40%; height:40%; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; }
.pol.is-up .pol-x{ opacity:1; }
.pol.is-out .pol-x{ opacity:0; }
@media (hover:hover){ .pol-x:hover{ background:var(--ink-dark); color:var(--ink); } }
.pol-x:focus-visible{ outline:2px solid var(--ink-dark); outline-offset:3px; }
/* пока открыта карточка: логотип и кружок «Архив» — над затемнением (но под редактором), логотип светлый,
   кнопки шапки и реплика под головой убраны */
.is-pol .logo{ z-index:66; color:var(--ink-dark); }
.is-pol .topnav,.is-pol .topbar-side,.is-pol .tip,.is-pol .subs{ visibility:hidden; }
.is-pol .arch-btn{ z-index:66; }

/* кружок «Архив» на главной (Figma: 171 при экране 1440×803, справа внизу): серый диск и две карточки */
.arch-btn{ --ab:clamp(110px, calc(var(--u) * 14.2), 230px); position:fixed; z-index:30; right:var(--pad-x); bottom:clamp(16px, calc(var(--u) * 2.5), 40px); display:block; width:var(--ab); height:var(--ab);
  text-decoration:none; -webkit-tap-highlight-color:transparent; animation:view-in .5s ease both; }
body:not([data-view="hero"]) .arch-btn,.no-pol .arch-btn{ display:none; }
.arch-disc{ position:absolute; inset:0; border-radius:50%; background:var(--dock-bg); -webkit-backdrop-filter:var(--dock-fx); backdrop-filter:var(--dock-fx); box-shadow:var(--dock-ring); transition:transform .45s var(--spring), background-color .35s; }
.arch-mini{ position:absolute; display:block; width:60%; aspect-ratio:281/341; padding:calc(var(--ab) * .036) calc(var(--ab) * .036) 0; border-radius:2px;
  background:linear-gradient(180deg, #E1E2EA, #EBEDF1); box-shadow:0 1px 1px rgba(20,22,40,.18), 0 6px 14px rgba(20,22,40,.18); transition:transform .45s var(--spring); }
.arch-mini::after{ content:''; position:absolute; left:2%; right:2%; bottom:0; height:1px; background:rgba(66,70,168,.4); }
/* наклейки на мини-карточке — как на настоящей: место и наклон в долях карточки, ширина — 30% её ширины */
.arch-stks{ position:absolute; inset:0; pointer-events:none; }
.arch-stks img{ position:absolute; width:30%; height:auto; aspect-ratio:1; object-fit:contain; transform:translate(-50%,-50%) rotate(var(--r, 0deg)); }
.arch-mini--a{ left:-6%; top:3%; transform:rotate(-21deg); }
.arch-mini--b{ left:42%; top:21%; transform:rotate(5deg); }
.arch-ph{ display:block; aspect-ratio:1; overflow:hidden; background:#CDD0D7; box-shadow:inset 0 0 0 1px rgba(0,0,0,.08); }
.arch-ph img{ display:block; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .45s ease; }
.arch-ph img.is-on{ opacity:1; }
@media (hover:hover){
  .arch-btn:hover .arch-disc{ transform:scale(1.04); }
  .arch-btn:hover .arch-mini--a{ transform:translate(-5%,-5%) rotate(-27deg); }
  .arch-btn:hover .arch-mini--b{ transform:translate(4%,-4%) rotate(9deg); }
}
.arch-btn:focus-visible{ outline:none; }
.arch-btn:focus-visible .arch-disc{ outline:2px solid var(--fg); outline-offset:4px; }
.arch-btn.is-bump .arch-disc{ animation:arch-bump .6s var(--spring); }
@keyframes arch-bump{ 40%{ transform:scale(1.12); } }
/* полароид без мыши: кнопка видна только в фокусе с клавиатуры */
.pol-a11y{ position:fixed; z-index:31; left:50%; bottom:calc(var(--bar-res, 0px) + 20px); transform:translateX(-50%); min-height:44px; padding:0 18px; border:0; border-radius:999px; background:var(--ink); color:var(--paper); font:400 14px/1 var(--font-text); pointer-events:auto; cursor:pointer; }
.pol-a11y:not(:focus){ position:absolute; width:1px; height:1px; min-height:0; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
.no-pol .pol-a11y,.no-webgl .pol-a11y{ display:none; }

/* страница архива: сетка карточек, каждая чуть повёрнута; при наведении выпрямляется */
.archive{ position:relative; z-index:20; min-height:100vh; padding:calc(var(--arc-top, var(--hdr)) + clamp(30px, calc(var(--u) * 6), 100px)) var(--pad-x) calc(var(--corner) + 80px); color:var(--fg); }
.archive:not([hidden]){ animation:view-in .4s ease both; }
.arc-grid{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:clamp(56px, calc(var(--u) * 7.5), 110px) clamp(28px, calc(var(--u) * 4.6), 72px); max-width:1320px; margin:0 auto; padding:0; list-style:none; }
.arc-li{ position:relative; display:block; transform:translateY(var(--dy, 0px)); }
.arc-card{ transform:rotate(var(--rot, 0deg)); }
/* своя карточка — лежит ровно и чуть выше соседних (тень глубже), когда остальные слегка повёрнуты: без цвета и надписей */
.arc-card.is-mine{ z-index:1; transform:none; box-shadow:0 1px 1px rgba(20,22,40,.16), 0 6px 14px rgba(20,22,40,.14), 0 26px 46px rgba(20,22,40,.2); }
.arc-empty{ max-width:560px; margin:10vh auto 0; text-align:center; font:400 calc(var(--fs-h2) * .8)/1.15 var(--font); text-wrap:balance; }
.arc-empty p{ margin:0; }
.arc-empty .btn{ margin-top:var(--sp-30); }
.arc-note{ margin:var(--sp-40) 0 0; min-height:1.25em; text-align:center; color:var(--mute); font-size:var(--fs-caption); }
.arc-more{ height:1px; }

/* ---------- «столбик»: телефон и планшет в портретной ориентации (Figma: режим «Телефон») ----------
   Логотип, голова, реплика; кнопки — в стеклянной панели по центру внизу (Figma: «Панель (телефон)»). Папок разделов
   на главной здесь по умолчанию нет (js/content.js, heroFolders); если их включить в админке, они встают лентой над панелью.
   То же условие — в js/content.js (STACK) и css/tokens.css. */
@media (max-width:760px), (max-width:1024px) and (max-aspect-ratio:17/20){
  /* Док: слева кружок, справа стеклянная панель кнопок — одним стеклом. Размеры дока всегда одни и те же, меняется
     только наполнение: в кружке — две свежие карточки архива (главная, каталог) или голова (архив, кейс), кружок
     всегда одного размера (Figma: 114 при ширине 390); в панели слева всегда CV одного размера, справа — «Все работы»
     или «К голове» на всё остальное место. Поля по 15 (на планшете док не шире 520) */
  :root{ --bar-gap:max(var(--bar-bottom), calc(env(safe-area-inset-bottom) + 6px)); --dock-h:calc(var(--btn-h) + 20px); --dock-l:max(15px, calc(50vw - 260px));
    --dock-c:clamp(84px, calc(100vw - 268px), 114px);
    --bar:calc(var(--dock-h) + var(--bar-gap)); --corner:var(--dock-c); --corner-r:15px; }
  body[data-view="case"],body[data-view="work"]{ --corner:var(--dock-c); --corner-r:15px; }
  .topbar{ grid-template-columns:1fr; padding-top:max(var(--pad-top), env(safe-area-inset-top)); }
  .topbar-side{ position:absolute; top:max(4px, env(safe-area-inset-top)); right:8px; }
  .lang{ height:36px; font-size:15px; }
  .cv-pre{ display:none; }      /* в панели места мало: просто «CV» */
  /* стеклянная панель (стекло — --dock-bg: размытие только в кейсе и архиве, где под ней едет содержимое; на главной
     и в каталоге фон ровный, а размытие поверх движущегося визуала дорого на телефоне) */
  .topnav,body[data-view="hero"] .topnav{ position:fixed; left:auto; right:var(--dock-l); bottom:var(--bar-gap); z-index:41; justify-self:auto; width:calc(100vw - var(--dock-l) * 2 - var(--dock-c) - var(--sp-10)); gap:var(--sp-10); height:var(--dock-h); padding:var(--sp-10);
    border-radius:calc(var(--dock-h) / 2); background:var(--dock-bg); -webkit-backdrop-filter:var(--dock-fx); backdrop-filter:var(--dock-fx); box-shadow:var(--dock-ring); transform:none; transition:none; }
  .topnav .btn{ flex:1 1 0; min-width:0; }
  .topnav [data-cv],.topnav [data-sound]{ flex:none; }       /* CV — первая в разметке, значит слева; ширина — по тексту, везде одна */
  /* голова в архиве и кейсе — в кружке дока, на месте карточек и того же размера */
  .stage.is-corner,.corner-probe{ top:calc(100% - var(--bar-gap) - var(--dock-c)); left:var(--dock-l); }
  /* её реплики — облачком над кружком: растут от головы вверх, хвостик смотрит на неё; ни панель, ни кружок не закрывают */
  body[data-view="case"] .subs,body[data-view="archive"] .subs{ left:var(--dock-l); right:var(--dock-l); top:auto; bottom:calc(var(--bar-gap) + var(--dock-c) + 12px); width:auto; max-width:none; transform:none; text-align:left; font-size:16px; line-height:1.25; }
  body[data-view="case"] .subs-line,body[data-view="archive"] .subs-line{ position:relative; max-width:100%; padding:.6em .85em .65em; border-radius:18px; background:color-mix(in srgb, var(--paper) 92%, transparent); -webkit-backdrop-filter:blur(20px) saturate(1.6); backdrop-filter:blur(20px) saturate(1.6);
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--fg) 8%, transparent), 0 8px 24px rgba(0,0,0,.1); transform-origin:calc(var(--dock-c) / 2) 100%; animation:say-in .38s cubic-bezier(.34,1.4,.5,1) both; }
  body[data-view="case"] .subs-line::after,body[data-view="archive"] .subs-line::after{ content:''; position:absolute; left:calc(var(--dock-c) / 2 - 8px); top:100%; border:8px solid transparent; border-bottom-width:0; border-top-color:color-mix(in srgb, var(--paper) 92%, transparent); }
  /* плашка наклона: на чистом экране — над панелью, место под неё оставляет раскладка (TIP_SLOT в js/app.js);
     с лентой папок места внизу нет — она встаёт наверху */
  .tip{ top:max(5px, env(safe-area-inset-top)); bottom:auto; }
  .no-folders .tip{ top:auto; bottom:calc(var(--bar) + 8px); }
  body:not(.no-folders) .diag{ top:calc(58px + env(safe-area-inset-top)); }
  /* папки разделов (если включены) — горизонтальная лента; первая стоит по центру, соседние выглядывают по бокам */
  .folders{ inset:auto 0 var(--bar) 0; display:flex; align-items:flex-start; gap:22px; padding:calc(var(--mfw,170px) * .4) calc(50% - var(--mfw,170px) / 2) 8px; overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory; scrollbar-width:none; pointer-events:auto; -webkit-overflow-scrolling:touch; }
  .folders::-webkit-scrollbar{ display:none; }
  .folders .gf,.folders .gf.is-open{ position:static; flex:none; transform:none; scroll-snap-align:center; scroll-snap-stop:always; cursor:pointer; touch-action:pan-x; }
  .folders .gf:last-child:nth-child(n+3){ order:-1; }
  .folders .gf-title{ margin-left:-14%; margin-right:-14%; color:var(--mute); transition:color .25s; }
  .folders .gf.is-cur .gf-title{ color:var(--fg); }
  /* каталог (Figma: «Каталог — телефон»): проект по центру — визуал, логотип проекта, описание, «Смотреть» и лайк, точки;
     внизу панель «К голове» / CV. Ленты карточек здесь нет: проекты листаются свайпом (js/catalog.js) */
  body[data-view="work"] .topnav [data-home]{ display:inline-flex; }
  .cat{ --dots-b:calc(var(--bar) + 18px); }      /* текст проекта и точки — у самого дока: визуалу больше места */
  .cat-strip{ display:none; }
  .cat-dots{ display:flex; }
  .cat-info{ top:auto; bottom:calc(var(--dots-b) + 34px); left:var(--cpad); width:calc(100% - var(--cpad) * 2); will-change:transform, opacity; text-align:center; }
  .cat-info-in{ top:auto; bottom:0; display:flex; flex-direction:column; align-items:center; }
  .cat-logo:not(:empty){ display:block; }
  .cat-logo:not(:empty) + .cat-title{ display:none; }
  .cat-title{ max-width:none; text-wrap:balance; }
  .cat-sum{ max-width:362px; margin-top:var(--sp-15); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
  .cat-acts{ justify-content:center; margin-top:var(--sp-20); }
  /* градиент поднят: визуал уходит в цвет проекта ещё до логотипа — логотип и описание лежат на почти чистом цвете.
     Ступени маски — по плавной кривой, без заметной границы */
  .cat-fade{ top:calc(var(--info-top, 60%) - 170px); height:auto; bottom:0;
    -webkit-mask-image:linear-gradient(to bottom, transparent, rgba(0,0,0,.12) 34px, rgba(0,0,0,.38) 70px, rgba(0,0,0,.68) 108px, rgba(0,0,0,.9) 145px, #000 185px);
    mask-image:linear-gradient(to bottom, transparent, rgba(0,0,0,.12) 34px, rgba(0,0,0,.38) 70px, rgba(0,0,0,.68) 108px, rgba(0,0,0,.9) 145px, #000 185px); }
  .cat-hero{ will-change:transform; }
  .cat-play{ right:var(--cpad); bottom:calc(var(--dots-b) - 10px); width:40px; }
  .case-end{ padding-bottom:calc(var(--bar) + 120px); }
  .site-footer{ padding-bottom:calc(var(--bar-gap) + var(--dock-c) + 24px); }
  /* полароид: кружок «Архив» — в доке слева от кнопок, того же стекла и размера, что кружок с головой; есть и в каталоге;
     голова и реплика на главной встают над ним (barH() в js/app.js) */
  .arch-btn{ --ab:var(--dock-c); left:var(--dock-l); right:auto; bottom:var(--bar-gap); }
  body[data-view="work"]:not(.no-pol) .arch-btn{ display:block; }
  .arch-mini--a{ left:1%; top:-2%; }
  .arch-mini--b{ left:44%; top:20%; }
  .is-pol .arch-btn{ visibility:hidden; }
  .folders{ bottom:var(--bar-res, var(--bar)); }
  .no-folders .tip{ bottom:calc(var(--bar-res, var(--bar)) + 8px); }
  /* архив: две колонки лесенкой (правая ниже), внизу — голова в кружке, CV и «Все работы» */
  .archive{ padding:calc(var(--hdr) + 24px) 12px calc(var(--bar-gap) + var(--dock-c) + 40px); }
  .arc-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); gap:30px 10px; padding-bottom:22%; }
  .arc-li:nth-child(even){ transform:translateY(calc(var(--dy, 0px) + 24%)); }
  /* редактор полароида: окно с репликой — внизу во всю ширину */
  .pol-dlg{ bottom:max(10px, env(safe-area-inset-bottom)); padding:18px; gap:14px; border-radius:32px; }
  .pol-acts{ width:100%; gap:10px; }
  .pol-acts .btn{ flex:1; min-width:0; }
  .pol-x{ top:max(10px, env(safe-area-inset-top)); right:10px; width:44px; height:44px; }
}
/* планшет в портрете: архив в три колонки, средняя ниже */
@media (min-width:600px) and (max-width:1024px) and (max-aspect-ratio:17/20){
  .arc-grid{ grid-template-columns:repeat(3, minmax(0, 1fr)); gap:40px 24px; }
  .arc-li:nth-child(even){ transform:translateY(var(--dy, 0px)); }
  .arc-li:nth-child(3n+2){ transform:translateY(calc(var(--dy, 0px) + 18%)); }
}
/* планшет в портрете: та же раскладка, что на телефоне */
@media (min-width:600px) and (max-width:1024px) and (max-aspect-ratio:17/20){
  .cat-info{ width:min(calc(100% - 40px), 560px); left:max(20px, calc(50% - 280px)); }
}
/* ---------- узкий экран: кейс в одну колонку ---------- */
@media (max-width:760px){
  .case-top{ padding-top:calc(var(--hdr) + var(--sp-20)); }
  .cover-card{ aspect-ratio:auto; padding-bottom:var(--sp-20); }
  .cover-text{ width:auto; padding:var(--sp-20) var(--sp-20) 0; }
  .cover-visual{ position:relative; right:auto; top:auto; width:86%; margin:var(--sp-10) auto 0; }
  .facts-card{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--sp-30) var(--sp-15); padding:var(--sp-30) var(--sp-20); }
  .case-results,.case-tldr{ grid-template-columns:minmax(0,1fr); gap:var(--sp-30); }
  .case-blocks,.case-blocks > .blk + .blk,.case-tags{ margin-top:var(--sp-80); }
  .blk-gallery{ grid-template-columns:minmax(0,1fr); }
  .blk-gallery.shape-phone{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--sp-15); }
  .blk-gallery.shape-card{ grid-template-columns:minmax(0,1fr); }
  .blk-idea{ grid-template-columns:repeat(3,minmax(0,1fr)); column-gap:var(--sp-10); row-gap:var(--sp-30); }
  .idea-text{ grid-area:1 / 1 / 2 / 4; max-width:none; }
  .idea-step{ grid-row:2; }
  .blk-split{ grid-template-columns:minmax(0,1fr); gap:var(--sp-30); }
  .blk-split.side-right .split-media{ order:0; }
  .split-media.shape-phone .tile-box{ width:min(72%, 330px); }
  .blk-metrics,.blk-metrics.has-title > .metrics-row{ grid-template-columns:minmax(0,1fr); justify-content:stretch; }
  .tile-box img{ position:static; display:block; width:100%; height:auto; max-height:72vh; }
  .tile-box.is-cover img{ height:100%; }
  .case-end{ grid-template-columns:minmax(0,1fr); }
  .case-next{ order:-1; padding:var(--sp-80) 0 0; }
  .vcard{ --vh:clamp(130px, 40vw, 170px); grid-template-columns:minmax(0,1fr); justify-items:center; text-align:center; padding:var(--sp-60) var(--sp-20) var(--sp-30); margin-top:var(--sp-60); }
  .vcard-acts{ justify-content:center; }
  /* на телефоне подводка и облачко — над кружком: голова говорит сверху вниз, хвостик смотрит на неё */
  .vcard-body{ display:contents; }
  .vcard-top{ order:-1; width:100%; margin-bottom:var(--sp-20); }
  .vcard-kicker{ margin:0; }
  .vcard-say{ left:50%; bottom:0; max-width:min(100%, 20em); transform:translateX(-50%); transform-origin:50% 100%; }
  .vcard-say::after{ right:auto; left:calc(50% - 8px); bottom:auto; top:100%; border-width:8px 8px 0; border-color:#fff transparent transparent; }
  .vcard:not(.is-said) .vcard-say{ transform:translateX(-50%) scale(.85); }
}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ animation:none !important; transition-duration:.01ms !important; transition-delay:0s !important; }
  .js-rv .rv{ opacity:1; transform:none; }
}
