/* ============================================================================
   STACK & SAVE — bundle builder
   ============================================================================ */

/* ------------------------------------------------------------------- hero */
.stk-hero{ position:relative; overflow:hidden; padding:54px 0 40px; border-bottom:1px solid var(--border); }
.stk-hero__glow{
  position:absolute; left:50%; top:-120px; width:min(900px,110%); aspect-ratio:2.2;
  transform:translateX(-50%); pointer-events:none; filter:blur(50px);
  background:radial-gradient(ellipse at center, rgba(255,27,60,.26), rgba(255,120,40,.1) 45%, transparent 72%);
}
.stk-hero__inner{ position:relative; z-index:1; text-align:center; }
.stk-hero h1{
  font-family:'Oswald',sans-serif; text-transform:uppercase; color:#fff;
  font-size:clamp(30px,5.4vw,58px); line-height:1.02; margin:12px 0 14px;
}
.stk-hero p{ color:var(--text-muted); font-size:clamp(14px,1.7vw,16.5px); max-width:60ch; margin:0 auto; line-height:1.65; }

.stk-tiers{ display:flex; gap:10px; justify-content:center; flex-wrap:wrap; margin-top:28px; }
.stk-tier{
  display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:12px 20px; border-radius:var(--radius-md); min-width:92px;
  background:var(--surface); border:1px solid var(--border-strong);
  transition:border-color .25s var(--ease), transform .25s var(--ease);
}
.stk-tier b{ font-family:'Oswald',sans-serif; font-size:24px; color:var(--volt); line-height:1; }
.stk-tier small{ font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-faint); font-weight:700; }
.stk-tier.is-on{ border-color:var(--volt); transform:translateY(-3px); box-shadow:0 12px 30px rgba(255,27,60,.22); }

/* ------------------------------------------------------------------ steps */
.stk-step{
  display:flex; align-items:center; gap:11px; margin:34px 0 16px;
  font-size:13px; font-weight:800; letter-spacing:.11em; text-transform:uppercase; color:var(--text);
}
.stk-step span{
  display:grid; place-items:center; width:26px; height:26px; border-radius:50%;
  background:var(--volt); color:#fff; font-size:12px;
}

