/* =============================================================
   MOVE IT CLEAR IT — hero-video.css
   EXPERIMENTAL full-bleed video hero. index.html ONLY.

   SOURCE (rev 5, 2026-08-04): a two-source recut, 7.37s, silent, built around
   the WRAP as the proof shot — crew carrying the wrapped piece outside (3.0s)
   -> the shrink-wrapped sofas inside at half speed (3.5s) -> the room finishing
   with the wrap still leaving frame (0.87s) -> a 0.2s dissolve back into the
   opening so the loop has no seam. Desktop is 1920x1080, FULL frame, uncropped
   and centred; mobile is a centred 9:16 column. An earlier revision cropped to
   the lower band to dodge text burned into a different edit of this footage and
   was rejected for destroying the scene — do not reintroduce a crop here.

   Rev 5 is rev 4 creatively unchanged — same footage, same in/out points for
   the crew and sofa beats, same 0.5x slow motion, same tonemap and shot match,
   same mobile crop, same 0.2s A->B dissolve and B->C hard cut. Only two things
   moved: the finishing beat shortened 1.30s -> 0.87s, and both files were
   re-optimised. 720x1280 was tested for mobile and REJECTED: at the size a
   phone actually paints (1125px on a DPR-3 handset) the 1.56x upscale visibly
   softened the plastic-wrap striations and the movers' faces, while 1080x1920
   at the SAME 3.5MB held both.

   FINAL QUALITY PASS (v=6): desktop CRF 25 -> 24 (6.98 -> 7.97 MB) and mobile
   CRF 28 -> 27 (3.52 -> 4.01 MB). Nothing else in the edit changed. Sharpening
   was TESTED AND REJECTED — cas=0.20 did lift the wrap micro-texture slightly
   with no halos, but it cost +0.61 MB (7.97 -> 8.58) which overshoots the
   agreed 7.8-8.2 MB ceiling, and cas=0.35 began etching the floorboards. The
   CRF bump alone buys the detail more cheaply; do not add a sharpen filter
   here without re-running that comparison.

   MOBILE IS ITS OWN EDIT AND ITS OWN ASPECT (v7, 2026-08-04). The desktop file
   is unchanged and approved; do not touch it.

   THE MOBILE CONTAINER IS NOT 9:16. Measured with getBoundingClientRect on
   .hero-media, the box is:
       360x780 -> 360x310 (1.161)    375x667 -> 375x273 (1.374)
       375x812 -> 375x320 (1.172)    390x844 -> 390x440 (0.886)
       430x932 -> 430x479 (0.898)
   i.e. it ranges from slightly PORTRAIT to clearly LANDSCAPE. Under
   object-fit:cover the painted fraction of the file is A/B (or B/A), so a
   0.5625 export left only 41% of the frame on screen at 375x667 — which is
   what turned the sofa into an unreadable close-up.

   The aspect that maximises the WORST case is sqrt(0.886 x 1.374) = 1.1034, so
   the mobile file is exported 1188x1080 (1.1:1). Every measured container now
   keeps >= 80% of the frame, and the crop takes 2376 of 3840 source px (62%)
   instead of 1215 (32%) — that extra width is what puts the whole sofa,
   its armrest, the second wrapped sofa and the room back on screen.
   3:4 and 4:5 were computed too and only reach 55% / 58% worst-case.

   VERTICAL SAFE AREA (v8). The fixed nav sits OVER the top of the media band,
   and on short phones it eats a lot of it — measured: 39.5% of the band at
   375x667, 34.9% at 360x780, 33.8% at 375x812, 24.6% at 390x844, 22.5% at
   430x932. Mapped back into the 1188x1080 canvas, the strip actually visible
   BELOW the divider is y 449-973 at 375x667 (centre 711) against a canvas
   centre of 540 — i.e. anything centred in the file reads ~170px too HIGH on a
   short phone, which is why v7 showed sofa-then-a-lot-of-floor.

   The crop already reached the top of the source, so it could not be moved up.
   The sofa beat therefore uses a SHORTER crop ANCHORED AT y=0 (1980x1800
   instead of 2376x2160): that drops the surplus foreground floor and moves the
   content DOWN the canvas by ~8.4% at the sofa's centre. ONLY the sofa beat is
   repositioned — the crew beat is approved and still 2376x2160 @ x732.

   If you re-cut mobile: re-measure the box AND the nav overlap first, then
   judge every frame on what survives BELOW the divider, not on the source.

   The rev-2 assets were marked APPROVED / do-not-re-encode; this rev replaces
   them on an explicit recut request. If you re-encode again, keep the tonemap:
   both camera originals are HLG BT.2020 10-bit, and the operator that matches
   the approved look is tonemap=hable:desat=0 at npl=100 — measured against the
   shipped rev-2 encode, mobius/reinhard/clip land 20-32% brighter and
   libplacebo lands desaturated.

   LAYOUT (rev 4). The copy sits LEFT, over the house and the entrance, which
   is the quiet part of the frame. The wrapped furniture is near centre and the
   movers are centre-right, so anything on the right covers the actual work —
   that is exactly what the previous right-hand panel did. Phones drop the
   overlay entirely and stack: video block on top, solid navy content below.

   REVERT: delete the one <link> in index.html. No other page loads this, and
   every selector is anchored on body.page-home or #hero.hero-video.
============================================================= */

