/** Shopify CDN: Minification failed

Line 1270:20 Expected identifier but found whitespace
Line 1270:62 Unexpected "/"

**/
/* Home — sparse spatial canvas with floating "instruments".
 *
 * Two-screen layout:
 *   Screen 1 (.stage)    — current line: POVA 8, Curve 02, POVA 7 Pro
 *   Screen 2 (.lineage)  — older line: Curve gen 1, POVA 7, 6 Pro, 5 Pro
 *
 * The user scrolls past the first viewport to discover the lineage
 * — the hero stays uncluttered, glance-test friendly. */

.home {
  position: relative;
  /* 100dvh = dynamic viewport height — accounts for mobile browser
   * address bar collapsing. Without it on iOS Safari / Android Chrome
   * the page falsely measures itself as 100vh of "address-bar-visible"
   * state, then when the bar collapses the bottom of the hero copy is
   * clipped behind the browser chrome. dvh follows live. */
  min-height: 100dvh;
  width: 100vw;
  overflow-x: hidden;
}

/* Stage — the first viewport. position: relative so instruments
 * resolve their percentage-based tops against the stage box itself,
 * and so the lineage section flows naturally below it. */
.stage {
  position: relative;
  width: 100%;
  height: 100dvh;
  min-height: 100dvh;
}

/* Each product card is absolutely positioned at viewport-% coords.
 * Hovering drives the halo + ticker via [data-product] attribute. */
.instrument {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  cursor: pointer;
  text-decoration: none;
  color: var(--pova-white);
  /* slight float baseline + idle drift */
  animation: float 8s var(--ease-in-out) infinite;
  transition: transform var(--t-med) var(--ease-out), filter var(--t-med) var(--ease-out);
  will-change: transform;
}
.instrument:nth-child(2) { animation-delay: -2s; animation-duration: 9s; }
.instrument:nth-child(3) { animation-delay: -4s; animation-duration: 7.5s; }
.instrument:nth-child(4) { animation-delay: -6s; animation-duration: 10s; }

@keyframes float {
  0%, 100% { transform: translate(-50%, -50%) translateY(0px); }
  50%      { transform: translate(-50%, -50%) translateY(-14px); }
}

.instrument:hover,
.instrument:focus-visible {
  filter: brightness(1.05);
  z-index: 10;
}

/* Satellites (everything except the hero) sit ABOVE the hero at every
 * state. The hero's bounding box at desktop is 870×743 and fully
 * encloses the Curve top-left satellite. Without an explicit stack
 * order, the hero's own :hover (z:10) covers the satellites and steals
 * their clicks. Pinning satellites at z:12 (rest) and z:20 (hover)
 * guarantees they're always reachable. */
.instrument[data-pos="tl"],
.instrument[data-pos="tr"],
.instrument[data-pos="br"],
.instrument[data-pos^="legacy-"] { z-index: 12; }
.instrument[data-pos="tl"]:hover,
.instrument[data-pos="tl"]:focus-visible,
.instrument[data-pos="tr"]:hover,
.instrument[data-pos="tr"]:focus-visible,
.instrument[data-pos="br"]:hover,
.instrument[data-pos="br"]:focus-visible,
.instrument[data-pos^="legacy-"]:hover,
.instrument[data-pos^="legacy-"]:focus-visible { z-index: 20; }
.instrument:hover .inst-photo,
.instrument:hover .inst-silhouette,
.instrument:focus-visible .inst-photo,
.instrument:focus-visible .inst-silhouette {
  transform: scale(1.04);
}

/* Photo / silhouette container */
.inst-photo,
.inst-silhouette {
  display: block;
  transition: transform var(--t-slow) var(--ease-out), filter var(--t-med) var(--ease-out);
}

/* Real product photo — transparent PNGs, drop straight onto the field
 * with a soft shadow for lift. No blend mode (renders are pre-isolated). */
.inst-photo {
  height: var(--inst-size, 280px);
  width: auto;
  object-fit: contain;
  filter: drop-shadow(0 40px 60px rgba(0, 0, 0, 0.55));
  transition: filter var(--t-med) var(--ease-out), transform var(--t-slow) var(--ease-out);
}
.instrument:hover .inst-photo {
  filter: drop-shadow(0 50px 80px rgba(0, 0, 0, 0.7));
}

/* SVG silhouette — for products without a photo */
.inst-silhouette {
  height: var(--inst-size, 220px);
  width: auto;
}
.inst-silhouette path,
.inst-silhouette rect,
.inst-silhouette circle {
  fill: #1a1a1a;
  stroke: rgba(255, 255, 255, 0.10);
  stroke-width: 1;
}
.inst-silhouette .accent {
  fill: rgba(255, 255, 255, 0.04);
}

/* Mobile-only elements (Figma phone spec): header control squares and the
 * phone variants of the label texts. Hidden on desktop; the ≤600 block
 * flips them on and hides the desktop variants. */
.mhdr { display: none; }
.name--m, .meta--m, .txt--m { display: none; }

/* Theme-swapped media: two <picture>s per themed image slot (POVA 8 hero,
 * footer wordmark). display:none removes the inactive one from flow entirely
 * (picture is display:contents), so the toggle swaps assets with zero flash
 * and no layout shift. */
[data-theme="black"] .themed--white { display: none; }
[data-theme="white"] .themed--black { display: none; }

/* Inline label below each instrument — appears on hover */
.inst-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-out);
  pointer-events: none;
}
.instrument:hover .inst-label,
.instrument:focus-visible .inst-label,
.instrument.is-tapped .inst-label {
  opacity: 1;
  transform: translateY(0);
}
.instrument:focus-visible {
  outline: 2px solid var(--pova-orange);
  outline-offset: 12px;
  border-radius: 8px;
}
/* Touch devices: kill the focus-visible outline. Some mobile browsers
 * fire :focus-visible on tap, which made the instrument look like it
 * had a big orange "selector box" around it after a tap. The tap
 * pulse (.is-tapped) and the field halo color shift already give
 * touch feedback without needing the outline. */
