/* =========================================================
   ПРЫТКОВ — портфолио-досье
   токены → база → раскладка → компоненты → анимации → @media
   ========================================================= */

/* ---------- 1. токены ---------- */
:root {
  /* палитра — только эти цвета */
  --bg: #F6F2AF;
  --surface: #F6F6F4;
  --text: #111111;
  --muted: #6E6D5F;
  --accent: #080D3A;
  --border: rgba(17,17,17,.9);
  --radius: 28px;

  --lavender: #E3E5F4;
  --halftone: #25241B;
  --dot: rgba(8,13,58,.22);
  --sepia-0: #0E0D0B; --sepia-1: #EFE6CF; --intro-bg: #0B0A08;
  --negative: #C4C7CA;
  --burn: #F2B45A;
  --olive: #A09F5F; --olive-deep: #474631; --olive-btn: #C5BF73; --olive-torn: #827B43;
  --rose: #C99A86; --rose-deep: #2B1611; --rose-ink: #E9D7C0;
  --night: #121212; --night-2: #0B0B0B; --text-inv: #F2F2F2; --muted-inv: #8A8A8A;
  --about: #E9E9E9;
  --forest: #2A281C; --gold: #C0C07D;

  --radius-tab: 10px; --radius-sm: 4px;
  --shadow-paper: 0 1px 0 rgba(0,0,0,.04), 0 18px 40px -18px rgba(30,28,15,.35);

  --gutter: clamp(16px, 1.55vw, 28px);
  --gutter-y: clamp(14px, 1.53vw, 26px);
  --header-h: clamp(56px, 7.2vh, 76px);
  --maxw: 1760px;
  --vh: 1vh;
  --safe-t: env(safe-area-inset-top, 0px); --safe-b: env(safe-area-inset-bottom, 0px);

  --fs-ui: clamp(12px, .92vw, 14px);
  --fs-mono: clamp(10px, .76vw, 11.5px);
  --fs-name: 10.7vw;
  --fs-manifesto: clamp(48px, 11.2vw, 240px);
  --fs-h2: clamp(48px, 8.4vw, 172px);
  --fs-about: clamp(20px, 1.95vw, 34px);

  --ease-expo: cubic-bezier(.16,1,.3,1);
  --ease-quint: cubic-bezier(.22,1,.36,1);
  --ease-sheet: cubic-bezier(.32,.72,0,1);
  --ease-inout: cubic-bezier(.76,0,.24,1);
  --ease-over: cubic-bezier(.34,1.56,.64,1);
  --ease-type: cubic-bezier(.22,.85,.24,1);

  --z-gl: 0; --z-content: 10; --z-header: 30; --z-menu: 40; --z-grain: 60; --z-intro: 90; --z-intro-ui: 95;

  /* переменные раскладки пишет JS (px); здесь значения по умолчанию */
  --page-bg: var(--bg);
  --fig-h: 331svh;
  --fig-w: calc(var(--fig-h) * .29163);
  --fig-x: calc(39.1vw - var(--fig-w) * .232);
  --fig-y: calc(38.2svh - var(--fig-h) * .12);
  --hero-track: 360svh;
  --torn-h: clamp(56px, 7vw, 110px);
  --menu-w: 54px; --menu-h: 36px;
  --plane-w: clamp(96px, 10vw, 190px); /* длина бумажного самолётика (нос → хвост) */
  --ff-sans: "Inter Tight", "Helvetica Neue", Arial, sans-serif;
  --ff-mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
  --ff-serif: "Source Serif 4", Georgia, serif; /* у Newsreader нет кириллицы */
}

html[data-theme="light"]  { --ink: var(--text);     --ink-muted: var(--muted); }
html[data-theme="dark"]   { --ink: var(--text-inv); --ink-muted: var(--muted-inv); }
html[data-theme="forest"] { --ink: #EDEBD8;         --ink-muted: #8C8A6E; }

/* ---------- 2. база ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { overflow-x: clip; }
html {
  -webkit-text-size-adjust: 100%;
  font-synthesis: none;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scrollbar-gutter: stable;
}
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }
body {
  margin: 0;
  isolation: isolate; /* свой контекст наложения: футер с z −1 ложится над боксом body — иначе body перехватывает клики и hover */
  background: var(--page-bg);
  color: var(--text);
  font: 400 var(--fs-ui)/1.25 var(--ff-sans);
  letter-spacing: -.005em;
}
img, video, svg { display: block; max-width: 100%; }
img, video { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
p, h1, h2, h3, ul, figure, pre { margin: 0; }
ul { list-style: none; padding: 0; }
:focus-visible { outline: 1.5px solid currentColor; outline-offset: 3px; }
.sr-only { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
::selection { background: var(--accent); color: var(--bg); }

/* ---------- 3. раскладка: фиксированные слои ---------- */
#gl {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: var(--z-gl); pointer-events: none;
}
main { position: relative; z-index: var(--z-content); }
.grain {
  position: fixed; inset: -50%; z-index: var(--z-grain); pointer-events: none;
  opacity: .07; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.2 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- 4. шапка ---------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-header);
  height: 0; pointer-events: none;
  color: var(--ink);
  font-size: var(--fs-ui);
  transition: color .4s var(--ease-quint);
}
.site-header a, .site-header button { pointer-events: auto; }
.logo {
  position: absolute; left: var(--gutter); top: calc(var(--gutter-y) + var(--safe-t));
  display: flex; align-items: center; gap: 8px;
}
.emblem { width: 36px; height: auto; aspect-ratio: 842 / 718; fill: currentColor; flex: none; }
.wordmark {
  font: 400 14px/.92 var(--ff-serif);
  text-transform: uppercase; letter-spacing: .05em;
  --brv-w: .56em; --brv-t: -.24em; /* мелкому кеглю шарф крупнее — иначе не читается */
}
/* «Й» знака: вместо краткой — шарф зайца из эмблемы (#scarf), летит назад по ветру */
.yot { position: relative; display: inline-block; }
.brv {
  position: absolute; left: 50%; top: var(--brv-t, -.15em);
  width: var(--brv-w, .36em); aspect-ratio: 242.2 / 106.4; height: auto;
  fill: currentColor; overflow: visible; pointer-events: none;
  transform: translateX(-58%) rotate(-6deg);
}

/* меню в скобках */
.menu-wrap {
  position: absolute; right: var(--gutter); top: calc(var(--gutter-y) + var(--safe-t) - 8px);
  z-index: var(--z-menu); pointer-events: auto;
}
.menu-frame {
  position: relative; width: var(--menu-w);
  transition: width .3s var(--ease-inout);
}
.menu-wrap.is-open .menu-frame { width: 132px; transition: width .42s var(--ease-quint); }
.c {
  position: absolute; width: 8px; height: 8px; border: 0 solid currentColor; pointer-events: none;
  transition: transform .35s var(--ease-quint);
}
.c--tl { left: 0; top: 0; border-left-width: 1px; border-top-width: 1px; }
.c--tr { right: 0; top: 0; border-right-width: 1px; border-top-width: 1px; }
.c--bl { left: 0; bottom: 0; border-left-width: 1px; border-bottom-width: 1px; }
.c--br { right: 0; bottom: 0; border-right-width: 1px; border-bottom-width: 1px; }
.menu-btn {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; height: var(--menu-h); font-weight: 500;
}
.menu-btn::after { content: ''; position: absolute; inset: -4px; }
.menu-wrap.is-open .menu-btn { justify-content: flex-end; padding-right: 12px; }
.menu-grid {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .3s var(--ease-inout);
}
.menu-wrap.is-open .menu-grid { grid-template-rows: 1fr; transition: grid-template-rows .42s var(--ease-quint); }
.menu-list { min-height: 0; overflow: hidden; padding: 0 12px; }
.menu-list li:last-child { padding-bottom: 12px; }
.menu-list a { display: block; font: 500 13px/18px var(--ff-sans); padding: 1px 0; white-space: nowrap; }
.menu-list a:hover { color: var(--ink-muted); }