/* ============================================================
   1. TOKENS
   Declared on BODY, not on #hero: #main-nav is a SIBLING of <main>, so tokens
   declared on the hero never reach it and every nav rule below would collapse
   to an invalid value.
============================================================ */
body.page-home {
  --hv-text:       #F5F1EA;                    /* Bone White */
  --hv-text-soft:  rgba(245, 241, 234, 0.90);
  --hv-text-muted: rgba(245, 241, 234, 0.74);
  --hv-line:       rgba(245, 241, 234, 0.42);
  --hv-line-soft:  rgba(245, 241, 234, 0.22);
  --hv-hover:      rgba(245, 241, 234, 0.10);

  --hv-pad:        clamp(28px, 5vw, 96px);     /* hero gutter */
  --hv-copy:       min(560px, 36vw);           /* copy measure */
  /* Proportional, not fixed: a flat 100px ramp is ~5% of a 1920 screen but
     ~7% of a 1440 one, which pushed total panel coverage past 48% there. */
  --hv-feather:    clamp(60px, 5vw, 100px);    /* panel's soft right edge */
  /* Stacked layouts only. The header sits OVER the top of this block, so the
     nav height is added on top of the target — otherwise the footage a visitor
     can actually see is 40svh minus the chrome, and it drops further again
     when the promo bar is showing. */
  --hv-media-h:    calc(48svh + var(--nav-h));
}

/* ============================================================
   2. SHELL
============================================================ */
/* The home page is the only page whose first section is full-bleed, so it is
   the only one that gives up the body offset reserving room for the fixed nav.
   #hero-inner puts that space back as padding: the COPY clears the nav, the
   VIDEO keeps running underneath it. */
body.page-home { padding-top: 0; }

#hero.hero-video {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  isolation: isolate;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  background: var(--navy);
  /* svh, not vh: on iOS `vh` is the LARGEST viewport, so a vh-sized hero is
     taller than the screen while the browser chrome shows and the CTA hides
     under it. The vh line is the fallback for browsers without svh. */
  min-height: 92vh;
  min-height: 92svh;
}
#hero.hero-video::before { display: none; }   /* old bone-hero glows */

/* ============================================================
   3. MEDIA
   max-width/margin are load-bearing: style.css:142 sets
   `main > section > * { max-width: var(--max-w); margin-inline: auto }`, and on
   an inset:0 absolute box `margin:auto` CENTRES it — without these the video
   renders 1180px wide with bare navy bands down both edges.
============================================================ */
#hero.hero-video .hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  max-width: none;
  margin: 0;
  background-color: var(--navy);
  background-image: url('../img/move-it-clear-it-hero-poster.webp?v=6');
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

