/* FLOW — test site stylesheet
   Palette + type per FLOW_VISUAL_GUIDELINES.pdf: black / white / copper (decorative accent only).
   Fonts: Milton Two (tagline/script), Montserrat (body/UI), Liberation Serif (editorial accents).
   2026-09-05: added --charcoal/--ivory/--ivory-muted for `section.alt` — see
   the comment above the :root block for why. Core black/white/copper palette
   unchanged everywhere else. */

@font-face{font-family:"Montserrat";src:url("../fonts/Montserrat-Regular.ttf") format("truetype");font-weight:400;font-display:swap;}
@font-face{font-family:"Montserrat";src:url("../fonts/Montserrat-Medium.ttf") format("truetype");font-weight:500;font-display:swap;}
@font-face{font-family:"Montserrat";src:url("../fonts/Montserrat-SemiBold.ttf") format("truetype");font-weight:600;font-display:swap;}
@font-face{font-family:"Montserrat";src:url("../fonts/Montserrat-Bold.ttf") format("truetype");font-weight:700;font-display:swap;}
@font-face{font-family:"Montserrat";src:url("../fonts/Montserrat-BoldItalic.ttf") format("truetype");font-weight:700;font-style:italic;font-display:swap;}
@font-face{font-family:"Milton Two";src:url("../fonts/Milton_Two_Bold.otf") format("opentype");font-weight:700;font-display:swap;}
@font-face{font-family:"Liberation Serif";src:url("../fonts/LiberationSerif-Regular.ttf") format("truetype");font-weight:400;font-display:swap;}
@font-face{font-family:"Liberation Serif";src:url("../fonts/LiberationSerif-Italic.ttf") format("truetype");font-weight:400;font-style:italic;font-display:swap;}

:root{
  --black:#0a0a0a;
  --white:#ffffff;
  --copper:#996632;
  --grey-line:#2a2a2a;
  --grey-line-light:#e4e4e4;
  --grey-text:#6b6b6b;
  --max:1240px;
  /* 2026-09-05: Marton wanted the off-white (#f6f5f3) gone — it read as a
     generic "premium neutral" default rather than anything specific to FLOW,
     and it broke the moody, cinematic tone the hero video / theatrical shots
     establish. `section.alt` (the off-white sections: homepage's product
     range, and the editorial/press blocks on the product + story pages) now
     runs on a warm near-black "charcoal" instead — one step up from the true
     `--black` used by the hero/cards/footer, so the two dark tones still
     read as distinct layers rather than one flat black field. --ivory and
     --ivory-muted replace plain black/grey body-text color on that new dark
     ground. */
  --charcoal:#171310;
  --ivory:#efe9df;
  --ivory-muted:#9c948a;
  --hairline-on-dark:rgba(239,233,223,.16);
  /* 2026-09-05: companion to --hairline-on-dark, for hairlines that sit on
     the true --black ground (`.range-top`) rather than the warm charcoal —
     see the --hairline-on-black comment above .range-fade for why this
     needed to exist separately. */
  --hairline-on-black:rgba(255,255,255,.28);
}
*{box-sizing:border-box;}
html{scroll-behavior:auto;}
body{
  margin:0;
  background:var(--white);
  color:var(--black);
  font-family:"Montserrat",Helvetica,Arial,sans-serif;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
.wrap{max-width:var(--max);margin:0 auto;padding:0 40px;}
.eyebrow{
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--grey-text);font-weight:600;
}
.eyebrow.copper{color:var(--copper);}
.serif{font-family:"Liberation Serif",Georgia,serif;font-weight:400;}
.script{font-family:"Milton Two",cursive;font-weight:700;}

/* ---------- NAV ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  padding:26px 46px;
  color:var(--white);
  transition:color .25s ease;
}
/* constant scrim band behind the nav so logo/links stay legible over any hero image,
   regardless of scroll position — replaces the earlier mix-blend-mode trick */
.nav::before{
  content:"";position:absolute;inset:0;height:150%;
  background:linear-gradient(180deg, rgba(0,0,0,.85) 0%, rgba(0,0,0,.6) 55%, rgba(0,0,0,0) 100%);
  z-index:-1;pointer-events:none;
  transition:background .25s ease;
}
.nav .logo{position:relative;z-index:2;display:inline-block;line-height:0;height:26.4px;aspect-ratio:1108/246;}
.nav .logo img{height:26.4px;width:auto;filter:invert(1);display:block;transition:filter .25s ease;}
.nav .links{display:flex;gap:36px;font-size:15.4px;letter-spacing:.07em;text-transform:uppercase;font-weight:600;}
.nav .links a{opacity:.92;}
.nav .links a:hover{opacity:1;text-decoration:underline;text-underline-offset:4px;}
.nav .links a.active{color:var(--copper);opacity:1;}
.nav .links a.active:hover{text-decoration:none;}

/* Hamburger toggle for the ≤900px nav, added 2026-09-27 — replaces the old
   layout where .links wrapped onto extra rows and the logo shrank to make
   room for it. That approach made the nav's own height variable, and since
   .nav is position:fixed, a taller nav covers more of the viewport at every
   scroll position, not just on load — it was overlapping in-page content
   like the configurator's "Configure Your FLOW" eyebrow on the product
   pages. A fixed-height bar plus a slide-down panel avoids that, and the
   logo now stays full-size at every width instead of shrinking.
   Hidden by default (desktop shows the inline .links row as always); the
   @media(max-width:900px) block below switches it on. Driven by
   assets/js/nav-toggle.js, which toggles .nav.is-open and locks page
   scroll via body.nav-open-lock while the panel is open. z-index:2 keeps
   the button clickable/visible above .links once that panel is showing
   (both are undeclared/auto z-index by default, and .links comes later in
   the DOM, so without this the open panel would paint over the toggle). */
.nav-toggle{display:none;position:relative;z-index:2;flex-direction:column;justify-content:center;gap:5px;width:26px;height:22px;padding:0;background:none;border:0;cursor:pointer;color:inherit;}
.nav-toggle span{display:block;width:100%;height:2px;background:currentColor;transition:transform .25s ease,opacity .2s ease;}
.nav.is-open .nav-toggle span:nth-child(1){transform:translateY(7px) rotate(45deg);}
.nav.is-open .nav-toggle span:nth-child(2){opacity:0;}
.nav.is-open .nav-toggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg);}
body.nav-open-lock{overflow:hidden;}

/* Products dropdown, added 2026-09-09 — Marton wants any page on the site
   to reach a specific product page directly, not just via the hub (the hub
   itself is already one click away and, after today's other work, shows
   all three products with no scrolling — so this isn't about speeding up
   hub→product, it's about skipping the hub entirely from anywhere else).
   Kept deliberately plain — three text links, no thumbnails — on purpose:
   a rich mega-menu with product photos is a fast-commerce pattern, and
   this site's whole visual language (full-bleed photography, large serif
   type, minimal chrome) leans slow and editorial. A photo-heavy dropdown
   would read as a tonal clash the moment it appeared; a quiet text list
   doesn't.
   Structure: .nav-item-dropdown wraps the existing "Products" link (same
   markup, same active/hover rules — .nav .links a still matches it since
   that selector matches any depth of link inside .links, not just direct
   children) plus a hidden .nav-dropdown panel, shown on :hover or
   :focus-within (so it's reachable by keyboard, not just mouse). The panel
   itself is split into an outer, invisible hit-area (.nav-dropdown, flush
   against the link with top:100% and no gap) and an inner, visibly-styled
   box (.nav-dropdown-inner, pushed down with padding-top on the outer
   rather than a margin) — a plain margin-top gap here is a classic dropdown
   bug: the cursor crosses genuinely empty space between the link and the
   panel, is briefly over neither element, and the menu can flicker closed
   before it's reached. Padding keeps that space inside the hoverable
   element instead of between two elements.
   Mobile has no hover state at all, so this is a desktop enhancement only
   there — tapping "Products" on a touch device just goes to the hub as it
   always did, which is a safe, unbroken fallback rather than a gap in
   functionality. */
.nav-item-dropdown{position:relative;}
.nav-dropdown{position:absolute;top:100%;left:0;padding-top:14px;opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .16s ease,transform .16s ease,visibility .16s ease;}
.nav-item-dropdown:hover .nav-dropdown,
.nav-item-dropdown:focus-within .nav-dropdown{opacity:1;visibility:visible;transform:translateY(0);}
.nav-dropdown-inner{min-width:168px;padding:12px 0;background:rgba(10,10,10,.96);border:1px solid rgba(255,255,255,.14);}
.nav-dropdown-inner a{display:block;padding:10px 22px;font-size:13px;letter-spacing:.04em;text-transform:none;font-weight:500;color:rgba(255,255,255,.82);opacity:1;}
.nav-dropdown-inner a:hover{color:var(--copper);text-decoration:none;}
body.on-light .nav-dropdown-inner, body.nav-light .nav-dropdown-inner{background:rgba(255,255,255,.97);border-color:rgba(0,0,0,.1);}
body.on-light .nav-dropdown-inner a, body.nav-light .nav-dropdown-inner a{color:rgba(0,0,0,.72);}
body.on-light .nav-dropdown-inner a:hover, body.nav-light .nav-dropdown-inner a:hover{color:var(--copper);}
/* 900px matches the nav's own hamburger breakpoint (below which "Products"
   is a plain link inside the slide-down panel, not a hover target) rather
   than a new number invented for this one component — keeps the two in
   sync if that breakpoint ever moves. Was 700px; widened 2026-09-27 when
   the nav switched to a hamburger at 900px so this lines up with it exactly
   instead of leaving a 700–900px gap where a hover dropdown could still
   appear over the collapsed nav. Hidden outright rather than just left
   hover-only: many mobile browsers (iOS Safari in particular) treat a first
   tap on anything with a :hover style as triggering the hover state rather
   than the click, which would turn "tap Products" into "tap twice" without
   this. */
@media(max-width:900px){.nav-dropdown{display:none;}}

/* Light nav treatment: body.on-light is the static, whole-page version (pages
   that are light top to bottom — Vision, Sustainability, Where to Buy). Pages
   that mix dark and light sections (the products hub, the three product
   pages) can't use a single page-level class, so nav-theme.js toggles
   body.nav-light dynamically as the user scrolls, based on data-nav-theme
   markers on each section — same rules, just driven by scroll position
   instead of being fixed for the whole page. */
body.on-light .nav, body.nav-light .nav{color:var(--black);}
/* same scrim technique as the dark pages, just in white — a soft fade for
   the nav to sit on rather than floating directly on the page background,
   instead of removing the scrim entirely on light pages */
body.on-light .nav::before, body.nav-light .nav::before{
  background:linear-gradient(180deg, rgba(255,255,255,.92) 0%, rgba(255,255,255,.65) 55%, rgba(255,255,255,0) 100%);
}
body.on-light .nav .logo img, body.nav-light .nav .logo img{filter:none;}

/* Current-page indicator: the logo turns copper on the homepage (it doubles as
   the "home" link and there's no separate text link to color); a nav text link
   turns copper on every other page. Ships as a separate pre-colored PNG
   (logo-flow-copper.png, exact #996632, alpha-matched to the source logo) —
   not a CSS mask-image, which needs to read the source PNG's pixel data and
   gets blocked by the browser's CORS policy when the site is opened directly
   from disk (file://, origin "null") rather than served over http — exactly
   how a downloaded test build gets previewed, so it has to work that way. */
body.page-home .nav .logo img{filter:none;}

/* ---------- HERO ----------
   .hero-wrap is a tall scroll runway; .hero pins via position:sticky while
   hero.js reads scroll progress across that runway and drives a gentle scale
   on .hero-img. The hero itself is now a video (AI-generated turn). */
.hero-wrap{position:relative;height:165vh;}
.hero{
  position:sticky;top:0;height:100vh;min-height:620px;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;background:var(--black);
}
.hero-stage{position:absolute;inset:0;perspective:1400px;}
.hero-img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
  opacity:.92;
  transform:scale(1.04);
  transform-style:preserve-3d;
  will-change:transform;
}
.hero-scrim{position:absolute;inset:0;background:linear-gradient(180deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.05) 35%, rgba(0,0,0,.55) 100%);}
/* Bottom opacity fade, added 2026-08-21 (Marton: "try the opacity fade below
   the landing page black Flow one") — separate from .hero-scrim above, which
   only partially darkens the whole hero for text legibility. This one fades
   the video itself out to solid black across its bottom, so the video
   dissolves into its own black background rather than ending on a hard
   rectangular edge.
   2026-09-07: widened and recolored to end on true #000 rather than
   --black (#0a0a0a) — the section right below (.flow-listening, the
   manifesto quote) was repainted pure #000 in the meantime, and the old
   34%-tall/var(--black) fade left a visible seam where the hero's fade-out
   tone didn't quite match the flat black block starting right under it.
   Taller ramp (46%) plus an earlier full-black stop (80%) means the hero is
   already solid, matching black well before the hard cut into the quote
   section, covering the tagline/scroll-cue area too rather than just the
   very bottom sliver. */
