/* =========================================================
   Cinema Skin FX — Credibility (#proof)

   Built to a reference comp, which is why it is its own file
   rather than a handful of rules in styles.css — the same
   reason hero.css, why.css, titlecard.css and results.css
   exist. Everything here is scoped under .proof.

   ⚠️ IT LOADS LAST, AFTER atmosphere.css. That is deliberate:
     atmosphere.css carries `.section{background:transparent}`
     at (0,1,0) so every section shows the fixed ambient layer
     through it. This section paints its own warm ground, and
     it can only do that from behind — or from a heavier
     selector. Both are used below (`.section.proof`, two
     classes) so the ground survives either a reorder of the
     <link> tags or a later rule in atmosphere.css.

   ⚠️ NOTHING HERE SELLS. The reviews, the ratings and the
     store all live on cinemaskinfx.com; this section shows
     the published figures and points there. No review wall,
     no prices, no capture.
   ========================================================= */

/* =========================================================
   1. THE GROUND
   ========================================================= */
/* ⚠️ overflow:CLIP, NOT hidden, HERE AND ON .proof-atmos — AND THAT IS THE
   WHOLE REASON THE SHEEN MOVES.

   overflow:hidden makes an element a scroll container. Two things in this
   project resolve against "the nearest ancestor scroll container" and both
   break silently when they find one that never scrolls:

     position:sticky        — it once left the last two products with no
                              background behind them at all
     animation-timeline:view() — .pf-beam below, which returned an identical
                              74.9962% at five scroll positions until this
                              line changed

   Measured, one ancestor at a time: clipping .proof alone was not enough,
   because .proof-atmos was the nearer container. Both had to go. Switching
   them moved the beam from a constant to 19.8 -> 59.1 -> 87.8 -> 114.7 ->
   141.6 across the section.

   clip does the same clipping and creates no scroll container, which was the
   only thing hidden was contributing. Nothing here is scrolled by script.
   ⚠️ Do not "tidy" either of these back to hidden. */
.section.proof{
  position:relative;
  overflow:clip;
  isolation:isolate;              /* also set by [data-spotlight]; stated so the
                                     stacking of the layers below is local */
  padding-block:clamp(58px,7vw,100px);
  /* Neutral ivory, warming and deepening downward.
     ⚠️ NEARLY OPAQUE, AND THAT IS THE POINT. At .72 the top of this section
     was letting the gold scene's ambient choose the hue, and it photographed
     champagne-yellow where the comp is a neutral ivory. More than that, the
     fall of light down the right is drawn in white — on a ground already at
     that luminance there is nothing for it to be brighter than, and it
     vanished. Turning the band up would not have helped; it is white
     already. The ground had to come DOWN.
     The first stop is still a shade translucent so the seam with #why above
     is a blend rather than a cut. */
  background:
    linear-gradient(180deg,
      rgba(250,248,244,.90) 0%,
      rgba(248,245,239,.985) 26%,
      rgba(247,243,236,1) 62%,
      rgba(244,239,229,1) 100%);
}

/* The pointer glow. [data-spotlight] in interactive.css supplies the
   behaviour and the ::before at z-index:-1; this is the warm key for it,
   wider and softer than the default because the surface it crosses is a
   plain one and a tight circle would read as a torch. */
.proof[data-spotlight]::before{
  background:radial-gradient(520px circle at var(--mx,50%) var(--my,50%),
    rgba(250,238,200,.62) 0%,
    rgba(198,164,85,.11) 44%,
    rgba(250,238,200,0) 72%);
}

/* =========================================================
   2. THE BACKGROUND — three kinds of movement

   (a) autonomous drift, so a phone with no pointer still sees
       a surface that is alive;
   (b) the pointer glow above, on a fine pointer;
   (c) a sheen that pans as the section crosses the window,
       which is the one that answers a THUMB.

   ⚠️ Each layer animates a DIFFERENT transform property.
     `transform` is the time-based drift, `translate` is the
     scroll-linked pan, `rotate` is the static tilt. They are
     separate properties and they compose; two animations on
     `transform` would simply fight and the last one would win.

   ⚠️ The order they apply in is translate → rotate → scale →
     transform, so `transform:translateX()` on a rotated band
     slides it along its OWN length rather than across the
     page. That is what is wanted here — a band of light
     travelling down its own axis.

   All of it stops when the section is off screen: main.js puts
   .is-idle on every section it cannot see and styles.css pauses
   every animation inside one. Nothing here needs to opt in.
   ========================================================= */
.proof-atmos{
  position:absolute;
  inset:0;
  z-index:-2;                     /* under the pointer glow (-1), under content */
  pointer-events:none;
  overflow:clip;                  /* ⚠️ clip, not hidden — see .section.proof */
  contain:layout paint style;
}

/* --- soft light pools --- */
.pf-pool{
  position:absolute;
  border-radius:50%;
  will-change:transform;
}
.pf-pool-a{
  width:min(58vw,700px);aspect-ratio:1;
  top:-26%;right:-8%;
  background:radial-gradient(circle at 50% 50%, rgba(250,238,200,.72) 0%, rgba(250,238,200,0) 68%);
  animation:pfPoolA 41s cubic-bezier(.22,.68,.32,1) infinite;
}
.pf-pool-b{
  width:min(46vw,560px);aspect-ratio:1;
  bottom:-30%;left:-10%;
  background:radial-gradient(circle at 50% 50%, rgba(198,164,85,.20) 0%, rgba(198,164,85,0) 66%);
  animation:pfPoolB 53s cubic-bezier(.22,.68,.32,1) infinite;
}
@keyframes pfPoolA{
  0%,100%{transform:translate3d(0,0,0) scale(1);}
  50%    {transform:translate3d(-3.5%,4%,0) scale(1.09);}
}
@keyframes pfPoolB{
  0%,100%{transform:translate3d(0,0,0) scale(1);}
  50%    {transform:translate3d(5%,-3%,0) scale(1.12);}
}

/* --- the silk bands ---
   The comp's signature is a broad diagonal fall of light down the right of
   the frame. It is drawn as a gradient with wide, soft stops rather than a
   hard band under filter:blur() — the gradient costs one paint and the blur
   costs a filter layer, and at these stop distances they look the same. */
.pf-silk{
  position:absolute;
  top:-45%;
  height:190%;
  rotate:19deg;
  will-change:transform;
  background:linear-gradient(90deg,
    rgba(255,255,255,0)   0%,
    rgba(255,255,255,.34) 22%,
    rgba(255,255,255,.90) 50%,
    rgba(255,255,255,.30) 76%,
    rgba(255,255,255,0)  100%);
  animation:pfSilk 37s cubic-bezier(.22,.68,.32,1) infinite;
}
/* ⚠️ Wider and further out than looks right in the file. Rotated 19deg and
   clipped by the section, only the middle of a band this tall is ever on
   screen, so a narrow one reads as a smear rather than as a fall of light —
   the first pass measured 22vw here and photographed as nothing at all. */
.pf-silk-a{right:-2%; width:clamp(190px,27vw,470px);opacity:1;}
.pf-silk-b{right:17%; width:clamp(80px,10vw,175px);opacity:.7;animation-duration:49s;animation-direction:reverse;}
/* the third is champagne rather than white, so the fall of light has a
   colour in it and does not read as a grey wash */