@media (hover: none), (pointer: coarse) {
  .instrument:focus-visible,
  .instrument:focus { outline: none; }
}
.inst-label .name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: 0.04em;
}
.inst-label .meta {
  font-family: var(--font-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.3em;
  opacity: 0.7;
  white-space: nowrap;
}

/* Layout — POVA 8 sits dead-centre as the singular subject; Curve 02
 * and 7 Pro orbit it as satellites. Hierarchy by size and stillness:
 * the hero is the gravity well, everything else floats around it. */

/* hero = POVA 8 — centered. Dominant scale, page's focal point.
 * Sized large to compensate for the 3/4 render's loose crop (the phone
 * subject only occupies ~40% of the source canvas). max-height keeps
 * clearance above the top wordmark and below the hero copy. */
.instrument[data-pos="hero"] { left: 50%; top: 50%; transform: translate(-50%, -50%); --inst-size: 1100px; }
.instrument[data-pos="hero"] .inst-photo { max-width: none; max-height: 78vh; }
.instrument[data-pos="hero"]:hover { transform: translate(-50%, -50%); }
.instrument[data-pos="hero"]:hover .inst-photo { transform: scale(1.03); }

/* Buds — floating accent image to the LEFT of the centre POVA 8 */
.stage-buds {
  position: absolute;
  left: 18%;
  top: 38%;
  transform: translate(-50%, -50%);
  z-index: 11;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  user-select: none;
  /* Float like the phone instruments (the @keyframes keeps the centering) */
  animation: float 9s var(--ease-in-out) -3s infinite;
}
.stage-buds img {
  height: clamp(180px, 32vh, 340px);
  width: auto;
  display: block;
}
/* Hover/focus reveals the label, exactly like the phone instruments */
.stage-buds:hover .inst-label,
.stage-buds:focus-visible .inst-label {
  opacity: 1;
  transform: translateY(0);
}
.stage-buds:focus-visible { outline: 2px solid var(--pova-orange); outline-offset: 12px; border-radius: 8px; }
@media (max-width: 800px) {
  .stage-buds { left: 16%; top: 34%; }
  .stage-buds img { height: 20vh; }
}

/* tr = POVA Curve 02 — top-right satellite, orbiting the hero */
.instrument[data-pos="tr"] { left: 84%; top: 26%; transform: translate(-50%, -50%); --inst-size: 260px; }
.instrument[data-pos="tr"]:hover { transform: translate(-50%, -50%); }
.instrument[data-pos="tr"]:hover .inst-photo { transform: scale(1.04); }

/* br = POVA 7 Pro — bottom-right satellite. Right-side satellites
 * (tr + br) bracket the hero on its right; manifesto copy occupies
 * the left so the composition stays balanced and uncollided. */
.instrument[data-pos="br"] { left: 84%; top: 74%; transform: translate(-50%, -50%); --inst-size: 260px; }
.instrument[data-pos="br"]:hover { transform: translate(-50%, -50%); }
.instrument[data-pos="br"]:hover .inst-photo { transform: scale(1.04); }

/* Hero copy — bottom-left, pinned to the first viewport. Absolute
 * inside .stage so it scrolls away when the user reveals the lineage,
 * instead of stickying over the second screen. */
.hero-copy {
  position: absolute;
  bottom: 60px;
  left: 80px;
  z-index: 50;
  max-width: 460px;
  font-family: var(--font-serif);
  font-weight: 200;
  font-size: 17px;
  line-height: 1.5;
  color: var(--pova-white);
  opacity: 0.95;
}
.hero-copy .label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: 18px;
  color: var(--pova-orange);
}
.hero-copy .tagline {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.0;
  letter-spacing: -0.02em;
  margin: 0 0 18px;
  max-width: 14ch;
  color: var(--pova-white);
  opacity: 1;
}
.hero-copy p {
  font-family: var(--font-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.5;
  margin: 0;
}

/* (.nav-pill rules moved to chrome.css — shared across home + product pages) */

/* Smaller screens — keep the centered-hero composition, scale satellites. */
@media (max-width: 1100px) {
  .instrument[data-pos="hero"] { --inst-size: 460px; left: 50%; top: 50%; }
  .instrument[data-pos="tr"]   { --inst-size: 240px; left: 84%; top: 28%; }
  .instrument[data-pos="br"]   { --inst-size: 170px; left: 84%; top: 76%; }
  .hero-copy { left: 40px; bottom: 40px; }
}
@media (max-width: 900px) {
  .instrument[data-pos="hero"] { --inst-size: 380px; }
  .instrument[data-pos="tr"]   { --inst-size: 200px; left: 84%; top: 26%; }
  .instrument[data-pos="br"]   { --inst-size: 140px; left: 84%; top: 78%; }
}
/* Mobile — version-priority constellation.
 *   01 / POVA 8       — newest, hero, top-centre, biggest
 *   02 / POVA Curve 02 — most important launch of the year, follows
 *                        POVA 8 in size and prominence. Sits below + to
 *                        the side as a clear second hero.
 *   03 / POVA 7 Pro   — older numbered, small bottom satellite
 *   04 / POVA Curve   — oldest, smallest bottom satellite */
/* Mobile constellation — all four products stay clear of:
 *   • Top strip (chrome: cart pill, about pill, wordmark, comp number)
 *   • Bottom-left text strip (hero copy)
 * Hierarchy: POVA 8 dominant, Curve 02 close second, 7 Pro + Curve tiny. */
/* Mobile constellation — strict no-overlap zones.
 *  Top  0-12%  : chrome only
 *  Hero 14-50% : POVA 8 alone, centred
 *  Mid  56-78% : Curve 02 alone, right
 *  Bot  84-96% : 7 Pro corner satellite (right)
 *  Side mid-left: Curve gen 1 (small, tucked) */
@media (max-width: 700px) and (min-width: 601px) {
  /* 601-700px sliver keeps the floating constellation; true phones (≤600)
   * get the Figma-spec stacked layout in the block further down. */
  .instrument[data-pos="hero"] { display: flex; --inst-size: 320px; left: 50%; top: 34%; }
  .instrument[data-pos="hero"] .inst-photo { max-width: 100vw; }
  .instrument[data-pos="tr"]   { display: flex; --inst-size: 120px; left: 78%; top: 60%; }
  /* Satellites: drop max-width: 96vw — the wrapper's --inst-size
   * already controls width via .inst-photo's natural aspect ratio.
   * The 96vw override let the image scale beyond its wrapper on
   * narrow screens, pushing the right edge of the Curve 02 satellite
   * off the viewport. Wrapper-based sizing keeps it on-screen. */
  .instrument[data-pos="br"]   { display: flex; --inst-size: 100px; left: 78%; top: 82%; }
  /* Hero copy — box hugs the actual text (left column) so the 7 Pro
   * satellite on the right never sits inside its hit-box. */
  .hero-copy { left: 20px; right: auto; bottom: 80px; max-width: 66%; }
  .hero-copy .tagline { font-size: clamp(28px, 8vw, 38px); max-width: 12ch; }
  /* Labels — static captions on phones (the hover:none rule reveals them).
   * Desktop hover metrics wrap the long mono meta line into a one-character-
   * wide column inside the 26vw cap; here they get phone metrics instead:
   * word-wrap on spaces, tighter tracking, readable at satellite size. */
  .inst-label { max-width: 34vw; }
  .inst-label .name { font-size: 12px; letter-spacing: 0.06em; white-space: nowrap; overflow-wrap: normal; }
  .inst-label .meta { font-size: 8px; letter-spacing: 0.14em; white-space: normal; overflow-wrap: normal; line-height: 1.5; }
}
/* Landscape phones / very short viewports — the portrait constellation
 * assumes vertical room; sideways it shoved the headline under the hero
 * render and clipped the top satellite. Compress: hero left-of-centre,
 * satellites right, copy bottom-left, everything inside one screen. */
@media (max-height: 500px) and (max-width: 1000px) {
  .instrument[data-pos="hero"] { --inst-size: 220px; left: 42%; top: 46%; }
  .instrument[data-pos="hero"] .inst-photo { max-height: 70vh; }
  .stage-buds { left: 13%; top: 42%; }
  .stage-buds img { height: 34vh; }
  .instrument[data-pos="tr"]   { --inst-size: 90px; left: 70%; top: 40%; }
  .instrument[data-pos="br"]   { --inst-size: 80px; left: 88%; top: 46%; }
  .hero-copy { left: 20px; right: auto; bottom: 20px; max-width: 44%; }
  .hero-copy .tagline { font-size: 24px; max-width: 16ch; }
  .hero-copy .label { margin-bottom: 8px; }
}
/* Responsive fix: the satellite product labels were unwrapped, so their text
   widened past the viewport and forced the whole page wide (the mobile
   zoom-out). Constrain + wrap them. Positions, sizes, content, arrangement
   are all unchanged. */
@media (max-width: 1100px){
  .inst-label{ max-width: 26vw; }
  .inst-label .name, .inst-label .meta{ white-space: normal; overflow-wrap: anywhere; }
}
/* Touch devices: reveal product labels by default since hover doesn't apply.
 * Also kill the float animation on touch — battery-friendly, and mobile
 * already reads the field as static. */
@media (hover: none) {
  .inst-label { opacity: 0.85; transform: none; }
  .instrument, .stage-buds { animation: none; }
  .stage-buds .inst-label { opacity: 0.85; transform: none; }
}

/* ----------------------------------------------------------------------
 * Kinetic full-bleed typographic statement — sits on top of the field
 * but behind the floating instruments. FH Lecturis at display-xl scale,
 * scroll-scrubbed parallax. The brand says itself before it shows itself.
 * (Per critic § "What Would Make This Awwwards-Worthy" item 3.)
 * ---------------------------------------------------------------------- */
.kinetic-statement,
.kinetic-statement.scroll-parallax {
  position: absolute;
  bottom: 18%;
  left: 50%;
  margin: 0;
  transform: translateX(-50%) translate3d(0, var(--parallax-y, 0), 0);
  z-index: 0;                     /* sits BEHIND every floating instrument */
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(56px, 12vw, 220px);
  letter-spacing: -0.04em;
  line-height: 0.92;
  color: var(--pova-white);
  opacity: 0.12;                  /* visible — wave 2 was 0.06 (a ghost) */
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  text-transform: none;
  /* Subtle drop shadow so the lockup separates from the field grid even
   * at low opacity, without lifting the contrast off-brand. */
  text-shadow: 0 8px 40px rgba(0, 0, 0, 0.4);
}
@media (max-width: 900px) {
  .kinetic-statement {
    bottom: 10%;
    font-size: clamp(46px, 18vw, 120px);
  }
}
@media (max-width: 600px) {
  /* Wave 2 hid this on mobile — but the kinetic statement is the brand
   * landing. Bring it back at a smaller scale, lower opacity, repositioned
   * above the bottom hero copy block so it never collides. */
  .kinetic-statement {
    display: block;
    bottom: auto;
    top: 12%;
    font-size: clamp(40px, 14vw, 72px);
    opacity: 0.10;
    white-space: nowrap;
  }
}
@media (prefers-reduced-motion: reduce) {
  .kinetic-statement { transform: translateX(-50%) !important; }
}

/* ============================================================
 * Scroll cue — bottom-centre of the stage. Mono caption + thin
 * vertical rule that drops on a slow loop. Affordance only —
 * the rest of the homepage tells you to look down by being
 * shorter than the document.
 * ============================================================ */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  z-index: 60;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--pova-white);
  opacity: 0.55;
  transition: opacity var(--t-med) var(--ease-out);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.3em;
}
.scroll-cue:hover,
.scroll-cue:focus-visible { opacity: 1; outline: none; }
.scroll-cue-rule {
  display: block;
  width: 1px;
  height: 36px;
  background: linear-gradient(to bottom, transparent, var(--pova-white) 40%, transparent);
  animation: scroll-cue-drop 2.6s var(--ease-in-out) infinite;
}
.scroll-cue-text { white-space: nowrap; }
@keyframes scroll-cue-drop {
  0%   { transform: translateY(-6px); opacity: 0.2; }
  50%  { transform: translateY(2px);  opacity: 0.8; }
  100% { transform: translateY(10px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue-rule { animation: none; opacity: 0.6; }
}
@media (max-width: 700px) {
  /* Scroll-cue on mobile — was at bottom:100 which collided with the
   * H1 (now at bottom:80, wrapping to ~3 lines). Drop it to bottom:24
   * inside the trust-ribbon zone, AND drop the vertical rule so it's
   * just the "↓ THE LINE SO FAR" label sitting cleanly between the
   * H1 and the trust-ribbon. */
  .scroll-cue { bottom: 24px; font-size: 9px; letter-spacing: 0.25em; }
  .scroll-cue-rule { display: none; }
  /* Hidden when there's a trust-ribbon overlap risk on the tiniest
   * viewports; trust-ribbon is the more important brand element. */
}
/* (The old ≤420 scroll-cue hide is gone — the Figma phone spec shows the
 * cue, and the ≤600 block above places it in-flow below the manifesto.) */

/* ============================================================
 * LINEAGE BAND — second viewport. Older POVA devices live here in
 * a clean horizontal rail, revealed when the user scrolls past the
 * hero. Same black field continues; just a quieter density.
 * ============================================================ */
.lineage {
  position: relative;
  width: 100%;
  /* min-height: 100vh + justify-content: center was forcing the section
   * to fill the viewport even when its content was shorter — that created
   * a big empty band below the row that made the "How we got here" title
   * appear to crowd the top chrome on scroll and pushed the footer way
   * down the page. Let the section be content-height with normal padding. */
  padding: 120px 80px 100px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 64px;
}

.lineage-header {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.lineage-header .label {
  display: block;
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  opacity: 0.55;
}
.lineage-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--pova-white);
}
.lineage-sub {
  font-family: var(--font-serif);
  font-weight: 200;
  font-size: 17px;
  line-height: 1.5;
  margin: 0;
  opacity: 0.65;
  max-width: 540px;
}

/* Lineage row — editorial scatter, NOT a comparison grid. Each item
 * lives at its own y-baseline, its own scale, its own slight tilt.
 * No card frames, no equal alignment. The eye trips across the
 * row instead of sliding down it. Brutal, not corporate. */
/* Lineage row — chronological progression band, NOT a memorial scatter.
 * Brand book §6: "Built to evolve — every new product should feel like
 * progress, not a repeat." Phones share a baseline, scale grows left→right
 * (older→newer), a thin orange spine connects them as a timeline. Reads as
 * a series moving forward, not products laid to rest. */
.lineage-row {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  align-items: end;
  min-height: 420px;
  padding: 32px 0 56px;
}
/* Progression spine removed — phones now read on their own without the orange hairline. */
.lineage-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  color: var(--pova-white);
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 0;
  transition: transform var(--t-med) var(--ease-out), filter var(--t-med) var(--ease-out), opacity var(--t-med) var(--ease-out);
  opacity: 0.95;
  filter: saturate(1);
  min-height: 0;
  gap: 16px;
}
/* Year-tick removed — phones read on their own without the orange dot. */
.lineage-item::after { content: none; }
/* Progressive scale — older on the left (smaller), newer on the right
 * (slightly larger). Subtle, not theatrical. All on the same baseline. */
