/* =========================================================
   Cinema Skin FX — step 4, "What sets Cinema apart"

   Built to a supplied reference comp. Its own file for the same reason
   titlecard.css and hero.css are: it is a full composition — ground,
   filigree, a centred head and four glass panels — not a few component
   rules. Loads last so it wins over the generic .section styles.
   ========================================================= */

.why{
  position:relative;
  overflow:hidden;
  isolation:isolate;
  /* ⚠️ This overrides .section's clamp(56px,7vw,96px) on purpose, and it
     only works because why.css loads last — same specificity, later wins.
     The section is meant to be taken in at a glance: head, rule, row. At
     the generic padding it was 940px tall against 811px of usable height
     on a 1440x900 laptop, so the bottom of every card was below the fold
     and the row read as a strip of things cut off.

     ⚠️ min(vw, vh) — the pattern repeats on every measurement in this file
     that pays into the section's height, and it is the point. What was
     wrong is not that the section was too wide for the screen, it was too
     TALL for the viewport, and a width clamp cannot see that: 1600x840 and
     1600x1080 are the same width and only one of them has room. A
     max-height media query was tried first and it is worse — it puts a
     cliff at one height and sails straight past anything just above it,
     which is exactly what happened (1600x840 came in 34px over while the
     query sat at 830). min() has no cliff: the vh term takes over
     smoothly wherever the viewport is the tighter of the two.

     ⚠️ It does not fire on phones, by construction. Below about a 0.71
     height:width ratio the vw term is the smaller one and governs, so a
     390px-wide screen never reads vh — which matters, because vh changes
     under a collapsing mobile URL bar and padding that moves with it would
     shift the page while you scroll. */
  padding-block:clamp(30px,min(4.4vw,6.2vh),66px);
}
.why > .shell{position:relative;z-index:2;}

/* ---------------------------------------------------------
   Ground: pearl satin

   Same construction as .story-silk and .hero-silk — light pooling into two
   corners, folds across, two repeating gradients at different angles AND
   different periods so they beat rather than stripe. This one is the
   brightest of the three: the comp is near-white satin, so the folds carry
   the whole read and they have to stay very low contrast to avoid looking
   like creases in paper.
   --------------------------------------------------------- */
