/* ============================================================
   Lofted Homes — Hero (slide 1 of 3)
   Reproduces the 430 x 932 Figma frame. Everything is sized in
   "design pixels": --u is one Figma pixel. Below 430px viewport
   --u shrinks with the screen (uniform scale); at >=430px it is
   locked to 1px, so the frame renders at the exact Figma sizes.

   --u is a LENGTH (px). We only ever multiply it by plain numbers
   -> works in every engine. (No length/length division, which is
   CSS Values 4 and missing in older Chromium builds.)
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  background: #0d0d0d;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* in-page anchors clear the fixed header */
.frame {
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

body {
  font-family: "Montserrat", -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  color: #d9d9d9;
  background: #0d0d0d;
}

img {
  display: block;
  max-width: 100%;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

a {
  color: inherit;
  text-decoration: none;
}

/* ---------- Hero shell ---------- */
.hero {
  position: relative;
  width: 100%;
  /* Site column cap on large monitors; sides fall back to the dark page
     background. hero-2 / hero-3 photos are only ~1084px wide, so
     background-size:cover upscales them a little here — a faint scrim
     (see .hero__slide::after) hides the softness. Keep this value in
     sync everywhere it appears (.site-header, .frame, .collection, --pc-w). */
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
  background: #0d0d0d;
  /* horizontal drags are the slider's; keep vertical gestures for the page */
  touch-action: pan-y;
}

.hero__slides {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
}

.hero__slide {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /* mobile-sized WebP by default; swapped for the larger one at >=600px */
  background-image: var(--img-m);
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.8s ease;
}

.hero__slide.is-active {
  opacity: 1;
}

/* Per-slide darkening, matching Figma: each slide sets its own --scrim
   inline next to the --img vars (Hero 1 = 0.4, Hero 2/3 = none). */
.hero__slide::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #000;
  opacity: var(--scrim, 0);
}

/* ---------- Phone-width frame ---------- */
.hero__frame {
  --u: min(1px, calc(100vw / 430)); /* one design pixel */

  position: relative;
  z-index: 2;
  width: min(100vw, 430px);
  min-height: 100vh;
  min-height: 100svh;
  margin-left: auto;
  margin-right: auto;
}

/* ============================================================
   Sticky global header
   One fixed header for the whole page. It is transparent with
   light content over dark sections (data-theme="dark") and a
   white bar with dark content over light sections
   (data-theme="light"); script.js flips the attribute as
   sections scroll under it. Colours cross-fade.
   ============================================================ */
.site-header {
  --u: min(1px, calc(100vw / 430));

  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* float over the site column only, not the full viewport — the white
     bar then lines up with the 1280 sections, dark page shows at the sides */
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  z-index: 100;
  color: #d9d9d9;
  transform: translateY(0);
  transition: transform 0.35s ease, color 0.3s ease,
    background-color 0.3s ease, box-shadow 0.3s ease,
    -webkit-backdrop-filter 0.3s ease, backdrop-filter 0.3s ease;
}

/* hidden while the hero is on screen — the hero has its own header
   (.hero__header) that scrolls away; this one slides in afterwards */
.site-header.is-hidden {
  transform: translateY(-100%);
  pointer-events: none;
}

/* phone/tablet: the sticky header is fully transparent on every section —
   no panel, no hairline, just the (dark) burger. The white bar + blur is
   desktop-only (see the 1024 block). */
.site-header[data-theme="light"],
.site-header[data-theme="photo-light"] {
  color: #0d0d0d;
}

.site-header__inner {
  width: min(100vw, 430px);
  margin-left: auto;
  margin-right: auto;
  display: flex;
  align-items: flex-start;
  /* phone/tablet: no logo, menu sits at the right (see .site-header__logo) */
  justify-content: flex-end;
  padding: calc(14 * var(--u)) calc(18 * var(--u)) calc(12 * var(--u));
}

/* phone/tablet: hide the logo, keep only the menu. Restored on desktop. */
.site-header__logo {
  display: none;
  line-height: 0;
}

/* phone/tablet: logo identical to the hero header — same file
   dimensions (logo-dark is a recolour of logo-white), same width.
   Desktop keeps the compact size (see the 1024 block). */
.site-header__logo-img {
  width: calc(143 * var(--u));
  height: auto;
}

/* show one logo per theme */
.site-header[data-theme="dark"] .site-header__logo-img--on-light,
.site-header[data-theme="light"] .site-header__logo-img--on-dark,
.site-header[data-theme="photo-light"] .site-header__logo-img--on-dark {
  display: none;
}

.site-header__menu {
  display: block;
  flex: none;
  width: calc(32 * var(--u));
  height: calc(32 * var(--u));
  color: inherit;
}

.site-header__menu svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- Hero's own header (scrolls with the hero) ---------- */
.hero__header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: calc(28 * var(--u)) calc(18 * var(--u)) 0 0;
}

.hero__logo-img {
  width: calc(143 * var(--u));
  height: auto;
}

/* slide 1 has a dark scrim -> white logo; slides 2-3 are bright -> dark logo.
   script.js sets .hero[data-logo] from the active slide. */
.hero:not([data-logo="dark"]) .hero__logo-img--dark,
.hero[data-logo="dark"] .hero__logo-img--light {
  display: none;
}

.hero__menu {
  display: block;
  flex: none;
  width: calc(32 * var(--u));
  height: calc(32 * var(--u));
  margin-top: calc(35 * var(--u));
}

.hero__menu img {
  width: 100%;
  height: 100%;
}

/* ---------- Bottom cluster ----------
   title + tag + controls + CTA are grouped and anchored to the
   bottom of the viewport. The CTA sits a fixed gap below the
   controls (like Figma) instead of floating at the screen bottom
   on tall screens. */
.hero__bottom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}

.hero__content {
  padding-left: calc(23 * var(--u));
  padding-right: calc(23 * var(--u));
}