.lineage-item[data-product="pova-5-pro"] { transform: scale(0.95); }
.lineage-item[data-product="pova-6-pro"] { transform: scale(0.98); }
.lineage-item[data-product="pova-curve"] { transform: scale(1.02); }
.lineage-item[data-product="pova-7"]     { transform: scale(1.05); }

.lineage-item:hover,
.lineage-item:focus-visible {
  opacity: 1;
  outline: none;
}
.lineage-item[data-product="pova-5-pro"]:hover { transform: scale(0.97); }
.lineage-item[data-product="pova-6-pro"]:hover { transform: scale(1.0); }
.lineage-item[data-product="pova-curve"]:hover { transform: scale(1.04); }
.lineage-item[data-product="pova-7"]:hover { transform: scale(1.07); }

.lineage-photo {
  display: block;
  height: 240px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: drop-shadow(0 20px 40px rgba(0, 0, 0, 0.6));
  transition: filter var(--t-slow) var(--ease-out);
}
.lineage-item:hover .lineage-photo,
.lineage-item:focus-visible .lineage-photo {
  filter: drop-shadow(0 20px 50px rgba(255, 124, 38, 0.22)) drop-shadow(0 10px 22px rgba(0, 0, 0, 0.6));
}

.lineage-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: center;
  align-items: center;
}

.lineage-label .name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 17px;
  letter-spacing: 0.04em;
}
.lineage-label .meta {
  font-family: var(--font-mono);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.3em;
  opacity: 0.55;
}

.lineage-all {
  /* CENTRED, per the frames — was `flex-end`, which pinned it to the right edge
     (measured centre 3676 of 3840 against Figma's 1920 on desktop black
     11:392 and 1789 on desktop white 1:1614). The black frame sits exactly on
     the 1920 midline; white is nudged 131 design px left. Same split as the
     mobile frames, where white is the centred one — a designer inconsistency,
     not a system, so centring is the choice that matches one frame exactly and
     stays close to the other. */
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--pova-white);
  font-size: var(--fs-mono-xs);
  letter-spacing: 0.3em;
  opacity: 0.65;
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  transition: opacity var(--t-med) var(--ease-out), border-color var(--t-med) var(--ease-out), gap var(--t-med) var(--ease-out);
}
.lineage-all:hover,
.lineage-all:focus-visible {
  opacity: 1;
  border-color: var(--pova-orange);
  gap: 16px;
  outline: none;
}

/* Tablet — three across, last item wraps to second row. */
@media (max-width: 1100px) {
  .lineage { padding: 100px 48px 80px; }
  .lineage-row { grid-template-columns: repeat(2, 1fr); gap: 24px; }
  .lineage-item { min-height: 280px; }
  .lineage-photo { height: 200px; }
}

/* Mobile — single column stack. */
@media (max-width: 600px) {
  .lineage {
    padding: 80px 24px 60px;
    gap: 56px;
    min-height: auto;
  }
  .lineage-row {
    grid-template-columns: 1fr 1fr;
    min-height: auto;
    gap: 32px 16px;
  }
  .lineage-item {
    padding: 24px 12px;
    min-height: 240px;
    gap: 16px;
  }
  /* Reset desktop scatter rotations — straight grid on small viewports. */
  .lineage-item:nth-child(1),
  .lineage-item:nth-child(2),
  .lineage-item:nth-child(3),
  .lineage-item:nth-child(4) {
    transform: none !important;
    align-items: center;
    padding-left: 0;
  }
  .lineage-item:nth-child(1):hover,
  .lineage-item:nth-child(2):hover,
  .lineage-item:nth-child(3):hover,
  .lineage-item:nth-child(4):hover {
    transform: translateY(-2px) !important;
  }
  .lineage-item:nth-child(1) .lineage-photo,
  .lineage-item:nth-child(2) .lineage-photo,
  .lineage-item:nth-child(3) .lineage-photo,
  .lineage-item:nth-child(4) .lineage-photo {
    height: 200px;
  }
  .lineage-photo { height: 200px; }
  .lineage-all { align-self: flex-start; }
}

/* ============================================================
 * PHONES ≤600px — Figma "POVA Home Page Mobile Black" spec.
 * The design frame is 2160px wide; every measurement below is the
 * design value / 21.6 expressed in vw so it scales pixel-proportionally
 * on every phone width. Asset wrapper sizes are calibrated for each
 * PNG's transparent padding so the VISIBLE device matches the design.
 * Desktop (>600px) is untouched.
 * ============================================================ */
