/* ===================== CONSTRUCTOR (station 3) ===================== */
.cstr { padding-block: var(--section-y); }
.cstr-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); align-items: start; margin-top: 2rem; }
@media (min-width: 900px) {
  .cstr-grid { grid-template-columns: minmax(0, 1fr) minmax(340px, 400px); }
  /* The form now starts directly with its first .va-row (no phase-head label),
     so the panel's top border lines up with the form's top border — no offset. */
  .cstr-panel { margin-top: 0; }
}
/* ── Review mode: /order-mobile reuses this block (review_mode=true) with the input flow
   hidden — the visitor reviews the recap, price and diagram, then attaches a photo and
   sends. The panel becomes a single centred card. See components/_constructor.html. ── */
.cstr--review .cstr-flow { display: none; }
.cstr--review .cstr-grid { grid-template-columns: 1fr; }
.cstr--review .cstr-panel { max-width: 34rem; margin-inline: auto; }
/* <label> is excluded from the global :focus-visible ring (styles.css); mirror it here so
   the attach button shows focus when constructor.js lands the visitor on it. */
.cstr--review .cstr-attach-btn:focus,
.cstr--review .cstr-attach-btn:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--radius-sm); }

/* result panel flows with the page as part of normal document flow —
   no sticky pinning, no separate inner scroll region */
.cstr-panel { position: static; }
.cstr-panel-inner { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-4); }
/* flat figure — the SVG is the only framed surface here; avoids box-in-box noise */
.cstr-figure { margin: 0; padding: 0; }
/* Object visual (architectural sketch) keyed to the selected object type; replaces the
   former live profile SVG. The sketches are 4:3 line drawings on white — contain (not
   cover) shows each drawing whole; the fixed aspect-ratio still prevents layout shift. */
.cstr-photo { width: 100%; height: auto; display: block; aspect-ratio: 4 / 3; object-fit: contain; background: #fff; border-radius: 6px; }
.cstr-figure-note { margin: var(--sp-2) 0 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--muted); }

/* Profile visualization — line + accent palette (custom props inherit into the inline SVG) */
#constructor {
  --pf-glass: rgba(44, 91, 143, .12);  /* glass tint — the only fill in the line+accent profile */
  --pf-mesh: #5c636c;                  /* plisse mesh */
}
/* subtle fade-in of the reactive layers on each re-render; motion-gated */
@media (prefers-reduced-motion: no-preference) {
  .pf-profile, .pf-plan, .pf-plisse { animation: pfFade .18s ease both; }
  @keyframes pfFade { from { opacity: 0 } to { opacity: 1 } }
}

/* ── Left input flow — engineering SPEC grammar (ported from constructor-variants/
   variant-a-spec.html, concept A). One row per parameter: label left (.va-key),
   value right (.va-val), hairline between rows. Text choices are inline values with
   no underline until chosen; sizes use sliders on a thin datum line + a bold readout.
   The form carries both `cstr-flow` (JS hook id) and `va-flow` (this grammar). */
.va-flow { display: grid; border-top: 1px solid var(--line); margin: 0; padding: 0; border-left: 0; }
.va-row { display: grid; grid-template-columns: 1fr; gap: var(--sp-3) var(--sp-5); padding: var(--sp-5) 0; border-bottom: 1px solid var(--line); }
@media (min-width: 680px) { .va-row { grid-template-columns: 160px minmax(0, 1fr); align-items: start; } }
.va-key { margin: 0; font-size: var(--fs-400); font-weight: 600; color: var(--ink); line-height: var(--lh-body); letter-spacing: var(--ls-tight); padding-top: .5rem; }
.va-val { min-width: 0; }

/* text choices — inline values, no underline until chosen; selected gets a tight 2px accent underline */
.va-opts { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-5); }
.va-opt { position: relative; display: inline-flex; align-items: center; min-height: 44px; }
.va-opt input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.va-opt > span { display: inline-block; padding: 0 .15rem 2px; cursor: pointer; color: var(--ink);
  font-size: var(--fs-300); line-height: var(--lh-heading); border-bottom: 2px solid transparent; transition: color .15s, border-color .15s; }
.va-opt input:hover + span { color: var(--accent); }
/* selected emphasis = accent color + 2px underline only. No font-weight (real weight
   widens the chip and reflows the flex-wrap row) and no text-shadow faux-bold (blurry
   synthetic weight outside the 400/600/700 grammar). */
.va-opt input:checked + span { color: var(--accent); border-bottom-color: var(--accent); }
.va-opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 2px; }

/* shapes drawn on a datum line */
.va-shapes { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.va-shape { position: relative; }
.va-shape input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.va-shape > span { display: grid; justify-items: center; gap: 6px; width: 66px; cursor: pointer; }
.va-shape__ico { display: flex; align-items: flex-end; justify-content: center; height: 40px; width: 100%; border-bottom: 1.5px solid var(--line); transition: border-color .15s; }
.va-shape__ico svg { width: 52px; max-width: 100%; height: auto; color: var(--aluminium); transition: color .15s; }
/* On the two-column row layout the five tiles fill the value column evenly so the
   datum lines align flush-right like every text row (no trailing gap). */
@media (min-width: 680px) {
  .va-shapes { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .va-shape > span { width: 100%; }
}
/* control label — 14 like every other option label, not 12 (12 = badges/fine print only) */
.va-shape__name { font-size: var(--fs-300); text-align: center; color: var(--muted); line-height: var(--lh-tight); transition: color .15s; }
.va-shape input:hover + span .va-shape__ico svg { color: var(--ink); }
.va-shape input:checked + span .va-shape__ico { border-bottom-color: var(--accent); }
.va-shape input:checked + span .va-shape__ico svg { color: var(--accent); }
.va-shape input:checked + span .va-shape__name { color: var(--ink); }
.va-shape input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }

/* dimensions — slider on a thin datum line + bold tabular readout */
.va-dims { display: grid; gap: var(--sp-5); }
.va-dim { display: grid; gap: .55rem; }
.va-dim__top { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; }
.va-dim__label { font-size: var(--fs-300); color: var(--muted); }
.va-dim__val { font-size: var(--fs-500); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: var(--ls-tight); }
.va-dim__val small { color: var(--muted); font-weight: 400; font-size: var(--fs-300); margin-left: .2rem; } /* unit = caption, quieter than the value */
.va-range { -webkit-appearance: none; appearance: none; width: 100%; height: 24px; background: transparent; cursor: pointer; margin: 0; }
.va-range::-webkit-slider-runnable-track { height: 3px; border-radius: 999px; background: linear-gradient(to right, var(--accent) var(--fill, 0%), var(--line) var(--fill, 0%)); }
.va-range::-moz-range-track { height: 3px; border-radius: 999px; background: var(--line); }
.va-range::-moz-range-progress { height: 3px; border-radius: 999px; background: var(--accent); }
.va-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); margin-top: -7.5px; box-shadow: 0 1px 2px rgba(35,39,44,.18); transition: box-shadow .15s; }
.va-range::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); box-shadow: 0 1px 2px rgba(35,39,44,.18); }
.va-range:focus-visible { outline: none; }
.va-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-wash); }
.va-range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--accent-wash); }
.va-hint { margin: var(--sp-3) 0 0; font-size: var(--fs-300); color: var(--muted); line-height: var(--lh-body); }