/* ---------- 5. вступление ---------- */
.intro { display: none; }
html.js.intro-short .intro-poster { clip-path: none; }
html.js .intro {
  display: block; position: fixed; inset: 0; z-index: var(--z-intro-ui);
  height: 100dvh; background: var(--intro-bg); color: var(--sepia-1);
  pointer-events: none;
}
html.js.gl-intro .intro { background: transparent; }
html.js.intro-done .intro,
html.js.intro-revealed .intro { display: none; } /* uReveal = 1: постер не должен вернуться до finishIntro */
.intro-video { position: absolute; left: 0; top: 0; width: 2px; height: 2px; opacity: 0; pointer-events: none; }
.intro-poster, .intro-poster img { position: absolute; inset: 0; width: 100%; height: 100%; }
.intro-poster img { object-fit: cover; object-position: 60% 42%; } /* = VID.d.px/py */
@media (max-aspect-ratio: 4/5) { .intro-poster img { object-position: 60% 38%; } } /* = VID.m.px/py */
.intro-poster { clip-path: inset(41% 0 41% 0); } /* uLetterbox .18 на первом кадре */
html.gl-intro .intro-poster { visibility: hidden; }
.letterbox { display: none; }
.skip {
  position: absolute; right: var(--gutter); bottom: calc(var(--gutter) + var(--safe-b));
  pointer-events: auto; font: 400 11px/1 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase;
  color: var(--sepia-1); padding: 12px;
  width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.skip:focus-visible { width: auto; height: auto; clip-path: none; }
html.is-intro { overflow: clip; }

/* ---------- 6. hero ---------- */
.hero { position: relative; height: var(--hero-track); }
.hero::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle, var(--dot) 1px, transparent 1.4px) 0 0 / 22px 22px;
  transition: opacity 1.2s var(--ease-inout);
}
html.is-intro .hero::before { opacity: 0; }
.hero-stage {
  position: sticky; top: 0; height: 100svh; overflow: clip;
}
.figure {
  position: absolute; left: 0; top: 0;
  width: var(--fig-w); height: var(--fig-h); max-width: none;
  transform: translate3d(var(--fig-x), calc(var(--fig-y) + var(--py, 0px)), 0);
  will-change: transform;
  filter: grayscale(1) contrast(1.35);
  -webkit-mask-image: radial-gradient(circle, #000 1.25px, transparent 1.75px);
  -webkit-mask-size: 4px 4px;
  mask-image: radial-gradient(circle, #000 1.25px, transparent 1.75px);
  mask-size: 4px 4px;
}
html.gl .figure { opacity: 0; }
.hero-screen {
  position: absolute; left: 0; top: 0; width: 100%; height: 100svh; pointer-events: none;
}
.hero-copy {
  position: absolute; left: var(--gutter); top: 132px;
  font-size: 14.5px; line-height: 1.35; z-index: 13;
}
.hero-role { font-weight: 600; }
.hero-copy p { overflow: hidden; }
.hero-copy span { display: inline-block; }
.name {
  position: absolute; left: 54vw; bottom: 11svh;
  font: 800 var(--fs-name)/.82 var(--ff-sans); letter-spacing: -.035em;
  text-rendering: optimizeLegibility; white-space: nowrap; text-transform: uppercase;
  color: var(--accent);
}
.name--ink { z-index: 11; }
.line { display: block; overflow: hidden; padding: .26em .06em .06em 0; margin: -.26em 0 -.06em; } /* .26em сверху — под кратку «Й» */
.line > span { display: inline-block; will-change: transform; }
/* спрятанная строка: на свою высоту + запас маски сверху (.26em + .06em снизу) — иначе кратка «Й» торчит снизу из маски */
:root { --line-off: translateY(calc(100% + .34em)); }

.manifesto {
  position: absolute; left: 0; top: 108svh; width: 100%;
  height: calc(14 * .9 * var(--fs-manifesto));
  font: 600 var(--fs-manifesto)/.9 var(--ff-sans); letter-spacing: -.045em;
  color: var(--accent); pointer-events: none;
  text-rendering: optimizeLegibility;
}
.manifesto--ink { z-index: 11; }
.manifesto--lav { z-index: 12; color: var(--lavender); }
.manifesto .w {
  position: absolute; white-space: nowrap;
  left: calc(var(--x) * 1vw); top: calc(var(--r) * .9em);
}
.manifesto .w:nth-child(1)  { --x: 35; --r: 0; }
.manifesto .w:nth-child(2)  { --x: 2;  --r: 1; }
.manifesto .w:nth-child(3)  { --x: 20; --r: 2; }
.manifesto .w:nth-child(4)  { --x: 70; --r: 2; }
.manifesto .w:nth-child(5)  { --x: 48; --r: 3; }
.manifesto .w:nth-child(6)  { --x: 2;  --r: 4; }
.manifesto .w:nth-child(7)  { --x: 16; --r: 4; }
.manifesto .w:nth-child(8)  { --x: 35; --r: 5; }
.manifesto .w:nth-child(9)  { --x: 2;  --r: 6; }
.manifesto .w:nth-child(10) { --x: 55; --r: 7; }
.manifesto .w:nth-child(11) { --x: 27; --r: 8; }
.manifesto .w:nth-child(12) { --x: 20; --r: 9; }
.manifesto .w:nth-child(13) { --x: 50; --r: 10; }
.manifesto .w:nth-child(14) { --x: 10; --r: 11; }
.manifesto .w:nth-child(15) { --x: 40; --r: 12; }
.manifesto .w:nth-child(16) { --x: 55; --r: 13; }

/* сэндвич: лавандовая копия видна только внутри силуэта фигуры ∩ сетки точек 4px */
html.js .manifesto--lav {
  -webkit-mask-image: url(media/figure.webp), radial-gradient(circle, transparent 1px, #000 1.3px);
  -webkit-mask-size: var(--fig-w) var(--fig-h), 4px 4px;
  -webkit-mask-position: var(--mx, -9999px) var(--my, 0px), 0 0;
  -webkit-mask-repeat: no-repeat, repeat;
  -webkit-mask-composite: source-in;
  mask-image: url(media/figure.webp), radial-gradient(circle, transparent 1px, #000 1.3px);
  mask-size: var(--fig-w) var(--fig-h), 4px 4px;
  mask-position: var(--mx, -9999px) var(--my, 0px), 0 0;
  mask-repeat: no-repeat, repeat;
  mask-composite: intersect;
}
.manifesto--lav { display: none; }
html.js .manifesto--lav { display: block; }

/* ---------- 7. рваные края ---------- */
.torn { position: absolute; left: 0; right: 0; height: var(--torn-h); pointer-events: none; }
.torn::before, .torn::after {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 100%;
  -webkit-mask: url(media/torn-edge.webp) repeat-x;
  -webkit-mask-size: auto 100%;
  -webkit-mask-position: var(--tb, 0px) 0;
  mask: url(media/torn-edge.webp) repeat-x;
  mask-size: auto 100%;
  mask-position: var(--tb, 0px) 0;
}
.torn::after { top: 12px; -webkit-mask-position: calc(var(--tb, 0px) * 1.35 + 37%) 0; mask-position: calc(var(--tb, 0px) * 1.35 + 37%) 0; }
.torn--top { top: calc(var(--torn-h) * -1 + 1px); }
.torn--top::before { background: var(--olive-torn); }
.torn--top::after { background: var(--night); }
.torn--bottom { bottom: -1px; }
.torn--bottom::before { background: var(--olive-deep); }
.torn--bottom::after { background: var(--forest); height: calc(100% - 11px); }
/* W4 (html.gl-torn): бокс .torn остаётся источником rect, живой край рисуется на canvas (z0) под main.
   DOM-слои над canvas уходят из зоны края, а шейдер перерисовывает их пиксель в пиксель:
   точки hero (сетка 22px от бокса hero) над верхним краем (вместе с зоной подъёма --torn-ext), цвет contact + бумага (тайл от бокса contact) над нижним краем. */
html.gl-torn .torn::before, html.gl-torn .torn::after { visibility: hidden; }
html.gl-torn .hero::before { /* --torn-ext: зона, в которую живой верхний край поднимается с опережением скролла (JS, px) */
  -webkit-mask: linear-gradient(#000, #000) 0 0 / 100% calc(100% - var(--torn-h) - var(--torn-ext, 0px) + 1px) no-repeat;
  mask: linear-gradient(#000, #000) 0 0 / 100% calc(100% - var(--torn-h) - var(--torn-ext, 0px) + 1px) no-repeat;
}
html.gl-torn .contact { background: linear-gradient(var(--about), var(--about)) 0 0 / 100% calc(100% - var(--torn-h) + 1px) no-repeat; }
html.gl-torn .contact.paper::before { bottom: calc(var(--torn-h) - 1px); }

/* ---------- 8. общая типографика ---------- */
.h2 {
  font: 600 var(--fs-h2)/.92 var(--ff-sans); letter-spacing: -.045em;
  text-rendering: optimizeLegibility;
}
.label, .mono {
  font: 400 11px/1.35 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase;
}
.paper { position: relative; isolation: isolate; }
.paper::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url(media/paper.webp) 0 0 / 512px repeat; opacity: .55;
}

/* кнопка-скобка («Напишите мне») */
.bracket-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-width: 150px; height: 40px; padding: 0 18px;
  font: 400 12px/1 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase;
}

/* ---------- 9. работы — полноэкранные проекты, смена лезвием рифлёного стекла (W5) ---------- */
/* секция закрепляется (sticky-стейдж 100svh), высота — трек прогресса P ∈ [−1, N−1]: --works-track (JS, px).
   Кадры рисует W5 на общем canvas под main (html.gl-works → фон секции прозрачный); без GL — canvas обложек в .works-art + шторка clip-path. */
.works {
  --wt: 7vw;                           /* размер заголовка */
  --card-w: clamp(320px, 30vw, 520px);
  --card-pad: clamp(20px, 1.95vw, 32px); /* 28px при 1440, 32px при 1920 (таблица раздела 5) */
  --glass-blur: 18px;
  --wp: 0;                             /* прогресс 0..1 по всем проектам, пишет JS */
  --slide-fs: clamp(40px, 3.6vw, 72px);
  --par: 6%;                           /* горизонтальный параллакс кадров фолбэка (= uPar) */
  position: relative; z-index: 1; height: var(--works-track, 500svh);
  background: var(--night); color: var(--text-inv);
}
html.gl-works .works { background: transparent; }
.works-stage { position: sticky; top: 0; height: 100svh; overflow: clip; }

/* фолбэк без GL: те же canvas обложек, следующий открывается шторкой справа налево */
.works-art, .works-edge { display: none; }
html:not(.gl-works):not(.reduced) .works-art { display: block; position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.works-art canvas {
  position: absolute; top: 0; left: calc(var(--par) * -1); width: calc(100% + 2 * var(--par)); height: 100%;
  object-fit: cover; visibility: hidden;
  transform: translate3d(var(--tx, 0px), 0, 0);
}
.works-art canvas.is-a { visibility: visible; z-index: 1; }
.works-art canvas.is-b { visibility: visible; z-index: 2; clip-path: inset(0 0 0 var(--clip, 100%)); }
html:not(.gl-works):not(.reduced) .works-edge {
  display: block; position: absolute; top: 0; bottom: 0; left: 0; z-index: 1; width: 1px;
  background: rgba(242,242,242,.6); transform: translate3d(var(--ex, 0px), 0, 0);
  opacity: 0; pointer-events: none;
}
.works-edge.is-on { opacity: 1; }

.works-title {
  position: absolute; left: var(--gutter); top: calc(var(--gutter-y) + 64px + var(--safe-t)); z-index: 2;
  font-size: var(--wt); width: max-content; pointer-events: none;
}

/* стеклянная плашка (liquid glass): у предков нет transform / filter — иначе backdrop-filter не видит canvas */
.works-card {
  position: absolute; left: var(--gutter); bottom: 11svh; z-index: 3;
  width: var(--card-w); padding: var(--card-pad);
  border-radius: var(--radius);
  background: rgba(242,242,242,.04);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  backdrop-filter: blur(var(--glass-blur)) saturate(130%);
  box-shadow: inset 0 1px 1px rgba(242,242,242,.12);
}
.works-card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(135deg, rgba(242,242,242,.40), rgba(242,242,242,.12) 20%, rgba(242,242,242,0) 40%, rgba(242,242,242,0) 60%, rgba(242,242,242,.12) 80%, rgba(242,242,242,.40));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.works-list { display: grid; margin: 0; padding: 0; list-style: none; }
.slide { grid-area: 1 / 1; min-width: 0; opacity: 0; pointer-events: none; } /* высота плашки = максимальный слайд */
.slide.is-active, .slide.is-leaving { opacity: 1; }
.slide.is-active { pointer-events: auto; }
.slide-top, .slide-meta {
  font: 400 12px/1.4 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted-inv);
}
.slide-top { display: flex; justify-content: space-between; gap: 16px; }
.slide-num { color: var(--text-inv); }
.slide-title {
  margin: .42em 0 .3em;
  font: 600 var(--slide-fs)/.92 var(--ff-sans); letter-spacing: -.045em; text-rendering: optimizeLegibility;
}
.slide-title .ln { display: block; overflow: hidden; padding-bottom: .1em; margin-bottom: -.1em; }
.slide-title .ln > span { display: block; }
.slide-title .ch { display: inline-block; } /* буквы — отдельные элементы морфа в проект (раздел 18) */
.work-soon {
  display: flex; align-items: center; gap: 10px; margin-top: 18px;
  font: 400 11px/1.4 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--olive-btn);
}
.work-soon i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: pulse 1.8s var(--ease-inout) infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.slide-link {
  display: inline-flex; align-items: center; gap: 10px; height: 40px; margin-top: 18px; padding: 0 18px;
  border-radius: 999px; background: rgba(242,242,242,.04); box-shadow: inset 0 0 0 1px rgba(242,242,242,.2);
  font: 400 11px/1 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase;
  transition: background .4s var(--ease-quint);
}
.slide-link > span { display: inline-flex; align-items: center; gap: 10px; } /* текст отдельно от фона пилюли — у морфа это две пары */
.slide-link i { font-style: normal; display: inline-block; transition: transform .4s var(--ease-quint); }

/* смена проекта: строки названия уходят/приходят по направлению скролла (--i — номер строки) */
.slide-title .ln:nth-child(2) > span { --i: 1; }
html.js:not(.reduced) .slide .ln > span { transform: translateY(105%); }
html.js:not(.reduced) .slide.from-top .ln > span { transform: translateY(-105%); }
html.js:not(.reduced) .slide.is-active .ln > span { transform: none; transition: transform .9s var(--ease-expo) calc(.12s + var(--i, 0) * .06s); }
html.js:not(.reduced) .slide.is-leaving .ln > span { transform: translateY(-105%); transition: transform .5s var(--ease-inout) calc(var(--i, 0) * .04s); }
html.js:not(.reduced) .works-list[data-dir="up"] .slide.is-leaving .ln > span { transform: translateY(105%); }
html.js:not(.reduced) .slide :is(.slide-top, .slide-meta, .work-soon, .slide-link) { opacity: 0; }
html.js:not(.reduced) .slide.is-active :is(.slide-top, .slide-meta, .work-soon, .slide-link) { opacity: 1; transition: opacity .6s var(--ease-quint) .18s; }
html.js:not(.reduced) .slide.is-leaving :is(.slide-top, .slide-meta, .work-soon, .slide-link) { opacity: 0; transition: opacity .3s var(--ease-quint); }
/* первое появление плашки (P ≥ −0.5); после входа transform снят — во время скролла его нет */
html.js:not(.reduced):not(.fs) .works-card { opacity: 0; translate: 0 24px; transition: opacity .9s var(--ease-expo), translate .9s var(--ease-expo); }
html.js:not(.reduced) .works-card.card-in { opacity: 1; translate: none; }

.works-count {
  position: absolute; right: var(--gutter); bottom: 11svh; z-index: 2;
  font: 400 13px/1.4 var(--ff-mono); letter-spacing: .06em; color: var(--muted-inv); pointer-events: none;
}
.works-count b { font-weight: 400; color: var(--text-inv); }
.works-progress {
  position: absolute; left: var(--gutter); right: var(--gutter); bottom: 5svh; z-index: 2;
  display: flex; align-items: center; gap: 16px; pointer-events: none;
  font: 400 11px/1.4 var(--ff-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted-inv);
}
.works-scroll { min-width: 5.6em; } /* «Листайте» ↔ «Дальше»: трек не сдвигается */
.works-track { position: relative; flex: 1; height: 1px; background: rgba(242,242,242,.14); }
.works-track s {
  position: absolute; top: 50%; width: 1px; height: 8px; margin: -4px 0 0 -.5px;
  background: rgba(242,242,242,.3); transition: background .4s var(--ease-quint);
}
.works-track s:nth-child(1) { left: 0; }
.works-track s:nth-child(2) { left: 33.333%; }
.works-track s:nth-child(3) { left: 66.667%; }
.works-track s:nth-child(4) { left: 100%; }
.works-track s.is-on { background: var(--text-inv); }
.works-track b {
  position: absolute; top: 50%; left: calc(var(--wp) * 100%);
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%;
  background: var(--text-inv); box-shadow: 0 0 12px rgba(242,242,242,.5);
}

/* ---------- 12. обо мне ---------- */
.about {
  background: var(--about); color: var(--text);
  padding: 22svh var(--gutter) 16svh;
  min-height: 100svh;
}
.about-text { width: 52vw; max-width: 760px; font: 400 var(--fs-about)/1.16 var(--ff-sans); letter-spacing: -.01em; }
.about-text .label { color: var(--muted); margin-bottom: 18px; }
.about-text p + p { margin-top: 1.16em; }

/* инструменты: «Мои инструменты & [док] ваш бренд.» — док как в macOS: иконки растут от низа, соседи расходятся (JS: --s, --dx) */
.tools { --icon: clamp(44px, 4.4vw, 84px); --gap: calc(var(--icon) * .26); width: fit-content; margin-bottom: 16svh; }
.tools-line { font: 500 calc(var(--icon) * 1.32)/.9 var(--ff-sans); letter-spacing: -.045em; white-space: nowrap; text-rendering: optimizeLegibility; }
.tools-line--end { text-align: right; }
.dock {
  position: relative; display: flex; align-items: flex-end; gap: var(--gap);
  height: calc(var(--icon) * 1.7); padding-bottom: calc(var(--icon) * .2); margin: 0; list-style: none;
}
.dock-item { position: relative; flex: none; width: var(--icon); height: var(--icon); translate: calc(var(--dx, 0) * 1px) 0; }
.dock-icon {
  position: relative; display: grid; place-items: center; width: 100%; height: 100%;
  border-radius: 23%; background: var(--bg); overflow: hidden; outline: none;
  scale: var(--s, 1); transform-origin: 50% 100%;
  box-shadow: 0 1px 1px rgba(0,0,0,.06), 0 6px 12px -6px rgba(0,0,0,.35), 0 14px 24px -14px rgba(0,0,0,.25);
}
.dock-icon::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.2), rgba(255,255,255,0) 45%, rgba(0,0,0,.07));
  box-shadow: inset 0 0 0 .5px rgba(0,0,0,.14), inset 0 1px 0 rgba(255,255,255,.22);
}
.dock-icon:focus-visible { box-shadow: 0 0 0 2px var(--about), 0 0 0 4px var(--text); }
.dock-glyph { width: 58%; height: 58%; }
.dock-glyph--full { position: absolute; inset: 0; width: 100%; height: 100%; }
.dock-tip {
  position: absolute; left: 50%; top: calc(100% + 7px); translate: -50% -4px;
  padding: 4px 7px; border-radius: 6px; background: rgba(255,255,255,.8); color: var(--muted);
  font: 500 11px/1 var(--ff-sans); white-space: nowrap; pointer-events: none;
  box-shadow: 0 2px 8px -3px rgba(0,0,0,.22); opacity: 0; transition: opacity .2s, translate .25s var(--ease-quint);
}
.dock-item:hover .dock-tip, .dock-icon:focus-visible + .dock-tip, .dock-item.is-tip .dock-tip { opacity: 1; translate: -50% 0; }