@media (max-width: 600px) {
  /* -- Canvas: black field WITH the signature grid + halo (same visual
        system as desktop; Figma export flattens it to #000 but the live
        experience keeps the engineering grid). Body must stay transparent
        or it occludes the z-index:-1 field (see tokens.css). Ticker/marks/
        kinetic stay hidden per the mobile design. -- */
  .ticker, .reg-marks, .kinetic-statement { display: none !important; }

  /* -- Header: compact wordmark, theme+sound squares left,
        counter + burger right (design y-band 80-155) -- */
  .wordmark { top: 3.6vw; }
  .wordmark img { width: 15.9vw; height: auto; }
  .nav-pill { display: none; }
  .mhdr { position: fixed; top: 3.6vw; left: 3.6vw; z-index: 100; display: flex; gap: 1.3vw; }
  /* Header chips, phone — same glass values as the seven PDPs and as the
     desktop header above, so all three icons match in both themes at both
     breakpoints. Was rgba(255,255,255,0.07) / 0.10 with no blur. */
  .mhdr-btn {
    width: 4.9vw; height: 4.9vw;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.10);
    border: 1px solid rgba(255,255,255,0.22);
    border-radius: 1.2vw; box-sizing: border-box; box-shadow: none;
    backdrop-filter: blur(14px) saturate(1.6); -webkit-backdrop-filter: blur(14px) saturate(1.6);
    color: #ffffff;
    padding: 0; cursor: pointer;
  }
  .mhdr-btn svg { width: 2.9vw; height: 2.9vw; }
  .comp-number { display: block; top: 4.2vw; right: 10.2vw; font-size: 2.05vw; letter-spacing: 0.25em; opacity: 0.55; }

  

  /* -- Stage: absolute constellation becomes the design's stacked flow -- */
  .stage {
    position: relative; height: auto; min-height: 0;
    display: flex; flex-wrap: wrap; align-items: flex-start;
    padding: 0; overflow: visible;
  }
  .stage .instrument, .stage-buds {
    position: static; transform: none; animation: none;
    padding: 0; gap: 1.6vw;
  }
  .stage .inst-label { gap: 0.5vw; position: relative; z-index: 1; }
  .stage .inst-photo { filter: none; }
  /* Tap = sticky :hover on touch. The desktop hover rules re-apply the
   * constellation centering transform (hero) and photo scale — on this
   * static stacked layout that made a tapped product JUMP by half its
   * size. Neutralize every hover/focus/tap transform at higher
   * specificity than the desktop rules. */
  .stage .instrument:hover,
  .stage .instrument:focus-visible,
  .stage .instrument.is-tapped,
  .stage .instrument[data-pos="hero"]:hover,
  .stage .instrument[data-pos="hero"]:focus-visible {
    transform: none;
    filter: none;
  }
  .stage .instrument:hover .inst-photo,
  .stage .instrument:focus-visible .inst-photo,
  .stage .instrument.is-tapped .inst-photo {
    transform: none;
    filter: none;
  }
  /* Labels: design shows them fully, name white / meta grey, meta wraps
   * centered at ~21vw like the design captions. .stage prefix outranks the
   * later ≤1100 label-wrap fix so these metrics always win on phones. */
  .stage .inst-label { opacity: 1; transform: none; max-width: none; }
  /* Figma: buds/TG/Curve2 names are 40 design px = 1.852vw; the HERO name is
     60 = 2.778vw (set separately below). Was 3.4vw -> 73 design px, ~83% over. */
  /* ls 0: Figma sets letterSpacing 0% on every product name. The inherited
     0.04em made these four up to 23 design px wider than the frame. */
  .stage .inst-label .name { font-size: 1.852vw; letter-spacing: 0; white-space: nowrap; overflow-wrap: normal; color: var(--pova-white); }
  /* Figma: colour lines are 32 design px = 1.481vw, ls 23% (hero meta is 35 =
     1.620vw, set below). */
  .stage .inst-label .meta { font-size: 1.481vw; letter-spacing: 0.23em; white-space: normal; overflow-wrap: normal; max-width: 21.5vw; text-align: center; color: var(--pova-orange); opacity: 1; line-height: 1.7; }
  
  .name--m, .meta--m { display: block; }
  .txt--m { display: inline; }

  /* Row 1 — BUDS (left) + CURVE 2 (right), design y 340-1141.
   * Column centres land on the design's device centres (20.9% / 80.7%)
   * via internal padding — no offsets that could poke off-viewport. */
  .stage-buds { order: 1; width: 50%; margin-top: 15.5vw; gap: 1.6vw; box-sizing: border-box; padding-right: 8.5vw; }
  .stage-buds img { width: 19.45vw; height: auto; }
  .instrument[data-pos="tr"] { order: 2; width: 50%; margin-top: 10.95vw; box-sizing: border-box; padding: 0 0 0 12.42vw; }
  /* 367/21.6 = 16.991vw — the Terminal Green back node (179:116) is 367x627.
       13.59vw was sized for the Curve 2 promo card that used to sit here. */
  .instrument[data-pos="tr"] .inst-photo { margin-top: 0; max-width: none; width: 16.991vw; height: auto; }

  /* Row 2 — POVA 8 hero (white render swaps in via <picture>), y 1238-3299 */
  .instrument[data-pos="hero"] { order: 3; width: 100%; margin-top: -8.64vw; }
  /* BLACK hero = 605/21.6 = 28.009vw (node 179:121, 605x1811). The white
       theme overrides to 38.241vw for its own 826x1919 render — the two frames
       genuinely ship different hero art at different sizes. 42.64vw was neither. */
  .instrument[data-pos="hero"] .inst-photo { max-width: none; max-height: none; width: 28.009vw; height: auto; }
  .instrument[data-pos="hero"] .inst-label { margin-top: -5.7vw; }

  /* Row 3 — manifesto left + 7 Pro right, y 3406-4207 */
  /* margin-top 9.42 -> 26.364vw. Figma places "[FIELD 2026]" at y3580 in BOTH
     mobile frames; after the hero renders were resized to their true node boxes
     (605x1811 black / 826x1919 white) the stage got shorter and this landed at
     3214 — 366 design px high = 16.944vw. This is the BLACK/base value; the
     white theme overrides it with its own figure because its hero is taller. */
  .hero-copy {
    order: 4; position: static; width: 55%;
    padding-left: 7.4vw; margin-top: 26.364vw; max-width: none; font-size: 1.9vw;
  }
  /* [FIELD 2026] 22.09 design px = 1.023vw, ls 30%. */
  .hero-copy .label { font-size: 1.023vw; letter-spacing: 0.3em; margin-bottom: 1.35vw; }
  /* "Built For What's Next." 160 design px = 7.407vw, line-height 99%. */
  .hero-copy .tagline { font-size: 7.407vw; line-height: 0.99; max-width: 11ch; margin: 0; }
  .instrument[data-pos="br"] { order: 5; width: 45%; margin-top: -1.83vw; box-sizing: border-box; padding: 0 0 0 9.18vw; }
  /* 294/21.6 = 13.611vw — Storm Titanium node (179:112) is 294x616. */
  .instrument[data-pos="br"] .inst-photo { width: 13.611vw; height: auto; max-width: none; }
  .instrument[data-pos="br"] .inst-label { align-items: flex-end; text-align: right; align-self: flex-end; padding-right: 7.5vw; }
  .instrument[data-pos="br"] .inst-label .meta { text-align: right; }

  /* Row 4 — scroll cue, centered, y 4320-4351 */
  .scroll-cue {
    order: 6; position: static; display: flex; width: 100%;
    justify-content: center; align-items: center;
    margin: 0.71vw 0 0; padding: 0; left: auto; bottom: auto; transform: none;
  }
  .scroll-cue .scroll-cue-rule { display: none; }
  .scroll-cue-text { font-size: 1.6vw; letter-spacing: 0.35em; opacity: 0.6; }

  /* -- Lineage: header y 4580-4863, grid rows y 5260-8427 -- */
  .lineage { padding: 9.7vw 0 0; gap: 0; }
  .lineage-header { padding: 0 7.4vw; }
  /* [FIELD 2026] in the lineage header is 19.76 design px = 0.915vw. */
  .lineage-header .label { font-size: 0.915vw; letter-spacing: 0.3em; color: var(--pova-orange); opacity: 1; }
  .lineage-title { font-size: 6.7vw; margin: -3.63vw 0 1.8vw; }
  .lineage-sub { font-size: 2.4vw; opacity: 0.6; margin: -3.44vw 0 0; }
  .lineage-row {
    display: grid; grid-template-columns: 1fr 1fr;
    /* margin-top 4.88 -> 0.389vw: Figma starts "Product PDP" at y4577 in both
       mobile frames and this was landing at 4674 (97 design px = 4.491vw low)
       once the hero renders were resized to their true node boxes. */
    width: 100%; padding: 0 6vw 0; margin-top: 0.389vw; gap: 5.8vw 0;
    max-width: none; min-height: 0; align-items: start;
  }
  .lineage-item:nth-child(1), .lineage-item:nth-child(2),
  .lineage-item:nth-child(3), .lineage-item:nth-child(4),
  .lineage-item:nth-child(1):hover, .lineage-item:nth-child(2):hover,
  .lineage-item:nth-child(3):hover, .lineage-item:nth-child(4):hover,
  .lineage-item:focus-visible { transform: none !important; }
  .lineage-item { justify-self: center; display: flex; flex-direction: column; align-items: center; gap: 4vw; overflow: hidden; padding: 0; }
  /* nth-child specificity beats the 200px clamp in the earlier ≤600 block
   * so each photo keeps its exact design height (201.5–209.4px varies). */
  .lineage-item:nth-child(1) .lineage-photo, .lineage-item:nth-child(2) .lineage-photo,
  .lineage-item:nth-child(3) .lineage-photo, .lineage-item:nth-child(4) .lineage-photo {
    width: auto; height: auto; max-height: none;
  }
  .lineage-item[data-product="pova-5-pro"] .lineage-photo { width: 23.63vw; }
  .lineage-item[data-product="pova-6-pro"] .lineage-photo { width: 23.84vw; }
  .lineage-item[data-product="pova-curve"] .lineage-photo { width: 26.24vw; margin: 0; }
  .lineage-item[data-product="pova-7"]     .lineage-photo { width: 29.51vw; }
  .lineage-label { display: flex; flex-direction: column; align-items: center; gap: 1vw; }
  /* Lineage names 73.87 design px = 3.420vw. */
  .lineage-label .name { font-size: 3.420vw; letter-spacing: 0em; }
  /* 48.27 design px = 2.234vw, ls 5%. COLOUR: the BLACK frame draws these
     WHITE (the white frame draws them orange) — it was orange in both. */
  .lineage-label .meta { font-size: 2.234vw; letter-spacing: 0.05em; color: var(--pova-white); opacity: 1; white-space: nowrap; }
  /* Design: SEE EVERY POVA text + arrow are orange #ff5d01. */
  /* CENTRED, per the frames. `margin-left:auto` with `margin-right:4.3vw` was
     pinning it to the right edge: measured centre 1629 of 2160 against Figma's
     1083 (mobile white 11:189, x861 w444) and 1010 (mobile black 1:1499, x788).
     The white frame centres it on the 1080 midline; the black frame sits 70
     design px left of that — a designer nudge, not a system. Centring matches
     white exactly and lands within 70 design px (13 css px) of black, which is
     the robust choice because our substituted font renders this string 670
     design px wide against IBM Plex's 444, so pinning a left edge would throw
     the visual centre out by more than the nudge it was correcting for. */
  /* Figma: 48.4 design px = 2.241vw, letter-spacing 10%, IBM Plex Sans MEDIUM.
     Was 2.7vw / 0.22em / 700 — 20% oversized, double the tracking and bold. */
  /* Figma: 48.4 design px = 2.241vw, ls 10%, IBM Plex Sans MEDIUM (500).
     NOTE the old rule declared font-weight TWICE — 500 then 700 — so the bold
     silently won. Only one declaration now. */
  .lineage-all { margin: 10.58vw auto 0 auto; font-size: 2.241vw; letter-spacing: 0.10em; border: 0; padding-bottom: 0; color: var(--pova-orange); font-weight: 500; }
  /* The trailing arrow is decorative and not a Figma node; matched to the label
     rather than left at the inherited 121.8 design px. */
  .lineage-all span[aria-hidden] { font-size: 2.241vw; font-weight: 500; }

  

  .subscribe { width: 100%; max-width: 100%; }
  .subscribe input { width: 100%; min-width: 0; box-sizing: border-box; }

  

  

  .subscribe input { font-size: 2.81vw; letter-spacing: 0.19em; font-weight: 500; color: #fff; }
  .subscribe input::placeholder { color: rgba(255, 255, 255, 0.9); text-transform: uppercase; }

}