.pf-silk-c{
  left:7%;width:clamp(90px,13vw,220px);opacity:.5;
  animation-duration:61s;
  background:linear-gradient(90deg,
    rgba(250,238,200,0)   0%,
    rgba(250,238,200,.55) 48%,
    rgba(250,238,200,0)  100%);
}
@keyframes pfSilk{
  0%,100%{transform:translateX(-5%);}
  50%    {transform:translateX(8%);}
}

/* --- the scroll-linked sheen ---
   ⚠️ SCROLL-LINKED, AND ONLY WHERE THAT IS REAL. animation-timeline:view()
     is behind @supports for a reason that is not caution: an
     `animation-name` with no supported timeline does not sit still, it falls
     back to a TIME timeline, and animation-duration:auto computes to 0s —
     the band would snap to its end state on load in every browser that does
     not implement it. Inside @supports, those browsers get no animation at
     all and the sheen simply rests where it is written, which is correct.
   This is the layer a touch reader actually drives: no pointer needed, the
   scroll itself moves it. */
.pf-beam{
  position:absolute;
  top:-30%;left:-15%;
  width:44%;height:160%;
  rotate:15deg;
  opacity:.55;
  background:linear-gradient(90deg,
    rgba(255,255,255,0)   0%,
    rgba(255,255,255,.62) 45%,
    rgba(250,238,200,.44) 62%,
    rgba(255,255,255,0)  100%);
}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .pf-beam{
      animation:pfBeam linear both;
      animation-timeline:view();
      animation-range:entry 0% exit 100%;
    }
  }
}
@keyframes pfBeam{
  from{translate:0 0;   opacity:.18;}
  50% {                 opacity:.62;}
  to  {translate:150% 0;opacity:.18;}
}

/* ---------------------------------------------------------
   THE FURNITURE FROM THE COMP

   Three things the comp carries that the layout alone did not:
   a big thin circle in the bottom right, a serum dropper
   entering top right, and a swirl of cream coming in from the
   left.

   ⚠️ THERE WERE FIVE, AND TWO OF THEM WERE NEVER IN THE COMP.
     A dashed route with a lit bead, and four contour strokes
     across the ground. Cropping the same region out of the
     comp and out of the build and setting them side by side
     settles it: the comp's ground is clean — no dashes
     anywhere, no contour strokes anywhere. Both were built
     from a reading of the comp the comp does not support, and
     both are gone.

   ⚠️ THE CIRCLE IS NOT ONE OF THEM. It reads like the same
     kind of thing and it is not: the comp really does draw one
     clean thin curve through the bottom right. Nor are the
     typographic rules — the dash after PROVEN BY MANY, the
     divider between the figures, the rule under RADIANT SKIN.
     All of those are in the comp.

   ⚠️ THE DROPPER AND THE CREAM ARE PHOTOGRAPHS NOW. The
     cut-outs were supplied and are carried as background
     images; the boxes, positions, sizes and motion are all
     here rather than in the artwork, which is why swapping
     them in changed no structure at all.

   ⚠️ EVERY ONE OF THEM IS DECORATION. .proof-atmos is
     aria-hidden and pointer-events:none, and main.js puts
     .is-idle on the section whenever it cannot see it, which
     pauses all of this outright.

   ⚠️ AND NONE OF IT MAY COST CONTRAST. The cream lies under
     the column the lead copy is read in and the dropper sits
     beside the kicker, so both are held to low opacity and
     both were re-measured after: twelve targets, no change.
   --------------------------------------------------------- */

/* --- the big circle, mostly out of frame --- */
.pf-arc{
  position:absolute;
  right:-14%;bottom:-34%;
  width:min(56vw,780px);aspect-ratio:1;
  border-radius:50%;
  border:1px solid rgba(198,164,85,.24);
  animation:pfArc 40s var(--ease-soft) infinite;
}
@keyframes pfArc{
  0%,100%{scale:1;    opacity:.85;}
  50%    {scale:1.035;opacity:1;}
}

/* --- the box the two objects hang off ---
   ⚠️ THE SAME GEOMETRY AS .shell, AND THAT IS THE POINT. The copy is inside a
   centred column; the section is the whole window. Anchoring decoration to the
   section means "beside the column" is a different offset at every width — it
   was clear at 1440 and 820 and across the kicker at 1280 and 1024, which is
   not a number problem. Anything positioned against this is beside the column
   at every width, because it is measured from the column. */
.pf-margin{
  position:absolute;
  left:0;right:0;top:0;bottom:0;
  width:100%;max-width:var(--shell);
  margin-inline:auto;
  pointer-events:none;
  /* ⚠️ HOW FAR THE WINDOW IS FROM THIS COLUMN, per side, and 0 once the
     column already fills the window. Both objects below sit ON the window's
     edge in the comp, and this is the only way to say that from inside a
     centred box: a fixed offset is a different distance from the window at
     every width, which is the fault that put the dropper through the kicker. */
  --pf-out:max(0px, (100vw - var(--shell)) / 2);
}

/* --- the dropper ---
   ⚠️ THE SUPPLIED CUT-OUT, and the numbers are fitted rather than chosen.
     solveplace.js searched the artwork's own alpha mask for the size and edge
     offset that reproduce the box the dropper occupies in the comp. At 1672
     that box is 142x344 — and the whole trimmed asset drawn 142 across IS
     142x344, so nothing is cropped by the frame. 142/1672 = 8.49vw.

   ⚠️ WHAT LOOKS LIKE A CROP IS BAKED INTO THE PHOTOGRAPH. The tube runs out
     of the asset's own top-right corner: its ink touches the file's top edge
     and its right edge, with 0px of margin on either. So the right edge has
     to land ON the window's edge — anywhere short of it and that cut shows as
     a tube sliced off in mid-air.
   */
.pf-dropper{
  position:absolute;
  right:calc(-1 * var(--pf-out));
  /* it enters from above the section, which is what the comp draws: 115px
     above the top edge there, and -6.6vw is 110px at 1672 */
  /* -6.9vw is 115px at 1672, which is where the comp puts it */
  top:clamp(-116px,-6.9vw,-40px);
  width:clamp(104px,8.5vw,170px);
  /* ⚠️ THE TRIMMED ASSET, SO THE BOX IS THE ARTWORK. The upload is 32.5%
     empty down its left side, and pfclear.js measures boxes against the copy
     on purpose. An untrimmed asset reports collisions that are not there. */
  aspect-ratio:635/1540;
  background-image:url('../img/decor/decor-dropper.png');
  background-image:image-set(url('../img/decor/decor-dropper.webp') type('image/webp'),
                             url('../img/decor/decor-dropper.png')  type('image/png'));
  background-size:100% 100%;
  background-repeat:no-repeat;
  /* the warm halo the comp puts behind the tip and the drop */
  filter:drop-shadow(0 0 30px rgba(214,168,74,.42));
  opacity:.96;
  /* ⚠️ THE PIVOT IS WHERE IT ENTERS. It hangs in from the top right corner,
     so that corner is the one that must not move; swaying about the middle
     reads as an object floating rather than one hanging. */
  transform-origin:100% 0;
  animation:pfSway 11s var(--ease-soft) infinite;
}
/* ⚠️ NO BASE ROTATION ANY MORE, AND THAT IS NOT A TIDY-UP. The stand-in was
   drawn upright and leaned 6deg to look right; this photograph already sits
   at its own angle, so a rotation here is 6deg of EXTRA lean plus a bounding
   box inflated by it — at 9deg a 187px dropper once measured 238px across,
   and the box is what has to clear the copy.
   And an animation supplies the computed value of every property it names, so
   these keyframes ARE the rotation: a declaration above would never be seen
   once this starts. */
