/* Additions on top of the calculator stylesheet: the three viewer states, the markers, the
   equipment cards, the data tables and the black matrix band. Palette, type and spacing come
   from kettle.css; nothing there is redefined. */

.stage{position:relative;overflow:hidden;aspect-ratio:16/9;background:#0c0d10;
  cursor:ew-resize;user-select:none;touch-action:pan-y}
.stage picture,.stage img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.stage img.ins{clip-path:inset(0 0 0 50%)}
/* kettle.css sets top:20px on .state-label. Setting bottom here without clearing top made
   the chip stretch the full height of the frame - a tall dark box down the left edge. */
.stage .state-label{position:absolute;top:auto;bottom:15px;z-index:3;font-size:12px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;background:rgba(12,13,16,.72);color:#fff;
  padding:6px 12px;pointer-events:none}
.stage .state-bare{left:15px}
.stage .state-ins{right:15px}
.stage .handle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:4;
  width:48px;height:48px;border-radius:999px;border:1px solid var(--gold);
  background:rgba(12,13,16,.74);color:var(--gold);display:flex;align-items:center;
  justify-content:center;font-size:15px;letter-spacing:2px;pointer-events:none}

/* Three states. Compare owns the divider, Bare owns the markers, Insulated owns neither.
   A divider and a marker never share a frame: on one image every drag would start on a
   marker, and choosing an element off a half-wrapped frame is confusing. */
.stage.state-bare-on{cursor:default}
.stage.state-bare-on .handle,
.stage.state-bare-on .state-ins{display:none}
.stage.state-insulated-on{cursor:default}
.stage.state-insulated-on .handle,
.stage.state-insulated-on .state-bare,
.stage.state-insulated-on .hotspot{display:none}
.stage.state-compare-on .hotspot{display:none}

/* The handle is the only divider control. A second slider under the frame doing the same
   job read as a glitch, and the handle already sits where the eye is. */
