/* VVAI sound bar v3.39 - loaded LAST on purpose.
   v3.30 body unchanged; the v3.38 block is appended at the end.
   The capsule stylesheet sets .vvai-sound{overflow:clip} and pins
   .vvai-sound__details to 246px with overflow:hidden. Both previously beat the
   page's inline <style> because that block is parsed BEFORE the capsule link,
   so equal-specificity overrides there were silently discarded. Everything here
   loads after both, so it simply wins. */

.vvai-sound{
  overflow: visible;
  max-width: calc(100vw - 24px);
  padding-right: 10px;
}

/* no reveal: the controls are always present */
.vvai-sound .vvai-sound__details,
.vvai-sound[data-open="true"] .vvai-sound__details,
.vvai-sound:hover .vvai-sound__details,
.vvai-sound:focus-within .vvai-sound__details{
  position: static;
  width: auto;
  min-width: 0;
  height: auto;
  min-height: 0;
  padding: 0;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  overflow: visible;
  background: none;
  border: 0;
  box-shadow: none;
  backdrop-filter: none;
  transition: none;
}

/* v3.21 left a mobile 6-column GRID on
   `.vvai-sound[data-open="true"] .vvai-sound__controls` (0,3,0), which outranks
   a plain `.vvai-sound .vvai-sound__controls` (0,2,0) and pushed the 7th icon
   onto a second row. Match its specificity so this file wins on load order. */
.vvai-sound .vvai-sound__controls,
.vvai-sound[data-open="true"] .vvai-sound__controls,
.vvai-sound:hover .vvai-sound__controls,
.vvai-sound:focus-within .vvai-sound__controls{
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  grid-template-columns: none;
  gap: 4px;
  padding: 0;
  width: auto;
}
.vvai-sound .vvai-sound__controls > *,
.vvai-sound[data-open="true"] .vvai-sound__controls > *{ grid-area: auto; grid-column: auto; grid-row: auto; }

/* the head stops being a toggle target and becomes an identity mark */
.vvai-sound .vvai-sound__head{ min-width: 0; padding-left: 14px; padding-right: 8px; cursor: default; }

.vvai-sound .vvai-sound__btn,
.vvai-sound .vvai-sound__seek,
.vvai-sound .vvai-sound__playpause,
.vvai-sound .vvai-sound__mute{
  width: 34px; min-width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 999px; padding: 0;
  grid-area: auto;
}
.vvai-sound .vvai-sound__btn svg{ width: 19px; height: 19px; }
.vvai-sound .vvai-sound__playpause{ font-size: .72rem; }

/* The mute button ships TWO icons and the capsule stylesheet swaps them. A
   blanket `svg{display:block}` here would force both visible - which stacked
   them, doubled the button height and pushed the lyric icon onto a second row.
   Drive the swap explicitly from the state the capsule already sets. */
.vvai-sound .vvai-sound__mute svg{ grid-area: 1/1; display: none; }
.vvai-sound .vvai-sound__mute .vvai-icon-unmuted{ display: block; }
.vvai-sound[data-muted="true"] .vvai-sound__mute .vvai-icon-unmuted{ display: none; }
.vvai-sound[data-muted="true"] .vvai-sound__mute .vvai-icon-muted{ display: block; }

/* the numeric readout goes - the owner asked for symbols, not numbers */
.vvai-sound .vvai-sound__value{ display: none; }

/* Lyric toggle is now an icon on the same convention as the speaker:
   a letter, struck through when lyrics are off. */