.hero__title {
  font-weight: 500;
  font-size: calc(24 * var(--u));
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

.hero__tag {
  display: flex;
  align-items: center;
  gap: calc(13 * var(--u));
  margin-top: calc(33 * var(--u));
}

.hero__tag-icon {
  flex: none;
  width: calc(32 * var(--u));
  height: calc(32 * var(--u));
}

.hero__tag span {
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- Controls ---------- */
.hero__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: calc(18 * var(--u));
}

.hero__pagination {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.hero__page {
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
}

.hero__page--total {
  opacity: 0.7;
}

.hero__dots {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

/* Progress dots — the three dashes from the mock, now interactive.
   Base line is the dim track; .hero__dot-fill scales in over the
   autoplay interval (driven from script.js via the Web Animations API). */
.hero__dot {
  position: relative;
  display: block;
  width: calc(20 * var(--u));
  height: 1px;
  padding: 0;
  background: rgba(217, 217, 217, 0.32);
  -webkit-tap-highlight-color: transparent;
}

.hero__dot::before {
  /* invisible, comfortably sized hit target around the 1px line */
  content: "";
  position: absolute;
  left: calc(-7 * var(--u));
  right: calc(-7 * var(--u));
  top: 50%;
  height: calc(32 * var(--u));
  min-height: 24px;
  transform: translateY(-50%);
}

.hero__dot-fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /* red so the running autoplay timer catches the eye */
  background: #e63329;
  transform: scaleX(0);
  transform-origin: left center;
}

.hero__dot.is-active .hero__dot-fill {
  transform: scaleX(1);
}

.hero__dot[disabled] {
  opacity: 0.22;
  pointer-events: none;
  cursor: default;
}

.hero__dot:focus-visible {
  outline: 1px solid #d9d9d9;
  outline-offset: calc(6 * var(--u));
}

.hero__lang {
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
}

.hero__lang span {
  font-weight: 400;
  font-size: calc(20 * var(--u));
  letter-spacing: 0.12em;
}

.hero__lang img {
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
  transition: transform 0.18s ease;
}

/* Language dropdown wrapper. The button (.hero__lang) keeps every rule
   from the mock; this only anchors the little menu that drops from it.
   Menu opens upward — the control sits near the bottom of the hero. */
.hero__langbox {
  position: relative;
}

.hero__langbox[data-open] .hero__lang img {
  transform: rotate(180deg);
}

.hero__langbox-menu {
  position: absolute;
  right: 0;
  bottom: calc(100% + 10 * var(--u));
  z-index: 5;
  display: none;
  min-width: calc(150 * var(--u));
  margin: 0;
  padding: calc(6 * var(--u)) 0;
  list-style: none;
  background: rgba(13, 13, 13, 0.92);
  border: 1px solid rgba(217, 217, 217, 0.28);
  backdrop-filter: blur(4px);
}

.hero__langbox[data-open] .hero__langbox-menu {
  display: block;
}

.hero__langbox-menu a {
  display: block;
  padding: calc(9 * var(--u)) calc(16 * var(--u));
  color: #d9d9d9;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.08em;
  text-decoration: none;
}

.hero__langbox-menu a:hover,
.hero__langbox-menu a:focus-visible {
  background: rgba(217, 217, 217, 0.14);
}

.hero__langbox-menu a[aria-current] {
  opacity: 0.55;
  pointer-events: none;
}

/* ---------- Bottom CTA bar ---------- */
.hero__cta {
  display: flex;
  align-items: center;
  /* Hidden on every breakpoint for now (per request). visibility:hidden,
     not display:none — the box keeps its space so the title, pagination
     and lang above it stay on the exact same pixels. The markup + all
     sizing rules are kept so it can be switched back on later. */
  visibility: hidden;
  margin-top: calc(42 * var(--u));
  min-height: calc(41 * var(--u));
  padding: calc(8 * var(--u)) calc(65 * var(--u));
  background: rgba(0, 0, 0, 0.25);
  font-weight: 600;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ============================================================
   TABLET  (>= 600px)
   No tablet mock in Figma. The phone column is dropped: the hero
   goes full-bleed, header spreads to the edges, and the type /
   spacing scale up fluidly (independent of --u, which stays a
   phone-only unit).
   ============================================================ */
@media (min-width: 600px) {
  /* Cap the hero on tall tablet screens so the whole composition
     (incl. the CTA bar) stays within one screenful instead of being
     stretched across a 1500px+ viewport. */
  .hero,
  .hero__frame {
    min-height: 0;
    height: min(100vh, 1000px);
  }

  .hero__frame {
    width: 100%;
  }

  .hero__slide {
    background-image: var(--img);
  }

  .site-header__inner {
    width: 100%;
    max-width: 1280px;
    padding: clamp(16px, 2.4vw, 32px) clamp(28px, 4.5vw, 60px) clamp(10px, 1.4vw, 16px);
  }

  /* tablet: logo matches the hero header */
  .site-header__logo-img {
    width: clamp(150px, 17vw, 220px);
  }

  .site-header__menu {
    width: clamp(34px, 4vw, 48px);
    height: clamp(34px, 4vw, 48px);
    margin-top: clamp(0px, 0.6vw, 8px);
  }

  .hero__header {
    padding: clamp(28px, 4.5vw, 60px) clamp(28px, 4.5vw, 60px) 0;
  }

  .hero__logo-img {
    width: clamp(150px, 17vw, 220px);
  }

  .hero__menu {
    width: clamp(34px, 4vw, 48px);
    height: clamp(34px, 4vw, 48px);
    margin-top: clamp(0px, 0.6vw, 8px);
  }

  .hero__content {
    padding-left: clamp(28px, 5vw, 76px);
    padding-right: clamp(28px, 5vw, 76px);
    max-width: 1100px;
  }

  .hero__title {
    font-size: clamp(30px, 5vw, 54px);
    line-height: 1.18;
  }

  .hero__tag {
    gap: clamp(12px, 1.4vw, 18px);
    margin-top: clamp(28px, 4vw, 52px);
  }

  .hero__tag-icon {
    width: clamp(32px, 3.6vw, 44px);
    height: clamp(32px, 3.6vw, 44px);
  }

  .hero__tag span,
  .hero__page,
  .hero__cta {
    font-size: clamp(14px, 1.7vw, 19px);
  }

  .hero__controls {
    margin-top: clamp(20px, 3vw, 40px);
  }

  .hero__pagination,
  .hero__dots {
    gap: clamp(12px, 1.6vw, 22px);
  }

  .hero__dot {
    width: clamp(20px, 2.6vw, 38px);
  }

  .hero__dot::before {
    left: -8px;
    right: -8px;
    height: 34px;
  }

  .hero__dot:focus-visible {
    outline-offset: 6px;
  }

  .hero__lang span {
    font-size: clamp(18px, 2.2vw, 26px);
  }

  .hero__lang img {
    width: clamp(16px, 1.8vw, 22px);
    height: clamp(16px, 1.8vw, 22px);
  }

  .hero__cta {
    margin-top: clamp(26px, 3.2vw, 48px);
    min-height: clamp(44px, 5vw, 62px);
    padding-left: clamp(28px, 5vw, 76px);
    padding-right: clamp(28px, 5vw, 76px);
  }
}

/* ============================================================
   DESKTOP  (>= 1024px)
   No sticky header in the desktop design, so the logo + menu move
   up near the top edge. Type is ~20% smaller than the tablet scale.
   ============================================================ */
@media (min-width: 1024px) {
  /* Very faint scrim on the bright slides (2 & 3). The hero-2/hero-3
     photos are only ~1084px wide and get upscaled to the 1280 column,
     so a touch of darkening softens the visible imperfections.
     Slide 1 keeps its own 0.4 (set inline in the markup). */
  .hero__slide[data-slide="2"],
  .hero__slide[data-slide="3"] {
    --scrim: 0.1;
  }

  .site-header__inner {
    padding-top: clamp(8px, 0.9vw, 12px);
    padding-bottom: clamp(10px, 1vw, 14px);
    /* like phone/tablet: no logo, burger on the right */
    justify-content: flex-end;
  }

  /* desktop sticky header = same as phone/tablet: fully transparent,
     no logo, no bottom hairline — just the burger. */

  .site-header__menu {
    width: clamp(26px, 2.2vw, 32px);
    height: clamp(26px, 2.2vw, 32px);
    margin-top: 0;
  }

  .hero__header {
    padding-top: clamp(12px, 1.4vw, 20px);
  }

  .hero__logo {
    display: block;
    line-height: 0;
  }

  .hero__logo-img {
    width: clamp(104px, 9vw, 132px);
  }

  /* desktop: hero logo is white on every slide (overrides the
     per-slide light/dark swap that still runs on phone/tablet) */
  .hero .hero__logo .hero__logo-img--light {
    display: block;
  }
  .hero .hero__logo .hero__logo-img--dark {
    display: none;
  }

  .hero__menu {
    width: clamp(26px, 2.2vw, 32px);
    height: clamp(26px, 2.2vw, 32px);
    margin-top: 0;
  }

  /* content edges line up with the header:
     title / "01—03" left  == logo left
     "EN" right            == menu right  */
  .hero__content {
    max-width: none;
    padding-left: clamp(28px, 4.5vw, 60px);
    padding-right: clamp(28px, 4.5vw, 60px);
  }

  .hero__title {
    font-size: clamp(24px, 2.7vw, 36px);
  }

  .hero__tag {
    margin-top: clamp(20px, 2.4vw, 32px);
  }

  .hero__tag-icon {
    width: clamp(24px, 2.1vw, 30px);
    height: clamp(24px, 2.1vw, 30px);
  }

  .hero__tag span,
  .hero__page,
  .hero__cta {
    font-size: clamp(11px, 0.95vw, 13px);
  }

  .hero__dot {
    width: clamp(16px, 1.7vw, 25px);
    /* desktop only: white track so the dashes stand out on the
       un-dimmed photos. The progress fill stays red (see .hero__dot-fill). */
    background: rgba(255, 255, 255, 0.85);
  }

  .hero__lang span {
    font-size: clamp(14px, 1.25vw, 17px);
  }

  .hero__lang img {
    width: clamp(13px, 1.15vw, 16px);
    height: clamp(13px, 1.15vw, 16px);
  }

  .hero__cta {
    margin-top: clamp(20px, 2.2vw, 34px);
    min-height: clamp(36px, 2.9vw, 44px);
  }
}

/* ============================================================
   "The Frame" — first light section below the hero
   (Figma node 218:41). White ground, dark type, centred wordmark.
   ============================================================ */
.frame {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  /* same cap as the hero: content stops at 1280, dark page shows at the sides */
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  /* phone/tablet: off-white, not pure white (restored to #fff on desktop) */
  background: #f9f9f9;
  color: #0d0d0d;
  /* full screen, but capped so tall tablets/monitors (e.g. 1152x1536)
     don't stretch the divider into a huge empty band */
  min-height: min(100vh, 1150px);
  min-height: min(100svh, 1150px);
  padding: calc(150 * var(--u)) calc(30 * var(--u)) calc(80 * var(--u));
}

.frame__title {
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.28;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.frame__wordmark {
  display: flex;
  justify-content: center;
  margin-top: calc(150 * var(--u));
}

.frame__wordmark img {
  width: calc(360 * var(--u));
  height: auto;
}

@media (min-width: 600px) {
  .frame {
    padding: clamp(150px, 20vw, 240px) clamp(28px, 5vw, 76px) clamp(80px, 10vw, 140px);
  }

  .frame__title {
    font-size: clamp(18px, 2.6vw, 30px);
  }

  .frame__wordmark {
    margin-top: clamp(90px, 13vw, 180px);
  }

  .frame__wordmark img {
    width: min(60vw, 560px);
  }
}

@media (min-width: 1024px) {
  .frame {
    background: #fff;
  }

  .frame__title {
    font-size: clamp(15px, 1.5vw, 21px);
  }

  .frame__wordmark img {
    width: min(42vw, 520px);
  }
}

/* ============================================================
   "The Frame" collection browser (Figma node 1:2, "Seven 1")
   Full-bleed model photo + bottom scrim + overlay chrome.
   Models 2-3 will be extra .collection__slide layers.
   ============================================================ */
.collection {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  /* same cap as the hero: photo + content stop at 1280 */
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  overflow: hidden;
  isolation: isolate;
  background: #0d0d0d;
  min-height: 100vh;
  min-height: 100svh;
  /* phone: pin the content frame to the bottom so the pagination is
     always visible and the top block clips instead (see .collection__frame) */
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.collection__slides {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  overflow: hidden;
}

/* horizontal track: JS sets translateX(-index * 100%) */
.collection__track {
  display: flex;
  width: 100%;
  height: 100%;
  transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.collection__slide {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  /* --img-m phone · --img tablet (portrait) · --img-pc desktop (wide) */
  background-image: var(--img-m);
  background-repeat: no-repeat;
  /* phone: place the photo exactly like the Figma "Firefly" node so the
     house stays locked in one spot while swiping between slides */
  background-size: calc(var(--bg-w) * var(--u)) calc(var(--bg-h) * var(--u));
  background-position: calc(var(--bg-x) * var(--u)) calc(var(--bg-y) * var(--u));
}

/* bottom-up gradient so the white chrome stays readable */
.collection__scrim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 55%;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.55));
}

/* Phone: exact repro of the 430x932 Figma frame (node 1:2).
   The frame keeps the design's 430:932 ratio no matter the device
   height, so the composition (headline over sky, house below, chrome
   at the bottom) always matches Figma. It is bottom-aligned; on short
   screens the top edge clips rather than the layout compressing. */
.collection__frame {
  position: relative;
  z-index: 2;
  flex: none;
  width: min(100vw, 430px);
  height: calc(min(100vw, 430px) * 2.1674);
  min-height: 100vh;
  min-height: 100svh;
  /* phone/tablet: slightly off-white text (matches the softer palette);
     restored to pure white on desktop */
  color: #f9f9f9;
}

/* eyebrow + headline sit on the bright sky -> dark ink */
.collection__eyebrow {
  position: absolute;
  left: calc(30 * var(--u));
  top: calc(175 * var(--u));
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.25;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #0d0d0d;
}

.collection__headline {
  position: absolute;
  left: calc(28 * var(--u));
  top: calc(268 * var(--u));
  font-weight: 400;
  font-size: calc(26 * var(--u));
  line-height: 1.36;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #0d0d0d;
}

/* Mirage headline has a shorter phone-only variant (EN site). Phone shows
   .collection__headline-m; tablet 600-1023 shows the full .collection__headline-d;
   desktop >=1024 hides .collection__headline entirely (see @media below). */
.collection__headline-d {
  display: none;
}

@media (min-width: 600px) {
  .collection__headline-m {
    display: none;
  }
  .collection__headline-d {
    display: inline;
  }
}

/* ---------- bottom cluster (anchored to the frame bottom) ---------- */
/* box == Figma node 160:373 (213x120); the artwork carries its own
   padding, so object-fit keeps the visible wordmark the Figma size */
.collection__wordmark {
  position: absolute;
  left: calc(202 * var(--u));
  bottom: calc(196 * var(--u));
  width: calc(213 * var(--u));
  height: calc(120 * var(--u));
  object-fit: cover;
  object-position: center;
}

.collection__model {
  position: absolute;
  left: calc(28 * var(--u));
  bottom: calc(148 * var(--u));
}

.collection__model-kicker,
.collection__model-name {
  display: block;
  text-transform: uppercase;
}

.collection__model-kicker {
  font-weight: 500;
  font-size: calc(20 * var(--u));
  letter-spacing: 0.09em;
}

.collection__model-name {
  margin-top: calc(7 * var(--u));
  font-weight: 400;
  font-size: calc(26 * var(--u));
  letter-spacing: 0.12em;
}

.collection__nav {
  position: absolute;
  left: calc(30 * var(--u));
  right: calc(44 * var(--u));
  bottom: calc(62 * var(--u));
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.collection__pagination {
  display: flex;
  align-items: center;
  gap: calc(7 * var(--u));
}

.collection__page {
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
}

.collection__dots {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.collection__dot {
  position: relative;
  display: block;
  width: calc(20 * var(--u));
  height: 1px;
  padding: 0;
  /* track colour (phone/tablet). Desktop swaps to a brighter white
     in the >=1024 block. The red on the active dash is the fill below. */
  background: #d9d9d9;
  -webkit-tap-highlight-color: transparent;
}

/* red fill on the active dash. The collection slider is manual (no
   autoplay — that lives on the hero only), so this is just held full
   for the active dot by the .is-active rule below; no JS animation. */
.collection__dot-fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #e63329;
  transform: scaleX(0);
  transform-origin: left center;
}

.collection__dot.is-active .collection__dot-fill {
  transform: scaleX(1);
}

.collection__dot::before {
  content: "";
  position: absolute;
  left: calc(-7 * var(--u));
  right: calc(-7 * var(--u));
  top: 50%;
  height: calc(30 * var(--u));
  min-height: 24px;
  transform: translateY(-50%);
}

.collection__dot[disabled] {
  pointer-events: none;
  cursor: default;
}

.collection__lang {
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
}

.collection__lang span {
  font-weight: 300;
  font-size: calc(20 * var(--u));
  letter-spacing: 0.12em;
}

.collection__lang img {
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
}

@media (min-width: 600px) {
  .collection {
    display: block;
    min-height: min(100vh, 1000px);
    height: min(100vh, 1000px);
  }

  .collection__slide {
    background-image: var(--img);
    background-size: cover;
    background-position: center;
  }

  .collection__frame {
    width: 100%;
    height: min(100vh, 1000px);
    /* drop the phone `min-height: 100vh` — the section is capped at
       min(100vh, 1000px), and a taller frame would push the bottom
       chrome (model name + pagination) below the clipped edge on
       tall screens (iPad portrait, 1152x1536, …) */
    min-height: 0;
  }

  .collection__eyebrow {
    left: clamp(28px, 6vw, 90px);
    top: clamp(120px, 17vw, 200px);
    font-size: clamp(14px, 1.7vw, 20px);
  }

  .collection__headline {
    left: clamp(28px, 6vw, 90px);
    top: clamp(190px, 28vw, 330px);
    font-size: clamp(30px, 5vw, 58px);
  }

  .collection__wordmark {
    left: auto;
    right: clamp(28px, 6vw, 90px);
    bottom: clamp(150px, 22vw, 250px);
    width: clamp(200px, 30vw, 380px);
    height: clamp(113px, 16.9vw, 214px);
  }

  .collection__model {
    left: clamp(28px, 6vw, 90px);
    bottom: clamp(110px, 16vw, 190px);
  }

  .collection__model-kicker {
    font-size: clamp(18px, 2.2vw, 26px);
  }

  .collection__model-name {
    font-size: clamp(28px, 4vw, 48px);
  }

  .collection__nav {
    left: clamp(28px, 6vw, 90px);
    right: clamp(28px, 6vw, 90px);
    /* raised ~5 mm vs the phone-frame position — the pagination sat too
       low on tablet across all 7 Frame collections */
    bottom: clamp(58px, 6vw, 82px);
  }

  .collection__page,
  .collection__lang span {
    font-size: clamp(14px, 1.7vw, 19px);
  }

  .collection__dot {
    width: clamp(20px, 2.6vw, 38px);
  }
}

@media (min-width: 1024px) {
  /* desktop photos (native ~1600px, AI-processed — never upscale them).
     Shown at a FIXED 1280 scale (still downscaled from 1600 -> crisp), cropped
     top/bottom to the section. --bg-y-pc = roof-apex height as a fraction of
     the image, so the apex lands at the same screen Y on every slide.
     NB: --pc-w is a constant 1280, not min(100vw, 1280px) — on viewports
     narrower than ~1260px the square render, scaled to the viewport width,
     wasn't tall enough to cover the 1000px frame once shifted for the
     roofline, leaving a black strip at the bottom. The whole calibration
     below assumes the 1280 scale. */
  .collection__slide {
    --pc-w: 1280px;
    background-image: var(--img-pc);
    background-size: var(--pc-w);
    background-position: center
      calc(245px - var(--bg-y-pc, 0.36) * var(--pc-w));
  }

  /* Every slide uses the same 1280 column scale (no per-slide zoom). Vertical
     placement is the only knob: --bg-y-pc (inline) shifts the crop so the
     roofline lands where we want. It is capped at ~0.41 — beyond that the
     photo's bottom edge would lift above the frame bottom and leave a dark
     strip (245 - 0.41*1280 = -280; frame is at most 1000 tall, 1280 - 280 = 1000). */

  .collection__frame {
    max-width: 1280px;
    color: #fff;
  }

  .collection__eyebrow {
    top: clamp(90px, 9vw, 120px);
    font-size: clamp(16px, 1.5vw, 20px);
  }

  /* PC version: drop the slogan and the FRAME COLLECTION wordmark */
  .collection__headline,
  .collection__wordmark {
    display: none;
  }

  .collection__model {
    bottom: clamp(90px, 10vw, 140px);
  }

  .collection__model-kicker {
    font-size: clamp(15px, 1.4vw, 20px);
  }

  .collection__model-name {
    font-size: clamp(24px, 2.6vw, 38px);
  }

  .collection__nav {
    /* lifted ~1.5 cm off the frame bottom (was clamp(32,3.5vw,52)) so the
       pagination doesn't sit on the very edge */
    bottom: clamp(48px, 5vw, 72px);
  }

  .collection__page,
  .collection__lang span {
    font-size: clamp(11px, 0.95vw, 14px);
  }

  /* PC: pagination dashes match the hero slider — brighter white track,
     same width. The red active fill comes from .collection__dot-fill. */
  .collection__dot {
    width: clamp(16px, 1.7vw, 25px);
    background: rgba(255, 255, 255, 0.85);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__slide,
  .collection__track,
  .finishes__track {
    transition: none;
  }
}

/* ============================================================
   "Оздоблення фасадів" — Exterior Finishes slider
   (Figma node 232:231 "Exterior Finishes 1 Glass"). White ground,
   dark type. Each slide = eyebrow-less heading + body copy + a
   photo band. Persistent chrome: section label + pagination + next.
   Manual only (no autoplay) — matches the arrow-driven Figma design.
   ============================================================ */
.finishes {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

/* section label, top-right (Figma 232:266) — persistent across slides */
.finishes__eyebrow {
  position: absolute;
  z-index: 2;
  top: calc(124 * var(--u));
  right: calc(20 * var(--u));
  font-weight: 500;
  font-size: calc(16 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* phone: exact 430 x 932 frame proportions (like .collection__frame) so
   the composition matches Figma on any device height */
.finishes__viewport {
  position: relative;
  width: min(100vw, 430px);
  margin: 0 auto;
  height: calc(min(100vw, 430px) * 2.1674);
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

.finishes__track {
  display: flex;
  height: 100%;
  transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.finishes__slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  /* clip each slide's photo to its own frame — the photo box is wider
     than the slide (Figma node sits at x -58, w 563) and would otherwise
     bleed onto the neighbouring slide's edge */
  overflow: hidden;
}

.finishes__heading {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(163 * var(--u));
  font-weight: 600;
  font-size: calc(28 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

.finishes__text {
  position: absolute;
  left: calc(20 * var(--u));
  /* --txt-y (inline per slide) lets a 2-line heading push the copy down */
  top: calc(var(--txt-y, 220) * var(--u));
  width: calc(366 * var(--u));
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.32;
  letter-spacing: 0.12em;
}

.finishes__text p + p {
  margin-top: 1em;
}

/* a paragraph hidden on phones (tight text zone), shown from tablet up (EN site) */
.finishes__text p.is-wide-only {
  display: none;
}

@media (min-width: 600px) {
  .finishes__text p.is-wide-only {
    display: block;
  }
}

/* EN slides whose heading is a long phrase and wraps (Thermally Modified
   Timber, Wood-Burning Stove or Fireplace). Phone: sane wrap width (2 lines),
   copy pushed down per-slide via --txt-y. Tablet 600-1023: the wrapped
   heading is taller than the default text top -> constrain it to ~2 lines
   and drop the body copy clear of it. Desktop >=1024 uses the grid layout. */
.finishes__slide--wrap .finishes__heading {
  white-space: normal;
  width: calc(300 * var(--u));
}

/* #finishes slide 2 heading has a short phone-only variant ("Thermo Wood");
   tablet/desktop keep the full "Thermally Modified Timber". */
.finishes__heading-d {
  display: none;
}

@media (min-width: 600px) {
  .finishes__heading-m {
    display: none;
  }
  .finishes__heading-d {
    display: inline;
  }
}

@media (min-width: 600px) and (max-width: 1023.98px) {
  .finishes__slide--wrap .finishes__heading {
    width: min(56vw, 420px);
  }

  .finishes__slide--wrap .finishes__text {
    top: clamp(300px, 42vw, 384px);
  }
}

/* photo band — box = Figma node per slide, passed as --ph-x/y/w/h inline
   (slide 1 "Glass" 232:232 = -58 / 403 / 563 / 408). */
.finishes__photo {
  position: absolute;
  left: calc(var(--ph-x, -58) * var(--u));
  top: calc(var(--ph-y, 403) * var(--u));
  width: calc(var(--ph-w, 563) * var(--u));
  height: calc(var(--ph-h, 408) * var(--u));
  background-image: var(--img-m);
  background-size: cover;
  background-position: center;
}

/* ---- persistent nav (pagination + next arrow), pinned to frame bottom ---- */
.finishes__nav {
  position: absolute;
  z-index: 2;
  left: calc(30 * var(--u));
  bottom: calc(58 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.finishes__pagination {
  display: flex;
  align-items: center;
  gap: calc(7 * var(--u));
}

.finishes__page {
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
}

.finishes__dots {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.finishes__dot {
  position: relative;
  display: block;
  width: calc(20 * var(--u));
  height: 1px;
  padding: 0;
  background: rgba(13, 13, 13, 0.28);
  -webkit-tap-highlight-color: transparent;
}

.finishes__dot.is-active {
  background: #0d0d0d;
}

.finishes__dot::before {
  content: "";
  position: absolute;
  left: calc(-7 * var(--u));
  right: calc(-7 * var(--u));
  top: 50%;
  height: calc(30 * var(--u));
  min-height: 24px;
  transform: translateY(-50%);
}

.finishes__dot[disabled] {
  pointer-events: none;
}

.finishes__next {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  color: #0d0d0d;
}

.finishes__next img,
.finishes__next svg {
  width: 100%;
  height: 100%;
}

.finishes__next[disabled] {
  opacity: 0.35;
  pointer-events: none;
}

/* language toggle — mirrors .collection__lang, bottom-right */
.finishes__lang {
  position: absolute;
  z-index: 2;
  right: calc(44 * var(--u));
  bottom: calc(58 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
}

.finishes__lang span {
  font-weight: 300;
  font-size: calc(20 * var(--u));
  letter-spacing: 0.12em;
}

.finishes__lang img {
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
}

/* ---------------- tablet ---------------- */
@media (min-width: 600px) {
  .finishes__viewport {
    width: 100%;
    height: min(100vh, 1150px);
    min-height: 0;
  }

  .finishes__eyebrow {
    top: clamp(96px, 12vw, 150px);
    right: clamp(28px, 6vw, 90px);
    font-size: clamp(14px, 1.7vw, 18px);
  }

  .finishes__heading {
    left: clamp(28px, 6vw, 90px);
    top: clamp(150px, 20vw, 240px);
    font-size: clamp(30px, 5vw, 52px);
  }

  .finishes__text {
    left: clamp(28px, 6vw, 90px);
    top: clamp(230px, 30vw, 360px);
    width: min(58vw, 520px);
    font-size: clamp(15px, 1.8vw, 19px);
  }

  .finishes__photo {
    left: auto;
    right: 0;
    top: auto;
    bottom: clamp(120px, 16vw, 180px);
    width: min(64vw, 760px);
    height: clamp(300px, 42vw, 520px);
  }

  .finishes__nav {
    left: clamp(28px, 6vw, 90px);
    bottom: clamp(40px, 5vw, 64px);
  }

  .finishes__page,
  .finishes__lang span {
    font-size: clamp(14px, 1.7vw, 19px);
  }

  .finishes__dot {
    width: clamp(20px, 2.6vw, 34px);
  }

  .finishes__next {
    width: clamp(24px, 2.6vw, 34px);
    height: clamp(24px, 2.6vw, 34px);
  }

  .finishes__lang {
    right: clamp(28px, 6vw, 90px);
    bottom: clamp(40px, 5vw, 64px);
  }
}

/* ---------------- desktop (invented layout) ----------------
   Two columns: text left, full-height photo right. */
@media (min-width: 1024px) {
  .finishes {
    background: #fff;
  }

  .finishes__viewport {
    height: min(100vh, 1150px);
  }

  .finishes__slide {
    display: grid;
    grid-template-columns: minmax(0, 49%) minmax(0, 51%);
  }

  .finishes__eyebrow {
    top: clamp(88px, 9vw, 118px);
    left: clamp(40px, 5vw, 76px);
    right: auto;
    font-size: clamp(14px, 1vw, 16px);
    opacity: 0.7;
  }

  .finishes__heading {
    position: static;
    align-self: end;
    /* left edge aligns with the body copy; small right margin gives the
       heading room so a ~10-char word (СКЛОПАКЕТИ) stays on one line while
       a longer one (ТЕРМОДЕРЕВИНА) still wraps — without shrinking the font */
    margin: 0 clamp(12px, 1.5vw, 20px) clamp(18px, 2vw, 28px)
      clamp(40px, 5vw, 76px);
    grid-column: 1;
    grid-row: 1;
    white-space: normal;
    overflow-wrap: anywhere;
    hyphens: none;
    font-size: clamp(30px, 3.4vw, 52px);
  }

  .finishes__text {
    position: static;
    align-self: start;
    margin: 0 clamp(40px, 5vw, 76px);
    grid-column: 1;
    grid-row: 2;
    width: auto;
    max-width: 46ch;
    font-size: clamp(15px, 1.1vw, 18px);
    line-height: 1.5;
  }

  .finishes__photo {
    position: static;
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 100%;
    height: 100%;
    background-image: var(--img);
  }

  .finishes__nav {
    left: clamp(40px, 5vw, 76px);
    bottom: clamp(56px, 6vw, 84px);
  }

  .finishes__page,
  .finishes__lang span {
    font-size: clamp(11px, 0.95vw, 14px);
  }

  .finishes__dot {
    width: clamp(16px, 1.7vw, 25px);
  }

  .finishes__next {
    width: clamp(22px, 1.8vw, 26px);
    height: clamp(22px, 1.8vw, 26px);
  }

  .finishes__lang {
    right: clamp(40px, 5vw, 76px);
    bottom: clamp(56px, 6vw, 84px);
  }
}

/* ============================================================
   Spec feature — heading + short copy + one full-bleed photo
   (Figma node 232:367 "The Frame" / КАРКАС). White ground, dark
   type. Same phone method as .finishes but no slider chrome.
   Desktop mirrors .finishes: text left, full-height photo right.
   ============================================================ */
.spec {
  --u: min(1px, calc(100vw / 430));
  /* phone only: nudge the whole composition (heading + copy + photo)
     down by ~5 mm. Tablet/desktop set their own top/bottom below. */
  --spec-shift: 34;

  position: relative;
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

.spec__viewport {
  position: relative;
  width: min(100vw, 430px);
  margin: 0 auto;
  height: calc(min(100vw, 430px) * 2.1674);
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

.spec__heading {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc((136 + var(--spec-shift)) * var(--u));
  font-weight: 500;
  font-size: calc(28 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

.spec__text {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc((195 + var(--spec-shift)) * var(--u));
  width: calc(395 * var(--u));
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.32;
  letter-spacing: 0.12em;
}

/* full-width photo band (Figma 232:368: 430 x 613 at x 0 / y 329) */
.spec__photo {
  position: absolute;
  left: 0;
  top: calc((329 + var(--spec-shift)) * var(--u));
  width: 100%;
  height: calc(613 * var(--u));
  background-image: var(--img-m);
  background-size: cover;
  background-position: center;
}

/* tablet + desktop — two columns: heading + copy left, full-height photo
   right (mirrors .finishes desktop). No slider, so the grid starts at 600
   already. Tablet keeps the #f9f9f9 ground; desktop goes pure #fff below. */
@media (min-width: 600px) {
  .spec__viewport {
    display: grid;
    grid-template-columns: minmax(0, 49%) minmax(0, 51%);
    width: 100%;
    height: min(100vh, 1150px);
    min-height: 0;
  }

  .spec__heading {
    position: static;
    align-self: end;
    grid-column: 1;
    grid-row: 1;
    margin: 0 clamp(12px, 1.5vw, 20px) clamp(18px, 2vw, 28px)
      clamp(28px, 5vw, 76px);
    white-space: normal;
    overflow-wrap: anywhere;
    font-size: clamp(28px, 3.4vw, 52px);
  }

  .spec__text {
    position: static;
    align-self: start;
    grid-column: 1;
    grid-row: 2;
    margin: 0 clamp(28px, 5vw, 76px);
    width: auto;
    max-width: 46ch;
    font-size: clamp(15px, 1.8vw, 18px);
    line-height: 1.5;
  }

  .spec__photo {
    position: static;
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 100%;
    height: 100%;
    background-image: var(--img);
  }
}

/* desktop — pure white ground, tighter copy, roomier left gutter */
@media (min-width: 1024px) {
  .spec {
    background: #fff;
  }

  .spec__heading {
    margin-left: clamp(40px, 5vw, 76px);
    font-size: clamp(30px, 3.4vw, 52px);
  }

  .spec__text {
    margin-left: clamp(40px, 5vw, 76px);
    margin-right: clamp(40px, 5vw, 76px);
    font-size: clamp(15px, 1.1vw, 18px);
  }
}

/* ============================================================
   .plan  —  "Індивідуальне планування" (#plan)
   Figma node 244:602 "individual plan". White ground, dark type.
   Spec-style feature, no slider: heading (413:2, 2 lines) + 3
   short paragraphs + one floor-plan line drawing. The drawing is
   a diagram, so it is CONTAINED (never cropped) on every size.
   Desktop mirrors .finishes/.spec: heading + text left, plan right.
   ============================================================ */
.plan {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

.plan__viewport {
  position: relative;
  width: min(100vw, 430px);
  margin: 0 auto;
  height: calc(min(100vw, 430px) * 2.1674);
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
}

/* heading — Figma 413:2: x 20 / y 138, Montserrat SemiBold 28, 2 lines */
.plan__heading {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(138 * var(--u));
  font-weight: 600;
  font-size: calc(28 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* text block — Figma 244:632: x 20 / y 240 / w 394, Montserrat Medium */
.plan__text {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(240 * var(--u));
  width: calc(394 * var(--u));
  font-weight: 500;
  font-size: calc(16 * var(--u));
  line-height: 1.32;
  letter-spacing: 0.12em;
}

.plan__text p + p {
  margin-top: 1em;
}

/* floor-plan drawing — Figma 244:636: x 20 / y 510 / w 387 / h 285 */
.plan__figure {
  position: absolute;
  left: calc(20 * var(--u));
  top: calc(510 * var(--u));
  width: calc(387 * var(--u));
  height: calc(285 * var(--u));
  background-image: var(--img-m);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

@media (min-width: 600px) {
  .plan__viewport {
    width: 100%;
    height: min(100vh, 1150px);
    min-height: 0;
  }

  .plan__heading {
    left: clamp(28px, 6vw, 90px);
    top: clamp(96px, 13vw, 170px);
    font-size: clamp(30px, 4.4vw, 48px);
  }

  .plan__text {
    left: clamp(28px, 6vw, 90px);
    top: clamp(210px, 30vw, 360px);
    width: min(58vw, 560px);
    font-size: clamp(15px, 1.8vw, 19px);
    line-height: 1.5;
  }

  .plan__figure {
    left: 50%;
    top: auto;
    bottom: clamp(56px, 9vw, 120px);
    transform: translateX(-50%);
    width: min(78vw, 760px);
    height: min(46vh, 420px);
    background-image: var(--img);
  }
}

/* desktop — two columns: heading + text left, contained plan right
   (mirrors .finishes / .spec desktop) */
@media (min-width: 1024px) {
  .plan {
    background: #fff;
  }

  .plan__viewport {
    display: grid;
    grid-template-columns: minmax(0, 46%) minmax(0, 54%);
    height: min(100vh, 1150px);
  }

  .plan__heading {
    position: static;
    align-self: end;
    grid-column: 1;
    grid-row: 1;
    margin: 0 clamp(12px, 1.5vw, 20px) clamp(18px, 2vw, 28px)
      clamp(40px, 5vw, 76px);
    white-space: normal;
    overflow-wrap: anywhere;
    font-size: clamp(30px, 3.4vw, 52px);
  }

  .plan__text {
    position: static;
    align-self: start;
    grid-column: 1;
    grid-row: 2;
    margin: 0 clamp(40px, 5vw, 76px);
    width: auto;
    max-width: 44ch;
    font-size: clamp(15px, 1.1vw, 18px);
    line-height: 1.6;
  }

  .plan__figure {
    position: static;
    transform: none;
    grid-column: 2;
    grid-row: 1 / span 2;
    width: 100%;
    height: 100%;
    padding: clamp(24px, 4vw, 72px) clamp(24px, 5vw, 88px);
    background-origin: content-box;
  }
}

/* ============================================================
   .faq  —  "Часті питання" plain accordion (#faq)
   No Figma node — built by eye from a phone mock. White ground,
   dark type. initFaq() (script.js) toggles .is-open per item and
   drives .faq__a max-height (independent toggles, all closed on
   load). Answer copy from vigocabins.com.
   ============================================================ */
.faq {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  /* Full-height screen like every other section (#plan, #karkas, .finishes).
     Only a handful of questions, so most of the screen is empty below the
     list — that's intentional headroom for more Q&A later.
     (The .faq__lang EN toggle is commented out in the HTML — the language
     switch now lives only on the hero; its CSS below is kept for restore.) */
  min-height: 100vh;
  min-height: 100svh;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
  /* PHONE: heading high (padding-top 60u), first question right under it
     (heading margin 24u). Normal flow — NO negative margins, the section
     sits flush after #plan with no overlap. Media queries below reset this. */
  padding: calc(60 * var(--u)) calc(26 * var(--u)) calc(150 * var(--u));
}

.faq__heading {
  margin: 0 0 calc(24 * var(--u));
  font-weight: 600;
  font-size: calc(32 * var(--u));
  letter-spacing: 0.02em;
  line-height: 1.15;
  text-transform: uppercase;
}

.faq__item {
  border-bottom: 1px solid rgba(13, 13, 13, 0.22);
}

.faq__item h3 {
  margin: 0;
  font: inherit;
}

.faq__q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: calc(14 * var(--u));
  padding: calc(22 * var(--u)) 0;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: inherit;
  font-family: inherit;
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1.4;
  letter-spacing: 0.005em;
}

/* + / − glyph — two 1.5px bars; vertical one collapses when open */
.faq__icon {
  position: relative;
  flex: 0 0 auto;
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
  margin-top: calc(1 * var(--u));
}

.faq__icon::before,
.faq__icon::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: currentColor;
}

.faq__icon::before {
  width: 100%;
  height: 1.5px;
  transform: translate(-50%, -50%);
}

.faq__icon::after {
  width: 1.5px;
  height: 100%;
  transform: translate(-50%, -50%);
  transition: transform 0.3s ease;
}

.faq__item.is-open .faq__icon::after {
  transform: translate(-50%, -50%) scaleY(0);
}

.faq__a {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.4s ease;
}

.faq__a p {
  margin: 0;
  padding: 0 calc(24 * var(--u)) calc(26 * var(--u)) 0;
  color: #6a6a6a;
  font-weight: 500;
  font-size: calc(15 * var(--u));
  line-height: 1.62;
  letter-spacing: 0.02em;
}

/* language toggle — same corner as .finishes__lang / .collection__lang:
   absolute, bottom-right of the (full-height) section */
.faq__lang {
  position: absolute;
  z-index: 2;
  right: calc(44 * var(--u));
  bottom: calc(58 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
}

.faq__lang span {
  font-weight: 300;
  font-size: calc(20 * var(--u));
  letter-spacing: 0.12em;
}

.faq__lang img {
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
}

@media (min-width: 600px) {
  .faq {
    min-height: min(100vh, 1150px);
    padding: clamp(96px, 13vw, 140px) clamp(40px, 7vw, 90px)
      clamp(96px, 11vw, 130px);
  }

  .faq__inner {
    max-width: 720px;
    margin: 0 auto;
  }

  .faq__heading {
    margin-bottom: clamp(40px, 6vw, 64px);
    font-size: clamp(34px, 5vw, 46px);
  }

  .faq__q {
    gap: clamp(24px, 4vw, 48px);
    padding: clamp(20px, 3vw, 28px) 0;
    font-size: clamp(16px, 2vw, 19px);
    letter-spacing: 0.04em;
  }

  .faq__icon {
    width: clamp(22px, 3vw, 26px);
    height: clamp(22px, 3vw, 26px);
  }

  .faq__a p {
    padding: 0 clamp(8px, 6vw, 60px) clamp(24px, 3vw, 32px) 0;
    font-size: clamp(15px, 1.9vw, 18px);
  }

  .faq__lang {
    right: clamp(28px, 6vw, 90px);
    bottom: clamp(40px, 5vw, 64px);
  }

  .faq__lang span {
    font-size: clamp(15px, 1.7vw, 19px);
  }

  .faq__lang img {
    width: clamp(14px, 1.6vw, 18px);
    height: clamp(14px, 1.6vw, 18px);
  }
}

/* desktop — heading left, list right (mirrors the other sections) */
@media (min-width: 1024px) {
  .faq {
    background: #fff;
    padding: clamp(96px, 10vw, 150px) clamp(40px, 5vw, 76px)
      clamp(110px, 11vw, 160px);
  }

  .faq__inner {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 34%) minmax(0, 66%);
    gap: clamp(40px, 6vw, 110px);
    align-items: start;
  }

  .faq__heading {
    margin-bottom: 0;
    font-size: clamp(34px, 3.6vw, 54px);
    position: sticky;
    top: clamp(96px, 12vw, 140px);
  }

  .faq__q {
    padding: clamp(22px, 2vw, 30px) 0;
    font-size: clamp(16px, 1.25vw, 19px);
  }

  .faq__icon {
    width: clamp(20px, 1.8vw, 26px);
    height: clamp(20px, 1.8vw, 26px);
  }

  .faq__a p {
    padding: 0 clamp(20px, 4vw, 90px) clamp(22px, 2vw, 32px) 0;
    font-size: clamp(15px, 1.1vw, 17px);
  }

  .faq__lang {
    right: clamp(40px, 5vw, 76px);
    bottom: clamp(56px, 6vw, 84px);
  }
}

/* ============================================================
   .contact  —  "Виставкові будинки та зв'язок з нами" (#contact)
   Closing section, no Figma node — built by eye from a phone mock.
   White ground, dark type, full-height screen like #plan / #faq.
   Layout: heading top, a CONTAINED Europe line-art map in the
   middle (never cropped — it's a diagram), a collapsible location
   card at the bottom. initContact() (script.js) opens/closes the
   card; open on load. Desktop mirrors .plan/.finishes: card +
   heading left, full-height map right.
   ============================================================ */
.contact {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100svh;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

.contact__inner {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(64 * var(--u)) calc(26 * var(--u)) calc(40 * var(--u));
}

.contact__heading {
  margin: 0;
  font-weight: 600;
  font-size: calc(27 * var(--u));
  line-height: 1.25;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* big line-art map straight under the heading, bled to the section edges,
   its own aspect ratio (contained — it's a diagram, never cropped) */
.contact__map {
  flex: none;
  width: auto;
  margin: calc(24 * var(--u)) calc(-26 * var(--u)) 0;
  aspect-ratio: 1330 / 1024;
  background-image: var(--img-m);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

/* card sits at the bottom of the screen; spare space falls above it */
.contact__card {
  margin-top: auto;
  padding-top: calc(26 * var(--u));
  padding-bottom: calc(26 * var(--u));
  border-bottom: 1px solid rgba(13, 13, 13, 0.16);
}

.contact__place {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
  padding-bottom: calc(12 * var(--u));
}

.contact__place-pin {
  flex: none;
  width: calc(22 * var(--u));
  height: calc(22 * var(--u));
}

.contact__place-name {
  font-weight: 600;
  font-size: calc(19 * var(--u));
  letter-spacing: 0.01em;
}

.contact__toggle {
  margin-left: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
}

.contact__toggle img {
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
  transition: transform 0.3s ease;
}

.contact__toggle[aria-expanded="true"] img {
  transform: rotate(180deg);
}

.contact__details {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.4s ease;
}

.contact__details-inner {
  padding-top: calc(4 * var(--u));
}

.contact__addr,
.contact__coords,
.contact__phone {
  margin: 0 0 calc(9 * var(--u));
  font-weight: 500;
  font-size: calc(15 * var(--u));
  line-height: 1.5;
  letter-spacing: 0.02em;
}

.contact__phone {
  margin-bottom: calc(14 * var(--u));
}

.contact__phone a {
  color: inherit;
  text-decoration: none;
}

.contact__maplink {
  display: inline-flex;
  align-items: center;
  gap: calc(8 * var(--u));
  color: inherit;
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.02em;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.contact__maplink img {
  width: calc(15 * var(--u));
  height: calc(15 * var(--u));
}

/* ---------------- tablet ---------------- */
@media (min-width: 600px) {
  .contact {
    min-height: min(100vh, 1150px);
  }

  .contact__inner {
    max-width: 900px;
    margin: 0 auto;
    min-height: min(100vh, 1150px);
    padding: clamp(96px, 13vw, 140px) clamp(40px, 7vw, 90px)
      clamp(48px, 7vw, 84px);
  }

  .contact__heading {
    font-size: clamp(28px, 4vw, 44px);
    letter-spacing: 0.05em;
  }

  .contact__map {
    margin: clamp(28px, 4vw, 48px) 0 0;
  }

  .contact__place {
    gap: clamp(12px, 1.6vw, 18px);
    padding-bottom: clamp(12px, 1.6vw, 18px);
  }

  .contact__place-pin {
    width: clamp(24px, 2.4vw, 28px);
    height: clamp(24px, 2.4vw, 28px);
  }

  .contact__place-name {
    font-size: clamp(20px, 2.4vw, 26px);
  }

  .contact__toggle {
    width: clamp(30px, 3vw, 36px);
    height: clamp(30px, 3vw, 36px);
    /* from tablet up the card is a narrow island — keep the caret next to
       the place name instead of flinging it to the far edge of the row */
    margin-left: clamp(10px, 1.4vw, 20px);
  }

  .contact__toggle img {
    width: clamp(20px, 2vw, 24px);
    height: clamp(20px, 2vw, 24px);
  }

  .contact__addr,
  .contact__coords,
  .contact__phone,
  .contact__maplink {
    font-size: clamp(15px, 1.8vw, 18px);
  }
}

/* ---------------- desktop (invented — mirrors .plan / .finishes) ----------------
   Two columns: heading + card left, full-height map right. */
@media (min-width: 1024px) {
  .contact {
    background: #fff;
    min-height: min(100vh, 1150px);
  }

  .contact__inner {
    display: grid;
    grid-template-columns: minmax(0, 38%) minmax(0, 62%);
    grid-template-rows: auto 1fr;
    column-gap: clamp(40px, 6vw, 110px);
    row-gap: clamp(28px, 4vw, 56px);
    max-width: none;
    min-height: min(100vh, 1150px);
    padding: clamp(80px, 9vw, 140px) clamp(40px, 5vw, 76px)
      clamp(64px, 7vw, 110px);
    align-items: start;
  }

  .contact__heading {
    grid-column: 1;
    grid-row: 1;
    font-size: clamp(30px, 3vw, 46px);
  }

  .contact__map {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin: 0;
    aspect-ratio: auto;
    height: 100%;
    background-image: var(--img);
  }

  .contact__card {
    grid-column: 1;
    grid-row: 2;
    align-self: center;
    max-width: 40ch;
    padding-bottom: 0;
    border-bottom: 0;
  }
}

/* ============================================================
   .request  —  "Залиште заявку" (#request)
   Closing lead form, no Figma node — built by eye from a phone
   mock. White ground, dark type, full-height screen. Heading +
   subtitle, a bordered card with the form, then the language
   toggle (bottom-right, like every other section — the mock had
   it on the left, which was wrong) and the social links.
   initRequest() (script.js) handles submit — no backend yet,
   it just shows a thank-you state.
   ============================================================ */
.request {
  --u: min(1px, calc(100vw / 430));

  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100svh;
  background: #f9f9f9;
  color: #0d0d0d;
  overflow: hidden;
  isolation: isolate;
  scroll-margin-top: clamp(72px, 12vw, 100px);
}

.request__inner {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  /* PHONE: this screen carries the most content (form + footer), so it is
     kept compact and everything is sized to fit ONE screen — scrolled to
     the bottom the heading still clears the top by ~2cm (padding-top 88u).
     The footer (socials + EN on one line) is pinned to the bottom. */
  padding: calc(88 * var(--u)) calc(26 * var(--u)) calc(30 * var(--u));
}

.request__heading {
  margin: 0;
  font-weight: 600;
  font-size: calc(27 * var(--u));
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.request__sub {
  margin: calc(10 * var(--u)) 0 0;
  max-width: calc(320 * var(--u));
  font-weight: 500;
  font-size: calc(15 * var(--u));
  line-height: 1.45;
  letter-spacing: 0.02em;
}

.request__card {
  margin-top: calc(18 * var(--u));
  padding: calc(20 * var(--u)) calc(20 * var(--u)) calc(22 * var(--u));
  border: 1px solid rgba(13, 13, 13, 0.18);
}

.request__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(50 * var(--u));
  height: calc(50 * var(--u));
  margin-bottom: calc(14 * var(--u));
  border: 1px solid rgba(13, 13, 13, 0.28);
  border-radius: 50%;
}

.request__badge img {
  width: calc(20 * var(--u));
  height: calc(20 * var(--u));
}

.request__fields {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--u));
}

.request__input {
  width: 100%;
  padding: calc(15 * var(--u)) calc(18 * var(--u));
  background: none;
  border: 1px solid rgba(13, 13, 13, 0.22);
  border-radius: 0;
  color: #0d0d0d;
  font-family: inherit;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.02em;
  -webkit-appearance: none;
  appearance: none;
}

.request__input::placeholder {
  color: #8a8a8a;
  opacity: 1;
}

.request__input:focus {
  outline: none;
  border-color: #0d0d0d;
}

.request__input--area {
  min-height: calc(92 * var(--u));
  line-height: 1.45;
  resize: vertical;
}

.request__submit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(14 * var(--u));
  width: 100%;
  margin-top: calc(12 * var(--u));
  padding: calc(16 * var(--u)) calc(22 * var(--u));
  background: #8f8f8f;
  border: 0;
  cursor: pointer;
  color: #fff;
  font-family: inherit;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.03em;
  transition: background 0.2s ease;
}

.request__submit:hover,
.request__submit:focus-visible {
  background: #0d0d0d;
  outline: none;
}

.request__submit img {
  width: calc(22 * var(--u));
  height: calc(22 * var(--u));
}

.request__done,
.request__error {
  margin: calc(14 * var(--u)) 0 0;
  font-weight: 500;
  font-size: calc(14 * var(--u));
  line-height: 1.5;
  letter-spacing: 0.02em;
}

.request__error {
  color: #b03636;
}

.request__submit:disabled {
  opacity: 0.6;
  cursor: default;
}

/* honeypot — off-screen, never shown to real users */
.request__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.request__done[hidden],
.request__error[hidden],
.request__fields[hidden],
.request__submit[hidden] {
  display: none;
}

/* footer — socials centered, EN pinned right on the SAME line;
   the whole row sits at the bottom of the screen */
.request__foot {
  position: relative;
  margin-top: auto;
  padding-top: calc(26 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
}

.request__social {
  display: flex;
  gap: calc(30 * var(--u));
  margin: 0;
  padding: 0;
  list-style: none;
}

.request__social a {
  display: block;
  color: #0d0d0d;
}

.request__social img {
  display: block;
  width: calc(25 * var(--u));
  height: calc(25 * var(--u));
}

/* EN — right edge, vertically centred on the social row (its box spans the
   row area below the foot's padding-top). Right side, like every other
   section; the mock had it on the left, which was wrong. */
.request__lang {
  position: absolute;
  right: 0;
  top: calc(26 * var(--u));
  bottom: 0;
  display: flex;
  align-items: center;
  gap: calc(9 * var(--u));
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
}

.request__lang span {
  font-weight: 300;
  font-size: calc(19 * var(--u));
  letter-spacing: 0.12em;
}

.request__lang img {
  width: calc(17 * var(--u));
  height: calc(17 * var(--u));
}

/* ---------------- tablet ---------------- */
@media (min-width: 600px) {
  .request {
    min-height: min(100vh, 1150px);
  }

  .request__inner {
    min-height: min(100vh, 1150px);
    padding: clamp(96px, 13vw, 140px) clamp(40px, 7vw, 90px)
      clamp(48px, 7vw, 84px);
  }

  .request__heading {
    font-size: clamp(28px, 4vw, 44px);
  }

  .request__sub {
    max-width: none;
    font-size: clamp(16px, 1.9vw, 19px);
  }

  .request__card {
    max-width: 620px;
    margin-top: clamp(28px, 4vw, 48px);
    padding: clamp(32px, 4vw, 48px) clamp(28px, 3.5vw, 44px)
      clamp(34px, 4vw, 48px);
  }

  .request__badge {
    width: clamp(60px, 6vw, 72px);
    height: clamp(60px, 6vw, 72px);
    margin-bottom: clamp(22px, 2.6vw, 32px);
  }

  .request__badge img {
    width: clamp(22px, 2.2vw, 26px);
    height: clamp(22px, 2.2vw, 26px);
  }

  .request__fields {
    gap: clamp(14px, 1.6vw, 18px);
  }

  .request__input {
    padding: clamp(18px, 2vw, 22px) clamp(18px, 2vw, 22px);
    font-size: clamp(15px, 1.6vw, 17px);
  }

  .request__input--area {
    min-height: clamp(140px, 16vw, 180px);
  }

  .request__submit {
    padding: clamp(20px, 2.2vw, 24px) clamp(22px, 2.4vw, 28px);
    font-size: clamp(15px, 1.6vw, 17px);
  }

  .request__lang {
    top: clamp(28px, 3.5vw, 44px);
  }

  .request__lang span {
    font-size: clamp(15px, 1.7vw, 19px);
  }

  .request__lang img {
    width: clamp(14px, 1.6vw, 18px);
    height: clamp(14px, 1.6vw, 18px);
  }

  .request__foot {
    max-width: 620px;
    padding-top: clamp(28px, 3.5vw, 44px);
  }

  .request__social {
    gap: clamp(26px, 3vw, 36px);
  }

  .request__social img {
    width: clamp(24px, 2.6vw, 28px);
    height: clamp(24px, 2.6vw, 28px);
  }
}

/* ---------------- desktop (invented — mirrors .plan / .contact) ----------------
   Two columns: heading + subtitle + footer (socials, EN) left, the form card
   right. Everything sized to fit ONE screen. White ground. */
@media (min-width: 1024px) {
  .request {
    background: #fff;
    min-height: min(100vh, 1150px);
  }

  .request__inner {
    display: grid;
    grid-template-columns: minmax(0, 40%) minmax(0, 60%);
    grid-template-rows: auto auto 1fr;
    column-gap: clamp(40px, 6vw, 100px);
    min-height: min(100vh, 1150px);
    padding: clamp(52px, 6vw, 92px) clamp(40px, 5vw, 76px)
      clamp(36px, 4vw, 64px);
  }

  .request__heading {
    grid-column: 1;
    grid-row: 1;
    align-self: start;
  }

  .request__sub {
    grid-column: 1;
    grid-row: 2;
    max-width: 34ch;
  }

  .request__card {
    grid-column: 2;
    grid-row: 1 / span 3;
    align-self: center;
    width: 100%;
    max-width: 620px;
    margin-top: 0;
    padding: clamp(24px, 2.6vw, 34px) clamp(24px, 2.4vw, 34px)
      clamp(24px, 2.6vw, 32px);
  }

  .request__badge {
    width: clamp(48px, 3.6vw, 58px);
    height: clamp(48px, 3.6vw, 58px);
    margin-bottom: clamp(14px, 1.6vw, 20px);
  }

  .request__fields {
    gap: clamp(10px, 1.1vw, 14px);
  }

  .request__input {
    padding: clamp(13px, 1.3vw, 16px) clamp(16px, 1.6vw, 20px);
    font-size: clamp(14px, 1vw, 16px);
  }

  .request__input--area {
    min-height: clamp(84px, 8vw, 112px);
  }

  .request__submit {
    margin-top: clamp(12px, 1.4vw, 16px);
    padding: clamp(15px, 1.6vw, 19px) clamp(20px, 2vw, 24px);
    font-size: clamp(14px, 1vw, 16px);
  }

  .request__foot {
    grid-column: 1;
    grid-row: 3;
    align-self: end;
    max-width: none;
    margin-top: 0;
    padding-top: clamp(32px, 4vw, 56px);
    justify-content: flex-start;
  }

  /* keep EN aligned with the social row (foot padding-top) */
  .request__lang {
    top: clamp(32px, 4vw, 56px);
  }
}

/* ============================================================
   Uniform desktop section-heading size — #finishes through #request.
   One size on every section from "Оздоблення фасадів" down, small
   enough that no heading wraps a word (white-space: nowrap enforces
   it; the intentional <br> line breaks in #plan / #options / #contact
   are kept). Per request — same size everywhere, none bigger/smaller.
   ============================================================ */
@media (min-width: 1024px) {
  .finishes__heading,
  .spec__heading,
  .plan__heading,
  .faq__heading,
  .contact__heading,
  .request__heading {
    font-size: clamp(23px, 2vw, 30px);
    line-height: 1.16;
    white-space: nowrap;
    overflow-wrap: normal;
    word-break: normal;
  }
}

/* ============================================================
   .nav  —  slide-in navigation panel (opened by either burger:
   .hero__menu on the hero, .site-header__menu in the sticky bar).
   Panel slides from the right over a dark scrim. Dark theme, like
   the hero. "Collections" is a collapsible group (closed on load);
   "Materials & Structure" and "Bespoke" start open. initNav() in
   script.js wires the toggles, the accordions, scroll-lock and the
   #finishes deep-links (data-slide).
   ============================================================ */
.nav {
  --u: min(1px, calc(100vw / 430));

  position: fixed;
  inset: 0;
  z-index: 200;
  visibility: hidden;
  transition: visibility 0s linear 0.4s;
}

.nav.is-open {
  visibility: visible;
  transition: visibility 0s;
}

html.nav-open,
body.nav-open {
  overflow: hidden;
}

.nav__scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.nav.is-open .nav__scrim {
  opacity: 1;
}

.nav__panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: min(92vw, 420px);
  padding: calc(26 * var(--u)) calc(30 * var(--u)) calc(48 * var(--u));
  background: #0d0d0d;
  color: #d9d9d9;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  transform: translateX(100%);
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.nav.is-open .nav__panel {
  transform: translateX(0);
}

.nav__close {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  margin-bottom: calc(14 * var(--u));
  width: calc(34 * var(--u));
  height: calc(34 * var(--u));
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.nav__close svg {
  width: calc(22 * var(--u));
  height: calc(22 * var(--u));
}

.nav__list {
  display: block;
}

.nav__link,
.nav__group-btn {
  display: flex;
  align-items: center;
  width: 100%;
  padding: calc(15 * var(--u)) 0;
  border: 0;
  border-bottom: 1px solid rgba(217, 217, 217, 0.16);
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 500;
  font-size: calc(15 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.nav__link:hover,
.nav__link:focus-visible,
.nav__group-btn:hover,
.nav__group-btn:focus-visible {
  color: #fff;
}

.nav__group-btn {
  justify-content: space-between;
  gap: calc(12 * var(--u));
}

.nav__group-icon {
  position: relative;
  flex: none;
  width: calc(13 * var(--u));
  height: calc(13 * var(--u));
}

.nav__group-icon::before,
.nav__group-icon::after {
  content: "";
  position: absolute;
  background: currentColor;
}

.nav__group-icon::before {
  left: 0;
  right: 0;
  top: 50%;
  height: 1.5px;
  transform: translateY(-50%);
}

.nav__group-icon::after {
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1.5px;
  transform: translateX(-50%);
  transition: opacity 0.2s ease;
}

.nav__group-btn[aria-expanded="true"] .nav__group-icon::after {
  opacity: 0;
}

.nav__group-panel {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.35s ease;
}

.nav__group-inner {
  padding: calc(6 * var(--u)) 0 calc(14 * var(--u));
}

.nav__sub {
  margin: calc(12 * var(--u)) 0 calc(4 * var(--u));
  color: #8a8a8a;
  font-size: calc(12 * var(--u));
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.nav__group-inner .nav__sub:first-child {
  margin-top: calc(4 * var(--u));
}

.nav__link--nested {
  padding: calc(10 * var(--u)) 0;
  border-bottom: 0;
  font-weight: 400;
  font-size: calc(14 * var(--u));
  letter-spacing: 0.1em;
  text-transform: none;
  color: #bdbdbd;
}

.nav__link--nested:hover,
.nav__link--nested:focus-visible {
  color: #fff;
}

@media (min-width: 1024px) {
  .nav__panel {
    padding: 30px 32px 56px;
  }
  .nav__close {
    width: 36px;
    height: 36px;
    margin-bottom: 18px;
  }
  .nav__close svg {
    width: 22px;
    height: 22px;
  }
  .nav__link,
  .nav__group-btn {
    padding: 16px 0;
    font-size: 14px;
    letter-spacing: 0.1em;
  }
  .nav__group-icon {
    width: 13px;
    height: 13px;
  }
  .nav__sub {
    margin: 14px 0 4px;
    font-size: 12px;
  }
  .nav__link--nested {
    padding: 11px 0;
    font-size: 14px;
  }
}

/* ============================================================
   "Базова комплектація" kit slider - /test/ sandbox, promoted to
   the live site 2026-09-05. Sits between #plan and #faq. 8 fixed
   slides (paged by dots/arrow, not scrolled), own --u scaled by
   BOTH width and height (min(1px, 100vw/430, 100svh/932)) so it
   reproduces the Figma frame proportionally on any device height -
   unlike other sections' width-only --u, scoped to .kit so no
   conflict. See test/PROGRESS.md and memory/test-kit-slider.md for
   the full build history (dozens of iterations, user-approved).
   ============================================================ */
.kit {
  --u: min(1px, calc(100vw / 430), calc(100svh / 932));

  max-width: 1280px;
  height: 100svh;
  margin: 0 auto;
  background: #f9f9f9;
  color: #0d0d0d;
  padding: 0 calc(20 * var(--u)) calc(10 * var(--u));
}

.kit__inner {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.kit__heading {
  flex: none;
  margin: calc(100 * var(--u)) 0 calc(21 * var(--u) + 5mm);
  font-weight: 600;
  font-size: max(12px, calc(28 * var(--u)));
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* viewport height is set by JS (script.js fitViewport) off SLIDE 1's
   content height, capped by whatever room is actually left - so the
   pagination lands on the SAME pixel on every one of the 8 slides
   regardless of how much text is above it on any given slide. A slide
   whose own content doesn't fit that fixed box scrolls inside itself
   rather than getting clipped. */
.kit__viewport {
  position: relative;
  flex: 0 1 auto;
  min-height: 0;
  overflow: hidden;
}

.kit__track {
  display: flex;
  height: 100%;
  transition: transform 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}

.kit__slide {
  flex: 0 0 100%;
  min-width: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(13, 13, 13, 0.25) transparent;
}

.kit__slide::-webkit-scrollbar {
  width: 4px;
}

.kit__slide::-webkit-scrollbar-track {
  background: transparent;
}

.kit__slide::-webkit-scrollbar-thumb {
  background: rgba(13, 13, 13, 0.25);
  border-radius: 2px;
}

/* ---------- blocks divided by hairlines ---------- */
.kit__block {
  padding-bottom: calc(8 * var(--u));
  margin-bottom: calc(9 * var(--u));
  border-bottom: 1px solid transparent; /* hairlines hidden per request; revert to #d9d9d9 to bring them back */
}

.kit__block-title {
  margin: 0 0 calc(11 * var(--u));
  font-weight: 500;
  font-size: max(12px, calc(20 * var(--u)));
  line-height: 1.22;
  letter-spacing: 0.12em;
}

/* nudges a specific block-title down 5mm on MOBILE only - applied
   one-off to a few headings on request, not the whole rule. */
@media (max-width: 599.98px) {
  .kit__block-title--down {
    margin-top: 5mm;
  }
}

.kit__body {
  padding-left: calc(20 * var(--u));
}

.kit__p {
  margin: 0 0 calc(12 * var(--u));
  font-weight: 400;
  font-size: max(12px, calc(14 * var(--u)));
  line-height: 1.3;
  letter-spacing: 0.08em;
}

.kit__p:last-child {
  margin-bottom: 0;
}

.kit__p--muted {
  color: #6a6a6a;
}

/* ---------- bulleted list ---------- */
.kit__list {
  list-style: none;
}

.kit__li {
  position: relative;
  margin: 0 0 calc(12 * var(--u));
  padding-left: calc(14 * var(--u));
  font-weight: 400;
  font-size: max(12px, calc(14 * var(--u)));
  line-height: 1.3;
  letter-spacing: 0.08em;
}

.kit__li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: calc(5 * var(--u));
  height: calc(5 * var(--u));
  border-radius: 50%;
  background: #0d0d0d;
}

.kit__li:last-child {
  margin-bottom: 0;
}

.kit__li strong {
  font-weight: 600;
}

/* nudges a specific list item down 5mm on MOBILE only */
@media (max-width: 599.98px) {
  .kit__li--down {
    margin-top: 5mm;
  }
}

/* slide 8 "Додаткова комплектація" - same list, but Figma specifies a
   larger 16px body size (with a bold lead-in per item) instead of the
   14px used everywhere else */
.kit__list--lead .kit__li {
  font-size: max(12px, calc(16 * var(--u)));
}

/* ---------- pagination (01 --- --- --- 08) + next arrow - shared by all
   slides, updated by script.js as the slider advances. Active page
   number is red (site's brand red, .hero__dot-fill). ---------- */
.kit__nav {
  flex: none;
  display: flex;
  align-items: center;
  gap: 5mm;
  margin-top: calc(20 * var(--u) + 10mm);
  padding-left: calc(30 * var(--u));
}

/* short screens (<=640px tall) - pagination raised vs the default.
   Two rules, not one: on a slide whose text still doesn't fit even at
   this size, fitViewport() (script.js) caps content to fill exactly
   whatever room .kit__nav's margin-top left available, so shrinking
   that margin alone just gives the clamped content more room and nav
   visually stays put. Shrinking .kit's own bottom padding moves the
   ceiling itself, which raises the nav in that case too. */
@media (max-height: 640px) {
  .kit {
    padding-bottom: calc(10 * var(--u) + 10mm);
  }

  .kit__nav {
    margin-top: calc(20 * var(--u));
  }
}

.kit__pagination {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
  font-weight: 500;
  font-size: max(12px, calc(15 * var(--u)));
  letter-spacing: 0.12em;
}

/* one button per page - same pattern as .hero__dot / .collection__dot:
   dim track line, red fill overlay that snaps in for the active one
   (no autoplay - that lives on the hero only). */
.kit__dots {
  display: flex;
  align-items: center;
  gap: calc(12 * var(--u));
}

.kit__dot {
  position: relative;
  display: block;
  width: calc(20 * var(--u));
  height: 1px;
  padding: 0;
  background: #0d0d0d;
  -webkit-tap-highlight-color: transparent;
}

.kit__dot::before {
  content: "";
  position: absolute;
  left: calc(-7 * var(--u));
  right: calc(-7 * var(--u));
  top: 50%;
  height: calc(32 * var(--u));
  min-height: 24px;
  transform: translateY(-50%);
}

.kit__dot-fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #e63329;
  transform: scaleX(0);
  transform-origin: left center;
}

.kit__dot.is-active .kit__dot-fill {
  transform: scaleX(1);
}

.kit__dot[disabled] {
  opacity: 0.22;
  pointer-events: none;
  cursor: default;
}

.kit__dot:focus-visible {
  outline: 1px solid #d9d9d9;
  outline-offset: calc(6 * var(--u));
}

.kit__next {
  flex: none;
  width: calc(24 * var(--u));
  height: calc(24 * var(--u));
  color: #0d0d0d;
}

/* ============================================================
   tablet - one centred column, heading on top
   ============================================================ */
@media (min-width: 600px) {
  .kit {
    padding: clamp(80px, 12vw, 130px) clamp(40px, 7vw, 80px)
      clamp(90px, 11vw, 130px);
  }

  .kit__inner {
    max-width: 760px;
    margin: 0 auto;
  }

  .kit__heading {
    margin: 0 0 clamp(40px, 6vw, 64px);
    font-size: clamp(30px, 4.6vw, 44px);
  }

  .kit__block {
    padding-bottom: clamp(24px, 3.4vw, 40px);
    margin-bottom: clamp(24px, 3.4vw, 40px);
  }

  .kit__block-title {
    margin-bottom: clamp(16px, 2vw, 22px);
    font-size: clamp(18px, 2.3vw, 22px);
  }

  .kit__body {
    padding-left: clamp(20px, 3vw, 36px);
  }

  .kit__p {
    margin-bottom: clamp(12px, 1.6vw, 16px);
    font-size: clamp(14px, 1.8vw, 16px);
    line-height: 1.6;
  }

  .kit__nav {
    gap: clamp(32px, 5vw, 56px);
    margin-top: clamp(28px, 4vw, 44px);
    padding-left: clamp(20px, 3vw, 36px);
  }

  .kit__pagination {
    gap: clamp(12px, 1.6vw, 16px);
    font-size: clamp(14px, 1.7vw, 16px);
  }

  .kit__dots {
    gap: clamp(12px, 1.6vw, 16px);
  }

  .kit__dot {
    width: clamp(20px, 2.6vw, 26px);
  }

  .kit__next {
    width: clamp(24px, 3vw, 30px);
    height: clamp(24px, 3vw, 30px);
  }
}

/* ============================================================
   desktop - two columns: sticky heading left, content right.
   Pure white ground, matching .finishes/.plan's own desktop pattern.
   ============================================================ */
@media (min-width: 1024px) {
  .kit {
    background: #fff;
    height: min(100vh, 880px);
    padding: clamp(24px, 2.4vw, 40px) clamp(48px, 6vw, 96px)
      clamp(18px, 1.8vw, 28px);
  }

  .kit__inner {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(220px, 300px) minmax(0, 720px);
    grid-template-rows: 1fr auto;
    justify-content: space-between;
    column-gap: clamp(48px, 7vw, 120px);
    height: 100%;
  }

  .kit__heading {
    grid-column: 1;
    grid-row: 1;
    align-self: start;
    position: static;
    margin: 0;
    font-size: clamp(23px, 2vw, 30px);
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1.16;
    white-space: nowrap;
  }

  .kit__viewport {
    grid-column: 2;
    grid-row: 1;
  }

  .kit__block {
    padding-bottom: clamp(10px, 1vw, 15px);
    margin-bottom: clamp(10px, 1vw, 15px);
    border-bottom: 1px solid transparent;
  }

  .kit__block-title {
    margin-bottom: clamp(7px, 0.7vw, 10px);
    font-size: clamp(18px, 1.4vw, 21px);
    line-height: 1.3;
  }

  .kit__body {
    padding-left: clamp(24px, 2.4vw, 40px);
  }

  .kit__p {
    margin-bottom: 6px;
    font-size: clamp(14px, 0.95vw, 16px);
    line-height: 1.4;
  }

  .kit__li {
    margin-bottom: 6px;
    padding-left: 18px;
    font-size: clamp(14px, 0.95vw, 16px);
    line-height: 1.4;
  }

  .kit__list--lead .kit__li {
    font-size: clamp(16px, 1.09vw, 18px);
  }

  .kit__li--down {
    margin-top: 5mm;
  }

  .kit__li::before {
    width: 6px;
    height: 6px;
  }

  .kit__nav {
    grid-column: 2;
    grid-row: 2;
    gap: clamp(36px, 4vw, 60px);
    margin-top: 0;
    padding-left: 0;
  }

  /* content sits at the BOTTOM of the viewport, not the top - so the
     gap before the pagination stays consistent on every slide
     regardless of how short its text is */
  .kit__slide {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }

  .kit__content {
    padding-bottom: 25px;
  }
}