#hero.hero-video .hero-media-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;   /* full frame, centred, no transform */
  border: 0;
  pointer-events: none;
}

/* ============================================================
   4. SCRIM — global, deliberately light
   Only enough to seat the header and the bottom edge. Text contrast is the
   panel's job (§5), so the picture is NOT uniformly dimmed and the movers keep
   their natural brightness.
============================================================ */
#hero.hero-video .hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  max-width: none;
  margin: 0;
  background:
    linear-gradient(180deg,
      rgba(10, 22, 40, 0.40) 0%,
      rgba(10, 22, 40, 0.04) 20%,
      rgba(10, 22, 40, 0.00) 50%,
      rgba(10, 22, 40, 0.22) 100%),
    linear-gradient(0deg, rgba(10, 22, 40, 0.05), rgba(10, 22, 40, 0.05));
}

/* ============================================================
   5. THE PANEL — full-height Ink Navy field on the LEFT, feathering right.
   Anchored to #hero-copy, not to a viewport percentage, so the feather lands
   exactly where the text ends at every width with no breakpoint arithmetic.
   Stops are absolute lengths measured from the pseudo-element's RIGHT edge, so
   the ramp is always --hv-feather wide however far left the box overshoots.
   top/bottom overshoot gives full hero height; the hero clips it.
============================================================ */
#hero.hero-video #hero-copy { position: relative; }

#hero.hero-video #hero-copy::before {
  content: '';
  position: absolute;
  left: calc(-1 * var(--hv-pad) - 50vw);    /* runs out to the viewport edge */
  right: calc(-1 * var(--hv-feather));
  top: -100vh;
  bottom: -100vh;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to left,
    rgba(10, 22, 40, 0.00) 0,
    rgba(10, 22, 40, 0.55) calc(var(--hv-feather) * 0.40),
    rgba(10, 22, 40, 0.94) var(--hv-feather),
    rgba(10, 22, 40, 0.97) 100%);
}

/* ============================================================
   6. CONTENT — left aligned
============================================================ */
#hero.hero-video #hero-inner {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: flex-start;    /* copy left, over the quiet house side */
  grid-template-columns: none;
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  padding: calc(var(--nav-h) + 28px) var(--hv-pad) 92px;
}
body.lang-banner-visible #hero.hero-video #hero-inner {
  padding-top: calc(var(--nav-h) + 28px + 46px);
}

#hero.hero-video #hero-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 18px;
  width: var(--hv-copy);
  max-width: 100%;
  margin: 0;
}

/* ONE source of vertical rhythm. Every child carried its own margin-bottom,
   which ADDS to the flex gap instead of replacing it. margin-inline matters
   too: .brand-truck-note is `margin: 18px auto 0`, and an auto inline margin
   in a flex column centres the item. */
#hero.hero-video #hero-copy > * { margin: 0; }
#hero.hero-video #hero-deposit-note { margin-top: -4px; }

/* ── DE-CLUTTER ─────────────────────────────────────────────
   Hidden, not deleted: markup, translations and analytics hooks stay intact,
   so restoring any of these is deleting one line. The supporting paragraph
   already states truck-included, labor-only and customer-supplied
   truck/container/storage, which is what made these repetitive.
   display:none also removes them from the accessibility tree, which is the
   point — a hidden duplicate a screen-reader user still hears is not removed. */
#hero.hero-video .brand-truck-note,
#hero.hero-video #hero-copy .starting-context,
#hero.hero-video #hero-cta-text { display: none; }

/* ── Type ───────────────────────────────────────────────────
   Antique Gold on Ink Navy is ~7.3:1. style.css says 12px gold fails contrast —
   that measurement was gold on the BONE hero, where it genuinely does. */
#hero.hero-video #hero-eyebrow {
  color: var(--gold);
  letter-spacing: 0.16em;
  font-size: 0.8125rem;
}