/* ============================================================================
   MOBILE (<=600px) — ABSOLUTE FIGMA LAYOUT
   Built the same way as the seven PDPs (figma-mobile-pdp-build-rule): every
   element is placed at its OWN design coordinate from the frame, converted
   2160 -> 100vw, i.e. design_px / 21.6 = vw. Nothing is spaced by flow, so a
   change to one element cannot move another — which is what kept breaking the
   margin-tuned version.

   Reference: mobile-black 1:1499 and mobile-white 11:189. Their GEOMETRY IS
   IDENTICAL — only text colour differs (and SEE EVERY POVA's x, 788 vs 861) —
   so one layout serves both themes and the colours stay in the theme files.
   ============================================================================ */
@media (max-width: 600px) {
  /* ---- STAGE: frame 0 -> 4577 (Product PDP starts there) ---- */
  body.home .stage {
    position: relative; display: block;
    width: 100%; height: 211.898vw;      /* 4577 / 21.6 */
    /* -3.194vw: the fixed header still occupies 69 design px of flow above the
       stage, so every absolutely-placed child inherited a +69 y offset. All the
       coordinates below are frame-absolute, so the box itself is pulled up
       instead of subtracting 69 from each one. */
    padding: 0; margin: -3.194vw 0 0; min-height: 0; max-height: none;
  }
  body.home .stage > * { position: absolute; margin: 0; }

  /* Buds group 179:105 — image 238,406 420x556 ; name 244,1004 ; meta 266,1059 */
  body.home .stage-buds { left: 11.019vw; top: 18.796vw; width: 19.444vw; max-width: none; }
  body.home .stage-buds img { width: 19.444vw !important; height: 25.741vw !important; max-width: none;
    display: block; margin: 0 auto 0 0; }   /* pin left: the wrapper was centring it */
  /* Labels are placed on the FRAME, not below their card. Figma gives each its
     own absolute coordinate and the two mobile frames agree exactly, so the
     label position no longer depends on how tall the phone above it renders —
     which is what made the black hero's caption overlap its image. */
  body.home .stage-buds .inst-label { position: absolute; left: 9.584vw; top: 30.880vw; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; }
  body.home .stage-buds .inst-label .name { display: block; margin: 0; }
  body.home .stage-buds .inst-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); top: 2.546vw; white-space: nowrap; }

  /* POVA 8 / Terminal Green 179:113 — image 1575,337 367x627 ; name 1618,1004 ; meta 1526,1059 */
  body.home .instrument[data-pos="tr"] { left: 72.917vw; top: 13.982vw; width: 16.991vw; padding: 0; }
  body.home .instrument[data-pos="tr"] .inst-photo { width: 16.991vw; height: 29.028vw; display: block; }
  /* tr name 1618,1004 / meta 1526,1059 ; card origin 1575,337 */
  body.home .instrument[data-pos="tr"] .inst-label { position: absolute; left: 8.472vw; top: 35.694vw; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; }
  body.home .instrument[data-pos="tr"] .inst-label .name { display: block; margin: 0; }
  body.home .instrument[data-pos="tr"] .inst-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); top: 2.546vw; white-space: nowrap; }

  /* POVA 8 PRO hero 179:101 — image 796,1224 605x1811 ; name 958,3132 ; meta 883,3209 */
  body.home .instrument[data-pos="hero"] { left: 36.852vw; top: 55.046vw; width: 28.009vw; padding: 0; }
  body.home .instrument[data-pos="hero"] .inst-photo { width: 28.009vw; height: 83.843vw; display: block; }
  /* hero name 958,3132 / meta 883,3209 — frame coords, minus the card origin
     (796,1224 black) so they resolve to the same absolute spot. */
  body.home .instrument[data-pos="hero"] .inst-label { position: absolute; left: 15.694vw; top: 98.842vw; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; }
  body.home .instrument[data-pos="hero"] .inst-label .name { display: block; margin: 0; }
  body.home .instrument[data-pos="hero"] .inst-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); top: 3.565vw; white-space: nowrap; }

  /* POVA Curve 2 / Storm Titanium 179:109 — image 1612,3406 294x616 ; name 1618,4071 ; meta 1559,4125 */
  body.home .instrument[data-pos="br"] { left: 74.630vw; top: 157.685vw; width: 13.611vw; padding: 0; }
  body.home .instrument[data-pos="br"] .inst-photo { width: 13.611vw; height: 28.519vw; display: block; }
  /* br name 1618,4071 / meta 1559,4125 ; card origin 1612,3406 */
  body.home .instrument[data-pos="br"] .inst-label { position: absolute; left: 6.759vw; top: 33.981vw; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; }
  body.home .instrument[data-pos="br"] .inst-label .name { display: block; margin: 0; }
  body.home .instrument[data-pos="br"] .inst-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); top: 2.500vw; white-space: nowrap; }

  /* [FIELD 2026] 164,3580 + "Built For What's Next." 153,3652 */
  body.home .hero-copy {
    left: 7.083vw; top: 168.935vw; width: 44.028vw;   /* +69 back: sits inside the pulled-up stage */
    padding: 0; max-width: none;
  }
  /* [FIELD 2026] 164,3580 and "Built For What's Next." 153,3652 have DIFFERENT
     x in the frame, so the label is nudged 11 design px right of the wrapper and
     the gap set to hit 3652 (72 design px below the label's top). */
  /* weight 400: Figma draws [FIELD 2026] in IBM Plex Sans REGULAR; the build
     inherited a 200 (ExtraLight) and read faint against the page. */
  body.home .hero-copy .label { display: block; margin: 0 0 1.389vw; padding-left: 0.509vw; font-weight: 400; }
  body.home .hero-copy .tagline { display: block; margin: 0; }

  /* ---- LINEAGE: group 1:1545 at y4577, so children are (design_y - 4577) ---- */
  body.home .lineage {
    position: relative; display: block;
    width: 100%; height: 212.176vw;      /* 9160 - 4577 = 4583 */
    padding: 0; margin: 3.194vw 0 0; min-height: 0;   /* +69: cancels the stage pull-up */
  }
  body.home .lineage > * { position: absolute; margin: 0; }
  body.home .lineage-header { left: 0; top: 0; width: 100%; }
  body.home .lineage-header .label { position: absolute; left: 7.546vw; top: 0; margin: 0; }
  body.home .lineage-header .tagline { position: absolute; left: 7.083vw; top: 2.176vw; width: 54.630vw; margin: 0; }
  body.home .lineage-header p { position: absolute; left: 7.454vw; top: 11.157vw; width: 45.556vw; margin: 0; }

  /* the four cards — image + label at their own coords, row wrapper neutralised */
  body.home .lineage-row { position: static; display: block; padding: 0; margin: 0; gap: 0; width: 100%; }
  /* overflow VISIBLE: `.lineage-item` still carries `min-height:240px` (a FIXED
     px value) and `overflow:hidden` from the old flex layout, while the label
     sits at `top: 56.8vw` — proportional. Past ~400px wide the vw offset grows
     beyond the 240px box and the name was being clipped; POVA CURVE and POVA 7
     have the largest tops so they cut first. Nothing here needs clipping: the
     card holds one exactly-sized img plus absolutely-positioned labels. */
  body.home .lineage-item { position: absolute; margin: 0; padding: 0; display: block; overflow: visible; }
  body.home .lineage-item .lineage-label { position: absolute; display: block; width: 40vw; }

  /* 5 Pro  img 401,5260 510x1116 | name 390,6464 | meta 267,6558 */
  body.home .lineage-item[data-product="pova-5-pro"] { left: 59.050vw; top: 116.153vw; width: 23.611vw; }
  body.home .lineage-item[data-product="pova-5-pro"] img { width: 23.611vw; height: 51.667vw; display: block; }
  body.home .lineage-item[data-product="pova-5-pro"] .lineage-label { left: 11.806vw; top: 55.741vw; }
  /* 6 Pro  img 1273,5257 515x1120 | name 1264,6464 | meta 1142,6558 */
  body.home .lineage-item[data-product="pova-6-pro"] { left: 18.449vw; top: 115.968vw; width: 23.843vw; }
  body.home .lineage-item[data-product="pova-6-pro"] img { width: 23.843vw; height: 51.852vw; display: block; }
  body.home .lineage-item[data-product="pova-6-pro"] .lineage-label { left: 11.898vw; top: 55.880vw; }
  /* Curve  img 372,7051 567x1160 | name 390,8278 | meta 267,8373 */
  body.home .lineage-item[data-product="pova-curve"] { left: 57.731vw; top: 29.606vw; width: 26.250vw; }
  body.home .lineage-item[data-product="pova-curve"] img { width: 26.250vw; height: 53.704vw; display: block; }
  body.home .lineage-item[data-product="pova-curve"] .lineage-label { left: 13.148vw; top: 56.806vw; }
  /* POVA 7 img 1212,7060 637x1133 | name 1400,8278 | meta 1201,8373 */
  body.home .lineage-item[data-product="pova-7"] { left: 15.625vw; top: 30.856vw; width: 29.491vw; }
  body.home .lineage-item[data-product="pova-7"] img { width: 29.491vw; height: 52.454vw; display: block; }
  body.home .lineage-item[data-product="pova-7"] .lineage-label { left: 14.723vw; top: 56.389vw; }

  /* SEE EVERY POVA — black 788,8760 ; white overrides x to 861 in home-white.css */
  body.home .lineage-all { left: 36.481vw; top: 193.657vw; width: auto; margin: 0; }
}