@keyframes pfSway{
  0%,100%{rotate:0deg;    translate:0 0;}
  50%    {rotate:-1.1deg; translate:0 7px;}
}

/* --- the cream ---
   Fitted the same way: 386px across in the 1672 comp with its left edge on
   the window's left edge, which is 23.09vw.
   ⚠️ Unlike the dropper this one floated free of every edge of its upload, so
     its ends are naturally rounded and the ONLY hard cut is the one the
     window makes. That is why it may sit flush without looking severed. */
.pf-cream{
  position:absolute;
  left:calc(-1 * var(--pf-out));
  /* ⚠️ INSIDE THE SECTION, NOT HANGING OFF IT — and the sign of this changed
     to put it there. At -3vw the swirl was cut in half by the section's
     bottom edge; the comp shows all of it. Measured: the comp's cream ends
     653px below the section top and the section is 695 tall, so 42px up from
     the bottom, and 2.5vw is 42px at 1672. */
  bottom:clamp(16px,2.5vw,46px);
  width:clamp(190px,23vw,400px);
  aspect-ratio:1213/1041;
  background-image:url('../img/decor/decor-cream.png');
  background-image:image-set(url('../img/decor/decor-cream.webp') type('image/webp'),
                             url('../img/decor/decor-cream.png')  type('image/png'));
  background-size:100% 100%;
  background-repeat:no-repeat;
  opacity:.92;
  filter:drop-shadow(0 18px 34px rgba(120,98,52,.14));
  animation:pfCreamFloat 19s var(--ease-soft) infinite;
}
@keyframes pfCreamFloat{
  0%,100%{translate:0 0;     rotate:0deg;}
  50%    {translate:6px -9px; rotate:-1.2deg;}
}

/* =========================================================
   3. THE STAGE

   One grid holds the lead, the medallion, the two figures,
   the kicker, the button and the pills. Everything the two
   comps move between desktop and phone is a child of it,
   because `order` cannot reorder across containers and the
   phone comp puts the button AFTER the pills while the
   desktop comp puts it on the right.

   ⚠️ The old section was two .pf-panel cards — a claims strip
     and a figures strip. Both are gone, and so are their
     rules. Nothing hides them; they are deleted.
   ========================================================= */
.proof .shell{position:relative;z-index:1;}

.pf-stage{
  display:grid;
  /* lead | medallion | figures | right column, and the right column is two
     rows so the kicker can sit above the button inside one area each */
  /* ⚠️ REBALANCED AFTER THE GUTTER TOOK 150px OFF THE ROW. The right-hand
     column only carries a four-word kicker and a button, so it gives width
     back to the lead — which had started wrapping the script line onto two
     — and to the two figures, which had lost the air around their divider. */
  grid-template-columns:minmax(0,1.34fr) auto minmax(0,.92fr) minmax(0,.46fr);
  grid-template-areas:
    "lead  medal stats kick"
    "lead  medal stats aside"
    "claims claims claims claims";
  align-items:center;
  column-gap:clamp(16px,2.4vw,44px);
  row-gap:clamp(8px,1.2vw,16px);
  /* ⚠️ A GUTTER FOR THE DECORATION, and it is a layout decision rather than
     a nicety. In the comp the right-hand column sits well inside the frame
     and the dropper occupies the band beside it. Right-aligned to the shell
     edge instead, there is no such band at any width — the dropper had to be
     lifted almost entirely off the top of the section to stay off the kicker,
     and it read as a sliver. This makes the band the comp assumes. */
  padding-right:clamp(0px,6.6vw,116px);
}
.pf-lead{grid-area:lead;min-width:0;}
.pf-medal{grid-area:medal;}
.pf-side{grid-area:stats;}
.pf-kicker{grid-area:kick;align-self:end;}
.pf-aside{grid-area:aside;align-self:start;}
.pf-claims-wrap{grid-area:claims;margin-top:clamp(22px,3vw,40px);}

/* ⚠️ THIS WRAPPER EXISTS FOR THE PHONE AND FOR NOTHING ELSE. On the phone
   comp the kicker sits BESIDE the medallion; on the desktop comp it sits in
   the right-hand column. display:contents dissolves the wrapper here so both
   children take their own grid areas, and the phone turns it back into a real
   flex row. */
.pf-medal-row{display:contents;}

/* ---------- the lead ---------- */

/* eyebrow, then a gold rule that ends in a star — the comp's own mark */
.pf-eyebrow{
  display:flex;align-items:center;gap:14px;
  margin-bottom:14px;
}
.pf-rule{
  display:inline-flex;align-items:center;gap:7px;
  /* it draws itself in from the left as the head lands */
  transform-origin:left center;
}
.pf-rule::before{
  content:"";
  display:block;
  width:clamp(48px,6vw,88px);
  height:1px;
  background:linear-gradient(90deg, rgba(198,164,85,.18) 0%, var(--gold) 45%, var(--gold) 100%);
}
.pf-star{
  width:13px;height:13px;flex:none;
  fill:var(--gold);
  animation:pfTwinkle 4.6s cubic-bezier(.22,.68,.32,1) infinite;
}
@keyframes pfTwinkle{
  0%,100%{opacity:.72;scale:1;}
  50%    {opacity:1;  scale:1.28;}
}

.pf-title{margin:0;}
/* ⚠️ <em> with the italic taken off. It is <em> and not <span> because the
   second half of the line is genuinely the emphasised half — a screen reader
   should hear that, and the gold is only how it is shown. */
.pf-title em{
  font-style:normal;
  color:var(--gold-accent);
}

/* ---- THE ROLLING WORD ----
   Four words on a reel: It Counts / It Matters / Results Speak / Results
   Show. A short hold, then a shuffle — a fast spin past several words that
   decelerates into the next stop.

       cycle            11s

   ⚠️ KEPT, THOUGH THE COMP DRAWS A STATIC "Results Speak". That word is one
     of the four, so the comp is a frame of this; and the brief asked for the
     design and for the motion both. The <br> in the markup is what puts it on
     its own line the way the comp has it.

   Nothing here opts into being paused off screen: main.js puts .is-idle on
   every section it cannot see and styles.css pauses every animation inside
   one. */
.pf-roll{
  position:relative;
  display:inline-block;
  overflow:clip;              /* ⚠️ clip, not hidden — see .section.proof */
  /* ⚠️ bottom, NOT baseline. An inline-block whose overflow is not visible
     takes its bottom margin edge AS its baseline, so vertical-align:baseline
     would quietly align the wrong edge. The rows below carry the heading's
     own line-height, so this box is exactly one line box tall and aligning
     the bottoms puts the two baselines together. */
  vertical-align:bottom;
  color:var(--gold-accent);
}
/* the sizer: all four words overlapped in ONE grid cell, so the box comes out
   as wide as the longest and one line tall — at every clamp() size, with no
   width written down anywhere to go stale */
.pf-roll-box{
  display:grid;
  grid-template-areas:"w";
  visibility:hidden;
}
.pf-roll-box > span{grid-area:w;}
.pf-roll-track{
  position:absolute;
  left:0;top:0;
  display:grid;
}
.pf-roll-box > span,
.pf-roll-track > span{
  white-space:nowrap;
  line-height:inherit;
}
/* it starts when the heading lands, rather than running unseen from load —
   so the first word is held from the moment it is read */