#hero.hero-video #hero-copy h1 {
  color: var(--hv-text);
  font-size: clamp(3.25rem, 4vw, 4.5rem);   /* 52 -> 72px */
  line-height: 0.99;
  letter-spacing: -0.03em;
  max-width: 100%;
  /* NO text-wrap:balance. It optimises for even line LENGTHS and strands
     "Lifting." on its own; natural wrapping breaks after the full stop:
       Save Your Back. / We Handle the / Heavy Lifting. */
  text-shadow: 0 2px 24px rgba(10, 22, 40, 0.40);
}

/* Matches the :not() chain in style.css and adds an id so it wins without
   !important. Do not shorten it — see the note at style.css:493. */
#hero.hero-video #hero-copy > p:not(#hero-eyebrow):not(#hero-deposit-note):not(#hero-urgency):not(.starting-context) {
  color: var(--hv-text-soft);
  font-size: 1.0625rem;
  line-height: 1.55;
  max-width: 32em;      /* never reaches toward the movers */
}

#hero.hero-video #hero-deposit-note {
  color: var(--hv-text-muted);
  font-size: 0.8125rem;
}

/* ── Google rating: credible, subordinate to the headline ── */
#hero.hero-video #hero-stars { gap: 7px; }
#hero.hero-video #hero-star-rating { color: var(--hv-text); font-size: 1rem; }
#hero.hero-video #hero-star-label  { color: var(--hv-text-muted); }
#hero.hero-video #hero-star-label:hover,
#hero.hero-video #hero-star-label:focus-visible {
  color: var(--hv-text);
  border-bottom-color: var(--hv-line);
}

/* ── Actions: ONE solid ember button, one restrained phone action ── */
#hero.hero-video #hero-cta-group { gap: 14px; align-items: center; }
#hero.hero-video #hero-cta-primary {
  padding: 17px 38px;
  font-size: 1.0625rem;
  box-shadow: 0 8px 28px rgba(10, 22, 40, 0.44), var(--shadow-orange);
}
#hero.hero-video #hero-phone {
  border-color: var(--hv-line);
  background: rgba(245, 241, 234, 0.06);
}
#hero.hero-video #hero-cta-call { color: var(--hv-text); }
#hero.hero-video #hero-cta-call:hover { background: var(--hv-hover); }

/* ============================================================
   7. NAVIGATION OVER THE HERO — home page only.
   The header is NOT rebuilt: markup, links, mobile menu, sticky behaviour and
   CTA destination are untouched. Only its skin changes while at the top.
   A navy scrim rather than transparency, so bone text always has something to
   sit on and the mobile menu can open at the top without the bar going blank.
   Deliberately no :has() — contrast must not depend on selector support.
============================================================ */
body.page-home #main-nav {
  background: linear-gradient(to bottom,
    rgba(10, 22, 40, 0.70) 0%,
    rgba(10, 22, 40, 0.34) 62%,
    rgba(10, 22, 40, 0.00) 100%);
  border-bottom-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition: background var(--t), border-color var(--t), box-shadow var(--t);
}

body.page-home #main-nav:not(.scrolled) #nav-logo,
body.page-home #main-nav:not(.scrolled) #nav-phone,
body.page-home #main-nav:not(.scrolled) #nav-links:not(.is-open) a {
  color: var(--hv-text);
}
body.page-home #main-nav:not(.scrolled) #nav-logo:hover,
body.page-home #main-nav:not(.scrolled) #nav-phone:hover { color: var(--gold); }

/* :not(.is-open) matters — the mobile menu is a WHITE panel, so its links must
   stay navy. Bone links on a bone panel would be invisible. */
body.page-home #main-nav:not(.scrolled) #nav-links:not(.is-open) a:hover {
  color: var(--hv-text);
  background: var(--hv-hover);
}
body.page-home #main-nav:not(.scrolled) #nav-hamburger span { background: var(--hv-text); }
body.page-home #main-nav:not(.scrolled) #nav-hamburger:hover { background: var(--hv-hover); }

