/* S1 canvas — стили. По умолчанию поток (телефон, без JS); .is-canvas — режим поля. */
:root {
  --bg: #fff; --ink: #111418; --ink-2: #4b545c; --ink-3: #7a838b;
  --line: #dfe4e7; --dot: #c3c9cf; --accent: #ff2a55;
  --f-head: 'Inter Tight', system-ui, sans-serif;
  --f-mono: 'JetBrains Mono', ui-monospace, monospace;
}
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); color: var(--ink); -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font: 400 16px/1.55 var(--f-mono); background: var(--bg);
  background-image: radial-gradient(var(--dot) 1.1px, transparent 1.4px); background-size: 26px 26px;
}
.js body { background-image: none; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* поле */
.field { display: none; position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 0; pointer-events: none; }
.js .field { display: block; }

/* шапка потока */
.site-head { position: relative; z-index: 2; display: flex; justify-content: space-between; align-items: center; gap: 16px; max-width: 1132px; margin: 0 auto; padding: 20px 16px; }
.brand { display: flex; align-items: center; gap: 10px; font: 600 18px var(--f-head); text-decoration: none; }
.brand img { width: auto; height: 28px; flex: none; }
.brand-word { position: relative; top: .5px; font: 600 18px/1 var(--f-head); letter-spacing: -.01em; }
.site-nav { display: flex; gap: 18px; font: 500 13px var(--f-mono); }
.site-nav a { text-decoration: none; border-bottom: 1px solid transparent; }
.site-nav a:hover { border-color: currentColor; }

/* мир и фреймы: поток */
.world { position: relative; z-index: 1; }
.frame { position: relative; max-width: 1132px; margin: 72px auto; padding: 0 16px; }
.frame-in { position: relative; border: 1px solid var(--line); padding: clamp(28px, 6vw, 84px) clamp(20px, 6vw, 80px); }
.frame-label { position: absolute; left: -1px; top: -26px; font: 500 13px var(--f-mono); color: var(--ink-3); white-space: nowrap; }
.frame-label span { color: #b3bac0; margin-left: 12px; }
.hd { position: absolute; width: 9px; height: 9px; background: var(--bg); border: 1px solid var(--ink); }
.hd.tl { left: -5px; top: -5px; } .hd.tr { right: -5px; top: -5px; }
.hd.bl { left: -5px; bottom: -5px; } .hd.br { right: -5px; bottom: -5px; }

.kicker { font: 500 13px var(--f-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 22px; }
.h1 { font: 600 clamp(40px, 7vw, 78px)/1.02 var(--f-head); letter-spacing: -.035em; margin: 0; max-width: 16ch; }
.h2 { font: 600 clamp(32px, 5vw, 52px)/1.05 var(--f-head); letter-spacing: -.03em; margin: 0; }
.lead { font: 400 clamp(15px, 1.6vw, 19px)/1.55 var(--f-mono); color: var(--ink-2); max-width: 44em; margin: 26px 0 0; }
.hint { font: 400 14px var(--f-mono); color: var(--ink-3); margin: 14px 0 0; }
.hint--canvas { display: none; }
.btns { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 36px; }
.btn { display: inline-block; font: 500 15px var(--f-mono); padding: 15px 22px; border: 1px solid var(--ink); background: var(--bg); color: var(--ink); text-decoration: none; transition: box-shadow .2s, translate .2s; }
.btn--fill { background: var(--ink); color: #fff; }
.btn:hover { box-shadow: 4px 4px 0 var(--ink); translate: -2px -2px; }
.frame-foot { margin-top: 48px; font: 400 13px var(--f-mono); color: var(--ink-3); }

/* граф: поток — каждая цепочка столбиком */
.graph { position: relative; margin-top: 44px; display: grid; gap: 64px; }
.chain { display: flex; flex-direction: column; align-items: center; gap: 36px; }
.g-outs { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.g-node, .g-chip { position: relative; background: var(--bg); color: var(--ink); }
.g-node { display: block; width: min(380px, 100%); border: 1px solid var(--ink); padding: 20px 22px; text-decoration: none; transition: box-shadow .2s, translate .2s; }
.g-node:hover, .g-node.is-drag { box-shadow: 5px 5px 0 var(--ink); translate: -2px -2px; }
.g-lab { display: block; font: 500 12px var(--f-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); }
.g-title { display: block; font: 600 30px var(--f-head); letter-spacing: -.02em; margin: 8px 0; }
.g-desc { display: block; font: 400 15px/1.5 var(--f-mono); color: var(--ink-2); }
.g-go { display: inline-block; margin-top: 14px; font: 500 14px var(--f-mono); border-bottom: 1px solid; }
.g-chip { border: 1px dashed var(--ink-3); padding: 9px 14px; font: 500 15px var(--f-mono); color: var(--ink-2); white-space: nowrap; }
.g-chip.is-hot { border-style: solid; border-color: var(--ink); color: var(--ink); }
/* порты рисует graph.js на canvas — на стороне, обращённой к соседу */
.port { display: none; }
.g-is-pre { opacity: 0; pointer-events: none; }
.g-reveal { animation: g-print .42s steps(14) both; }
@keyframes g-print { from { clip-path: inset(-8px 100% -8px -8px); } to { clip-path: inset(-8px -8px -8px -8px); } }

/* HUD — только canvas */
.hud { display: none; }
.hud-box { position: fixed; z-index: 3; font: 500 11px var(--f-mono); color: #59626a; background: rgba(255,255,255,.92); border: 1px solid #e1e5e8; padding: 6px 9px; }
/* левый верхний угол: логотип, повтор заставки, координаты — в ряд */
.hud-tl { position: fixed; z-index: 3; left: 12px; top: 12px; display: flex; align-items: stretch; gap: 8px; }
.hud-tl .hud-box { position: static; }
.hud-brand { display: flex; align-items: center; gap: 8px; font: 600 14px var(--f-head); color: var(--ink); text-decoration: none; padding: 4px 10px 4px 8px; }
.hud-brand img { width: auto; height: 22px; flex: none; }
.hud-brand .brand-word { font-size: 14px; }
.hud-brand:hover { border-color: var(--ink); }
.hud-coords { display: flex; align-items: center; }
.hud-replay { width: 32px; padding: 0; display: grid; place-items: center; cursor: pointer; }
.hud-replay:hover { color: var(--ink); border-color: var(--ink); }
.hud-replay svg { width: 18px; height: 14px; }
@media (prefers-reduced-motion: reduce) { .hud-replay { display: none; } }
.hud-hint { left: 12px; bottom: 12px; color: #8a939a; }
.hud-nav { right: 12px; top: 12px; display: flex; gap: 4px; padding: 4px; }
.hud-nav a { padding: 5px 8px; text-decoration: none; color: #59626a; }
.hud-nav a.is-on { background: var(--ink); color: #fff; }
.hud-mini { right: 12px; bottom: 12px; width: 170px; height: 110px; padding: 0; cursor: pointer; }
.hud-mini canvas { display: block; width: 100%; height: 100%; }

/* ---------- режим canvas ---------- */
.is-canvas, .is-canvas body { overflow: hidden; height: 100%; }
.is-canvas body { cursor: grab; user-select: none; touch-action: none; }
.is-canvas .kicker, .is-canvas .h1, .is-canvas .h2, .is-canvas .lead, .is-canvas .hint, .is-canvas .g-desc, .is-canvas .frame-foot { user-select: text; }
.is-canvas body.is-panning { cursor: grabbing; }
.is-canvas .site-head { display: none; }
.is-canvas .world { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.is-canvas .frame { position: absolute; margin: 0; padding: 0; max-width: none; left: calc(var(--x) * 1px); top: calc(var(--y) * 1px); width: calc(var(--w) * 1px); height: calc(var(--h) * 1px); }
.is-canvas .frame-in { height: 100%; padding: 84px 80px; }
.is-canvas .h1 { font-size: 78px; }
.is-canvas .h2 { font-size: 52px; }
.is-canvas .lead { font-size: 19px; }
.is-canvas .hint--canvas { display: block; }
.is-canvas .graph { position: absolute; left: 0; top: 0; width: 100%; height: 100%; margin: 0; display: block; pointer-events: none; }
.is-canvas .g-node, .is-canvas .g-chip { position: absolute; left: calc(var(--gx) * 1px); top: calc(var(--gy) * 1px); cursor: grab; pointer-events: auto; will-change: transform; }
.is-canvas .g-node { width: 380px; }
.is-canvas .hud { display: block; }
.is-canvas .g-is-pre { pointer-events: none; }

/* ---------- Заставка «ноутбук → канвас» ---------- */
/* Ранний скрипт в <head> ставит intro-pending, чтобы сайт не мелькнул до заставки.
   Предохранитель: если intro.js не загрузился, через 3 с страница всё равно видна. */
.intro-pending body { visibility: hidden; animation: intro-failsafe 0s linear 3s forwards; }
@keyframes intro-failsafe { to { visibility: visible; } }
.is-intro, .is-intro body { overflow: hidden; }
.is-intro .hud { visibility: hidden; }

.intro {
  --ls: 1;
  --lp-b: calc(1.5px / (.5 * var(--ls)));
  position: fixed; inset: 0; z-index: 20; overflow: hidden; background: var(--bg); visibility: visible;
  cursor: default; user-select: none;
}
.intro-stage { position: absolute; left: 0; top: 0; width: 960px; height: 540px; transform-origin: 0 0; }
.intro-world { position: absolute; left: 0; top: 0; width: 960px; height: 540px; }
.intro-world > svg { position: absolute; left: 0; top: 0; overflow: visible; }

/* линия A: одна толщина на экране при любом масштабе сцены */
.intro .i-ln { fill: none; stroke: var(--ink); stroke-width: calc(1.5px / var(--ls)); stroke-linecap: round; stroke-linejoin: round; }
.intro .i-fw { fill: var(--bg); stroke: var(--ink); stroke-width: calc(1.5px / var(--ls)); stroke-linecap: round; stroke-linejoin: round; }
.intro .i-ink { fill: var(--ink); }
.intro .intro-cat { --cs: 2.7; }
.intro .i-cut { fill: var(--ink); stroke: var(--bg); stroke-width: calc(1.5px / (var(--ls) * var(--cs))); stroke-linejoin: round; }
.intro .i-cwl { fill: none; stroke: var(--bg); stroke-width: calc(1.5px / (var(--ls) * var(--cs))); stroke-linecap: round; }
.intro .i-cwf { fill: var(--bg); }
.intro .i-cln { fill: none; stroke: var(--ink); stroke-width: calc(1.5px / (var(--ls) * var(--cs))); stroke-linecap: round; }
.intro .intro-cat .i-zz { font-size: 6px; }
.intro .i-pane { fill: url(#intro-dots); }
.intro .i-grain { fill: none; stroke: #8f99a1; stroke-width: calc(.7px / var(--ls)); stroke-linecap: round; stroke-linejoin: round; opacity: .55; }
.intro .i-tl { fill: none; stroke: #8f99a1; stroke-width: calc(.6px / var(--ls)); opacity: .6; }
.intro .i-zz { font: 500 12px var(--f-mono); fill: var(--ink-3); opacity: 0; animation: i-zz 3.3s linear infinite; }
.intro .i-zz:nth-of-type(2) { animation-delay: 1.1s; }
.intro .i-zz:nth-of-type(3) { animation-delay: 2.2s; }
@keyframes i-zz { 0% { opacity: 0; transform: translate(0, 0); } 20% { opacity: .85; } 100% { opacity: 0; transform: translate(12px, -28px); } }
.intro .i-breath { transform-box: fill-box; transform-origin: 50% 100%; animation: i-breath 3.6s ease-in-out infinite; }
@keyframes i-breath { 50% { transform: scaleY(1.05); } }
.intro .i-head { transform-box: fill-box; transform-origin: 50% 100%; }
.intro .intro-cat.is-twitch .i-head { animation: i-twitch .35s ease-in-out 2; }
@keyframes i-twitch { 50% { transform: rotate(-5deg) translateY(-1px); } }
/* глаза, зрачки и поворот головы ведёт intro.js от времени заставки (кадр — функция t) */
.intro .i-eye { transform-box: fill-box; transform-origin: 50% 50%; transform: scaleY(0); }
.intro .intro-cat.is-awake .i-zz { animation: none; }
.intro .i-steam path { fill: none; stroke: var(--ink-2); stroke-width: calc(1.5px / var(--ls)); stroke-linecap: round; opacity: 0; transform-box: fill-box; animation: i-steam 3.2s ease-in-out infinite; }
.intro .i-steam path:nth-child(2) { animation-delay: 1.07s; }
.intro .i-steam path:nth-child(3) { animation-delay: 2.13s; }
@keyframes i-steam { 0% { opacity: 0; transform: translateY(6px) scaleX(.8); } 35% { opacity: .9; } 100% { opacity: 0; transform: translateY(-12px) scaleX(1.15); } }
.intro .i-tulle { transform-box: view-box; transform-origin: 480px 72px; animation: i-sway 7s ease-in-out infinite; }
@keyframes i-sway { 50% { transform: skewX(.6deg); } }

/* 3D-ноутбук: основание наклонено на 50°, крышку крутит intro.js */
.intro .lp-holder { position: absolute; width: 2080px; height: 1280px; transform: scale(.5); transform-origin: 0 0; }
.intro .lp-scene { position: absolute; inset: 0; perspective: 4000px; perspective-origin: 1040px 640px; }
.intro .lp-rig { position: absolute; inset: 0; transform-style: preserve-3d; transform-origin: 1040px 950px; transform: rotateX(50deg); }
.intro .lp-base { position: absolute; left: 560px; top: 950px; width: 960px; height: 640px; background: var(--bg); border: var(--lp-b) solid var(--ink); border-radius: 36px; box-sizing: border-box; }
.intro .lp-base svg { position: absolute; left: 0; top: 0; }
.intro .lp-keys rect, .intro .lp-k { fill: none; stroke: var(--ink); stroke-width: calc(1.2px / (2 * var(--ls))); }
.intro .lp-lid { position: absolute; left: 560px; top: 950px; width: 960px; height: 620px; transform-style: preserve-3d; transform-origin: 50% 0; transform: rotateX(0deg); }
.intro .lp-face { position: absolute; inset: 0; border-radius: 36px; box-sizing: border-box; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.intro .lp-back { background: var(--bg); border: var(--lp-b) solid var(--ink); display: flex; align-items: center; justify-content: center; transform: translateZ(4px); }
/* надкушенный кекс — на крышке ноутбука и на телефоне; --k — масштаб символа к экрану, линия A сохраняется */
/* на крышке знак ровный для того, кто сидит напротив открытого ноутбука, — с места владельца он вверх ногами, как у Apple */
.intro .lp-logo { transform: rotate(180deg); }
.intro .i-cup { fill: none; stroke: var(--ink); stroke-width: calc(1.5px / (var(--ls) * var(--k))); stroke-linecap: round; stroke-linejoin: round; }
.intro .lp-screen { background: var(--ink); transform: rotateX(180deg) translateZ(4px); }
.intro .lp-glass { position: absolute; left: 40px; top: 40px; width: 880px; height: 540px; background: #000; }
/* экран загрузки: кекс и полоса, intro.js задаёт --boot 0..1 */
.intro .lp-boot { --boot: 0; position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 36px; opacity: min(1, calc(var(--boot) * 4)); }
.intro .lp-boot .i-cup { stroke: #fff; }
.intro .lp-boot i { display: block; width: 280px; height: 14px; border: var(--lp-b) solid #fff; border-radius: 7px; box-sizing: border-box; overflow: hidden; }
.intro .lp-boot s { display: block; height: 100%; width: calc(var(--boot) * 100%); background: #fff; }
.intro .lp-mark { position: absolute; left: 480px; top: 616px; width: 4px; height: 4px; }

@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
@media (prefers-reduced-motion: reduce) { .g-reveal { animation: none; } .btn, .g-node { transition: none; } }