/* ---- DESKTOP (>=601px): card labels at their OWN frame coordinates ----
   Same correction as mobile: the labels were anchored to their card, so the
   two different hero heights (white 1407, black 1332) pushed the caption to two
   different places — on black it landed 39 design px ABOVE the image bottom and
   overlapped. Figma puts POVA 8 PRO at 1901,1602 and its colour line at
   1863,1637 in BOTH desktop frames, independent of the phone above. */
@media (min-width: 601px) {
  body.home .stage-buds .inst-label,
  body.home .instrument .inst-label {
    position: absolute; margin: 0; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; white-space: nowrap;
  }
  body.home .stage-buds .inst-label .name,
  body.home .instrument .inst-label .name { display: block; margin: 0; }
  body.home .stage-buds .inst-label .meta,
  body.home .instrument .inst-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); white-space: nowrap; }

  /* Label tops carry the SAME offset the card was raised by (buds 32, tr 41,
     br 36 design px): the label is a child of the card, so moving the card
     moved it too. Card origins: buds 522,571 / tr 3178,264 / br 3199,1162. */
  body.home .stage-buds .inst-label { left: 5.417vw; top: 15.181vw; }
  body.home .stage-buds .inst-label .meta { top: 0.911vw; }
  /* tr card origin 3178,264 */
  /* POVA 8 only: +23 design px below the Figma y. Figma seats this name box
     EXACTLY on the image box bottom (662 = 264+398) while the buds and Curve 2
     names get 27 and 31 px of clearance, so the render read as touching its
     label. 23 px brings the VISIBLE gap (alpha-bbox bottom -> glyph top) to 36,
     matching Curve 2. Deliberate departure from the frame, user-requested. */
  body.home .instrument[data-pos="tr"] .inst-label { left: 2.995vw; top: 10.967vw; }
  body.home .instrument[data-pos="tr"] .inst-label .meta { top: 0.911vw; }
  /* br card origin 3199,1162 */
  body.home .instrument[data-pos="br"] .inst-label { left: 2.448vw; top: 11.068vw; }
  body.home .instrument[data-pos="br"] .inst-label .meta { top: 0.911vw; }
}

@media (max-width: 600px) {
  /* The hero card's caption is larger than the other three: Figma 60 and 35
     design px against their 40 and 32. */
  body.home .instrument[data-pos="hero"] .inst-label .name { font-size: 2.778vw; }
  body.home .instrument[data-pos="hero"] .inst-label .meta { font-size: 1.620vw; }
  /* "Each one earned its place..." is 40 design px = 1.852vw, ls 5%. */
  body.home .lineage-header p { font-size: 1.852vw; letter-spacing: 0.05em; }
  /* "How we got here." 160 design px = 7.407vw. */
  body.home .lineage-header .tagline { font-size: 7.407vw; line-height: 0.99; }
}

@media (max-width: 600px) {
  /* ---- Lineage card labels at their OWN Figma coordinates ----
     Same correction as the stage cards: these were anchored under their image,
     which put them 167-335 design px right of the frame positions. Offsets are
     (label_xy - card_xy) so they resolve to the absolute design coordinate. */
  body.home .lineage-item .lineage-label { position: absolute; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; white-space: nowrap; margin: 0; }
  body.home .lineage-item .lineage-label .name { display: block; margin: 0; }
  body.home .lineage-item .lineage-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); white-space: nowrap; }
  /* 5 Pro: card 401,5260 */
  body.home .lineage-item[data-product="pova-5-pro"] .lineage-label { left: 11.806vw; top: 55.741vw; }
  body.home .lineage-item[data-product="pova-5-pro"] .lineage-label .meta { top: 4.352vw; }
  /* 6 Pro: card 1273,5257 */
  body.home .lineage-item[data-product="pova-6-pro"] .lineage-label { left: 11.898vw; top: 55.880vw; }
  body.home .lineage-item[data-product="pova-6-pro"] .lineage-label .meta { top: 4.352vw; }
  /* Curve: card 372,7051 */
  body.home .lineage-item[data-product="pova-curve"] .lineage-label { left: 13.148vw; top: 56.806vw; }
  body.home .lineage-item[data-product="pova-curve"] .lineage-label .meta { top: 4.398vw; }
  /* POVA 7: card 1212,7060 */
  body.home .lineage-item[data-product="pova-7"] .lineage-label { left: 14.723vw; top: 56.389vw; }
  body.home .lineage-item[data-product="pova-7"] .lineage-label .meta { top: 4.398vw; }
}