/* multi-select — same inline values (underline only when chosen) plus a checkbox affordance */
.va-checks { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-5); }
.va-check { position: relative; display: inline-flex; align-items: center; min-height: 44px; }
.va-check input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.va-check > span { display: inline-flex; align-items: center; gap: .5rem; padding: 0 .15rem 2px; cursor: pointer; color: var(--ink);
  font-size: var(--fs-300); line-height: var(--lh-heading); border-bottom: 2px solid transparent; transition: color .15s, border-color .15s; }
.va-check__box { flex: 0 0 auto; width: 17px; height: 17px; border: 1.5px solid var(--aluminium); border-radius: 3px; position: relative; transition: background .15s, border-color .15s; }
.va-check input:hover + span { color: var(--accent); }
.va-check input:hover + span .va-check__box { border-color: var(--accent); }
.va-check input:checked + span { color: var(--accent); border-bottom-color: var(--accent); text-shadow: .03em 0 0 currentColor, -.03em 0 0 currentColor; }
.va-check input:checked + span .va-check__box { background: var(--accent); border-color: var(--accent); }
.va-check input:checked + span .va-check__box::after { content: ""; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.va-check input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .va-opt > span, .va-shape__ico, .va-shape__ico svg, .va-shape__name,
  .va-range::-webkit-slider-thumb, .va-check > span, .va-check__box { transition: none; }
}

/* «Услуги» — the mobile-office option carries a 1px-line info glyph (no tile) that
   opens the #mobile-office-dialog popup. The glyph sits OUTSIDE the <label> so a
   click on it opens the popup instead of toggling the checkbox. */
.va-svc { display: inline-flex; align-items: center; }
.va-info { appearance: none; -webkit-appearance: none; background: none; border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; cursor: pointer;
  /* The label's text line sits ~2px above its box centre because the span reserves 4px at the
     bottom for the «selected» underline (padding-bottom 2px + border-bottom 2px). Mirror that
     reserve here (border-box) so the centred glyph lands on the same optical line as the text. */
  padding: 0 0 4px; margin: 0 -.6rem;
  color: var(--aluminium); border-radius: 50%; transition: color .15s; }
.va-info svg { width: 18px; height: 18px; display: block; }
.va-info:hover { color: var(--accent); }
.va-info:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .va-info { transition: none; } }
/* The «Тип стекла» row label carries the same 1px-line info glyph inline after its text; it opens
   the #glass-types-dialog comparison. Compact so it rides the heading line without growing the row. */
.va-key--info .va-info { width: 28px; height: 28px; padding: 0; margin: 0 0 0 .15rem; vertical-align: middle; }

/* Info popup — a calm content card reusing the native <dialog> mechanics of .lightbox. */
.info-dialog { padding: 0; border: 0; max-width: min(560px, 92vw); width: 100%;
  background: var(--surface); color: var(--ink); border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px -20px rgba(11,13,15,.45); overflow: hidden; }
.info-dialog::backdrop { background: rgba(11,13,15,.55); }
.info-dialog__inner { position: relative; }
.info-dialog__media { margin: 0; background: var(--surface-2); }
.info-dialog__media img,
.info-dialog__media video { display: block; width: 100%; height: auto; }
.info-dialog__body { padding: var(--sp-5); }
.info-dialog__title { margin: 0 0 var(--sp-3); font-size: var(--fs-500); font-weight: 700;
  line-height: var(--lh-heading); letter-spacing: var(--ls-tight); color: var(--ink); }
.info-dialog__body p { margin: 0 0 var(--sp-3); color: var(--muted); line-height: var(--lh-body); }
.info-dialog__body p:last-child { margin-bottom: 0; }
.info-dialog__close { position: absolute; top: .6rem; right: .6rem; width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.88); border: 1px solid var(--line); border-radius: 50%;
  color: var(--ink); cursor: pointer; transition: color .15s, border-color .15s; }
.info-dialog__close:hover { color: var(--accent); border-color: var(--accent); }
.info-dialog__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .info-dialog__close { transition: none; } }

/* Text-only info popup (no media figure) — keep the title clear of the floating ✕ button. */
.info-dialog--text .info-dialog__title { padding-right: var(--sp-7); }

/* Glass-type comparison — each row pairs a swatch (the same mini-scene seen through that glass)
   with its description, so clarity, tint and frost read side by side. */
.glass-compare { list-style: none; margin: var(--sp-4) 0; padding: 0; display: grid; }
.glass-compare > li { display: grid; grid-template-columns: 72px minmax(0, 1fr); column-gap: var(--sp-4);
  align-items: start; padding: var(--sp-3) 0; border-top: 1px solid var(--line); }