.vvai-sound .vvai-sound__lyrics-toggle{
  width: 34px; min-width: 34px; height: 34px; padding: 0;
  display: grid; place-items: center;
  border-radius: 999px; grid-area: auto;
}
.vvai-sound .vvai-sound__lyrics-toggle svg{ width: 19px; height: 19px; display: block; grid-area: 1/1; }
.vvai-sound .vvai-sound__lyrics-toggle .vvai-icon-lyr-on{ display: none; }
.vvai-sound .vvai-sound__lyrics-toggle .vvai-icon-lyr-off{ display: block; }
.vvai-sound .vvai-sound__lyrics-toggle[aria-pressed="true"] .vvai-icon-lyr-on{ display: block; }
.vvai-sound .vvai-sound__lyrics-toggle[aria-pressed="true"] .vvai-icon-lyr-off{ display: none; }
/* on = filled, matching how the rest of the bar shows an active state */
.vvai-sound .vvai-sound__lyrics-toggle[aria-pressed="true"]{
  background: var(--vvai-sound-fg, #f3efe9);
  color: #0b0b0c;
  border-color: var(--vvai-sound-fg, #f3efe9);
}
.vvai-sound .vvai-sound__lyrics-toggle:disabled{ opacity: .3; }
.vvai-sound .vvai-sound__lyrics-indicator{ display: none; }
.vvai-sound .vvai-sound__divider{ display: none; }

/* the two groups read as groups */
.vvai-sound .vvai-sound__controls > [data-seek="5"]{ margin-right: 7px; }
.vvai-sound .vvai-sound__controls > [data-mute]{ margin-right: 7px; }

@media (max-width: 620px){
  .vvai-sound .vvai-sound__label{ display: none; }   /* keep the dot + waveform */
  .vvai-sound .vvai-sound__head{ padding-left: 12px; padding-right: 6px; }
  .vvai-sound .vvai-sound__wave{ min-width: 30px; grid-template-columns: repeat(7, 1px); }
  /* Seven columns, so seven bars. The capsule hides 10+; without this, 8 and 9
     auto-place onto a second grid row - the `|||||||` over `||` in the
     2026-08-24 device photo, reproduced at 440x956 in both engines. */
  .vvai-sound .vvai-sound__wave .vvai-sound__bar:nth-child(n+8){ display: none; }
  .vvai-sound .vvai-sound__btn,
  .vvai-sound .vvai-sound__seek,
  .vvai-sound .vvai-sound__playpause,
  .vvai-sound .vvai-sound__mute{ width: 32px; min-width: 32px; height: 32px; }
  .vvai-sound .vvai-sound__lyrics-toggle{ height: 32px; padding: 0 9px; }
  .vvai-sound .vvai-sound__controls{ gap: 3px; }
}
@media (max-width: 380px){
  .vvai-sound .vvai-sound__wave{ display: none; }
}

/* ---- lyric veil centring ----
   `.vvai-lyrics__line` had no text-align (so: left) while the [dir="rtl"] rule
   set right. With the box spanning 5vw..77vw, right-aligned Hebrew landed near
   centre and everything else sat hard left, over the hero paragraph. Centre the
   box and the text for every language, RTL included - which is what the
   capsule stylesheet already does under 560px. */
.vvai-lyrics{
  left: max(4vw, env(safe-area-inset-left));
  right: max(4vw, env(safe-area-inset-right));
  width: auto;
  text-align: center;
}
.vvai-lyrics__line,
.vvai-lyrics__line[dir="rtl"],
.vvai-lyrics__line[dir="ltr"],
.vvai-lyrics__line[dir="auto"]{
  text-align: center;
  margin-inline: auto;
}

/* ---- vertical placement ----
   Keep the veil at the BOTTOM, where it belongs. v3.31 briefly moved it to
   `top: 23vh`, which laid text across the models' faces - wrong for this brand,
   and not what was asked: the report was that Hebrew's position looked right and
   the other languages did not match it. That was a HORIZONTAL problem only.

   Bottom-anchoring does collide with the hero CTA row (705-750 at 1440x900) if
   it sits too high - at `bottom + 104px` the line landed straight on "Enter the
   lookbook". The answer is to sit LOWER, not higher. A centred line at roughly
   768-820 clears the CTA row vertically, and clears the thumbnail strip
   (x 964-1412), the sound bar (x 986-1422) and the notice (x 14-354)
   horizontally, because centred text occupies about x 612-828.
   Measure with hero_bands.py before changing these numbers. */
.vvai-lyrics{
  top: auto;
  bottom: calc(max(22px, env(safe-area-inset-bottom)) + 74px);
}
@media (min-width: 761px){
  .vvai-lyrics__line{ font-size: clamp(24px, 2.7vw, 46px); }
}
@media (max-width: 760px){
  /* Mobile is tighter: at 393x852 the CTA row ends 712 and the thumbnail strip
     starts 750 - a 38px gap, and the strip runs the full width so it cannot be
     dodged horizontally the way the desktop one can. A 26px line fits if it sits
     in that gap. */
  .vvai-lyrics{ bottom: calc(max(16px, env(safe-area-inset-bottom)) + 91px); }
  .vvai-lyrics__line{ font-size: clamp(20px, 5.4vw, 34px); }
}
@media (max-height: 600px) and (orientation: landscape){
  .vvai-lyrics{ top: auto; bottom: max(14px, env(safe-area-inset-bottom)); }
  .vvai-lyrics__line{ font-size: clamp(20px, 4.4vh, 34px); }
}

/* ---- notice opt-out contrast ----
   `.vvai-notice__link` at .72 opacity measures 4.24 in light mood, under the
   4.5 AA floor. Dark mood is unaffected but is raised in step for consistency. */
.vvai-notice__link{ opacity: .82; }
html[data-mood="light"] .vvai-notice__link{ opacity: 1; color: rgba(23,21,26,.92); }

/* ---- control grouping ----
   Volume sat immediately beside mute, so three sound controls ran together and
   read as one confusing cluster. Regroup with flex `order` (no markup change,
   so the JS bindings are untouched):
       [vol-][vol+]   [rewind][play][forward]   [mute][lyrics]      */
.vvai-sound .vvai-sound__controls > [data-volume-down]{ order: 1; }
.vvai-sound .vvai-sound__controls > [data-volume-up]  { order: 2; margin-right: 7px; }
.vvai-sound .vvai-sound__controls > [data-seek="-5"]  { order: 3; }
.vvai-sound .vvai-sound__controls > [data-playpause]  { order: 4; }
.vvai-sound .vvai-sound__controls > [data-seek="5"]   { order: 5; margin-right: 7px; }
.vvai-sound .vvai-sound__controls > [data-mute]       { order: 6; margin-right: 0; }
.vvai-sound .vvai-sound__controls > [data-lyrics-toggle]{ order: 7; }

/* ---- lyric colour follows the mood ----
   Dark mood: white, as before. Light mood: near-black - but the veil sits over
   the HERO VIDEO, which is dark in BOTH moods, so plain black would disappear
   there. The soft white halo keeps it legible over a light section and a dark
   video frame alike. */
html[data-mood="light"] .vvai-lyrics{
  color: #0b0b0c;
  text-shadow: 0 1px 18px rgba(255,255,255,.85), 0 0 42px rgba(255,255,255,.6);
}


/* =====================================================================
   v3.38 - 2026-08-24 QC. Everything below is additive to the v3.30 body.
   ===================================================================== */

/* ---- the volume readout has to stay in the accessibility tree ----
   v3.30 removed the number with `display:none`, which also removes the element
   from the accessibility tree - so its `aria-live` announced nothing and a
   screen-reader user pressing + or - got no feedback at all. The big flash
   overlay that shows the number visually is aria-hidden and cannot stand in.
   Hide it visually and keep it readable. It stays out of flow exactly as
   display:none did, and its 1px box is below the size filter every width and
   paint assertion applies, so nothing in the suite starts counting it. */
.vvai-sound .vvai-sound__value{
  display: block;
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- 44px touch targets on real touch devices, above the collapse width ----
   Scoped to `pointer: coarse` on purpose. A narrow DESKTOP window keeps the
   32/34px v3.30 bar, which is the geometry the 390x844 drive-test and every
   fine-pointer width assertion exercise. Above 620px a coarse device has room
   for seven 44px controls in the always-open bar (about 484px of 768). */
@media (pointer: coarse) and (min-width: 1024px){
  .vvai-sound .vvai-sound__btn,
  .vvai-sound .vvai-sound__seek,
  .vvai-sound .vvai-sound__playpause,
  .vvai-sound .vvai-sound__mute,
  .vvai-sound .vvai-sound__lyrics-toggle{
    width: 44px; min-width: 44px; height: 44px;
  }
  .vvai-sound .vvai-sound__head{ min-height: 48px; }
}

/* ---- the footer reserve, unconditional, every pointer and width ----
   The lyric is fixed. On a fine pointer it anchors at
   `calc(max(22px, env(...)) + 74px)` = 96px and its glyphs reach 145px, while the
   footer's own `padding: 50px 5vw 30px` leaves 30px - so at footer scroll the line
   was drawn straight through the footer NAVIGATION: Lookbook, Films, Top,
   Instagram, and the Analytics opt-out the privacy notice points people to.
   Measured at 48 of 120 fine-pointer cases, 0 of them first-visit, because the
   notice's 230px rule was covering it exactly as it did on phones.

   170px clears the 145px worst case. This rule must stay BEFORE the coarse-mobile
   override below: both are `.footer` at (0,1,0), so source order is what lets the
   narrower 160px win on phones. The notice's 230px rule outranks both at (0,3,1). */
.footer{ padding-bottom: calc(170px + env(safe-area-inset-bottom)); }

/* ---- the fixed bar and the fixed lyric must not sit on the footer ----
   96px cleared the bar but not the lyric, which is anchored at ~107px and rises
   to 134px on the tallest phones. That went unnoticed because index.html gives
   the footer 230px WHILE THE PRIVACY NOTICE IS SHOWING - so a first-time visitor
   never saw it, and only returning visitors, who are most visitors, got the last
   footer rows drawn through the lyric. This reserve must therefore stand on its
   own and not lean on the notice. */
@media (max-width: 1023px) and (pointer: coarse){
  .footer{ padding-bottom: calc(160px + env(safe-area-inset-bottom)); }
}


/* =====================================================================
   v3.39 - five always-visible mobile controls
   =====================================================================

   v3.38 collapsed the phone player to a pill that opened a two-row popover.
   The owner rejected the expansion step: the five essential controls must be
   there at rest. Independent QC measured 0/5 visible before expansion at every
   mobile geometry.

   Arithmetic, which is why v3.38 went the other way: SEVEN 44px controls plus
   gaps and the head need ~434px against a ~369px budget at 393px. FIVE fit -
   5 x 44 + 4 gaps = 244px, leaving room for the head and padding at 375px, the
   narrowest supported width. So volume -/+ and the numeric readout are the ones
   that stand down on a phone; they stay on desktop.

   Visibility here is unconditional. It must not depend on `data-open`, hover,
   focus, or whether `audio.play()` succeeded. `!important` is deliberate: the
   capsule stylesheet carries

     @media (hover:none) {
       .vvai-sound:not([data-open="true"]):hover
         .vvai-sound__details:not(:focus-within) { width:0; visibility:hidden }
     }

   at (0,5,0) - the rule that made the whole strip vanish on a real iPhone once a
   finger left :hover parked. No specificity this file can reach is worth relying
   on against a rule whose whole job was to hide these controls. */

@media (max-width: 1023px) and (pointer: coarse){

  /* the shell hugs its contents; no wide empty glass */
  .vvai-sound[data-vvai-sound][data-mobile-row="true"]{
    left: auto;
    right: max(12px, env(safe-area-inset-right));
    width: max-content;
    max-width: calc(100vw - 24px - env(safe-area-inset-left) - env(safe-area-inset-right));
    padding-right: 6px;
    border-radius: 999px;
  }

  /* the head is an identity mark again, not a disclosure trigger */
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__head{
    cursor: default;
    min-width: 0;
    padding-left: 13px;
    padding-right: 4px;
  }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__head::after{
    content: none;                 /* the v3.38 chevron is gone */
  }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__label{ display: none; }

  /* ---- the five controls, always ---- */
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__details{
    position: static !important;
    width: auto !important;
    min-width: 0 !important;
    height: auto !important;
    min-height: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    pointer-events: auto !important;
    overflow: visible !important;
    transform: none !important;
    transition: none !important;
  }

  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls{
    display: flex !important;
    flex-wrap: nowrap !important;
    align-items: center;
    grid-template-columns: none !important;
    gap: 4px;
    padding: 0 2px;
    width: auto;
    height: auto;
  }

  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > button{
    width: 44px !important;
    min-width: 44px !important;
    height: 44px !important;
    margin: 0 !important;
    padding: 0 !important;
    border-radius: 999px;
    grid-area: auto !important;
    grid-column: auto !important;
    grid-row: auto !important;
    opacity: 1 !important;
    visibility: visible !important;
    pointer-events: auto !important;
  }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > button svg{
    width: 20px; height: 20px;
  }

  /* volume pair and the numeric readout stand down on a phone - this is the
     40px x 2 that makes five 44px targets fit at 375px */
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-volume-down],
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-volume-up]{
    display: none !important;
  }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__value{
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__divider{
    display: none !important;
  }

  /* order left to right: back, play, forward, mute, lyrics */
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-seek="-5"]{ order: 1; }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-playpause]{ order: 2; }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-seek="5"]{ order: 3; }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-mute]{ order: 4; }
  .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__controls > [data-lyrics-toggle]{
    order: 5; width: 44px !important; min-width: 44px !important; height: 44px !important;
  }

  /* the waveform is decorative; drop it wherever the five controls need the room */
  @media (max-width: 430px){
    .vvai-sound[data-vvai-sound][data-mobile-row="true"] .vvai-sound__wave{ display: none; }
  }
}

/* ---- the recorded lyric anchor, restored ----
   v3.38 derived this from the hero switcher's rect and recomputed it on resize.
   Once scrolled past the hero that rect's `top` is negative, so a chrome-resize
   mid-scroll produced offsets of 988-1188px and stranded the line off-screen
   with no way back. The owner's recorded constraint (v3.32) is a FIXED low
   anchor, and it is fixed here: no measurement, no scroll input, no geometry.
   At a zero safe-area inset this computes to 107px. */
@media (max-width: 900px){
  .vvai-lyrics{ bottom: calc(max(16px, env(safe-area-inset-bottom)) + 91px); }
}

/* ---- short landscape: its own fixed low anchor ----
   107px puts the line across the hero copy in a 393px-tall viewport. This is a
   FIXED constant like the portrait one - safe-area aware, no DOM geometry, no
   scroll input - computing to 80px at a zero inset. Measured against the Option A
   hero: player top 72px, copy bottom 124px, so the line sits 80-102px with 8px
   below it and 22px above. */
@media (max-width: 1024px) and (max-height: 460px) and (orientation: landscape){
  .vvai-lyrics{ bottom: calc(max(16px, env(safe-area-inset-bottom)) + 64px); }
}