/* ---------- 13. контакты ---------- */
.contact {
  background: var(--about); text-align: center;
  padding: 22svh var(--gutter) calc(var(--torn-h) + 22svh);
  display: flex; flex-direction: column; align-items: center;
}
.contact-title { font: 800 clamp(40px, 6.4vw, 120px)/.92 var(--ff-sans); letter-spacing: -.035em; max-width: 12ch; }
/* облёт самолётика (z-слои в контексте .paper): буквы — z1; самолётик сзади кольца — z0 (за буквами), спереди — z4 (поверх).
   На заголовке и span-ах нет transform/opacity/filter — иначе z-index перестанет сравниваться с самолётиком */
.ct-w, .ct-q { position: relative; z-index: 1; }
.contact-tg { margin-top: calc(var(--plane-w) * .34 + 44px); } /* место под севший самолётик */
/* полка: волосок по верху кнопки между уголками — на него садится самолётик */
.contact-tg::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: currentColor;
  transform: scaleX(0); transition: transform .6s var(--ease-expo);
}
.contact.pl-ledge .contact-tg::before { transform: scaleX(1); }
.contact-mail {
  position: relative; /* над слоем тени/пунктира (z0) */
  margin-top: 22px; font: 400 12px/1 var(--ff-mono); letter-spacing: .06em; color: var(--muted);
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px;
}
.contact-mail:hover { color: var(--text); }