.pf-title.is-in .pf-roll-track{
  /* not var(--ease-out): a reel needs a hard settle, not a gentle one. Half
     the distance is covered in under a third of the 0.50s, so the rows in
     the middle are a blur and only the last one is legible on the way in. */
  animation:pfRoll 11s cubic-bezier(.38,0,.1,1) infinite;
}
/* ⚠️ the percentages are 1/21 of the TRACK, not of a row: 21 rows means one
   row is 4.761905%, and each stop is 5 of them further down. */
@keyframes pfRoll{
  0%,   20.4545%{translate:0 0;}
  25%,  45.4545%{translate:0 -23.809524%;}
  50%,  70.4545%{translate:0 -47.619048%;}
  75%,  95.4545%{translate:0 -71.428571%;}
  100%          {translate:0 -95.238095%;}
}

.pf-sub{
  margin-top:12px;
  font-size:14.5px;font-weight:300;
  /* ⚠️ --ink-2, NOT --ink-3. Measured off the pixels at 1280: --ink-3 is
     rgb(119,115,108) on this cream and comes out 4.33:1, under the 4.5 a
     14.5px line owes. The hierarchy is carried by the size and the 300
     weight, which is where it belongs — a subtitle should be smaller and
     lighter, not harder to read. */
  color:var(--ink-2);
}

/* the script line. ⚠️ aria-hidden in the markup: it repeats a promise the
   page has already made in words, and a screen reader reading "Real People.
   Real Results." a third time is noise. Parisienne is requested alongside the
   three faces the page already asks for, and cursive is the fallback. */
.pf-script{
  margin:clamp(10px,1.4vw,16px) 0 0;
  font-family:"Parisienne", "Segoe Script", "Brush Script MT", cursive;
  font-size:clamp(20px,2.15vw,28px);
  line-height:1.25;
  /* one line is the whole idea of a signature */
  white-space:nowrap;
  /* ⚠️ --gold-ink, and --gold-accent was the obvious choice. Measured 2.75:1
     against this ground; the README records it as never having cleared 3:1
     anywhere, so it cannot carry 21px non-bold text, which owes 4.5:1. Large
     text starts at 24px — a clamp() MINIMUM of 21 is what decides that, not
     the 31 it reaches on a desktop. --gold-ink measures 4.9:1 here. */
  color:var(--gold-ink);
  /* it writes itself on rather than fading: a script face that slides is a
     signature, and the delay lets the sub-line land first */
  opacity:0;translate:-10px 0;
  transition:opacity .9s var(--ease) .1s, translate .9s cubic-bezier(.16,.84,.44,1) .1s;
}
.pf-script.is-in{opacity:1;translate:0 0;}

/* ---------- the medallion ---------- */
.pf-medal{
  position:relative;
  justify-self:center;
  width:clamp(184px,17.5vw,258px);
  aspect-ratio:1;
  display:grid;place-items:center;
  border-radius:50%;
  background:
    radial-gradient(circle at 50% 38%, rgba(255,255,255,.97) 0%, rgba(253,248,238,.93) 54%, rgba(246,235,212,.8) 100%);
  box-shadow:
    0 0 0 1px rgba(198,164,85,.30),
    0 0 54px -4px rgba(226,190,110,.72),
    0 26px 56px -36px rgba(60,48,22,.5),
    0 1px 0 rgba(255,255,255,.92) inset;
}
/* the halo, which is the whole reason the comp's rating reads as lit rather
   than printed. It breathes on scale and opacity only — the medallion itself
   is carrying a [data-reveal] transform while this runs. */
.pf-medal-halo{
  position:absolute;inset:clamp(-14px,-1.2vw,-9px);
  border-radius:50%;
  border:1px solid rgba(198,164,85,.34);
  pointer-events:none;
  animation:pfHalo 7.4s var(--ease-soft) infinite;
}
@keyframes pfHalo{
  0%,100%{scale:1;    opacity:.5;}
  50%    {scale:1.045;opacity:.95;}
}
.pf-medal-in{display:grid;justify-items:center;gap:clamp(3px,.5vw,6px);}
.pf-score{
  margin:0;
  font-family:var(--f-display);
  font-size:clamp(44px,5.4vw,70px);
  line-height:1;font-weight:400;
  letter-spacing:-.012em;
  color:var(--gold-ink);
}
.pf-stars{display:flex;gap:clamp(2px,.4vw,5px);}
.pf-star-ico{
  width:clamp(14px,1.55vw,20px);height:auto;flex:none;
  fill:var(--gold);
}
.pf-medal-cap{
  margin:clamp(2px,.4vw,5px) 0 0;
  font-family:var(--f-body);
  font-size:12.5px;font-weight:400;
  color:var(--ink-2);
}

/* ---------- the two figures ---------- */
.pf-side{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(14px,2.1vw,32px);
}
.pf-stat{text-align:center;min-width:0;}
.pf-num{
  margin:0;
  font-family:var(--f-display);
  font-size:clamp(25px,3vw,40px);
  line-height:1.05;font-weight:400;
  color:var(--gold-ink);
  white-space:nowrap;
}
.pf-cap{
  margin:5px 0 0;
  font-size:12.5px;font-weight:400;
  color:var(--ink-2);
}
.pf-vr{
  flex:none;
  width:1px;height:clamp(38px,4.4vw,58px);
  background:linear-gradient(180deg, rgba(198,164,85,0), rgba(198,164,85,.55) 50%, rgba(198,164,85,0));
}

/* ---------- the right column ---------- */
.pf-kicker{
  margin:0 0 clamp(10px,1.3vw,16px);
  justify-self:end;
  text-align:right;
  font-family:var(--f-display);
  font-style:italic;
  font-size:clamp(11px,1vw,13px);
  line-height:1.62;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--ink-2);
}
.pf-aside{display:grid;justify-items:end;gap:clamp(12px,1.6vw,18px);}
.pf-kicker-rule{
  width:clamp(26px,3vw,40px);height:1px;
  background:linear-gradient(90deg, rgba(198,164,85,0), var(--gold));
}

/* ---------- the ornament beside the medallion ----------
   Off by default: it exists for the phone row and the desktop has the kicker
   in its right-hand column instead. See the note on the markup. */
.pf-spark{display:none;}
/* .btn .btn-gold .btn-sheen supply the pill, the fill and the sweep — this
   only has to stop the label breaking */
.pf-cta{white-space:nowrap;}

/* the ornament's catch of light. scale and opacity only — both are
   compositor properties, and this sits over a ground that already moves. */
@keyframes pfSparkLit{
  0%,100%{opacity:var(--o,.6);scale:1;}
  46%    {opacity:1;scale:1.16;}
}

