/* ==========================================================================
   WATCH AND SHOP
   ========================================================================== */

.vshop__rail {
  list-style: none; margin: 0; padding: 0 0 6px;
  display: grid; grid-auto-flow: column; grid-auto-columns: 68%;
  gap: var(--grid-gap);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.vshop__rail::-webkit-scrollbar { display: none; }
.vshop__rail > * { scroll-snap-align: start; }
@media (min-width: 600px) { .vshop__rail { grid-auto-columns: 38%; } }
@media (min-width: 900px) { .vshop__rail { grid-auto-columns: 26%; } }
@media (min-width: 1200px) { .vshop__rail { grid-auto-columns: minmax(0, 1fr); grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); overflow: visible; } }

.vcard { display: flex; flex-direction: column; min-width: 0; }
.vcard__open {
  position: relative; display: block; width: 100%; padding: 0;
  border: 0; background: #111; cursor: pointer; overflow: hidden;
  aspect-ratio: 9 / 16;
}
.vcard__video { width: 100%; height: 100%; object-fit: cover; display: block; }
.vcard__open:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.vcard__play {
  position: absolute; left: 50%; top: 50%;
  width: 54px; height: 54px; margin: -27px 0 0 -27px;
  border-radius: 50%; background: rgba(255,255,255,.9);
  transition: transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.vcard__play::after {
  content: ""; position: absolute; left: 21px; top: 17px;
  border-left: 16px solid #111;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}
.vcard__open:hover .vcard__play { transform: scale(1.08); background: #fff; }

.vcard__foot { padding: var(--sp-sm) 0 0; }
.vcard__label { font-size: 0.9375rem; font-weight: 600; margin: 0 0 4px; }
.vcard__price { font-size: var(--fs-xs); color: var(--muted); margin: 0 0 var(--sp-sm); }
.vcard__price del { opacity: .6; margin-right: 6px; }
.vcard__cta { width: 100%; text-align: center; }

/* --- Full size, with sound --- */

.vmodal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; }
.vmodal[hidden] { display: none; }
.vmodal__backdrop { position: absolute; inset: 0; background: rgba(10,10,10,.88); }
.vmodal__panel {
  position: relative; z-index: 1;
  width: min(92%, 460px);
  max-height: 92svh;
  display: flex; flex-direction: column;
  background: #000;
}
.vmodal__video { width: 100%; max-height: 72svh; background: #000; display: block; object-fit: contain; }

/* Phones and small tablets get a full-height sheet rather than a small box
   floating in the middle of a dark screen. */
@media (max-width: 700px), (max-height: 560px) {
  .vmodal__panel {
    width: 100%; height: 100svh; max-height: none;
    justify-content: center;
  }
  .vmodal__video {
    width: 100%;
    height: calc(100svh - 132px);
    max-height: none;
  }
}

.vmodal__close {
  position: absolute; top: -52px; right: 0;
  color: #fff; background: none; border: 0;
}
.vmodal__close svg { width: 22px; height: 22px; }

.vmodal__bar {
  display: grid; grid-template-columns: auto minmax(0,1fr) auto;
  gap: var(--sp-sm); align-items: center;
  padding: var(--sp-sm) var(--sp-md);
  background: var(--bg);
}
.vmodal__mute {
  font: inherit; font-size: var(--fs-xs); letter-spacing: .04em; text-transform: uppercase;
  background: none; border: 1px solid var(--line); padding: 8px 12px; cursor: pointer; color: var(--ink);
}
.vmodal__meta { min-width: 0; }
.vmodal__name { font-size: 0.875rem; font-weight: 600; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vmodal__price { font-size: var(--fs-xs); color: var(--muted); margin: 2px 0 0; }
.vmodal__cta { white-space: nowrap; }

@media (max-width: 700px), (max-height: 560px) {
  .vmodal__close { top: 12px; right: 12px; position: fixed; z-index: 2; background: rgba(0,0,0,.55); border-radius: 50%; }
  .vmodal__close svg { color: #fff; }
  .vmodal__bar {
    position: fixed; left: 0; right: 0; bottom: 0;
    grid-template-columns: auto minmax(0,1fr) auto;
    padding-bottom: max(var(--sp-sm), env(safe-area-inset-bottom));
  }
}


/* ==========================================================================
   WATCH AND SHOP — HARD CONTAINMENT

   The client's device reported, from its own binary isolation run:

     base 580 · noVideos 384 · noMain 384
     noHeader 580 · noHero 580 · noAnnounce 580 · noFooter 580 · noFixedOverlays 580

   Hiding this one section is the only thing that removes the 196px of extra
   document width. No element inside it exceeds the viewport by bounding rect,
   which points at intrinsic sizing: once a <video> has metadata its natural
   dimensions (1080 wide and up) become the content-based minimum of whatever
   box it sits in, and any ancestor still at min-width:auto inherits that
   minimum. It only appears after the videos load, which is why every
   measurement taken a second after page load came back clean.

   Every box from the section down to the video is therefore pinned to its
   parent, and the section clips horizontally as a backstop. overflow-x:clip
   (not hidden) does not create a scroll container, so the rail keeps its own
   horizontal scrolling and vertical page scroll is untouched.
   ========================================================================== */

.vshop { max-width: 100%; overflow-x: hidden; }
.vshop > .container { max-width: 100%; min-width: 0; }

.vshop__rail { max-width: 100%; min-width: 0; }

.vcard,
.vcard > *,
.vcard__open,
.vcard__video { min-width: 0; max-width: 100%; }


/* ==========================================================================
   RAIL — FLEX INSTEAD OF GRID

   The client's device isolated the fault to this rail and nothing else:

     base 580 · noRail 384 · noVcards 384 · noVideoEls 580
     (hiding the rail or its cards fixes it; hiding the <video> tags does not)

   Every box measured correctly — section 384, rail 336 with 701 of internal
   scroll, cards 228 — yet removing the rail removed 196px of document width.
   That is a grid-scroller intrinsic-sizing fault, not a box that is too wide,
   which is why constraining widths did not help.

   The rail is therefore rebuilt as a flex scroller. Flexbox has no
   grid-auto-columns intrinsic-track behaviour, so the track cannot report a
   larger size to the document. The layout, sizes and swipe behaviour are
   identical.

   Snapping is proximity rather than mandatory: mandatory snapping on a nested
   scroller is the other half of this class of bug on Android.
   ========================================================================== */

.vshop__rail {
  display: flex;
  flex-wrap: nowrap;
  scroll-snap-type: x proximity;
}

.vshop__rail > .vcard { flex: 0 0 68%; }

@media (min-width: 600px) {
  .vshop__rail > .vcard { flex-basis: 38%; }
}

@media (min-width: 900px) {
  .vshop__rail > .vcard { flex-basis: 26%; }
}

/* Above 1200px the row stops scrolling and becomes a plain wrapped grid, as
   it did before. */
@media (min-width: 1200px) {
  .vshop__rail {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    grid-auto-flow: row;
    overflow: visible;
    scroll-snap-type: none;
  }
  .vshop__rail > .vcard { flex: none; }
}


/* ==========================================================================
   RAIL — BLOCK SCROLLER (the actual fix)

   Property-by-property toggle run on the client's device, viewport 384,
   document 580:

     railOverflowHidden   580     railSnapNone       580
     railOverflowClip     580     railFlowRow        580
     railOverflowVisible  580     cardSnapAlignNone  580
     railOverscrollAuto   580     cardAspectNone     580
     railDisplayBlock     384  <- fixes it
     railContain          384  <- fixes it

   Not overflow, not scroll-snap, not grid-auto-flow, not aspect-ratio. The
   only two things that fix it are removing the flex/grid formatting context
   and forcing containment. On this Android build the rail's flex/grid track
   sizing is reported up to the document, so the page gains the track's extra
   width even though every box measures correctly and the rail scrolls its own
   content properly.

   So the rail is a plain block scroller: nowrap text flow with inline-level
   cards, the pattern horizontal scrollers used before flexbox existed. It has
   no track sizing to leak. `contain` is added as well, since the device proved
   that independently stops it.

   Card widths, gaps, scrolling and appearance are unchanged.
   ========================================================================== */

.vshop__rail {
  display: block;
  white-space: nowrap;
  font-size: 0;                 /* removes the whitespace gap between inline cards */
  overflow-x: auto;
  contain: layout paint style;
}

.vshop__rail > .vcard {
  display: inline-flex;
  flex: none;                   /* cancels the flex-basis from the previous pass */
  flex-direction: column;
  vertical-align: top;
  white-space: normal;
  font-size: var(--fs-body, 1rem);
  width: 68%;
  margin-right: var(--grid-gap);
}

.vshop__rail > .vcard:last-child { margin-right: 0; }

@media (min-width: 600px) {
  .vshop__rail > .vcard { width: 38%; }
}

@media (min-width: 900px) {
  .vshop__rail > .vcard { width: 26%; }
}

/* Above 1200px the row stops scrolling and wraps, exactly as it did before. */
@media (min-width: 1200px) {
  .vshop__rail {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    grid-auto-flow: row;
    gap: var(--grid-gap);
    white-space: normal;
    font-size: inherit;
    overflow: visible;
    contain: none;
  }
  .vshop__rail > .vcard {
    display: flex;
    width: auto;
    margin-right: 0;
  }
}