.stk-goal-row{ display:flex; gap:10px; flex-wrap:wrap; }
.stk-goal{
  padding:11px 20px; border-radius:var(--radius-pill); cursor:pointer;
  font-size:13px; font-weight:700; color:var(--text-muted);
  background:var(--surface); border:1px solid var(--border-strong);
  transition:.2s var(--ease);
}
.stk-goal:hover{ color:var(--text); border-color:rgba(255,27,60,.45); }
.stk-goal.is-on{ background:var(--volt); border-color:var(--volt); color:#fff; }

/* ------------------------------------------------------------------ layout */
/* Room for the sticky bar. Driven by the same measured value as the bar
   itself, so it can never be too small. */
.stk-main{ padding-bottom:calc(var(--stk-peek, 92px) + 70px); }
.stk-layout{ display:grid; grid-template-columns:190px 1fr; gap:28px; align-items:start; }

.stk-nav{
  position:sticky; top:calc(var(--header-h) + 16px);
  display:flex; flex-direction:column; gap:4px;
  padding:12px; border-radius:var(--radius-lg);
  background:var(--surface); border:1px solid var(--border-strong);
}
.stk-cat{
  text-align:left; padding:10px 13px; border-radius:var(--radius-md); cursor:pointer;
  font-size:13px; font-weight:600; color:var(--text-muted);
  background:none; border:0; transition:.18s var(--ease);
}
.stk-cat:hover{ background:rgba(255,255,255,.05); color:var(--text); }
.stk-cat.is-on{ background:rgba(255,27,60,.14); color:#fff; font-weight:800; }

.stk-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:16px; }
.stk-empty{ grid-column:1/-1; text-align:center; color:var(--text-muted); padding:50px 0; }

/* Filtering hides with a class, never the `hidden` attribute — `hidden` only
   sets display:none in the UA stylesheet and loses to the display:flex above. */
.stk-card.is-hidden,
.stk-empty.is-hidden{ display:none !important; }

/* ------------------------------------------------------------------- card */
.stk-card{
  display:flex; flex-direction:column; overflow:hidden;
  border-radius:var(--radius-lg); background:var(--surface);
  border:1px solid var(--border-strong);
  transition:border-color .25s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease);
}
.stk-card:hover{ transform:translateY(-4px); border-color:rgba(255,27,60,.4); box-shadow:0 18px 40px rgba(0,0,0,.45); }
.stk-card__media{ position:relative; display:block; aspect-ratio:1; overflow:hidden; background:#141418; }
.stk-card__media img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .5s var(--ease); }
.stk-card:hover .stk-card__media img{ transform:scale(1.06); }
.stk-card__body{ padding:13px 14px 14px; display:flex; flex-direction:column; gap:7px; flex:1; }
.stk-card__cat{ font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--red); font-weight:800; }
.stk-card__body h3{
  margin:0; font-size:13.5px; line-height:1.35; text-transform:uppercase; color:var(--text);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* ---- Split flavour cards ----
   When a variable product is shown as one card per flavour, the product name
   repeats down the grid and the flavour is the only thing that distinguishes
   one card from the next. So the flavour gets the loud treatment — a badge on
   the image, where the eye lands first — and the repeated product name is
   allowed to recede. Without this the grid reads as duplicates. */
.stk-card__flavour{
  position:absolute; left:8px; bottom:8px; z-index:2; max-width:calc(100% - 16px);
  padding:5px 11px; border-radius:var(--radius-pill);
  font-size:11px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  color:#fff; background:rgba(10,10,13,.82);
  border:1px solid rgba(255,27,60,.55);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.stk-card--variant .stk-card__body h3{ color:var(--text-muted); font-weight:600; }
.stk-card--variant:hover .stk-card__flavour{ border-color:var(--volt); background:rgba(255,27,60,.9); }

.stk-card__price{ display:flex; align-items:baseline; gap:8px; margin-top:auto; }
.stk-card__price b{ font-size:16px; color:#fff; }
.stk-card__price s{ font-size:12px; color:var(--text-faint); }

.stk-add{
  position:relative; margin-top:8px; width:100%; padding:11px 12px;
  border-radius:var(--radius-pill); border:1.5px solid var(--border-strong);
  background:rgba(255,255,255,.04); color:var(--text);
  font-size:12.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase; cursor:pointer;
  display:flex; align-items:center; justify-content:center; gap:8px;
  transition:.22s var(--ease);
}
.stk-add:hover{ border-color:var(--volt); color:#fff; background:rgba(255,27,60,.12); }
.stk-add.is-added{ background:var(--volt); border-color:var(--volt); color:#fff; }
.stk-add.is-busy{ opacity:.6; cursor:wait; }
.stk-add__count{
  display:grid; place-items:center; min-width:20px; height:20px; padding:0 6px;
  border-radius:10px; background:rgba(0,0,0,.35); font-size:11px;
}

/* ---- Flavour picker modal ----
   Centred dialog rather than a popover inside the card: a card-level panel is
   clipped by the grid, overlaps its neighbours, and on a phone is only ~190px
   wide — too narrow to read a flavour name and a price on one line. */
.stk-modal{
  position:fixed; inset:0; z-index:9500;
  display:grid; place-items:center; padding:20px;
  opacity:0; transition:opacity .22s var(--ease);
  /* Second line of defence. `hidden` is now enforced globally in style.css,
     but there is still a 220ms window on close where the element is faded
     out and not yet `hidden` — without this it would swallow clicks for a
     fifth of a second after every close. An invisible overlay must never be
     clickable, whatever the reason it is invisible. */
  pointer-events:none;
}
.stk-modal.is-open{ opacity:1; pointer-events:auto; }
.stk-modal__backdrop{
  position:absolute; inset:0; background:rgba(5,5,7,.82);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
}
.stk-modal__card{
  position:relative; z-index:2; width:min(440px,100%); max-height:82vh;
  display:flex; flex-direction:column; overflow:hidden;
  padding:24px; border-radius:var(--radius-lg);
  background:linear-gradient(155deg, rgba(30,28,34,.98), rgba(12,12,15,.98));
  border:1px solid rgba(255,27,60,.42);
  box-shadow:0 44px 96px rgba(0,0,0,.8), 0 0 68px rgba(255,27,60,.22);
  transform:scale(.94) translateY(12px);
  transition:transform .28s var(--ease);
}
.stk-modal.is-open .stk-modal__card{ transform:none; }
.stk-modal__x{
  position:absolute; top:12px; right:14px; z-index:3;
  width:34px; height:34px; border-radius:50%; cursor:pointer;
  font-size:22px; line-height:1; color:var(--text-muted);
  background:rgba(255,255,255,.06); border:1px solid var(--border-strong);
  display:grid; place-items:center; transition:.2s var(--ease);
}
.stk-modal__x:hover{ background:var(--volt); border-color:var(--volt); color:#fff; }

.stk-modal__head{ display:flex; align-items:center; gap:14px; margin-bottom:18px; padding-right:36px; }
.stk-modal__img{
  width:64px; height:64px; border-radius:12px; object-fit:cover; flex-shrink:0;
  border:1px solid var(--border-strong); background:#141418;
}
.stk-modal__kicker{
  display:block; font-size:10px; font-weight:800; letter-spacing:.13em;
  text-transform:uppercase; color:var(--volt); margin-bottom:4px;
}
.stk-modal__head h3{ margin:0; font-size:16px; text-transform:uppercase; color:#fff; line-height:1.25; }

.stk-modal__opts{ display:flex; flex-direction:column; gap:8px; overflow-y:auto; }
.stk-opt{
  display:flex; align-items:center; gap:12px; width:100%; cursor:pointer;
  padding:11px 13px; border-radius:var(--radius-md); text-align:left;
  background:rgba(255,255,255,.04); border:1.5px solid var(--border-strong); color:var(--text);
  transition:.18s var(--ease);
}
.stk-opt:hover, .stk-opt:focus-visible{
  background:rgba(255,27,60,.14); border-color:var(--volt); outline:none; transform:translateX(3px);
}
.stk-opt img{ width:40px; height:40px; border-radius:9px; object-fit:cover; flex-shrink:0; }
.stk-opt__dot{
  width:40px; height:40px; border-radius:9px; flex-shrink:0;
  background:linear-gradient(135deg,var(--volt),var(--volt-dark));
}
/* The row must survive a long attribute value ("190g 38 Scoops · Lemon Lime")
   without the price crushing the name. min-width:0 lets the name shrink below
   its longest word instead of forcing the row wider; overflow-wrap breaks a
   single very long token rather than overflowing; and the price is capped so
   it can never claim more than its half of the row. */
.stk-opt__name{
  flex:1 1 auto; min-width:0; font-size:14px; font-weight:700;
  line-height:1.35; overflow-wrap:anywhere;
}
.stk-opt em{
  flex:0 1 auto; max-width:48%; text-align:right;
  font-style:normal; font-size:13.5px; font-weight:800; color:var(--volt);
  display:flex; flex-direction:column; align-items:flex-end; gap:1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.stk-opt em s{ font-size:11.5px; font-weight:600; color:var(--text-faint); }

@media (max-width:620px){
  .stk-modal{ padding:0; place-items:end center; }
  /* Bottom sheet on a phone — reachable with a thumb, which a centred dialog
     on a tall screen is not. */
  .stk-modal__card{
    width:100%; max-height:78vh; border-radius:20px 20px 0 0;
    transform:translateY(100%); padding:20px 18px calc(20px + env(safe-area-inset-bottom));
  }
  .stk-modal.is-open .stk-modal__card{ transform:none; }
  .stk-modal__img{ width:54px; height:54px; }
}
@media (prefers-reduced-motion:reduce){
  .stk-modal, .stk-modal__card, .stk-opt{ transition:none; }
}

/* The flying clone. Fixed-position and pointer-transparent so it can never
   interfere with the page it is animating over. */
.stk-fly{
  position:fixed; z-index:9998; border-radius:12px; object-fit:cover; pointer-events:none;
  transition:transform .62s cubic-bezier(.4,.1,.2,1), opacity .62s ease;
  box-shadow:0 18px 40px rgba(0,0,0,.5);
}

/* ------------------------------------------------------- sticky summary */
.stk-bar{
  position:fixed; left:0; right:0; bottom:0; z-index:900;
  background:linear-gradient(180deg, rgba(16,15,18,.97), rgba(9,9,11,.99));
  border-top:1px solid rgba(255,27,60,.35);
  box-shadow:0 -18px 50px rgba(0,0,0,.6);
  backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px);
  /* How much of the bar peeks when closed is MEASURED, not guessed.
     It used to be a hardcoded 84px (92px with items), with three more
     hardcoded values in the media queries below. Those numbers were only ever
     right for one font size and one message length — the moment the reward
     line said "10% off applied · 1 more for 15% off" instead of something
     short, or the totals column grew a "You saved" line, the extra height fell
     below the fold and the text was cut in half. js/stack-builder.js measures
     the grip + head and writes --stk-peek, and re-measures whenever the
     content or the window changes. */
  transform:translateY(calc(100% - var(--stk-peek, 92px)));
  transition:transform .42s var(--ease);
}
.stk-bar.is-open{ transform:translateY(0); }

.stk-bar__grip{
  display:block; width:100%; padding:9px 0 3px; background:none; border:0; cursor:pointer;
}
.stk-bar__grip-line{
  display:block; width:44px; height:4px; border-radius:4px; margin:0 auto;
  background:rgba(255,255,255,.28);
}

.stk-bar__head{
  display:grid; grid-template-columns:1fr auto auto; gap:22px; align-items:center;
  max-width:1240px; margin:0 auto; padding:8px 22px 16px;
}
.stk-bar__track{ height:6px; border-radius:6px; background:rgba(255,255,255,.1); overflow:hidden; }
.stk-bar__track span{
  display:block; height:100%; border-radius:6px;
  background:linear-gradient(90deg,var(--volt),#ff8a3d);
  transition:width .5s var(--ease);
}
.stk-bar__reward p{ margin:8px 0 0; font-size:12.5px; color:var(--text-muted); line-height:1.5; }
.stk-bar__reward p b{ color:#fff; }

.stk-bar__totals{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; white-space:nowrap; }
.stk-bar__count{ font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-faint); font-weight:700; }
.stk-bar__count b{ color:#fff; font-size:14px; }
.stk-bar__price{ display:flex; align-items:baseline; gap:8px; }
.stk-bar__price s{ font-size:12.5px; color:var(--text-faint); }
.stk-bar__price b{ font-family:'Oswald',sans-serif; font-size:23px; color:#fff; }
.stk-bar__saved{ font-size:11.5px; font-weight:800; color:#4ade80; }

.stk-bar__body{ max-width:1240px; margin:0 auto; padding:0 22px 20px; }
.stk-bar__items{ display:flex; flex-direction:column; gap:8px; max-height:220px; overflow-y:auto; }
.stk-none{ margin:6px 0; color:var(--text-faint); font-size:13px; }

.stk-item{
  display:flex; align-items:center; gap:12px; padding:9px 12px;
  border-radius:var(--radius-md); background:rgba(255,255,255,.035); border:1px solid var(--border);
  transition:opacity .25s var(--ease), transform .25s var(--ease);
}
.stk-item.is-going{ opacity:0; transform:translateX(-14px); }
.stk-item img{ width:40px; height:40px; border-radius:8px; object-fit:cover; flex-shrink:0; }
.stk-item--gift img{ object-fit:contain; background:rgba(0,0,0,.3); }
.stk-item__name{ flex:1; min-width:0; font-size:13px; color:var(--text); display:flex; flex-direction:column; }
.stk-item__name small{ font-size:10.5px; color:#4ade80; font-weight:700; }
.stk-item__qty{ display:flex; align-items:center; gap:4px; }
.stk-item__qty button{
  width:26px; height:26px; border-radius:7px; cursor:pointer; font-size:15px; line-height:1;
  background:rgba(255,255,255,.07); border:1px solid var(--border-strong); color:var(--text);
}
.stk-item__qty button:hover{ background:var(--volt); border-color:var(--volt); color:#fff; }
.stk-item__qty b{ min-width:22px; text-align:center; font-size:13px; }
.stk-item__x{ background:none; border:0; color:var(--text-faint); font-size:19px; cursor:pointer; padding:0 3px; }
.stk-item__x:hover{ color:var(--red); }
.stk-item__free{ font-size:11px; font-weight:800; color:#4ade80; letter-spacing:.08em; text-transform:uppercase; }
.stk-item--gift{ border-color:rgba(74,222,128,.32); background:rgba(74,222,128,.06); }

.stk-gifts{ display:flex; gap:10px; flex-wrap:wrap; margin-top:14px; }
.stk-gift{
  display:flex; align-items:center; gap:10px; padding:9px 14px 9px 10px;
  border-radius:var(--radius-pill); background:rgba(255,255,255,.035);
  border:1px dashed var(--border-strong); opacity:.55; transition:.3s var(--ease);
}
.stk-gift.is-on{ opacity:1; border-style:solid; border-color:rgba(74,222,128,.55); background:rgba(74,222,128,.08); }
.stk-gift__img{ width:30px; height:30px; border-radius:50%; display:grid; place-items:center; overflow:hidden; background:rgba(255,255,255,.06); color:var(--text-faint); }
.stk-gift__img img{ width:100%; height:100%; object-fit:contain; }
.stk-gift__img svg{ width:16px; height:16px; }
.stk-gift__txt{ display:flex; flex-direction:column; }
.stk-gift__txt b{ font-size:12.5px; color:var(--text); }
.stk-gift__txt small{ font-size:10px; color:var(--text-faint); }
.stk-gift__tick{ color:#4ade80; font-weight:900; opacity:0; transition:opacity .3s; }
.stk-gift.is-on .stk-gift__tick{ opacity:1; }

.stk-insights{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-top:14px; }
.stk-insight{
  padding:11px 14px; border-radius:var(--radius-md);
  background:rgba(255,255,255,.035); border:1px solid var(--border);
  display:flex; flex-direction:column; gap:3px;
}
.stk-insight span{ font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--text-faint); font-weight:700; }
.stk-insight b{ font-size:14px; color:#fff; }

.stk-bar__foot{ display:flex; align-items:center; gap:16px; margin-top:14px; }
.stk-share, .stk-viewcart{
  background:none; border:0; padding:0; cursor:pointer;
  font-size:12px; font-weight:700; color:var(--text-muted); text-decoration:underline;
}
.stk-share:hover, .stk-viewcart:hover{ color:var(--red); }

/* --------------------------------------------------------- celebration */
.stk-celebrate{
  position:fixed; inset:0; z-index:9990; display:grid; place-items:center;
  pointer-events:none; opacity:0; transition:opacity .35s var(--ease);
}
.stk-celebrate.is-on{ opacity:1; }
.stk-confetti{ position:absolute; inset:0; }
.stk-celebrate__card{
  position:relative; text-align:center; padding:28px 38px; border-radius:var(--radius-lg);
  background:linear-gradient(150deg, rgba(34,31,37,.97), rgba(11,11,14,.96));
  border:1px solid rgba(255,27,60,.5);
  box-shadow:0 40px 90px rgba(0,0,0,.75), 0 0 70px rgba(255,27,60,.3);
  transform:scale(.9); transition:transform .4s var(--ease);
}
.stk-celebrate.is-on .stk-celebrate__card{ transform:scale(1); }
.stk-celebrate__ic{ font-size:34px; display:block; margin-bottom:8px; }
.stk-celebrate__card h3{ margin:0 0 6px; font-size:19px; text-transform:uppercase; color:#fff; }
.stk-celebrate__card p{ margin:0; font-size:13.5px; color:#4ade80; font-weight:700; }

/* --------------------------------------------------------------- toast */
.stk-toast{
  position:fixed; left:50%; bottom:calc(130px + var(--footer-mobile-h, 0px)); transform:translate(-50%,14px); z-index:9995;
  padding:12px 20px; border-radius:var(--radius-pill);
  background:rgba(14,14,18,.96); border:1px solid var(--border-strong); color:#fff;
  font-size:13px; opacity:0; transition:.3s var(--ease); pointer-events:none;
  max-width:88vw; text-align:center;
}
.stk-toast.is-on{ opacity:1; transform:translate(-50%,0); }

/* ---------------------------------------------------------- responsive */
@media (max-width:1000px){
  .stk-layout{ grid-template-columns:1fr; gap:16px; }
  /* On a phone the category rail becomes a scrolling row of tabs pinned under
     the header — a vertical list here would push the products themselves
     below the fold, which is the one thing this page cannot afford. */
  .stk-nav{
    position:sticky; top:var(--header-h); z-index:5;
    flex-direction:row; gap:8px; overflow-x:auto; padding:10px;
    border-radius:var(--radius-md); scrollbar-width:none;
  }
  .stk-nav::-webkit-scrollbar{ display:none; }
  .stk-cat{ white-space:nowrap; padding:9px 15px; border-radius:var(--radius-pill); }
  .stk-bar__head{ grid-template-columns:1fr auto; gap:14px; padding:6px 16px 14px; }
  .stk-bar__go{ grid-column:1/-1; width:100%; }
}
@media (max-width:620px){
  /* The site has its own fixed bottom tab bar on mobile. The summary sat at
     bottom:0 and buried it, so Home / Categories / Cart / Search / Account
     were unreachable from this page — and so was the Checkout button whenever
     the drawer was closed. It now sits ON TOP of that bar, and the page keeps
     enough bottom padding that the last row of products is never trapped
     underneath either. */
  .stk-bar{
    bottom:var(--footer-mobile-h);
    border-radius:16px 16px 0 0;
  }
  .stk-bar.is-open{ transform:translateY(0); max-height:calc(100vh - var(--header-h) - var(--footer-mobile-h)); overflow-y:auto; }

  .stk-main{ padding-bottom:calc(var(--stk-peek, 104px) + 80px + var(--footer-mobile-h)); }
  .stk-grid{ grid-template-columns:repeat(2,1fr); gap:11px; }
  .stk-card__body{ padding:11px; gap:5px; }
  .stk-card__body h3{ font-size:12px; }
  .stk-card__price b{ font-size:14px; }
  .stk-add{ padding:9px 8px; font-size:11px; }
  .stk-hero{ padding:34px 0 28px; }
  .stk-tier{ min-width:76px; padding:9px 13px; }
  .stk-tier b{ font-size:19px; }
  .stk-bar__body{ padding:0 16px 18px; }
  .stk-bar__items{ max-height:34vh; }
  .stk-bar__head{ padding:4px 14px 12px; gap:10px; }
  .stk-bar__totals{ align-items:flex-end; }
  .stk-bar__price b{ font-size:19px; }
  .stk-bar__reward p{ margin-top:6px; font-size:11.5px; }
  .stk-insights{ grid-template-columns:1fr; }
}
@media (prefers-reduced-motion:reduce){
  .stk-card, .stk-bar, .stk-bar__track span, .stk-celebrate, .stk-celebrate__card{ transition:none; }
  .stk-fly{ display:none; }
}