.hero-fade{position:absolute;left:0;right:0;bottom:0;height:46%;background:linear-gradient(180deg, rgba(0,0,0,0) 0%, #000 80%);pointer-events:none;}
.hero-content{position:relative;z-index:2;text-align:center;color:var(--white);padding:0 24px;}
.hero-tagline{
  font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;
  font-style:italic;
  font-weight:400;
  font-size:clamp(35px,5.5vw,68px);
  line-height:1.2;
  margin:0 0 20px;
}
.hero-sub{font-size:17.5px;letter-spacing:.04em;color:rgba(255,255,255,.8);max-width:620px;margin:0 auto;}
.hero-scroll-cue{position:absolute;bottom:28px;left:50%;transform:translateX(-50%);color:rgba(255,255,255,.65);font-size:12.6px;letter-spacing:.16em;text-transform:uppercase;z-index:2;}

/* ---------- SECTIONS ---------- */
section{padding:110px 0;}
section.tight{padding:72px 0;}
section.alt{background:var(--charcoal);color:var(--ivory);}
/* Everything below this section-head rule assumed a light section (default
   body text is near-black) — now that `.alt` is a dark panel, its own
   typography needs an explicit light color instead of inheriting black. */
section.alt .section-head h2{color:var(--ivory);}
section.alt .manifesto{color:var(--ivory);}
section.alt .manifesto-attr span{color:var(--ivory-muted);}
/* The hairline gap between product cards used a light grey fill designed to
   sit quietly on an off-white ground; on the new charcoal ground that same
   light grey would read as a bright line slicing across the black cards, so
   it's dimmed to a faint warm hairline instead — still just enough definition
   between cards, not a design element on its own. */
section.alt .grid3{background:rgba(239,233,223,.08);}
section.alt .editorial-grid{background:rgba(239,233,223,.08);}
section.alt .editorial-grid .ph{background:var(--black);}
section.alt .press-quote{color:var(--white);}
section.alt .press-quote span{color:var(--ivory-muted);}
/* `.range-top` originated as a fix for a warm-charcoal-wedged-between-two-
   true-blacks clash around the manifesto quote and product grid (still the
   right diagnosis — a warm near-black sandwiched between two colder
   true-blacks reads as a dirty smear, not a deliberate second tone). The
   2026-09-06 homepage redesign extends the same true-black ground further
   down to cover the new `.craft-band` too, so the whole hero → manifesto →
   "The Range" → product grid → craft-band stretch now reads as one
   continuous, unbroken black canvas — zero color seams to patch with fades,
   which is most of what the last several rounds of fixes were fighting.
   The warm charcoal Marton confirmed he likes ("good down here in the
   editor's choices") is kept, but now only for the `.recognition` band
   further down, past the forest video — a real break in the photography
   sits between the two tones instead of them touching directly. */
/* 2026-09-07: background bumped from --black (#0a0a0a) to true #000 — the
   quote (.flow-listening) and the hero's own fade-out (.hero-fade) were
   both repainted pure #000, which left .range-top's original --black as
   the odd one out: a visible lighter rectangle in the 150px gap between
   the hero and the quote, exactly the "true-black sandwiching a warmer/
   lighter tone reads as a smear" problem described above, just one shade
   pair over from the original fix. Padding-top also halved (150px→75px)
   per Marton's ask to shrink that gap, not just recolor it. */
.range-top{background:#000;padding-top:75px;}
section.dark{background:var(--black);color:var(--white);}
.section-head{max-width:640px;margin:0 auto 56px;text-align:center;}
.section-head h2{font-size:clamp(24px,3vw,36px);font-weight:400;margin:14px 0 0;font-family:"Liberation Serif",Georgia,serif;}
.vision-link{color:var(--copper);text-decoration:none;border-bottom:1px solid var(--copper);padding-bottom:1px;transition:opacity .2s ease;}
.vision-link:hover{opacity:.72;}

/* Liberation Serif italic — now a genuine italic cut (self-hosted
   LiberationSerif-Italic.ttf), not the browser-synthesized oblique slant this
   site used to render for it. That synthetic slant is what read as "too
   techy" here originally, so EB Garamond was substituted as a workaround;
   with a real italic file now loaded for the family, the manifesto matches
   the "Editor's Choice" / "full-blooded amp" mentions (.rec-line) and the
   product-page press quotes (.press-quote) properly, instead of matching
   the same rendering bug those still had. */
/* 2026-09-06, round 2 — genuine redesign, not a recolor. Marton's direct
   reaction to the first redesign pass was that this section "is almost
   completely the same as before": true of the visual language even though
   the section it sat in had changed — still a modest centered italic line
   at a headline-adjacent size. This version gives the quote real editorial
   weight: a large decorative quotation mark (the site's one other serif
   flourish, scaled up into a genuine graphic element) sits above it, and the
   quote itself is set nearly twice as large as before — closer to a
   magazine pull-quote's scale than a caption's. */
.manifesto-block{position:relative;max-width:920px;margin:0 auto;padding-top:64px;}
.manifesto-mark{
  position:absolute;top:-34px;left:50%;transform:translateX(-50%);
  font-family:"Liberation Serif",Georgia,serif;font-style:normal;
  font-size:150px;line-height:1;color:var(--copper);opacity:.32;
  pointer-events:none;user-select:none;
}
.manifesto{max-width:none;margin:0;text-align:center;font-size:clamp(34px,4.6vw,56px);line-height:1.28;font-weight:400;font-style:italic;font-family:"Liberation Serif",Georgia,serif;}
.manifesto-oneline{max-width:100%;white-space:normal;font-size:clamp(34px,4.6vw,56px);}
.manifesto-attr{text-align:center;margin:28px 0 0;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--copper);font-weight:600;}
.manifesto-attr span{color:var(--grey-text);font-weight:400;}

@media (max-width:900px){
  .manifesto-block{padding-top:44px;}
  .manifesto-mark{font-size:100px;top:-22px;}
  .manifesto-oneline{white-space:normal;font-size:30px;max-width:100%;}
}

/* ---------- AWARD / RECOGNITION SECTION (distributed: manifesto after hero,
   "Best Sound" below The Range, remaining two mentions below the teaser row) ---------- */
/* Shared style for every press citation that now links out to the real review
   (manifesto attribution, "Best Sound" attribution, both scattered mentions) —
   keeps whatever color it already had (copper on .rec-tag, grey on the others)
   and just adds an underline as the "this is clickable" affordance. */
.press-link{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;transition:opacity .2s ease;}
.press-link:hover{opacity:.7;}

/* 2026-09-06 — homepage redesign. Marton's call after days of section-by-
   section patching ("we've been trying to fix it for days now, and we just
   can't make it work"): the recognition content had been split three ways
   down the page (manifesto near the top, "Best Sound" as its own bigger
   moment mid-page, the two remaining citations scattered lower still) with
   three different visual treatments between them, which is exactly why it
   never settled — every fix improved one third of it in isolation. All three
   press citations (the High Fidelity award and the two Hifi Pig/High Fidelity
   quotes) are now one `.recognition` band, lower on the page, past the forest
   video — a single considered "what others said" moment instead of three.
   The manifesto quote stays where it is, right after the hero: it's FLOW's
   own voice, not a citation, and conflating the two was part of the muddle. */
/* Round 2 (2026-09-06, same day) — the three-equal-column grid below was the
   first redesign pass's answer to the old scattered layout, but three equal
   boxes is close in shape to what "scattered mentions" already looked like
   in earlier rounds (see claude/flow-website-layout.md), so it still read as
   more of the same rather than a real redesign. Restructured around actual
   hierarchy instead: "Best Sound" is FLOW's single biggest accolade (a named
   award, not just a review line), so it now stands alone as a large featured
   moment; the two review quotes sit below as a smaller, deliberately
   secondary two-up list — one hero citation plus supporting evidence, not
   three equally-weighted boxes. */
.recognition{padding:96px 40px 120px;max-width:900px;margin:0 auto;}
.rec-eyebrow{text-align:center;margin-bottom:56px;}
.rec-featured{text-align:center;max-width:640px;margin:0 auto;}
.rec-featured .rec-pub{font-size:13px;}
.rec-featured .rec-line{font-size:42px;line-height:1.25;margin:0 0 20px;}
.rec-featured .rec-tag{font-size:13px;}
.rec-fade{width:100%;max-width:280px;height:1px;margin:52px auto;background:linear-gradient(90deg, transparent 0%, var(--hairline-on-dark) 50%, transparent 100%);}
.rec-list{display:grid;grid-template-columns:1fr 1fr;gap:56px;}
.rec-item{text-align:center;position:relative;}
.rec-item + .rec-item::before{
  content:"";position:absolute;top:0;left:0;bottom:0;
  width:1px;background:linear-gradient(180deg, transparent 0%, var(--hairline-on-dark) 50%, transparent 100%);
}
.rec-pub{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ivory-muted);margin:0 0 14px;padding-bottom:10px;position:relative;}
.rec-pub::after{content:"";position:absolute;left:50%;bottom:0;transform:translateX(-50%);width:20px;height:1px;background:var(--copper);}
.rec-line{font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-size:18px;line-height:1.5;color:var(--ivory);margin:0 0 12px;}
.rec-tag{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--copper);font-weight:600;}

/* homepage-only: tighten this section's bottom padding — the generic 110px
   (from the base `section` rule) left too much grey space below the
   recognition band before the footer. Top padding used to live here, giving
   the manifesto quote room below the hero — moved onto `.range-top` itself
   (see that rule, above) so the black panel starts flush with the very top
   of the section instead of sitting inside an already-charcoal padding area. */
.home-range{padding-top:0;padding-bottom:48px;}
/* Manifesto quote moved inside .home-range 2026-08-21 — it used to sit in its
   own white `section.tight` directly above this one, which produced two
   independent paddings stacked on top of each other (the white section's
   bottom padding + this section's top padding) with an arbitrary black/white/
   grey color seam landing in the middle of that dead space. Folding it into
   this section removes that seam entirely — hero goes straight to grey, one
   deliberate gap separates the quote from "The Range" heading below it. */
.home-range .section-head{margin-top:72px;}
/* .range-fade (a thin fading hairline between the manifesto quote and "The
   Range" heading, added 2026-08-25) is removed as of the quote's white-band
   redesign below — the quote is now its own full-bleed white section, so the
   white-band edge itself is the separation between "a quote about the brand"
   and "the start of the product range"; a divider on top of that hard color
   change read as redundant. `.home-range .section-head{margin-top:72px}`
   above is what now provides the gap on its own. */

/* ---------- THEATRICAL FULL-BLEED IMAGES (homepage) ----------
   Two grayscale scene photos (forest, mountain — wave sits this round out,
   see chat) at full page width, cinematic 2.2:1 crop. Replaces the earlier
   hover-reveal treatment on the product cards: the elemental imagery is now
   shown at real scale instead of hidden behind an interaction, and gives the
   homepage the two deliberate "grandiose" beats Marton asked for. Placed far
   apart on purpose — one right after The Range, one as the closing image
   right before the footer — rather than stacked near each other. */
/* Both theatrical shots are now scroll-scrubbed video (assets/js/theatrical-scrub.js)
   rather than static images — same technique as the hero, but not pinned: each
   clip's own scroll-through-viewport progress drives its currentTime. */
.theatrical-shot{width:100%;aspect-ratio:2.2/1;overflow:hidden;position:relative;}
.theatrical-shot img,
.theatrical-shot video{width:100%;height:100%;object-fit:cover;display:block;}
/* Legibility can't depend on the photo happening to be dark under the caption
   (the forest crop has bright light-shaft patches right where the text sits).
   An outline on the letters was tried first and Marton didn't like the look —
   replaced with a soft, blurred dark patch sitting behind just the caption,
   feathered at the edges (no hard box) rather than a scrim across the whole
   image. Darkened 30% past the first approved test per his follow-up. */
.theatrical-cap{
  position:absolute;left:46px;bottom:28px;z-index:1;color:var(--white);
  font-size:12.7px;letter-spacing:.14em;text-transform:uppercase;font-weight:600;
  padding:14px 20px;
}
.theatrical-cap::before{
  content:"";position:absolute;inset:-14px -28px;z-index:-1;
  background:radial-gradient(ellipse 100% 100% at center, rgba(0,0,0,.78) 0%, rgba(0,0,0,.55) 45%, rgba(0,0,0,0) 78%);
  filter:blur(7px);
}
.theatrical-cap span{color:#e0a868;}
/* Mountain caption only: that crop is already dark right where the text sits
   (rock in shadow, not a bright highlight like the forest crop), so the same
   dark patch just muddies into the photo instead of helping — lightened 30%
   for this one caption specifically. */
.theatrical-cap-light::before{
  background:radial-gradient(ellipse 100% 100% at center, rgba(0,0,0,.55) 0%, rgba(0,0,0,.39) 45%, rgba(0,0,0,0) 78%);
}
@media (max-width:900px){
  .theatrical-shot{aspect-ratio:4/5;}
  .theatrical-cap{left:20px;bottom:16px;font-size:11.5px;}
}

/* ---------- PRODUCT GRID / CARDS ----------
   Cards switched from white to black 2026-08-21: the product photography is
   shot on a near-black studio background, so at the top of each card (where
   it meets the grid) it was already reading as one undifferentiated black
   strip across all three cards, with a plain white card (dark text) sitting
   awkwardly underneath. Marton flagged this from a screenshot and asked for
   "a black shape and white text" — rather than fight the photography, the
   whole card is now black so the photo bleeds straight into its own card
   background with no seam, and the copy underneath (name/price/link) is
   white/light-grey to read against it.

   Gap briefly widened to 40px on 2026-08-25 on a misreading of "the attached
   parts have to be separated" — Marton clarified he meant the manifesto quote
   and "The Range" heading above this grid, not the product cards themselves.
   Reverted back to the original 1px hairline the same day; see "Manifesto/
   Range separated with a fade, award cards unboxed" further down for what the
   comment actually referred to. */
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--grey-line-light);}
.p-card{background:var(--black);padding:0 0 34px;}
.p-card .p-img{aspect-ratio:1/1;overflow:hidden;background:var(--black);}
/* Elemental identity (forest/wave/mountain) moved out of the product cards and
   into two full-bleed "theatrical" images elsewhere on the page (see above) —
   plain product photo here, no hover/tap crossfade. */
.p-card .p-img img{width:100%;height:100%;object-fit:cover;transition:transform .5s ease;}
.p-card:hover .p-img img{transform:scale(1.035);}
.p-card .p-meta{padding:26px 32px 0;}
.p-card .p-meta .element{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--copper);margin-bottom:8px;}
.p-card .p-meta h3{font-size:19px;font-weight:600;margin:0 0 8px;color:var(--white);}
.p-card .p-meta p{font-size:13px;color:#b0b0b0;line-height:1.6;margin:0 0 14px;}
.p-card .p-meta .price{font-size:13px;font-weight:600;color:var(--white);}
.p-card .p-meta .view-link{display:inline-block;margin-top:14px;font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--white);border-bottom:1px solid var(--white);padding-bottom:3px;}

/* ---------- CRAFT BAND (2026-09-06 homepage redesign) ----------
   Replaces the two separate `.teaser-band` white rectangles (founder photo,
   amp photo) that used to sit apart from each other, each breaking the dark,
   cinematic mood the hero and theatrical videos establish — a bright white
   card reading as an interruption rather than a considered beat, however
   much the edge fades around it were refined. Same two photos, same two
   captions/links, unchanged — grayscale like the site's other elemental/
   lifestyle photography (forest, mountain), sitting on the same continuous
   true black as the product grid above it rather than punching a white hole
   in it.

   Round 2 (same day) — the first pass paired the two photos as an equal
   side-by-side diptych, which read too close to a generic "two feature
   boxes" layout to feel like a real change from what was there before.
   Rebuilt as an asymmetric editorial spread instead: one large full-height
   portrait (the founder) anchors the section, a narrower column beside it
   carries the copy as real pull-quote-scale statements plus a smaller inset
   photo — a magazine profile-page shape, not a matched pair of cards. */
