/* ============================================================
   HOME V2 — THE VEHICLE WALL (Fable concept, Hamza, 2026-09-19).
   The homepage hero since 2026-09-19 (views/site/index.php; it graduated from
   /concepts/vehicle-wall-fable the night it was built). Rendered by
   //site/_home_v2_wall_fable.php, driven by
   js/concept-vehicle-wall-fable.js. The fold's words on the left, three
   drifting columns of tiles on the right, the proof capsule at the words'
   foot. This sheet owns the section's grid, the wall, the tile face, the
   edge fades, hover and focus, the static grid (reduced motion / no JS)
   and the stacked layout (phones, upright windows). The words keep
   fold.css; the two-class selectors below only re-seat them.

   Everything is px (styles_v3 sets html font-size 62.5%), every class is
   hv2-, every token hangs off .hv2 (base.css). Only transform and opacity
   move per frame; the engine writes translate3d on .hv2-wall-track and
   nothing else. Light-theme rules: theme-light/parts/72-home-wall-fable.css.

   THE MEASURED BAR (superside.com, 2026-09-19): 3 columns 181px wide, 16px
   gaps, a fixed 753px hero, tiles at two heights, a vertical mask fading
   the top and bottom quarters, 25px/s per column, neighbours opposite,
   hover slows the column to 0.3x. Ours: 12px gaps, the source aspect per
   tile, 18/13/22px/s, hover stops the column, a 12% fade and a left
   vignette so the words own the left third.
   ============================================================ */

/* ---- the section: words | wall, proof under the words ---------------- */
.hv2-wall-hero {
  position: relative;
  height: calc(100vh - var(--hv2-header-h));
  min-height: 560px;
  /* 900, not the still's 1100: on a 1080p screen the still needs the room,
     the wall does not, and the void between the button and the capsule grew
     with every extra pixel (the fold critic, round 1: 272px at 1920). */
  max-height: 900px;
  overflow: hidden;
  background: #000;
  display: grid;
  grid-template-columns: minmax(0, 46fr) minmax(0, 54fr);
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas:
    "words wall"
    "proof wall";
}
.hv2-wall-words {
  grid-area: words;
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* 40px off the edge up to 1440, then the gutter grows with the screen so
     the words never hug the edge of a 1920 canvas (fold critic, round 1). */
  padding: 24px 24px 12px clamp(40px, calc((100vw - 1440px) / 2 + 40px), 160px);
  min-width: 0;
}
/* fold.css seats the identity block absolute at 40/22 for the film; here it
   is a static block in the words column, centred on the hero's height. Two
   classes beat fold.css's one at every width. */
.hv2-wall-hero .hv2-identity {
  position: static;
  max-width: 640px;
  pointer-events: auto;
}
/* The words own 46% of the screen here, not a corner of a film frame, so
   the headline takes one more step than fold.css's clamp (54 at 1280, 60 at
   1440, 64 at 1920) and the h1 balances its two lines instead of orphaning
   "Texas." — both from the fold critic, round 1.
   2026-09-21 (Ale): one step further again. At 64px the headline hit its
   ceiling while the column kept growing, so the words stopped short of the
   wall and the fold read barren at 1440 and above. 4.9vw/84px lets the type
   use the column it already owns; 0.96 keeps the two lines reading as one
   block at the larger size. The 46/54 split is deliberately UNCHANGED —
   narrowing the words column wraps "10 YEAR WARRANTY" onto two lines in the
   capsule. */
.hv2-wall-hero .hv2-headline { font-size: clamp(34px, 4.9vw, 84px); line-height: 0.96; text-shadow: none; }
/* 40ch, not 30 (Ale, 2026-09-21): the category line now carries a hard <br>
   after "sirens.", and "Emergency vehicle lighting and sirens." is 38 characters,
   so a 30ch box would soft-wrap it a second time and defeat the break. */