.why-silk{
  position:absolute;inset:0;
  z-index:0;
  pointer-events:none;
  background:
    radial-gradient(56% 50% at 12% 6%,  rgba(255,255,255,.96) 0%, rgba(255,255,255,0) 62%),
    radial-gradient(50% 48% at 92% 88%, rgba(255,253,248,.9)  0%, rgba(255,253,248,0) 66%),
    repeating-linear-gradient(109deg,
      rgba(214,199,170,0)   0px,
      rgba(214,199,170,.07) 78px,
      rgba(255,255,255,.5)  152px,
      rgba(214,199,170,0)   252px),
    repeating-linear-gradient(63deg,
      rgba(214,199,170,0)   0px,
      rgba(214,199,170,.04) 124px,
      rgba(255,255,255,.26) 218px,
      rgba(214,199,170,0)   374px),
    linear-gradient(160deg, #FEFDFB 0%, #F7F1E6 48%, #FEFCF8 100%);
}

/* ---------------------------------------------------------
   Filigree

   pathLength="100" normalises every curve to the same 100-unit path, so one
   stroke-dasharray draws all three regardless of their real length — the
   same trick the title card's arcs use. non-scaling-stroke keeps the
   hairline a hairline while preserveAspectRatio="slice" scales the box.
   --------------------------------------------------------- */
.why-filigree{
  position:absolute;inset:0;
  z-index:1;
  width:100%;height:100%;
  pointer-events:none;
  /* ⚠️ SVG ink overflow is not contained by an ancestor's overflow:hidden —
     it is clipped visually but still counts toward scrollWidth, which showed
     up as 320px of sideways scroll at tablet width. preserveAspectRatio is
     "none" on the element for the same reason: "slice" scales the viewBox to
     cover, so the curves run far outside the box before anything clips them.
     Stretching the curves is fine — they are abstract, and
     vector-effect:non-scaling-stroke keeps the hairline a hairline. */
  clip-path:inset(0);
}
.wf-curve{
  fill:none;
  stroke:url(#wfGold);
  stroke:rgba(198,164,85,.55);
  stroke-width:1.4;
  stroke-linecap:round;
  vector-effect:non-scaling-stroke;
  stroke-dasharray:100;
  stroke-dashoffset:100;
  animation:wfDraw 2.6s var(--ease-soft) .25s forwards;
}
.wf-2{stroke:rgba(198,164,85,.4);animation-delay:.5s;animation-duration:3s;}
.wf-3{stroke:rgba(198,164,85,.3);stroke-width:1;animation-delay:.85s;}
@keyframes wfDraw{ to{ stroke-dashoffset:0; } }

/* The burst top right. Its rays are the shape itself; the glow is a
   drop-shadow so it follows the star rather than boxing it. */
.why-burst{
  position:absolute;
  top:clamp(18px,4vw,64px);
  right:clamp(14px,5vw,90px);
  z-index:1;
  width:clamp(46px,5vw,78px);aspect-ratio:1;
  pointer-events:none;
  opacity:0;
  animation:wfBurst 1.4s var(--ease-back) 1.1s forwards;
}
.why-burst svg{
  display:block;width:100%;height:100%;
  fill:rgba(214,182,106,.85);
  filter:drop-shadow(0 0 10px rgba(250,238,200,.9)) drop-shadow(0 0 26px rgba(198,164,85,.45));
  animation:wfTwinkle 7s var(--ease-soft) 2.5s infinite;
}
@keyframes wfBurst{ from{opacity:0;scale:.4;rotate:-40deg;} to{opacity:1;scale:1;rotate:0deg;} }
@keyframes wfTwinkle{
  0%,100%{opacity:.85;scale:1;}
  46%    {opacity:1;scale:1.1;}
  62%    {opacity:.62;scale:.94;}
}

/* ---------------------------------------------------------
   The head
   --------------------------------------------------------- */
.why-head{
  max-width:min(760px,92%);
  margin:0 auto clamp(20px,min(2.9vw,4vh),38px);
  text-align:center;
}
.why-eyebrow{
  font-size:clamp(10.5px,.86vw,12.5px);
  font-weight:600;
  letter-spacing:.3em;
  text-transform:uppercase;
  color:var(--gold-ink);
  margin-bottom:4px;
}
.why-title{
  font-family:var(--f-display);
  font-weight:400;
  font-size:clamp(28px,min(3.9vw,5.4vh),50px);
  line-height:1.08;
  letter-spacing:-.02em;
  color:var(--ink);
}
.why-lede{
  margin:14px auto 0;
  max-width:46ch;
  font-size:clamp(13.5px,1.05vw,15.5px);
  font-weight:300;
  line-height:1.72;
  color:var(--ink-2);
}

/* Rule with a sparkle set into it. Grows out of the centre on reveal —
   `transform` here, never `translate`, because main.js owns that property. */
.why-rule{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(10px,1.2vw,18px);
  width:min(430px,78%);
  /* There are two of these, above and below the title, so every pixel
     here is paid twice. */
  margin:clamp(6px,min(.9vw,1.25vh),12px) auto;
}
.why-rule i{
  flex:1 1 auto;height:1px;
  background:linear-gradient(90deg, rgba(198,164,85,0), rgba(198,164,85,.7));
}
.why-rule i + i,
.why-rule svg ~ i{background:linear-gradient(90deg, rgba(198,164,85,.7), rgba(198,164,85,0));}
.why-rule svg{
  flex:none;
  width:clamp(13px,1.1vw,17px);height:auto;aspect-ratio:1;
  fill:var(--gold-accent);
}
.why-rule[data-reveal]{transform:scaleX(.2);transition:transform .9s var(--ease-soft) .1s, opacity .7s var(--ease);}
.why-rule[data-reveal].is-in{transform:scaleX(1);}

/* ---------------------------------------------------------
   The panels
   --------------------------------------------------------- */
.value-grid{
  position:relative;
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(12px,1.3vw,22px);
  /* The comp's row is narrower than the shell and its panels are portrait.
     Both matter: at full shell width they go landscape and stop reading as
     a set of cards standing on the satin. */
  width:min(100%,1080px);
  margin:clamp(6px,min(1.1vw,1.5vh),16px) auto 0;
  list-style:none;
}

/* The ground under the row.

   ⚠️ The panels were losing their own edges. Measured off a screenshot:
   the step from satin to card face was 1.03:1 across the top edge and
   1.07:1 at the foot — far under what a hairline needs to read at all, so
   the row looked like four faint smudges rather than four objects standing
   on satin. Two halves fix that and BOTH are needed, because the card is
   already near white and there is nowhere above it to go: the ground under
   the row goes down, and the panel goes up. This is the ground half — one
   wide, very soft warm pool sized to the row and faded to nothing well
   inside its own box, so it deepens the satin without ever reading as a
   panel of its own.

   ⚠️ position:absolute is load-bearing, not tidiness: .value-grid is
   display:grid, so a static ::before is laid out as a fifth grid item and
   every card loses a fifth of the row.

   ⚠️ The radii are 50%/50% and the box is deliberately far bigger than the
   row. That is the whole trick and it is easy to get wrong: a radial
   gradient sized past 50% is still part-way up its own ramp when it hits
   the element's edge, so it cuts off — the first cut of this used
   112% 86% and what you saw was a rounded rectangle sitting behind the
   cards, which is worse than the problem it was fixing. At 50%/50% the
   ellipse ends exactly on all four edges, so the pool has no edge of its
   own anywhere. The row then sits at roughly 70–78% along the ramp, which
   is where the useful darkening has to be — hence the stops bunched late
   rather than spread evenly. */
.value-grid::before{
  content:"";
  position:absolute;
  inset:clamp(-80px,-6vw,-44px) clamp(-150px,-11vw,-56px);
  z-index:0;
  pointer-events:none;
  background:
    radial-gradient(50% 50% at 50% 52%,
      rgba(168,134,56,.24)  0%,
      rgba(172,138,60,.215) 42%,
      rgba(180,146,68,.16)  62%,
      rgba(190,156,78,.085) 80%,
      rgba(198,164,85,0)    100%);
}
.value-card{
  position:relative;
  display:flex;flex-direction:column;align-items:center;
  /* Bottom padding reserves the foot's lane; the foot itself is anchored to
     the card's bottom edge, so the rules line up across the row for free
     once the grid has stretched every card to the same height. */
  padding:clamp(18px,min(2.3vw,3.2vh),34px)
          clamp(14px,1.5vw,26px)
          clamp(26px,min(3vw,4.2vh),46px);
  text-align:center;
  border-radius:clamp(16px,1.6vw,24px);
  z-index:1;                     /* above the pool laid down by ::before */
  /* Glass, not white card stock: the satin still has to carry through it,
     which is the whole reason the panels read as objects sitting ON the
     comp rather than boxes pasted over it — but it carries through the
     lower half now, where the warm end of the face is, rather than evenly.
     An even 44% let the satin's own folds run straight across the panel
     and that is most of what dissolved the edge. */
  background:linear-gradient(168deg,
    rgba(255,255,255,.95) 0%,
    rgba(255,253,249,.88) 54%,
    rgba(253,247,236,.8)  100%);
  backdrop-filter:blur(9px) saturate(1.35);
  -webkit-backdrop-filter:blur(9px) saturate(1.35);
  /* ⚠️ A white border on a white card is not an edge. It was
     rgba(255,255,255,.72), which is invisible against every ground this
     section has. A warm hairline is: it does not depend on the satin
     behind it being any particular brightness, so the card keeps its shape
     over the bright corner AND over the folds. The white inset line just
     inside it is what stops the gold reading as a drawn-on outline — a lit
     lip and a hairline together read as a bevel. */
  border:1px solid rgba(194,163,92,.36);
  box-shadow:
    /* contact — this is the one that puts the card ON the satin */
    0 1px 2px rgba(120,92,30,.12),
    0 8px 16px -10px rgba(140,108,34,.42),
    0 34px 58px -30px rgba(120,92,30,.55),
    inset 0 1px 0 rgba(255,255,255,.96),
    inset 0 0 0 1px rgba(255,255,255,.58);
  transition:
    transform .5s var(--ease),
    box-shadow .5s var(--ease),
    border-color .5s var(--ease),
    background-color .5s var(--ease);
}
.value-card:hover{
  border-color:rgba(198,164,85,.8);
  box-shadow:
    0 2px 4px rgba(120,92,30,.14),
    0 12px 22px -12px rgba(140,108,34,.5),
    0 46px 74px -30px rgba(120,92,30,.62),
    inset 0 1px 0 rgba(255,255,255,1),
    inset 0 0 0 1px rgba(255,255,255,.72);
}

/* The pearl lens.

   A cream dome under glass: a lit shoulder top left, a warm shadow at the
   bottom, a gold ring inside the rim and two pin dots on the lower curve.
   The dots are hard-stop radial gradients rather than elements — two more
   spans for two 3px dots is not worth the markup. */
.value-lens{
  position:relative;
  display:grid;place-items:center;
  width:clamp(62px,min(6.3vw,8.8vh),100px);aspect-ratio:1;
  margin-bottom:clamp(12px,min(1.8vw,2.5vh),26px);
  border-radius:50%;
  background:
    radial-gradient(2.2px 2.2px at 24% 80%, rgba(170,133,44,.55) 0 100%, rgba(0,0,0,0) 100%),
    radial-gradient(2.2px 2.2px at 76% 80%, rgba(170,133,44,.55) 0 100%, rgba(0,0,0,0) 100%),
    radial-gradient(circle at 34% 26%,
      rgba(255,255,255,1)   0%,
      rgba(255,253,248,.96) 26%,
      rgba(247,239,225,.92) 62%,
      rgba(238,227,205,.95) 100%);
  /* Deeper than it looks it should be: the face behind the dome went up,
     so the same shadow reads flatter than it did. */
  box-shadow:
    inset 0 3px 6px rgba(255,255,255,1),
    inset 0 -11px 21px rgba(198,164,85,.34),
    inset 0 -2px 3px rgba(198,164,85,.26),
    0 16px 28px -14px rgba(160,124,40,.7);
  transition:transform .55s var(--ease-back), box-shadow .55s var(--ease);
}
/* Gold ring, inside the rim */
.value-lens::before{
  content:"";
  position:absolute;inset:clamp(5px,.5vw,7px);
  border-radius:50%;
  border:1px solid rgba(198,164,85,.5);
  transition:border-color .5s var(--ease), inset .5s var(--ease);
}
/* Specular, parked off-frame until the card is hovered */
.value-lens::after{
  content:"";
  position:absolute;inset:0;
  border-radius:50%;
  pointer-events:none;
  background:linear-gradient(102deg,
    rgba(255,255,255,0) 34%, rgba(255,255,255,.9) 47%, rgba(255,255,255,0) 60%);
  background-size:260% 100%;
  background-position:190% 0;
  transition:background-position 1.05s var(--ease);
}
.value-card:hover .value-lens{
  transform:translateY(-4px) scale(1.05);
  box-shadow:
    inset 0 2px 5px rgba(255,255,255,.98),
    inset 0 -7px 14px rgba(198,164,85,.24),
    0 18px 30px -14px rgba(160,124,40,.65);
}
.value-card:hover .value-lens::before{border-color:rgba(198,164,85,.8);}
.value-card:hover .value-lens::after{background-position:-100% 0;}

.vl-glass{
  position:absolute;inset:0;
  border-radius:50%;
  background:linear-gradient(180deg, rgba(255,255,255,.75) 0%, rgba(255,255,255,0) 46%);
  pointer-events:none;
}
.vl-ico{
  position:relative;
  width:44%;height:44%;
  fill:none;
  stroke:var(--gold-accent);
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
  transition:transform .55s var(--ease-back), stroke .45s var(--ease);
}
/* The sparkle cluster is a fill shape, not a stroke one */
.value-card:first-child .vl-ico{fill:none;}
.value-card:hover .vl-ico{transform:scale(1.1);stroke:var(--gold-ink);}

.value-name{
  font-family:var(--f-display);
  font-weight:500;
  font-size:clamp(16px,1.42vw,23px);
  line-height:1.26;
  letter-spacing:.055em;
  text-transform:uppercase;
  color:var(--ink);
  margin-bottom:clamp(7px,min(1vw,1.4vh),13px);
}
/* The index and the tag pill are DECK FURNITURE and nothing else. On a
   desktop the four cards are side by side, so a per-card "01/04" is
   answering a question nobody asked and the pill would land on the foot
   rule's lane. They are switched on inside the deck's media block. */
.value-idx,
.value-tag,
.value-halo,
.value-div,
.value-steps{display:none;}

.value-copy{
  max-width:17ch;
  font-size:clamp(12.5px,.98vw,14.5px);
  font-weight:300;
  line-height:1.62;
  color:var(--ink-2);
}

/* The foot: the card's own gold rule, with a sparkle set into it. In the
   comp the rules line up across all four panels and read as one line under
   the row — which only holds if the panels are the same height, so the
   grid stretches and the foot is pushed down by margin-top:auto. */
.value-foot{
  position:absolute;
  left:clamp(16px,1.6vw,26px);
  right:clamp(16px,1.6vw,26px);
  bottom:clamp(9px,min(1.3vw,1.8vh),18px);
  display:flex;align-items:center;justify-content:center;
  pointer-events:none;
}
.vf-line{
  position:absolute;left:0;right:0;top:50%;
  height:1px;
  background:linear-gradient(90deg,
    rgba(198,164,85,0), rgba(198,164,85,.62) 22%, rgba(198,164,85,.62) 78%, rgba(198,164,85,0));
  transform:scaleX(.72);
  transition:transform .6s var(--ease), background-color .5s var(--ease);
}
.vf-spark{
  position:relative;
  display:grid;place-items:center;
  width:clamp(16px,1.4vw,21px);aspect-ratio:1;
  /* A plate of the panel's own colour, so the rule appears to pass behind
     the sparkle rather than through it */
  border-radius:50%;
  background:radial-gradient(circle, rgba(255,253,249,.95) 0 58%, rgba(255,253,249,0) 100%);
  animation:vfTwinkle var(--tw,7s) var(--ease-soft) var(--td,0s) infinite;
  transition:transform .55s var(--ease-back);
}
.vf-spark svg{width:100%;height:100%;fill:var(--gold-accent);}
@keyframes vfTwinkle{
  0%,100%{opacity:.82;}
  48%    {opacity:1;}
  70%    {opacity:.55;}
}
.value-card:hover .vf-line{transform:scaleX(1);}
.value-card:hover .vf-spark{transform:scale(1.28) rotate(90deg);}

/* ---------------------------------------------------------
   Responsive
   --------------------------------------------------------- */

@media (max-width:1024px){
  .value-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:720px){
  .why-title{font-size:clamp(27px,7.4vw,38px);}
  .why-rule{width:min(300px,82%);}
  /* ⚠️ .why-burst USED TO BE display:none HERE, with no reason written down.
     It was the only ANIMATED element on the page that a phone lost without a
     recorded justification — a gold star with a 1.4s draw-in and a 7s twinkle,
     present on a desktop and absent on a phone.

     Checked before restoring rather than after, because reinstating a fault
     somebody silently fixed is worse than the gap. Forced visible and measured
     at 720 / 560 / 430 / 390 / 360 / 320: it lands 16–35px inside the
     section's right edge at every one, and overlaps NOTHING — not the eyebrow,
     the heading, the subline, or any card title or copy. Its own box is
     clamped (top 18px, right 14px, 46px square at the small end), which is
     why it never ran out of room in the first place.

     If it ever has to go again, say what it collided with. */
}
/* The wrapper is nothing at all until the deck exists. */
.value-deck{display:contents;}
.value-deck-nav{display:none;}

/* ---------------------------------------------------------
   The row becomes a deck on a phone

   Built to a supplied reference: one card at a time with the next one
   peeking, a counter and a round advance button. Four portrait cards stacked
   one under another is four screens of scrolling for four sentences; sideways
   they are one screen and the reader chooses how many to read.
   --------------------------------------------------------- */
@media (max-width:560px){
  .value-copy{max-width:30ch;}

  .value-deck{display:block;position:relative;}
  /* The ground pool moves off the scroller and onto the wrapper. Same
     gradient, same geometry, but now it belongs to an element that does not
     scroll, so it cannot add scroll width. The row still needs it: the step
     from satin to card face measured 1.03:1 without it. */
  .value-grid::before{display:none;}
  .value-deck::before{
    content:"";
    position:absolute;
    inset:clamp(-80px,-6vw,-44px) clamp(-150px,-11vw,-56px);
    z-index:0;
    pointer-events:none;
    background:
      radial-gradient(50% 50% at 50% 52%,
        rgba(168,134,56,.24)  0%,
        rgba(172,138,60,.215) 42%,
        rgba(180,146,68,.16)  62%,
        rgba(190,156,78,.085) 80%,
        rgba(198,164,85,0)    100%);
  }

  .value-grid{
    /* ⚠️ grid-template-columns has to be cleared, not just overridden by
       display:flex. It is inert under flex, but if this block is ever edited
       back toward grid the stale four-column template is waiting. */
    display:flex;
    grid-template-columns:none;
    overflow-x:auto;
    overscroll-behavior-x:contain;     /* a swipe past the end is not a back gesture */
    scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    width:auto;
    /* ⚠️ NO BLEED, AND THAT IS WHAT MAKES IT ONE CARD. The scroller used to
       run to the screen edges with the gutter put back as padding, which is
       right when a neighbour is meant to peek. It is wrong here: the card is
       100% of the scroller's CONTENT box, so with a bleed the next card
       started 12px past the card's right edge and 8px of it sat on screen at
       every rest position. Keeping the scroller inside the gutter puts the
       neighbours completely outside the scrollport, which is the whole point
       of one at a time. */
    margin-inline:0;
    padding-inline:0;
    gap:20px;
    /* room for the lift and the shadow, which a scroller would otherwise clip */
    padding-block:10px 14px;
    scrollbar-width:none;
  }
  .value-grid::-webkit-scrollbar{display:none;}
  /* ⚠️ ONE CARD, NO PEEK. The first cut ran 78% so the next card showed at the
     edge, which is the usual way to say "this scrolls". Asked for the
     reference's proportion instead: one card filling the width, read, then
     next. 100% here is the scroller's CONTENT box, so the card lands exactly
     on the page gutter at both edges and snaps dead centre with no fractional
     scroll left over. Measured: first card centres at scrollLeft 0, last at
     1086, which is the scroller's own maximum. */
  .value-card{
    flex:0 0 100%;
    scroll-snap-align:center;
    /* ⚠️ SIZED OFF THE REFERENCE, NOT OFF A ROUND NUMBER. The card in the
       comp is 86% of the screen and about 1.16 times as tall as it is wide.
       The width already matched (90% here, and the gutter is the page's
       own). The height did not: a flat 86vw floor made the card SQUARE at
       360 and slightly wider than tall at 390, which is what made it read
       as a tile rather than a panel.

       So the floor is derived from the card's own width — 100vw minus the
       two 20px gutters — times the comp's ratio. It stays a MINIMUM: any
       card whose content needs more simply takes more, and at 320 it does.
       The top of the clamp is there because 1.16 x 520px is 603px at 560,
       which is a card taller than a lot of the phones that report that
       width. */
    min-height:clamp(330px, calc((100vw - 40px) * 1.16), 470px);
    justify-content:center;
    /* The bottom padding is the advance button's lane, reserved so the
       centred content cannot drift into it. Same composition as the comp:
       everything in the upper two thirds, the control alone at the foot. */
    padding:34px 22px 72px;
    border-radius:20px;
    background:
      radial-gradient(126% 64% at 50% 116%,
        rgba(198,164,85,.24)  0%,
        rgba(198,164,85,.115) 44%,
        rgba(198,164,85,0)    72%),
      linear-gradient(168deg,
        rgba(255,255,255,.95) 0%,
        rgba(255,253,249,.88) 54%,
        rgba(253,247,236,.8)  100%);
  }

  /* ---- The three things that make the card an object ----

     ⚠️ ::before ON .value-card IS TAKEN. interactive.css owns it as the
     tilt glare ([data-tilt]::before), so the spine has to be ::after.

     1. The spine. The comp's card is held by a coloured bar down its left
        edge; it is the single strongest reason that card reads as a card
        and not as text on a panel. Gold here, top and bottom inset so it
        stays inside the 20px corner. */
  .value-card::after{
    content:"";
    position:absolute;
    left:0;
    top:clamp(20px,6vw,30px);
    bottom:clamp(20px,6vw,30px);
    width:4px;
    border-radius:0 4px 4px 0;
    background:linear-gradient(180deg, var(--gold) 0%, var(--gold-ink) 100%);
    box-shadow:0 0 0 1px rgba(255,255,255,.55);
  }

  /* 2. The index, inside the card at the top right, exactly where the comp
        carries it. It is STATIC MARKUP, one number per card, which is why
        it is right during a drag as well as at rest: there is no position
        to derive it from and nothing to keep in sync. */
  .value-idx{
    display:block;
    position:absolute;
    top:clamp(15px,4.2vw,21px);
    right:clamp(16px,4.6vw,22px);
    font-family:var(--f-display);
    font-size:13px;
    letter-spacing:.05em;
    line-height:1;
    color:var(--ink-3);
  }
  .value-idx b{
    font-weight:600;
    font-style:italic;
    font-size:18px;
    color:var(--gold-ink);
  }
  .value-idx i{font-style:normal;}

  /* 3. The tag. The comp closes its card with a pill that says the claim in
        two words, and that is what stops a phone card looking like a
        paragraph in a box. The words are the card's OWN — lifted out of the
        sentence above, not new claims bolted on.

        12px is the floor for anything at body weight on a phone; this sits
        on it and buys the size back with weight and tracking. --gold-ink is
        the one gold that clears 4.5:1. */
  .value-tag{
    display:inline-block;
    margin-top:clamp(15px,4.2vw,20px);
    padding:7px 15px;
    border:1px solid rgba(198,164,85,.6);
    border-radius:999px;
    background:rgba(255,255,255,.62);
    font-size:12px;
    font-weight:600;
    letter-spacing:.13em;
    text-transform:uppercase;
    color:var(--gold-ink);
  }

  /* ---- The halo behind the lens ----

     The lens is lit and nothing in the card said where the light was. Two
     hairline rings and a soft pool put a source around it, which is the
     brand's own word for what this section is doing.

     ⚠️ It is a child of .value-lens, not of the card, and that is what keeps
     it registered. The lens sits in the flow of a vertically centred column,
     so its position moves with the length of the title and the copy; a halo
     placed against the CARD would have to be re-aimed every time a line
     wrapped differently.

     ⚠️ z-index:-1 is doing real work. .value-lens is position:relative with
     z-index:auto, so it makes no stacking context and this escapes up to the
     card, which does (z-index:1). The result is that the halo paints ABOVE
     the card's face and BELOW the lens's own disc: rings outside the dome,
     nothing showing through it. */
  /* ⚠️ THE SIZE IS CAPPED BY THE CARD, NOT BY TASTE. At -34%/-13% the outer
     ring reached 53px above the lens and the lens only has the card's 34px of
     top padding above it: the ring escaped through the card's top edge. The
     card does not clip, and .value-grid is a scroll container whose
     overflow-y computes to auto the moment overflow-x is not visible, so
     anything sticking out of it becomes scrollable height. -16%/-11% puts the
     outer ring 29px above the lens, inside the padding with room to spare. */
  .value-halo{
    display:block;
    position:absolute;
    inset:-16%;
    z-index:-1;
    border-radius:50%;
    border:1px solid rgba(198,164,85,.26);
    background:radial-gradient(circle,
      rgba(250,240,214,.5) 0 46%,
      rgba(198,164,85,.1)  72%,
      rgba(198,164,85,0)   100%);
  }
  .value-halo::before{
    content:"";
    position:absolute;inset:-11%;
    border-radius:50%;
    border:1px solid rgba(198,164,85,.14);
  }

  /* ---- The rule under the title ----

     The same device the section head uses on itself and the interview cards
     use on theirs: a hairline with a mark set into it. It gives the title an
     end, which a centred block of three type sizes otherwise does not have.

     ⚠️ It pays for itself out of the title's bottom margin rather than out of
     the card's height. The card had 16px of slack inside the 1.16 box it was
     sized to, and spending all of it would have pushed the card taller and
     broken the proportion that was measured last time. */
  .value-name{margin-bottom:2px;}
  .value-div{
    display:block;
    position:relative;
    width:clamp(92px,32vw,132px);
    height:9px;
    margin:0 0 11px;
  }
  .value-div::before{
    content:"";
    position:absolute;left:0;right:0;top:50%;
    height:1px;
    background:linear-gradient(90deg,
      rgba(198,164,85,0), rgba(198,164,85,.55) 26%,
      rgba(198,164,85,.55) 74%, rgba(198,164,85,0));
  }
  .value-div::after{
    content:"";
    position:absolute;left:50%;top:50%;
    translate:-50% -50%;
    rotate:45deg;
    width:6px;height:6px;
    background:var(--gold);
    /* a plate of the card's own colour, so the rule passes behind the mark */
    box-shadow:0 0 0 3px rgba(255,253,249,.96);
  }

  /* ---- The step dots ----

     The bottom-left corner was the only dead area left on the card: the pill
     is centred and the button is hard right. Four dots there turn the foot
     into a strip rather than a corner with a button in it.

     Not a second copy of the index. "01/04" is a COUNT; this is a MAP — two
     behind you, one ahead — and they are read at opposite corners of the
     card, not side by side.

     ⚠️ The markup is identical in all four cards. Which dot is lit is decided
     here, from the card's own position in the row, so there is no per-card
     value in the HTML that can fall out of step with the index above it. */
  .value-steps{
    display:flex;
    position:absolute;
    left:clamp(18px,5.2vw,24px);
    /* centred on the button's centre line: the button's bottom is inset by
       the card's own padding, it is 44px tall, and a dot is 6px */
    bottom:calc(clamp(16px,4.6vw,22px) + 19px);
    align-items:center;
    gap:6px;
    z-index:2;
    pointer-events:none;
  }
  .value-steps i{
    width:6px;height:6px;
    border-radius:50%;
    background:rgba(160,124,40,.28);
    transition:width .35s var(--ease), background-color .35s var(--ease);
  }
  .value-card:nth-child(1) .value-steps i:nth-child(1),
  .value-card:nth-child(2) .value-steps i:nth-child(2),
  .value-card:nth-child(3) .value-steps i:nth-child(3),
  .value-card:nth-child(4) .value-steps i:nth-child(4){
    width:18px;
    border-radius:3px;
    background:linear-gradient(90deg, var(--gold), var(--gold-ink));
  }

  /* ⚠️ THE FOOT GOES, AND THIS IS THE REASON. Its own comment says what it
     is for: "in the comp the rules line up across all four panels and read
     as one line under the row". In the deck there is no row — there is one
     card — so the alignment it exists to produce cannot happen, and the
     lane it was anchored to is now the advance button's. It is still there
     on every other layout, sparkle and all. */
  .value-foot{display:none;}
  /* Everything inside grows with the card. A 62px lens and 12.5px copy were
     sized for a quarter of a desktop row, not for the whole screen. */
  .value-lens{width:clamp(84px,24vw,104px);margin-bottom:20px;}
  .value-name{font-size:clamp(20px,5.6vw,24px);}
  /* 24ch left a 178px column inside a 306px card and pushed one sentence to
     three lines. 28ch is two on every width measured and still well short of
     the line length where centred text gets hard to track. */
  .value-copy{max-width:28ch;font-size:clamp(14px,3.8vw,16px);line-height:1.7;}

  /* ⚠️ The cards are forced visible inside the deck. [data-reveal] rests at
     opacity:0 and main.js only adds .is-in when the IntersectionObserver
     fires against the VIEWPORT — and cards two to four start outside it
     horizontally. They do reveal as you swipe, which sounds fine and is not:
     a card fading and sliding in while your thumb is dragging it reads as the
     deck stuttering. The deck is the progressive disclosure here; the cards
     do not need a second one. */
  .value-grid .value-card[data-reveal]{
    opacity:1;
    transform:none;
    filter:none;
  }

  /* ⚠️ THE NAV IS OVER THE CARD NOW, NOT UNDER THE DECK, which is where the
     comp puts it. .value-deck is position:relative and the scroller has no
     bleed, so the wrapper's box IS the card's box and these offsets are the
     card's own padding.

     pointer-events:none on the strip is load-bearing: it lies across the
     bottom of a scroll container, and without it a swipe that starts down
     there hits a dead element instead of the deck. The button takes its
     events back. */
  .value-deck-nav{
    position:absolute;
    left:0;right:0;
    bottom:calc(14px + clamp(16px,4.6vw,22px));
    padding-inline:clamp(16px,4.6vw,22px);
    z-index:2;
    display:flex;align-items:center;justify-content:flex-end;
    gap:14px;
    margin-top:0;
    pointer-events:none;
  }
  /* ⚠️ The derived counter is off, not deleted. .value-idx carries the number
     inside the card now and two copies of the same number in one card is a
     bug waiting to be reported. main.js still writes to this element and
     that is fine — it is also what isDeck() reads the nav's display for, so
     the NAV itself must stay displayed. */
  .vdn-count{display:none;}
  .vdn-adv{
    pointer-events:auto;
    display:grid;place-items:center;
    /* 44px is the touch floor and this is a control */
    width:44px;height:44px;flex:none;
    border-radius:50%;
    border:1.5px solid var(--gold);
    background:linear-gradient(140deg, #FFFDF8, var(--gold-tint));
    box-shadow:0 10px 20px -12px rgba(160,124,40,.7);
    cursor:pointer;
    transition:transform .3s var(--ease), box-shadow .3s var(--ease);
  }
  .vdn-adv:active{transform:scale(.94);}
  .vdn-adv svg{
    width:18px;height:18px;
    fill:none;stroke:var(--gold-ink);stroke-width:2;
    stroke-linecap:round;stroke-linejoin:round;
  }
}

/* ---------------------------------------------------------
   Each card's icon does the thing its card is about

   The deck card had no motion of its own. The desktop card is not still —
   it has the foot sparkle twinkling and the lens specular on hover — and
   the deck has neither, because the foot is off and a phone has no hover.
   So the one thing already sitting in the middle of the card is asked to
   move, and what it does is the card's own subject rather than decoration
   that could be swapped between any two of them.

   ⚠️ DECK ONLY, AND THAT IS ARITHMETIC RATHER THAN TASTE. Above 560 the
   four cards are side by side, so all four loops would run at once in one
   row and there is nowhere for the eye to rest. In the deck exactly one
   card is on screen, so exactly one of these is ever playing.

   ⚠️ Guarded on prefers-reduced-motion:no-preference rather than switched
   off later in the reduce block. The reduce block lists everything that has
   to be remembered; this is one fewer thing to remember, because it never
   exists in the first place. (There is a pointer to here in that block.)

   ⚠️ THE CHILDREN ARE ANIMATED, NEVER .vl-ico ITSELF. .vl-ico already
   carries a transform from the hover rule and a transition to match, and an
   animation on the same property would fight it for the same value.

   ⚠️ transform-box:fill-box is load-bearing on an SVG child. Without it
   transform-origin resolves against the SVG's own viewport instead of the
   shape's box, so "scale from the centre" scales from somewhere off to one
   side and the sparkle walks across the lens as it grows.
   --------------------------------------------------------- */
@media (max-width:560px) and (prefers-reduced-motion:no-preference){
  .vl-ico > *{transform-box:fill-box;transform-origin:center;}

  /* 1 / Visible Confidence. The three sparkles catch the light in turn,
         biggest first. The card is about something you can SEE happen. */
  .value-card:nth-child(1) .vl-ico path{
    animation:viSparkle 5.4s var(--ease-soft) infinite;
  }
  .value-card:nth-child(1) .vl-ico path:nth-child(2){animation-delay:1.8s;}
  .value-card:nth-child(1) .vl-ico path:nth-child(3){animation-delay:3.6s;}

  /* 2 / Modern Simplicity. One unhurried beat: the heart doing the single
         thing a heart does, at a pace that reads as easy and not urgent. */
  .value-card:nth-child(2) .vl-ico path{
    animation:viBeat 4.6s var(--ease-soft) infinite;
  }

  /* 3 / Trust & Transparency. The tick draws itself inside the shield and
         does it again. "Honest science" is a claim; this is the claim being
         checked in front of you. The shield itself holds still.
         11 is a little over the path's own length (about 9.8 user units,
         3.25 up and 6.51 down), so the dash clears the whole stroke. */
  .value-card:nth-child(3) .vl-ico path:nth-of-type(2){
    stroke-dasharray:11;
    animation:viCheck 4.8s var(--ease) infinite;
  }

  /* 4 / Everyday Glamour. The light turns. Eight rays 45deg apart, so a
         45deg rotation lands on the identical shape and the loop has no
         seam anywhere. 14s for that 45deg is about 3deg a second: light
         moving, not a spinner. The core stays put, the way a sun does. */
  .value-card:nth-child(4) .vl-ico path{
    animation:viRays 14s linear infinite;
  }
  .value-card:nth-child(4) .vl-ico circle{
    animation:viCore 4.5s var(--ease-soft) infinite;
  }
}

@keyframes viSparkle{
  0%, 60%, 100%{opacity:.5;  scale:.84;}
  10%          {opacity:1;   scale:1.08;}
  24%          {opacity:.76; scale:.96;}
}
@keyframes viBeat{
  0%, 52%, 100%{scale:1;}
  8%           {scale:1.1;}
  17%          {scale:1;}
  25%          {scale:1.05;}
  34%          {scale:1;}
}
@keyframes viCheck{
  0%        {stroke-dashoffset:11; opacity:0;}
  6%        {opacity:1;}
  34%       {stroke-dashoffset:0;}
  80%       {stroke-dashoffset:0;  opacity:1;}
  94%, 100% {stroke-dashoffset:0;  opacity:0;}
}
@keyframes viRays{ to{ rotate:45deg; } }
@keyframes viCore{
  0%, 100%{opacity:.78; scale:.9;}
  50%     {opacity:1;   scale:1.08;}
}

/* ---------------------------------------------------------
   Motion off — the composition stays, it just stops moving
   --------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  /* ⚠️ The four deck icon loops are NOT listed here. They are written under
     "and (prefers-reduced-motion:no-preference)" instead, so they never
     exist under reduce rather than being created and then cancelled. */
  .wf-curve{animation:none;stroke-dashoffset:0;}
  .why-burst{animation:none;opacity:1;}
  .why-burst svg{animation:none;}
  .vf-spark{animation:none;}
  .why-rule[data-reveal]{transform:none;transition:none;}
  .value-card,
  .value-lens,
  .vl-ico,
  .vf-line,
  .vf-spark{transition:none;}
  .value-lens::after{display:none;}
}

/* ---------- Phone legibility ----------
   The section eyebrow bottoms out at 10.5px, which is under the floor on a
   phone. Audited at 390x844. */
@media (max-width:700px){
  .why-eyebrow{font-size:12px;letter-spacing:.22em;}
}
