/* ==========================================================================
   MELT — direction layer
   Theme: ice cream photographed like it is about to be lost.
   Villain: heat. The product's defining property is that it does not last,
            and the brand is named after losing. So the site races the clock.
   Through-line: one drip. It leaves the bar in the hero and runs the whole
            page, thickening at each chapter, pooling into the footer.
   Restraint: two radii (--r and the pill). Coral appears three times.
   ========================================================================== */

:root{
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --e2:cubic-bezier(.16,1,.3,1);
  --choc:#3C2118;
}

/* ── the hero must be the first thing, not the fourth ─────────────────── */
/* the ticker was stacked above the fold; it now works as a velocity band
   between chapters instead of pushing the hero down the page. */
.ticker{border-block:1px solid rgba(60,33,24,.12)}

/* ── margins are real estate ──────────────────────────────────────────── */
.edge{
  position:fixed; top:0; bottom:0; width:clamp(18px,2.4vw,34px); z-index:60;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:24px;
  pointer-events:none; font-family:var(--mono); font-size:9.5px; letter-spacing:.2em;
  color:rgba(60,33,24,.42);
}
.edge span{writing-mode:vertical-rl; white-space:nowrap}
.edge--l{left:0}
.edge--r{right:0}
.edge--r span{transform:rotate(180deg)}
.baseline{
  position:fixed; left:clamp(18px,2.4vw,34px); right:clamp(18px,2.4vw,34px); bottom:12px; z-index:60;
  display:flex; align-items:center; gap:14px; pointer-events:none;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.18em; color:rgba(60,33,24,.5);
}
.baseline__rule{flex:1; height:1px; background:currentColor; opacity:.24; position:relative}
.baseline__rule i{position:absolute; inset:0 auto 0 0; background:var(--coral); width:var(--prog,0%)}
.freeze-dot{width:5px;height:5px;border-radius:999px;background:#7FB7D4;display:inline-block;margin-right:7px}
:root[data-chapter="signoff"] .edge,:root[data-chapter="signoff"] .baseline{color:rgba(250,237,221,.5)}
@media (max-width:1100px){.edge{display:none} .baseline{left:14px;right:14px}}

/* ── the through-line: one drip, page-level, never inside a section ────── */
.tl-layer{display:none;
  position:absolute; top:0; left:0; width:100%; z-index:2; pointer-events:none; overflow:visible;
  clip-path:inset(0 0 calc((1 - var(--tlp,0)) * 100%) 0);
}
.tl-drip{fill:none; stroke:var(--choc); stroke-width:2.2; opacity:.30;
  vector-effect:non-scaling-stroke; stroke-linecap:round}
.tl-bead{fill:var(--choc); opacity:.42}
:root[data-chapter="melt"] .tl-drip{stroke:#8A4B2A; opacity:.5}

/* ── chapters ─────────────────────────────────────────────────────────── */
/* one deliberate temperature beat: the page warms where the thing melts,
   then cools again. Not a drift — a beat. */
:root{--paper:#FAEDDD}
body{background:var(--paper); transition:background 1.1s var(--e2)}
.sec,.freezer,.inside,.reviews,.faq{background:transparent}

/* ══ CHAPTER — FREEZER ══ travel: the pints run past a fixed frame ═════ */
.freezer .pint-rail{
  display:flex; gap:clamp(14px,1.8vw,26px); width:max-content; min-width:max-content;
  transform:translate3d(var(--x,0),0,0); will-change:transform;
}
.pint-rail>*{flex:none; width:clamp(230px,24vw,330px)}
.pint-rail-wrap{display:flex; overflow:visible; margin-top:clamp(24px,3.4vw,44px)}

/* ── reduced motion: a design, not a kill switch ──────────────────────── */
@media (prefers-reduced-motion:reduce){
    .freezer .pint-rail{transform:none; width:auto; flex-wrap:wrap}
  body{transition:none}
}

/* ══ MOTION ════════════════════════════════════════════════════════════
   One system, capped. Entrances only, eased, revealed once, staggered.
   Scroll itself stays 1:1 — nothing lags behind the wheel.
   ────────────────────────────────────────────────────────────────────── */
:root{--ease-out:cubic-bezier(.2,.8,.2,1)}

.rv,.rvl{opacity:0; will-change:opacity,transform}
.rv{transform:translateY(20px) scale(.994)}
.rvl{transform:translateX(-22px)}
.rv.in,.rvl.in{opacity:1; transform:none;
  transition:opacity .78s var(--ease-out), transform .78s var(--ease-out)}
.rv.d1.in{transition-delay:.07s} .rv.d2.in{transition-delay:.14s} .rv.d3.in{transition-delay:.21s}

/* groups stagger their own children rather than all arriving together */
.models.in .cell,.svc.in .cell,.cards.in .card,.freezer .grid.in>*{
  animation:riseIn .72s var(--ease-out) both}
.models.in .cell:nth-child(n){animation-delay:calc(var(--i,0) * 70ms)}
@keyframes riseIn{from{opacity:0; transform:translateY(16px) scale(.995)} to{opacity:1; transform:none}}

/* the primary action pulls toward the cursor — the only hover flourish */
.sc__add{transition:transform .28s var(--ease-out), background .28s var(--ease-out)}
.sc__add:hover{transform:translateY(-2px)}

@media (prefers-reduced-motion:reduce){
  .rv,.rvl{opacity:1; transform:none}
  .models.in .cell,.svc.in .cell,.cards.in .card,.freezer .grid.in>*{animation:none}
  .sc__add:hover{transform:none}
}



/* ══ MERCHANDISING THE FREEZER ═════════════════════════════════════════
   The grid keeps its own order. A card carries a mark only when there is a
   fact to state about it: it is new, it is reduced, or it is already in your
   bag. All of that reads from real state — cart contents, real prices — and
   nothing here invents scarcity, urgency, or a ranking.
   ────────────────────────────────────────────────────────────────────── */
.freezer .wrap{position:relative}

/* ── the corner labels ────────────────────────────────────────────────
   One sticker, three readings. A solid cocoa pill punched a black hole in the
   photograph and a solid coral one shouted over it; the bone chip sits on top
   of the image instead of in it, and stays legible over the dark chocolate bar
   and the pale vanilla alike. The colour lives in the type, not the ground —
   so SAVE is still the only red thing in the grid, at a weight the photograph
   can carry. The hairline picks up each label's own hue. */
.flag--new{color:var(--choc)}
.flag--sale{color:#B8433F;
  box-shadow:inset 0 0 0 1px rgba(184,67,63,.3), 0 6px 16px -10px rgba(184,67,63,.6)}
.flag--mine{color:#2C6446;
  box-shadow:inset 0 0 0 1px rgba(44,100,70,.3), 0 6px 16px -10px rgba(44,100,70,.6)}
.is-merched .flag{opacity:1; transform:none;
  transition-delay:calc(.72s + var(--fi,0) * .07s)}
.card .new{display:none}

/* the reduced ones mark themselves down in front of you */
.was{position:relative; margin-right:9px; color:var(--ink-faint); font-size:.82em}
.was::after{content:""; position:absolute; left:-1px; right:-1px; top:52%; height:1.5px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .5s cubic-bezier(.22,.9,.24,1)}
.is-merched .was::after{transform:scaleX(1); transition-delay:1.05s}
.card.is-cut{box-shadow:0 0 0 1.5px rgba(218,101,100,.45), var(--shadow)}

/* ── the header speaks to the person reading it ───────────────────────── */
.freezer__meta{
  display:flex; align-items:center; justify-content:center; gap:12px; flex-wrap:wrap;
  margin:0 0 clamp(18px,2.4vw,30px); padding:0 var(--pad);
  font-family:var(--mono); font-size:10px; letter-spacing:.16em;
  color:var(--ink-faint); text-align:center;
}
.freezer__meta b{color:var(--choc); font-weight:400}
.freezer__meta .sep{opacity:.4}
.freezer__hi{color:var(--coral)}

/* ── immersion: the card under the pointer warms ──────────────────────── */
@media (hover:hover) and (pointer:fine){
  .freezer .grid .card{position:relative}
  .freezer .grid .card::before{
    content:""; position:absolute; inset:0; z-index:2; pointer-events:none; opacity:0;
    border-radius:inherit;
    background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%),
               rgba(255,255,255,.42), transparent 62%);
    transition:opacity .35s ease;
  }
  .freezer .grid .card:hover::before{opacity:1}
}

@media (prefers-reduced-motion:reduce){
  .flag{opacity:1; transform:none; transition:none}
  .was::after{transform:scaleX(1)}
  .freezer .grid .card::before{display:none}
}


/* ── base rules restored (an earlier edit removed these) ──────────────── */
.flag{
  position:absolute; top:12px; right:12px; z-index:4;
  display:inline-flex; align-items:center; height:26px; padding:0 12px;
  border-radius:999px; white-space:nowrap;
  background:rgba(253,247,238,.93);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  box-shadow:inset 0 0 0 1px rgba(59,37,22,.15), 0 6px 16px -10px rgba(59,37,22,.55);
  font-family:var(--mono); font-size:9px; letter-spacing:.18em; line-height:1;
  opacity:0; transform:translateY(-8px);
  transition:opacity .45s cubic-bezier(.22,.9,.24,1), transform .45s cubic-bezier(.22,.9,.24,1);
}
.was{position:relative; margin-right:9px; color:var(--ink-faint); font-size:.82em}
.was::after{content:""; position:absolute; left:-1px; right:-1px; top:52%; height:1.5px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .5s cubic-bezier(.22,.9,.24,1)}
.is-merched .was::after{transform:scaleX(1); transition-delay:1.05s}
.card.is-cut{box-shadow:0 0 0 1.5px rgba(218,101,100,.45), var(--shadow)}

/* ── the gate ──────────────────────────────────────────────────────────
   direct.js drives this on a timer (arm → open at 260ms → done at 1400ms)
   but no rule ever answered those classes, so the SVG was rendering
   unstyled in normal flow: a ~1563px brown blob sitting at the top of the
   document forever, with the real hero pushed below it.

   Fixed, not in flow, so it costs the layout nothing and the hero is
   painted underneath the whole time. It lifts away upward on a curved
   edge — the scoop the business is named after, used once, as the way in. */
.gate{
  position:fixed; inset:0; z-index:200;
  display:grid; place-items:center;
  background:var(--cream);
  pointer-events:none;
  transform:translateY(0);
  transition:transform .95s cubic-bezier(.72,0,.18,1),
             border-radius .95s cubic-bezier(.72,0,.18,1);
  /* safety net: if the JS never runs, the gate must not trap the page */
  animation:gate-failsafe 0s linear 2.6s forwards;
}
@keyframes gate-failsafe{to{opacity:0;visibility:hidden}}
.gate__mark{display:flex;flex-direction:column;align-items:center;gap:15px}
.gate__mark svg{width:clamp(58px,7.5vw,92px);height:auto;display:block}
.gate__mark b{font-family:Disp,Georgia,serif;font-weight:600;
  font-size:clamp(15px,1.8vw,21px);letter-spacing:.36em;text-indent:.36em;
  color:var(--ink)}
html.gate-open .gate{
  transform:translateY(-101%);
  border-radius:0 0 54% 54% / 0 0 24% 24%;
}
html.gate-done .gate{display:none}
/* reduced motion: direct.js jumps straight to gate-done, but belt and braces */
@media(prefers-reduced-motion:reduce){.gate{display:none;animation:none}}