.glass-swatch { width: 72px; height: 56px; display: block; border: 1px solid var(--line);
  border-radius: var(--radius-sm); overflow: hidden; object-fit: cover; object-position: center;
  background: var(--surface-2); }
.glass-compare__text { min-width: 0; display: grid; gap: var(--sp-1); }
.glass-compare__name { color: var(--ink); font-weight: 600; font-size: var(--fs-400); line-height: var(--lh-heading); }
.glass-compare__desc { color: var(--muted); font-size: var(--fs-400); line-height: var(--lh-body); }

/* drafting-sheet ordinal — used by the process strip (docs/preview-process-horizontal.html) */
.step-ord { display: inline-flex; align-items: center; gap: var(--sp-1); font-size: var(--fs-300); font-weight: 600; line-height: var(--lh-flat); color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: var(--ls-tight); }
.step-ord::after { content: ""; width: 8px; height: 1px; background: var(--aluminium); flex: none; }
.step-ord--accent { color: var(--accent); }

/* .cstr-chip base is REUSED by #product .vh-chip (see comment near the object preview
   bar below) — keep it. The :hover/:checked/:focus states here drive the old
   configurator chips; the .vh-chip states are scoped separately under #product. */
.cstr-chip { position: relative; }
.cstr-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.cstr-chip > span { display: flex; align-items: center; min-height: 44px; padding: .55rem .9rem; border: 1px solid var(--line);
  border-radius: 6px; background: var(--surface); color: var(--ink); font-size: var(--fs-300); cursor: pointer; transition: border-color .15s, background .15s; }
.cstr-chip input:hover + span { border-color: var(--aluminium); }
.cstr-chip input:checked + span { border-color: var(--accent); color: var(--accent); }
.cstr-chip input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* VERDICT zone — flat hairline section, not a boxed card (de-templating: no box-in-box) */
.cstr-result { border-top: 1px solid var(--line); padding-top: var(--sp-4); }
.cstr-result.is-consultation { border-top-color: var(--accent); }
.cstr-result-live { display: grid; gap: var(--sp-3); }
/* ориентир (price) is the headline; recommendation + pricing caveat group tightly below it */
.cstr-note { display: grid; gap: .35rem; }
.cstr-reco { font-size: var(--fs-400); font-weight: 600; color: var(--ink); margin: 0; line-height: var(--lh-body); }
/* .cstr-limits is a <details>; amount/disclaimer are <p> — all block, so the JS .hidden toggle
   works natively. Keep the limits rule explicit for clarity. */
.cstr-limits[hidden] { display: none; }
.cstr-estimate-amount { font-size: var(--fs-500); font-weight: 600; color: var(--ink); margin: 0; font-variant-numeric: tabular-nums; letter-spacing: var(--ls-tight); }
.cstr-estimate-disclaimer { margin: 0; font-size: var(--fs-300); line-height: var(--lh-body); }
.cstr-muted { color: var(--muted); }
.cstr-flags { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.cstr-flags:empty { display: none; }
.cstr-flags li { display: flex; gap: .5rem; font-size: var(--fs-300); color: var(--ink); line-height: var(--lh-body);
  padding: .5rem .7rem; background: var(--surface); border-left: 3px solid var(--accent); border-radius: var(--radius-sm); }

/* merged limitations: a chip (summary) reveals the flag list — replaces the in-SVG text badge */
.cstr-limits { border: 0; padding: 0; margin: 0; }
.cstr-limit-chip { display: inline-flex; align-items: center; gap: .4rem; width: max-content; cursor: pointer; list-style: none;
  font-size: var(--fs-300); font-weight: 600; color: var(--accent); padding: .35rem .65rem;
  border: 1px solid var(--accent); border-radius: var(--radius-sm); background: var(--accent-wash); }
.cstr-limit-chip::-webkit-details-marker { display: none; }
.cstr-limit-chip::after { content: "▾"; font-size: .75em; transition: transform .15s; }
.cstr-limits[open] .cstr-limit-chip::after { transform: rotate(180deg); }
.cstr-limit-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cstr-limits > .cstr-flags { margin-top: var(--sp-3); }
@media (prefers-reduced-motion: reduce) { .cstr-limit-chip::after { transition: none; } }

/* ACTION zone — recap chips + contact form set apart as a tinted footer of the panel */
.cstr-send { margin: 0 calc(-1 * var(--sp-4)) calc(-1 * var(--sp-4)); padding: var(--sp-4); background: var(--bg);
  border-top: 1px solid var(--line); border-radius: 0 0 var(--radius) var(--radius); display: grid; gap: var(--sp-3); }
/* recap = neat 2-column spec table on the tinted footer — reads as "what we send" */
.cstr-recap { width: 100%; border-collapse: collapse; font-size: var(--fs-300);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.cstr-recap:has(tbody:empty) { display: none; }
.cstr-recap th, .cstr-recap td { text-align: left; padding: 6px 10px; vertical-align: top; border-top: 1px solid var(--line); line-height: var(--lh-body); }
.cstr-recap tr:first-child th, .cstr-recap tr:first-child td { border-top: 0; }
.cstr-recap th { font-weight: 600; color: var(--muted); white-space: nowrap; width: 1%; }
.cstr-recap td { color: var(--ink); font-variant-numeric: tabular-nums; }
.cstr-lead { display: grid; gap: var(--sp-3); }
.cstr-attach { display: grid; gap: var(--sp-2); }
.cstr-attach-title { margin: 0; font-size: var(--fs-300); font-weight: 600; color: var(--ink); }
.cstr-attach-actions { display: flex; gap: var(--sp-2); }
.cstr-attach-actions .btn { flex: 1 1 0; min-width: 0; }
.cstr-attach-btn { cursor: pointer; }
.cstr-attach-name { display: block; }
/* Кнопка «Прикрепить фото»: на десктопе — пара «С компьютера» / «С телефона»,
   на телефонах — одна кнопка «Загрузить» (QR-передача на телефоне не нужна). */
.cstr-attach-txt-sm { display: none; }
@media (max-width: 560px) {
  .cstr-attach-btn--qr { display: none; }
  .cstr-attach-txt-lg { display: none; }
  .cstr-attach-txt-sm { display: inline; }
}

/* «Продолжить на телефоне» QR hand-off modal — builds on .info-dialog (js/phone-handoff.js). */
.qr-dialog { max-width: min(420px, 92vw); }
.qr-dialog__body { display: grid; gap: var(--sp-3); text-align: center; }
.qr-dialog__title { margin: 0; }
.qr-dialog__figure { display: flex; justify-content: center; }
.qr-dialog__code { width: 260px; max-width: 72vw; aspect-ratio: 1; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--sp-2); }
.qr-dialog__code svg { display: block; width: 100%; height: 100%; }
.qr-dialog__lead { margin: 0; color: var(--muted); line-height: var(--lh-body); }
.qr-recap { list-style: none; margin: 0; padding: 0; text-align: left; border-top: 1px solid var(--line); }
.qr-recap li { display: flex; justify-content: space-between; gap: var(--sp-3);
  padding: 6px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-300); }
