/* ============================================================================
   SPECTER — site.css  ·  landing + docs + account
   Layered on top of core.css. Only page-specific rules live here.
   ========================================================================== */

.screen[hidden]{ display:none !important; }
.acc{ color:var(--acc); }
.b{ font-weight:600; }

/* header extras ---------------------------------------------------------- */
.acct-chip{ display:flex; align-items:center; gap:9px; cursor:pointer; padding:4px 10px 4px 4px;
  border-radius:var(--r-pill); transition:background var(--t-2); color:var(--ink); }
.acct-chip:hover{ background:var(--surface-4); color:var(--ink); }
.acct-chip .nm{ font-size:var(--fs-14); font-weight:500; color:var(--ink-3); }
.avatar{ width:30px; height:30px; border-radius:var(--r-pill); background:var(--acc); color:var(--on-solid);
  display:flex; align-items:center; justify-content:center; font-size:var(--fs-12); font-weight:600;
  flex:0 0 auto; letter-spacing:.02em; }
.avatar.lg{ width:52px; height:52px; font-size:var(--fs-19); }
#theme-btn{ font-size:var(--fs-16); }

/* ═════════════════════════════ HERO ═══════════════════════════════════ */
.hero{ position:relative; overflow:hidden; background:var(--paper); }
.hero-wash{ position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(1000px 500px at 72% 18%, rgba(255,255,255,.95), rgba(251,249,245,0) 70%); }
html[data-theme=dark] .hero-wash{
  background:radial-gradient(1000px 500px at 72% 18%, rgba(40,52,70,.55), rgba(16,22,31,0) 70%); }
.hero-in{ position:relative; display:grid; grid-template-columns:1.05fr .95fr; gap:56px;
  align-items:center; padding-block:88px 92px; }
.hero-copy .h1{ margin:22px 0 0; }
.hero-copy .lead{ max-width:530px; margin:22px 0 0; }
.hero-cta{ gap:12px; margin-top:30px; }
.hero-trust{ gap:26px; margin-top:30px; font-family:var(--mono); font-size:var(--fs-12); color:var(--mut); }

.hero-frame .hero-stage{ position:relative; height:390px; background:var(--surface-2);
  overflow:hidden; display:flex; align-items:center; justify-content:center; }
/* §21.13 / §22.7 — no float, no bob, no sway. The kitchen has to be readable at
   a glance; the 7-second bob moved it out of frame and made the eye chase it. */
.hero-frame .stage3d{ perspective:1500px; }
.hud.float{ position:absolute; animation:spIn var(--t-6) ease both; }
.hud.float.bl{ left:26px; bottom:26px; color:var(--acc); border-color:var(--acc-line-2); animation-delay:var(--t-4); }
.hud.float.tr{ right:26px; top:26px; color:var(--ink); animation-delay:var(--t-5); }
.hud.float.br{ right:26px; bottom:26px; display:flex; align-items:center; gap:8px;
  color:var(--ink); animation-delay:var(--t-6); }
.pulse{ width:7px; height:7px; border-radius:var(--r-pill); background:var(--acc);
  animation:spPulse var(--t-loop-pulse) ease-in-out infinite; flex:0 0 auto; }
.hero-fill{ border-top:1px solid var(--line-2); padding:13px 16px; display:flex; gap:18px;
  align-items:center; background:var(--surface); }
.hero-fill .lbl{ font-size:var(--fs-11); color:var(--mut); white-space:nowrap; }
.hero-fill .bar{ flex:1; }
/* §31.6 — this used to override the fill to `width 1.2s`, a third slower than
   the `.bar > i` every other bar in the program uses, for no reason anybody
   wrote down and none `site.js` depends on (it sets `style.width` once, when
   the model's facts arrive). An override with no reason is not a decision, so
   the hero bar fills at `--t-7` like the rest of them. */
.hero-fill .val{ font-size:var(--fs-12); font-weight:600; color:var(--acc); min-width:44px; text-align:right; }

/* CSS-3D board faces ----------------------------------------------------- */
.p3d > i{ position:absolute; display:block; box-sizing:border-box; border:1px solid var(--ink);
  background:var(--f, rgba(255,255,255,.96)); }
html[data-theme=dark] .p3d > i{ border-color:rgba(255,255,255,.28); }

/* ═════════════════════════════ STATS ══════════════════════════════════ */
.stats-strip{ background:var(--surface); }
.stats-grid{ display:grid; grid-template-columns:repeat(4,1fr); padding-inline:var(--pad); }
.stats-grid > div{ padding:38px 24px; border-left:1px solid var(--border-4); }
.stats-grid > div:first-child{ border-left:0; }
.stat-v{ font-size:var(--fs-42); font-weight:700; letter-spacing:-.035em; color:var(--ink);
  font-variant-numeric:tabular-nums; }
.stat-l{ font-family:var(--mono); font-size:var(--fs-11); letter-spacing:.1em; color:var(--mut);
  margin-top:7px; text-transform:uppercase; }

/* ════════════════════════════ PIPELINE ════════════════════════════════ */
.pipeline{ position:relative; background:var(--paper); }
/* §41.2 — 160vh for four states was one wheel notch per state, and a wheel
   listener on top of that which turned the notch into a jump. Twelve states
   now, across 200vh of travel: about 17vh each, one to two notches, and
   something changes on every one of them. Nothing swallows the gesture. */
.pipe-track{ height:300vh; position:relative; }
.pipe-sticky{ position:sticky; top:var(--head-h); height:calc(100vh - var(--head-h));
  min-height:560px; display:flex; align-items:center; padding-block:24px; }
.pipe-in{ width:100%; display:grid; grid-template-columns:.85fr 1.15fr; gap:40px; align-items:center; }
.pipe-title{ margin:14px 0 22px; }

/* ── the twelve ticks ────────────────────────────────────────────────────
   The only thing on screen that says how long this section is and how far
   through it you are. On a wide screen it sits under the step list; on a
   narrow one it is what the step list becomes (§41.3). */
.pipe-rail{ display:flex; gap:5px; margin:0 0 18px; }
.pipe-rail > i{ flex:1; height:3px; border-radius:var(--r-pill); background:var(--line);
  transition:background var(--t-3) var(--ease), transform var(--t-3) var(--ease);
  transform-origin:50% 50%; }
.pipe-rail > i.past{ background:var(--acc-line-2); }
/* aktivni podeok dobija meki plavi sjaj — senka sa skale (--sh-acc) */
.pipe-rail > i.now{ background:var(--acc); transform:scaleY(2.2); box-shadow:var(--sh-acc); }

/* the active step, spelled out. Hidden where the whole list fits. */
.pipe-now{ display:none; }
.pipe-now .i{ font-size:var(--fs-12); font-weight:600; color:var(--acc); }
.pipe-now .t{ display:block; font-size:var(--fs-17); font-weight:600; color:var(--ink);
  letter-spacing:-.02em; margin-top:2px; }
.pipe-now .d{ display:block; font-size:var(--fs-14); line-height:1.55; color:var(--mut); margin-top:4px; }
.pipe-step{ display:flex; gap:15px; padding:15px 16px; border-radius:var(--r-10); cursor:pointer;
  background:transparent; border:1px solid transparent; text-align:left; width:100%;
  transition:background var(--t-4), border-color var(--t-4); }
.pipe-step .i{ font-family:var(--mono); font-size:var(--fs-12); font-weight:600; color:var(--mut-4);
  padding-top:2px; transition:color var(--t-4); }
/* §22.5 — `.t` and `.d` were both inline spans, so the title ran straight into
   the sentence after it: „3D scenaSklopite element po element…". They are the
   two lines of one step and must be blocks. */
.pipe-step .t{ display:block; font-size:var(--fs-16); font-weight:600; color:var(--mut); transition:color var(--t-4); }
.pipe-step .d{ display:block; font-size:var(--fs-14); line-height:1.55; color:var(--mut); margin-top:3px; max-width:330px; }
.pipe-step.on{ background:var(--acc-soft); border-color:var(--acc-line); }
.pipe-step.on .i{ color:var(--acc); }
.pipe-step.on .t{ color:var(--ink); }

.pipe-stage{ position:relative; height:min(62vh,520px); }
.pipe-layers{ position:absolute; inset:38px 0 0; }
.pipe-layer{ position:absolute; inset:0; opacity:0; transform:translateY(16px) scale(.99);
  transition:opacity var(--t-5) ease, transform var(--t-6) var(--ease); pointer-events:none;
  background:var(--surface); overflow:hidden; }
.pipe-layer[data-stage="0"]{ background:var(--surface-2); display:flex; align-items:center;
  justify-content:center; }
.pipe-layer.on{ opacity:1; transform:none; }
.pipe-layer .stage3d{ perspective:1500px; }

/* ── §41.2 — what a sub-step actually does ───────────────────────────────
   Every piece inside a layer carries `data-rev` — the sub-step it belongs to
   — and `site.js` puts `.in` on the ones at or before the current one. Two
   properties only, both composited: a layer opening cannot make the page
   behind it lay out again. */
.pipe-layer [data-rev]{ opacity:0; transform:translateY(10px);
  transition:opacity var(--t-5) var(--ease), transform var(--t-5) var(--ease); }