.craft-band{padding:130px 40px 150px;max-width:1200px;margin:0 auto;}
.craft-eyebrow{text-align:center;margin-bottom:56px;}
.craft-grid{display:grid;grid-template-columns:1.15fr 1fr;gap:72px;align-items:stretch;}
.craft-main{position:relative;}
.craft-img{overflow:hidden;background:var(--grey-line);}
.craft-img img{width:100%;height:100%;object-fit:cover;display:block;filter:grayscale(1) contrast(1.05) brightness(.96);}
.craft-img-main{aspect-ratio:4/5;height:100%;}
.craft-side{display:flex;flex-direction:column;justify-content:center;text-align:left;}
.craft-copy{max-width:420px;margin:0 0 22px;font-size:23px;line-height:1.5;color:var(--ivory);font-family:"Liberation Serif",Georgia,serif;font-style:italic;}
.craft-link{display:inline-block;font-weight:600;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--copper);border-bottom:1px solid var(--copper);padding-bottom:2px;}
.craft-side .craft-link{margin-bottom:52px;}
.craft-img-inset{aspect-ratio:16/10;margin-bottom:22px;}
.craft-copy-small{font-size:17px;margin-bottom:14px;}
.craft-side .craft-item + .craft-item .craft-link{margin-bottom:0;}

/* ---------- FOOTER ---------- */
footer{background:var(--black);color:#cfcfcf;padding:70px 0 36px;}
footer .cols{display:flex;gap:64px;flex-wrap:wrap;margin-bottom:48px;}
footer .cols .col-title{color:var(--white);font-size:11px;letter-spacing:.1em;text-transform:uppercase;margin-bottom:16px;font-weight:600;}
footer .cols a,footer .cols div div{display:block;font-size:13px;line-height:2;color:#a9a9a9;}
footer .cols a:hover{color:var(--white);}
footer .fine{border-top:1px solid #262626;padding-top:20px;font-size:11.5px;color:#6f6f6f;}

/* ---------- PRODUCT DETAIL PAGE ----------
   Rebuilt 2026-09-08 — Marton asked for the three product pages to get the
   same "grandiose and luxurious" treatment as the homepage and products hub,
   with explicit license to reorganize/restructure rather than just reskin
   colors. The .pd- prefix, .spec-flag, .editorial-grid, .press-quote and
   .compare-row classes are all exclusive to these three pages (confirmed via grep before editing — no
   shared-selector risk to the rest of the site here), so this whole block
   was safe to redesign directly rather than needing a .page-products-style
   scoping wrapper.
   The core lever is the same one used on the homepage and the hub: large-
   scale italic Cormorant Garamond type and confident negative space, not new
   photography — these pages now share that same font (loaded via the
   Google Fonts <link> added to each page's <head>, matching the hub page). */
/* 2026-09-09 — reverted away from the italic-serif treatment (see below)
   after Marton shared a reference showing the poetic element name back as
   an uppercase letter-spaced tag and the device name as a bold upright
   sans headline, and confirmed via a direct question that both change,
   not just the tag. Tag styling now matches the site's standard .eyebrow
   pattern (11px/.16em/600, see line ~57) rather than reintroducing a
   near-duplicate rule. Device name switches from italic Cormorant
   Garamond to bold Montserrat — which also means the products-hub card
   h3 (scoped override further down, "device names...correct font") needs
   to flip back the same way, or the hub/hero mismatch this session
   already fixed once just reopens in the opposite direction. */


/* ---------- PRODUCT HERO — "the stage" (2026-09-28) ----------
   Replaces the 50/50 copy-left / photo-right split. Marton: the hero wasn't
   grand enough next to the homepage. Diagnosis, not just taste:
   1. The photo read as a pasted-in box — its studio floor band (~#222) sat
      as a visible grey rectangle against the page black.
   2. A two-column split is the default e-commerce layout; nothing about it
      says "one object, presented".
   3. No hierarchy past the headline and no next step at €9–19k.
   Fix: the product is staged alone, centred and large, under a pool of
   light, standing on a horizon line, with its model word set monumentally
   behind it. The photo is a true alpha cut-out (see .pd-product), so no
   studio floor or box edge can show.
   Deliberately NO spec figures here — see the Engineering comment below:
   raw numbers invite a losing benchmark at this price. Tagline, price and
   the audition CTA carry the bar instead.
   Entrance is a slow reveal from darkness (CSS); scroll parallax is
   pd-hero.js. Both off under prefers-reduced-motion. */
.pd-hero{
  position:relative;height:100vh;height:100svh;min-height:680px;max-height:1200px;
  display:grid;grid-template-rows:1fr auto;
  background:var(--black);color:var(--white);overflow:hidden;isolation:isolate;
  padding:84px 0 0;
}
/* pool of light from above, warm at the core — the only "decoration" */
.pd-stage-light{
  position:absolute;inset:-10% 0 0 0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(ellipse 38% 46% at 50% 38%, rgba(153,102,50,.16) 0%, rgba(153,102,50,.05) 45%, rgba(0,0,0,0) 72%),
    radial-gradient(ellipse 60% 55% at 50% 30%, rgba(255,255,255,.055) 0%, rgba(255,255,255,0) 70%);
  transform:translateY(calc(var(--pd-p,0) * -60px));
}
.pd-hero .pd-element{
  display:flex;align-items:center;gap:14px;
  margin:0 0 18px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;
  text-transform:uppercase;color:var(--copper);font-size:12.5px;letter-spacing:.32em;
}
.pd-hero .pd-element::before{content:"";width:40px;height:1px;background:var(--copper);}
.pd-stage{position:relative;min-height:0;}
/* horizon line the product stands on (behind it, so the body occludes it) */
.pd-stage::after{content:"";position:absolute;left:40px;right:40px;bottom:0;height:1px;z-index:0;background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.2) 20%,rgba(255,255,255,.2) 80%,rgba(255,255,255,0));}
/* monumental model word, behind the product. Fill fades top→bottom so the
   letters dissolve into the product rather than colliding with it. */
.pd-ghost{
  position:absolute;left:0;right:0;top:3%;z-index:0;text-align:center;pointer-events:none;line-height:0;
  transform:translateY(calc(var(--pd-p,0) * -90px));
}
/* FLOW's own model wordmarks (supplied by Marton 2026-09-28), pre-baked as
   white PNGs with the top-to-bottom fade in the alpha channel — a plain
   <img>, not a CSS mask, because mask-image with a url() fails under
   file:// (same bug the copper nav logo hit on 2026-08-19). */
.pd-ghost img{display:inline-block;height:min(15vw,24vh);width:auto;max-width:92vw;object-fit:contain;}
/* product: fills the stage row, bottom-anchored, overlapping the bar's
   hairline slightly so the reflection dissolves into it. The image is a
   hand-masked cut-out (pd-stage-*.webp, alpha = product silhouette + a
   fading reflection) cropped from the *-front.jpg studio shots — so the
   studio floor band never shows and the model word can sit behind it. */
.pd-product{
  position:absolute;z-index:1;left:50%;bottom:0;
  height:calc(100% - 25vh);width:auto;max-width:80vw;aspect-ratio:1800/1040;
  transform:translateX(-50%) translateY(calc(var(--pd-p,0) * 40px)) scale(calc(1 - var(--pd-p,0) * .04));
  transform-origin:50% 100%;
}
.pd-product img{display:block;width:100%;height:100%;object-fit:contain;object-position:50% 100%;filter:drop-shadow(0 30px 60px rgba(0,0,0,.55));}
/* the bar, decluttered 2026-09-28 (Marton: "too cluttered"): two groups
   only — identity on the left (element line + the real FLOW model
   logotype, which carries MK2 itself, so the separate badge is gone),
   acquisition on the right on ONE baseline (price, Configure, audition).
   The tagline left the hero; it now lives in the page's meta description. */
.pd-hero-bar{
  position:relative;z-index:3;
  display:flex;align-items:flex-end;justify-content:space-between;gap:48px;
  padding-top:34px;padding-bottom:46px;
}
.pd-hero h1{margin:0;line-height:0;}
.pd-logo{display:block;height:clamp(30px,3.1vw,48px);width:auto;max-width:100%;}
.pd-buy{display:flex;align-items:center;gap:30px;flex-shrink:0;}
/* price in Montserrat (2026-09-28, Marton): the serif figures clashed with
   the geometric FLOW logotype right beside them; same family as the nav and
   buttons now, medium weight, lining tabular figures, lightly tracked. */
.pd-hero .pd-price{margin:0;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:500;font-size:22px;letter-spacing:.06em;font-variant-numeric:lining-nums tabular-nums;line-height:1;color:var(--white);white-space:nowrap;}
.pd-hero .pd-price span{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,255,255,.5);margin-right:8px;vertical-align:middle;}
.pd-buy a{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:11.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;white-space:nowrap;text-decoration:none;transition:background .3s ease,color .3s ease,border-color .3s ease;}
.pd-cta-primary{color:var(--white);border:1px solid var(--copper);padding:15px 26px;background:rgba(153,102,50,.08);}
.pd-cta-primary:hover{background:var(--copper);color:#fff;}
.pd-cta-secondary{color:rgba(255,255,255,.72);border-bottom:1px solid rgba(255,255,255,.3);padding-bottom:3px;}
.pd-cta-secondary:hover{color:#fff;border-color:#fff;}
/* One sizing for all three pages (2026-09-28, Marton: "match the One").
   The product box is locked to FLOW One's crop ratio (1800x1040); the Two and
   Three cut-outs are wider/shorter, so object-fit:contain makes them fill the
   box's width — every amp therefore renders at exactly the same width, which
   is also true to life (all three chassis are 440mm wide). Only their
   heights differ, as they really do (200 / 150 / 100mm). */

/* entrance: out of darkness */
@media (prefers-reduced-motion:no-preference){
  .pd-product img{animation:pdReveal 2.4s cubic-bezier(.2,.7,.1,1) .15s both;}
  .pd-ghost img{animation:pdGhost 3.2s cubic-bezier(.2,.7,.1,1) both;}
  .pd-stage-light{animation:pdFade 2.8s ease .1s both;}
  .pd-hero-bar > *{animation:pdRise 1.4s cubic-bezier(.2,.7,.1,1) both;}
  .pd-hero-bar > :nth-child(1){animation-delay:.9s;}
  .pd-hero-bar > :nth-child(2){animation-delay:1.05s;}
  .pd-hero-bar > :nth-child(3){animation-delay:1.2s;}
}
@keyframes pdReveal{from{opacity:0;filter:brightness(.15);transform:translateY(26px) scale(1.035);}to{opacity:1;filter:none;transform:none;}}
@keyframes pdGhost{from{opacity:0;transform:scale(1.06);}to{opacity:1;transform:none;}}
@keyframes pdFade{from{opacity:0;}to{opacity:1;}}
@keyframes pdRise{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}

@media (max-width:1100px){
  .pd-buy{gap:22px;}
  .pd-cta-secondary{display:none;}
}
@media (max-width:900px){
  .pd-hero{height:auto;min-height:0;max-height:none;padding-top:100px;}
  .pd-stage{height:calc(100vw * 0.62 + 16vw);}
  .pd-ghost{top:0;}
  .pd-ghost img{height:15vw;}
  .pd-product{width:100vw;max-width:none;height:auto;}
  .pd-hero-bar{flex-direction:column;align-items:center;gap:26px;text-align:center;padding-bottom:56px;}
  .pd-logo{height:auto;width:min(78vw,340px);margin:0 auto;}
  .pd-buy{flex-direction:column;gap:18px;}
  .pd-cta-secondary{display:inline;}
  .pd-stage::after{left:22px;right:22px;}
  .pd-hero .pd-element{justify-content:center;}
  .pd-hero .pd-element::before{display:none;}
}

/* ---------- REAR-PANEL SCENE (FLOW One, 2026-09-28, v2) ----------
   Rebuilt with full freedom after the copper-title round fell flat. It now
   speaks the product hero's language, which is what worked:
   - restraint first: the forest is pulled down into near-night, so the
     page stays in the site's black register instead of a grey photo;
   - light does the work: one soft white glow sits *behind the amp only*,
     backlighting the black chassis (the reason white beat black earlier);
   - one monumental word: HARMONY in the hero's model-word face (Montserrat
     Bold, tight), white fading downward so its letters dissolve into the
     light behind the amp — the same trick as ONE behind the front view;
   - "of the Forest" set beneath the amp (the foot bar with the tagline was
     removed at Marton's request).
   The glow breathes very slowly (10s) so the scene is alive, not animated.
   Forest photo: Magnific stock, licensed via Marton's subscription. */
.pd-rear{position:relative;padding:0;height:100vh;height:100svh;min-height:680px;max-height:1150px;overflow:hidden;background:#000;
  display:grid;grid-template-rows:1fr auto;isolation:isolate;color:#fff;}
.pd-rear-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 42%;z-index:-4;}
/* night: heavy overall shade, deepest at top and foot */
.pd-rear-shade{position:absolute;inset:0;z-index:-3;pointer-events:none;
  background:linear-gradient(180deg,rgba(0,0,0,.88) 0%,rgba(0,0,0,.62) 34%,rgba(0,0,0,.58) 60%,rgba(0,0,0,.93) 100%);}
/* the light behind the amp */
.pd-rear-halo{position:absolute;inset:0;z-index:-2;pointer-events:none;
  background:radial-gradient(ellipse 48% 52% at 50% 49%, rgba(255,255,255,.95) 0%, rgba(255,255,255,.88) 48%, rgba(255,255,255,.42) 68%, rgba(255,255,255,.1) 86%, rgba(255,255,255,0) 100%);}
.pd-rear-ghost{position:absolute;left:0;right:0;top:9%;z-index:-1;text-align:center;pointer-events:none;white-space:nowrap;
  font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:700;text-transform:uppercase;
  font-size:min(16vw,30vh);line-height:.9;letter-spacing:-.035em;
  color:rgba(255,255,255,.34);
  /* copper outline, 2px (Marton: thicker, and it must fade with the fill).
     text-stroke can't take a gradient, so the fade now lives in a mask on
     the whole word — fill and outline dissolve together. Two layers,
     intersected: a top-to-bottom fade, and a soft hollow centred on the
     white glow below, so the letters that sit over the light (the middle
     of the word, lower half) fade hardest and the outer letters hold. */
  -webkit-text-stroke:2px rgba(176,122,66,.85);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.6) 50%,rgba(0,0,0,.08) 92%,transparent 100%),radial-gradient(ellipse 42% 120% at 50% 118%,rgba(0,0,0,.1) 0%,rgba(0,0,0,.45) 55%,#000 100%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.6) 50%,rgba(0,0,0,.08) 92%,transparent 100%),radial-gradient(ellipse 42% 120% at 50% 118%,rgba(0,0,0,.1) 0%,rgba(0,0,0,.45) 55%,#000 100%);
  mask-composite:intersect;}
.pd-rear-stage{position:relative;display:flex;align-items:flex-end;justify-content:center;min-height:0;padding-bottom:0;}
.pd-rear-amp{display:block;width:min(46.8vw,60vh * 1.32,760px);height:auto;filter:drop-shadow(0 34px 44px rgba(0,0,0,.7));}
/* "of the Forest" beneath the amp, completing the HARMONY above it —
   the element name reads top-to-bottom through the product. Wide-tracked
   caps flanked by fading hairlines (the hero eyebrow's language), white so
   it holds on the dark forest floor. The full phrase is kept for screen
   readers since the ghost word is aria-hidden. */
.pd-rear-caption{margin:0;padding:0 24px 11vh;display:flex;align-items:center;justify-content:center;gap:26px;
  font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:clamp(13px,1.15vw,17px);letter-spacing:.62em;
  text-transform:uppercase;color:rgba(255,255,255,.86);padding-left:calc(24px + .62em);}
.pd-rear-caption::before,.pd-rear-caption::after{content:"";width:clamp(40px,6vw,96px);height:1px;background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.55));}
.pd-rear-caption::after{transform:scaleX(-1);}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
@media (prefers-reduced-motion:no-preference){
  .pd-rear-halo{animation:pdBreathe 10s ease-in-out infinite alternate;}
  .pd-rear-ghost,.pd-rear-amp,.pd-rear-caption{opacity:0;}
  .pd-rear-ghost{letter-spacing:.06em;transition:opacity 2.6s ease, letter-spacing 3.2s cubic-bezier(.2,.7,.1,1);}
  .pd-rear-amp{transform:translateY(34px) scale(1.03);filter:brightness(.2) drop-shadow(0 34px 44px rgba(0,0,0,.7));
    transition:opacity 2.2s ease .25s, transform 2.6s cubic-bezier(.2,.7,.1,1) .25s, filter 2.6s ease .25s;}
  .pd-rear-caption{letter-spacing:.3em;transition:opacity 1.8s ease 1s, letter-spacing 2.6s cubic-bezier(.2,.7,.1,1) 1s;}
  .pd-rear.is-in .pd-rear-ghost{opacity:1;letter-spacing:-.035em;}
  .pd-rear.is-in .pd-rear-amp{opacity:1;transform:none;filter:drop-shadow(0 34px 44px rgba(0,0,0,.7));}
  .pd-rear.is-in .pd-rear-caption{opacity:1;letter-spacing:.62em;}
}
@keyframes pdBreathe{from{opacity:.86;transform:scale(1);}to{opacity:1;transform:scale(1.05);}}
@media (max-width:900px){
  .pd-rear{height:auto;min-height:0;max-height:none;aspect-ratio:auto;}
  .pd-rear-stage{height:118vw;padding-bottom:6vw;}
  .pd-rear-ghost{top:22vw;font-size:14.5vw;}
  .pd-rear-halo{background:radial-gradient(ellipse 72% 42% at 50% 50%, rgba(255,255,255,.95) 0%, rgba(255,255,255,.86) 52%, rgba(255,255,255,.38) 72%, rgba(255,255,255,.08) 88%, rgba(255,255,255,0) 100%);}
  .pd-rear-amp{width:84vw;}
  .pd-rear-caption{font-size:11px;letter-spacing:.45em;gap:14px;padding:5vw 16px 12vw;}
  .pd-rear.is-in .pd-rear-caption{letter-spacing:.45em;}
  .pd-rear-caption::before,.pd-rear-caption::after{width:28px;}
}