/* ---- DESKTOP: lineage labels and headline at their OWN Figma coordinates ----
   Measured drift before this block (identical on both themes, so it comes from
   the shared rules, not a theme bug):
     POVA 5 PRO  +22,+7    POVA 6 PRO +18,+7    POVA CURVE +18,+14
     2023 . DARK ILLUSION +9,+14   2024 . METEOR GREY +17,+14
     How we got here. -16 y
   Figma: names y3338, captions y3370, "How we got here." y2387.
   Cards sit at 453/1363/2266/3161 x 2932-2940. */
@media (min-width: 601px) {
  body.home .lineage-item .lineage-label { position: absolute; margin: 0; width: 0; max-width: none; display: flex; flex-direction: column; align-items: center; white-space: nowrap; }
  body.home .lineage-item .lineage-label .name { display: block; margin: 0; }
  body.home .lineage-item .lineage-label .meta { display: block; margin: 0; position: absolute; left: 0; right: auto; width: auto; transform: translateX(-50%); white-space: nowrap; }
  /* 5 Pro: card 453,2940 -> name 446,3338 / meta 405,3370 */
  body.home .lineage-item[data-product="pova-5-pro"] .lineage-label { left: 2.162vw; top: 10.339vw; }
  body.home .lineage-item[data-product="pova-5-pro"] .lineage-label .meta { top: 0.833vw; }
  /* 6 Pro: card 1363,2939 -> name 1360,3338 / meta 1319,3370 */
  body.home .lineage-item[data-product="pova-6-pro"] .lineage-label { left: 2.266vw; top: 10.365vw; }
  body.home .lineage-item[data-product="pova-6-pro"] .lineage-label .meta { top: 0.833vw; }
  /* Curve: card 2266,2932 -> name 2266,3338 / meta 2225,3370 */
  body.home .lineage-item[data-product="pova-curve"] .lineage-label { left: 2.344vw; top: 10.547vw; }
  body.home .lineage-item[data-product="pova-curve"] .lineage-label .meta { top: 0.833vw; }
  /* POVA 7: card 3161,2935 -> name 3225,3338 / meta 3158,3370 */
  body.home .lineage-item[data-product="pova-7"] .lineage-label { left: 2.813vw; top: 10.469vw; }
  body.home .lineage-item[data-product="pova-7"] .lineage-label .meta { top: 0.833vw; }
  /* "How we got here." measured 16 design px high against Figma's y2387. */
  body.home .lineage-header .tagline { margin-top: 0.417vw; }
  /* [FIELD 2026] sits at x249 while "Built For What's Next." below it starts at
     x239 — same 10 design px inset the mobile frames use. */
  body.home .hero-copy .label { position: relative; left: 0.260vw; padding-left: 0; }
}

/* ---- Product name + caption line box = font size, as Figma draws them ----
   Every one of these nodes is lineHeight 100% with textAlignVertical TOP, so in
   Figma the line box IS the font size and the glyphs start at the node's y. Ours
   ran 1.39-1.7x, which seated the glyphs up to 22 design px lower inside the box
   and made a coordinate-exact `top` still look low. Scoped to the eight product
   labels; no other type on the page is touched. */
body.home .stage-buds .inst-label .name,
body.home .stage-buds .inst-label .meta,
body.home .instrument .inst-label .name,
body.home .instrument .inst-label .meta,
body.home .lineage-item .lineage-label .name,
body.home .lineage-item .lineage-label .meta { line-height: 1; }

/* ---- [FIELD 2026] hidden on the phone (user request 2026-08-11) ----
   Both mobile labels read "[FIELD 2026]": the hero-copy one above "Built For
   What's Next." and the lineage-header one above "How we got here.".
   `visibility` rather than `display:none` on purpose — the hero label is IN FLOW
   and "Built For What's Next." sits directly below it, so removing its box would
   pull the headline up off its Figma y. The lineage label is absolute and would
   not have moved anything, but both are treated the same way for consistency.
   DESKTOP IS UNAFFECTED: it renders the .txt--d strings ("[ FIELD / 2026 ]" and
   "[ LINEAGE / 2023 -> 2026 ]"), which stay visible.
   NOTE: this is a deliberate departure from the frame — Figma draws [FIELD 2026]
   at 164,3580 and 163,4577 in both mobile frames. */
@media (max-width: 600px) {
  body.home .hero-copy .label,
  body.home .lineage-header .label { visibility: hidden; }
}

/* ---- [ FIELD / 2026 ], [ LINEAGE / 2023 -> 2026 ] and [ THE LINE SO FAR ]
       hidden on the DESKTOP home page (user request 2026-08-11) ----
   `visibility` rather than `display:none` for the same reason as the phone rule
   above: both labels are IN FLOW (hero label `position:relative` with
   margin-bottom 13.5px, lineage label `position:static`) and "Built For What's
   Next." / "How we got here." sit directly beneath them, so collapsing their
   boxes would pull both headlines up off their Figma y (1506 and 2387).
   `.scroll-cue` is absolute and would not have moved anything, but it is treated
   the same way so the three behave identically. Hiding it also takes the link out
   of the tab order and the a11y tree, which is what "remove" should mean here.
   The hero label carries BOTH strings (`.txt--d` "[ FIELD / 2026 ]" and `.txt--m`
   "[FIELD 2026]"), so this covers the black desktop's short-caption flip too.
   MOBILE IS UNAFFECTED — scoped to >=601px. */
@media (min-width: 601px) {
  body.home .hero-copy .label,
  body.home .lineage-header .label,
  body.home .scroll-cue { visibility: hidden; }
}

/* ==========================================================================
   FIRST-SCREEN PRODUCTS — name appears on hover (desktop, 2026-08-17)
   --------------------------------------------------------------------------
   User: same reveal + pop as the products page, for the four products on the
   first home screen only, with the vertical motion kept intact. Confirmed
   before changing anything:
       centre  POVA 8 PRO         float 8s
       left    POVA AI BUDS PRO   float 9s
       top-r   POVA 8             float 7.5s
       bot-r   POVA Curve 2       float 10s

   Measured first, and only ONE half was missing:
     - the POP already works — hovering scales .inst-photo to 1.04 and reverses
       (home.css L82-87), so nothing is added for it here.
     - the NAME did not, because the Figma-derived theme sheets pin it visible:
       home-black.css L80/L109 and home-white.css L105/L142 set
       `.stage .inst-label { opacity: 1 }` at (0,3,1). The base hidden state at
       L139-148 loses to them. Overridden below at (0,5,1).

   The float animation is on the CONTAINER (.instrument / .stage-buds), not on
   the photo or the label, so changing label opacity cannot disturb it —
   verified still running throughout hover.

   `hover: hover` so touch devices are untouched: the existing `@media
   (hover: none)` block at L367 already reveals labels there, and this must not
   fight it. `min-width: 601px` keeps the phone layout exactly as it was.
   Scoped to `.stage` so the lineage strip lower down the page is unaffected.
   ========================================================================== */
@media (min-width: 601px) and (hover: hover) {
  body.home[data-theme] .stage .instrument .inst-label,
  body.home[data-theme] .stage .stage-buds .inst-label {
    opacity: 0;
    transform: translateY(6px);
    transition: opacity var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-out);
    pointer-events: none;
  }
  body.home[data-theme] .stage .instrument:hover .inst-label,
  body.home[data-theme] .stage .instrument:focus-visible .inst-label,
  body.home[data-theme] .stage .stage-buds:hover .inst-label,
  body.home[data-theme] .stage .stage-buds:focus-visible .inst-label {
    opacity: 1;
    transform: translateY(0);
  }
}
@media (min-width: 601px) and (hover: hover) and (prefers-reduced-motion: reduce) {
  body.home[data-theme] .stage .instrument .inst-label,
  body.home[data-theme] .stage .stage-buds .inst-label {
    transform: none; transition: opacity var(--t-med) var(--ease-out);
  }
}

/* The POP already worked for three of the four — but NOT the buds, because its
   <img> carries no `.inst-photo` class (index.html: the buds is a plain
   <picture><img>, unlike the three .instrument cards), so home.css L82-87 never
   matched it. Measured: hero/TR/BR all 222.51->229.18, 119->123.76, 94->97.76,
   while the buds stayed at 210.01 in both themes. Same scale(1.04) given to it
   here so all four behave alike. The float stays on the CONTAINER, so scaling
   the image cannot disturb it. */