.hv2-wall-hero .hv2-category { text-shadow: none; text-wrap: balance; max-width: 40ch; }
.hv2-wall-hero .hv2-identity .hv2-cta-row { margin-top: 24px; }

/* THE CAPSULE joins the stack: static, 40px under the button, left-aligned
   with SYNCHRONIZE, so headline, h1, button and proof read as one group
   (fold critic, rounds 1 and 2: anchored to the hero's foot it read as a
   footer with a 200-270px void above it). The whole group is centred on the
   hero's height; while the consent bar is up the column pads its foot so the
   group rides clear of it — the :has() rule out-ranks fold.css's (0,3,1 over
   0,2,1), and bottom: on a static box is inert anyway. */
.hv2-wall-hero .hv2-proof {
  position: static;
  left: auto;
  bottom: auto;
  transform: none;
  width: min(640px, 100%);
  margin: 0;
  /* The capsule is the live homepage's — fold.css's blur, line, radius and
     centred type, 70-home-live.css's light colours mirrored in the light part
     (Hamza, 2026-09-19 evening: "match exactly how they look on the actual
     live homepage") — with ONE change on the dark theme: the live glass is
     rgba(8,8,8,.6), which over the still's photograph reads as a capsule and
     over this flat black ground all but vanishes. A lighter dark, still dark
     (Hamza, same night: "a lighter but still maybe dark shade so people can
     see them better"), and a line one step stronger. */
  background: rgba(34, 35, 38, 0.92);
  border-color: rgba(255, 255, 255, 0.2);
}
/* THE CAPSULE'S SEAT (Hamza, 2026-09-19 late: "lower the 3 tabs to the bottom
   before the fold"): the foot copy sits in the grid's bottom row, on the words'
   gutter, 76px off the fold — the still hero's own seat — and rides up above
   the consent bar while it is up; the words stay centred in the row above.
   The copy inside the words column is hidden on desktop and shows only in
   the stacked layout, where the foot copy is hidden instead. */