/* ---------- the claim pills ---------- */
.pf-claims-wrap{min-width:0;}
.pf-claims{
  /* ⚠️ THE SAPAW IS GONE AND THIS IS A REAL GAP NOW. The three pills used to
     be pulled under one another by a negative margin, with matching extra
     padding keeping each label clear of the covered edge. On a desktop that
     read as three cards jammed into one another rather than as three separate
     claims, so the overlap comes out at every width and the row is spaced.
     ⚠️ STILL ONE VARIABLE, for the reason the old one was one: the space
     BETWEEN the pills and the space SUBTRACTED from each pill's width are the
     same number, and two hard-coded copies drift apart at the widths between
     their clamps. That is how the trust band's divider ended up 14px out. */
  --pfc-gap:clamp(10px,1.5vw,20px);
  position:relative;
  list-style:none;margin:0 auto;padding:0;
  display:flex;
  gap:var(--pfc-gap);
  /* the cluster does not stretch to the whole shell on a wide screen */
  width:min(100%, 920px);
}
.pf-claim{
  /* ⚠️ --ac IS THE RAMP, AND IT IS SET BY POSITION, NOT BY PILL. These are the
     three the story cards already carry — the ones supplied as a reference and
     shipped on .scard — so a reader meets the same gold -> taupe -> espresso
     step twice on the page instead of two unrelated palettes. A ramp belongs to
     the ORDER, so it is :nth-child here rather than an inline style: reorder
     the claims and the colours still run light to dark. The default below is
     the first stop, so a fourth pill is coloured rather than transparent. */
  --ac:176,139,44;
  position:relative;
  /* ⚠️ SAME SHAPE, AND flex:1 1 0 DOES NOT GIVE IT. These measured 196, 266
     and 254 wide on a desktop — three pills of three different lengths. The
     obvious fix was flex:1 1 0, and it shipped three widths of 86.3 / 97.2 /
     97.2 at 320: with the global box-sizing:border-box, a flex-basis of 0
     CANNOT go below the item's own padding + border, so a pill carrying more
     padding than its neighbours came out WIDER than them instead.
     State the width and the arithmetic is closed whatever the padding does:
     3w + 2gap == 100%. */
  flex:0 0 auto;
  width:calc((100% - var(--pfc-gap) * 2) / 3);
  min-width:0;
  display:flex;align-items:center;
  gap:clamp(9px,1vw,13px);
  padding:clamp(8px,.9vw,11px) clamp(17px,1.9vw,26px) clamp(8px,.9vw,11px) clamp(8px,.9vw,11px);
  border-radius:999px;
  /* ⚠️ OPAQUE, NOT rgba(255,255,255,.86). The backdrop behind these drifts
     — a pool, a beam and the star field all move under this row — and a
     translucent pill lets them travel across its own label. The cream base
     under the colour wash is what holds the three grounds identical to each
     other and steady while the section moves behind them. */
  background:
    linear-gradient(rgba(var(--ac),.20), rgba(var(--ac),.20)),
    var(--cream);
  border:1px solid rgba(var(--ac),.45);
  box-shadow:
    /* ⚠️ DOWN, NOT 9px TO THE RIGHT. The sideways cast existed to land on
       the pill this one was sitting on top of. With the pills apart there is
       nothing under it any more and it fell into the gap as a grey smear. */
    0 8px 18px -12px rgba(var(--ac),.55),
    0 14px 30px -24px rgba(60,48,22,.5),
    0 1px 0 rgba(255,255,255,.85) inset;
  transition:
    background-color .42s var(--ease),
    border-color .42s var(--ease),
    box-shadow .42s var(--ease),
    translate .42s cubic-bezier(.16,.84,.44,1);
}
.pf-claim:nth-child(2){--ac:124,104,86;}
.pf-claim:nth-child(3){--ac:51,36,23;}

/* The three z-index rules that dealt these like a hand of cards, and the
   .pf-claim + .pf-claim rule that pulled each pill under its neighbour, came
   out with the overlap: nothing crosses anything now, so a stacking order has
   nothing to order. Recorded in README.md — there is no version control here
   to recover them from. */

/* ⚠️ GATED, BECAUSE :hover STICKS AFTER A TAP. A touch browser leaves the
   hovered state on the last thing a finger landed on, so an ungated lift
   leaves one of the three boxes sitting 2px higher than its neighbours until
   something else is touched — in a row whose whole job is that the three read
   as equals. The FAQ rows on this page carry the same gate for the same
   reason. Wrapped in place rather than moved, so the cascade is unchanged:
   same selector, same specificity, same position in the file. */
@media (hover:hover){
  .pf-claim:hover{
    background:
      linear-gradient(rgba(var(--ac),.26), rgba(var(--ac),.26)),
      var(--cream);
    border-color:rgba(var(--ac),.72);
    box-shadow:
      0 12px 22px -12px rgba(var(--ac),.6),
      0 20px 36px -22px rgba(60,48,22,.5),
      0 1px 0 rgba(255,255,255,.9) inset;
    translate:0 -2px;
  }
}
/* and a press state for the finger, which is what the gate takes away */
@media (hover:none){
  .pf-claim:active{
    border-color:rgba(var(--ac),.72);
    background:
      linear-gradient(rgba(var(--ac),.26), rgba(var(--ac),.26)),
      var(--cream);
  }
}
.pf-ico{
  flex:none;
  width:clamp(30px,3vw,38px);height:clamp(30px,3vw,38px);
  display:grid;place-items:center;
  border-radius:50%;
  /* The disc carries the pill's own stop at FULL strength — this is where the
     colour actually reads; the wash behind the label is only its echo.
     ⚠️ NO WHITE HIGHLIGHT ON IT. A radial 32% white bloom was drawn across the
     top, which is where half the glyph sits: measured off the rendered pixels,
     it lifted the first disc to rgb(201,176,112) and a white glyph on that is
     2.11:1 — under the 3:1 a graphic owes. Flat, the same disc is 3.19:1 and
     the two darker stops are 5.30 and 14.96. The bloom was mine and removing
     it is the whole fix. */
  background:rgb(var(--ac));
  box-shadow:
    0 0 0 1px rgba(255,255,255,.5) inset,
    0 6px 14px -8px rgba(var(--ac),.9);
}
.pf-ico svg{
  width:52%;height:auto;
  /* ⚠️ white on the FIRST stop is the tightest of the three. An icon is a
     graphic, so it owes 3:1, not 4.5:1 — measured against the rendered pixels
     below. The other two discs are far darker and clear it easily. */
  fill:none;stroke:#fff;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
}
/* ---------- the glyphs are alive inside the discs ----------
   ⚠️ THE GLYPH MOVES, THE DISC DOES NOT. The disc is the colour, and the ramp
   only reads if the three circles sit still enough to be compared. Everything
   here is inside the svg.

   ⚠️ transform-box:fill-box ON EVERY ROTATING PART. Without it an SVG child
   rotates about the SVG's own origin — the top-left of a 24x24 viewBox — and a
   6deg rock becomes a swing halfway out of the circle. fill-box puts the origin
   on the shape's own box, which is what "spin in place" means.

   ⚠️ rotate/translate/scale AS THEIR OWN PROPERTIES, NEVER THE transform
   SHORTHAND. A later transform at equal specificity would silently wipe the
   others — that trap has already cost this page four separate breakages, and
   here it would be three animations quietly reduced to whichever came last.

   ⚠️ THEY ONLY RUN ONCE THE ROW HAS BEEN SEEN (.is-in), so nothing animates
   above the fold or in a section the reader has not reached. */

.pf-ico svg{overflow:visible;}

/* 1 — FDA Approved: the tick is ticked, over and over.
   ⚠️ dasharray 14 against a path about 9 units long. The tick is
   M9 12.2 l2.1 2.1 L15.4 10 — two segments of ~2.97 and ~6.08, so ~9.05 total.
   A dash longer than the path is fully drawn at offset 0 and fully clear at
   +/-14, which is what lets it draw IN and then draw OUT instead of blinking.
   Using the measured 9.05 exactly would leave the ends touching. */
.pf-claims-wrap.is-in .pf-claim:nth-child(1) .pf-ico svg path:nth-child(2){
  stroke-dasharray:14;
  animation:pf-tick 3.8s cubic-bezier(.16,.84,.44,1) infinite;
}
@keyframes pf-tick{
  0%, 10%   {stroke-dashoffset:14;}
  30%, 68%  {stroke-dashoffset:0;}
  86%, 100% {stroke-dashoffset:-14;}
}
/* the shield takes a breath under it, on the same clock */
.pf-claims-wrap.is-in .pf-claim:nth-child(1) .pf-ico svg path:nth-child(1){
  transform-box:fill-box;transform-origin:50% 50%;
  animation:pf-shield 3.8s ease-in-out infinite;
}
@keyframes pf-shield{
  0%, 100%{scale:1;}
  30%     {scale:1.06;}
  60%     {scale:.99;}
}