/* бумажный самолётик: 4 грани на CSS 3D (крылья + стенки киля), кадр, свет и тень считает main.js */
.contact-fx {
  position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;
  z-index: 0; pointer-events: none;
}
.trail {
  fill: none; stroke: rgba(17,17,17,.3); stroke-width: 1.25; stroke-dasharray: 1.5 7; stroke-linecap: round;
  transition: opacity 1s var(--ease-quint);
}
.trail-reveal { fill: none; stroke: #fff; stroke-width: 8; }
.contact.pl-trail-off .trail { opacity: 0; }
.contact.pl-throw .trail { transition: none; } /* пунктир броска — сразу, без проявления за 1s */
.plane-shadow { fill: #1B1A12; opacity: 0; }
.plane {
  position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 0; /* после svg в DOM → над тенью и пунктиром */
  pointer-events: none; visibility: hidden;
  transform-style: preserve-3d; perspective: 1000px;
}
.contact.pl-on .plane { visibility: visible; }
.contact.pl-front .plane { z-index: 4; }
.pf {
  position: absolute; left: 0; top: 0; width: 100px; height: 100px;
  transform-origin: 0 0; backface-visibility: visible;
  clip-path: polygon(0 0, 100% 0, 0 100%); /* (0,0) — хвост у сгиба, (100,0) — нос, (0,100) — законцовка / низ киля */
  background-color: rgb(var(--c, 233 232 228));
  background-size: 100% 100%, 100% 100%, 90px;
  background-blend-mode: normal, normal, multiply;
}
/* крыло: линия второго сгиба от носа + светлая свежая кромка + тонкий задний срез */
.pf--wl, .pf--wr {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M100 0L0 56' stroke='rgba(70,62,38,.26)' stroke-width='.8' fill='none'/%3E%3Cpath d='M100 0L0 100' stroke='rgba(255,255,255,.85)' stroke-width='1.6' fill='none'/%3E%3Cpath d='M0 0L0 100' stroke='rgba(70,62,38,.18)' stroke-width='1.2' fill='none'/%3E%3C/svg%3E"),
    linear-gradient(to bottom, rgba(40,35,20,.14), rgba(40,35,20,0) 24%),
    url(media/paper.webp);
}
/* стенка киля: край внутреннего слоя бумаги */
.pf--kl, .pf--kr {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M100 0L0 52' stroke='rgba(70,62,38,.22)' stroke-width='.9' fill='none'/%3E%3Cpath d='M100 0L0 100' stroke='rgba(255,255,255,.55)' stroke-width='1.2' fill='none'/%3E%3C/svg%3E"),
    linear-gradient(to bottom, rgba(40,35,20,.12), rgba(40,35,20,0) 30%),
    url(media/paper.webp);
}

/* ---------- 14. футер — монументальная подпись ---------- */
/* Сцена лежит ПОД main (z −1 < canvas z0 < main z10) и липнет к верху экрана, пока бумага contact уезжает вверх:
   футер поднят на --reveal под contact, ::after — трек той же высоты. Низ живого рваного края (W4) прозрачен —
   подпись видна прямо сквозь разрыв. Без sticky (reduced) — обычный поток. */
.footer {
  --reveal: 100svh;
  --gold-hi: #EDEBD8; --gold-lo: #8C8A6E;
  position: relative; z-index: -1;
  margin-top: calc(var(--reveal) * -1);
  background: var(--forest); color: var(--gold);
}
.footer::after { content: ''; display: block; height: var(--reveal); }
.foot-stage {
  position: sticky; top: 0;
  display: flex; flex-direction: column;
  min-height: 100svh;
  padding: calc(var(--header-h) + var(--safe-t) + 4.5svh) var(--gutter) calc(var(--gutter-y) + var(--safe-b));
  transform: translate3d(0, var(--fdrift, 0px), 0); /* JS: лёгкий параллакс глубины — сцена чуть догоняет бумагу */
}
.foot-body { position: relative; flex: 1 0 auto; display: flex; flex-direction: column; }

/* шапка сцены: «Дмитрий / дизайн и разработка» + статус */
.foot-intro { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; }
.foot-hi {
  font: 500 clamp(26px, 2.55vw, 46px)/1.02 var(--ff-sans); letter-spacing: -.035em;
  color: var(--gold-hi); max-width: 16ch; text-wrap: balance;
}
.foot-hi b { font-weight: 400; color: var(--gold-lo); padding: 0 .08em; }
.foot-status {
  display: inline-flex; align-items: center; gap: 10px; margin-top: .6em; white-space: nowrap;
  font: 400 11px/1 var(--ff-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--gold-lo);
}
.foot-status i { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); flex: none; }
.foot-status i::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; background: inherit;
  animation: statusPulse 2.4s var(--ease-quint) infinite;
}
@keyframes statusPulse { 0% { transform: scale(1); opacity: .55; } 70%, 100% { transform: scale(3.2); opacity: 0; } }