/* #nav-cta carries no fill anywhere on the site (the shared button rule gives
   it the shape; the fill belongs to .btn-primary, which it does not have). On
   five white pages it reads as navy text; over video it needed handling.
   A BONE GHOST button, not a second solid ember one — there is already one
   Ember CTA on this screen and two would split the primary action. */
body.page-home #main-nav:not(.scrolled) #nav-cta {
  color: var(--hv-text);
  background: rgba(245, 241, 234, 0.10);
  border-color: var(--hv-line);
}
body.page-home #main-nav:not(.scrolled) #nav-cta:hover {
  background: rgba(245, 241, 234, 0.18);
  border-color: var(--hv-text);
  color: var(--hv-text);
}

/* EN/ES is navy-on-navy at rest, so it inverts. The SELECTED language keeps
   its white pill — that already reads on a dark bar and must stay obvious. */
body.page-home #main-nav:not(.scrolled) .lang-toggle {
  background: rgba(245, 241, 234, 0.14);
  border-left-color: var(--hv-line-soft);
}
body.page-home #main-nav:not(.scrolled) .lang-toggle button { color: rgba(245, 241, 234, 0.80); }
body.page-home #main-nav:not(.scrolled) .lang-toggle button:hover:not(.active) {
  background: var(--hv-hover);
  color: var(--hv-text);
}
body.page-home #main-nav:not(.scrolled) .lang-toggle button[aria-pressed="true"],
body.page-home #main-nav:not(.scrolled) .lang-toggle button.active {
  background: var(--white);
  color: var(--navy);
}

/* main.js already toggles .scrolled past 8px; once on, the header returns to
   exactly the component style.css defines. */
body.page-home #main-nav.scrolled {
  background: rgba(255, 255, 255, 0.96);
  border-bottom-color: var(--navy-12);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

body.page-home #main-nav:not(.scrolled) a:focus-visible,
body.page-home #main-nav:not(.scrolled) button:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(245, 241, 234, 0.35);
  border-radius: var(--radius-sm);
}

/* ============================================================
   8. PROMO BAR — homepage only.
   A full-width solid Ember band above a premium video reads as a coupon site.
   The offer, phone number and close control are unchanged; only the colour
   weight moves — Ink Navy field, Bone text, Ember kept for the DISCOUNT itself.
   HEIGHT IS DELIBERATELY NOT CHANGED: style.css hard-codes the nav offset for
   this bar at 46px/48px and #hero-inner mirrors it. Changing the height here
   would desynchronise three files.
============================================================ */
body.page-home #lang-banner {
  background: rgba(10, 22, 40, 0.94);
  color: var(--hv-text);
  border-bottom: 1px solid rgba(245, 241, 234, 0.12);
}
body.page-home #lang-banner .promo-offer { color: var(--orange); }
body.page-home #lang-banner .promo-audience,
body.page-home #lang-banner .promo-instruction,
body.page-home #lang-banner .promo-call-short { color: var(--hv-text-muted); }
body.page-home #lang-banner .promo-phone { color: var(--hv-text); }
body.page-home #lang-banner .promo-phone:hover { color: var(--gold); }
body.page-home #lang-banner .promo-divider { background: rgba(245, 241, 234, 0.24); }
body.page-home #lang-banner .promo-badge-bg  { fill: var(--orange); }
body.page-home #lang-banner .promo-badge-pct { stroke: var(--navy); }
body.page-home #lang-banner .promo-badge-dot { fill: var(--navy); }
/* 2026-08-04: the ring moved to ::before in style.css so the 44px TAP TARGET
   and the ~35px VISIBLE CONTROL can differ. These overrides have to move with
   it — left on the button they painted the whole 44px box as a bone disc,
   which is the heavy control the refinement was meant to remove. Bone tints
   here (the homepage banner is Ink Navy, not Ember), at the same reduced
   weights as the base: border 0.40 -> 0.22, fill 0.10 -> 0.06. */