@media (min-width: 601px) and (hover: hover) {
  body.home[data-theme] .stage .stage-buds img {
    transition: transform var(--t-slow) var(--ease-out), filter var(--t-med) var(--ease-out);
  }
  body.home[data-theme] .stage .stage-buds:hover img,
  body.home[data-theme] .stage .stage-buds:focus-visible img {
    transform: scale(1.04);
  }
}
@media (min-width: 601px) and (hover: hover) and (prefers-reduced-motion: reduce) {
  body.home[data-theme] .stage .stage-buds:hover img,
  body.home[data-theme] .stage .stage-buds:focus-visible img { transform: none; }
}

/* =========================================================================
   SEE EVERY POVA — flow button
   =========================================================================
   Ported from a React/Tailwind reference to plain CSS (this site has no build
   step). Every size is expressed in `em` so the ONE set of ratios below scales
   itself to each variant's own font-size — 0.521vw on desktop, 2.241vw on
   mobile — instead of needing a second, hand-tuned copy per breakpoint.

   Ratios are the reference's px values over its 14px text:
     padding 12/32 -> 0.857em / 2.286em      border 1.5 -> 0.107em
     radius  100 -> 7.143em, CONSTANT        (see below)
     arrows  16 -> 1.143em (size AND inset)  circle rest 16 -> 1.143em

   ONE DELIBERATE DEPARTURE FROM THE REFERENCE: it animates the radius from
   100px down to 12px on hover, so the pill squares off as the fill lands.
   User rejected that — the silhouette must not change shape. The radius is
   therefore constant at 7.143em in both states and is NOT transitioned; the
   fill, colour and arrows still animate exactly as the reference does. */

   Specificity note: the four variant rules in home-black.css / home-white.css
   each declare `padding: 0; border: 0`, and they load AFTER this file. The
   `body.home a.lineage-all` selector (0,2,2) outranks their (0,2,1), so the
   pill wins without either theme file being edited. `position` is deliberately
   NOT set here — the variants make the element absolute and that must stand. */

.lineage-all { position: relative; }        /* fallback only; variants use absolute */

body.home a.lineage-all {
  overflow: hidden;
  padding: 0.857em 2.286em;
  border: 0.107em solid rgba(255, 93, 1, 0.4);
  border-radius: 7.143em;
  background: transparent;
  gap: 0;
  opacity: 1;
  transition: border-color 600ms cubic-bezier(0.23, 1, 0.32, 1),
              color 600ms cubic-bezier(0.23, 1, 0.32, 1),
              transform 200ms ease;
}
body.home a.lineage-all:hover,
body.home a.lineage-all:focus-visible {
  border-color: transparent;
  color: #fff;
  gap: 0;
  opacity: 1;
  outline: none;
}
body.home a.lineage-all:active { transform: scale(0.95); }

/* Label — rides right as the fill sweeps in. */
body.home a.lineage-all .la-text {
  position: relative; z-index: 1;
  transform: translateX(-0.857em);
  transition: transform 800ms ease-out;
}
body.home a.lineage-all:hover .la-text,
body.home a.lineage-all:focus-visible .la-text { transform: translateX(0.857em); }

/* Arrows — the outgoing one exits right as the incoming one enters left. */
body.home a.lineage-all .la-arr {
  position: absolute; top: 50%; z-index: 9;
  line-height: 1; transform: translateY(-50%);
  transition: left 800ms cubic-bezier(0.34, 1.56, 0.64, 1),
              right 800ms cubic-bezier(0.34, 1.56, 0.64, 1),
              color 800ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
body.home a.lineage-all .la-arr--in  { left: -25%; }
body.home a.lineage-all .la-arr--out { right: 1.143em; }
body.home a.lineage-all:hover .la-arr--in,
body.home a.lineage-all:focus-visible .la-arr--in  { left: 1.143em; color: #fff; }
body.home a.lineage-all:hover .la-arr--out,
body.home a.lineage-all:focus-visible .la-arr--out { right: -25%; color: #fff; }

/* Brand-orange fill. Sized at 140% of the BUTTON's own width (square, via
   aspect-ratio) so it always covers the pill's diagonal whatever the label
   length or viewport — 1.4w >= sqrt(w^2 + h^2) holds comfortably at both
   breakpoints. The reference's #111111 is replaced by Pulse Orange. */
body.home a.lineage-all .la-circle {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 1.143em; aspect-ratio: 1;
  background: var(--pova-orange);
  border-radius: 50%;
  opacity: 0; z-index: 0;
  transition: width 800ms cubic-bezier(0.19, 1, 0.22, 1),
              opacity 800ms cubic-bezier(0.19, 1, 0.22, 1);
}
body.home a.lineage-all:hover .la-circle,
body.home a.lineage-all:focus-visible .la-circle { width: 140%; opacity: 1; }

/* ---- Anchor compensation -------------------------------------------------
   The label must not move. The pill adds padding + border INSIDE the box
   (box-sizing: border-box), the element is anchored by its RIGHT edge on
   desktop and its LEFT edge on mobile, AND the label carries the reference's
   resting translateX(-0.857em) — three offsets pulling in different directions.
   VERTICAL uses calc, not a plain vw number, because the ORIGINAL top offset
   was not proportional: the base rule at line 641 sets `padding: 10px 0` in
   FIXED px, and the mobile rule only zeroes padding-BOTTOM — so the old label
   sat a constant 10px below the box top while everything around it scaled.
   A single vw correction tracked that at one width only (measured drift: 0px
   at 390 but +1.5px at 430 and +5.6px at 600). Carrying the 10px term through
   the calc cancels it at every width:
       new top = original + 10px - (border + padding-y) = original + 10px - 0.964em
   Desktop variants set `padding: 0`, so their fixed term is 0.
   HORIZONTAL stays an empirical vw value — the old box width depended on the
   arrow glyph's advance, which no formula predicts; measured residual is
   +0.2396vw desktop / +2.0308vw mobile, holding within 0.44px at every width.
   Originals stay in home-black.css / home-white.css untouched. */
@media (min-width: 601px) {
  body.home[data-theme="white"] a.lineage-all { right: 49.4099vw; top: calc(46.830vw - 0.964em); }
  body.home[data-theme="black"] a.lineage-all { right: 45.9980vw; top: calc(46.257vw - 0.964em); }
}
@media (max-width: 600px) {
  body.home a.lineage-all { left: 33.1491vw; top: calc(193.657vw + 10px - 0.964em); }
  body.home[data-theme="white"] a.lineage-all { left: 36.5291vw; top: calc(193.102vw + 10px - 0.964em); }
}

/* ===== SEE EVERY POVA — aligned to the header wordmark (2026-08-26) ========
   User: this button must sit on the same vertical line as the header POVA logo,
   in all four home variants. Nothing else about it changes.

   MEASURED BEFORE: the button was never on that line, and the error grew with
   width — desktop white was -45.98px at 1440 and -61.42px at 1920, while the
   two themes sat on OPPOSITE sides of centre (black +3.15px at 1440).

   *** ALIGNED TO THE LOGO, NOT TO 50%. *** The wordmark is centred in three of
   the four variants, but home-white.css:409 deliberately places the PHONE white
   wordmark at `left: 48.51%` (the white Figma frame puts its centre at x1047.7,
   not 1080). Centring the button would therefore have missed the logo by
   ~1.49vw on exactly that one variant. These rules mirror the wordmark's own
   left value per variant, so the two track together by construction.

   ONLY the horizontal anchor is set. `top` is untouched — the calc values in
   the block above still apply, so the button does not move vertically. */
@media (min-width: 601px) {
  body.home[data-theme="white"] a.lineage-all,
  body.home[data-theme="black"] a.lineage-all { left: 50%; right: auto; transform: translateX(-50%); }
}
@media (max-width: 600px) {
  body.home[data-theme="black"] a.lineage-all { left: 50%;    right: auto; transform: translateX(-50%); }
  body.home[data-theme="white"] a.lineage-all { left: 48.51%; right: auto; transform: translateX(-50%); }
}
/* The press animation must KEEP the centring translate, or pressing the button
   would snap it half its own width to the right. */
body.home a.lineage-all:active { transform: translateX(-50%) scale(0.95); }

/* ============================================================
   Desktop homepage stage — enlarge the satellite products ~14%
   (the older/smaller phones read too small next to the hero). Uses the
   CSS `scale` property so it composes with the hover transform and does
   NOT shift the absolute Figma layout boxes. Desktop only (>=701px).
   ============================================================ */
@media (min-width: 701px){
  body.home .instrument[data-pos="tr"] .inst-photo,
  body.home .instrument[data-pos="br"] .inst-photo { scale: 1.14; }
  body.home .stage-buds img { scale: 1.12; }
}