.pipe-layer [data-rev].in{ opacity:1; transform:none; }
/* §PREGLED-2 — kaskada UNUTAR podeoka: redovi krojne liste i komadi na tabli
   ne ulaze svi u istom kadru nego jedan za drugim (samo transition-delay,
   kompozitna svojstva, ništa se ne preračunava). Komad na tabli „legne"
   iz blagog uvećanja — kao da ga optimizacija spušta na ploču.
   PAZI: početni transform za komade MORA da stoji na `:not(.in)`. Bez toga
   pravilo ima ISTU specifičnost kao `.pipe-layer [data-rev].in{transform:none}`
   a stoji POSLE njega, pa trajno pobeđuje i komadi ostanu zaglavljeni —
   to je bio kvar koji je pokvario sloj „Optimizacija ploče". */
/* Zastoj ide SA SKALE `--t-*`, kao i svako drugo trajanje u projektu (§18.6):
   poslato je bilo .06/.07/.13 s, što `node tools/design_check.js` broji kao
   trajanje van skale. `--t-0` (.12 s) i `--t-2` (.18 s) daju isti stepenasti
   ulaz, a skala ostaje čista. */
.pipe-layer .cut-mini .rw:nth-child(odd){ transition-delay:var(--t-0); }
.pipe-layer .cut-mini .rw:nth-child(4n){ transition-delay:var(--t-2); }
.pipe-layer .pc[data-rev]:not(.in){ transform:translateY(8px) scale(.9); }
.pipe-layer .pc:nth-child(2n){ transition-delay:var(--t-0); }
.pipe-layer .pc:nth-child(3n){ transition-delay:var(--t-2); }

/* the model's own numbers, read out of the file on screen — same source as
   the captions on the hero, so swapping the file changes them */
.pipe-facts{ position:absolute; left:14px; bottom:14px; right:14px; display:flex;
  flex-wrap:wrap; gap:7px; pointer-events:none; }
.pipe-facts span{ font-family:var(--mono); font-size:var(--fs-10); letter-spacing:.06em;
  padding:5px 9px; border-radius:var(--r-pill); background:var(--surface);
  border:1px solid var(--border-3); color:var(--mut); box-shadow:var(--sh-1); }

/* ── §15.13 / §17.16 — alatna imitacija, gore desno u istom sloju ─────────
   Krstić je tačka koju bi alat obeležio; „− 100% +" je isti oblik kao
   `#zoom-val` u pravom radnom prostoru (`app.html`, traka `.vp-foot`).
   Brojka nije izmišljena — 100 % je i doslovno tačna, jer je ovo ogledalo
   podignuto na svoj podrazumevani okvir (§23.2), nikad uvećano ni umanjeno.
   `pointer-events:none` i `aria-hidden` na roditelju: ovo je izgled, ne
   dugme — dugmići u pravom alatu su `min 44 × 44px`, ovi ovde nisu dodirna
   meta ni na jednom uređaju, pa im F8 ne sudi.
   Isti recept kao `.pipe-facts` (mono, fs-10, pill, surface, border-3,
   sh-1) — nova značka, stari tokeni. */
.pipe-vhud{ position:absolute; right:14px; top:14px; display:flex; align-items:center; gap:8px; pointer-events:none; }
.pipe-cross{ font-size:var(--fs-13); color:var(--mut-4); }
/* §15.16 — nova animacija: spor dah, ne treptaj, i tek POŠTO se krstić
   otkrije. Isti krug (`spBlink`) i ista petlja (`--t-loop-pulse`) koje
   `.pulse` tačka već koristi na hero okviru — ritam ostaje jedan, mesto je
   novo. Petlja mora na `.in`, ne na golom `.pipe-cross`: `animation` ide
   preko `.pipe-layer [data-rev]{opacity:0}` bez obzira na tu klasu, pa bi
   krstić treptao i pre nego što je uopšte otkriven — tačno onaj kvar koji
   je §41.2 već jednom zakrpio komadima na tabli (v. napomena kod „PAZI"
   gore uz `.pc[data-rev]`). */
.pipe-cross.in{ animation:spBlink var(--t-loop-pulse) ease-in-out infinite; }
.pipe-zoom{ display:flex; align-items:center; gap:5px; font-family:var(--mono);
  font-size:var(--fs-10); letter-spacing:.04em; color:var(--mut-4);
  border:1px solid var(--border-3); border-radius:var(--r-pill); padding:5px 9px;
  background:var(--surface); box-shadow:var(--sh-1); }
.pipe-zoom i{ font-style:normal; opacity:.6; }
.pipe-zoom b{ font-weight:600; color:var(--mut); }

/* ── §12.4 — krojna lista mora da stane u svoj okvir ──────────────────────
   `node tools/lang_fit.js` je izmerio: na 844 × 390 (položen telefon) sloj je
   177 px visok, a tabela 352 px. 175 px tabele i 104 ćelije u njoj su ispadali
   ispod maske `.pipe-layer{overflow:hidden}` — u svih osam jezika, 112 nalaza.
   Ostala dva sloja (`.nest-mini`, `.qr-block`) sama drže svoju visinu; ovaj je
   jedini koji nije. `max-height:100%` je JEMSTVO: koliko god neki jezik podigao
   red, tabela ostane u okviru umesto da procuri kroz njega. */
.cut-mini{ padding:20px 22px; max-height:100%; overflow:auto; }
/* §41.3 — bez razmaka su se na 390 px susedne ćelije čitale kao jedan broj:
   „2436 × 600" i „1" su ispadali kao „2436 × 6001". Kolona koja dodiruje
   sledeću nije kolona. */
.cut-mini .hd,.cut-mini .rw{ display:grid; grid-template-columns:1.6fr .9fr .7fr .7fr; gap:12px; }
.cut-mini .hd{ font-family:var(--mono); font-size:var(--fs-10); letter-spacing:.1em; color:var(--mut);
  padding-bottom:9px; border-bottom:1px solid var(--line-2); }
.cut-mini .rw{ padding:10.5px 0; border-bottom:1px solid var(--line-3); font-size:var(--fs-13);
  align-items:center; }
.cut-mini .rw span:nth-child(1){ font-weight:500; }
.cut-mini .rw span:nth-child(2),.cut-mini .rw span:nth-child(3){ font-family:var(--mono);
  font-size:var(--fs-12); color:var(--ink-3); }
.cut-mini .rw span:nth-child(4){ font-family:var(--mono); font-size:var(--fs-11); color:var(--acc); }

.nest-mini{ padding:22px; height:100%; display:flex; flex-direction:column; background:var(--surface-2); }
.nest-mini .sheet{ position:relative; flex:1; border:1.5px solid var(--ink); background:var(--surface);
  background-image:repeating-linear-gradient(135deg,rgba(26,36,48,.035) 0 8px,transparent 8px 16px); }
/* the pieces land one wave at a time now (`data-rev`), so the keyframe that
   used to slide each of them in on its own inline delay is gone */
.nest-mini .pc{ position:absolute; background:var(--acc-soft-2); border:1.3px solid var(--acc);
  display:flex; align-items:center; justify-content:center; font-family:var(--mono); font-size:var(--fs-10);
  color:var(--acc-ink); }
.nest-meta{ display:flex; justify-content:space-between; align-items:center; gap:12px;
  flex-wrap:wrap; margin-top:12px; font-family:var(--mono); font-size:var(--fs-11); color:var(--mut); }

/* ── §41.5 — a real QR, drawn on a canvas ────────────────────────────────
   It was a 7 × 7 grid of `<i>` from a seeded random generator: a picture of a
   QR code. It is an anchor now, because a code that opens a page and a box
   that does nothing when it is clicked are not the same object — and the
   canvas inside it is what `tools/landing_measure.js --only qr` reads back
   pixel by pixel. Colours are fixed rather than themed on purpose: a QR
   inverted by a dark theme does not scan. */
/* `max-height` + `overflow` je isto jemstvo koje §12.4 već daje krojnoj listi:
   koliko god neki jezik podigao pasus, sloj ostane u okviru umesto da procuri
   kroz masku `.pipe-layer{overflow:hidden}` i odseče značke pri dnu. */
.qr-block{ display:flex; gap:24px; align-items:center; justify-content:center; flex-wrap:wrap;
  align-content:center; height:100%; max-height:100%; overflow:auto; padding:24px; }
/* §PREGLED-2 — QR kao PRAVA radionička nalepnica, ne kvadrat u praznini:
   beli štampani listić sa senkom (fizički predmet) i mekim plavim oreolom
   iza njega, hover ga „podigne" kao da se uzima u ruku. Sve vrednosti sa
   postojećih skala: --sh-3/--sh-4, --acc-soft/-2, --acc-line/-2, --r-12, --t-3.
   BEZ NAGIBA — kod se čita kamerom, a nakrivljen kod izgleda kao greška u
   štampi, ne kao stil. Oreol je SENKA, ne `::before` sa negativnim inset-om:
   `.pipe-layer{overflow:hidden}` bi ga odsekao (i jeste ga odsecao). */
.qr{ width:186px; height:186px; border:1px solid var(--line); border-radius:var(--r-12); padding:12px;
  display:flex; align-items:center; justify-content:center; background:#fff; flex:0 0 auto;
  position:relative; will-change:transform;
  /* §S3 — U MIROVANJU BEZ `--sh-3`. Kod stoji unutar `.frame.pipe-stage`, a
     `.frame` je već podignut sa strane. Podignut predmet na podignutom
     predmetu poništava obe poruke: kad je sve iznad nečega, ništa nije.
     Mereno `node tools/slop.js`: „senka na senci" na naslovnoj 1 → 0.
     Prsten i sjaj OSTAJU — oni ne govore o visini nego o tome da je ovo kod
     koji se čita kamerom, i to je jedini razlog zbog kog su i uvedeni.
     Podizanje ostaje na `:hover`, gde je stanje, a ne stalna visina. */
  box-shadow:0 0 0 10px var(--acc-soft), 0 0 34px -6px var(--acc-line);
  transition:box-shadow var(--t-3) var(--ease), transform var(--t-3) var(--ease); }