body.page-home #lang-banner-close {
  border-color: transparent;
  background: transparent;
  color: var(--hv-text);
}
body.page-home #lang-banner-close::before {
  border-color: rgba(245, 241, 234, 0.22);
  background: rgba(245, 241, 234, 0.06);
}
body.page-home #lang-banner-close:hover::before {
  border-color: rgba(245, 241, 234, 0.38);
  background: rgba(245, 241, 234, 0.12);
}
body.page-home #lang-banner-close:active::before {
  background: rgba(245, 241, 234, 0.18);
}
body.page-home #lang-banner-close svg { stroke: var(--hv-text); }
body.page-home #lang-banner-close:focus-visible { outline: none; }
body.page-home #lang-banner-close:focus-visible::before {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* ============================================================
   9. SCROLL CUE — overlay layouts only
============================================================ */
#hero.hero-video .hero-scroll {
  position: absolute;
  z-index: 2;
  left: var(--hv-pad);
  bottom: 30px;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 0;
  color: var(--hv-text-muted);
  text-decoration: none;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transition: color var(--t);
}
#hero.hero-video .hero-scroll:hover { color: var(--hv-text); }
#hero.hero-video .hero-scroll:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  color: var(--hv-text);
}
#hero.hero-video .hero-scroll svg { display: block; animation: hv-nudge 2.4s ease-in-out infinite; }
@keyframes hv-nudge {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

body.page-home #service-choice { scroll-margin-top: var(--nav-h); }

/* ── SERVICE-CARD TRUCK BADGES (homepage conversion pass, 2026-08-02) ──
   The two cards now each carry a badge answering the single question that
   separates the products: who brings the truck.

   The full-service card reuses .price-card-truck exactly as style.css defines
   it — gold, because style.css already reserves gold for "the included truck"
   and orange for primary actions. Only the customer-supplied variant is new,
   and it is a NEUTRAL navy rather than a second gold: gold means "we include
   it", so using it for "you provide it" would say the opposite of the truth.

   Lives here, not in style.css, because #service-choice exists on index.html
   only and this file is loaded by index.html only — so the whole experiment
   still reverts by deleting one <link>. */
body.page-home .price-card-truck--customer {
  color: var(--navy-60);
  background: var(--navy-06);
  border-color: var(--navy-12);
}

#hero.hero-video .hv-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   10. REDUCED MOTION
   The video is REMOVED, not paused, so nothing moves at all and the poster
   beneath becomes the hero. CSS only — no script decides this, so it is right
   on the first paint and cannot be broken by a JS error.
============================================================ */
@media (prefers-reduced-motion: reduce) {
  #hero.hero-video .hero-media-video { display: none; }
  #hero.hero-video .hero-scroll svg { animation: none; }
  body.page-home #main-nav { transition: none; }
}

/* ============================================================
   11. LANDSCAPE TABLET / SMALL LAPTOP — keep the left overlay.
   Chosen on SHAPE, not device label: a wide-but-short window still has room
   for the picture beside the copy, so the overlay holds. Portrait windows fall
   through to the stacked layout in §12, where a narrow video sliver next to a
   tall text block would be the wrong answer.
============================================================ */
@media (max-width: 1024px) and (orientation: landscape) {
  /* 46vw put the panel at 59.7% of a 1024x768 screen — over the ~50% ceiling
     for landscape tablets, and it was eating the movers. 38vw still holds
     "Save Your Back." on one line at this H1 size. */
  body.page-home { --hv-copy: min(430px, 38vw); --hv-feather: 60px; }
  #hero.hero-video #hero-inner { padding: calc(var(--nav-h) + 18px) var(--hv-pad) 72px; }
  body.lang-banner-visible #hero.hero-video #hero-inner {
    padding-top: calc(var(--nav-h) + 18px + 46px);
  }
  #hero.hero-video #hero-copy { gap: 15px; }
  #hero.hero-video #hero-copy h1 { font-size: clamp(2.25rem, 4.4vw, 3rem); }
  #hero.hero-video #hero-copy > p:not(#hero-eyebrow):not(#hero-deposit-note):not(#hero-urgency):not(.starting-context) {
    font-size: 1rem;
  }
}