/* .spec-flag ("static — not scroll-tied") was a dev-only note-to-self
   flagging that this section had no scroll animation yet — useful mid-build,
   but a green badge reading like debug output has no place on a page meant
   to look finished, let alone luxurious. Removed from the markup on all
   three pages; the rule itself deleted rather than left as dead CSS. */
/* Spec sheet redesigned, 2026-09-09 — the old version (plain grey
   hairlines, label and value in the same case/weight/size) read as a
   flat data dump, not a luxury-goods spec plate. Reworked around a
   pattern common to that category: label set small, uppercase and
   tracked out (reusing the site's own .eyebrow voice) against a value
   in the editorial serif, right-aligned so the figures line up as a
   clean column instead of sitting flush against their labels. A thin
   copper rule opens the block — a quiet echo of the eyebrow color
   rather than a full border-box, which would read more like a form
   than a spec plate — and the Price row (flagged with .specs-price in
   the markup, not assumed to be tr:last-child, since a future edit
   could reorder rows) is set apart in copper at a larger size, since
   it's the one figure a buyer's eye is actually looking for. */
/* Spacing tightened, 2026-09-09 — measured via bounding rects, not
   eyeballed: the copper rule sat flush against the configurator's price
   row above it (0px gap, looked glued-on) while the gap below it to
   "SPECIFICATION" was 40px against a 24px gap from "SPECIFICATION" down
   to the first row — two visibly uneven, overly loose gaps reading as
   dead space rather than deliberate rhythm. Now: 40px margin above the
   rule (real separation from the configurator, instead of none) and
   12px padding below it, which combined with the text's own line-height
   lands the rule-to-eyebrow gap at ~24px — matching the eyebrow-to-row
   gap exactly instead of nearly-double it. */
.specs-wrap{max-width:640px;margin:40px auto 0;padding-top:12px;border-top:1px solid var(--copper);}
.specs-wrap .eyebrow{display:block;margin-bottom:24px;}
/* pd-specs is its own section (flow-one only, since the split off the configurator) — it already
   gets the section's 72px top padding, so the 40px margin-top above is redundant here. */
.pd-specs .specs-wrap{margin-top:0;}
table.specs{width:100%;border-collapse:collapse;font-size:13.5px;}
table.specs tr{border-top:1px solid var(--grey-line-light);}
table.specs tr:first-child{border-top:none;}
table.specs td{padding:19px 2px;}
table.specs td:first-child{color:var(--grey-text);width:46%;font-size:11px;letter-spacing:.09em;text-transform:uppercase;font-weight:600;}
/* text-align left, not right, on the value column — tried right-aligned
   first since it makes short numeric values (most rows) line up as a
   clean column, but the Finish row's value ("Hand-polished, varnished
   walnut; black piano lacquer") is long enough to wrap on FLOW One, and
   a wrapped right-aligned line produces a ragged left edge that's much
   harder to read than a ragged right edge — the classic reason body text
   is virtually never right-aligned. Left keeps every row legible whether
   it wraps or not; the label/value split still does the visual-column
   work right-align was there for. */
table.specs td:last-child{text-align:left;font-family:"Liberation Serif",Georgia,serif;font-size:16px;color:var(--black);}
table.specs tr.specs-price td{border-top:1px solid var(--black);padding-top:22px;}
table.specs tr.specs-price td:first-child{color:var(--black);}
table.specs tr.specs-price td:last-child{color:var(--copper);font-size:21px;font-style:italic;}
.specs-note{margin:16px 0 0;font-size:11.5px;line-height:1.6;color:var(--grey-text);}
.pd-configure-eyebrow{display:block;text-align:center;margin-bottom:28px;}

/* Finish configurator, added 2026-09-07 — replaces the old flat 6-swatch
   list (wood/aluminium/piano-black/red/blue, all shown as equal no-cost
   options). Reconciled against the newer, confirmed docs: aluminium was
   dropped as a finish entirely (Marton, 2026-08-25 — never propagated into
   this build until now), and the FLOW Signature customization program
   (confirmed 2026-09-02) replaced the flat list with four real tiers and
   real pricing — see flow-positioning-strategy.md / flow-pricing-strategy.md.
   Red/Blue are now shown as Signature example commissions (bespoke, priced),
   not free-standard swatches, which is what they actually are.
   Per-model base price, tier add-ons and video paths are set via data-
   attributes on each .pd-configurator / .swatch in the page markup; this
   file only styles the component. No per-finish video assets exist yet
   (Marton is producing those separately) — the stage defaults to a "coming
   soon" placeholder and swaps to a real video automatically, per swatch,
   the moment a file lands at the path already wired into that swatch's
   data-video attribute. See assets/js/pd-configurator.js for the swap/
   fallback logic. */
/* Compacted 2026-09-09 (pass 1) — shrank the stage's aspect ratio and
   tightened tier spacing. That reduced total height, but didn't touch the
   actual complaint: the stage and the four option tiers were stacked in one
   column, so seeing the product AND every option still meant scrolling —
   a shorter stack is still a stack. Restructured 2026-09-09 (pass 2) into
   two side-by-side columns instead: the stage/caption on the left, the
   tier panel on the right (.pd-configurator-body below), so total height
   is the TALLER of the two columns rather than their sum. On flow-one at
   1512px this brings it to ~520px (tier panel is the taller column) versus
   ~790px stacked — genuinely fits in one screen alongside the rest of the
   page chrome on typical laptop heights, not just shorter. Below ~860px
   available width the two columns get too narrow for the swatch rows and
   Signature note to stay readable, so it drops back to a single stacked
   column there (see the max-width:860px query) — the pass-1 compacting
   still does real work in that mode. Widened the component's own max-width
   from 900 to 1180 to give both columns room, and added side padding since
   section.tight (the parent) carries none of its own — at 900-1180px
   viewports this would otherwise sit flush against the browser edges. */
.pd-configurator{max-width:1180px;margin:40px auto 0;padding:0 24px;}
.pd-configurator-body{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:start;}
/* Stage enlarged 2026-09-09 — at 2.35/1 the stage (~238px tall at this
   column's width) sat well short of the tier panel beside it (~524px
   tall), leaving a slab of empty white space under the caption on the
   left. Squared off to 1/1 so the two columns read as comparable sizes
   instead of one dwarfing the other — still a deliberate ratio choice
   (see the compacting note above), just a taller one now that "match the
   panel" is the actual goal rather than "as short as possible". */
.pd-configurator-stage{position:relative;aspect-ratio:1/1;background:#f2efe9;border:1px solid var(--grey-line-light);overflow:hidden;user-select:none;}
/* :not([hidden]) matters here, not just style — .pd-configurator-video and
   .pd-configurator-placeholder are toggled via the `hidden` attribute in
   JS, and a plain `display:block`/`display:flex` rule on either has HIGHER
   specificity than the UA [hidden]{display:none} rule, so it would win and
   the element would stay visible even while "hidden" — e.g. the video
   rendering as a solid black box on top of the placeholder it's supposed
   to be hidden behind. Gating on :not([hidden]) keeps [hidden] authoritative. */
/* object-fit history, 2026-09-09: went cover -> contain when the only
   asset available was 16:9 footage forced into this 1:1 stage — contain
   guaranteed nothing got cropped, at the cost of visible black letterbox
   bars Marton (correctly) called out as looking like an unfinished patch.
   Fixed at the source instead of papering over it in CSS: finish videos
   are now rendered natively 1:1 (matching this stage's own aspect ratio),
   so there's no mismatch left for either object-fit value to resolve —
   cover and contain are equivalent here. Back to cover for consistency
   with every other media rule on this site. If a non-square finish video
   ever gets dropped in again, redo it as 1:1 rather than reintroducing
   letterboxing here. */
.pd-configurator-stage video:not([hidden]){width:100%;height:100%;object-fit:cover;display:block;background:#000;touch-action:none;}
/* Drag-to-rotate, added 2026-09-09 — see pd-configurator.js for the pointer
   logic. `is-draggable` (set once a real video is showing, not during the
   placeholder state) swaps the cursor to a grab hand and reveals the hint
   label; `is-dragging` (set only for the duration of an active drag) swaps
   to the closed-hand cursor. touch-action:none on the video above stops
   the browser treating a horizontal touch-drag as a page-scroll gesture. */
.pd-configurator-stage.is-draggable{cursor:grab;}
.pd-configurator-stage.is-draggable.is-dragging{cursor:grabbing;}
.pd-configurator-drag-hint{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);background:rgba(10,10,10,.6);color:var(--white);font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:7px 14px;border-radius:20px;pointer-events:none;opacity:0;transition:opacity .3s ease;white-space:nowrap;}
.pd-configurator-stage.is-draggable:hover .pd-configurator-drag-hint{opacity:1;}
.pd-configurator-stage.is-dragging .pd-configurator-drag-hint{opacity:0;}
.pd-configurator-placeholder:not([hidden]){position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:20px;text-align:center;}
.pd-configurator-placeholder svg{width:24px;height:24px;color:var(--grey-text);opacity:.55;}
.pd-configurator-placeholder p{margin:0;font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--grey-text);}
.pd-configurator-note{display:block;max-width:340px;font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-size:13px;color:#9a948c;line-height:1.5;}
.pd-configurator-caption{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin-top:12px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--grey-text);}
.pd-configurator-caption strong{color:var(--black);font-weight:600;}
.pd-configurator-caption-price{font-weight:600;color:var(--black);}
.pd-config-star{margin-left:2px;color:var(--grey-text);font-weight:400;}
.pd-footnote{margin:56px auto 0;text-align:center;font-size:10.5px;line-height:1.6;letter-spacing:.01em;color:var(--grey-text);max-width:70ch;}


.pd-configurator-panel{margin-top:0;}
.pd-tier{border-top:1px solid var(--grey-line-light);padding:18px 0;}
.pd-tier:first-child{border-top:none;padding-top:0;}
.pd-tier-head{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin-bottom:20px;}
.pd-tier-head h4{margin:0;font-size:11px;letter-spacing:.12em;text-transform:uppercase;font-weight:600;color:var(--black);}
.pd-tier-price{font-size:11px;letter-spacing:.05em;color:var(--grey-text);white-space:nowrap;}
.pd-tier-note{margin:0 0 12px;max-width:560px;font-size:13px;line-height:1.5;color:var(--grey-text);}
.pd-tier .swatch-row{display:flex;gap:16px;flex-wrap:wrap;}
.pd-tier-commission{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;}
.pd-tier-commission .pd-tier-note{margin:0;}
.pd-commission-link{flex-shrink:0;font-size:11px;letter-spacing:.08em;text-transform:uppercase;border-bottom:1px solid var(--copper);padding-bottom:4px;white-space:nowrap;}
.pd-commission-link:hover{color:var(--copper);}