.qr-recap__k { color: var(--muted); }
.qr-recap__v { color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.qr-dialog__fallback, .qr-dialog__note { margin: 0; }

/* success replaces the form inside the same footer — flat, no extra box */
.cstr-success { border: 0; padding: 0; }
.cstr-success h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-500); }
.cstr-success p { margin: 0 0 var(--sp-2); }
.cstr-success p:last-child { margin: 0; }

/* recap caption */
.cstr-recap-label { margin: 0; font-size: var(--fs-300); font-weight: 600; color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .cstr-chip > span { transition: none; }
}

/* ---------- Station 1: hero ---------- */
.hero { padding: clamp(2rem, 5vw, 4rem) 0 2.5rem; }
.hero__grid {
  display: grid; gap: clamp(1.5rem, 4vw, 3rem);
  grid-template-columns: 1fr; align-items: center;
}
.hero__copy { max-width: 36rem; }
.hero h1 {
  font-size: var(--fs-800); line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight); margin: 0.4rem 0 1rem; font-weight: 700;
}
.hero__lead { color: var(--muted); font-size: var(--fs-500); max-width: 34rem; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 1.5rem 0 0.5rem; }
.hero__secondary { margin: 0.75rem 0 0; }
.hero__media {
  position: relative; margin: 0; border-radius: 8px; overflow: hidden;
  background: var(--bg);
}
.hero__img { display: block; width: 100%; height: auto; aspect-ratio: 1376 / 768; object-fit: cover; }
.hero__caption {
  position: absolute; left: 0.75rem; bottom: 0.75rem; margin: 0;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  padding: 0.25rem 0.5rem; border-radius: 5px;
  border-left: 0; /* floating dimension tag, not an editorial figcaption */
}

/* proof strip */
.proof-strip {
  list-style: none; margin: 2rem 0 0; padding: 1rem 0 0; border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem 1.5rem;
}
.proof-strip li { display: flex; flex-direction: column; gap: 0.1rem; }
.proof-strip strong { font-variant-numeric: tabular-nums; } /* weight 600 comes from the global strong rule */
.proof-strip span { color: var(--muted); font-size: var(--fs-300); }

@media (min-width: 880px) {
  .hero__grid { grid-template-columns: 1.05fr 1fr; }
  .proof-strip { grid-template-columns: repeat(5, 1fr); }
}
/* While the proof strip is 2-col, 5 items leave a lone 5th in the last row —
   let it span the full width so it reads as intentional, not a grid error. */
@media (max-width: 879px) {
  .proof-strip li:last-child { grid-column: 1 / -1; }
}
/* On phones stack the two hero CTAs full-width so they share one tidy width
   instead of two buttons of different intrinsic width. */
@media (max-width: 560px) {
  .hero__cta { display: grid; grid-template-columns: 1fr; }
  .hero__cta .btn { width: 100%; }
}

/* ---------- Station 2: product / object preview (replaces old value cards) ---------- */
.value { padding: var(--section-y) 0; }   /* keep station padding; section--alt supplies the band */

/* ── Variant B2 — "Architectural frame + object preview" ──
   B's editorial composition (dominant ticked photo + narrow text column) with a
   pure-CSS object PREVIEW that swaps the photo, its caption and the CTA wording in place.
   It is NOT a second configurator step: one CTA carries the chosen object into #constructor.
   All selectors scoped under #product; token-driven; no shadows beyond --shadow-card. */

/* plain band background — no engineered grid, so the hairline rows and photo frames read cleanly.
   #product is a white panel via .section--alt (white on the --bg ground); stays relative to contain the radios. */
#product {
  position: relative;   /* contain the visually-hidden absolutely-positioned radios */
}

/* radios are control-only — visually hidden, kept in flow & focusable.
   Direct children of the section so ":checked ~ .container" matches photo, caption, chip, CTA. */
#product .vh-radio {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

#product .vh-grid {
  display: grid;
  gap: var(--sp-6);
  align-items: center;
}

/* ── Figure: dominant photo; .figure--ticked supplies the corner registration ticks ── */
#product .vh-figure {
  margin: 0;
  background: var(--surface);
}
/* fixed 3:2 stage → all sources share the box → zero layout shift on switch;
   object-fit:cover gives a consistent full-bleed architectural frame. */
#product .vh-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
}
#product .vh-shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;            /* full-bleed: consistent architectural frame; box never shifts */
  object-position: center bottom; /* anchor crop to the base of the frame: ground line stays visible */
  opacity: 0;
  transition: opacity .35s ease;
}
/* default visible object = Терраса (also the markup default-checked) */
#product .vh-shot--terrace { opacity: 1; }

/* ── caption: only the active per-object line shows ── */
/* all caption lines share ONE grid cell → the box is as tall as the longest line,
   so switching never changes height (the chip row below never jumps). */
#product .vh-cap { position: relative; display: grid; }
#product .vh-cap__line {
  grid-area: 1 / 1;
  visibility: hidden;
  line-height: var(--lh-body);
  max-width: 36rem;
}
#product .vh-cap__line--terrace { visibility: visible; }