.hv2-wall-words .hv2-proof { display: none; }
.hv2-wall-foot {
  grid-area: proof;
  display: block;
  margin: 0 24px 76px clamp(40px, calc((100vw - 1440px) / 2 + 40px), 160px);
  transition: margin-bottom 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
body:has(.cky-consent-container:not(.cky-hide)) .hv2-wall-foot {
  margin-bottom: calc(var(--hv2-cookie-safe) + 10px);
}
/* Under 1400px the words column is ~525px, a third of the live capsule's
   840: the cells keep the live type and lose 6px of side padding each so
   "10 YEAR WARRANTY" stays on one line. */
@media (max-width: 1400px) {
  .hv2-wall-foot .hv2-proof-cell { padding-left: 10px; padding-right: 10px; }
  .hv2-wall-foot .hv2-proof-l { letter-spacing: 0.08em; white-space: nowrap; }
}

/* ---- the wall --------------------------------------------------------- */
.hv2-wall {
  grid-area: wall;
  position: relative;
  z-index: 1;
  height: 100%;
  min-height: 0;
  padding: 0 40px 0 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  overflow: hidden;
  /* fades in once the first posters have decoded (engine adds is-ready) */
  opacity: 0;
  transition: opacity 0.6s ease;
}
.hv2-wall.is-ready,
.hv2-wall.is-static { opacity: 1; }
/* THE EDGES. Painted overlays, not a mask-image: a mask makes the browser
   re-composite the whole wall through an offscreen surface every frame the
   tracks move, and in software rendering that alone cost ~30ms a frame. Three
   static gradient layers over three moving layers cost nothing. Top and
   bottom 12% dissolve so tiles enter and leave softly; the left 70px so the
   words own the left third. */
.hv2-wall-shade,
.hv2-wall-fade {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}
/* The left edge is a whisper, not a wall (Hamza, 2026-09-19 night: "the fade
   on the left side is a little strong"): 44px, and it starts at 62% rather
   than solid, so the first column's tiles keep their own edge instead of
   dissolving into the ground. Same weight in both themes. */
.hv2-wall-shade {
  top: 0;
  bottom: 0;
  left: 0;
  width: 44px;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.62) 0, rgba(0, 0, 0, 0) 100%);
}
.hv2-wall-fade {
  left: 0;
  right: 40px;
  height: 24%; /* the bar's 25/75 mask; the last 10% is solid so a tile never ends on a visible edge */
}
.hv2-wall-fade--top {
  top: 0;
  background: linear-gradient(180deg, #000 0, #000 10%, rgba(0, 0, 0, 0) 100%);
}
.hv2-wall-fade--bottom {
  bottom: 0;
  background: linear-gradient(0deg, #000 0, #000 10%, rgba(0, 0, 0, 0) 100%);
}
/* The page ground behind the hero. The merged bundle paints body the site's
   light photo ground (#fbfbfb), which flashed as a white band above the header
   and under the fold during a wheel burst (motion critic, round 2: Lenis
   overscroll). This page is dark from the header to the footer, so the ground
   is black wherever the wall is on the page, and overscroll does not bounce;
   the light part restores the light ground under the light theme. */
html:has(#hv2-wall-hero) { overscroll-behavior-y: none; }
body:has(#hv2-wall-hero) { background: #000; }
.hv2-wall-col {
  position: relative;
  height: 100%;
  min-width: 0;
  overflow: hidden;
}
.hv2-wall-track {
  display: flex;
  flex-direction: column;
  gap: 12px;
  will-change: transform;
}

/* ---- the tile face ---------------------------------------------------- */
.hv2-wall-tile {
  position: relative;
  display: block;
  flex: 0 0 auto;
  width: 100%;
  aspect-ratio: var(--vw-ar, 4 / 3); /* the source aspect, from the manifest (inline --vw-ar) */
  background: #000;
  border: 1px solid rgba(255, 255, 255, 0.12); /* every tile has an edge, even a dark one */
  border-radius: 10px;
  overflow: hidden;
  text-decoration: none;
  color: var(--hv2-ink);
  transition: filter 0.22s ease, transform 0.22s ease, border-color 0.22s ease;
}
.hv2-wall-tile img,
.hv2-wall-tile video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain; /* the whole vehicle, the whole product, always */
  background: #000;
}
.hv2-wall-video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.hv2-wall-video.is-playing { opacity: 1; }
.hv2-wall-tile:hover,
.hv2-wall-tile:focus-visible {
  filter: brightness(1.06);
  transform: scale(1.02);
  border-color: rgba(255, 255, 255, 0.16);
  z-index: 1;
}
.hv2-wall-tile:focus-visible {
  outline: 2px solid var(--hv2-accent);
  outline-offset: 2px;
}
/* the caption: hover and focus only, a bottom gradient the words sit in —
   not a chip, which covered the product on the wall's one interaction
   (fold critic, round 2) */
.hv2-wall-cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 44px 14px 12px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0.78) 100%);
  opacity: 0;
  visibility: hidden; /* not painted at all until hovered: the blur is not free */
  transform: translateY(6px);
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0s linear 0.22s;
  pointer-events: none;
}
.hv2-wall-tile:hover .hv2-wall-cap,
.hv2-wall-tile:focus-visible .hv2-wall-cap {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0s;
}
.hv2-wall-cap-1 {
  display: block;
  font-family: "Oswald", sans-serif;
  font-weight: 600;
  font-size: 13px;
  line-height: 1.1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
}
.hv2-wall-cap-2 {
  display: block;
  margin-top: 3px;
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244, 245, 247, 0.62);
}

/* ---- static: reduced motion, no JS (the noscript block in the partial
   repeats these, KEEP IN SYNC) ------------------------------------------ */