.stage .handle{cursor:ew-resize;pointer-events:auto}
.stage .handle:focus-visible{outline:3px solid #fff;outline-offset:3px}
.stage.state-compare-on .handle::before{content:"";position:absolute;top:-50vh;bottom:-50vh;
  left:calc(50% - .5px);width:1px;background:var(--gold);opacity:.85;pointer-events:none}

.hotspot{position:absolute;z-index:5;transform:translate(-50%,-50%);width:38px;height:38px;
  border-radius:999px;border:1.5px solid var(--gold);background:rgba(12,13,16,.55);
  display:flex;align-items:center;justify-content:center;
  transition:transform .22s,background .22s}
.hotspot-no{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:12px;
  font-weight:700;color:var(--gold);line-height:1}
.hotspot-count{position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 4px;
  border-radius:999px;background:var(--gold);color:var(--control-ink);font-size:11px;
  font-weight:700;line-height:18px;text-align:center}
.hotspot::after{content:"";position:absolute;inset:-10px;border-radius:999px;
  border:1.5px solid var(--gold);opacity:.3;animation:hs 2.8s ease-out infinite}
@keyframes hs{0%{transform:scale(.7);opacity:.45}72%{transform:scale(1.24);opacity:0}100%{opacity:0}}
.hotspot:hover,.hotspot:focus-visible{transform:translate(-50%,-50%) scale(1.15);
  background:rgba(201,162,63,.3);outline:none}
.hotspot:focus-visible{outline:3px solid #fff;outline-offset:3px}
.hotspot-label{position:absolute;left:50%;top:calc(100% + 12px);transform:translateX(-50%);
  white-space:nowrap;font-size:12px;font-weight:600;color:var(--control-ink);background:var(--gold);
  padding:5px 11px;border-radius:999px;opacity:0;pointer-events:none;transition:opacity .2s}
.hotspot:hover .hotspot-label,.hotspot:focus-visible .hotspot-label{opacity:1}
.stage.dragging .hotspot{opacity:.2;pointer-events:none}
@media(prefers-reduced-motion:reduce){.hotspot::after{animation:none}}
/* No hover on a phone, so the label is simply always on. */
@media(hover:none){.hotspot{width:46px;height:46px}
  .hotspot-label{opacity:1;font-size:11px;padding:4px 9px}}

.view-switch button{cursor:pointer}

.pcards{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:30px}
@media(max-width:1000px){.pcards{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.pcards{grid-template-columns:1fr}}
.pcard{display:flex;flex-direction:column;gap:9px;padding:22px;border:1px solid var(--line);
  background:#fff;transition:border-color .2s,transform .2s}
a.pcard:hover{border-color:var(--gold);transform:translateY(-2px)}
.pcard .kicker{font-size:11.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gold)}
.pcard h3{font-size:19px}
.pcard p{font-size:14.5px;color:var(--secondary);flex:1;margin:0}
.pcard .more{font-weight:700;font-size:14px;color:var(--ink)}
/* U+2192 only. U+2197 and U+2194 carry emoji presentation on iOS and arrive as pictures. */
.pcard .more::after{content:" →"}
.pcard-soon{opacity:.62;background:#fafafa}
.pcard-soon .more.soon{color:var(--secondary)}
.pcard-soon .more.soon::after{content:""}

.scrollx{overflow-x:auto;-webkit-overflow-scrolling:touch;margin-top:26px}
table.data{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;background:#fff}
table.data th,table.data td{text-align:right;padding:11px 14px;border-bottom:1px solid var(--line);
  font-size:14.5px}
table.data th:first-child,table.data td:first-child{text-align:left}
table.data thead th{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--secondary);border-bottom:2px solid var(--ink)}
table.data tfoot th{font-size:14.5px;border-top:2px solid var(--ink);border-bottom:0;
  text-align:right;padding:12px 14px}
table.data tfoot th:first-child{text-align:left}
p.note{font-size:13.5px;color:var(--secondary);margin-top:16px}

/* ===== Matrix band — the densest block on the page, so it gets the black =====
   One black inset inside the white sheet. The sizes and the temperatures are the
   combinatorics we chose not to spend on URLs. */
/* No 100vw full-bleed trick here: the section is already a direct child of <main>, and
   100vw counts the scrollbar, which put 8px of sideways scroll on the whole document. */
.matrix{background:var(--graphite);color:#e9eae6;padding:54px 0 50px}
.matrix .wrap{width:min(1280px,calc(100% - 64px));margin-inline:auto}
.matrix .eyebrow{color:var(--gold)}
.matrix h2{color:#fff}
.matrix .section-heading>p{color:#b9bdbb}
.matrix .scrollx{margin-top:24px}
table.matrixtable{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;
  background:transparent;color:#e9eae6;min-width:640px}
table.matrixtable th,table.matrixtable td{text-align:right;padding:10px 14px;
  border-bottom:1px solid rgba(255,255,255,.16);font-size:14.5px;white-space:nowrap}
table.matrixtable thead th{font-size:11.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:#b9bdbb;border-bottom:1px solid rgba(255,255,255,.85)}
/* Sticky first column: without it you lose track of the row on a phone. */
table.matrixtable th[scope=row],table.matrixtable thead th:first-child{position:sticky;left:0;
  text-align:left;background:var(--graphite);z-index:1}
table.matrixtable th[scope=row]{font-weight:600;color:#fff;font-size:14.5px}
table.matrixtable th[scope=row] small{display:block;font-weight:400;font-size:12px;color:#9ca09e}
table.matrixtable tbody tr:hover td,
table.matrixtable tbody tr:hover th[scope=row]{background:rgba(201,162,63,.09)}
table.matrixtable td.hi{color:var(--gold)}
.matrix p.note{color:#9ca09e;margin-top:18px}
.matrix .srcline{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:#8b8f8d;margin-top:14px}
@media(max-width:760px){.matrix{padding:40px 0 38px}
  .matrix .wrap{width:calc(100% - 32px)}
  table.matrixtable th,table.matrixtable td{padding:9px 11px;font-size:13.5px}}

/* ===== Verdict — the conclusion of the page, stated not implied ===== */
.verdict{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin-top:28px;
  border-top:1px solid var(--ink)}
.verdict div{padding:20px 22px 20px 0;border-right:1px solid var(--line)}
.verdict div:last-child{border-right:0}
.verdict dt{font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--secondary);margin-bottom:9px}
.verdict dd{margin:0;font-size:19px;font-weight:600;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums}
.verdict dd small{display:block;font-size:13.5px;font-weight:400;color:var(--secondary);
  margin-top:6px;letter-spacing:0}
.verdict .pass{color:#1c7a43}
.verdict .warn{color:#8a6a1c}
@media(max-width:760px){.verdict{grid-template-columns:1fr}
  .verdict div{border-right:0;border-bottom:1px solid var(--line);padding-right:0}
  .verdict div:last-child{border-bottom:0}}

/* ===== No-render notice — we never borrow someone else's picture ===== */
.norender{background:#0c0d10;color:#c9cdcb;aspect-ratio:16/9;display:flex;align-items:center;
  justify-content:center;text-align:center;padding:30px}
.norender p{max-width:46ch;font-size:15px;line-height:1.6}
.norender b{color:var(--gold);display:block;font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;margin-bottom:12px}

/* kettle.css styles .mobile-result only inside its max-width:760px block, so above that it
   would fall back to an inline link and show. It belongs to narrow screens only. */
@media(min-width:761px){.mobile-result{display:none}}

/* ===== Breadcrumbs — the way back up =====
   Sits on the black body under the topbar. People land on any level from search, so every
   page has to hand them the levels above it, not just the ones below. */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:4px 0 14px;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase}
.crumbs a{color:#9ca09e;text-decoration:none;min-height:24px;display:inline-flex;align-items:center}
.crumbs a:hover{color:var(--gold);text-decoration:underline;text-underline-offset:3px}
.crumbs .sep{color:#5b605e}
.crumbs [aria-current=page]{color:#fff}
@media print{.crumbs{display:none}}

/* Tool links: the funnel read from the bottom up. A node page has to offer the calculator,
   not only its siblings. */
.toolrow{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;margin-top:26px}
@media(max-width:700px){.toolrow{grid-template-columns:1fr}}
.toolcard{display:flex;flex-direction:column;gap:8px;padding:22px;border:1px solid var(--ink);
  background:#fff;transition:background .2s}
a.toolcard:hover{background:rgba(201,162,63,.07)}
.toolcard .kicker{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.5px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--gold-d,#8a6a1c)}
.toolcard h3{font-size:19px}
.toolcard p{font-size:14.5px;color:var(--secondary);margin:0;flex:1}
.toolcard .more{font-weight:700;font-size:14px;color:var(--ink)}
.toolcard .more::after{content:" →"}

/* ===== Lead paragraph — the definitional opening =====
   An answer engine lifts the first clean "X is a ..." sentence it finds, so it is set as
   plain readable text at the top of the sheet, not buried under the calculator. */
.leadtext{max-width:64ch;margin-top:26px}
.leadtext p{font-size:16.5px;line-height:1.7;color:var(--secondary);margin-bottom:18px}
.leadtext p:first-child{font-size:18px;color:var(--ink)}
.leadtext b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

/* ===== Questions and answers ===== */
.qagrid{display:grid;grid-template-columns:1fr 1fr;gap:0 44px;margin-top:8px;
  border-top:1px solid var(--ink)}
@media(max-width:820px){.qagrid{grid-template-columns:1fr;gap:0}}
.qa{padding:22px 0;border-bottom:1px solid var(--line)}
.qa h3{font-size:17.5px;letter-spacing:-.01em;margin-bottom:9px}
.qa p{font-size:14.5px;line-height:1.7;color:var(--secondary);margin:0}
.qa b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}

/* Continuation rows in the room matrix: same equipment, next service band. */
table.matrixtable th[scope=row].cont{color:#6f7472;font-weight:400}
table.matrixtable th[scope=row] a{color:#fff;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.35)}
table.matrixtable th[scope=row] a:hover{color:var(--gold);border-color:var(--gold)}
table.matrixtable tr.band td,table.matrixtable tr.band th[scope=row]{background:rgba(201,162,63,.07)}

/* ═══════════════════════════════════════════════════════════════════════════
   ТИПОГРАФИКА — шкала апекса.

   kettle.css заканчивается блоком сжатия (`body{font-size:13px}`,
   `.intro h1{font-size:24px}`, `h2{font-size:22px}`), которым калькулятор
   ужимали под один экран. Для эксплорера это убивает иерархию: замерено на
   1425px — h1 приходил 24px вместо 61.6, h2 22px вместо 40.5.
   Здесь шкала возвращается к апексу. Кегли фиксированные, clamp только на отступы.
   ═══════════════════════════════════════════════════════════════════════════ */
body{font-size:15px}
.viewer .intro h1,.viewer h1{font-size:61.6px;font-weight:600;letter-spacing:-.015em;
  line-height:1.05;max-width:16ch}
.light-sheets h2,.matrix h2,.section-heading h2{font-size:40.5px;font-weight:600;
  letter-spacing:-.015em;line-height:1.1}
.light-sheets h3,.matrix h3{font-size:20.2px;font-weight:600;letter-spacing:-.01em}
.section-heading>p{font-size:15.2px;color:var(--secondary);max-width:34em}
.eyebrow{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.1px;
  font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#8b8f94}
.viewer .eyebrow{color:var(--gold)}
.value-ribbon strong{font-size:31.3px;font-weight:700;letter-spacing:-.02em}
.section{padding-top:clamp(64px,7vw,110px);padding-bottom:clamp(60px,6.5vw,104px)}
@media(max-width:1000px){
  .viewer .intro h1,.viewer h1{font-size:44px}
  .light-sheets h2,.matrix h2,.section-heading h2{font-size:31px}
}
@media(max-width:640px){
  .viewer .intro h1,.viewer h1{font-size:33px;max-width:none}
  .light-sheets h2,.matrix h2,.section-heading h2{font-size:26px}
  .value-ribbon strong{font-size:26px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ЧЕТЫРЕ КОНТУРА — чёрная полоса с колонками по рёбрам, идиома апекса .ind4.
   Карточки без рамок: сетку держат линии, как на апексе. У построенного контура
   реальный кадр; у непостроенных кадра НЕТ и подставлять чужой мы не будем —
   вместо него честная тёмная плашка.
   ═══════════════════════════════════════════════════════════════════════════ */
.circuits{background:var(--graphite);color:#e9eae6;padding:clamp(64px,7.5vw,116px) 0}
.circuits .wrap{width:min(1280px,calc(100% - 64px));margin-inline:auto}
.circuits h2{color:#fff}
.circuits .section-heading>p{color:rgba(255,255,255,.6)}
.circ4{display:grid;grid-template-columns:repeat(4,1fr);gap:0;
  border-top:1px solid rgba(255,255,255,.9);margin-top:clamp(36px,4.4vw,60px)}
.circ4 > *{padding:0 clamp(14px,1.8vw,28px) 30px 0;border-right:1px solid rgba(255,255,255,.17);
  margin-right:clamp(14px,1.8vw,28px);display:flex;flex-direction:column}
.circ4 > *:last-child{border-right:0;margin-right:0;padding-right:0}
.circ-ph{aspect-ratio:4/3;overflow:hidden;background:#111;margin:22px 0 18px}
.circ-ph img{width:100%;height:100%;object-fit:cover;display:block;transform:scale(1.06);
  transition:transform 1.1s cubic-bezier(.16,1,.3,1)}
a.circ:hover .circ-ph img{transform:scale(1)}
.circ-ph.empty{display:flex;align-items:center;justify-content:center;
  background:repeating-linear-gradient(135deg,#101114 0 12px,#0c0d10 12px 24px)}
.circ-ph.empty span{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:9.7px;
  letter-spacing:.14em;text-transform:uppercase;color:#5b605e}
.circ .kicker{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:9.7px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--gold);padding-top:22px;
  display:inline-flex;align-items:center;gap:8px}
.circ.soon .kicker{color:rgba(255,255,255,.4)}
.circ .kicker.live::before{content:"";width:5px;height:5px;background:var(--gold);
  animation:blink 2s infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.2}}
@media(prefers-reduced-motion:reduce){.circ .kicker.live::before{animation:none}}
.circ h3{font-size:22px;font-weight:700;letter-spacing:-.015em;color:#fff;margin:0}
.circ p{font-size:13.4px;line-height:1.65;color:rgba(255,255,255,.62);margin:10px 0 0;flex:1}
.circ .go{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.1px;
  letter-spacing:.11em;text-transform:uppercase;color:var(--gold);margin-top:20px;
  display:inline-block;border-bottom:1px solid transparent;padding-bottom:3px}
.circ .go::after{content:" →"}
a.circ:hover .go{border-bottom-color:var(--gold)}
a.circ:hover h3{color:var(--gold)}
.circ.soon .go{color:rgba(255,255,255,.32)}
.circ.soon .go::after{content:""}
a.circ{text-decoration:none}
@media(max-width:900px){.circ4{grid-template-columns:1fr 1fr}
  .circ4 > *:nth-child(2){border-right:0;margin-right:0}
  .circ4 > *:nth-child(n+3){border-top:1px solid rgba(255,255,255,.17);margin-top:8px}}
@media(max-width:560px){.circ4{grid-template-columns:1fr}
  .circ4 > *{border-right:0;margin-right:0;padding-right:0;
    border-top:1px solid rgba(255,255,255,.17)}
  .circ4 > *:first-child{border-top:0}}

/* ═══════════════════════════════════════════════════════════════════════════
   ПЕРВЫЙ ЭКРАН ЗОНТА — кадр, описание и четыре контура на одном экране.

   Язык снят с icomat.co.uk 04.09.2026: одна мысль на вьюпорт, моно-подписи по
   углам как на техническом чертеже, рамки с угловыми засечками, разрежённая
   сетка реперных точек. Картинка не ВМЕСТО содержания, а ПОД ним.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Шапка и крошки стоят НАД первым экраном, поэтому 100svh их не учитывает и лента
   контуров уходила под сгиб. Вычитаем их высоту. */
.lede{position:relative;min-height:calc(100svh - 104px);background:#08090b;color:#fff;
  overflow:hidden;display:flex;flex-direction:column}
.lede-bg{position:absolute;inset:0;z-index:0}
.lede-bg img{width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1.04);animation:ledeIn 2.4s cubic-bezier(.16,1,.3,1) forwards}
@keyframes ledeIn{to{transform:scale(1)}}
@media(prefers-reduced-motion:reduce){.lede-bg img{animation:none;transform:none}}
/* Затемнение слева под текст — читаемость важнее эффектности. */
/* Затемнение только под колонкой текста. Первая версия глушила кадр целиком —
   железо переставало читаться, а оно и есть содержание первого экрана. */
.lede::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(97deg,rgba(8,9,11,.92) 0%,rgba(8,9,11,.72) 26%,
    rgba(8,9,11,.30) 46%,rgba(8,9,11,0) 62%),
    linear-gradient(180deg,rgba(8,9,11,.55) 0%,rgba(8,9,11,0) 22%,
    rgba(8,9,11,0) 58%,rgba(8,9,11,.75) 100%)}
.lede > .wrap{position:relative;z-index:2;width:min(1440px,calc(100% - 64px));
  margin-inline:auto;display:flex;flex-direction:column;flex:1;
  padding:22px 0 0}

/* Реперные подписи по верхним углам */
.lede-marks{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  padding-bottom:16px;border-bottom:1px solid rgba(255,255,255,.16)}
.lede-marks span{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.5)}
.lede-marks b{color:#fff;font-weight:400}

.lede-body{margin-top:auto;padding-bottom:clamp(18px,2.2vh,32px);max-width:min(56vw,820px)}
.lede h1{font-size:clamp(34px,4.8vw,72px);font-weight:600;letter-spacing:-.025em;
  line-height:1.02;margin:0 0 18px;color:#fff;max-width:14ch}
.lede h1 em{font-style:normal;color:var(--gold)}
.lede p.say{font-size:clamp(15px,1.25vw,19px);line-height:1.55;color:rgba(255,255,255,.82);
  max-width:52ch;margin:0}
.lede p.say b{color:#fff;font-weight:600;font-variant-numeric:tabular-nums}

/* Четыре контура прямо в первом экране, лентой по рёбрам */
.lede-circ{position:relative;z-index:2;display:grid;grid-template-columns:repeat(4,1fr);
  border-top:1px solid rgba(255,255,255,.34);
  width:min(1440px,calc(100% - 64px));margin:0 auto}
.lede-circ > *{padding:16px clamp(12px,1.4vw,22px) 22px 0;
  border-right:1px solid rgba(255,255,255,.16);margin-right:clamp(12px,1.4vw,22px);
  display:flex;flex-direction:column;gap:7px;text-decoration:none;
  transition:background .25s}
.lede-circ > *:last-child{border-right:0;margin-right:0}
a.lede-c:hover{background:rgba(201,162,63,.08)}
.lede-c .n{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:9.6px;
  letter-spacing:.15em;text-transform:uppercase;color:rgba(255,255,255,.42)}
.lede-c .t{font-size:clamp(17px,1.5vw,23px);font-weight:600;letter-spacing:-.015em;color:#fff}
a.lede-c:hover .t{color:var(--gold)}
.lede-c .s{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:9.6px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--gold);
  display:inline-flex;align-items:center;gap:7px;margin-top:2px}
.lede-c.off .t{color:rgba(255,255,255,.5)}
.lede-c.off .s{color:rgba(255,255,255,.3)}
.lede-c .s.live::before{content:"";width:5px;height:5px;background:var(--gold);
  animation:blink 2s infinite}
a.lede-c .s::after{content:" →"}
@media(prefers-reduced-motion:reduce){.lede-c .s.live::before{animation:none}}
@media(max-width:900px){
  .lede::after{background:linear-gradient(180deg,rgba(8,9,11,.72) 0%,rgba(8,9,11,.5) 40%,
    rgba(8,9,11,.94) 100%)}
  .lede-body{max-width:none}
  .lede-circ{grid-template-columns:1fr 1fr}
  .lede-circ > *:nth-child(2){border-right:0;margin-right:0}
  .lede-circ > *:nth-child(n+3){border-top:1px solid rgba(255,255,255,.16)}
}
@media(max-width:520px){.lede-circ{grid-template-columns:1fr}
  .lede-circ > *{border-right:0;margin-right:0;border-top:1px solid rgba(255,255,255,.16)}
  .lede-circ > *:first-child{border-top:0}}

/* ═══════════════════════════════════════════════════════════════════════════
   СЦЕНА ВО ВСЮ ШИРИНУ — рендер выходит за края, а не сидит в коробке 16:9.
   Снято 04.09.2026 с icomat.co.uk и rejouice.com/work: у них железо всегда
   обрезано кадром и уходит за все стороны. Переходов минимум — владелец прямо
   сказал, что у референсов их слишком много и смысл теряется.
   ═══════════════════════════════════════════════════════════════════════════ */
.viewer{padding:0;color:var(--white)}
.stage-full{position:relative;aspect-ratio:16/9;height:auto;width:100%;
  background:#08090b;overflow:hidden}
.stage-full picture,.stage-full img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:52% 50%}
/* Затемнение снизу и сверху под подписи. Один слой, без эффектов. */
.stage-full::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(8,9,11,.72) 0%,rgba(8,9,11,0) 20%,
    rgba(8,9,11,0) 52%,rgba(8,9,11,.82) 100%)}

/* Реперы по верхним углам: номер узла слева, его имя справа */
.stage-marks{position:absolute;top:0;left:0;right:0;z-index:4;display:flex;
  justify-content:space-between;gap:16px;
  padding:18px clamp(20px,3vw,44px);pointer-events:none;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.55)}
.stage-marks b{color:var(--gold);font-weight:400}

/* Заголовок поверх кадра, по нижней трети */
.stage-title{position:absolute;left:clamp(20px,3vw,44px);bottom:96px;z-index:4;
  max-width:min(70vw,760px);pointer-events:none}
.stage-title .eyebrow{color:var(--gold);margin-bottom:10px}
.stage-title h1{color:#fff;font-size:clamp(30px,4.4vw,64px);font-weight:600;
  letter-spacing:-.025em;line-height:1.02;margin:0;
  text-shadow:0 2px 30px rgba(0,0,0,.5)}

/* Подвал кадра: переключатель состояний и подсказка */
.stage-foot{position:absolute;left:0;right:0;bottom:0;z-index:5;padding-bottom:18px}
.stage-foot .wrap{width:min(1440px,calc(100% - 64px));margin-inline:auto;
  display:flex;align-items:center;gap:18px}
.stage-full .state-label{bottom:auto;top:52px}
.stage-full .state-bare{left:clamp(20px,3vw,44px)}
.stage-full .state-ins{right:clamp(20px,3vw,44px)}

/* ── Выноски вместо колец: точка, тонкая линия-лидер, моно-подпись ────────── */
/* Маркер должен САМ выглядеть целью: кружок с номером, а не точка. Раньше .stage-full
   перебивал базовый стиль на голый диск 11px — попасть в него было нельзя. */
.stage-full .hotspot{width:44px;height:44px;border:1.5px solid var(--gold);
  border-radius:999px;background:rgba(10,12,16,.62);backdrop-filter:blur(2px);
  transform:translate(-50%,-50%);display:grid;place-items:center;padding:0;z-index:6;
  cursor:pointer;transition:transform .18s,background .18s,box-shadow .18s}
.stage-full .hotspot .hotspot-no{position:static;width:auto;height:auto;
  font:700 13px/1 var(--mono,ui-monospace,Consolas,monospace);color:var(--gold);
  background:none;box-shadow:none}
.stage-full .hotspot:hover,.stage-full .hotspot:focus-visible{
  transform:translate(-50%,-50%) scale(1.12);background:var(--gold);
  box-shadow:0 0 0 8px rgba(201,162,63,.22)}
.stage-full .hotspot:hover .hotspot-no,
.stage-full .hotspot:focus-visible .hotspot-no{color:var(--control-ink,#0a0a0a)}
.stage-full .hotspot:focus-visible{outline:3px solid #fff;outline-offset:3px}
.stage-full .hotspot::after{content:none}

.stage-full .hotspot .hotspot-count{top:-16px;left:6px;right:auto}
/* линия-лидер вверх-вправо */
.stage-full .hotspot::before{content:none}
.stage-full .hotspot .hotspot-label{position:absolute;left:30px;bottom:34px;
  transform:none;opacity:1;background:none;color:#fff;padding:0 0 3px;border-radius:0;
  border-bottom:1px solid rgba(255,255,255,.45);white-space:nowrap;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;font-weight:400;
  letter-spacing:.13em;text-transform:uppercase;transition:color .2s,border-color .2s}
.stage-full .hotspot:hover .hotspot-label,
.stage-full .hotspot:focus-visible .hotspot-label{color:var(--gold);border-color:var(--gold)}
.stage-full .hotspot:hover::before{background:var(--gold)}
.stage-full.dragging .hotspot{opacity:.15}

@media(max-width:760px){
  .stage-full{aspect-ratio:16/9;height:auto}
  .stage-title{bottom:88px;max-width:none;right:clamp(16px,4vw,24px)}
  .stage-full .hotspot .hotspot-label{font-size:9px;letter-spacing:.1em}
  .stage-full .hotspot::before{height:30px}
  .stage-full .hotspot .hotspot-label{left:22px;bottom:24px}
  .stage-marks{font-size:9px;letter-spacing:.12em}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ГЛАВНАЯ — переписана 04.09.2026. Шесть блоков вместо пятнадцати.
   Что чиним: страница была 7634px и делала работу пяти страниц; один и тот же
   кадр стоял дважды; object-fit:cover резал железо; обёртка 1280px на широком
   экране читалась узкой; статусные подписи показывали внутреннюю кухню.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Ширина полосы. !important здесь перебивал мобильное правило kettle.css (32px) и
   на 390 давал поля 36px вместо 16 — колонка 318 вместо 358. Каскад восстановлен:
   ограничение действует там, где оно и нужно, а мобильная ширина остаётся за
   kettle.css. */
.wrap,.matrix .wrap,.circuits .wrap,.lede > .wrap,.lede-circ,.stage-foot .wrap{
  width:min(1560px,calc(100% - 72px));margin-inline:auto}
@media(max-width:760px){
  .wrap,.matrix .wrap,.circuits .wrap,.lede > .wrap,.lede-circ,.stage-foot .wrap{
    width:calc(100% - 32px)}}

/* Кадр НЕ обрезается: полоса сама 16:9, железо видно целиком. */
.plate{position:relative;width:100%;aspect-ratio:16/9;background:#08090b;overflow:hidden}
.plate img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}
.plate.empty{background:repeating-linear-gradient(135deg,#101114 0 14px,#0b0c0f 14px 28px)}

/* 1. ГЕРОЙ: кадр целиком, текст ПОД ним — ничего не перекрыто и ничего не срезано */
.hero2{background:#08090b;color:#fff;padding-bottom:clamp(40px,5vw,80px)}
.hero2 .plate{aspect-ratio:16/9;max-height:78svh}
.hero2 .plate img{object-position:center}
.hero2 .hcopy{width:min(1560px,calc(100% - 72px));margin:clamp(28px,3.4vw,52px) auto 0;
  display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(28px,4vw,72px);align-items:end}
.hero2 h1{font-size:clamp(38px,5.2vw,78px);font-weight:600;letter-spacing:-.025em;
  line-height:1.02;margin:0;color:#fff;max-width:15ch}
.hero2 h1 em{font-style:normal;color:var(--gold)}
.hero2 .hsay{font-size:clamp(15px,1.15vw,18px);line-height:1.6;color:rgba(255,255,255,.78);
  margin:0;max-width:46ch}
.hero2 .hsay b{color:#fff;font-weight:600;font-variant-numeric:tabular-nums}
@media(max-width:900px){.hero2 .hcopy{grid-template-columns:1fr;gap:18px;align-items:start}}

/* 2. ЧЕТЫРЕ РАЗДЕЛА: одинаковые полосы, свой кадр, имя, одна строка. Без статусов. */
.sections{background:#08090b;color:#fff;padding:clamp(30px,4vw,64px) 0 clamp(56px,6vw,104px)}
.sect{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,3vw,56px);align-items:center;
  padding:clamp(26px,3vw,52px) 0;border-top:1px solid rgba(255,255,255,.16);
  text-decoration:none;color:inherit}
.sect:first-of-type{border-top:1px solid rgba(255,255,255,.9)}
.sect:nth-child(even) .plate{order:2}
.sect .n{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;
  letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.42);
  display:block;margin-bottom:14px}
.sect h3{font-size:clamp(26px,3.2vw,46px);font-weight:600;letter-spacing:-.02em;
  line-height:1.05;margin:0;color:#fff}
.sect p{font-size:15px;line-height:1.65;color:rgba(255,255,255,.62);margin:14px 0 0;
  max-width:44ch}
.sect .go{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.5px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--gold);margin-top:22px;
  display:inline-block;border-bottom:1px solid transparent;padding-bottom:3px}
.sect .go::after{content:" →"}
a.sect:hover h3{color:var(--gold)}
a.sect:hover .go{border-bottom-color:var(--gold)}
@media(max-width:820px){.sect{grid-template-columns:1fr;gap:20px}
  .sect:nth-child(even) .plate{order:0}}

/* ═══════════════════════════════════════════════════════════════════════════
   БЕЛОЕ ТЕЛО, ЧЁРНЫЕ ПОЛОСЫ — канон апекса.
   kettle.css заливает body графитом (раскладка brewery: чёрное тело, белые листы).
   Для эксплорера это дало чёрным ВСЁ. Тело белое; чёрными остаются только кадр
   рендера и матрица — то есть там, где чёрный несёт смысл, а не фон ради фона.
   ═══════════════════════════════════════════════════════════════════════════ */
body{background:#fff;color:var(--ink)}

.hero2{background:#fff;color:var(--ink);padding-bottom:clamp(44px,5vw,88px)}
.hero2 h1{color:var(--ink)}
.hero2 .hsay{color:var(--secondary)}
.hero2 .hsay b{color:var(--ink)}

.sections{background:#fff;color:var(--ink);
  padding:clamp(24px,3vw,52px) 0 clamp(56px,6vw,104px)}
.sect{border-top:1px solid var(--line)}
.sect:first-of-type{border-top:1px solid var(--ink)}
.sect .n{color:var(--faint,#8b8f94)}
.sect h3{color:var(--ink)}
.sect p{color:var(--secondary)}
.sect .go{color:var(--gold-d,#8a6a1c)}
a.sect:hover h3{color:var(--gold-d,#8a6a1c)}
a.sect:hover .go{border-bottom-color:var(--gold-d,#8a6a1c)}

/* Лента показателей — чёрная полоса на белом, как statband на апексе */
.statband-wrap{background:var(--graphite);color:#fff;padding:0}
.statband-wrap .value-ribbon{width:min(1560px,calc(100% - 72px));margin-inline:auto;
  border-top:0;border-bottom:0}

/* Крошки и шапка теперь на белом */
.topbar{color:var(--ink)}
.topbar .brand img{filter:none}
.topbar .back{color:var(--secondary)}
.crumbs a{color:var(--secondary)}
.crumbs .sep{color:var(--line)}
.crumbs [aria-current=page]{color:var(--ink)}

/* ═══════════════════════════════════════════════════════════════════════════
   ОДИН ОБЪЕКТ НА ЭКРАН.
   То, чего у меня не было ни разу: у icomat.co.uk первый экран это материал во
   весь вьюпорт и ни одной буквы; второй — одна фраза на весь экран; третий — две
   панели в рамках. Плотность у нас была вчетверо выше: заголовок, лид, сетка и
   таблица на одном экране. Здесь — по одному.
   ═══════════════════════════════════════════════════════════════════════════ */
.vp{position:relative;min-height:100svh;display:flex;flex-direction:column;
  justify-content:center}

/* ── 1. Кадр во весь экран. Ничего сверху, кроме реперной строки в углу. ──── */
.vp-shot{background:#08090b;padding:0;overflow:hidden}
.vp-shot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 52%}
.vp-shot .mark{position:absolute;z-index:2;font-family:var(--mono,ui-monospace,Consolas,monospace);
  font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.5)}
.vp-shot .mark.tl{top:24px;left:clamp(20px,3vw,48px)}
.vp-shot .mark.br{bottom:24px;right:clamp(20px,3vw,48px);color:rgba(255,255,255,.65)}
.vp-shot .mark b{color:var(--gold);font-weight:400}

/* ── 2. Одна фраза на весь экран. ────────────────────────────────────────── */
.vp-say{background:#fff;text-align:center;padding:0 clamp(20px,5vw,80px)}
.vp-say p,.vp-say h1{font-size:clamp(30px,5.4vw,84px);font-weight:600;letter-spacing:-.03em;
  line-height:1.06;color:var(--ink);max-width:20ch;margin:0 auto}
.vp-say p span,.vp-say h1 span{color:#9a9ea2}
.vp-say p b,.vp-say h1 b{color:var(--gold-d,#8a6a1c);font-weight:600;font-variant-numeric:tabular-nums}
.vp-say .foot{position:absolute;left:0;right:0;bottom:34px;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--faint,#8b8f94)}

/* ── 3. Две панели: до и после. Рамка, угловые засечки, моно-подпись. ────── */
.vp-two{background:#ececeb;padding:clamp(40px,6vh,90px) 0}
.vp-two .in{width:min(1560px,calc(100% - 72px));margin-inline:auto;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(16px,2vw,34px)}
.pane{position:relative;border:1px solid #b9b9b6;background:#08090b;aspect-ratio:4/3;
  overflow:hidden}
.pane img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pane .lbl{position:absolute;top:12px;left:14px;z-index:2;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;letter-spacing:.15em;
  text-transform:uppercase;color:rgba(255,255,255,.82);line-height:1.5}
.pane .lbl em{font-style:normal;display:block;color:var(--gold)}
/* угловые засечки */
.pane::before,.pane::after{content:"";position:absolute;z-index:3;width:7px;height:7px;
  border:1px solid rgba(255,255,255,.5)}
.pane::before{top:5px;left:5px;border-right:0;border-bottom:0}
.pane::after{bottom:5px;right:5px;border-left:0;border-top:0}
.vp-two .cap{width:min(1560px,calc(100% - 72px));margin:16px auto 0;display:flex;
  justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:#6d7175}
.vp-two .cap b{color:var(--ink);font-weight:400}
@media(max-width:760px){.vp-two .in{grid-template-columns:1fr}
  .vp{min-height:auto}
  .vp-shot{min-height:62svh}
  .vp-say{min-height:70svh}}

/* ═══════════════════════════════════════════════════════════════════════════
   ВЫСОТА ПЕРВОГО ЭКРАНА. Шапка и крошки стоят в обычном потоке и толкают его
   вниз — 100svh давал переполнение ровно на их высоту. Вычет только у первой
   секции: дальше шапка уже прокручена. svh, а не dvh: dvh пересчитывается при
   каждом показе панели браузера и даёт видимый сдвиг вёрстки.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{--header-h:98px}
@media(max-width:760px){:root{--header-h:88px}}
.vp{min-height:100vh;min-height:100svh}
.vp.first{min-height:calc(100vh - var(--header-h));
          min-height:calc(100svh - var(--header-h))}

/* Мобильные поправки по замеру 04.09.2026 (PROBE, 375px):
   1) шапка+крошки на 375 реально 142px, а не 88 — первый экран зонта вылезал на 54px;
   2) в липкой навигации «On this page» стало 6 ссылок — ряд не переносился и толкал
      документ вбок на 26px. Ряд остаётся одной строкой и скроллится сам. */
@media(max-width:760px){
  :root{--header-h:142px}
  .section-nav .wrap{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;
    justify-content:flex-start;gap:22px}
  .section-nav a{flex:none}
}

/* Полосы оборудования на хабе — язык зонта на белом. Первая полоса под чёрным ребром,
   дальше по светлым; кадр слева/справа попеременно как в .sect. */
.sections-inline .sect{border-top:1px solid var(--line)}
.sections-inline .sect:first-child{border-top:1px solid var(--ink)}
.sections-inline .sect p b{color:var(--ink);font-variant-numeric:tabular-nums}
#equipment-bands{padding-top:0}

/* Четыре аудитории на зонте: колонки по рёбрам, без рамок. */
.who{display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin-top:clamp(34px,4vw,64px);
  border-top:1px solid var(--ink)}
.who > div{padding:20px clamp(14px,1.8vw,28px) 4px 0;border-right:1px solid var(--line);
  margin-right:clamp(14px,1.8vw,28px)}
.who > div:last-child{border-right:0;margin-right:0}
.who .wn{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;
  letter-spacing:.16em;color:var(--faint,#8b8f94);display:block;margin-bottom:10px}
.who b{font-size:18px;font-weight:600;letter-spacing:-.01em;display:block}
.who p{font-size:13.5px;line-height:1.6;color:var(--secondary);margin:8px 0 0}
@media(max-width:820px){.who{grid-template-columns:1fr 1fr}
  .who > div:nth-child(2){border-right:0;margin-right:0}
  .who > div:nth-child(n+3){border-top:1px solid var(--line);margin-top:6px}}
@media(max-width:520px){.who{grid-template-columns:1fr}
  .who > div{border-right:0;margin-right:0;border-top:1px solid var(--line)}
  .who > div:first-child{border-top:0}}

/* ── Подзаголовок героя. Владелец 04.09.2026: описание назначения — одна-две фразы
   под заголовком, а не отдельная секция с четырьмя колонками аудиторий. ───────── */
.vp-say .sub{font-size:clamp(15px,1.15vw,18.5px);line-height:1.62;font-weight:400;
  letter-spacing:0;color:var(--secondary,#5c6165);max-width:62ch;
  margin:clamp(22px,2.4vw,34px) auto 0}
/* Строка выбора над полосами контуров: что именно от посетителя требуется. */
.sections .pick{font-size:clamp(14px,1vw,16px);line-height:1.6;color:rgba(255,255,255,.66);
  max-width:56ch;margin:0 0 clamp(20px,2.4vw,34px)}
.sections-inline .pick{color:var(--secondary,#5c6165)}

/* ═══════════════════════════════════════════════════════════════════════════
   КАДР И ЗАГОЛОВОК. Владелец 04.09.2026: «hero page обрезанная», «зачем
   подписать hot-water skid и remote assessment на самом изображении»,
   «ОПЯТЬ ДЕЛАЕШЬ ЭКРАН МАЛЕНЬКИЙ».

   Три причины дефекта, все измерены:
     1. .stage-full имел height:min(86svh,940px) при ширине 1905 — это 2.5:1
        против исходных 16:9, cover срезал 29% высоты кадра.
     2. picture() отдавал sizes="1280px" — браузер тянул 1280-й файл в рамку
        1905 и растягивал его. Теперь 100vw и 3840 в srcset.
     3. Заголовок и eyebrow стояли ПОВЕРХ железа. Теперь под кадром, на белом.
   ═══════════════════════════════════════════════════════════════════════════ */
.stage-head{background:#fff;padding:clamp(26px,3vw,46px) 0 clamp(6px,1vw,14px)}
.stage-head .eyebrow{color:var(--gold-d,#8a6a1c);margin-bottom:12px}
.stage-head h1{font-size:clamp(32px,4.6vw,72px);font-weight:600;letter-spacing:-.028em;
  line-height:1.02;margin:0;color:var(--ink)}
.stage-head .stage-cap{font-size:clamp(15px,1.15vw,18.5px);line-height:1.62;
  color:var(--secondary,#5c6165);max-width:62ch;margin:clamp(16px,1.8vw,26px) 0 0}
/* Заголовок ушёл с кадра — старая накладка больше не выводится. */
.stage-title{display:none}
/* Лента и примечание идут по белому, а не по тёмному вьюеру. */
.viewer .wrap .scenario-note{color:var(--secondary,#5c6165)}

/* Переключение ракурсов. Кадров по 15 на состояние; одна точка съёмки —
   это не осмотр оборудования, а открытка. */
/* Ракурсы — именованными пилюлями. Снято с живой /calc/laundry/dryer/ 04.09.2026: там
   CLOSE-UP / ISO RIGHT / ISO LEFT / FRONT / END текстом, и это читается лучше миниатюр —
   название камеры говорит, куда ты смотришь, а миниатюра 104px не говорит ничего. */
.angles{display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap;
  background:#0f1113;padding:12px clamp(16px,3vw,44px)}
.angles .lbl{font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:9.5px;
  letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.38);
  margin-right:8px}
.angles button{flex:0 0 auto;padding:8px 14px;min-height:36px;border:1px solid rgba(255,255,255,.16);
  background:transparent;color:rgba(255,255,255,.72);cursor:pointer;border-radius:0;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap}
.angles button:hover{color:#fff;border-color:rgba(255,255,255,.42)}
.angles button[aria-pressed="true"]{background:var(--gold);border-color:var(--gold);
  color:var(--control-ink,#141414)}

/* Цифры в кадре: предмет · голый · изолированный · процент. */
.stage-figures{position:absolute;left:50%;bottom:58px;transform:translateX(-50%);z-index:4;
  display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;justify-content:center;
  max-width:calc(100% - 40px);background:#0d1013e8;border:1px solid rgba(255,255,255,.14);
  padding:9px 16px;pointer-events:none;
  font-family:var(--mono,ui-monospace,Consolas,monospace);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
.stage-figures b{color:#fff;font-weight:500;font-variant-numeric:tabular-nums;
  letter-spacing:.04em}
.stage-figures b:last-of-type{color:var(--gold)}
@media(max-width:760px){.stage-figures{bottom:auto;top:auto;position:static;transform:none;
  max-width:none;border-left:0;border-right:0;justify-content:flex-start}}

/* Маркеры посажены по обзорному кадру — на другом ракурсе они гасятся. */
.stage.angle-off .hotspot{display:none}
/* kettle.css @media(min-width:1500px) ставит .stage{max-height:760px} — при ширине 1905
   это 2.5:1 против исходных 16:9, и cover срезал 29% кадра. Полноэкранной сцене кап не
   нужен: она полосой во весь вьюпорт, а не картинкой в колонке. */
@media(min-width:1500px){.viewer .stage.stage-full{max-height:none}}

/* ═══════════════════════════════════════════════════════════════════════════
   КАДР ЦЕЛИКОМ И В ОДИН ЭКРАН. Владелец 04.09.2026: «надо ОТДАЛИТЬ само фото,
   в один кадр не влезает теплообменник» и «можешь уменьшить экран, чтобы в
   один влезало всё».

   Рамка держит 16:9, но ограничена высотой вьюпорта за вычетом шапки и места
   под заголовок. Кадр вписывается через contain, а не cover: ничего не
   срезается, оборудование видно целиком и мельче. Поля по бокам чёрные, как и
   фон самих рендеров, поэтому их не видно.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Полоса кадра равна самому кадру. Раньше ширина была 100%, высота резалась потолком,
   и object-fit:contain вписывал 16:9 в коробку 2.28:1 — по 316px черноты по бокам на
   1440 и больше на широком экране. Считаем высоту, ширину выводим из неё. */
/* Во всю ширину экрана и в собственной пропорции кадра: нечего вписывать в поля и
   нечего обрезать. Обрезка здесь недопустима отдельно — метки заданы в процентах
   от рамки, и любой кроп сдвигает их с оборудования, на которое они указывают. */
.viewer .stage.stage-full{width:100%;aspect-ratio:16/9;height:auto;max-height:none;
  margin-inline:0}
.stage-full picture,.stage-full img{object-fit:contain}
@media(max-width:760px){.viewer .stage.stage-full{max-height:none;aspect-ratio:16/9}}

/* ═══════════════════════════════════════════════════════════════════════════
   ДВА ВАРИАНТА ГЕРОЯ. Запрошены владельцем 04.09.2026 для сравнения на живой
   странице теплообменников. Отличаются только первым экраном; всё ниже кадра
   одинаковое, чтобы сравнивать именно герой, а не две разные страницы.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Вариант 1 — светлый. Кадр на белом, поля вокруг белые, подписи тёмные.
   Рендеры сняты на чёрном, поэтому у кадра остаётся своя тёмная рамка: это
   видно и это осознанно — снимок лежит на листе, а не залит во весь экран. */
body.v-white .viewer .stage.stage-full{background:#fff;
  max-height:calc(100svh - var(--header-h) - 178px)}
body.v-white .stage-full::before{background:none}
body.v-white .stage-full .state-label{background:#fff;border-color:var(--line);
  color:var(--secondary)}
body.v-white .stage-marks{color:var(--faint,#8b8f94)}
body.v-white .stage-marks b{color:var(--gold-d,#8a6a1c)}
body.v-white .stage-figures{background:#fff;border-color:var(--line);
  color:var(--secondary,#565a5f)}
body.v-white .stage-figures b{color:var(--ink)}
body.v-white .stage-figures b:last-of-type{color:var(--gold-d,#8a6a1c)}
body.v-white .stage-foot .view-switch{background:#fff;border-color:var(--line)}
body.v-white .stage-foot .view-switch button{color:var(--secondary)}
body.v-white .stage-foot .view-switch button[aria-pressed="true"]{background:var(--gold);
  color:var(--control-ink)}
body.v-white .stage-foot .drag-hint{color:var(--faint,#8b8f94)}
body.v-white .angles{background:#fff;border-top:1px solid var(--line);
  border-bottom:1px solid var(--line)}
body.v-white .angles .lbl{color:var(--faint,#8b8f94)}
body.v-white .angles button{border-color:var(--line);color:var(--secondary)}
body.v-white .angles button:hover{color:var(--ink);border-color:var(--ink)}
body.v-white .angles button[aria-pressed="true"]{background:var(--gold);
  border-color:var(--gold);color:var(--control-ink)}

/* Вариант 2 — во весь экран. Кадр занимает весь вьюпорт от края до края,
   без вычета под заголовок и без полей: cover вместо contain. Кадр 16:9 в
   рамке 16:9 не режется; режется только там, где вьюпорт заметно площе. */
body.v-wide .viewer .stage.stage-full{max-height:none;aspect-ratio:auto;
  height:calc(100svh - var(--header-h));width:100%}
body.v-wide .stage-full picture,body.v-wide .stage-full img{object-fit:cover}
body.v-wide .stage-figures{bottom:74px}
body.v-wide .stage-head{padding-top:clamp(34px,4vw,64px)}
/* Кегль заголовка НЕ трогаем. Отдельная шкала на вариант — это ровно то, из-за чего
   «шрифты гуляют то мелкие то крупные»: на одном разделе должна быть одна лестница.
   Вариант отличается кадром, а не типографикой. */

/* guide-hero */
.ghero{background:#0c0d10}
.ghero-media{position:relative;width:100%;max-width:none;aspect-ratio:16/9;
  max-height:clamp(240px,58svh,600px);overflow:hidden}
.ghero-media picture,.ghero-media img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover}
.ghero-cap{color:#c4cbc8;font-size:13px;padding:13px 0 17px}
.ghero-lead{color:var(--secondary);margin-top:14px;max-width:44ch}
@media(max-width:760px){.ghero-media{max-height:52svh}.ghero-cap{font-size:12px}}

/* bare-state owns the markers */
/* В состоянии Bare кадр принадлежит меткам. Полоса цифр стоит по центру снизу и
   налезала на метку 6 — цифры перенесены в подпись под кадром. */
.stage.state-bare-on .stage-tag,
.stage.state-bare-on .stage-figures{display:none}

/* umbrella hero cta */
.vp-say .vp-cta{margin:clamp(26px,3vw,42px) auto 0;justify-content:center;gap:0}
@media(max-width:760px){.vp-say .vp-cta{margin-top:24px}}

/* umbrella hero aside */
.vp-say .vp-aside{margin:clamp(16px,1.6vw,24px) auto 0;max-width:52ch;
  font-size:clamp(13px,1vw,15px);line-height:1.6;color:var(--secondary,#5c6165)}
.vp-say .vp-aside a{color:var(--gold-d,#8a6a1c);text-underline-offset:3px}

/* circuits band title */
.sections-title{color:inherit;margin-bottom:8px}
.sections .pick{margin-bottom:clamp(22px,2.4vw,34px)}

/* hot-water hero */
.hw-hero{background:#08090b}
.hw-wipe{position:relative;overflow:hidden;background:#0e1013;user-select:none;
  cursor:ew-resize;touch-action:none;width:100%;
  height:min(calc(100svh - 112px),calc(100vw * 9 / 16))}
.hw-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:52% 50%;pointer-events:none}
.hw-over{position:absolute;inset:0;overflow:hidden;width:50%}
.hw-over .hw-img{width:auto;max-width:none}
.hw-bar{position:absolute;top:0;bottom:0;left:50%;width:2px;background:var(--gold);
  pointer-events:none;z-index:4}
.hw-bar::after{content:"";position:absolute;top:42%;left:50%;width:52px;height:52px;
  transform:translate(-50%,-50%);border:2px solid var(--gold);background:rgba(10,10,10,.55)}
.hw-knob{position:absolute;top:42%;left:50%;transform:translate(-50%,-50%);
  font:600 17px/1 var(--mono,ui-monospace,Consolas,monospace);color:var(--gold);z-index:5}
.hw-tip{position:absolute;top:calc(42% + 42px);left:50%;transform:translateX(-50%);
  white-space:nowrap;font:600 10.5px/1 var(--mono,ui-monospace,Consolas,monospace);
  letter-spacing:.14em;color:var(--gold);background:rgba(10,10,10,.8);padding:6px 10px;
  z-index:5}
.hw-lab{position:absolute;top:26px;z-index:3;font:600 11px/1 var(--mono,ui-monospace,
  Consolas,monospace);letter-spacing:.12em;text-transform:uppercase;color:#fff;
  background:rgba(10,10,10,.72);padding:8px 12px}
.hw-l{left:26px}
.hw-r{right:26px}
/* Текст стоит ПОД кадром, как в index_v3.html. Поэтому никакого затемнения на
   фотографии не нужно — оно существовало только чтобы белый текст поверх неё
   читался. */
/* Никакой полосы и никакого затемнения: текст висит прямо на кадре. Читаемость даёт
   тень на самом тексте, а не заливка поверх фотографии. */
.hw-copy{position:absolute;left:0;right:0;bottom:0;z-index:6;background:none;
  padding:0 0 clamp(26px,3.4vw,46px);pointer-events:none}
.hw-copy .wrap{pointer-events:auto}
.hw-copy h1,.hw-copy .eyebrow{text-shadow:0 2px 18px rgba(0,0,0,.75),0 1px 3px rgba(0,0,0,.9)}

.hw-copy .eyebrow{color:var(--gold);margin-bottom:10px}
/* Кегль меньше глобальной лестницы — по прямому указанию владельца для
   этого экрана: одна фраза, не плакат. */
.hw-copy h1{color:#fff;max-width:30ch;margin:0;font-size:clamp(24px,2.4vw,38px);line-height:1.12}
.hw-lead{color:#d3d7da;max-width:56ch;margin:14px 0 0;font-size:clamp(14px,1.05vw,16px);
  line-height:1.6}
.hw-cta{margin-top:clamp(18px,2vw,28px);justify-content:center;gap:0}
@media(max-width:760px){
  .hw-wipe{height:min(calc(100svh - 210px),calc(100vw * 9 / 16))}
  .hw-lab{top:14px;font-size:10px;padding:6px 9px}
  .hw-l{left:14px}.hw-r{right:14px}
  .hw-tip{display:none}
  .hw-copy h1{max-width:none}
}

/* explorer page */
/* На странице-маршрутизаторе метки — главное, поэтому они крупнее и всегда читаемы. */
.stage-full .hotspot .hotspot-label{background:rgba(10,10,10,.86);padding:6px 10px;
  color:#fff;left:50%;top:calc(100% + 8px);bottom:auto;transform:translateX(-50%)}
.stage-full .hotspot:hover .hotspot-label{background:var(--gold);
  color:var(--control-ink,#0a0a0a)}

/* hero cta hit area */
.hw-copy .wrap{position:relative;z-index:7}
.hw-cta{position:relative;z-index:8;pointer-events:auto}

/* pack dimensions */
.dim-title{font-weight:600}
.dim-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:10px}
.dim-grid label{display:block;font-size:12.4px;color:var(--secondary,#5c6165);
  margin-bottom:6px}
.dim-grid input{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--line);
  background:#fff;font:inherit;font-size:15px}
.dim-grid input:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
@media(max-width:520px){.dim-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
  .dim-grid input{padding:9px 8px;font-size:14px}}

/* label side */
.stage-full .hotspot.hs-right .hotspot-label{left:auto;right:-6px;transform:none;text-align:right}
.stage-full .hotspot .hotspot-label{max-width:min(46vw,260px);white-space:normal;
  line-height:1.25}

/* dark bar */
/* Полоса на прачечной: 70px, залита rgb(10,10,10). Белая полоса над чёрным героем
   выглядела как чужой элемент. */
.topbar{position:relative;color:#edece6;min-height:70px}
/* .topbar и .crumbs — это .wrap, поэтому заливка по ним оставляла белые поля по краям.
   Полоса красится подложкой во всю ширину окна. */
.topbar::before,.crumbs::before{content:"";position:absolute;top:0;bottom:0;left:50%;
  transform:translateX(-50%);width:100vw;background:#0a0a0a;z-index:0}
.topbar>*,.crumbs>*{position:relative;z-index:1}
.crumbs{position:relative}
/* Логотип один файл и он тёмный. Прачечная осветляет его этим же фильтром — способ
   домашний, файл не подменяется. */
.topbar .brand img{filter:brightness(0) invert(1)}
.topbar a{color:#c9ccc8}
.topbar a:hover{color:#fff}
.topbar .back{color:#c9ccc8}
.crumbs a{color:#9aa0a4}
.crumbs span[aria-current]{color:#edece6}
.crumbs .sep{color:#5c6165}

/* hero figure line */
.hw-fig{margin:14px 0 0;color:#9aa0a4;font:600 12.4px/1 var(--mono,ui-monospace,Consolas,
  monospace);letter-spacing:.12em;text-transform:uppercase}

/* bar to canon */
/* Снято с /calc/laundry/: ссылки разделов внутри полосы, кнопка — пилюля, а не .button. */
.topbar{gap:22px}
.topbar .secnav{display:flex;align-items:center;gap:0 22px;margin-left:auto;min-width:0;
  overflow-x:auto;scrollbar-width:none}
.topbar .secnav::-webkit-scrollbar{display:none}
.topbar .secnav a{font-size:13px;color:#c9ccc8;white-space:nowrap;padding:6px 0}
.topbar .secnav a:hover{color:#fff}
.topbar .pill{display:inline-flex;align-items:center;gap:7px;background:var(--gold);
  color:var(--control-ink,#0a0a0a);font-weight:700;font-size:13.5px;letter-spacing:.01em;
  padding:10px 18px;min-height:40px;border:0;text-decoration:none;white-space:nowrap}
.topbar .pill:hover{background:var(--gold-2,#d8b45a)}
.topbar .back{margin-right:0}
@media(max-width:900px){
  .topbar .secnav{order:4;flex-basis:100%;margin:4px 0 0}
  .topbar .pill{margin-left:auto}
}

/* guide wipe */
.gw-wipe{height:min(calc(100svh - 300px),calc(100vw * 9 / 16))}
.ghero-cap{color:#c4cbc8;font-size:13px;padding:13px 0 17px}
.gw-cta{margin:0 0 22px}
.gw-cta .pill{display:inline-flex;align-items:center;background:var(--gold);
  color:var(--control-ink,#0a0a0a);font-weight:700;font-size:13.5px;padding:12px 20px;
  min-height:44px;text-decoration:none}
.gw-cta .pill:hover{background:var(--gold-2,#d8b45a)}

/* instruction rows */
.igroup{margin-top:26px}
.ihead{font:600 11px/1 var(--mono,ui-monospace,Consolas,monospace);letter-spacing:.12em;
  text-transform:uppercase;color:var(--secondary,#5c6165);margin:0 0 8px}
.irow{display:grid;grid-template-columns:52px 1fr auto;align-items:center;gap:16px;
  padding:14px 0;border-top:1px solid var(--line);text-decoration:none;color:inherit}
.irow:last-child{border-bottom:1px solid var(--line)}
.irow:hover{background:rgba(201,162,63,.06)}
.irow .no{font:600 11px/1 var(--mono,ui-monospace,Consolas,monospace);
  color:var(--gold-d,#8a6a1c);letter-spacing:.1em}
.irow .itxt b{display:block;font-size:16px;font-weight:600}
.irow .itxt small{display:block;font-size:14px;color:var(--secondary,#5c6165);margin-top:3px}
.irow .go{font:600 12.4px/1 var(--mono,ui-monospace,Consolas,monospace);
  letter-spacing:.1em;text-transform:uppercase;color:var(--gold-d,#8a6a1c)}
@media(max-width:760px){.irow{grid-template-columns:44px 1fr;gap:12px}
  .irow .go{display:none}}

/* brand target size */
/* Ссылка-логотип была 20px по высоте — ниже минимума 24 по WCAG 2.5.8.
   Картинка не меняется, растёт только область нажатия. */
.topbar .brand{display:inline-flex;align-items:center;min-height:44px}

/* crumb target size */
/* Ссылки крошек были 18px. Картинка та же, растёт только область нажатия. */
.crumbs a{display:inline-flex;align-items:center;min-height:24px}
@media(max-width:760px){.crumbs a{min-height:28px}}

/* table link target size */
/* Ссылки в ячейках таблицы итогов были 18px — ниже минимума 24 по WCAG 2.5.8. */
table a{display:inline-flex;align-items:center;min-height:24px}

/* select target size */
/* Селекторы формы и размера были 23px — на пиксель ниже минимума. */
.slider-field select,.number-unit select{min-height:44px;padding:8px 10px}

/* equipment cta */
.eqcta{display:inline-flex;align-items:center;margin-top:14px;background:var(--gold);
  color:var(--control-ink,#0a0a0a);font-weight:700;font-size:13.5px;padding:11px 18px;
  min-height:44px;text-decoration:none}
.eqcta:hover{background:var(--gold-2,#d8b45a)}

/* Полосу шапки красит ::before шириной 100vw. 100vw считает вместе с полосой прокрутки,
   поэтому подложка вылезала за документ на её ширину — 8px горизонтального скролла на
   каждой странице. clip, а не hidden: hidden создал бы блок прокрутки и убил бы
   position:sticky у .section-nav, .result-card и .mobile-result. */
body{overflow-x:clip}


/* Строка элемента с кадром. Форма снята с /boilers/: номер, миниатюра, цифры, стрелка.
   Приставка e-, потому что .row, .thumb и .card в проекте уже заняты. */
.erows{display:grid;gap:1px;background:var(--line,#e4e4e2);border-top:1px solid var(--line,#e4e4e2);
  border-bottom:1px solid var(--line,#e4e4e2)}
.erow{display:grid;grid-template-columns:56px 132px 1fr auto 24px;align-items:center;
  gap:18px;padding:16px 4px;background:#fff;text-decoration:none;color:inherit;
  min-height:96px}
.erow:hover{background:#fbfaf7}
.erow .no{font:500 11px/1 var(--mono,ui-monospace,monospace);letter-spacing:.12em;
  color:var(--gold-d,#8a6a1c)}
.erow .ethumb{display:block;height:74px;border-radius:2px;background:#0a0a0a center/cover no-repeat}
.erow .etxt{min-width:0}
.erow .etxt b{display:block;font-size:17px;font-weight:600;letter-spacing:-.01em}
.erow .etxt small{display:block;font-size:14px;line-height:1.5;margin-top:4px;
  color:var(--secondary,#5c6165);font-variant-numeric:tabular-nums}
.erow .etxt em{display:block;font-style:normal;font-size:12.5px;margin-top:4px;
  color:var(--gold-d,#8a6a1c)}
.erow .ego{font-size:13px;font-weight:600;white-space:nowrap}
.erow .earr{color:var(--gold-d,#8a6a1c);text-align:right}
@media(max-width:860px){
  .erow{grid-template-columns:44px 96px 1fr;gap:12px;min-height:0}
  .erow .ethumb{height:58px}
  .erow .ego,.erow .earr{display:none}
}


/* Хаб контура собран через viewer(), а тот несёт заголовок УЗЛОВОЙ страницы:
   clamp(32px,4.6vw,72px), то есть 66px на 1425. У хаба горячей воды свой герой и своё
   правило 2.4vw, отсюда расхождение вдвое. Приводим хабы к той же шкале, узлы не трогаем. */
.circuit-hub .stage-head h1{font-size:clamp(24px,2.4vw,38px);line-height:1.12;
  letter-spacing:-.02em}
.circuit-hub .stage-head .lede-sub{font-size:clamp(14px,1.05vw,16px)}