.qr:hover{ box-shadow:var(--sh-4), 0 0 0 12px var(--acc-soft-2), 0 0 44px -6px var(--acc-line-2);
  transform:translateY(-3px); }
.qr canvas{ width:100%; height:100%; display:block; image-rendering:pixelated; }
.qr.qr-plain{ font-family:var(--mono); font-size:var(--fs-11); color:var(--ink); text-align:center;
  word-break:break-all; padding:14px; }
.qr-copy{ max-width:270px; }
.qr-copy .h5{ margin-top:8px; }
.qr-copy .small{ margin-top:9px; }
.qr-badges{ margin-top:14px; gap:8px; align-items:center; }
.qr-url{ font-size:var(--fs-11); color:var(--mut); }
/* the box stays paper-white in both themes, so in the dark one the ink border
   and the fallback text would be light-on-white — invisible. They are pinned
   to the light-theme ink here, because what is inside this box is not part of
   the page's colour scheme: it is a thing a camera has to read. */
html[data-theme=dark] .qr{ border-color:rgba(26,36,48,.35); }
html[data-theme=dark] .qr.qr-plain{ color:#1A2430; }

/* ═════════════════════════ SECTION BLOCKS ═════════════════════════════ */
/* §0! D2/D3 — zaglavlje sekcije je stajalo ZALEPLJENO za mrežu ispod sebe.
   Izmereno na 1920×1080, sekcija „MOGUĆNOSTI": donja ivica naslova 6935,1 px,
   gornja ivica `.bento` 6935,1 px — **0 px razmaka**, i isto toliko od linka
   „Detaljno u dokumentaciji →" do prve ivice mreže. Cene su isti razmak imale
   samo zato što im je u `index.html` upisan `margin-bottom:40px` rukom; ovde
   nije bio, pa je ista vrsta zaglavlja izgledala drugačije na dve sekcije.
   Razmak sada stoji uz klasu, jednom, za oba mesta.
   Bilo: 0 px i 40 px · sada: 40 px i 40 px. */
.sec-head{ justify-content:space-between; align-items:flex-end; gap:24px; margin-bottom:40px; }
.linkarrow{ font-size:var(--fs-15); font-weight:600; color:var(--acc); cursor:pointer;
  border-bottom:1px solid var(--acc-line-2); padding-bottom:2px; background:none; }
.grid-3{ display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
.grid-2{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.split{ display:grid; grid-template-columns:1.05fr .95fr; gap:56px; align-items:center; }
.split.rev > :first-child{ order:-1; }

.how-card{ border:1px solid var(--line); border-radius:var(--r-12); padding:26px;
  background:var(--surface-2); transition:transform var(--t-3), box-shadow var(--t-3), border-color var(--t-3); }
.how-card:hover{ transform:translateY(-4px); box-shadow:var(--sh-3); border-color:var(--border-2); }
.how-card .n{ font-family:var(--mono); font-size:var(--fs-12); color:var(--acc); font-weight:600; }
.how-card .t{ font-size:var(--fs-19); font-weight:600; letter-spacing:-.02em; margin-top:14px; }
.how-card .d{ font-size:var(--fs-15); line-height:1.62; color:var(--ink-3); margin-top:9px; text-wrap:pretty; }

.bento{ display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--line);
  border:1px solid var(--line); border-radius:var(--r-12); overflow:hidden; }
.bento > div{ background:var(--surface); padding:28px 26px 30px; transition:background var(--t-3); }
.bento > div:hover{ background:var(--surface-2); }
.bento .n{ font-family:var(--mono); font-size:var(--fs-11); color:var(--mut-4); }
.bento .t{ font-size:var(--fs-17); font-weight:600; letter-spacing:-.02em; margin-top:16px; }
.bento .d{ font-size:var(--fs-14); line-height:1.62; color:var(--mut-2); margin-top:8px; text-wrap:pretty; }

.quote{ border:1px solid var(--line); border-radius:var(--r-12); padding:28px; display:flex;
  flex-direction:column; gap:18px; background:var(--surface-2); }
.quote .q{ font-size:var(--fs-17); line-height:1.6; letter-spacing:-.01em; color:var(--ink); text-wrap:pretty; }
.quote .who{ display:flex; align-items:center; gap:11px; margin-top:auto; }
.quote .ini{ width:34px; height:34px; border-radius:var(--r-pill); background:var(--surface-4);
  border:1px solid var(--border); display:flex; align-items:center; justify-content:center;
  font-size:var(--fs-12); font-weight:600; color:var(--ink-3); flex:0 0 auto; }

/* ── §41.4 — the measured nesting, where the LiDAR phone used to be ───────
   The phone was a drawn mock-up of a feature the program no longer has (§40),
   with an invented „12.840 TAČAKA" on it. What stands here now is a readout
   of `node tools/nest_bench.js`, and every figure in it can be reproduced by
   running that command. A table, not a picture, because the claim is a
   measurement.                                                              */
.ben-t{ margin-top:14px; }
.ben-d{ margin-top:16px; max-width:520px; font-size:var(--fs-16); line-height:1.65; }
.ben-lines{ gap:9px; margin-top:20px; }
.nest-proof{ background:var(--surface); }
.nest-proof .frame-bar .path{ font-size:var(--fs-10); letter-spacing:.06em; }
.nest-tbl{ padding:16px 18px 4px; }
.nest-tbl .hd,.nest-tbl .rw{ display:grid; grid-template-columns:1.35fr .6fr 1fr 1fr .8fr;
  gap:10px; align-items:center; }
.nest-tbl .hd{ font-family:var(--mono); font-size:var(--fs-10); letter-spacing:.1em; color:var(--mut);
  padding-bottom:10px; border-bottom:1px solid var(--line-2); }
.nest-tbl .rw{ padding:13px 0; border-bottom:1px solid var(--line-3); font-family:var(--mono);
  font-size:var(--fs-13); color:var(--ink-3); }
.nest-tbl .rw span:first-child{ color:var(--ink); font-weight:600; }
.nest-tbl .rw:last-child{ border-bottom:0; }
.nest-note{ margin:0; padding:0 18px 18px; color:var(--mut); line-height:1.6; }

/* x-ray drilling demo ---------------------------------------------------- */
.xray{ position:relative; height:280px; background:var(--surface-2); padding:26px; }
.xray .board{ position:absolute; inset:26px; border:1.5px solid var(--ink);
  background:rgba(216,190,150,.28); }
.xray .h{ position:absolute; border-radius:var(--r-pill); background:var(--surface); }
.xray .h.d{ width:14px; height:14px; margin:-7px; border:2px solid var(--drill-dowel); }
.xray .h.s{ width:11px; height:11px; margin:-5.5px; border:2px solid var(--drill-sys32); }
.xray .groove{ position:absolute; left:40px; right:40px; bottom:44px; height:6px;
  background:repeating-linear-gradient(90deg,rgba(26,36,48,.22) 0 3px,transparent 3px 7px);
  border:1px dashed var(--ink); }
.xray .lgd{ position:absolute; right:26px; bottom:-2px; font-family:var(--mono); font-size:var(--fs-10);
  color:var(--mut); }

/* client portal block ---------------------------------------------------- */
.comment-pin{ border:1.5px solid var(--warn-line); border-left:3px solid var(--warn);
  border-radius:var(--r-10); background:var(--warn-soft); padding:15px 17px; }
.chat-card{ padding:15px 17px; display:flex; flex-direction:column; gap:10px; }
.msg{ max-width:82%; border-radius:var(--r-9); padding:9px 12px; }
.msg .who{ font-size:var(--fs-9); }
.msg .txt{ font-size:var(--fs-13); line-height:1.5; margin-top:4px; }
.msg.them{ align-self:flex-start; background:var(--surface-2); border:1px solid var(--line-2); }
.msg.them .who{ color:var(--mut-3); }
.msg.me{ align-self:flex-end; background:var(--ink); color:var(--on-ink); }
.msg.me .who{ color:var(--on-dark-2); }

/* ═══════════════════════════════ CENE ═════════════════════════════════ */
.plans{ align-items:start; gap:20px; }
.plan{ border:1.5px solid var(--line); border-radius:var(--r-14); padding:30px 28px 32px;
  background:var(--surface); position:relative;
  transition:transform var(--t-3), box-shadow var(--t-3); }
/* §31.6 — `.card.hoverable`, `.how-card` and `.plan` are the same gesture:
   lift 4 px, cast `--sh-3`. Only the plan card had its own, 25 % larger. */
.plan:hover{ transform:translateY(-4px); box-shadow:var(--sh-3); }
.plan.hot{ border-color:var(--ink); background:var(--ink); color:var(--on-ink); }
.plan.hot .plan-note,.plan.hot .plan-per,.plan.hot .plan-item{ color:var(--on-dark); }
.plan.hot .plan-sep{ background:rgba(255,255,255,.14); }
.plan.hot .tick{ color:#7FB0FF; }
.plan-top{ display:flex; justify-content:space-between; align-items:center; gap:10px; }
.plan-name{ font-size:var(--fs-16); font-weight:700; letter-spacing:-.02em; }
.plan-price{ display:flex; align-items:baseline; gap:6px; margin-top:20px; }
.plan-price b{ font-size:var(--fs-42); font-weight:700; letter-spacing:-.04em; font-variant-numeric:tabular-nums; }
.plan-per{ font-family:var(--mono); font-size:var(--fs-12); color:var(--mut); }
.plan-note{ font-size:var(--fs-14); color:var(--mut); margin-top:8px; line-height:1.55; }
.plan-cta{ width:100%; margin-top:22px; }
.plan-sep{ height:1px; background:var(--line-2); margin:24px 0 18px; }
.plan-item{ display:flex; gap:10px; font-size:var(--fs-14); line-height:1.5; color:var(--ink-3); }
.plan-seat{ margin-top:16px; font-size:var(--fs-13); font-weight:600; }

/* ══════════════════ KOLONA ZA ČITANJE — §0! D2/D3 · §27.3 ══════════════
   Pitanja i pravni tekstovi su stajali u `.wrap` sa `max-width:840px`. `.wrap`
   je `margin:0 auto`, pa je uža kutija bila CENTRIRANA u strani, a ne uvučena
   u red ostalih sekcija. Izmereno na 1920×1080: sve ostale sekcije počinju na
   x=368, a te tri na x=568 — 200 px razlike, na istoj strani, jedna ispod
   druge. To je tačno ono „pozicije, alignment sa ostalim elementima".
   Sada `.wrap` ostaje pun (1240), a mera za čitanje je unutrašnja kolona koja
   počinje na levoj ivici strane. Leva ivica: bilo 568 → sada 368. */
.readcol{ max-width:784px; }

/* ═══════════════════════════════ FAQ ══════════════════════════════════ */
.faq-item{ border-bottom:1px solid var(--line); }
.faq-q{ width:100%; display:flex; align-items:center; gap:16px; padding:20px 2px; text-align:left;
  font-size:var(--fs-17); font-weight:600; letter-spacing:-.02em; color:var(--ink); }
.faq-q .pm{ margin-left:auto; font-family:var(--mono); color:var(--acc); font-size:var(--fs-19);
  transition:transform var(--t-3); flex:0 0 auto; }
.faq-item.on .faq-q .pm{ transform:rotate(45deg); }
.faq-a{ display:grid; grid-template-rows:0fr; transition:grid-template-rows var(--t-4) var(--ease); }
.faq-item.on .faq-a{ grid-template-rows:1fr; }
.faq-a > div{ overflow:hidden; }
.faq-a p{ padding:0 2px 22px; font-size:var(--fs-15); line-height:1.7; color:var(--ink-3); max-width:70ch; }

/* ═══════════════════════════════ CTA ══════════════════════════════════ */
.cta-band{ background:var(--ink); color:var(--on-ink); position:relative; overflow:hidden; }

/* ══════════════════════════════ LEGAL ═════════════════════════════════ */
.legal-body h3{ font-size:var(--fs-17); font-weight:600; letter-spacing:-.02em; margin:26px 0 8px; }
/* §0! D3 — mera je stajala samo na `<p>` (76ch ≈ 578 px), a stavke spiska su
   išle do pune širine kolone. Rezultat: desna ivica pravnog teksta skače
   578 → 784 px iz reda u red. Mera se sada zadaje JEDNOM, na telu teksta, pa
   je desna ivica jedna za sve. Bilo: dve desne ivice · sada: jedna. */
.legal-body{ max-width:76ch; }
.legal-body p{ font-size:var(--fs-15); line-height:1.72; color:var(--ink-2); margin:0 0 12px; }
/* §46.5f — stavka pravnog spiska NE SME da bude flex kutija.
   Bila je: `display:flex` sa kvačicom u `::before`. Flex red se ne prelama, pa
   je svaki komad teksta oko podebljane reči postajao SVOJ flex element i svi
   su stajali u jednom redu. Srpski je to preživeo slučajno, jer je kraći;
   nemački nije. Mereno na telefonu 390 px: `scrollWidth 429` u kutiji od
   `358` px — **71 px van strane**, dok je srpski bio 358 : 358.
   Sada je stavka običan blok (`list-item`), pa se tekst prelama kao tekst, a
   kvačica stoji u levom prostoru koji joj `padding-left` čuva. Uvlaka je ista
   kao pre (znak + 10 px razmaka ≈ 20 px), pa se ništa na ekranu ne pomera. */
.legal-body ul{ margin:0 0 14px; padding-left:0; list-style:none; }
.legal-body li{ display:list-item; position:relative; padding-left:20px;
  font-size:var(--fs-15); line-height:1.65; color:var(--ink-2); margin-bottom:7px; }
.legal-body li::before{ content:"▸"; position:absolute; left:0; top:3px;
  color:var(--acc); font-family:var(--mono); font-size:var(--fs-11); }

/* ══════════════════════════════ FOOTER ════════════════════════════════ */
.ftr{ border-top:1px solid var(--line); background:var(--paper); }
.ftr-in{ padding:48px var(--pad) 40px; display:grid; grid-template-columns:1.4fr 3fr; gap:32px; }
.ftr-cols{ display:grid; grid-template-columns:repeat(3,1fr); gap:32px; }
.ftr-cols .t{ font-family:var(--mono); font-size:var(--fs-10); letter-spacing:.14em; color:var(--mut-3);
  margin-bottom:12px; text-transform:uppercase; }
.ftr-cols a{ display:block; font-size:var(--fs-14); color:var(--ink-3); margin-bottom:9px;
  transition:color var(--t-1); cursor:pointer; }
.ftr-cols a:hover{ color:var(--acc); }
.ftr-legal{ justify-content:space-between; padding:0 var(--pad) 34px; font-size:var(--fs-11);
  color:var(--mut-3); }

/* ══════════════════════════ DOKUMENTACIJA ═════════════════════════════ */
.docs{ display:grid; grid-template-columns:288px 1fr; min-height:calc(100vh - var(--head-h));
  background:var(--paper); }
.docs-side{ border-right:1px solid var(--line); padding:30px 22px 60px; position:sticky;
  top:var(--head-h); height:calc(100vh - var(--head-h)); overflow:auto; background:var(--surface); }
.docs-side .inp{ margin-bottom:20px; }
/* §24.6 — the fold-out header exists at every width but only shows where the
   sidebar is not a column of its own */
.docs-side-toggle{
  display:none; width:100%; align-items:center; justify-content:space-between; gap:10px;
  padding:10px 12px; border:1px solid var(--line); border-radius:var(--r-8);
  background:var(--surface); color:var(--ink); cursor:pointer;
  font-size:var(--fs-14); font-weight:600; text-align:left;
}
.docs-side-toggle .arw{ color:var(--mut); transition:transform var(--t-1); }
.docs-side-toggle:hover{ border-color:var(--acc); color:var(--acc); }
.doc-grp{ margin-bottom:22px; }
.doc-grp .t{ font-family:var(--mono); font-size:var(--fs-10); letter-spacing:.14em; color:var(--mut-3);
  margin-bottom:8px; text-transform:uppercase; }
.doc-link{ display:block; width:100%; text-align:left; padding:7.5px 10px; border-radius:var(--r-6);
  font-size:var(--fs-14); cursor:pointer; color:var(--ink-3); transition:background var(--t-1); }
.doc-link:hover{ background:var(--surface-3); }
.doc-link.on{ background:var(--acc-soft); color:var(--acc); font-weight:600; }
/* §0! D3 — `.docs` je mreža `288px 1fr`, a telo dokumentacije je bilo
   zaključano na 1120 px i LEVO poravnato u toj drugoj koloni. Izmereno na
   1920×1080: sadržaj završava na x=1364, a strana je 1920 — 556 px praznine
   uz desnu ivicu, bez razloga. Mera za čitanje (782 px) je dobra i ostaje;
   menja se samo to gde ta kolona stoji. Bilo: prazno levo 0 / desno 556 px ·
   sada: 256 / 256. Na užim ekranima od 1408 px ovo ne menja ništa, jer tamo
   kolona ionako popunjava sav prostor. */
.docs-main{ display:grid; grid-template-columns:1fr 210px; gap:40px; padding:48px 44px 90px;
  max-width:1120px; margin-inline:auto; }
.docs-art h2{ font-size:var(--fs-22); letter-spacing:-.02em; font-weight:600; margin:0 0 12px; }
.doc-block{ margin-bottom:34px; scroll-margin-top:90px; }
.doc-block p{ font-size:var(--fs-16); line-height:1.75; color:var(--ink-2); margin:0 0 13px; text-wrap:pretty; }
.doc-list{ display:flex; flex-direction:column; gap:9px; margin-top:4px; }
/* Stavka spiska NIJE flex red. Bila je, i to je bio kvar: u flex redu svaki
   <b> u rečenici postaje zasebna stavka, pa najmanja širina reda postane ZBIR
   svih tih komada i razmaka među njima. Izmereno na 390 px, u članku
   „Biblioteka projekata": red „U pregledu su dugmad Otvorite, Preimenujte,
   Premestite i Obrišite." razvukao je stranu na 499 px i dao 110 px
   vodoravnog skrola. Sa običnim tekstualnim tokom i strelicom u apsolutnom
   položaju rečenica se prelama kao rečenica. */
.doc-list div{ position:relative; padding-left:22px; font-size:var(--fs-15);
  line-height:1.6; color:var(--ink-2); }
.doc-list div::before{ content:"▸"; position:absolute; left:0; top:3px;
  font-family:var(--mono); font-size:var(--fs-11); color:var(--acc); }
.docs-nav{ justify-content:space-between; gap:14px; border-top:1px solid var(--line);
  padding-top:22px; margin-top:44px; }
.docs-pn{ flex:1; padding:14px 16px; cursor:pointer; text-align:left; background:var(--surface); }
.docs-pn.r{ text-align:right; }
.docs-pn .t{ display:block; font-size:var(--fs-15); font-weight:600; margin-top:5px; }
.docs-toc{ position:sticky; top:110px; align-self:start; }
.docs-toc .in{ display:flex; flex-direction:column; gap:2px; border-left:1px solid var(--line); }
.docs-toc a{ font-size:var(--fs-13); line-height:1.45; color:var(--mut-2); padding:6px 0 6px 13px;
  margin-left:-1px; border-left:1px solid transparent; transition:color var(--t-1), border-color var(--t-1); }
.docs-toc a:hover,.docs-toc a.on{ color:var(--acc); border-left-color:var(--acc); }

/* ── §29.4 — slika i listalica u članku ─────────────────────────────────────
   Slika je pravi snimak ekrana, pa nosi svoju meru u atributima; ovde stoji
   samo `max-width:100%` i `height:auto` da se uklopi u kolonu, i `display:block`
   da ispod nje ne ostane razmak od reda teksta. Sve vrednosti su iz core.css
   (--r-*, --sh-*, --t-*); nijedan nov broj se ovde ne uvodi. */
.doc-fig{ margin:16px 0 4px; }
.doc-fig img{ display:block; width:100%; height:auto; max-width:100%;
  border:1px solid var(--line); border-radius:var(--r-10); background:var(--surface-2); }
.doc-fig figcaption{ margin-top:8px; font-size:var(--fs-13); line-height:1.55; color:var(--mut-2); }
/* Uzak isečak — panel od 291 px — ne razvlači se preko cele kolone: razvučen
   je mutan, a mutan snimak ekrana ne dokazuje ništa.
   ŠIRINA MORA DA OSTANE U PROCENTIMA. Sa `width:auto` zamenjeni element unosi
   svoju prirodnu širinu u najmanju širinu mreže, pa je `1fr` kolona postala
   široka koliko i slika: izmereno na 390 px, članak „Biblioteka projekata"
   je razvukao stranu na 499 px i dao 110 px vodoravnog skrola. `width:100%`
   ne unosi ništa, a `max-width` u pikselima drži sliku u njenoj meri. */
.doc-fig.narrow img{ width:100%; max-width:var(--nw,100%); margin-inline:auto; }

/* listalica: kadrovi jedan preko drugog, mesto drži `aspect-ratio` sa mere
   samog fajla — zato strana ne poskoči dok kadrovi stižu */
.doc-flip .doc-flip-stage{ position:relative; width:100%; overflow:hidden;
  border:1px solid var(--line); border-radius:var(--r-10); background:var(--surface-2); }
.doc-flip .doc-flip-stage img{ position:absolute; inset:0; width:100%; height:100%;
  border:0; border-radius:0; opacity:0; transition:opacity var(--t-0) linear; }
.doc-flip .doc-flip-stage img.on{ opacity:1; }
.doc-flip-bar{ display:flex; align-items:center; gap:12px; margin-top:9px; }
.doc-flip-btn{ padding:5px 14px; border:1px solid var(--line); border-radius:var(--r-pill);
  background:var(--surface); color:var(--ink-2); cursor:pointer;
  font-size:var(--fs-12); font-weight:600; min-width:74px;
  transition:border-color var(--t-1), color var(--t-1), background var(--t-1); }
.doc-flip-btn:hover{ border-color:var(--acc); color:var(--acc); }
.doc-flip-btn[aria-pressed="true"]{ background:var(--acc-soft); border-color:var(--acc); color:var(--acc); }
.doc-flip-dots{ display:flex; gap:5px; flex:1; }
.doc-flip-dots i{ width:7px; height:7px; border-radius:var(--r-pill); background:var(--border-2);
  transition:background var(--t-1), transform var(--t-1); }
.doc-flip-dots i.on{ background:var(--acc); transform:scale(1.25); }
.doc-flip-n{ font-size:var(--fs-11); color:var(--mut-3); letter-spacing:.06em; }
/* mirna slika: kadar stoji, dugme piše „Pusti" i ništa se ne kreće samo */
@media (prefers-reduced-motion: reduce){
  .doc-flip .doc-flip-stage img{ transition:none; }
}

/* ══════════════════════════════ NALOG ═════════════════════════════════ */
/* §0! D3 — nalog je bio na 1080 px dok je ceo ostatak sajta (i zaglavlje
   IZNAD njega) na `--wrap` = 1240 px. Izmereno na 1920×1080: `.hdr-in`
   340→1580, a sadržaj naloga 448→1472 — 80 px razlike sa svake strane, na
   istom ekranu, jedno ispod drugog. Sada je jedna širina za ceo sajt.
   Bilo: sadržaj 448→1472 · sada: 368→1552, poravnato sa logotipom.
   §F8 — `node tools/measure.js` je našao razmak gore ≠ dole preko 2×:
   44 px gore, 90 dole (2,05×). Gore drži razdaljinu od zaglavlja; dole
   90 px nije nosilo nikakav sadržaj posle sebe (nalog je ceo `.screen`,
   ne nastavlja se u podnožje) — samo veći broj bez razloga. Spušteno na
   64 px (1,45×), ista mera koja zatvara `.docs-main` ispod. */
.acct{ padding:44px var(--pad) 64px; max-width:var(--wrap); }
.acct-head{ gap:16px; margin-bottom:28px; }
.acct-tabs{ border-bottom:1px solid var(--line); margin-bottom:26px; }
.acct-grid{ display:grid; grid-template-columns:1fr 320px; gap:18px; align-items:start; }
.plan-card{ padding:26px; position:relative; overflow:hidden; border-radius:var(--r-14); }
.pay{ padding:13px; border:1px solid var(--line); border-radius:var(--r-8); background:var(--surface-2); gap:12px; }
.pay-card{ width:38px; height:26px; border-radius:var(--r-3); background:var(--ink); flex:0 0 auto; }
.dashed-add{ width:100%; margin-top:16px; text-align:center; padding:10px;
  border:1.5px dashed var(--border-2); border-radius:var(--r-7); font-size:var(--fs-14); font-weight:600;
  color:var(--ink-3); cursor:pointer; transition:border-color var(--t-2), color var(--t-2); }
.dashed-add:hover{ border-color:var(--acc); color:var(--acc); }
.inv-row{ display:grid; grid-template-columns:1.1fr .9fr .7fr auto; gap:12px; padding:14px 22px;
  border-bottom:1px solid var(--line-3); align-items:center; font-size:var(--fs-14); }
/* §0! D2 — iznos je bio levo poravnat, pa se cifre nisu poklapale po redovima.
   Novac se čita po jedinicama, desetinama, stotinama; kolona novca se poravnava
   DESNO i piše tabelarnim ciframa, inače se dva reda ne mogu uporediti okom.
   Bilo: leva ivica iznosa jedna, desna četiri različite · sada obrnuto. */
.inv-row > span:nth-child(3){ text-align:right; font-variant-numeric:tabular-nums; }
.inv-row:hover{ background:var(--surface-2); }
.notif-row{ display:flex; align-items:center; gap:16px; padding:17px 22px;
  border-bottom:1px solid var(--line-3); }
.notif-row:last-child{ border-bottom:0; }
.sess-row{ display:flex; justify-content:space-between; align-items:center; font-size:var(--fs-14);
  padding:11px 0; border-top:1px solid var(--line-3); }
.danger-card{ border-color:var(--danger-line); background:var(--danger-soft); }

/* ═══════════════════════════ RESPONSIVE ═══════════════════════════════ */
@media (max-width:1080px){
  .hero-in,.split{ grid-template-columns:1fr; gap:40px; }
  .split.rev > :first-child{ order:0; }
  /* ── §41.3 — isti smisao na 390 px i na 1920 px ────────────────────────
     Do sada je ispod 1080 px cevovod prestajao da bude zalepljen, pa je na
     telefonu ostajala hrpa: naslov, četiri opisana koraka i okvir koji se
     menja negde iza leđa dok strana klizi. Nijedan od dvanaest podeoka se
     nije video kao korak — a to je ceo smisao ovog dela.
     Sada je zalepljen i na telefonu, samo je spisak koraka spakovan: traka od
     dvanaest crtica i JEDAN ispisan korak (`#pipe-now`) umesto sva četiri.
     Isti dvanaest podeoka, isti redosled, manje mastila.                    */
  .pipe-in{ grid-template-columns:1fr; gap:16px; align-content:center; }
  .pipe-track{ height:280vh; }
  .pipe-sticky{ position:sticky; top:var(--head-h); height:calc(100vh - var(--head-h));
    min-height:0; padding-block:14px; }
  .pipe-title{ margin:10px 0 16px; font-size:var(--fs-27); }
  .pipe-rail{ margin-bottom:14px; }
  .pipe-now{ display:block; min-height:78px; }
  #pipe-steps{ display:none; }
  .pipe-stage{ height:min(50vh, 420px); }
  /* mereno na 390 × 844: sloj ima 350 px, a QR od 132 px sa punim pasusom je
     tražio ~390 i sekao značke pri dnu. Manji kod i uži prored, pa stane. */
  .qr-block{ gap:12px; padding:14px; }
  .qr{ width:116px; height:116px; padding:8px; }
  .qr-copy{ max-width:520px; }  /* §PREGLED-2 — red od ~84 znaka (mereno na 844 px) je predugačak i kad QR stoji iznad teksta */
  .qr-copy .small{ font-size:var(--fs-13); line-height:1.5; }
  .qr-copy .h5{ margin-top:5px; }
  .qr-badges{ margin-top:10px; }
  .cut-mini{ padding:16px 16px; }
  .cut-mini .hd,.cut-mini .rw{ grid-template-columns:1.3fr 1.15fr .45fr .7fr; gap:8px; }
  .nest-tbl .hd,.nest-tbl .rw{ grid-template-columns:1.2fr .5fr .9fr .9fr .7fr; gap:6px; }
  .nest-tbl .rw{ font-size:var(--fs-12); }
  .docs{ grid-template-columns:1fr; }
  .docs-side{ position:sticky; top:var(--head-h); z-index:20; height:auto; border-right:0;
    border-bottom:1px solid var(--line); padding:10px 16px; }
  /* §24.6 — folded by default, and it stays at the top of the screen so the
     next article is always one tap away instead of a scroll back up */
  .docs-side-toggle{ display:flex; }
  .docs-side .docs-side-body{ display:none; padding-top:12px; max-height:min(58vh,460px); overflow:auto; }
  .docs-side.open .docs-side-body{ display:block; }
  .docs-side.open .docs-side-toggle .arw{ transform:rotate(180deg); }
  /* §F8 — na ovoj širini (≤820 px) razmak je bio 32 px gore / 70 dole, 2,19×;
     `node tools/measure.js --w 390 --h 844` je to beležio kao „gore≠dole" nalaz
     (na 1440 px odnos je 48/90 = 1,875×, ispod praga, zato se tamo ne vidi).
     70 → 60 (1,875×), ista mera kao gore na širem ekranu. */
  .docs-main{ grid-template-columns:1fr; padding:32px 20px 60px; }
  .docs-toc{ display:none; }
  .acct-grid{ grid-template-columns:1fr; }
}
/* ── položen telefon: nema šta da se zalepi ───────────────────────────────
   §12.4 je već izmerio da na 844 × 390 ostaje 326 px visine, a najviši sloj
   cevovoda (krojna lista) traži 352 px. Zalepljen okvir na takvom ekranu ne
   pokazuje ništa što već ne pokazuje obična strana koja klizi, pa se ovde
   vraća na staro ponašanje. Granica je merena, ne pogođena.                 */
@media (max-width:1080px) and (max-height:560px){
  .pipe-track{ height:auto; }
  .pipe-sticky{ position:static; height:auto; min-height:0; }
  .pipe-stage{ height:clamp(400px, 56vh, 440px); }
  .pipe-now{ min-height:0; }
}
@media (max-width:820px){
  /* ── §12.4 — značka je REČENICA u obliku čipa ───────────────────────
     `.chip` je `white-space:nowrap` po pravilu (čip je oznaka, a oznaka koja
     se prelama je pasus). Ova nosi `hero.badge`, pet odeljaka teksta. Mereno:
     na 390 px španska značka „ESCANEO DE ESPACIOS · CAD · CNC · LISTA DE
     DESPIECE · AR" je 424 px široka u prozoru od 390 px. Pošto se ne prelama,
     razvuče ceo levi stubac, a `.hero{overflow:hidden}` odseče 50 px — sa
     naslovom, podnaslovom, dugmetom „Ver la documentación" i brojkama ispod
     njega. Pet nalaza iz jednog `nowrap`-a. Rezerva u srpskom je bila 43 px,
     u ruskom 42 px — dakle jedna duža reč od kvara u još dva jezika.
     Ispod tablet-mere značka sme da se prelomi. Nigde drugde. */
  .hero-copy .chip.acc{ white-space:normal; }
  .stats-grid{ grid-template-columns:repeat(2,1fr); }
  .stats-grid > div:nth-child(odd){ border-left:0; }
  .stats-grid > div{ padding:26px 16px; }
  .grid-3,.bento,.plans,.ftr-cols{ grid-template-columns:1fr; }
  .bento{ gap:1px; }
  .ftr-in{ grid-template-columns:1fr; }
  .hero-in{ padding-block:52px 60px; }
  .hero-frame .hero-stage{ height:300px; }
  .grid-2{ grid-template-columns:1fr; }
  .sec-head{ align-items:flex-start; }
}
@media (max-width:520px){
  /* §0! D2/D3 — na 390 px se dva glavna dugmeta slažu jedno ispod drugog i
     bila su različito široka, po dužini svog teksta: „Otvorite radni prostor"
     183 px, „Pogledajte dokumentaciju" 216 px, oba levo poravnata. Dva
     dugmeta u koloni, sa dve različite desne ivice, čitaju se kao greška.
     Bilo: 183 i 216 px · sada: oba 358 px (puna širina kolone). */
  .hero-cta{ flex-direction:column; align-items:stretch; }
  .hero-cta .btn{ width:100%; justify-content:center; }
  .hero-trust{ gap:12px; font-size:var(--fs-11); }
  .plan-price b{ font-size:var(--fs-34); }
  .nest-tbl{ padding:14px 14px 2px; }
  .nest-tbl .hd{ font-size:var(--fs-9); }
  .nest-tbl .hd,.nest-tbl .rw{ gap:9px; }
  .nest-note{ padding:0 14px 14px; }
}


/* header: one line, everything centred on it */
.hdr-in { align-items: center; }
#hdr-actions { display: flex; align-items: center; gap: 8px; }
.hdr-prefs {
  display: flex; align-items: center; gap: 6px; order: -1;
  padding-right: 10px; margin-right: 2px; border-right: 1px solid var(--line);
}
#hdr-actions > * { align-self: center; }
#hdr-actions .btn, .hdr-prefs .btn { height: 34px; display: inline-flex; align-items: center; }
.hdr-prefs .btn-icon { width: 34px; justify-content: center; padding: 0; }
.hdr-prefs .lang { display: flex; align-items: center; position: relative; }
@media (max-width: 720px) { .hdr-prefs { border-right: 0; padding-right: 4px; } }

/* §53.3 — `core.css` pod `pointer:coarse` već diže VISINU svakog `.btn` na
   44 px, ali kvadratna ikonica ovde ima zadatu ŠIRINU koja tu granicu ne
   prati: 34 px u `.hdr-prefs` (dugme „Tema"), 38 px van njega (dugme „Meni").
   Rezultat je dugme visoko tačno 44 a usko 34/38 — mereno `node tools/dodir.js`:
   „Meni" 38×44, „Tema" 34×44. Širina se ovde izjednačuje sa visinom, samo
   na dodirnom ekranu; mišu ostaje kompaktno zaglavlje kakvo je bilo. */
@media (pointer: coarse) {
  .hdr-prefs .btn-icon, .hdr-burger.btn-icon { width: 44px; }
}

/* §53.3 — ispod 560 px `core.css` sakrije natpis „Specter" i ostavi samo
   znak od 28 px (§ „mark alone is the logo"); visina loga je već 44 px
   (`core.css` `.brand{min-height:44px}` pod dodirom), ali širina prati samo
   ikonicu. Mereno: 28×44. Log je link na naslovnu — meta, ne reč u rečenici. */
@media (pointer: coarse) and (max-width: 560px) {
  .hdr-in .brand { min-width: 44px; justify-content: center; }
}

/* §53.3 — nalog u zaglavlju: avatar 30 px + 4/4 px razmaka gore/dole = 38 px.
   Mereno `node tools/dodir.js`: „F Filip" 80×38. Razmak gore/dole raste, sve
   ostalo (avatar, natpis, boja) ostaje isto — kutija samo postaje viša. */
@media (pointer: coarse) {
  .acct-chip { padding-block: 7px; }
}

/* §53.3 — dugmad ekrana Nalog stilizovana kao tekst-veza („Pogledajte
   pakete", „Otvorite portal za naplatu") nemaju sopstvenu visinu — samo
   red teksta. Mereno: 123×19. Ovo su prava dugmad (`<button>`, akcija koja
   menja stanje), ne reč u rečenici, pa kutija sme da naraste. Selektor je
   `button.linkarrow` — ne dira veze `<a class="linkarrow">` u ostatku strane
   (one su već dovoljno velike u svom redu). */
@media (pointer: coarse) {
  button.linkarrow { min-height: 44px; display: inline-flex; align-items: center; }
}

/* §53.3 — sklopivi sadržaj dokumentacije na uskom ekranu: 10 px razmaka
   gore/dole + red teksta ≈ 38 px. Mereno: 812×38 (položen telefon) i
   358×38 (uspravan). Dugme je već `align-items:center`, pa kutija samo
   raste do 44 i tekst ostaje na sredini. */
@media (pointer: coarse) {
  .docs-side-toggle { min-height: 44px; }
}

/* §53.3 — jezički prekidač u zaglavlju je natpis („SR ▾") u `.btn-sm`, uz
   dovoljno malo popune da širina padne na 38 px. Mereno `node tools/dodir.js`.
   Ne dira se `.btn-sm` uopšte (koristi se i van zaglavlja) — samo ovo dugme. */
@media (pointer: coarse) {
  #lang-btn { min-width: 44px; justify-content: center; }
}

/* §53.3 — noga strane je bila 12 veza od 21 px, meta za prst traži 44 —
   PRVI pokušaj je ovo vezao za `max-width:820px` (kad noga postane jedna
   kolona), ali telefon POLOŽEN je 844 px širok: i dalje dodir, i dalje tri
   kolone, i dalje 21 px. Uslov je zato `pointer:coarse`, ne širina — radi u
   obe kolone, jednoj i trima. Mereno: 358×21 uspravno, 154×21 položeno.
   Kutija raste na 44 px, tekst ostaje iste veličine i stoji na sredini;
   razmak između veza nestaje jer sada visina kutije sama nosi ritam. */
@media (pointer: coarse) {
  .ftr-cols a { display: flex; align-items: center; min-height: 44px; margin-bottom: 0; }
}

/* §53.3 — „+ Pozovite člana" (ekran Nalog, tim): 10 px popune + red teksta
   ≈ 37 px. Mereno `node tools/dodir.js`: 750×37. Tekst je već `text-align:
   center` vodoravno; dodaje se `flex` da ostane na sredini i kad kutija
   naraste do 44 px. */
@media (pointer: coarse) {
  .dashed-add { min-height: 44px; display: flex; align-items: center; justify-content: center; }
}

/* §53.3 — „Otvorite radni prostor →" (ekran Nalog, potrošnja): 26 px, samo
   red teksta. Mereno na tabletu (768×1024 i 1024×768) `node tools/dodir.js`:
   686×26 / 930×26 — nije se pojavilo na telefonu jer ekran uskog telefona
   ovu karticu slaže drugačije, ali dodirni ekran je i tablet. `display:
   inline-flex` je ovde stalan (bio je `inline-block` u samom HTML-u, radi
   istog posla — `margin-top` na `inline` elementu se ne bi primenio), a
   visina raste na 44 px samo pod dodirom. */
.usage-open { display: inline-flex; align-items: center; }
@media (pointer: coarse) {
  .usage-open { min-height: 44px; }
}

/* ── §21.15 · §0! N9 — kutija „SAVET" ────────────────────────────────────
   Ovde su stajala dva pravila i oba su otišla u `core.css`, gde im je i
   mesto, jer istu kutiju prikazuju i radni prostor i modal na prijavi, a oni
   `site.css` ne učitavaju:
     · §21.15 „<b>SAVET</b>tekst" se čitalo kao „SAVETtekst" — naslov je sada
       zaseban blok sa razmakom ispod, pa razmak sa desne strane nema šta da
       radi (blok ionako zauzima ceo red).
     · §0! D2/D3 zakrpa `.note > b ~ b { display:inline }` — uzrok je bio
       `.note b { display:block }`, koji je važio za SVAKI <b>. Sada u
       `core.css` piše `.note > b:first-child`, pa naglašena reč usred
       rečenice ostaje u redu sama od sebe, na sve tri strane, bez zakrpe.
   Mereno pre → posle, ista kutija na 520 px: dokumentacija 101,4 → 101,4 px
   (nije se pomerila), radni prostor 148,5 → 101,4 px, prijava 148,5 → 101,4 px. */
.doc-block p > b, .sec p > b, .pipe-step .t + .d > b { margin-right: 3px; }

/* ── all four packages on one row ────────────────────────────────────────
   Enterprise was pushed onto a second line because the grid was fixed at
   three columns. Four equal columns, tighter padding and smaller type so
   they genuinely fit side by side; below 1180 px they go two-by-two, and on
   a phone one per row. */
.plans {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px; align-items: stretch;
}
.plans .plan { padding: 22px 18px 24px; display: flex; flex-direction: column; }
.plans .plan-name { font-size:var(--fs-17); }
.plans .plan-price b { font-size:var(--fs-27); letter-spacing: -.035em; }
.plans .plan-per { font-size:var(--fs-12); }
.plans .plan-note { font-size:var(--fs-13); line-height: 1.5; }
.plans .plan-item { font-size:var(--fs-13); line-height: 1.45; }
.plans .plan-cta { margin-top: 14px; }
.plans .plan-sep { margin: 14px 0; }
/* ── §0! D2/D3 — jedan paket je gurao svoj spisak 55 px niže od ostalih ──
   „Basic" jedini nosi napomenu („Jedan nalog = jedan aktivan uređaj u isto
   vreme."), i ona je stajala IZMEĐU dugmeta i crte. Izmereno na 1920×1080:
   crta na 8553,2 px u tri kartice i na 8608,2 px u četvrtoj, prva kvačica
   8568,2 prema 8623,2 — razlika 55 px, u redu od četiri kartice iste visine
   sa dugmadima poravnatim u piksel. Napomena nije uslov paketa nego sitno
   slovo, pa ide na dno kartice, gde je i inače prazno (25–100 px).
   Bilo: 2 različite visine početka spiska (8568,2 i 8623,2) · sada: 1. */
.plans .plan { position: relative; }
.plans .plan-seat { order: 9; margin-top: auto; padding-top: 14px;
  font-size: var(--fs-12); font-weight: 500; color: var(--mut); }
.plans .plan-top .chip { font-size:var(--fs-9); padding: 3px 6px; }
@media (max-width: 1180px) { .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .plans { grid-template-columns: 1fr; } }

/* ── §0! D2/D3 — četiri kartice u tri kolone ─────────────────────────────
   „ODLUKE PROGRAMA" (`#quotes`) ima ČETIRI stavke, a `.grid-3` daje tri
   kolone. Izmereno na 1920×1080: mreža 368→1552, kolone 380 px, pa je
   četvrta kartica stajala sama u drugom redu sa 782 px prazne mreže pored
   sebe. Dve po dve — nema ni prazne ćelije ni usamljene kartice.
   Bilo: 1 prazan red od 2 ćelije (782 px) · sada: 0. */
#quotes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 820px) { #quotes { grid-template-columns: 1fr; } }

.hero-frame { overflow: visible; }
/* §22.5 — `will-change` is set by site.js only while the scene is on screen.
   Leaving it here permanently pinned a compositor layer for a kitchen that is
   off screen for most of the page. */

/* ═══════════ §22.5 — the page must not chop on the scroll ═══════════
   The landing page is 13 574 px tall with 2 848 nodes. Without containment the
   browser lays out and paints all thirteen sections on every invalidation,
   even the twelve nobody is looking at.

   · `contain: layout paint style` — a change inside a section can no longer
     make the other twelve re-lay-out.
   · `content-visibility: auto` — an off-screen section is skipped entirely.
   · `contain-intrinsic-size: auto <h>` — the browser remembers the real height
     once it has measured it, so the scrollbar does not jump.

   Deliberately NOT applied to `.hero` (always on screen, nothing to skip) or
   to `.pipeline` (it owns a `position:sticky` child and a scroll-driven
   sequence — skipping it would break the snap).

   The `.cv` class is added by site.js **after** it has measured each section's
   real height and written it into `contain-intrinsic-size`. A guessed
   placeholder height makes the page shorter than it is and the scrollbar jumps
   as you scroll — so the guess is never used. */
html.cv [data-screen="home"] > .sec:not(.hero):not(.pipeline),
html.cv [data-screen="home"] > .cta-band {
  contain: layout paint style;
  content-visibility: auto;
}

/* the docs and account screens get the same treatment for their long bodies */
[data-screen="docs"] .doc-body > * { contain: layout style; }

/* ═══════════ §18.1 — what Specter is ═══════════ */
.what-h { margin: 14px 0 18px; max-width: 720px; }
.what-lead { max-width: 760px; margin: 0 0 40px; }
.what-grid .card { display: flex; flex-direction: column; gap: 8px; }
.what-grid .card .h5 { margin: 2px 0 0; }
.what-grid .card .small { color: var(--mut); line-height: 1.6; }

/* ═══════════ §24.13 — the project opens · §16.4 — the cursor has weight ═════
   The hero waits for a 3.4 MB model. §24.12 made that wait an empty frame,
   which is honest; this makes it say something true instead — a file explorer
   with the project in it, a cursor that walks over and opens it. Everything
   here is `transform` and `opacity`; nothing in the sequence can force layout.
   `opening.js` owns the timing, `cursor.js` owns the physics.                */

/* while the explorer is up the scene waits behind it, small and invisible */
.hero-frame .hero-stage.fo-on .stage3d{ opacity:0; transform:scale(.88); }
.hero-frame .hero-stage.fo-on .hud.float{ opacity:0; animation:none; }
/* …and grows into the frame when the file opens. This rule comes after the
   one above on purpose — same specificity, so the later one wins.           */
/* the spring at the end is the macOS part: the scene does not slide to its
   size, it arrives just past it and settles back.

   `z-index` is not decoration here, it is the whole bug: „izgleda da koristiš
   ovo animirano sve kao overlay u layeru preko i zato ne možeš da prikažeš
   lepo animaciju." Exactly right. The explorer is an overlay ABOVE the scene,
   so the kitchen was growing UNDERNEATH a white window that was still fading
   out and underneath the flash — the one moment that had to be seen was the
   one moment covered up. During the reveal the scene is lifted above the
   overlay (5 against the overlay's 3), so the sheet and the flash are behind
   the growth, which is what a cross-fade needs anyway: the kitchen fades IN
   on top while the paper fades OUT underneath. */
/* §31.6 — these two were .44 s and .86 s, and `core.css` excused them as
   „choreographed against the JS PACE". They are not, and it is worth writing
   down why: `openFile()` sets `s3.style.transition` INLINE, from `PACE`, before
   it adds `.fo-reveal` — an inline declaration beats a stylesheet one, so the
   growth the visitor sees is always the JS number and never these. This rule
   is the fallback for the path where nothing inline is written. A fallback has
   no sequence to stay in step with, so it goes on the scale: .44 → .45 (10 ms,
   2 %) and .86 → .90 (40 ms, 5 %). */
.hero-frame .hero-stage.fo-reveal .stage3d{ opacity:1; transform:none; z-index:5;
  transition:opacity var(--t-5) var(--ease), transform var(--t-7) cubic-bezier(.18,1.3,.32,1); }

.fo{ position:absolute; inset:0; z-index:3; overflow:hidden; }

.fo-win{ position:absolute; inset:24px 28px; display:flex; flex-direction:column;
  background:var(--surface); border:1px solid var(--border-3); border-radius:var(--r-12);
  box-shadow:var(--sh-3); overflow:hidden; opacity:0; transform:scale(.965);
  /* §41.1 — the CSS half of the HAND, doubled with `PACE` (1.55 → 3.10).
     .45 → .9 is exactly 2× and it is the next step on the scale, so the
     window opens at the same speed the arrow now crosses it. */
  animation:foWin var(--t-7) var(--ease) forwards; }
@keyframes foWin{ to{ opacity:1; transform:none; } }

.fo-top{ flex:0 0 auto; height:33px; display:flex; align-items:center; gap:10px;
  padding:0 12px; background:var(--surface-2); border-bottom:1px solid var(--line-2); }
.fo-dots{ display:flex; gap:5px; }
.fo-dots i{ width:8px; height:8px; border-radius:var(--r-pill); background:var(--border-2); }
.fo-path{ font-size:var(--fs-11); color:var(--mut); letter-spacing:.06em; }

.fo-body{ flex:1; min-height:0; display:flex; }
.fo-side{ flex:0 0 106px; display:flex; flex-direction:column; gap:2px; padding:10px 8px;
  background:var(--surface-2); border-right:1px solid var(--line-2); }
.fo-fold{ font-size:var(--fs-12); color:var(--mut); padding:6px 8px; border-radius:var(--r-4);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.fo-fold.on{ background:var(--acc-soft); color:var(--acc); }

.fo-grid{ flex:1; display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px;
  padding:14px; align-content:start; }
.fo-file{ display:flex; flex-direction:column; align-items:center; gap:6px; padding:11px 6px;
  border:1px solid transparent; border-radius:var(--r-8); text-align:center; min-width:0;
  /* the delay is a STAGGER, not a duration — `.13s` is the gap between one
     tile and the next, and a gap that snapped to a duration step would put
     four files on screen at once. It stays off the scale on purpose.
     §41.1 — both halves doubled with `PACE`: .45 → .9 and .065 → .13, so the
     drawer still fills at the speed the hand now moves. */
  animation:spIn var(--t-7) var(--ease) both; animation-delay:calc(.26s + var(--i) * .13s);
  transition:transform var(--t-4) var(--ease), background var(--t-4) var(--ease),
             border-color var(--t-4) var(--ease); }
.fo-ico{ position:relative; width:36px; height:44px; flex:0 0 auto; display:flex;
  align-items:center; justify-content:center; color:var(--mut-2);
  background:var(--surface); border:1px solid var(--border-2); border-radius:var(--r-4);
  box-shadow:var(--sh-1); }
.fo-ico::after{ content:''; position:absolute; right:-1px; top:-1px; width:10px; height:10px;
  background:var(--surface-3); border-left:1px solid var(--border-2);
  border-bottom:1px solid var(--border-2); border-top-right-radius:var(--r-4); }
.fo-ico.plain{ color:var(--mut); }
.fo-ext{ font-size:var(--fs-9); letter-spacing:.06em; }
.fo-nm{ font-size:var(--fs-11); color:var(--ink-2); max-width:100%; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.fo-mt{ font-size:var(--fs-9); color:var(--mut-4); }

.fo-file.hot{ background:var(--surface-3); transform:translateY(-2px); }
.fo-file.sel{ background:var(--acc-soft); border-color:var(--acc-line); }
.fo-file.sel .fo-nm{ color:var(--acc); }
.fo-file.sel .fo-ico{ border-color:var(--acc-line-2); color:var(--acc); }
/* the second click: pushed in, then thrown open. A file that only fades is a
   file nobody clicked. */
.fo-file.act{ animation:foPunch var(--t-7) var(--ease) forwards; }
@keyframes foPunch{
  0%  { transform:translateY(-2px) scale(1); }
  34% { transform:translateY(0) scale(.9); }
  100%{ transform:translateY(-3px) scale(1.08); }
}
/* the frame flashes as the window lets go — the same beat macOS gives it */
/* behind everything in the overlay, not in front of it — a glow the growth
   comes out of rather than a white sheet laid over the top of it */
.fo-flash{ position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(120% 90% at 50% 50%, var(--surface), transparent 72%);
  opacity:0; animation:foFlash var(--t-6) var(--ease) both; }
@keyframes foFlash{ 0%{ opacity:0; } 22%{ opacity:.6; } 100%{ opacity:0; } }

/* the tile leaves through the front of the picture; the window steps back */
.fo-zoom{ position:absolute; z-index:4; display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:6px; background:var(--acc-soft); border:1px solid var(--acc-line);
  border-radius:var(--r-8); transform-origin:50% 50%; will-change:transform, opacity;
  transition:transform var(--t-7) var(--ease), opacity var(--t-6) var(--ease-io) var(--t-0); }
.fo-zoom .fo-nm, .fo-zoom .fo-mt{ transition:opacity var(--t-1) linear; }
.fo-opening .fo-zoom .fo-nm, .fo-opening .fo-zoom .fo-mt{ opacity:0; }
/* the window goes first and quickly: it is opaque, it is behind a canvas
   drawn with alpha, and every millisecond it lingers is a millisecond of
   „folder iza kuhinje" */
.fo-opening .fo-win{ opacity:0; transform:scale(.955);
  transition:opacity var(--t-2) var(--ease), transform var(--t-4) var(--ease); }

/* ── §12.4 / §24.13 — pretraživač fajlova prati svoju pozornicu ──────────
   Ispod 820 px pozornica se spušta sa 390 px na 300 px, a prozor pretraživača
   i pločice u njemu su ostajali na punoj meri. Mereno na 768 × 1024:
   prozor 670 × 252, a dva reda pločica traže 258 px — donji red je ispisivao
   „640 kB · 12.7." četrnaest piksela ispod ivice prozora, u svih osam jezika,
   16 nalaza. Manji okvir dobija manje pločice; odnos ostaje isti.
   Blok stoji OVDE, a ne gore u odeljku RESPONSIVE, zato što se `.fo-*` pišu
   tek posle njega — pravilo iste težine koje dolazi ranije ne bi ništa učinilo
   (i nije: prvi pokušaj je izmerio isti 14 px). */
@media (max-width:820px){
  .fo-win{ inset:16px 18px; }
  .fo-grid{ padding:10px; gap:8px; }
  .fo-file{ padding:7px 5px; gap:4px; }
  .fo-ico{ width:28px; height:34px; }
}



/* ── §16.4 the cursor ────────────────────────────────────────────────────
   `contain` is not decoration here: it is the promise that a burst appearing
   inside this layer cannot make the page behind it lay out again.          */
.spc-layer{ position:absolute; inset:0; z-index:6; pointer-events:none; opacity:0;
  contain:layout style paint; }
.spc-halo, .spc-ring, .spc-tip, .spc-burst{ position:absolute; left:0; top:0;
  will-change:transform; }
/* three bodies, each softer than the one in front of it — the halo is the one
   you read as weight, the ring as direction, the arrow as the hand */
.spc-halo{ width:72px; height:72px; margin:-36px 0 0 -36px; border-radius:var(--r-pill);
  background:var(--acc-soft); }
.spc-ring{ width:50px; height:50px; margin:-25px 0 0 -25px; border-radius:var(--r-pill);
  border:2px solid var(--acc-line-2); background:var(--acc-soft-2); }
.spc-tip{ margin:-4px 0 0 -4px; color:var(--ink); }
.spc-tip svg{ display:block; filter:drop-shadow(0 4px 10px rgba(26,36,48,.28)); }
.spc-tip .spc-out{ fill:var(--surface); }
.spc-tip .spc-in{ fill:currentColor; }
.spc-burst{ width:34px; height:34px; margin:-17px 0 0 -17px; border-radius:var(--r-pill);
  border:2px solid var(--acc); animation:spcBurst var(--t-7) var(--ease) both; }
/* `both`, not `forwards`: the second ring starts a beat late, and during that
   beat an animation with only `forwards` applies NOTHING — so the ring sat at
   the layer's origin with its own negative margin, which is a circle in the
   top-left corner of the frame every time the cursor clicked. `backwards`
   (inside `both`) holds the first keyframe through the delay. */
.spc-burst.late{ animation-delay:.09s; border-width:1px; }
@keyframes spcBurst{
  from{ transform:translate3d(var(--bx),var(--by),0) scale(.42); opacity:.75; }
  to  { transform:translate3d(var(--bx),var(--by),0) scale(2.6); opacity:0; }
}

@media (max-width: 760px){
  .fo-win{ inset:14px 16px; }
  .fo-side{ display:none; }
  .fo-grid{ padding:11px; gap:8px; }
  .fo-file{ padding:8px 4px; }
  .fo-ico{ width:31px; height:38px; }
}
@media (prefers-reduced-motion: reduce){
  .fo{ display:none; }
  .hero-frame .hero-stage.fo-on .stage3d{ opacity:1; transform:none; }
  .hero-frame .hero-stage.fo-on .hud.float{ opacity:1; }
}