/* колонки ссылок — сетка 12: контакты 1–6, навигация 7–9, соцсети 10–12 */
.foot-nav {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter);
  margin-top: clamp(40px, 8svh, 110px);
}
.foot-col:nth-child(1) { grid-column: 1 / span 6; }
.foot-col:nth-child(2) { grid-column: 7 / span 3; }
.foot-col:nth-child(3) { grid-column: 10 / span 3; }
.foot-label {
  font: 400 10.5px/1 var(--ff-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--gold-lo);
  margin-bottom: 14px;
}
.links a {
  position: relative; display: inline-flex; align-items: center; gap: .7em;
  font: 400 12px/34px var(--ff-mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold); white-space: nowrap;
  transition: color .45s var(--ease-quint);
}
.links a i, .go-top i { font-style: normal; display: inline-block; transition: transform .6s var(--ease-expo); }
.links a.is-lit, .go-top.is-lit { color: var(--gold-hi); }
.links a.is-lit i { transform: rotate(45deg); }
.go-top.is-lit i { transform: translateY(-3px); }

/* нижняя строка над подписью: волосок рисуется слева направо */
.foot-meta {
  position: relative; margin-top: auto; padding-top: 16px;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: center;
  font: 400 11px/1 var(--ff-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--gold-lo);
}
.foot-meta::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, rgba(192,192,125,.5), rgba(192,192,125,.18));
  transform-origin: left;
}
.foot-meta > :nth-child(1) { grid-column: 1 / span 6; }
.foot-meta > :nth-child(2) { grid-column: 7 / span 3; }
.go-top {
  grid-column: 10 / span 3; justify-self: start;
  display: inline-flex; align-items: center; gap: .7em; color: var(--gold);
  line-height: 34px; margin: -9px 0;
  transition: color .45s var(--ease-quint);
}

/* PRYTKOV: кегль, кернинг (margin-right букв) и компенсацию левого поля «P» считает JS по canvas-метрикам —
   чернила ровно от гаттера до гаттера. Каждая буква — в своей маске (§3.3), выходит по прогрессу подъёма бумаги */