/* ============================================================
   12. STACKED — phones and PORTRAIT tablets.
   The overlay is dropped entirely here. On a narrow screen any panel large
   enough to hold this copy covers the whole picture, so the video gets its own
   block at the top and the copy gets a solid navy block underneath it. The
   only thing still over the footage is the fixed header.
============================================================ */
@media (max-width: 640px), (max-width: 900px) and (orientation: portrait) {

  #hero.hero-video {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    /* content-driven: the brief allows the hero to run past one screen rather
       than shrink the type to fit. */
    min-height: 0;
    min-height: auto;
    background: var(--navy);
  }

  /* ── the video block ── */
  #hero.hero-video .hero-media {
    position: relative;
    inset: auto;
    flex: 0 0 auto;
    width: 100%;
    height: var(--hv-media-h);
    min-height: 320px;
    background-image: url('../img/move-it-clear-it-hero-poster-mobile.webp?v=8');
    background-position: 50% 50%;
  }
  /* 50% 50% checked against the whole loop: it holds the wrapped piece and at
     least one mover's upper body in frame throughout, with the house behind.
     45% drifts toward heads-and-sky, 55% toward legs. */
  #hero.hero-video .hero-media-video { object-position: 50% 50%; }

  /* the scrim now only seats the header over the video block */
  #hero.hero-video .hero-scrim {
    height: var(--hv-media-h);
    min-height: 320px;
    bottom: auto;
    background: linear-gradient(180deg,
      rgba(10, 22, 40, 0.66) 0%,
      rgba(10, 22, 40, 0.18) 30%,
      rgba(10, 22, 40, 0.00) 58%);
  }

  /* no overlay panel — the content block is solid */
  #hero.hero-video #hero-copy::before { display: none; }

  #hero.hero-video #hero-inner {
    display: block;
    flex: 1 1 auto;
    max-width: none;
    background: var(--navy);
    padding: 28px 24px 32px;
  }
  /* the promo bar sits over the VIDEO block now, not the copy, so the copy
     does not compensate for it */
  body.lang-banner-visible #hero.hero-video #hero-inner { padding-top: 28px; }

  #hero.hero-video #hero-copy {
    width: 100%;
    gap: 12px;
  }

  #hero.hero-video #hero-copy h1 {
    font-size: clamp(2.2rem, 9vw, 2.65rem);
    line-height: 1.02;
    text-align: left;
  }
  /* 0.875rem, not 0.75rem: this selector scores (2 IDs, 1 class) and so beat
     brand-system.css's own 14px mobile floor for hero copy
     (`#main #hero-copy > p`, 2 IDs + 1 type), dropping the eyebrow to 12px on
     phones — the one width where it needed the floor most. */
  #hero.hero-video #hero-eyebrow { font-size: 0.875rem; text-align: left; }
  #hero.hero-video #hero-copy > p:not(#hero-eyebrow):not(#hero-deposit-note):not(#hero-urgency) {
    font-size: 1rem;
    text-align: left;
    max-width: 100%;
  }

  /* order: eyebrow, H1, paragraph, CTA + call, rating, $49 note */
  #hero.hero-video #hero-copy       { display: flex; flex-direction: column; }
  #hero.hero-video #hero-eyebrow    { order: 1; }
  #hero.hero-video #hero-copy h1    { order: 2; }
  #hero.hero-video #hero-sub        { order: 3; }
  #hero.hero-video #hero-cta-group  { order: 4; }
  #hero.hero-video #hero-stars      { order: 5; }
  #hero.hero-video #hero-deposit-note { order: 6; margin-top: 0; }

  /* Primary stays the big solid button; the phone action is deliberately
     shorter and quieter so it does not read as a second primary — still a
     44px touch target. */
  #hero.hero-video #hero-cta-group {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    max-width: 380px;
    gap: 10px;
  }
  #hero.hero-video #hero-cta-primary { width: 100%; justify-content: center; }
  #hero.hero-video #hero-phone {
    width: 100%;
    min-height: 44px;
    background: transparent;
    border-color: var(--hv-line-soft);
  }
  #hero.hero-video #hero-cta-call {
    flex: 1 1 auto;
    justify-content: center;
    font-size: 0.9375rem;
  }

  #hero.hero-video .hero-scroll { display: none; }
}