/* ── PURE-CSS switch logic: radio :checked ~ .container … ──
   The five inputs are siblings of .container, so checked state reaches photo, caption, chip, CTA. */
#product #vh-obj-terrace:checked ~ .container .vh-shot--terrace,
#product #vh-obj-veranda:checked ~ .container .vh-shot--veranda,
#product #vh-obj-house:checked   ~ .container .vh-shot--house,
#product #vh-obj-gazebo:checked  ~ .container .vh-shot--gazebo,
#product #vh-obj-balcony:checked ~ .container .vh-shot--balcony,
#product #vh-obj-horeca:checked  ~ .container .vh-shot--horeca,
#product #vh-obj-greenhouse:checked ~ .container .vh-shot--greenhouse { opacity: 1; }
/* when a non-default object is chosen, hide the default terrace shot */
#product #vh-obj-veranda:checked ~ .container .vh-shot--terrace,
#product #vh-obj-house:checked   ~ .container .vh-shot--terrace,
#product #vh-obj-gazebo:checked  ~ .container .vh-shot--terrace,
#product #vh-obj-balcony:checked ~ .container .vh-shot--terrace,
#product #vh-obj-horeca:checked  ~ .container .vh-shot--terrace,
#product #vh-obj-greenhouse:checked ~ .container .vh-shot--terrace { opacity: 0; }

#product #vh-obj-veranda:checked ~ .container .vh-cap__line--terrace,
#product #vh-obj-house:checked   ~ .container .vh-cap__line--terrace,
#product #vh-obj-gazebo:checked  ~ .container .vh-cap__line--terrace,
#product #vh-obj-balcony:checked ~ .container .vh-cap__line--terrace,
#product #vh-obj-horeca:checked  ~ .container .vh-cap__line--terrace,
#product #vh-obj-greenhouse:checked ~ .container .vh-cap__line--terrace { visibility: hidden; }
#product #vh-obj-veranda:checked ~ .container .vh-cap__line--veranda,
#product #vh-obj-house:checked   ~ .container .vh-cap__line--house,
#product #vh-obj-gazebo:checked  ~ .container .vh-cap__line--gazebo,
#product #vh-obj-balcony:checked ~ .container .vh-cap__line--balcony,
#product #vh-obj-horeca:checked  ~ .container .vh-cap__line--horeca,
#product #vh-obj-greenhouse:checked ~ .container .vh-cap__line--greenhouse { visibility: visible; }

/* ── Aside: narrow editorial text column ── */
#product .vh-aside { max-width: 32rem; }
#product .vh-title { margin: 0 0 var(--sp-4); text-wrap: balance; }
#product .vh-lead { margin: 0 0 var(--sp-5); max-width: 30rem; }

/* ── 4 constant product truths as quiet hairline-divided caption lines — never boxes ── */
#product .vh-truths {
  margin: 0;
  border-top: 1px solid var(--line);
}
#product .vh-truth {
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
#product .vh-truth__term {
  font-size: var(--fs-400);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: var(--ls-tight);
}
#product .vh-truth__desc {
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-400); /* section content reads at body size, not caption */
  line-height: var(--lh-body);
  color: var(--muted);
}

/* ── Object PREVIEW bar — reuses the live .cstr-chip > span base styling so it never drifts.
   Only the active/focus STATE is scoped here (section-level radio drives a remote label). ── */
#product .vh-objbar { margin: var(--sp-5) 0 0; }
#product .vh-objbar__label {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-300);
  color: var(--muted);
}
#product .vh-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
/* .vh-chip rides on .cstr-chip > span base (border, 44px target, radius, transition from home.css).
   The label is associated via [for]; no nested <input>, so state must be scoped here. */
#product .vh-chip { position: relative; }
/* hover feedback: .vh-chip reuses .cstr-chip > span but has no nested input, so the
   base `cstr-chip input:hover + span` rule never fires — supply hover here. */
#product .vh-chip:hover > span { border-color: var(--aluminium); }
/* active chip reflects the checked radio (accent-wash + accent border, like the configurator) */
#product #vh-obj-terrace:checked ~ .container .vh-chip[for="vh-obj-terrace"] > span,
#product #vh-obj-veranda:checked ~ .container .vh-chip[for="vh-obj-veranda"] > span,
#product #vh-obj-house:checked   ~ .container .vh-chip[for="vh-obj-house"]   > span,
#product #vh-obj-gazebo:checked  ~ .container .vh-chip[for="vh-obj-gazebo"]  > span,
#product #vh-obj-balcony:checked ~ .container .vh-chip[for="vh-obj-balcony"] > span,
#product #vh-obj-horeca:checked  ~ .container .vh-chip[for="vh-obj-horeca"]  > span,
#product #vh-obj-greenhouse:checked ~ .container .vh-chip[for="vh-obj-greenhouse"] > span {
  border-color: var(--accent);
  color: var(--accent);
}
/* keyboard focus ring follows the (visually hidden) radio onto its chip label */
#product #vh-obj-terrace:focus-visible ~ .container .vh-chip[for="vh-obj-terrace"] > span,
#product #vh-obj-veranda:focus-visible ~ .container .vh-chip[for="vh-obj-veranda"] > span,
#product #vh-obj-house:focus-visible   ~ .container .vh-chip[for="vh-obj-house"]   > span,
#product #vh-obj-gazebo:focus-visible  ~ .container .vh-chip[for="vh-obj-gazebo"]  > span,
#product #vh-obj-balcony:focus-visible ~ .container .vh-chip[for="vh-obj-balcony"] > span,
#product #vh-obj-horeca:focus-visible  ~ .container .vh-chip[for="vh-obj-horeca"]  > span,
#product #vh-obj-greenhouse:focus-visible ~ .container .vh-chip[for="vh-obj-greenhouse"] > span {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── ONE CTA whose object word swaps with the preview — proves it's the same flow ── */
#product .vh-link {
  margin-top: var(--sp-4);
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .3ch;
}
#product .vh-link__obj { display: none; }
#product .vh-link__obj--terrace { display: inline; }
#product #vh-obj-veranda:checked ~ .container .vh-link__obj--terrace,
#product #vh-obj-house:checked   ~ .container .vh-link__obj--terrace,
#product #vh-obj-gazebo:checked  ~ .container .vh-link__obj--terrace,
#product #vh-obj-balcony:checked ~ .container .vh-link__obj--terrace,
#product #vh-obj-horeca:checked  ~ .container .vh-link__obj--terrace,
#product #vh-obj-greenhouse:checked ~ .container .vh-link__obj--terrace { display: none; }
#product #vh-obj-veranda:checked ~ .container .vh-link__obj--veranda,
#product #vh-obj-house:checked   ~ .container .vh-link__obj--house,
#product #vh-obj-gazebo:checked  ~ .container .vh-link__obj--gazebo,
#product #vh-obj-balcony:checked ~ .container .vh-link__obj--balcony,
#product #vh-obj-horeca:checked  ~ .container .vh-link__obj--horeca,
#product #vh-obj-greenhouse:checked ~ .container .vh-link__obj--greenhouse { display: inline; }