/* 2 — Advanced Formulations: the flask rocks and the liquid keeps its level.
   ⚠️ THE LEVEL LINE MOVES AGAINST THE ROCK, NOT WITH IT. It is a child of the
   same svg, so it already inherits the rotation; giving it the opposite bob is
   what reads as liquid staying flat while the glass tips. In phase it would
   just look like a crack in the drawing. */
.pf-claims-wrap.is-in .pf-claim:nth-child(2) .pf-ico svg{
  transform-box:fill-box;transform-origin:50% 64%;
  animation:pf-rock 4.4s ease-in-out infinite;
}
@keyframes pf-rock{
  0%, 100%{rotate:-6deg;}
  50%     {rotate:6deg;}
}
.pf-claims-wrap.is-in .pf-claim:nth-child(2) .pf-ico svg path:nth-child(2){
  transform-box:fill-box;transform-origin:50% 50%;
  animation:pf-level 4.4s ease-in-out infinite;
}
@keyframes pf-level{
  0%, 100%{rotate:5deg;translate:0 .5px;opacity:.72;}
  50%     {rotate:-5deg;translate:0 -.5px;opacity:1;}
}

/* 3 — Trusted by Celebrities: a four-point star, so it twinkles.
   45deg is the whole point — a four-point star at 45 is its own silhouette
   again, so the turn reads as a glint rather than as the icon spinning. */
.pf-claims-wrap.is-in .pf-claim:nth-child(3) .pf-ico svg path{
  transform-box:fill-box;transform-origin:50% 50%;
  animation:pf-twinkle 3.2s ease-in-out infinite;
}
@keyframes pf-twinkle{
  0%, 100%{scale:.88;rotate:0deg;opacity:.78;}
  42%     {scale:1.12;rotate:45deg;opacity:1;}
  66%     {scale:.97;rotate:52deg;opacity:.92;}
}

.pf-label{
  font-family:var(--f-display);
  font-size:clamp(13.5px,1.32vw,16.5px);
  line-height:1.25;
  color:var(--ink);
  white-space:nowrap;
}

/* =========================================================
   4. THE ENTRANCE

   [data-reveal] carries each block in — it owns `opacity`,
   `transform` and `filter` on the elements that hold it, and
   nothing here touches those three on the same element.

   The pieces INSIDE a revealed block are staggered off that
   block's own .is-in rather than carrying their own
   [data-reveal]: the block arrives as one object, so a second
   observer per child would measure the same moment again, and
   the delays can be tuned against each other rather than in
   95ms steps.

   ⚠️ They move on `translate`, not `transform`. The element
     above them is mid-transform while these run.
   ========================================================= */
.pf-rule{scale:0 1;opacity:0;transition:scale .9s cubic-bezier(.16,.84,.44,1) .12s, opacity .5s var(--ease) .12s;}
.pf-eyebrow.is-in .pf-rule{scale:1 1;opacity:1;}

/* the five stars arrive one after another, which is the one moment in this
   section that earns a stagger — they are a count */
.pf-star-ico{
  opacity:0;translate:0 7px;
  transition:opacity .5s var(--ease), translate .5s cubic-bezier(.16,.84,.44,1);
}
.pf-medal.is-in .pf-star-ico{opacity:1;translate:0 0;}
.pf-medal.is-in .pf-star-ico:nth-child(1){transition-delay:.30s;}
.pf-medal.is-in .pf-star-ico:nth-child(2){transition-delay:.38s;}
.pf-medal.is-in .pf-star-ico:nth-child(3){transition-delay:.46s;}
.pf-medal.is-in .pf-star-ico:nth-child(4){transition-delay:.54s;}
.pf-medal.is-in .pf-star-ico:nth-child(5){transition-delay:.62s;}

.pf-claim{
  opacity:0;translate:0 16px;
  transition:
    opacity .8s var(--ease),
    translate .8s cubic-bezier(.16,.84,.44,1),
    background-color .42s var(--ease),
    border-color .42s var(--ease),
    box-shadow .42s var(--ease);
}
.pf-claims-wrap.is-in .pf-claim{opacity:1;translate:0 0;}
.pf-claims-wrap.is-in .pf-claim:nth-child(1){transition-delay:.16s;}
.pf-claims-wrap.is-in .pf-claim:nth-child(2){transition-delay:.30s;}
.pf-claims-wrap.is-in .pf-claim:nth-child(3){transition-delay:.44s;}

/* the two figures come up with the rule between them drawing out */
.pf-stat{
  opacity:0;translate:0 14px;
  transition:opacity .8s var(--ease), translate .8s cubic-bezier(.16,.84,.44,1);
}
.pf-side.is-in .pf-stat{opacity:1;translate:0 0;}
.pf-side.is-in .pf-stat:nth-child(1){transition-delay:.14s;}
.pf-side.is-in .pf-stat:last-child{transition-delay:.28s;}
.pf-vr{scale:1 0;transition:scale .7s cubic-bezier(.16,.84,.44,1) .34s;}
.pf-side.is-in .pf-vr{scale:1 1;}

/* ⚠️ THE KICKER RULE DOES NOT ANIMATE, AND THE FIRST DRAFT OF THIS FILE
   PRETENDED IT DID. It sits BEFORE .pf-cta in the DOM, so no sibling
   combinator can reach back to it from the element that gets .is-in, and
   nothing between them carries [data-reveal] at all — the three selectors
   written here first could never have matched anything. A 40px hairline is
   not worth a :has() or a wrapper, so it simply arrives with its column. */

/* =========================================================
   5. THE PHONE

   The supplied phone comp is not the desktop stacked. The
   kicker moves beside the medallion, the pills become a
   swipeable row, and the button goes full width at the very
   end — after the pills, which is why every one of these is a
   child of one grid.
   ========================================================= */