.foot-sign { position: relative; margin-top: clamp(18px, 3.2svh, 44px); padding-top: calc(var(--sign-fs, 21vw) * .74 * (var(--sign-sy, 1) - 1)); }
.fs-word {
  position: relative; display: flex; white-space: nowrap;
  transform: scaleY(var(--sign-sy, 1)); transform-origin: 0 100%; /* JS: вытяжка под свободную высоту, от базовой линии */
  font: 800 var(--sign-fs, 21vw)/.74 var(--ff-sans); letter-spacing: 0;
  margin-left: var(--sign-lsb, -.06em);
  text-rendering: optimizeLegibility; font-kerning: none;
}
.fs-l { display: block; overflow: hidden; padding: .07em 0 .035em; margin: -.07em 0 -.035em; }
.fs-l > span {
  display: block; transform-origin: 0 100%;
  /* литое золото: вертикальный градиент + блик за курсором (--sx/--sy — от левого края слова, --lx — сдвиг буквы) */
  background:
    radial-gradient(circle calc(var(--sign-fs, 21vw) * .95) at calc(var(--sx, -9999px) - var(--lx, 0px)) var(--sy, 50%),
      rgba(255, 251, 224, calc(.78 * var(--sa, 0))), rgba(255, 251, 224, calc(.22 * var(--sa, 0))) 38%, rgba(255, 251, 224, 0) 78%),
    linear-gradient(180deg, #D6D494 0%, var(--gold) 44%, #A3A262 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.fs-probe { position: absolute; left: 0; top: 0; visibility: hidden; white-space: nowrap; font: 800 200px/1 var(--ff-sans); }

/* стеклянная линза — одна на все ссылки футера (JS: html.has-lens). Внутри — клон .foot-body с увеличением
   и разъездом RGB: сквозь капсулу видно то же, что под ней, но как через толстое стекло */
.lens {
  position: absolute; left: 0; top: 0; z-index: 3; width: 0; height: 0;
  border-radius: 999px; pointer-events: none; visibility: hidden; opacity: 0;
  will-change: transform, width, height, opacity;
  box-shadow: 0 12px 26px -14px rgba(0,0,0,.55), 0 2px 5px -2px rgba(0,0,0,.3);
}
.lens-view {
  position: absolute; inset: 0; z-index: 0; border-radius: inherit; overflow: hidden;
  background: #2E2C20; /* forest сквозь стекло — на полтона светлее фона */
}
.foot-clone {
  position: absolute !important; left: 0; top: 0; margin: 0; transform-origin: 0 0;
  pointer-events: none; will-change: transform;
  text-shadow: -.45px 0 rgba(255, 120, 90, .22), .45px 0 rgba(120, 185, 255, .22); /* дисперсия толстого стекла */
}
.foot-clone .foot-status i::after { animation: none; }
.lens::before { /* объём: верхний свет, каустика у нижней кромки, блик догоняет движение (--hx/--hy) */
  content: ''; position: absolute; inset: 0; z-index: 1; border-radius: inherit;
  background:
    radial-gradient(56px 18px at var(--hx, 30%) var(--hy, 30%), rgba(255, 252, 232, .3), rgba(255, 252, 232, 0) 72%),
    linear-gradient(180deg, rgba(255,255,255,.1), rgba(255,255,255,.015) 42%, rgba(255,255,255,0) 60%, rgba(237,235,216,.07));
  box-shadow: inset 0 1px 1px rgba(255,255,255,.26), inset 0 -1px 1px rgba(237,235,216,.12), inset 0 0 12px rgba(0,0,0,.14);
}
.lens::after { /* светящаяся кромка без border (§2.1): mask-composite оставляет только кольцо 1.2px */
  content: ''; position: absolute; inset: 0; z-index: 1; border-radius: inherit; padding: 1.2px;
  background: linear-gradient(165deg,
    rgba(237,235,216,.62) 0%, rgba(237,235,216,.2) 22%, rgba(237,235,216,0) 42%,
    rgba(237,235,216,0) 58%, rgba(237,235,216,.16) 80%, rgba(237,235,216,.48) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

/* ---------- 15. состояния появления (только под html.js и только если движение разрешено) ---------- */
@media (prefers-reduced-motion: no-preference) {
  html.js:not(.fs):not(.reduced):not(.header-in) .logo,
  html.js:not(.fs):not(.reduced):not(.header-in) .menu-wrap { opacity: 0; transform: translateY(-8px); }
  html.js:not(.fs):not(.reduced) .hero-copy span { opacity: 0; transform: translateY(14px); }
  html.js:not(.fs):not(.reduced) .name .line > span { transform: var(--line-off); }
  html.js .manifesto .w {
    opacity: 0; transform: translateY(40px); filter: blur(6px);
    transition: opacity .9s var(--ease-expo) var(--d, 0s), transform .9s var(--ease-expo) var(--d, 0s), filter .9s var(--ease-expo) var(--d, 0s);
  }
  /* .in не трогает transition: браузер берёт его из нового стиля, поэтому переход базового .w должен остаться; мгновенно — только fs / reduced */
  html.js .manifesto .w.in { opacity: 1; transform: none; filter: none; }
  html.fs .manifesto .w, html.reduced .manifesto .w { opacity: 1; transform: none; filter: none; transition: none; }
  html.js .reveal { opacity: 0; transform: translateY(var(--ry, 24px)); transition: opacity .8s var(--ease-quint) var(--d, 0s), transform .8s var(--ease-quint) var(--d, 0s); }
  html.js .reveal.in, html.fs .reveal, html.reduced .reveal { opacity: 1; transform: none; }
  html.js .works-title .ch { display: inline-block; transform: translateY(100%); transition: transform 1s var(--ease-expo) var(--d, 0s); }
  html.js .works-title .chw { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
  html.js .works-title.in .ch { transform: none; }
  html.js .tools .line > span { transform: var(--line-off); transition: transform 1s var(--ease-expo); }
  html.js .tools .tools-line--end .line > span { transition-delay: .4s; }
  html.js .tools.in .line > span { transform: none; }
  html.js .dock-icon { opacity: 0; transform: translateY(50%) scale(.6); transition: opacity .6s var(--ease-quint) calc(.15s + var(--i) * .05s), transform 1s var(--ease-expo) calc(.15s + var(--i) * .05s); }
  html.js .tools.in .dock-icon { opacity: 1; transform: none; }
  html.fs .tools .line > span, html.reduced .tools .line > span { transform: none; }
  html.fs .dock-icon, html.reduced .dock-icon { opacity: 1; transform: none; }
  /* футер: элемент получает .in, когда кромка бумаги проходит над ним (JS); буквы подписи ведёт скролл */
  html.js .foot-hi .line > span { transform: var(--line-off); transition: transform 1.1s var(--ease-expo) var(--d, 0s); }
  html.js .foot-hi.in .line > span { transform: none; }
  html.js .foot-fade { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--ease-quint) var(--d, 0s), transform 1s var(--ease-expo) var(--d, 0s); }
  html.js .foot-fade.in { opacity: 1; transform: none; }
  html.js .foot-meta > * { opacity: 0; transition: opacity .8s var(--ease-quint) .25s; }
  html.js .foot-meta::before { transform: scaleX(0); transition: transform 1.4s var(--ease-expo); }
  html.js .foot-meta.in > * { opacity: 1; }
  html.js .foot-meta.in::before { transform: none; }
  html.js .fs-l > span { transform: translate3d(0, 108%, 0); }
  html.fs .foot-hi .line > span, html.reduced .foot-hi .line > span,
  html.fs .foot-fade, html.reduced .foot-fade, html.fs .fs-l > span, html.reduced .fs-l > span { opacity: 1; transform: none; }
  html.fs .foot-meta > *, html.reduced .foot-meta > * { opacity: 1; }
  html.fs .foot-meta::before, html.reduced .foot-meta::before { transform: none; }
  /* клон внутри линзы всегда в конечном состоянии */
  html .foot-clone .line > span, html .foot-clone .foot-fade, html .foot-clone .foot-meta > * { opacity: 1 !important; transform: none !important; transition: none !important; }
  html .foot-clone .foot-meta::before { transform: none !important; transition: none !important; }
}

/* ---------- 16. hover (только точные указатели) ---------- */
@media (hover: hover) and (pointer: fine) {
  /* без линзы (reduced / сбой JS) — простой отклик цветом */
  html:not(.has-lens) .links a:hover, html:not(.has-lens) .go-top:hover { color: var(--gold-hi); }
  html:not(.has-lens) .links a:hover i { transform: rotate(45deg); }
  .menu-frame:hover .c--tl, .bracket-btn:hover .c--tl { transform: translate(-4px, -4px); }
  .menu-frame:hover .c--tr, .bracket-btn:hover .c--tr { transform: translate(4px, -4px); }
  .menu-frame:hover .c--bl, .bracket-btn:hover .c--bl { transform: translate(-4px, 4px); }
  .menu-frame:hover .c--br, .bracket-btn:hover .c--br { transform: translate(4px, 4px); }
  .slide-link:hover { background: rgba(242,242,242,.12); }
  .slide-link:hover i { transform: translate(2px, -2px); }
}
@media not ((hover: hover) and (pointer: fine)) {
  .links a:active, .go-top:active { color: var(--gold-hi); }
}

/* ---------- 17. @media ---------- */
/* 1920×1080 */
@media (min-width: 1800px) {
  .hero-copy { top: 156px; font-size: 16px; }
  :root { --menu-w: 60px; --menu-h: 40px; }
  .about-text { width: 50vw; max-width: 900px; }
  .works-count { font-size: 14px; }
}

/* планшет */
@media (max-width: 1023px) {
  :root { --gutter: 20px; --gutter-y: 18px; --menu-w: 56px; --menu-h: 38px; }
  .hero-copy { top: 110px; font-size: 14px; }
  .name { left: auto; right: 20px; bottom: 12svh; }
  .works { --wt: 9vw; --card-w: 46vw; --card-pad: 24px; --slide-fs: 48px; }
  .works-card { bottom: 10svh; }
  .works-count { bottom: 10svh; font-size: 12px; }
  .works-progress { bottom: 4svh; }
  .about-text { width: 72vw; font-size: 26px; }
  .foot-col:nth-child(1), .foot-meta > :nth-child(1) { grid-column: 1 / span 5; }
  .foot-col:nth-child(2), .foot-meta > :nth-child(2) { grid-column: 6 / span 4; }
  .foot-col:nth-child(3), .go-top { grid-column: 10 / span 3; }
}

/* мобильный */
@media (max-width: 767px) {
  :root { --gutter: 16px; --gutter-y: 16px; --menu-w: 58px; --menu-h: 40px; --torn-h: 60px; --fs-manifesto: 15vw;
    --fig-h: 169svh; --fig-x: calc(27.5vw - var(--fig-w) * .232); --fig-y: calc(35.5svh - var(--fig-h) * .12); }
  .menu-list a { line-height: 44px; padding: 0; }
  .menu-wrap.is-open .menu-frame { width: 150px; }
  .hero-copy { top: 84px; font-size: 14px; }
  .name { left: 16px; right: auto; bottom: 16svh; }
  .manifesto { line-height: .92; height: calc(16 * .92 * var(--fs-manifesto)); }
  .manifesto .w { top: calc(var(--r) * .92em); }
  .manifesto .w:nth-child(3n+1) { --x: 0; } .manifesto .w:nth-child(3n+2) { --x: 18; } .manifesto .w:nth-child(3n) { --x: 36; }
  .manifesto .w:nth-child(1) { --r: 0; } .manifesto .w:nth-child(2) { --r: 1; } .manifesto .w:nth-child(3) { --r: 2; }
  .manifesto .w:nth-child(4) { --r: 3; } .manifesto .w:nth-child(5) { --r: 4; } .manifesto .w:nth-child(6) { --r: 5; }
  .manifesto .w:nth-child(7) { --r: 6; } .manifesto .w:nth-child(8) { --r: 7; } .manifesto .w:nth-child(9) { --r: 8; }
  .manifesto .w:nth-child(10) { --r: 9; } .manifesto .w:nth-child(11) { --r: 10; } .manifesto .w:nth-child(12) { --r: 11; }
  .manifesto .w:nth-child(13) { --r: 12; } .manifesto .w:nth-child(14) { --r: 13; } .manifesto .w:nth-child(15) { --r: 14; }
  .manifesto .w:nth-child(16) { --r: 15; }
  .manifesto .w { left: min(calc(var(--x) * 1vw), var(--xmax, 100vw)); }

  .works { --wt: 64px; --card-pad: 20px; --slide-fs: 40px; --par: 4%; }
  .works-card { right: var(--gutter); width: auto; bottom: calc(9svh + var(--safe-b)); }
  .works-count { display: none; }
  .works-progress { bottom: calc(4svh + var(--safe-b)); }

  .about { padding: 14svh 16px 10svh; }
  .tools { --icon: 9.2vw; margin-bottom: 12svh; }
  .tools-line { font-size: 10vw; }
  .about-text { width: 100%; font-size: 21px; line-height: 1.18; }
  .contact-tg { height: 44px; }
  .foot-stage { padding-top: calc(var(--header-h) + var(--safe-t) + 3svh); }
  .foot-intro { flex-direction: column; gap: 14px; }
  .foot-hi { font-size: 30px; }
  .foot-status { margin-top: 0; }
  .foot-nav { grid-template-columns: 1fr 1fr; row-gap: 26px; margin-top: 7svh; }
  .foot-col:nth-child(1) { grid-column: 1 / -1; }
  .foot-col:nth-child(2) { grid-column: 1; }
  .foot-col:nth-child(3) { grid-column: 2; }
  .foot-label { margin-bottom: 6px; }
  .links a { line-height: 44px; font-size: 12px; }
  .foot-meta { grid-template-columns: 1fr auto; padding-top: 12px; }
  .foot-meta > :nth-child(1) { grid-column: 1; }
  .foot-meta > :nth-child(2) { display: none; }
  .go-top { grid-column: 2; line-height: 44px; margin: -14px 0; }
}

@media (max-width: 359px) {
  :root { --gutter-y: 14px; --fs-manifesto: 44px; }
  .hero-copy { top: 76px; font-size: 13px; }
  .name { bottom: 14svh; }
  .works { --wt: 56px; --card-pad: 18px; --slide-fs: 34px; }
  .about-text { font-size: 20px; }
  .foot-hi { font-size: 26px; }
  .links a { font-size: 11px; }
}

/* низкий альбомный */
@media (max-height: 500px) and (orientation: landscape) {
  :root { --gutter: 16px; --gutter-y: 10px; --menu-w: 54px; --menu-h: 34px; --torn-h: 56px; --fs-manifesto: 9vw;
    --fig-h: 403svh; --fig-x: calc(40.2vw - var(--fig-w) * .232); --fig-y: calc(37.4svh - var(--fig-h) * .12); }
  .hero-copy { top: 60px; font-size: 12px; }
  .name { left: 50vw; right: auto; bottom: 8svh; }
  .works { --wt: 6vw; --card-w: 38vw; --card-pad: 16px; --slide-fs: 28px; --par: 6%; }
  .works-title { top: calc(var(--gutter-y) + 44px); }
  .works-card { right: auto; width: var(--card-w); bottom: 14svh; }
  .slide-title { margin: .3em 0 .2em; }
  .work-soon, .slide-link { margin-top: 10px; }
  .works-count { display: none; }
  .works-progress { bottom: 4svh; }
  .about-text { width: 60vw; font-size: 18px; }
  .foot-stage { padding-top: calc(var(--gutter-y) + 52px); }
  .foot-hi { font-size: 24px; }
  .foot-nav { margin-top: 5svh; }
  .links a { line-height: 28px; }
  .foot-label { margin-bottom: 6px; }
}

/* уменьшенное движение */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  html.js .intro { display: none; }
}
/* финальные статичные состояния — html.reduced ставит main.js при prefers-reduced-motion (или ?reduced) */
html.reduced .intro { display: none; }
/* футер в reduced: без подъёма бумаги — обычный поток, всё видно сразу */
html.reduced .footer { margin-top: 0; z-index: var(--z-content); }
html.reduced .footer::after { display: none; }
html.reduced .foot-stage { position: relative; }
html.reduced .foot-status i::after { display: none; }
/* работы в reduced: не закреплены, вертикальный список «обложка + инфо» без стекла, лезвия и анимаций */
html.reduced .works { height: auto; }
html.reduced .works-stage { position: relative; height: auto; overflow: visible; padding: calc(var(--gutter-y) + 64px + var(--safe-t)) 0 12svh; }
html.reduced .works-title { position: relative; left: auto; right: auto; top: auto; margin: 0 var(--gutter) 24px; text-align: left; }
html.reduced .works-card { position: static; width: auto; margin: 6svh var(--gutter) 0; padding: 0; border-radius: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
html.reduced .works-card::before { display: none; }
html.reduced .works-list { display: flex; flex-direction: column; gap: 10svh; }
html.reduced .slide { opacity: 1; pointer-events: auto; }
html.reduced .slide-cover { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius); margin-bottom: 20px; }
html.reduced .works-count, html.reduced .works-progress, html.reduced .works-art, html.reduced .works-edge { display: none; }
@media (max-width: 767px) { html.reduced .slide-cover { aspect-ratio: 4 / 5; } }

/* ---------- 18. морф в проект (cross-document View Transitions) ---------- */
/* «Смотреть проект» с data-morph: main.js гасит UI «Работ» (html.morph-out, 0.38 с), ставит имена (html.morphing) и уходит по URL.
   Браузер снимает старую страницу и живую новую и ведёт общие элементы: буквы IRUVAI → логотип проекта, «Мальдивы» → заголовок,
   мета → координаты, пилюля → «Забронировать виллу», «Меню» → пилюля «Забронировать». Псевдоэлементы перехода живут в новом документе:
   полёт «туда» описывает CSS проекта, полёт «назад» (страница из bfcache) — этот блок. Без VT (Firefox) — только pre-exit */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* имена — только у активного слайда: одинаковое имя у двух элементов отменило бы переход */
html.morphing .slide.is-active .slide-title .ln:first-child .ch { view-transition-class: vt-ch; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(1) { view-transition-name: vt-l1; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(2) { view-transition-name: vt-l2; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(3) { view-transition-name: vt-l3; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(4) { view-transition-name: vt-l4; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(5) { view-transition-name: vt-l5; }
html.morphing .slide.is-active .slide-title .ln:first-child .ch:nth-child(6) { view-transition-name: vt-l6; }
html.morphing .slide.is-active .slide-title .ln:nth-child(2) > span { view-transition-name: vt-title; width: fit-content; }
html.morphing .slide.is-active .slide-meta { view-transition-name: vt-meta; view-transition-class: vt-txt; width: fit-content; }
html.morphing .slide.is-active .slide-link { view-transition-name: vt-cta; view-transition-class: vt-shape; }
html.morphing .slide.is-active .slide-link > span { view-transition-name: vt-cta-t; view-transition-class: vt-txt; }
html.morphing .menu-frame { view-transition-name: vt-pill; view-transition-class: vt-shape; } /* скобки растягиваются в пилюлю */
html.morphing .menu-label { view-transition-name: vt-pill-t; view-transition-class: vt-txt; }

/* pre-exit: «Работы» уходит вверх по буквам, гаснут логотип, счётчик, прогресс и номер; у плашки тает стекло, тексты остаются и улетают.
   Состояние — один класс на transitions: при возврате его снимают, и всё проявляется обратно (morph-back держит переходы ~1 с) */
html.morph-out { --mo-t: .38s; background-color: var(--night); } /* классический скроллбар: Lenis стоит, в пустом жёлобе — ночь, а не жёлтый фон */
html.morph-back { --mo-t: .7s; }
html.js:is(.morph-out, .morph-back) :is(.logo, .works-count, .works-progress) { transition: opacity var(--mo-t) var(--ease-quint); }
html.morph-out :is(.logo, .works-count, .works-progress) { opacity: 0; }
html.js.morph-out:not(.reduced) .slide.is-active .slide-top { opacity: 0; transition: opacity .3s var(--ease-quint); }
html.js.morph-out .works-title .ch {
  transform: translateY(-105%); filter: blur(6px);
  transition: transform .3s cubic-bezier(.55,0,.8,.2) calc(var(--d, 0s) * .6), filter .3s ease-in calc(var(--d, 0s) * .6);
}
html.js:is(.morph-out, .morph-back):not(.reduced) .works-card {
  transition: opacity .9s var(--ease-expo), translate .9s var(--ease-expo),
    background-color var(--mo-t) var(--ease-quint), box-shadow var(--mo-t) var(--ease-quint),
    -webkit-backdrop-filter var(--mo-t) var(--ease-quint), backdrop-filter var(--mo-t) var(--ease-quint);
}
html.js:is(.morph-out, .morph-back) .works-card::before { transition: opacity var(--mo-t) var(--ease-quint); }
html.morph-out .works-card {
  background-color: rgba(242,242,242,0); box-shadow: inset 0 1px 1px rgba(242,242,242,0);
  -webkit-backdrop-filter: blur(0px) saturate(100%); backdrop-filter: blur(0px) saturate(100%);
}
html.morph-out .works-card::before { opacity: 0; }

/* полёт «назад»: буквы из шапки проекта садятся в плашку по одной (28 мс), пилюли сжимаются обратно, тексты сменяются в середине пути */
html.morphing::view-transition-group(*) { animation-duration: .9s; animation-timing-function: cubic-bezier(.7,0,.2,1); }
html.morphing::view-transition-group(vt-l2) { animation-delay: 28ms; }
html.morphing::view-transition-group(vt-l3) { animation-delay: 56ms; }
html.morphing::view-transition-group(vt-l4) { animation-delay: 84ms; }
html.morphing::view-transition-group(vt-l5) { animation-delay: 112ms; }
html.morphing::view-transition-group(vt-l6) { animation-delay: 140ms; }
html.morphing::view-transition-image-pair(*.vt-ch) { animation: vt-blur .9s cubic-bezier(.7,0,.2,1) both; animation-delay: inherit; } /* motion-blur на середине полёта */
/* фон пилюль тянется по размеру группы; текст — в натуральную величину по центру, сменяется в середине */
html.morphing::view-transition-old(*.vt-shape), html.morphing::view-transition-new(*.vt-shape) { height: 100%; object-fit: fill; }
html.morphing::view-transition-old(*.vt-txt), html.morphing::view-transition-new(*.vt-txt) { inset: 0; width: auto; height: auto; margin: auto; }
html.morphing::view-transition-old(vt-meta), html.morphing::view-transition-new(vt-meta) { inset: 0 auto 0 0; margin: auto 0; }
html.morphing::view-transition-old(*.vt-txt) { animation: vt-out .3s cubic-bezier(.4,0,1,1) both; }
html.morphing::view-transition-new(*.vt-txt) { animation: vt-in .45s var(--ease-quint) .4s both; }
/* заголовок проекта (у него пустой прокси) → «Мальдивы» собирается из размытия */
html.morphing::view-transition-old(vt-title) { animation: vt-out .25s linear both; }
html.morphing::view-transition-new(vt-title) { animation: vt-condense .6s var(--ease-quint) .25s both; }
/* кадр: страница проекта сверху «вдыхает» до зума обложки (--vt-s, тот же кадр пиксель в пиксель) и уже на нём растворяется над портфолио */
html.morphing::view-transition-old(root) { z-index: 1; animation: vt-inhale .5s var(--ease-expo) both, vt-out .3s linear .25s both; }
html.morphing::view-transition-new(root) { animation: none; }
@media (max-width: 767px) and (orientation: portrait) {
  html.morphing::view-transition-old(root) { animation: vt-out .5s ease both; } /* у проекта на телефоне другой кадр — просто кроссфейд */
}
@keyframes vt-blur { 50% { filter: blur(1.5px); } }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; } }
@keyframes vt-condense { from { opacity: 0; filter: blur(10px); } }
@keyframes vt-inhale { to { transform: scale(var(--vt-s, 1)); } }