/* Phones only: slightly less than the tablet share, because the copy block
   below is proportionally taller on a narrow screen. Still clears the 40svh
   floor with the promo bar showing. */
@media (max-width: 640px) {
  body.page-home { --hv-media-h: calc(45svh + var(--nav-h)); }
  /* 46svh put the primary CTA 13px under the fold on a 390x844 phone. The
     brief ranks the CTA above the rating and the $49 note, so one svh of
     picture and a few pixels of rhythm buy it back. */
  #hero.hero-video #hero-inner { padding: 22px 24px 30px; }
  body.lang-banner-visible #hero.hero-video #hero-inner { padding-top: 22px; }
  #hero.hero-video #hero-copy { gap: 11px; }
}

/* Short PORTRAIT phones (iPhone SE / 8 at 375x667). The copy block is a fixed
   ~400px whatever the screen does, so on a 667px viewport a 45svh video puts
   the primary CTA 93px under the fold. Trading a little picture back gets it
   to ~35px under — "slightly below", which the brief allows, rather than out
   of sight. The headline is NOT reduced.
   NOTE: style.css already hides #hero-stars under 720px height (a pre-existing
   rule, 9598), so the rating is absent here by existing site design, not by
   anything this experiment does. */
/* Also triggers on NARROW screens, not only short ones: at 360px the copy
   wraps onto more lines than it does at 390px, which pushed the primary CTA
   19px under the fold on a 360x800 phone even though the viewport was tall. */
@media (max-width: 640px) and (max-height: 700px),
       (max-width: 380px) {
  /* 2026-08-03: 38svh never actually applied here. At 375x667 it computes to
     38% of 667 + 60px nav = 313px, but the 320px min-height on .hero-media
     (and its scrim) floored it at 320 — so the picture could not shrink and the
     primary CTA sat 32px UNDER the fold, measured. The earlier note above
     accepted "~35px under"; the current brief does not, and a primary CTA below
     the fold is a straight conversion loss on the smallest phones.
     32svh + a 250px floor gives a 273px band at 375x667 and lifts the CTA to
     ~652px — clear of the fold with room to spare.
     Checked against the footage, not just the arithmetic: at 375 wide the band
     shows ~41% of the frame height, which still holds the wrapped piece, the
     lead mover's head and shoulders, and later in the loop the second mover and
     the house. Only foreground path is lost. */
  body.page-home { --hv-media-h: calc(32svh + var(--nav-h)); }
  #hero.hero-video .hero-media,
  #hero.hero-video .hero-scrim { min-height: 250px; }
  #hero.hero-video #hero-inner { padding: 16px 24px 24px; }
  body.lang-banner-visible #hero.hero-video #hero-inner { padding-top: 16px; }
  #hero.hero-video #hero-copy { gap: 9px; }
}

/* Short landscape phones: the overlay layout applies (§11 shape rule), so the
   hero simply sizes to content and drops the cue. */
@media (max-height: 520px) and (orientation: landscape) {
  #hero.hero-video {
    min-height: 0;
    min-height: auto;
  }
  #hero.hero-video #hero-inner { padding-top: calc(var(--nav-h) + 16px); padding-bottom: 48px; }
  #hero.hero-video .hero-scroll { display: none; }
}