/* ── Asymmetric two-column from 900px: photo dominant, text narrow ── */
@media (min-width: 900px) {
  #product .vh-grid {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: var(--sp-8);
    align-items: stretch;
  }
  /* Photo fills the column height so the media + object switcher and the
     truths + CTA share a bottom baseline at every desktop width — this fixes
     the uneven section bottom without depending on one fixed ratio. The shots
     are inset:0 inside the stage, so object-fit:cover only crops and nothing
     shifts when the object is switched. */
  #product .vh-media { display: flex; flex-direction: column; }
  #product .vh-figure { flex: 1 1 auto; display: flex; flex-direction: column; }
  #product .vh-stage { aspect-ratio: auto; flex: 1 1 auto; min-height: 20rem; }
  /* keep the truth rows a touch tighter so the columns stay close in height */
  #product .vh-truth { padding-block: var(--sp-3); }
}

/* respect reduced motion — instant swap, no crossfade */
@media (prefers-reduced-motion: reduce) {
  #product .vh-shot { transition: none; }
}

/* ── Компоненты системы — a single horizontal row of component cards. Each card is a
   4:3 photo with the component name and a one-line note beneath it. No switcher, no
   ordinals; the row wraps 6-up → 3-up → 2-up as the viewport narrows. ── */
#product .vh-comp {
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  padding-bottom: var(--sp-6);
  border-top: 1px solid var(--line);
}
#product .vh-comp__title {
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-500);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}

/* the row: 2-up (mobile) → 3-up → 6-up single strip on desktop.
   minmax(0,1fr) lets the narrow columns shrink without overflow. */
#product .vh-comp-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-5) var(--sp-4);
  align-items: start;
}
@media (min-width: 600px) {
  #product .vh-comp-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 960px) {
  #product .vh-comp-row { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--sp-4); }
}

/* one card — borderless, image-led; caption sits directly under the photo */
#product .vh-comp-card { margin: 0; }
/* fixed 4:3 box → object-fit:cover crops every source to one consistent frame, zero shift */
#product .vh-comp-card__media {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
}
#product .vh-comp-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;   /* full-bleed architectural crop to 4:3 */
}
#product .vh-comp-card__cap {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  margin-top: var(--sp-3);
  /* opt out of the global figcaption hairline rail so the caption sits flush
     under the photo (same as .timeline__cap / .diagram__cap) */
  border-left: 0;
  padding-left: 0;
}
#product .vh-comp-card__term {
  font-size: var(--fs-400);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}
#product .vh-comp-card__desc {
  font-size: var(--fs-400); /* section content reads at body size, not caption */
  line-height: var(--lh-body);
  color: var(--muted);
}
#product .vh-comp-card__badge {
  display: inline-block;
  margin-left: var(--sp-2);
  padding: .05em .5em;
  font-size: var(--fs-200);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  vertical-align: 0.08em;
}

#product .vh-comp__more { margin: var(--sp-6) 0 0; }

/* ---------- Station 9: Lumon timeline ---------- */
.lumon { padding: var(--section-y) 0; }
/* cap the working width so the timeline reads as dense as the engineering/process
   blocks rather than stretching the full container with over-long text lines */
.timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; position: relative; max-width: 64rem; }
.timeline__item {
  display: grid; grid-template-columns: 5.5rem 1fr; gap: 0.75rem 1.25rem;
  border-left: 2px solid var(--line); padding: 0 0 0.25rem 1.25rem;
}
.timeline__year { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--accent); }
.timeline__photo { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; display: block; margin: 0 0 0.6rem; border: 1px solid var(--line); }
.timeline__text h3 { margin: 0 0 0.25rem; } /* size/weight inherit the base h3 role (20/700) */
.timeline__text p { margin: 0; color: var(--muted); max-width: 68ch; }
.timeline__media { margin: 0.75rem 0 0; max-width: 16rem; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--surface); }
.timeline__media img { display: block; width: 100%; height: auto; }
/* caption sits inside the framed .timeline__media box — no editorial side-rule */
.timeline__cap { padding: 0.4rem 0.6rem; font-size: var(--fs-300); color: var(--muted); border-left: 0; }
.lumon__note { margin: 1.5rem 0 0; }

/* scroll-reveal: enhanced by ui.js; falls back to visible under reduced-motion or no-JS */
.js .timeline__item[data-reveal] { opacity: 0; transform: translateY(12px); transition: opacity .5s ease, transform .5s ease; }
.js .timeline__item[data-reveal].is-revealed { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .timeline__item[data-reveal] { opacity: 1; transform: none; transition: none; }
}

@media (min-width: 720px) { .timeline__item { grid-template-columns: 6rem 1fr; } }

/* ---------- Station 9b: press / media coverage (Мы в СМИ) ---------- */
/* Horizontal press cards: a 4-up row of framed thumbnails + citation text.
   De-templated — flat, no outer box, no shadow, no lift. The thumbnail's hairline
   frame (the .timeline__media image idiom) plus whitespace carry the structure,
   the same way the "Наши работы" scenario grid does. Equal-height cards align the
   accent read-cue to a common baseline (margin-top:auto). */