.swatch{display:flex;flex-direction:column;align-items:center;gap:6px;font-size:11px;color:var(--grey-text);background:none;border:0;padding:0;font-family:inherit;cursor:pointer;}
.swatch .dot{width:28px;height:28px;border-radius:50%;border:1px solid rgba(0,0,0,.1);outline:2px solid transparent;outline-offset:3px;transition:outline-color .15s ease;}
.swatch:hover .dot{outline-color:rgba(0,0,0,.3);}
.swatch[aria-pressed="true"] .dot{outline-color:var(--black);}
.swatch[aria-pressed="true"]{color:var(--black);font-weight:600;}
.swatch:focus-visible{outline:2px solid var(--black);outline-offset:4px;}
.dot.wood-shiny{background:linear-gradient(135deg,#b8804a,#6d4321);}
.dot.wood-matte{background:linear-gradient(135deg,#a97a4c,#5f3c22);filter:saturate(.75);}
.dot.piano-black{background:linear-gradient(135deg,#3a3a3a,#000);}
.dot.aluminium{background:linear-gradient(135deg,#e4e6e8,#a9adb2 55%,#7d8186);}
.dot.sig-red{background:linear-gradient(135deg,#c23b3b,#7a1f1f);}
.dot.sig-blue{background:linear-gradient(135deg,#3a5a9c,#1c2f56);}
/* Stacks the two-column layout back to one column once there isn't enough
   width left for both to stay usable — the swatch rows and the Signature
   tier's note are the first things to suffer in a too-narrow column. 860px
   is a deliberate second breakpoint above the site's usual 700px mobile
   line, not a typo: this component needs more room per column than most
   others need for their whole layout. */
@media(max-width:860px){
  .pd-configurator-body{grid-template-columns:1fr;gap:0;}
  .pd-configurator-panel{margin-top:28px;}
}
@media(max-width:700px){
  .pd-configurator{margin-top:32px;}
  .pd-configurator-caption{font-size:10px;}
  .pd-tier{padding:15px 0;}
  .pd-tier-commission{flex-direction:column;align-items:flex-start;}
}

/* Elemental cinematic moment + press quote, replaces the old boxed
   1.3fr:1fr editorial-grid (element photo + a second, redundant crop of the
   same product photo already shown in the hero) plus a separate small quote
   below it. Two moves here: dropped the repeated product photo (the hero
   already shows the product) so this section can be ONE full-bleed cinematic
   image instead of a cramped grid, and moved the quote text on top of that
   image with a scrim — the same overlay technique the homepage uses for
   "relax into the music" over element-wave.jpg — rather than a caption
   floating separately underneath.
   FLOW One and FLOW Three reuse the same theatrical-forest.jpg /
   theatrical-mountain.jpg crops already shot and color-graded for exactly
   this full-bleed 2.2:1 use on the homepage (2400px wide, cinematic crop) —
   real, tested assets, not new photography. FLOW Two has no equivalent: the
   only wave asset is element-wave.jpg, a plain 1400×927 product-brief photo,
   not a wide cinematic crop, and it's already the literal background of the
   homepage's "relax into the music" quote — using it full-bleed here would
   both look visibly softer at typical laptop widths than One/Three's crisp
   2400px crops, sitting right next to them in the nav, and repeat a moment
   the visitor may have just seen on the homepage. Rather than force a
   full-bleed slot a lower-res asset can't fill cleanly, FLOW Two's version
   uses .pd-elemental-contained: the image kept at a size that holds up
   (max-width 640px) with a different quote ("Though inexpensive...") below
   it rather than overlaid, on the same charcoal editorial ground already
   used elsewhere on the site (.alt). Real gap, not hidden — flagged to
   Marton so he can commission a proper wide wave crop if he wants full
   parity across all three pages. */
/* 2026-09-09 — quote section moved to sit directly under the hero (was
   between specs and "continue exploring"). In that old spot the bare
   <section>'s default 110px white padding was invisible: white above a
   white specs section reads as spacing, not a gap. Now sandwiched between
   the dark hero and this dark image, that same white padding showed up as
   a jarring band splitting the two — caught via full-page screenshot, not
   assumed away. .pd-quote makes the section itself full-bleed black with
   no padding, so the hero flows straight into the photo with no seam.
   FLOW Two doesn't need this class: its quote section is already
   section.alt (charcoal background, see comment above), which already
   reads as a continuation rather than a gap. */
.pd-quote{padding:0;background:var(--black);}
.pd-elemental{position:relative;width:100%;aspect-ratio:2.2/1;overflow:hidden;background:var(--black);margin:0;}
/* <figure> carries a 1em/40px user-agent default margin — invisible on most
   of the site (nothing else uses a bare <figure>) but it pushed this one
   40px off the left edge and past the right edge, causing real horizontal
   page overflow. Caught via a bounding-rect sweep after the fullPage
   screenshot came back visibly corrupted (the stitching artifact was a
   symptom of the page actually being wider than the viewport, not a
   screenshot bug). */
.pd-elemental img{width:100%;height:100%;object-fit:cover;display:block;}
.pd-elemental::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg, rgba(0,0,0,.5) 0%, rgba(0,0,0,.44) 38%, rgba(0,0,0,.68) 100%);}
/* Deepened from an earlier .28 mid-stop, 2026-09-08 — checked against the
   mountain crop specifically (bright snow/sky sits right where the quote
   lands) and the figcaption attribution was reading too faint at that
   opacity. A uniform gradient can't target just the caption's own line the
   way the homepage's blurred-patch trick does for a single small caption,
   so instead the whole scrim was deepened until both the forest crop's
   light-shaft area and the mountain crop's bright sky hold contrast. */
.pd-elemental-quote{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:40px;}
.pd-elemental-quote blockquote{margin:0 0 22px;max-width:780px;font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-size:clamp(23px,3.1vw,40px);line-height:1.35;color:var(--white);}
.pd-elemental-quote figcaption{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.8);text-shadow:0 1px 6px rgba(0,0,0,.5);}
.pd-elemental-quote figcaption span{color:var(--copper);}
/* FLOW One's review quote only (scoped via the added .pd-quote-one class,
   not the shared .pd-elemental-quote) — blockquote +30% from the 11px/23-40px
   base, 2026-09-27. figcaption: +40% to 15.4px same day, then -10% to
   13.86px, 2026-09-27 (net +26% over the 11px base). FLOW Two/Three reuse
   the same base .pd-elemental-quote markup and are intentionally left
   untouched. */
.pd-quote-one blockquote{font-size:clamp(29.9px,4.03vw,52px);}
.pd-quote-one figcaption{font-size:13.86px;}
@media(max-width:900px){
  .pd-elemental{aspect-ratio:4/5;}
  .pd-elemental-quote{padding:28px;}
}

/* FLOW Two only — contained variant, see comment above. */
.pd-elemental-contained{position:static;aspect-ratio:auto;max-width:640px;margin:0 auto;background:none;}
.pd-elemental-contained img{height:auto;aspect-ratio:1400/927;}
.pd-elemental-contained::before{display:none;}
.pd-elemental-contained .pd-elemental-quote{position:static;padding:32px 0 0;}
.pd-elemental-contained .pd-elemental-quote blockquote{color:var(--ivory);}

/* Closing "continue exploring" section, replaces the old bare-bones
   .compare-row (three plain bordered text links). Now a proper small
   moment: the other two models shown as real thumbnails (reusing the same
   thumb-*.jpg already used on the products hub, not new assets) rather than
   text-only links, plus a single clear CTA beneath rather than folded into
   the same row as the product links. */
.pd-continue h2{font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-style:italic;font-weight:400;font-size:clamp(28px,3.4vw,44px);letter-spacing:-.02em;margin:14px 0 48px;}
.pd-continue-grid{display:flex;justify-content:center;gap:32px;flex-wrap:wrap;margin-bottom:44px;}
.pd-continue-card{display:block;width:220px;}
.pd-continue-card img{width:100%;aspect-ratio:1/1;object-fit:cover;background:var(--black);margin-bottom:14px;transition:transform .4s ease;}
.pd-continue-card:hover img{transform:scale(1.03);}
.pd-continue-card span{font-size:12px;letter-spacing:.08em;text-transform:uppercase;border-bottom:1px solid var(--black);padding-bottom:3px;}
.pd-continue-card:hover span{color:var(--copper);border-color:var(--copper);}
.pd-continue-cta{display:inline-block;background:var(--black);color:var(--white);padding:14px 30px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;}
.pd-continue-cta:hover{background:var(--copper);}
@media(max-width:700px){.pd-continue-grid{gap:24px;}.pd-continue-card{width:150px;}}

/* "Continue Exploring" moved to the bottom of the page (below the gallery,
   just above the footer) and enlarged, 2026-09-27 — thumbnails +40%,
   all text in the section +20%. Scoped to .pd-continue specifically (not
   the shared .eyebrow) so this doesn't bleed into the Gallery/Configure
   eyebrows above it. Card width scales the picture; everything else here
   is a font-size-only bump, spacing/padding untouched. */
.pd-continue-card{width:308px;}
.pd-continue h2{font-size:clamp(33.6px,4.08vw,52.8px);}
.pd-continue .eyebrow{font-size:13.2px;}
.pd-continue-card span{font-size:14.4px;}
.pd-continue-cta{font-size:14.4px;}
@media(max-width:700px){.pd-continue-card{width:210px;}}

/* Product gallery, rebuilt 2026-09-28 — was an auto-rotating carousel
   (added 2026-09-09, history below) that hid every angle but one behind
   a slideshow: "Every Angle" as a headline, but the back panel took three
   clicks to reach, and full-amplifier shots shared a fixed frame with the
   much smaller remote-control close-ups. Replaced with a hero image plus
   a thumbnail rail — every angle (front / three-quarter / back / both
   remote finishes) visible at once, click a thumbnail to swap the hero.
   Hero stays the same 820px square stage on the same black backdrop the
   carousel used (source photos are already 1:1 studio shots, so this was
   never actually cropping them — the headroom above the product in some
   shots is baked into the photography itself, not a crop artifact).
   See pd-gallery.js for the swap logic — no more auto-rotate/pause-on-
   hover, since a static rail doesn't need it.

   Prior history (carousel, superseded above): built 2026-09-09 from the
   real FLOW_HIGHRES_OK / REMOTE_FLOW photo set once Marton confirmed that
   folder (not the old, badly color-graded "few usable" one) was the real
   deal. Later that day, tried a black section background matching the
   hero/quote sections — Marton preferred the original white, reverted.
   Widened the stage from 640px to 820px per his request for bigger
   photos — that 820px figure carries over unchanged to the hero below. */
.pd-gallery .eyebrow{margin-bottom:0;}
.pd-gallery-viewer{max-width:820px;margin:36px auto 0;}
.pd-gallery-hero{width:100%;aspect-ratio:1/1;background:var(--black);overflow:hidden;}
.pd-gallery-hero img{width:100%;height:100%;object-fit:cover;display:block;transition:opacity .15s ease;}
.pd-gallery-thumbs{display:flex;justify-content:center;gap:14px;margin-top:20px;flex-wrap:wrap;}
.pd-gallery-thumb{display:flex;flex-direction:column;align-items:center;gap:8px;width:96px;padding:0;border:0;background:none;cursor:pointer;font-family:inherit;}
.pd-gallery-thumb-img{display:block;width:72px;height:72px;background:var(--black);overflow:hidden;border-bottom:2px solid transparent;}
.pd-gallery-thumb-img img{width:100%;height:100%;object-fit:cover;display:block;opacity:.6;transition:opacity .2s ease;}
.pd-gallery-thumb:hover .pd-gallery-thumb-img img{opacity:.85;}
.pd-gallery-thumb.active .pd-gallery-thumb-img{border-bottom-color:var(--copper);}
.pd-gallery-thumb.active .pd-gallery-thumb-img img{opacity:1;}
.pd-gallery-thumb-label{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--grey-text);}
.pd-gallery-thumb.active .pd-gallery-thumb-label{color:var(--black);font-weight:600;}
@media(max-width:700px){
  .pd-gallery-viewer{max-width:100%;}
  .pd-gallery-thumbs{gap:9px;}
  .pd-gallery-thumb{width:74px;}
  .pd-gallery-thumb-img{width:58px;height:58px;}
  .pd-gallery-thumb-label{font-size:9px;}
}

/* ---------- STORY / SUSTAINABILITY ---------- */
.story-block{max-width:720px;margin:0 auto;}
.story-block p{font-size:15.5px;line-height:1.85;color:#3a3a3a;font-family:"Liberation Serif",Georgia,serif;}
.founder-row{display:grid;grid-template-columns:280px 1fr;gap:48px;align-items:center;max-width:900px;margin:64px auto 0;}
.founder-row img{width:100%;filter:grayscale(1);}
.founder-row .fr-name{font-weight:600;font-size:15px;margin-bottom:6px;}
.founder-row .fr-role{font-size:12px;color:var(--grey-text);letter-spacing:.04em;text-transform:uppercase;margin-bottom:16px;}
.founder-row p{font-size:14px;line-height:1.8;color:#4a4a4a;}

.sus-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:40px;max-width:1000px;margin:0 auto;}
.sus-item{padding-top:22px;border-top:1px solid var(--grey-line-light);}
.sus-item h4{margin:0 0 10px;font-size:15px;font-weight:600;}
.sus-item p{margin:0;font-size:13.5px;color:var(--grey-text);line-height:1.7;}

/* ---------- CONTACT ---------- */
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:56px;max-width:1000px;margin:0 auto;}
.contact-grid h4{font-size:12px;letter-spacing:.08em;text-transform:uppercase;margin-bottom:20px;}
.dealer-row{display:flex;justify-content:space-between;padding:15px 0;border-top:1px solid var(--grey-line-light);font-size:13.5px;}
.dealer-row:last-child{border-bottom:1px solid var(--grey-line-light);}
.dealer-row .city{color:var(--grey-text);}
/* Added 2026-09-09 pre-launch, alongside removing the fabricated [Dealer
   name] rows — plain body copy in the same slot, no borders/rows since
   there's nothing tabular to show yet. */
.dealer-note{font-size:13.5px;line-height:1.6;color:var(--grey-text);padding-top:15px;}
.field{width:100%;border:none;border-bottom:1px solid var(--grey-line-light);padding:12px 2px;font-family:inherit;font-size:14px;margin-bottom:18px;background:transparent;}
.field:focus{outline:none;border-color:var(--black);}
textarea.field{resize:vertical;min-height:100px;}
.submit-btn{background:var(--black);color:var(--white);border:none;padding:14px 30px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;}

/* ---------- PAGE HEADER (non-home pages) ---------- */
.page-header{padding:170px 0 60px;text-align:center;background:var(--white);}
.page-header .eyebrow{margin-bottom:16px;}
.page-header h1{font-size:clamp(32px,4.6vw,52px);font-weight:400;margin:0;font-family:"Liberation Serif",Georgia,serif;}
/* Products hub header rebuilt as a full-bleed black moment, 2026-09-08 —
   Marton asked for the products hub to be "grandiose and luxurious, like we
   did with the homepage." The header started as a plain white banner (same
   template as Vision/Sustainability/Contact) sitting on top of the already-
   black grid panel below it — flat and quiet where the homepage uses
   confident, continuous black canvas (.range-top, .flow-craft) with large-
   scale italic serif type as its main grandeur lever, not new imagery.
   Applying that same lever here: .page-header stays scoped to
   .page-products (it's shared with Vision/Sustainability/Contact, which
   keep the plain white version — this rule changes nothing there), painted
   black and pushed up to flow-craft's own display scale (clamp(52px,7.4vw,
   100px) there; matched here) instead of the earlier, much smaller
   clamp(32px,4.6vw,52px) meant for a quiet white banner. Text set to
   Cormorant Garamond italic — the same face used for "Sound, naturally."
   and "relax into the music" — and color flipped to white/copper since the
   ground is now black. Net effect: header + .products-grid-intro +
   .products-grid-panel are all black with no seam between them, reading as
   one continuous canvas from the nav down to the product grid, the same
   way the homepage's opening sections run together. data-nav-theme on this
   div is switched from "light" to "dark" in products/index.html to match
   (see nav-theme.js) — it was "light" for the old white banner; left as
   "light" here would make the white nav text disappear against this new
   black ground. */
/* Photo hero, 2026-09-08 — replaces the flat white/black text-only banner.
   Marton supplied a landscape (mountain, forest slope, and its own water
   reflection all in one frame — graded to match the site's desaturated
   theatrical treatment, same 2.2:1 crop as .theatrical-shot) as the one
   image that represents the whole range rather than a single model, which
   is why it belongs here and not on an individual product page (those each
   keep their own single-element photo: forest/wave/mountain). Text flips
   to white-on-photo; eyebrow and hairline stay copper since that reads on
   both light and dark grounds already used elsewhere on the site.
   Sourced from Wirestock via Magnific.com under a paid subscription
   (Premium/Premium+/Pro) — no attribution credit required per Magnific's
   terms of use at that tier, so no credit line in the markup (was present
   under the earlier free-with-attribution download; removed 2026-09-08 once
   Marton confirmed the subscription). Keep the license/download record on
   file in case it's ever questioned — the terms tie the no-attribution
   right to downloading while subscribed, not to the image itself. Per the
   same terms, this photo must not be run through any AI/ML tool (no
   animating it) — that restriction is separate from the attribution tier
   and still applies. It stays a static image. */
/* Back to the full-bleed overlaid-text hero, 2026-09-08 — the boxed/
   uncropped restructure above was itself rejected: Marton pointed at a
   screenshot of THIS full-bleed version and asked for it back, with only
   the bottom darkening gradient reduced. So this reintroduces object-fit
   cover cropping (image absolutely positioned behind the text, both inside
   .page-header) — a deliberate reversal of the "don't crop" note above,
   made on Marton's explicit instruction, not a regression. object-position
   is biased toward the top so the mountain peak and skyline stay fully in
   frame (matches the "don't clip the peak" fix from the very first pass at
   this layout) while most of the crop comes out of the water at the
   bottom, which is the part of the frame doing the least work.
   The gradient overlay only exists for two jobs now: (1) enough legibility
   under the white/copper text and (2) fading the last few percent to
   rgb(10,10,10) — the site's --black, not pure #000 — so the photo meets
   .products-grid-panel with zero seam (see the z-index/color-match fix
   earlier the same day: the image and overlay need explicit z-index or the
   image silently paints over the overlay).
   Rewritten again the same day — the two-stop version above (transparent
   until 78%, then a steep jump to solid by 92%) still read as a flat black
   bar dropped onto the photo, not a shadow that belongs to it, because a
   straight linear ramp over a short span looks like an edge no matter how
   low the numbers are. Replaced with an 11-stop smoothstep curve (opacity
   0 at 50% down the frame, easing up to 1 at 100%, gentle at BOTH ends —
   see the s-curve math this models: 3x²−2x³) so there's no point along it
   where the rate of darkening changes abruptly; it reads as the photo's
   own falloff into the water rather than a layer sitting on top of it. The
   curve still lands on exactly rgb(10,10,10) at 100% (unchanged) — that
   part isn't the "black line," it's the seam fix, and removing it would
   bring back the hard edge against .products-grid-panel this was built to
   avoid; only the shape of the approach to it changed. object-position
   nudged from 18% to 23%, then to 63.7% (see next note) — a touch more
   sky trimmed off the top each time, peak still fully clears the frame
   (re-checked each time; tip sits at source row ~354, crop line is at
   ~121, well clear).
   Cropped another 10% off the top, 2026-09-08 — "nothing else" per
   Marton, so this holds the bottom edge exactly where it was (still the
   same source row, still the same gradient/seam) and only moves the top
   crop line down. Worked out in source pixels for precision: old crop
   window was rows [21,1021] of the 1090-tall source (aspect-ratio 2.4/1);
   removing the top 10% of that 1000px window shifts the top edge down by
   100px to row 121, leaving [121,1021] — a 900px-tall window, i.e. an
   8/3 (2.667/1) box instead of 2.4/1. object-position recomputed from
   that window via the standard object-fit:cover formula (crop_top =
   (source_h − crop_h) × position) rather than nudged by feel, so the
   bottom edge lands on exactly the same source pixel row as before and
   only the top moves. This is a desktop-only change: on mobile
   (aspect-ratio 1/1 below) the image is relatively wider than the box,
   so object-fit:cover there crops LEFT/RIGHT to fill height, not
   top/bottom — the vertical value of object-position has no effect on
   that layout at all, so mobile's framing is untouched by this edit. */
/* Cropped another 20% vertically, 2026-09-09 — same method as the 10% pass
   above: hold the bottom edge on the exact same source row (still 1021,
   still the same shadow/seam calibration) and only move the top crop line
   down. Previous window was [121,1021], 900px tall; removing 20% of that
   (180px) from the top leaves [301,1021], 720px tall — a 10/3 (3.333/1)
   box instead of 8/3. object-position recomputed the same way: crop_top =
   (source_h − crop_h) × position → 301 = (1090−720) × position, position
   ≈ 81.35%. Checked the peak clears this one too — tip is at source row
   ~354, crop line now at 301, so ~53px of margin instead of the ~130px it
   had before. Tighter than any previous pass, but confirmed clear by
   rendering it, not just by the math. */
.page-products .page-header{position:relative;background:var(--black);color:var(--white);padding:0;max-width:none;overflow:hidden;aspect-ratio:10/3;display:flex;align-items:flex-end;justify-content:center;}
.page-header-photo-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 81.35%;z-index:0;display:block;}
.page-products .page-header::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,
  rgba(10,10,10,0.000) 50%,
  rgba(10,10,10,0.028) 55%,
  rgba(10,10,10,0.104) 60%,
  rgba(10,10,10,0.216) 65%,
  rgba(10,10,10,0.352) 70%,
  rgba(10,10,10,0.500) 75%,
  rgba(10,10,10,0.648) 80%,
  rgba(10,10,10,0.784) 85%,
  rgba(10,10,10,0.896) 90%,
  rgba(10,10,10,0.972) 95%,
  rgb(10,10,10) 100%);}
.page-header-copy{position:relative;z-index:2;text-align:center;padding-bottom:52px;}
.page-products .page-header .eyebrow{color:var(--copper);text-shadow:0 1px 14px rgba(0,0,0,.55);}
.page-products .page-header h1{color:var(--white);font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-style:italic;font-size:clamp(52px,7.4vw,100px);letter-spacing:-.025em;line-height:1;text-shadow:0 2px 22px rgba(0,0,0,.6);}
/* Small copper flourish under the heading — same device as .flow-press
   h2::after on the homepage (a short hairline, not a full rule), reused
   here rather than invented fresh so the two pages share a visual grammar. */
.page-products .page-header h1::after{content:"";display:block;width:36px;height:1px;background:var(--copper);margin:30px auto 0;}
@media (max-width:700px){
  /* Text stays bottom-anchored (not centered/top) specifically so it can't
     collide with the fixed nav, which wraps to two lines on narrow screens
     — see the bounding-box overlap bug caught and fixed earlier the same
     day at a taller mobile aspect-ratio. Kept square-ish here for the same
     reason: enough height that the crop doesn't eat too much of the image
     while the text still sits safely below the nav. */
  .page-products .page-header{aspect-ratio:1/1;}
  .page-header-copy{padding-bottom:36px;}
}

/* Products hub card typography elevated, 2026-09-08 — part of the same
   "grandiose and luxurious" pass as the black header above. .p-card/.p-meta
   are shared with the homepage's own product grid (identical markup, same
   classes, reused on both pages), so this stays scoped to .page-products
   rather than edited on the shared rule — the homepage's own version stays
   exactly as already shipped there. Model name and price nudged up so they
   carry more weight now that the card has no separate tagline line at all
   (see below — the poetic names went through several placements today
   before Marton decided the card just doesn't need them as their own line
   anywhere, on the photo or in the meta block). */
.page-products .p-card .p-meta{padding:30px 34px 4px;}
/* 2026-09-09 — device names ("FLOW One MK2" etc.) briefly went through an
   italic-Cormorant-Garamond pass here to match the hero heading, but the
   hero itself has since switched to bold upright Montserrat (see .pd-hero
   h1 above — Marton's reference + a direct confirmation that the device
   name changes too, not just the tag above it). So this override now just
   drops back to the shared base rule's font (Montserrat, inherited,
   already bold at font-weight:600) — no family/style/weight needed here
   at all, only the size bump stays. Scoped to .page-products only,
   matching every other card tweak on this page: the homepage's shared
   .p-card/.p-meta markup stays untouched. */
.page-products .p-card .p-meta h3{font-size:clamp(24px,2vw,28px);}
.page-products .p-card .p-meta .price{font-size:14px;}
@media (max-width:700px){.page-products .p-card .p-meta{padding:26px 24px 4px;}}

/* Product photo frames shortened 15%, 2026-09-09 — corrected from an
   earlier attempt that shrank the photo WITHIN its unchanged 1:1 frame
   (flex-centered at 85% width/height), which just added black matte
   around each amp. That wasn't the goal: Marton wants less vertical space
   per row so the grid needs less scrolling to see all three products, but
   still wants the photos filling their frames edge-to-edge with no empty
   margin. So this shortens the frame itself instead of shrinking the photo
   inside it: base .p-img is a 1:1 square (shared with the homepage grid,
   untouched there); here it's 1/0.85, i.e. 15% shorter than it is wide,
   with the photo still at width:100%/height:100%/object-fit:cover filling
   that shorter box completely — same crop behavior as before, just less
   of it visible top-to-bottom, and zero matte. */
.page-products .p-card .p-img{aspect-ratio:1/0.85;}

/* Poetic names retired as a standalone line, 2026-09-08 — went from a small
   uppercase tag, to a large italic serif line in the meta block, to an
   overlay on the photo — each pass fixed the specific complaint about the
   previous one, but it never stopped reading as a bolted-on extra element.
   Marton's call: drop it as its own line entirely and fold the same three
   words into the one line that was already there and already worked — the
   CTA — instead of finding it a fourth home. "Explore FLOW One" becomes
   "Explore the Forest", etc., with just the poetic word in copper so it
   still carries a little of that editorial color without needing its own
   slot in the layout. See .view-link .accent below and the CTA text in
   products/index.html. */
.page-products .p-card .view-link .accent{color:var(--copper);}
/* Underline recolored to match, 2026-09-08 — the base .view-link rule
   underlines in white (shared with the homepage grid, untouched there).
   Scoped here so the underline picks up the same copper as the accent word
   instead of clashing white-under-copper. */
.page-products .p-card .p-meta .view-link{border-bottom-color:var(--copper);}

/* Products hub grid panel, fixed 2026-09-08 — Marton flagged an ugly white
   rectangle sitting between the product cards and the footer. Root cause:
   section.tight only sets padding, not a background, so its own 72px of
   top/bottom padding is transparent. That was invisible above the grid
   (the .page-header behind it is white too), but below the grid it sat
   directly on top of the black footer, showing as a stray white band the
   full width of the page. .p-card paints its own black background, but
   only for the card itself — not the section's padding around it.
   Scoped to .products-grid-panel (this section only) rather than changing
   section.tight globally, since that class is also used for light-toned
   spec-table sections on the product detail pages — painting those black
   would have been a much worse mistake than the one being fixed. */
/* padding-top specificity bug, found and fixed 2026-09-08 — a single-class
   rule (.products-grid-panel, specificity 0-1-0) can never beat the
   element+class rule above it (section.tight, specificity 0-1-1), no
   matter what value it sets or how much later it's declared. So every
   earlier pass at shrinking this gap (72px → 40px → 32px on mobile) was
   silently discarded by the cascade — the page was still rendering
   section.tight's original 72px this whole time, which is the actual
   dead space Marton kept pointing at between the hero and the product
   cards. Fixed by scoping with .page-products the same way .page-header
   already is elsewhere in this file, which raises it to 0-2-0 and
   actually wins. Values also cut further now that they're finally live —
   just enough breathing room to keep the top card edge off the header's
   copper hairline, not the 40/32 that was silently never applied. */
.page-products .products-grid-panel{background:var(--black);padding-top:16px;}
@media (max-width:700px){.page-products .products-grid-panel{padding-top:12px;}}

@media (max-width:900px){
  .wrap{padding:0 22px;}
  .grid3, .editorial-grid, .contact-grid, .founder-row, .sus-grid{grid-template-columns:1fr;}
  .craft-band{padding:80px 22px 96px;}
  .craft-grid{grid-template-columns:1fr;gap:48px;}
  .craft-img-main{aspect-ratio:5/4;}
  .craft-side{text-align:center;align-items:center;}
  .craft-copy{margin-left:auto;margin-right:auto;text-align:center;}
  .craft-side .craft-link{margin-bottom:40px;}
  .recognition{padding:72px 22px 88px;}
  .rec-featured .rec-line{font-size:30px;}
  .rec-fade{margin:40px auto;}
  .rec-list{grid-template-columns:1fr;gap:0;}
  /* the desktop 2-up row only makes sense side-by-side — stacked on mobile,
     a short horizontal hairline (echoing `.range-fade`'s shape) marks the
     gap between items instead of the vertical divider. */
  .rec-item + .rec-item{padding-top:32px;margin-top:32px;}
  .rec-item + .rec-item::before{
    top:0;left:50%;bottom:auto;transform:translateX(-50%);
    width:120px;height:1px;background:linear-gradient(90deg, transparent 0%, var(--hairline-on-dark) 50%, transparent 100%);
  }
  /* Nav stays a single fixed-height row (logo left, toggle right) instead
     of stacking — that's the whole point of the hamburger swap. Logo size
     is left untouched here on purpose (still the 26.4px desktop value from
     line ~80): Marton asked specifically to keep it full-size rather than
     shrink it to fit a squeezed link row, as the old layout did. */
  .nav{padding:22px 24px;}
  .nav-toggle{display:flex;}
  .nav .links{
    position:fixed;inset:0 0 auto 0;z-index:1;
    display:flex;flex-direction:column;gap:0;
    padding:104px 32px 40px;
    max-height:100vh;overflow-y:auto;
    background:rgba(10,10,10,.98);
    transform:translateY(-100%);opacity:0;visibility:hidden;
    transition:transform .3s ease,opacity .25s ease,visibility .3s ease;
  }
  .nav.is-open .links{transform:translateY(0);opacity:1;visibility:visible;}
  .nav .links a{display:block;padding:16px 0;border-bottom:1px solid rgba(255,255,255,.14);opacity:1;}
  .nav .links a:last-child{border-bottom:0;}
  .nav-item-dropdown{position:static;}
  body.on-light .nav .links, body.nav-light .nav .links{background:rgba(255,255,255,.98);}
  body.on-light .nav .links a, body.nav-light .nav .links a{border-bottom-color:rgba(0,0,0,.1);}
  /* Pre-existing bug found and fixed 2026-09-08 while checking the products
     hub on mobile: .page-header carries both "page-header" and "wrap"
     classes, and both rules set the full `padding` shorthand at equal
     specificity — so whichever is declared later in the cascade wins the
     whole property, not just the values it changes. .wrap's own mobile
     override (`padding:0 22px`, above) sits later in the file than the base
     `.page-header{padding:170px 0 60px}` rule, so on every page ≤900px wide
     it silently discarded page-header's vertical padding entirely, letting
     the fixed nav (which also grows taller here, stacking to two rows)
     overlap the eyebrow/heading beneath it. This hit every page that shares
     .page-header — Vision, Sustainability, Where to Buy, and the products
     hub — not just the page I was working on. Restoring only padding-top/
     bottom here (not the shorthand) keeps .wrap's horizontal 22px intact
     and clears the taller stacked mobile nav (measured ~96px) with room
     to spare. */
  .page-header{padding-top:128px;padding-bottom:44px;}
  section{padding:70px 0;}
  .founder-row img{max-width:220px;margin:0 auto;}
}

/* dev-only note styling (visible marker for provisional content in this test build) */

/* "The Engineering" cutaway-illustration widget, product pages, 2026-09-27 v3.
   Replaces an earlier "Performance" stat-tile concept (never shipped): raw
   specs invited a losing comparison against real competitors at this price
   (75W/150W, 0.07% THD, 96dB S/N all trail Luxman/Hegel/Accuphase). A line-
   drawing cutaway can't be benchmarked the way a number can — it borrows the
   convention watch/car/camera makers use to show engineering depth without
   competing on a spec sheet.
   PROVISIONAL — dual-mono construction is not yet confirmed with Béla; verify
   before this goes further than a draft. (Top-mounted control count/labeling
   corrected 2026-09-28 per Marton — standby + 2× channel-select on the left,
   2× volume on the right, from his own knowledge of the unit — but still
   worth a sign-off against the actual spec sheet, same as dual-mono.)

   2026-09-28: compacted 20% end to end per Marton's request. Section padding,
   eyebrow, h2 and the diagram's top margin are each ×0.8 explicitly below.
   The diagram's own geometry and its embedded SVG text (.pd-eng-label-title/
   -sub) are NOT touched here — they live inside the SVG's viewBox, so
   shrinking .pd-eng-diagram's max-width by the same 20% (1033px → 826px)
   already scales the whole diagram, callout lines and labels together by
   exactly that amount. Changing the label font-sizes too would double-shrink
   the text on top of the container scaling.

   2026-09-28 (same day, follow-up): label text bumped +15% on top of that
   (13.75px→15.81px title, 13.125px→15.09px sub) per Marton's request to
   make the callout text bigger. This IS a font-size change, so — unlike the
   compaction above — it does not ride along with the container scaling; it
   measurably overflowed the viewBox on 4 of the 8 callouts (worst case,
   "INPUT SELECT & STANDBY", clipped ~14 units past the left edge). Fixed
   the same way as the earlier +40%/+25% overflow: widened the SVG's own
   viewBox symmetrically (1080→1140 units, ±30 each side, in the HTML) and
   rescaled this max-width by the same ratio (826px × 1140/1080 ≈ 872px) so
   the chassis illustration itself stays the same rendered size and only
   the text margin around it grows. Re-verified via measure.js — every
   label's getBBox() now clears the new viewBox edge by 16px+.

   2026-09-28 (same day, second follow-up): another +10% on top of that
   (15.81px→17.39px title, 15.09px→16.6px sub), still per Marton. Same
   overflow risk as last time, so widened the viewBox again (1140→1200
   units, ±30 each side) and rescaled max-width to match (872px ×
   1200/1140 ≈ 918px). A first pass at only ±20/side technically cleared
   the edge but left just ~10px of margin on the tightest label — went
   wider for the same ~16px+ buffer the first overflow fix used, rather
   than ship something that clips on the next font hinting difference.
   Re-verified via measure.js before shipping.

   2026-09-28 (same day, third follow-up): another +10% on top of THAT
   (17.39px→19.13px title, 16.6px→18.26px sub) — third size bump today,
   now ~52% above the original 13.75px/13.125px this section shipped with.
   Widened the viewBox again by the same ±30/side that worked last time
   (1200→1260) and rescaled max-width to match (918px × 1260/1200 ≈
   964px). Re-verified via measure.js — every label clears the new edge.
   Flagged to Marton: at some point diminishing the text/diagram ratio
   like this starts to fight the "restrained" brand voice the rest of the
   page uses — worth deciding on a target size rather than repeat +10%s.

   2026-09-28 (same day, fourth follow-up): another +10% on the label text
   (19.13px→21.04px title, 18.26px→20.09px sub) PLUS two independent
   spacing increases, all in the HTML's <text>/<line> coordinates rather
   than here (this section's own CSS only carries the font-size and the
   viewBox-driven max-width, same division as always):
     - title-to-sub gap within one callout: baseline offsets from the
       dot's y widened from −6/+11 (17px apart) to −7/+13 (20px apart).
     - gap between adjacent callout blocks: measured the three tightest
       pairs (front-display→top-controls on both sides, transformer→
       heatsink on the left) and nudged the SECOND block of each pair
       further away. The leader-line's dot end stays exactly on the real
       component (unchanged x1/y1) — only the text-side end angles
       slightly to reach the moved label, same convention exploded-view
       product diagrams use. The other pairs already had 100px+ of air
       and were left alone. First pass used a uniform 14-unit nudge; actual
       getBBox() measurement showed the right-side and heatsink pairs
       still landing tighter than the left (the underlying component
       anchors aren't evenly spaced to begin with), so those two got
       nudged further (26 and 22 units) to bring all three gaps to a
       comparable ~22–27px.
   Widened the viewBox again for the font growth (1260→1320, ±30/side)
   and rescaled max-width to match (964px × 1320/1260 ≈ 1010px). Verified
   both the horizontal overflow and the new vertical gaps via measure.js
   before shipping.

   2026-09-28 (same day, fifth follow-up): corrected the left-side control
   count from 2 buttons to 3 (standby + channel −/+, per Marton — the
   render actually only had two on that side before this). Relabeled that
   callout "STANDBY & CHANNEL SELECT". The longer string overflowed the
   left edge by ~28 units the moment it rendered — widened the viewBox
   again (1320→1420, ±50/side this time) and rescaled max-width to match
   (1010px × 1420/1320 ≈ 1087px). Also swapped the three diagonal leader
   lines from the previous spacing fix for right-angle "elbow" paths
   (H/V/L segments) per Marton's request — considered keeping them
   diagonal (simpler, one fewer decision) vs. the elbow (reads as a
   circuit trace, matches the schematic style of the rest of the
   diagram) and went with the elbow. Re-verified clearances via
   measure.js before shipping. */
.pd-engineering{background:var(--black);padding:80px 0;}
.pd-engineering .eyebrow{font-size:14.8px;}
.pd-engineering h2{color:var(--white);margin:8px 0 0;font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-weight:400;font-size:clamp(37.7px,4.03vw,51.1px);}
.pd-eng-diagram{max-width:1087px;margin:45px auto 0;}
.pd-eng-diagram svg{width:100%;height:auto;display:block;}
.pd-eng-label-title{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:21.04px;letter-spacing:.14em;fill:var(--copper);}
.pd-eng-label-sub{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:400;font-size:20.09px;letter-spacing:.04em;fill:rgba(255,255,255,.55);}
/* model name under each engineering diagram, 2026-09-28 per Marton — reuses
   the site's .eyebrow voice (uppercase, tracked-out, copper) rather than a
   near-duplicate rule, just with its own top margin off the diagram. */
/* ---- "What's Inside", interactive (2026-09-28) — see pd-engineering.js.
   Draw-in: every stroke etches itself in (pathLength=1 dash trick); fills
   and callout text fade up after. Tour/hover: the active component turns
   pale copper and glows, a soft copper light moves behind it, the rest of
   the drawing drops back, and the readout names it. */
.pd-engineering{position:relative;overflow:hidden;}
.pd-engineering::before{content:"";position:absolute;left:50%;top:52%;width:min(1100px,90vw);height:min(760px,80vh);transform:translate(-50%,-50%);
  background:radial-gradient(ellipse at center,rgba(153,102,50,.10) 0%,rgba(153,102,50,.03) 45%,rgba(0,0,0,0) 70%);pointer-events:none;}
.pd-eng-diagram svg .eng-hit{fill:transparent;stroke:none;pointer-events:all;}
.pd-eng-diagram svg .eng-part,.pd-eng-diagram svg .eng-callout{cursor:pointer;transition:opacity .7s ease;}
.pd-eng-diagram svg .eng-part *{transition:stroke .7s ease,fill .7s ease;}
.pd-eng-diagram svg .eng-part{transition:opacity .7s ease,filter .7s ease;}
.pd-eng-diagram svg .eng-spot{opacity:0;transition:cx 1.1s cubic-bezier(.2,.7,.1,1),cy 1.1s cubic-bezier(.2,.7,.1,1),opacity .8s ease;pointer-events:none;}
.pd-eng-diagram svg.has-active .eng-part:not(.is-active){opacity:.32;}
.pd-eng-diagram svg.has-active .eng-callout:not(.is-active){opacity:.22;}
.pd-eng-diagram svg .eng-part.is-active{filter:drop-shadow(0 0 5px rgba(217,168,105,.75)) drop-shadow(0 0 16px rgba(217,168,105,.35));}
.pd-eng-diagram svg .eng-part.is-active :is(path,line,rect,circle):not(.eng-hit){stroke:#e8bd86;}
.pd-eng-diagram svg .eng-part.is-active circle[r="1.4"]{fill:#e8bd86;}
.pd-eng-diagram svg .eng-callout.is-active .pd-eng-label-title{fill:#e8bd86;}
.pd-eng-diagram svg .eng-callout.is-active .pd-eng-label-sub{fill:rgba(255,255,255,.9);}
.pd-eng-diagram svg .eng-callout.is-active circle{animation:engPulse 1.8s ease-in-out infinite;transform-box:fill-box;transform-origin:center;}
@keyframes engPulse{0%,100%{transform:scale(1);opacity:1;}50%{transform:scale(1.9);opacity:.55;}}
/* draw-in */
.pd-eng-diagram svg.pre-draw :is(path,line,rect,circle,polyline,polygon):not(.eng-hit):not(.eng-spot){stroke-dasharray:1;stroke-dashoffset:1;}
.pd-eng-diagram svg.pre-draw text{opacity:0;}
.pd-eng-diagram svg.pre-draw [fill^="url(#fin"]{fill-opacity:0;}
.pd-eng-diagram svg.pre-draw .eng-callout circle,.pd-eng-diagram svg.pre-draw circle[r="1.4"]{opacity:0;}
.pd-eng-diagram svg.is-drawing :is(path,line,rect,circle,polyline,polygon){transition:stroke-dashoffset 1.6s cubic-bezier(.45,0,.2,1),opacity .8s ease,fill-opacity 1.2s ease;}
.pd-eng-diagram svg.is-drawing text{transition:opacity 1.2s ease 2.2s;}
.pd-eng-diagram svg.is-drawn :is(path,line,rect,circle,polyline,polygon):not(.eng-hit):not(.eng-spot){stroke-dashoffset:0;}
.pd-eng-diagram svg.is-drawn text,.pd-eng-diagram svg.is-drawn .eng-callout circle,.pd-eng-diagram svg.is-drawn circle[r="1.4"]{opacity:1;}
.pd-eng-diagram svg.is-drawn [fill^="url(#fin"]{fill-opacity:1;}
/* readout */
.pd-eng-readout{margin:34px auto 0;max-width:640px;min-height:150px;transition:opacity 1.2s ease;}
.pd-engineering:has(svg.pre-draw:not(.is-drawn)) .pd-eng-readout,.pd-engineering:has(svg.is-drawing) .pd-eng-readout{opacity:0;}
.pd-eng-count{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:12px;letter-spacing:.24em;color:var(--copper);}
.pd-eng-of{color:rgba(255,255,255,.35);margin-left:8px;}
.pd-eng-title{margin:14px 0 8px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:clamp(17px,1.6vw,22px);letter-spacing:.26em;text-transform:uppercase;color:#fff;padding-left:.26em;}
.pd-eng-sub{margin:0;font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-size:18px;color:rgba(255,255,255,.62);}
.pd-eng-readout.is-swapping .pd-eng-title,.pd-eng-readout.is-swapping .pd-eng-sub,.pd-eng-readout.is-swapping .pd-eng-n{animation:engSwap .9s cubic-bezier(.2,.7,.1,1) both;}
.pd-eng-readout.is-swapping .pd-eng-sub{animation-delay:.08s;}
@keyframes engSwap{from{opacity:0;transform:translateY(8px);letter-spacing:.34em;}to{opacity:1;transform:none;}}
/* the glow around the active part can reach past the SVG's viewBox (the
   front display sits right at its top edge) — let it spill instead of
   being cut square; the section itself clips (overflow:hidden). */
.pd-eng-diagram svg{overflow:visible;}
.pd-eng-nav{display:flex;align-items:center;justify-content:center;gap:18px;margin-top:22px;}
.pd-eng-ticks{display:flex;justify-content:center;gap:10px;}
.pd-eng-arrow{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border-radius:50%;
  border:1px solid rgba(255,255,255,.18);background:transparent;color:rgba(255,255,255,.7);cursor:pointer;transition:border-color .4s ease,color .4s ease,background .4s ease;}
.pd-eng-arrow svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;}
.pd-eng-arrow:hover{border-color:var(--copper);color:#e8bd86;background:rgba(153,102,50,.08);}
.pd-eng-arrow:focus-visible{outline:1px solid var(--copper);outline-offset:3px;}
.pd-eng-tick{appearance:none;border:0;background:none;padding:10px 0;width:28px;cursor:pointer;position:relative;}
.pd-eng-tick::after{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:rgba(255,255,255,.25);transition:background .5s ease,transform .5s ease;}
.pd-eng-tick:hover::after{background:rgba(255,255,255,.6);}
.pd-eng-tick.is-active::after{background:var(--copper);transform:scaleY(2);}
.pd-eng-tick:focus-visible{outline:1px solid var(--copper);outline-offset:4px;}
@media (max-width:700px){
  .pd-eng-diagram svg{overflow:visible;}
  .pd-eng-diagram svg .eng-callout{display:none;}
  .pd-eng-readout{margin-top:22px;min-height:130px;padding:0 12px;}
  .pd-eng-title{font-size:15px;letter-spacing:.2em;}
  .pd-eng-sub{font-size:16px;}
  .pd-eng-tick{width:18px;}
  .pd-eng-ticks{gap:7px;}
  .pd-eng-nav{gap:12px;}
  .pd-eng-arrow{width:36px;height:36px;}
}
.pd-eng-model{margin-top:28px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--copper);font-weight:600;}
@media(max-width:700px){
  .pd-engineering{padding:58px 0;}
  .pd-eng-diagram{margin-top:32px;}
}
#configure{scroll-margin-top:80px;}
/* FLOW Three hero (2026-09-28): the Three is the shortest chassis, so at the
   shared bottom-anchored position it sat low with a big gap under THREE.
   Lift the amp — and the horizon line it stands on — on this page only;
   width stays identical to One/Two. */
.pd-hero-short .pd-product{bottom:25vh;}
.pd-hero-short .pd-stage::after{bottom:25vh;}
@media (max-width:900px){.pd-hero-short .pd-product{bottom:26vw;}.pd-hero-short .pd-stage::after{bottom:26vw;}}
/* Hover lift on the amps (2026-09-28, Marton): hero product and the rear-panel
   scene. Uses the standalone `scale` property so it never fights the
   transform-based scroll parallax / entrance reveal already on these
   elements. Mouse/trackpad only (no sticky hover on touch), and off under
   reduced motion. */
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .pd-product img{transition:scale 1.1s cubic-bezier(.2,.7,.1,1);}
  .pd-product:hover img{scale:1.035;}
  .pd-rear-amp{transition:opacity 2.2s ease .25s, transform 2.6s cubic-bezier(.2,.7,.1,1) .25s, filter 2.6s ease .25s, scale 1.1s cubic-bezier(.2,.7,.1,1) 0s;}
  .pd-rear-amp:hover{scale:1.04;}
}

/* ---------- SPECIFICATION, reimagined (2026-09-28) ----------
   Was a white two-column table (grey label / serif value) that read like a
   data sheet. Now a dark spec plate in the site's premium register: the
   model's own logotype heads it, nine figures sit in a 3×3 grid of hairline
   cells — small copper label, clean Montserrat value, secondary detail in a
   muted line beneath — and it closes on the price + audition CTA, echoing
   the hero bar. Same position on all three pages (after the gallery). */
.pd-spec{background:#000;color:#fff;padding:110px 0 100px;}
.sp-head{display:flex;align-items:flex-end;justify-content:space-between;gap:32px;padding-bottom:34px;border-bottom:1px solid rgba(153,102,50,.55);}
.sp-eyebrow{margin:0;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:12px;letter-spacing:.32em;text-transform:uppercase;color:var(--copper);}
.sp-logo{height:clamp(22px,2.1vw,32px);width:auto;display:block;}
.sp-grid{margin:0;display:grid;grid-template-columns:repeat(3,1fr);}
.sp-cell{padding:38px 40px 38px 0;border-bottom:1px solid rgba(255,255,255,.1);}
.sp-cell:not(:nth-child(3n+1)){padding-left:40px;border-left:1px solid rgba(255,255,255,.1);}
.sp-cell dt{margin:0 0 14px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:600;font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:rgba(176,122,66,.95);}
.sp-cell dd{margin:0;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:400;font-size:clamp(17px,1.35vw,21px);line-height:1.4;letter-spacing:.01em;color:#fff;font-variant-numeric:lining-nums;}
.sp-cell dd span{display:block;margin-top:8px;font-family:"Liberation Serif",Georgia,serif;font-style:italic;font-size:15px;letter-spacing:0;color:rgba(255,255,255,.5);}
.sp-foot{display:flex;align-items:center;justify-content:space-between;gap:32px;padding-top:44px;}
.sp-price{margin:0;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-weight:500;font-size:28px;letter-spacing:.05em;font-variant-numeric:lining-nums;}
.sp-price span{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,255,255,.5);margin-right:10px;vertical-align:middle;}
.pd-spec .pd-cta-primary{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:11.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;text-decoration:none;transition:background .3s ease;}
@media (max-width:900px){
  .pd-spec{padding:72px 0 64px;}
  .sp-grid{grid-template-columns:1fr 1fr;}
  .sp-cell,.sp-cell:not(:nth-child(3n+1)){padding:26px 18px 26px 0;border-left:0;}
  .sp-cell:nth-child(2n){padding-left:18px;border-left:1px solid rgba(255,255,255,.1);}
  .sp-foot{flex-direction:column;align-items:flex-start;gap:22px;}
}
@media (max-width:520px){
  .sp-grid{grid-template-columns:1fr;}
  .sp-cell:nth-child(2n){padding-left:0;border-left:0;}
  .sp-head{align-items:flex-start;flex-direction:column;gap:16px;}
}

/* Spec switched to a single vertical list (2026-09-28, Marton — easier to
   scan and compare page to page than the 3×3 grid). Narrow, centred column
   so each label stays close to its value. Overrides the grid rules above. */
.pd-spec .wrap{max-width:860px;}
.sp-grid{display:block;}
.sp-cell,.sp-cell:not(:nth-child(3n+1)){display:grid;grid-template-columns:230px 1fr;gap:32px;align-items:baseline;padding:24px 0;border-left:0;}
.sp-cell dt{margin:0;}
@media (max-width:900px){.sp-cell,.sp-cell:not(:nth-child(3n+1)),.sp-cell:nth-child(2n){grid-template-columns:1fr;gap:8px;padding:20px 0;border-left:0;}}

/* Continue Exploring: model logotypes instead of typed names (white PNGs
   inverted to black on this light section), and the audition CTA in the
   same Montserrat tracked caps as the hero/spec buttons. */
.pd-continue-card span.pd-continue-name{display:inline-flex;align-items:center;gap:14px;border:0;padding:0;margin-top:14px;font-size:inherit;}
.pd-continue-name img{height:22px;width:auto;margin:0;aspect-ratio:auto;background:none;filter:invert(1);transition:filter .3s ease;}
.pd-continue-card:hover .pd-continue-name img{transform:none;filter:invert(40%) sepia(60%) saturate(500%) hue-rotate(350deg) brightness(.9);}
.pd-continue-name i{font-style:normal;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:22px;line-height:1;color:var(--copper);transition:transform .3s ease;}
.pd-continue-card:hover .pd-continue-name i{transform:translateX(4px);}
.pd-continue-cta{font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:11.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  padding:17px 32px;background:#0a0a0a;color:#fff;border:1px solid var(--copper);text-decoration:none;transition:background .3s ease;}
.pd-continue-cta:hover{background:var(--copper);color:#fff;}
@media(max-width:700px){.pd-continue-name img{height:17px;}}

/* Compact spec (2026-09-28, Marton: didn't fit on one screen) — ~35% shorter. */
.pd-spec{padding:64px 0 56px;}
.sp-head{padding-bottom:20px;}
.sp-logo{height:clamp(20px,1.7vw,26px);}
.sp-cell,.sp-cell:not(:nth-child(3n+1)){padding:13px 0;}
.sp-cell dd{font-size:clamp(15.5px,1.15vw,18px);line-height:1.35;}
.sp-cell dd span{display:inline;margin:0 0 0 12px;font-size:14px;}
.sp-foot{padding-top:26px;}
.sp-price{font-size:24px;}
@media (max-width:900px){.sp-cell,.sp-cell:not(:nth-child(3n+1)),.sp-cell:nth-child(2n){padding:12px 0;gap:4px;}.sp-cell dd span{display:block;margin:4px 0 0;}}

/* Nav scrim darker (2026-09-28): near-solid black behind the logo/links,
   then a shorter fade — it read as a grey band over light sections. */
.nav::before{background:linear-gradient(180deg,rgba(0,0,0,.93) 0%,rgba(0,0,0,.78) 55%,rgba(0,0,0,0) 100%);}

/* "Specification" set as a heading, not an eyebrow — it matched the copper
   row labels and blended in. Same italic serif as "What's Inside". */
.pd-spec .sp-eyebrow{font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-style:italic;font-weight:400;text-transform:none;letter-spacing:-.01em;color:#fff;font-size:clamp(30px,2.8vw,40px);line-height:1;}

/* Configurator · name-origin card on the two Signature colours (hover on
   desktop, tap on touch). Dark card with a copper hairline over the light
   panel; anchored to the swatch's left edge so it never runs off-screen. */
.swatch.has-tip{position:relative;}
.sw-tip{position:absolute;left:-12px;bottom:calc(100% + 16px);z-index:20;width:320px;max-width:calc(100vw - 40px);padding:20px 22px 22px;text-align:left;background:#0a0a0a;border:1px solid rgba(153,102,50,.6);box-shadow:0 26px 50px rgba(0,0,0,.35);
  display:flex;flex-direction:column;gap:0;pointer-events:none;opacity:0;visibility:hidden;transform:translateY(8px);transition:opacity .35s ease,transform .5s cubic-bezier(.2,.7,.1,1),visibility 0s linear .35s;font-weight:400;}
.sw-tip::after{content:"";position:absolute;top:100%;left:24px;width:10px;height:10px;margin-top:-5px;background:#0a0a0a;border-right:1px solid rgba(153,102,50,.6);border-bottom:1px solid rgba(153,102,50,.6);transform:rotate(45deg);}
.sw-tip-eye{margin:0 0 9px;font-family:"Montserrat",sans-serif;font-size:9.5px;font-weight:600;letter-spacing:.3em;text-transform:uppercase;color:var(--copper);}
.sw-tip-t{margin:0 0 10px;font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-size:26px;line-height:1.05;color:#fff;}
.sw-tip-t em{font-style:italic;color:#e8bd86;}
.sw-tip-d{font-family:"Montserrat",sans-serif;font-size:12.5px;line-height:1.7;color:rgba(255,255,255,.72);letter-spacing:0;}
@media (hover:hover) and (pointer:fine){.swatch.has-tip:hover .sw-tip{opacity:1;visibility:visible;transform:none;transition-delay:0s;}}
.swatch.has-tip:focus-visible .sw-tip,.swatch.has-tip.tip-on .sw-tip{opacity:1;visibility:visible;transform:none;transition-delay:0s;}
.swatch.tip-below .sw-tip{bottom:auto;top:calc(100% + 16px);}
.swatch.tip-below .sw-tip::after{top:auto;bottom:100%;margin:0 0 -5px;transform:rotate(225deg);}

/* Configurator heading — 2026-10-01 */
.pd-configure-head{text-align:center;margin:0 auto 44px;max-width:760px;}
.pd-configure-head .pd-configure-eyebrow{margin-bottom:18px;}
.pd-configure-title{margin:0;font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-weight:400;font-size:clamp(42px,4.6vw,72px);line-height:1;letter-spacing:-.015em;color:var(--black);}
.pd-configure-title em{font-style:italic;color:var(--copper);}
.pd-configure-sub{margin:20px auto 0;max-width:560px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:clamp(14.5px,1.05vw,16.5px);line-height:1.75;color:var(--grey-text);}

/* Gallery heading — 2026-10-01 */
.pd-gallery .pd-gallery-title{margin:14px 0 0;font-family:"Cormorant Garamond","Liberation Serif",Georgia,serif;font-weight:400;font-size:clamp(42px,4.6vw,72px);line-height:1;letter-spacing:-.015em;}
.pd-gallery-title em{font-style:italic;color:var(--copper);}
.pd-gallery-sub{margin:18px auto 0;max-width:520px;font-family:"Montserrat",Helvetica,Arial,sans-serif;font-size:clamp(14.5px,1.05vw,16.5px);line-height:1.75;color:var(--grey-text);}

/* Inside FLOW readout — the text travels in the direction of the tour, and a
   copper bar glides along the ticks from one component to the next */
.pd-eng-readout.is-swapping[data-dir="fwd"] .pd-eng-title,.pd-eng-readout.is-swapping[data-dir="fwd"] .pd-eng-sub,.pd-eng-readout.is-swapping[data-dir="fwd"] .pd-eng-n{animation-name:engSwapFwd;}
.pd-eng-readout.is-swapping[data-dir="back"] .pd-eng-title,.pd-eng-readout.is-swapping[data-dir="back"] .pd-eng-sub,.pd-eng-readout.is-swapping[data-dir="back"] .pd-eng-n{animation-name:engSwapBack;}
@keyframes engSwapFwd{from{opacity:0;transform:translateX(-34px);}to{opacity:1;transform:none;}}
@keyframes engSwapBack{from{opacity:0;transform:translateX(34px);}to{opacity:1;transform:none;}}
.pd-eng-ticks{position:relative;}
.pd-eng-glide{position:absolute;top:50%;height:2px;margin-top:-1px;left:0;width:28px;background:var(--copper);box-shadow:0 0 10px rgba(232,189,134,.6);pointer-events:none;transition:left .85s cubic-bezier(.65,0,.25,1),width .85s cubic-bezier(.65,0,.25,1);}
.pd-eng-ticks.has-glide .pd-eng-tick.is-active::after{background:rgba(255,255,255,.25);transform:none;}

/* Configure header centred in its white band (2026-10-02): equal space above
   the eyebrow and below the headline, instead of ~112px above / 44px below. */
section#configure.tight{padding-top:54px;}
#configure .pd-configurator{margin-top:0;}
#configure .pd-configure-head{margin-bottom:64px;}
@media (max-width:900px){section#configure.tight{padding-top:34px;}#configure .pd-configure-head{margin-bottom:44px;}}