@media (max-width:980px){
  .pf-stage{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:none;
    row-gap:clamp(16px,3.4vw,26px);
    justify-items:stretch;
    /* ⚠️ THE GUTTER COMES OFF, AND IT IS WHY NOTHING IN THIS SECTION WAS
       CENTRED. The base rule reserves padding-right:clamp(0px,6.6vw,116px)
       so the dropper has a band beside the right-hand column, which is what
       the desktop comp draws. There is no right-hand column here — the grid
       is one stacked track — so all that band does is push every row left.
       Measured before: 20px from the left and 45.7 from the right at 390,
       43.8 at 360, 41.1 at 320, on the title, the lead, the figures, the
       three claim boxes and the button alike. 6.6vw is 25.7px at 390 and
       that is the whole of the difference.
       ⚠️ The dropper does NOT move with this. It is absolutely positioned
       against the SECTION — right:-7.2vw, top:-30px here — not against this
       grid, so taking the padding off widens the rows and leaves the
       decoration where it is. Checked against the title, which is the row
       that reaches nearest to it. */
    padding-right:0;
  }
  /* ⚠️ every area assignment has to be released, or a named area on an item
     whose grid no longer declares that name lands it in an implicit track */
  .pf-lead,.pf-medal,.pf-side,.pf-kicker,.pf-aside,.pf-claims-wrap{grid-area:auto;}

  .pf-lead{order:1;}
  .pf-medal-row{
    display:flex;                 /* ⚠️ no longer contents — see section 3 */
    order:2;
    align-items:center;justify-content:center;
    gap:clamp(14px,4vw,28px);
  }
  .pf-medal{justify-self:auto;width:clamp(168px,44vw,220px);}
  /* ⚠️ THE FOUR WORDS COME OUT, ASKED FOR: "remove the words beside the
     circle, theres too much words on this part na kasi". They are not a
     fact and nothing is lost with them — "Backed by real results" is two
     rows above, and .pf-script says "Real People. Real Results." one row
     above that, which is the same promise in the same section for the third
     time. display:none rather than deleted, because the DESKTOP still uses
     this element in its right-hand column above the button, where it is one
     item in a two-row area rather than a third restatement beside a circle.
     .pf-spark takes the space here. */
  .pf-kicker{display:none;}
  /* ⚠️ THE ORNAMENT IS NARROW ON PURPOSE. The row is a centred flex line and
     the medallion is 44vw of it; the words it replaces were 64px wide at 390
     and carried the row off centre on their own. At about 38px the medallion
     stays the thing being looked at and the row still reads as two objects
     rather than one circle adrift. */
  .pf-spark{
    display:grid;
    justify-items:center;
    align-content:center;
    position:relative;
    flex:none;
    width:clamp(34px,11.4vw,52px);
    gap:clamp(11px,3.6vw,18px);
    padding-block:clamp(6px,2vw,10px);
  }
  /* the hairline the three marks are strung on, fading out at both ends so it
     ends in light rather than on a cut */
  .pf-spark::before{
    content:"";
    position:absolute;left:50%;top:0;bottom:0;width:1px;
    translate:-50% 0;
    background:linear-gradient(180deg,
      rgba(198,164,85,0) 0%,
      rgba(198,164,85,.62) 24%,
      rgba(198,164,85,.62) 76%,
      rgba(198,164,85,0) 100%);
  }
  .pf-spark svg{
    position:relative;          /* above the hairline */
    display:block;
    fill:var(--gold);
    height:auto;
  }
  /* ⚠️ THREE SIZES, NOT THREE COPIES. Equal marks on a rule read as a
     bullet list; graded, they read as light catching. The middle one is the
     largest because it sits level with the medallion's own centre. */
  /* ⚠️ THE RESTING OPACITY IS A VARIABLE, AND IT HAS TO BE. An animation
     beats a normal declaration outright, so a keyframe naming opacity would
     swallow all three of these figures and twinkle the row between one
     shared pair of values. The keyframes read --o instead, so each mark
     breathes around ITS OWN rest. This file has been bitten by that exact
     cascade rule before — see the note on the hero photograph scale. */
  .pf-spark svg:nth-child(1){--o:.58; width:clamp(10px,3.2vw,14px);opacity:var(--o);}
  .pf-spark svg:nth-child(2){--o:.95; width:clamp(16px,5vw,22px);   opacity:var(--o);}
  .pf-spark svg:nth-child(3){--o:.72; width:clamp(12px,3.8vw,17px); opacity:var(--o);}

  /* a slow catch of light down the three, gated rather than put in the
     reduce block below — this element only exists at this breakpoint */
  @media (prefers-reduced-motion:no-preference){
    .pf-spark svg{animation:pfSparkLit 6.4s var(--ease) infinite;}
    .pf-spark svg:nth-child(2){animation-delay:.9s;}
    .pf-spark svg:nth-child(3){animation-delay:1.9s;}
  }
  .pf-side{order:3;gap:clamp(18px,6vw,34px);}
  .pf-claims-wrap{order:4;margin-top:clamp(6px,1.6vw,12px);}
  .pf-aside{
    order:5;
    justify-items:stretch;
    gap:0;
  }
  .pf-kicker-rule{display:none;}
  .pf-cta{width:100%;justify-content:center;}

  /* ⚠️ THERE IS NO SWIPE HERE ANY MORE. This row used to be a scroll
     container with two arrows, three dots and a "Swipe to explore" label
     under it, showing one and a half pills at a time. The ask was to show all
     three at once instead, so the row is a grid that fits and the affordance
     is gone from the markup, from main.js and from this file. Written up in
     README.md, because there is no version control here to recover it from.

     ⚠️ minmax(0,1fr), NOT 1fr. 1fr is minmax(auto,1fr) and an auto minimum is
     min-content, so "Formulations" — the longest unbreakable word in the
     three — would widen its own column and push the row past the shell. */
  /* the cluster fills the shell here — there is nothing to hold back */
  .pf-claims{
    /* tighter than the desktop's, because the row has the whole shell here and
       the labels have wrapped to two lines — the pills are taller, so they
       need less air between them to read as three things */
    --pfc-gap:clamp(8px,1.8vw,14px);
    width:100%;
  }
  .pf-claim{
    max-width:none;
    justify-content:center;
  }
  /* two lines is the intended shape for the long two, not a defect — the comp
     wraps them as well. ⚠️ This is what stops a nowrap label from setting its
     own column's min-content width and pushing the row past the shell. */
  .pf-label{white-space:normal;line-height:1.28;}
}

@media (max-width:720px){
  .pf-sub{font-size:13.5px;}
  .pf-script{font-size:clamp(20px,6.4vw,26px);}
  .pf-num{font-size:clamp(26px,7.6vw,34px);}
  .pf-cap{font-size:11.5px;}
  .pf-medal-cap{font-size:11.5px;}
  .pf-silk-b{display:none;}     /* three bands on a 390px screen is a stripe */
  /* ⚠️ THE DROPPER AND THE CREAM STAY ON A PHONE. The supplied phone comp
     has both, and they are most of what makes that screen look like the
     brand rather than like a list. Only the sizes come down. */
  /* on a phone the shell has almost no outer margin, so both of these have
     to hang further off the edge to stay out of the copy */
  /* ⚠️ on a phone the column IS the window — .shell's gutter is all the
     margin there is — so both of these hang off the edge properly, and the
     cream drops below the attribution note it was crossing by 19% at 390 */
  /* ⚠️ THE PHONE COMP IS A DIFFERENT DESIGN, NOT THE DESKTOP ONE SCALED, and
     these are fitted against the handset's SCREEN rather than against the
     photograph of the handset — the bezel and the desk are most of that file.
     On the screen the dropper is 25.04vw with 7.19vw of it off the right; on
     the desktop none of it is off the edge at all. */
  .pf-dropper{width:clamp(88px,25vw,150px);right:-7.2vw;top:-30px;}
  /* ⚠️ ONE RULE, ONE PLACE. A second .pf-cream rule was added a few lines
     above this one to move it, and lost the cascade to this one for left and
     bottom while winning it for top — so the element ended up with BOTH top
     and bottom set, which stretches an absolutely positioned box between
     them: it measured 662px tall instead of 129 and reached the attribution
     note from halfway up the section. Two rules for one box is how that
     happens; this is the only one.
     ⚠️ bottom:auto is load-bearing, not tidiness.
     Position: beside the medallion at the left edge, which is where the
     supplied phone comp puts it and the one band of that edge with no type
     in it. */
  .pf-cream{
    /* ⚠️ HALF OF IT IS OFF SCREEN HERE, against none of it on the desktop —
       fitted at 63.6vw wide with 31.9vw past the left edge. The earlier
       numbers (-90px, 40vw) were tuned to a box that was mostly empty
       artwork; this box IS the artwork, so they do not carry over. */
    /* ⚠️ 54vw, NOT the 63.6vw the comp fits to. At 63.6 this is 213px tall
       at 390 and the clear band between the script and the figures is 199 —
       it does not fit, and the ink probe measured 20% of it over the
       "52,800+" figure and 66% over the caption under it. The comp's phone
       section is much taller than this one, so its ratio of width to height
       does not carry across. */
    width:clamp(180px,54vw,280px);
    /* ⚠️ 22vw off the edge leaves 32vw of it showing, and the comp shows
       31.66vw. The earlier -27 came from reading the comp's "220px visible"
       against a 390px viewport — but that 220 was measured on the handset's
       695px screen, so the figure that transfers is the vw, not the px. */
    left:-22vw;
    /* ⚠️ top, and bottom:auto is load-bearing rather than tidiness. Setting
       both stretches an absolutely positioned box between them — that once
       measured 662px tall instead of 129 and reached the attribution note. */
    /* 28% of the section puts its top just under the script line and its
       bottom just above the figures, which is the one band down this edge
       with nothing in it. It crosses the medallion on the way, and that is
       intended — the face is opaque, so the swirl passes behind it exactly
       as the comp draws. */
    /* ⚠️ PIXELS, NOT PER CENT, and that is the whole point. The script line
       above ends between 226 and 234 at every phone width while the section
       itself grows from 852 to 937 — so a percentage of the section drifts
       away from the thing it has to clear. At 28% this sat 41px onto the
       "52,800+" figure at 600 and cleanly under it at 390, which is a unit
       error rather than a number that needed tuning.
       ⚠️ bottom:auto is load-bearing. Setting both stretches an absolutely
       positioned box between them — that once measured 662px instead of 129. */
    top:240px;bottom:auto;
    opacity:.8;
  }
  .pf-arc{right:-38%;bottom:-24%;width:96vw;}
}