.press { padding: var(--section-y) 0; }
.press-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-5);
}
@media (min-width: 600px) { .press-list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) {
  .press-list { grid-template-columns: repeat(4, 1fr); gap: var(--sp-5) var(--sp-4); }
}

.press-item {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  color: var(--ink);
  text-decoration: none;
}

/* thumbnail: normalise the four mixed aspect ratios into one framed plate */
.press-item__media {
  margin: 0;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg);
  transition: border-color .18s ease;
}
.press-item__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

.press-item__body { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.press-item__source { font-weight: 600; color: var(--ink); transition: color .18s ease; }
.press-item__headline { color: var(--muted); line-height: var(--lh-body); } /* body size — it's content, not a caption */
.press-item__cue {
  align-self: start;
  display: inline-flex; align-items: center; gap: var(--sp-1);
  color: var(--accent); font-size: var(--fs-300); font-weight: 600; white-space: nowrap;
}
.press-item__arrow { flex: none; transform: translateY(0.5px); }

/* hover / keyboard focus: hairline warm-up — thumbnail frame + source turn accent, no lift
   (the global :focus-visible ring still supplies the keyboard focus indicator) */
.press-item:hover .press-item__media, .press-item:focus-visible .press-item__media { border-color: var(--aluminium); }
.press-item:hover .press-item__source, .press-item:focus-visible .press-item__source { color: var(--accent); }

/* scroll-reveal: same grammar as the timeline; falls back visible under reduced-motion / no-JS */
.js .press-list__item[data-reveal] { opacity: 0; transform: translateY(12px); transition: opacity .5s ease, transform .5s ease; }
.js .press-list__item[data-reveal].is-revealed { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .press-list__item[data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---------- Station 10a: contacts (channels + lead form) ---------- */
/* .contact__grid / .contact__channels / .contact__meta / .contact__form /
   .contact__success — relocated to styles.css (2026-06-27) so deep pages can use them. */

/* The shared .section helper is a flat 4.5rem; the contacts + QR stations use it,
   so on small screens they carry more air than the clamp-based stations. Match
   the clamp rhythm so vertical spacing reads consistently down the page (#13). */
#contacts.section, #continue.section { padding-block: var(--section-y); }

/* Contact channels — compact home version of the contacts-page list component. */
.contacts-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap: var(--sp-1); }
.contacts-list__item{ display:flex; align-items:flex-start; gap: var(--sp-4); padding: var(--sp-3) var(--sp-4); border-radius: var(--radius); transition: background-color 0.1s; }
.contacts-list__item:hover{ background: var(--accent-wash); }
.contacts-list__icon{ flex:none; width:22px; height:22px; color: var(--accent); margin-top:2px; }
.contacts-list__content{ display:flex; flex-direction:column; gap:2px; }
.contacts-list__label{ font-size: var(--fs-300); color: var(--muted); font-weight: 600; }
.contacts-list__link{ font-size: var(--fs-400); font-weight:600; color: var(--ink); text-decoration:none; letter-spacing: var(--ls-tight); } /* UI link — must not read as an H3 */
.contacts-list__link:hover{ color: var(--accent); text-decoration:underline; }
/* .contact__success relocated to styles.css */

/* ---------- Station 10b: continue on phone (QR codes in one row) ---------- */
/* spread the four codes edge-to-edge across the full-width container: the first
   code sits flush to the left content edge, the last flush to the right, with the
   gap distributed evenly between them — no left/right margins around the group. */
.qr-row{ list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; justify-content:space-between; gap: var(--sp-5); }
.qr-cell{ display:flex; flex-direction:column; align-items:center; gap:10px; }
.qr-cell img{ width:132px; height:132px; border:1px solid var(--line); border-radius: var(--radius); background:#fff; padding:8px; }
.qr-label{ font-size: var(--fs-300); color: var(--muted); }
.qr-hint{ margin-top: var(--sp-5); }
@media (min-width: 860px){
  /* On desktop the four codes sit in one row — equal size, never wrapping — spread
     flush from the left content edge to the right via space-between (inherited).
     A fixed cell width (instead of label-driven width) keeps the squares uniform;
     the clamp sets a minimum gutter while any extra width is shared evenly. */
  .qr-row{ flex-wrap: nowrap; gap: clamp(var(--sp-5), 3.2vw, var(--sp-7)); }
  .qr-cell{ flex: 0 0 auto; width: 168px; }
  .qr-cell img{ width:168px; height:168px; padding:10px; }
}

/* Shared lead-form field rules (.field--check, .field__err, [aria-invalid]) moved to
   styles.css so they apply on every page, not just the home page that loads home.css. */
.lead__note { margin: 0; }

/* ---------- Station 12: FAQ ----------
   The FAQ accordion now lives in styles.css so it is identical on every page
   (home.css used to box it, which diverged from the deep pages). Nothing here. */


/* ===== Node cross-section schematics ===== */
.node{ margin:0; }
.node__svg{ width:100%; max-width:260px; height:auto; display:block; background:var(--surface); border:1px solid var(--line); border-radius:6px; }
.nd-alu{ fill:var(--aluminium); stroke:var(--ink); stroke-width:.8; }
.nd-glass{ fill:var(--accent-wash); stroke:var(--accent); stroke-width:1.2; }
.nd-roller{ fill:var(--surface); stroke:var(--ink); stroke-width:1; }
.nd-brush{ stroke:var(--muted); stroke-width:1; }
.nd-base{ stroke:var(--ink); stroke-width:2; }
.nd-wall{ fill:var(--grid); stroke:var(--aluminium); stroke-width:.8; }
.nd-seal{ fill:var(--accent); }
.nd-flash{ fill:none; stroke:var(--aluminium); stroke-width:1.5; }
.nd-drain{ fill:none; stroke:var(--accent); stroke-width:1; }
.nd-dim{ stroke:var(--accent); stroke-width:.8; }
.nd-dimtext{ fill:var(--muted); font:600 7px/1 var(--font); font-variant-numeric:tabular-nums; letter-spacing: var(--ls-tight); }
.node__cap{ margin-top:.5rem; color:var(--muted); font-size: var(--fs-300); line-height: var(--lh-body); }

/* .proc-flow__term и выравнивание .proc-flow--dated перенесены в styles.css
   (универсальный лист): блок процесса теперь единый на всех страницах. */
.proc__facts { margin: var(--sp-4) 0 0; max-width: 62rem; }

/* Табы Coupe/7T: элементы существуют только на телефоне */
.sys-tab-radio, .sys-tabs { display: none; }

/* ==========================================================================
   МОБИЛЬНАЯ ПОДАЧА ГЛАВНОЙ (спека 2026-07-18-mobile-homepage-design.md)
   Только до 759px; десктоп не трогаем.
   ========================================================================== */
@media (max-width: 759px) {
  /* --- QR-блок «Продолжить с телефона»: посетитель уже на телефоне --- */
  #continue { display: none; }

  /* --- Докрутка плотности (Task 9, шаг 2): единый ритм секций главной ---
     .section/.systems/.process/.scenarios/.lumon/.press/.faq/.value несут
     padding: var(--section-y) 0 (или padding-block) в styles.css/home.css;
     #contacts.section, #continue.section переопределяют .section точечно
     (home.css) — специфичнее плоского .section, поэтому нужно перекрыть и их. */
  .section, .systems, .process, .scenarios, .lumon, .press, .faq, .value,
  #contacts.section, #continue.section {
    padding-block: var(--sp-5);
  }
  .section-head { margin-bottom: var(--sp-5); }

  /* --- Конструктор: плотность вместо десктопного воздуха --- */
  /* строки-вопросы */
  .va-row { padding: var(--sp-4) 0; gap: var(--sp-2) var(--sp-5); }
  .va-key { padding-top: 0; }
  /* текстовые варианты: плотнее, но тап-цель не ниже 40px */
  .va-opts { gap: var(--sp-1) var(--sp-4); }
  .va-opt { min-height: 40px; }
  /* иконки формы проёма: 5 плиток в 2 ряда без воздуха */
  .va-shapes { gap: var(--sp-3) var(--sp-4); }
  .va-shape > span { width: 58px; gap: 4px; }
  .va-shape__ico { height: 32px; }
  .va-shape__ico svg { width: 44px; }
  /* слайдеры: плотнее по вертикали; сами контролы не уменьшаем (палец) */
  .va-dims { gap: var(--sp-4); }
  /* эскиз-превью: не выше 160px (докрутка плотности, Task 9) */
  .cstr-photo { aspect-ratio: auto; height: 160px; }
  /* таблица «Что войдёт в заявку»: чуть плотнее ряды */
  .cstr-recap th, .cstr-recap td { padding-block: 3px; }
  /* поля лида (имя/телефон) чуть плотнее */
  .cstr-lead { gap: var(--sp-2); }
  /* рамка панели заявки — на шаг плотнее (sp-4 → sp-3); .cstr-send «вылезает»
     к краю панели через отрицательный margin, равный этому же padding —
     меняем оба значения в паре, иначе блок съедет за скруглённый угол */
  .cstr-panel-inner { padding: var(--sp-3); }
  .cstr-send { margin: 0 calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)); padding: var(--sp-3); }
  .cstr-result { padding-top: var(--sp-3); }

  /* --- #product: переключатель объектов одной строкой с прокруткой вбок --- */
  /* нижняя лента чипов (nowrap) не должна распирать колонку грида:
     сбрасываем автоматический min-width элементов .vh-grid */
  #product .vh-grid > * { min-width: 0; }
  #product .vh-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: var(--sp-2);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  #product .vh-chips::-webkit-scrollbar { display: none; }
  #product .vh-chips .vh-chip { flex: 0 0 auto; }
  /* побеждаем специфичность #product .vh-comp-row (display: grid) */
  #product .vh-comp-row.m-scroll { display: flex; }
  /* карточки компонентов чуть уже, чтобы был виден край следующей */
  .vh-comp-row.m-scroll > * { flex-basis: 62%; }
  /* выгоды продукта: плотнее строки (было sp-4 — .vh-truth ещё не сжат ниже 900px) */
  #product .vh-truth { padding-block: var(--sp-3); }
  /* полоса объектов под фото: чуть ближе к выгодам */
  #product .vh-objbar { margin-top: var(--sp-4); }

  /* --- Табы Coupe / 7T: видна одна система --- */
  .sys-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); margin-bottom: var(--sp-5); }
  .sys-tab {
    display: flex; align-items: center; justify-content: center;
    min-height: 44px; border: 1px solid var(--line); border-radius: var(--radius-sm);
    font-weight: 600; cursor: pointer;
  }
  .sys-tab-radio { display: block; position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; overflow: hidden; clip: rect(0 0 0 0); }
  /* выбранный таб: полная акцентная рамка (конвенция v3 highlight) */
  #sys-tab-coupe:checked ~ .container .sys-tab[for="sys-tab-coupe"],
  #sys-tab-7t:checked ~ .container .sys-tab[for="sys-tab-7t"] {
    box-shadow: inset 0 0 0 1px var(--accent); border-color: var(--accent); color: var(--accent);
  }
  #sys-tab-coupe:checked ~ .container .sys-diagram--7t { display: none; }
  #sys-tab-7t:checked ~ .container .sys-diagram--coupe { display: none; }
  .sys-diagrams { grid-template-columns: 1fr; }
  .sys-tab-radio:focus-visible ~ .container .sys-tabs { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* --- карусели карточек: ширины под чтение ленты --- */
  /* .press-list определён выше с display: grid, поэтому plain .m-scroll теряет в каскаде */
  .press-list.m-scroll { display: flex; gap: var(--sp-4); }
  .press-list.m-scroll > .press-list__item { flex-basis: 85%; }
  .aged-grid.m-scroll > .aged-exhibit { flex-basis: 88%; }
}