.hv2-wall.is-static {
  opacity: 1;
  -webkit-mask-image: none;
  mask-image: none;
  align-content: start;
}
.hv2-wall.is-static .hv2-wall-col { height: auto; overflow: visible; }
.hv2-wall.is-static .hv2-wall-track { display: grid; gap: 12px; transform: none; will-change: auto; }
.hv2-wall.is-static .hv2-wall-track > .hv2-wall-tile:nth-child(n+3) { display: none; }
.hv2-wall.is-static .hv2-wall-video { display: none; }
.hv2-wall.is-static .hv2-wall-shade,
.hv2-wall.is-static .hv2-wall-fade { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hv2-wall {
    opacity: 1;
    align-content: start;
  }
  .hv2-wall-col { height: auto; overflow: visible; }
  .hv2-wall-track { display: grid; gap: 12px; transform: none; will-change: auto; }
  .hv2-wall-track > .hv2-wall-tile:nth-child(n+3) { display: none; }
  .hv2-wall-video { display: none; }
  .hv2-wall-shade,
  .hv2-wall-fade { display: none; }
  .hv2-wall-tile,
  .hv2-wall-cap { transition: none; }
}

/* ---- stacked: phones and upright windows (hero.css's own breakpoint;
   the engine's static gate is 860px / reduced motion, KEEP IN SYNC) ------ */
@media (max-width: 860px), (max-aspect-ratio: 3/2) {
  .hv2-wall-hero {
    height: auto;
    min-height: 0;
    max-height: none;
    display: flex;
    flex-direction: column;
    padding: 26px 0 24px;
  }
  .hv2-wall-words {
    order: 1;
    justify-content: flex-start;
    padding: 0 22px;
  }
  .hv2-wall-hero .hv2-identity { max-width: none; }
  .hv2-wall {
    order: 2;
    height: auto;
    padding: 18px 16px 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    opacity: 1;
  }
  .hv2-wall-shade,
  .hv2-wall-fade { display: none; }
  .hv2-wall-col { height: auto; overflow: visible; }
  .hv2-wall-col:nth-child(6) { display: none; } /* the third column: shade, fade, fade, col, col, COL */
  .hv2-wall-track { display: grid; gap: 12px; transform: none; will-change: auto; }
  .hv2-wall-track > .hv2-wall-tile:nth-child(n+3) { display: none; }
  /* Four tiles, one shape: the stacked grid locks every cell to 4:3 (contain,
     never a crop) so the two rows land level — mixed source aspects made a
     ragged masonry with a hole under the shortest tile (the mobile critic,
     round 1). The manifest keeps the first two tiles of columns A and B as
     two lit vehicles over two product close-ups for exactly this grid. */
  .hv2-wall-tile { aspect-ratio: 4 / 3; }
  .hv2-wall-video { display: none; }
  .hv2-wall-cap { display: none; }
  /* The one button is red on the phone too. fold.css turns the film's phone
     button into a full-width ghost; on this fold the only other red is the
     word EVERYTHING and the header's cart icon, and the eye landed on the
     cart. A concept-page call; Hamza can veto it. */
  .hv2-wall-hero .hv2-identity .hv2-btn {
    background: var(--hv2-accent);
    border-color: var(--hv2-accent);
    color: #fff;
  }
  .hv2-wall-hero .hv2-proof {
    order: 3;
    width: auto;
    margin: 18px 16px 0;
  }
  .hv2-wall-foot { display: block; order: 3; margin: 0; }
  body:has(.cky-consent-container:not(.cky-hide)) .hv2-wall-foot { margin-bottom: 0; }
}
/* Upright tablets: the stacked layout on a 1000px canvas wants a bigger
   headline than the phone clamp gives it. */
@media (min-width: 700px) and (max-aspect-ratio: 3/2) {
  .hv2-wall-hero .hv2-headline { font-size: clamp(44px, 6vw, 64px); }
  .hv2-wall-hero .hv2-category { font-size: clamp(17px, 2vw, 22px); }
}
@media (max-width: 600px) {
  .hv2-wall-hero .hv2-proof { margin: 18px 16px 0; }
}