/* ⚠️ ONE PER ROW ON A PHONE. Asked for directly: "wag pag tabi tabihin".

   THE NOTE THAT USED TO BE HERE WAS RIGHT ABOUT ITS OWN ARITHMETIC AND WRONG
   ABOUT WHAT TO DO WITH IT. It said three across a 350px strip leaves 111px to
   a column, the icon alone is 30 of them, the label gets about 50 and there is
   no choice — so it stood the pill UP, icon over label, and kept all three
   side by side under a deliberate sapaw. The measurements were correct. The
   result was three overlapping blobs, every label wrapped to two lines at
   11.3px, and the middle pill's edge running through both of its neighbours.

   Being side by side is the constraint that produced the 50px. Take it away
   and the pill goes back to the shape it has at every other width: disc on
   the left, label beside it, on one line. The grid still collapses at 980 and
   the pills still run the gold -> taupe -> espresso ramp in order.

   ⚠️ THE OVERLAP THIS BLOCK USED TO SWITCH OFF NO LONGER EXISTS AT ANY
   WIDTH. It zeroed --pfc-ov and restated the left padding, because the sapaw
   rule was 0,2,0 and beat this block's padding shorthand. Both of those lines
   went out with the overlap itself. The decision this block records — a full
   row each, at a size worth reading — is untouched. */
@media (max-width:640px){
  /* ⚠️ A ROW OF BOXES, AND IT REVERSES THE STACK THIS BLOCK USED TO ENFORCE.
     Asked for directly, against the hero's own stat cards as the reference:
     "gawing ganito lang, parang boxes style sya".

     ⚠️ THE 11.3px THAT JUSTIFIED THE STACK WAS MEASURED ON A PILL, and that
     is why it does not carry over. The pill is a ROW inside a column: disc on
     the left, label beside it. A third of a 350px shell is 111px, and the
     36px disc plus its gap plus the pill's asymmetric padding took about 66
     of them — so the label was trying to set two words in 45px and the only
     way to fit was to shrink the type.
     Stand the disc ON TOP and the same 111px box gives the label 99 of them.
     Nothing else changed. That is the whole reason .hstat carries three
     across in the hero with "RECOMMENDED" in it. Measured after: 12.9px at
     390 and 12px at 320, both on or over the floor. */
  .pf-claims{
    /* tighter than the desktop's: three boxes in a 350px shell */
    --pfc-gap:clamp(6px,2vw,10px);
    flex-direction:row;
    /* ⚠️ stretch, NOT center. The three labels wrap to one, two and two
       lines, so centred they would be three boxes of two different heights
       hung on a middle line. Stretch makes them one row of equal cards,
       which is the whole point of the shape. */
    align-items:stretch;
    gap:var(--pfc-gap);
    width:100%;
  }
  .pf-claim{
    /* the base arithmetic already closes: 3w + 2gap == 100% */
    width:calc((100% - var(--pfc-gap) * 2) / 3);
    max-width:none;
    flex-direction:column;
    justify-content:flex-start;
    align-items:center;
    text-align:center;
    gap:clamp(7px,2.2vw,10px);
    /* even side padding now, where the pill's was asymmetric to clear a disc
       that no longer sits beside anything */
    padding:clamp(11px,3.4vw,15px) clamp(5px,1.6vw,9px) clamp(10px,3vw,13px);
    /* ⚠️ A BOX, SO THE RADIUS HAS TO SAY SO. The base is border-radius:999px
       — a pill shape on a portrait card reads as a lozenge, not a card. */
    border-radius:var(--r-md);
  }
  .pf-ico{width:clamp(30px,8vw,36px);height:clamp(30px,8vw,36px);}
  /* ⚠️ 12px IS A FLOOR, NOT A CHOICE. The lower end is the size at which
     "Formulations" — 12 characters and unbreakable, the longest string here —
     still fits the narrowest column: 79px of usable width at 320 against
     about 70px of Playfair at 12px. Raise it without re-measuring at 320 and
     that word overflows its box rather than wrapping, which is the one
     failure a narrower column cannot fix by itself. */
  .pf-label{
    font-size:clamp(12px,3.4vw,15px);
    letter-spacing:0;
    line-height:1.24;
    white-space:normal;
  }
}

/* =========================================================
   6. REDUCED MOTION

   Everything that moves here is decoration, so under a
   reduced-motion preference it all simply stops — nothing is
   hidden, because every resting state above is the visible one
   except where the entrance sets opacity, and those are reset.
   ========================================================= */
@media (prefers-reduced-motion:reduce){
  .pf-pool,
  .pf-silk,
  .pf-beam,
  .pf-star,
  .pf-medal-halo,
  .pf-arc,
  .pf-dropper,
  .pf-cream{animation:none !important;}
  .pf-claim,
  .pf-stat,
  .pf-star-ico{opacity:1;translate:0 0;transition:none;}
  /* the glyphs stop where they are readable: tick drawn, flask upright, star
     at rest — animation:none alone would leave whatever the first keyframe
     said, so the resting values are stated */
  .pf-ico svg,
  .pf-ico svg path{animation:none;rotate:0deg;translate:0 0;scale:1;opacity:1;}
  .pf-claim:nth-child(1) .pf-ico svg path:nth-child(2){stroke-dasharray:none;stroke-dashoffset:0;}
  .pf-script{opacity:1;translate:0 0;transition:none;}
  .pf-rule{scale:1 1;opacity:1;transition:none;}
  .pf-vr{scale:1 1;transition:none;}
  /* the reel stops on the first word — translate:0 is "It Counts", which is
     also what the .sr-only <em> says, so the two agree */
  .pf-roll-track{animation:none;}
}
