/* ============================================================
   FUNNLR PRODUCT DETAIL PAGE
   Loaded by product.html on top of shell.css. Replaces the old
   shop.css + shop-hybrid.css pairing, which was a different design
   language to the rest of the shop.

   SYSTEM NOTES (keep these true when editing)

   Accent lock:  lime (--lime) is the only brand accent on this page.
                 The gold family is used ONLY by the limited-run
                 components (chip, stock panel, progress bar). It is a
                 status colour, the way red means error, not a second
                 brand colour. Never use gold for a button, a link or a
                 heading.

   Shape lock:   buttons are pill (40px, from shell.css .btn)
                 panels and the gallery are var(--r-lg)
                 small tiles, thumbs and inputs are 12px
                 Nothing else. No fourth radius.

   Layout shift: every image box declares aspect-ratio, and #pdp-mount
                 ships a skeleton of the same geometry as the real
                 content. The old page scored CLS 0.835 because the
                 mount was empty until shop.js ran. Do not remove the
                 skeleton or the min-heights without re-measuring.

   Motion:       MOTION_INTENSITY 4. Transitions, one scroll reveal,
                 hover lift. No parallax, no scroll hijack. Everything
                 collapses under prefers-reduced-motion at the bottom
                 of this file.
   ============================================================ */

/* ---------- dark band behind the sticky header ---------- */
/* margin-top:-72px pulls this band UP underneath the sticky header, which is
   transparent until you scroll. Without it the white nav text sits on the white
   page and disappears. .sh-head and .hero pull the same trick; if you change
   the header height, change all three. */
.pd-bar{
  background:linear-gradient(180deg,var(--black) 0%,var(--ink) 100%);
  color:var(--onink);
  margin-top:-72px;
  padding-top:calc(72px + clamp(14px,2vw,22px));
  padding-bottom:clamp(30px,4vw,44px);
}
.pd-crumb{display:flex;align-items:center;gap:9px;font-size:.85rem;color:var(--onink-mute)}
.pd-crumb a:hover{color:var(--lime)}
.pd-crumb .sep{opacity:.4}
.pd-crumb .here{color:var(--onink)}

/* The light page lifts over the dark band on a rounded corner, the same
   move the footer makes in reverse. It is what stitches the two halves
   together instead of leaving a hard colour line. */
.pd-body{
  background:var(--white);
  border-radius:var(--r-xl) var(--r-xl) 0 0;
  margin-top:calc(var(--r-xl) * -1);
  position:relative;z-index:1;
  padding-top:clamp(26px,4vw,44px);
  /* The footer pulls itself up by one radius to sit under this panel's rounded
     corner. Without clearance for that the last accordion row disappears
     beneath it, which is exactly what happened to the final FAQ. */
  padding-bottom:calc(var(--r-xl) + clamp(20px,3vw,40px));
}

/* ---------- hero: gallery + buy column ---------- */
.pd-hero{display:grid;gap:clamp(16px,2.5vw,36px);align-items:start}
@media(min-width:980px){
  /* Asymmetric on purpose: the gallery earns the extra width, the buy
     column only needs enough to keep the price and CTA comfortable. */
  .pd-hero{grid-template-columns:minmax(0,1.15fr) minmax(400px,.85fr);gap:clamp(22px,3vw,44px)}
}

/* The gallery stays put while the accordions scroll past it, so the thing you
   are buying never leaves the screen. Desktop only: on a phone it would eat
   the viewport. */
@media(min-width:980px){.pd-gal{position:sticky;top:92px}}
@media(max-width:979px){
  .pd-gal{max-width:340px;margin-inline:auto;width:100%}
}

.pd-stage{
  aspect-ratio:1/1;border-radius:var(--r-lg);overflow:hidden;
  background:var(--gray);position:relative;max-width:100%;
}
@media(max-width:979px){
  .pd-stage{max-height:280px;border-radius:16px}
}

/* Horizontal swipe track with scroll-snap */
.pd-track{
  display:flex;flex-direction:row;width:100%;height:100%;
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
}
.pd-track::-webkit-scrollbar{display:none}

.pd-slide{
  flex:0 0 100%;width:100%;height:100%;
  scroll-snap-align:center;scroll-snap-stop:always;
  position:relative;display:flex;align-items:center;justify-content:center;
  background:#060608;overflow:hidden;
}
.pd-slide img{width:100%;height:100%;object-fit:cover;display:block}
.pd-slide video{
  width:100%;height:100%;object-fit:contain;background:#000;display:block;
  cursor:pointer;
}

/* Video wrapper & minimal floating controls */
.pd-video-wrap{
  position:relative;width:100%;height:100%;
  display:flex;align-items:center;justify-content:center;
  background:#000;
}
.pd-vid-sound-pill{
  position:absolute;top:10px;left:10px;
  display:flex;align-items:center;gap:6px;
  background:rgba(6,6,8,0.85);backdrop-filter:blur(8px);
  color:#fff;font-size:11.5px;font-weight:700;letter-spacing:0.02em;
  padding:6px 12px;border-radius:999px;
  border:1px solid rgba(255,255,255,0.25);
  cursor:pointer;z-index:5;
  transition:transform .15s ease, background .2s ease;
  box-shadow:0 4px 12px rgba(0,0,0,0.3);
}
.pd-vid-sound-pill:hover{background:rgba(6,6,8,0.98);transform:scale(1.05)}
.pd-vid-sound-pill.unmuted{background:#C8F04A;color:#060608;border-color:transparent;font-weight:800}

.pd-vid-ctrls{
  position:absolute;bottom:10px;right:10px;
  display:flex;align-items:center;gap:8px;z-index:4;
}
.pd-vid-btn{
  width:34px;height:34px;border-radius:50%;
  background:rgba(6,6,8,0.75);backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,0.25);color:#fff;
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;transition:transform .15s ease, background .2s ease;
  padding:0;
}
.pd-vid-btn:hover{background:rgba(6,6,8,0.95);transform:scale(1.08)}
.pd-vid-btn svg{width:16px;height:16px;stroke:currentColor}

.pd-vid-playbadge{
  position:absolute;inset:0;margin:auto;width:48px;height:48px;
  border-radius:50%;background:rgba(6,6,8,0.65);backdrop-filter:blur(6px);
  color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:18px;pointer-events:none;transition:opacity .2s ease;
  z-index:3;
}
.pd-video-wrap.playing .pd-vid-playbadge{opacity:0;pointer-events:none}

.pd-thumbs{
  display:flex;flex-wrap:nowrap;gap:10px;margin-top:10px;
  overflow-x:auto;overflow-y:hidden;padding-bottom:6px;
  -webkit-overflow-scrolling:touch;scrollbar-width:thin;
}
.pd-thumbs::-webkit-scrollbar{height:4px}
.pd-thumbs::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}

.pd-thumb{
  flex:0 0 72px;width:72px;height:72px;aspect-ratio:1/1;
  border-radius:12px;overflow:hidden;padding:0;
  background:var(--gray);border:1.5px solid var(--line);
  position:relative;cursor:pointer;
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease)
}
@media(max-width:767px){
  .pd-thumbs{gap:8px;margin-top:8px}
  .pd-thumb{flex:0 0 54px;width:54px;height:54px;border-radius:10px}
}

.pd-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.pd-thumb:hover{border-color:var(--ink)}
.pd-thumb.on{border-color:var(--ink);box-shadow:0 0 0 2px var(--ink)}
.pd-thumb.video-thumb::after{
  content:"▶";position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,0.45);color:#fff;font-size:13px;
  border-radius:inherit;transition:background .2s ease
}
.pd-thumb.video-thumb:hover::after{background:rgba(0,0,0,0.3)}

/* ---------- buy column ---------- */
.pd-buy{display:grid;gap:16px}
.pd-flags{display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-height:30px}
.pd-title{font-size:clamp(1.8rem,1.3rem + 2.1vw,2.9rem);letter-spacing:-.03em;line-height:1.05}

.pd-price{display:flex;align-items:baseline;gap:11px;flex-wrap:wrap}
.pd-now{font-family:Syne,sans-serif;font-weight:800;font-size:clamp(2rem,1.5rem + 1.7vw,2.7rem);letter-spacing:-.035em;line-height:1}
.pd-was{text-decoration:line-through;color:var(--muted);font-size:1.05rem}
.pd-once{font-size:.9rem;color:var(--muted)}
.pd-save{
  background:rgba(200,240,74,.22);border:1px solid rgba(169,210,47,.5);
  color:#3f5c0a;border-radius:999px;padding:5px 12px;
  font-size:.76rem;font-weight:800;letter-spacing:.02em;white-space:nowrap
}
.pd-short{color:var(--muted);font-size:1rem;line-height:1.55;max-width:52ch}

/* ---------- quantity chooser ---------- */
.pd-choose-label{
  font-size:.76rem;font-weight:800;text-transform:uppercase;
  letter-spacing:.1em;color:var(--muted)
}
.bundle-row{display:grid;gap:10px}
.bundle-opt{
  display:flex;align-items:center;gap:13px;width:100%;text-align:left;
  background:var(--white);border:1px solid var(--line);border-radius:14px;
  padding:13px 15px;position:relative;
  transition:border-color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease)
}
.bundle-opt:hover{border-color:#b9c8a0}
.bundle-opt.on{
  border-color:var(--lime-d);background:rgba(200,240,74,.09);
  box-shadow:0 0 0 1px var(--lime-d) inset
}
.bundle-opt .bo-thumb{
  flex:0 0 auto;width:52px;height:52px;border-radius:12px;overflow:hidden;
  background:#fff;border:1px solid var(--line);display:grid;place-items:center
}
.bundle-opt .bo-thumb img{width:100%;height:100%;object-fit:contain}
.bundle-opt .bo-info{flex:1;min-width:0}
.bundle-opt .bo-qty{display:block;font-family:Syne,sans-serif;font-weight:800;font-size:.95rem;letter-spacing:-.015em}
.bundle-opt .bo-sub{display:block;font-size:.78rem;color:var(--muted);margin-top:3px}
.bundle-opt.on .bo-sub{color:#4d6b12;font-weight:600}
.bundle-opt .bo-price{
  display:flex;align-items:baseline;gap:6px;white-space:nowrap;
  font-family:Syne,sans-serif;font-weight:800;font-size:1.08rem
}
.bundle-opt .bo-price s{font-family:"DM Sans",sans-serif;font-weight:500;font-size:.8rem;color:var(--muted)}
.bundle-opt .bo-tag{
  position:absolute;top:-9px;right:13px;background:var(--lime);color:var(--black);
  font-family:Syne,sans-serif;font-size:.62rem;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;padding:3px 10px;border-radius:999px
}

/* Plain quantity stepper, for products with no multi-buy pricing. */
.pd-qty{display:flex;align-items:center;justify-content:space-between;gap:14px;
  border:1px solid var(--line);border-radius:14px;padding:11px 15px}
.pd-qty-box{display:flex;align-items:center;gap:4px}
.pd-qty-box button{
  width:34px;height:34px;border-radius:10px;border:1px solid var(--line);
  font-size:1.1rem;line-height:1;display:grid;place-items:center;
  transition:background .18s var(--ease)
}
.pd-qty-box button:hover{background:var(--gray)}
.pd-qty-box output{min-width:34px;text-align:center;font-weight:800;font-family:Syne,sans-serif}

/* ---------- CTAs ---------- */
.pd-ctas{display:grid;gap:10px}
.pd-soldout{
  width:100%;border-radius:40px;padding:15px 22px;cursor:not-allowed;
  font-family:"DM Sans",sans-serif;font-weight:700;font-size:1rem;
  color:#fff;background:#7a7f88;border:1px solid #7a7f88
}
.pd-alt{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  font-size:.9rem;font-weight:700;color:#a8801f;padding:4px
}
.pd-alt:hover{text-decoration:underline}

/* ---------- pay-later line ---------- */
/* Deliberately carries NO instalment figure. See the note in shop.js: the
   terms are Stitch's to set, not ours to advertise. */
.pd-later{font-size:.86rem;color:var(--muted);line-height:1.5}
.pd-later a{font-weight:700;color:var(--text);border-bottom:1px solid var(--line)}
.pd-later a:hover{border-color:var(--text)}

/* ---------- trust chips ---------- */
.pd-chips{display:flex;flex-wrap:wrap;gap:8px}
.pd-chip{
  display:inline-flex;align-items:center;gap:7px;background:var(--gray);
  border-radius:10px;padding:7px 11px;font-size:.8rem;line-height:1.2;color:var(--muted)
}
.pd-chip b{color:var(--text);font-weight:700}

/* ---------- section rhythm ---------- */
.pd-sec{padding-block:clamp(34px,4.4vw,62px)}
.pd-sec + .pd-sec{border-top:1px solid var(--line)}
.pd-h2{font-size:clamp(1.5rem,1.2rem + 1.5vw,2.25rem);letter-spacing:-.025em;max-width:20ch}
.pd-lede{color:var(--muted);font-size:1.02rem;line-height:1.6;max-width:60ch;margin-top:12px}

/* ---------- why it works: bullet grid, not cards ---------- */
.pd-points{display:grid;gap:16px}
/* Single column: these now live in the buy column, not full width. */
.pd-point{display:flex;gap:12px;align-items:flex-start}
.pd-point .tick{
  flex:0 0 22px;height:22px;border-radius:50%;background:var(--lime);
  display:grid;place-items:center;margin-top:2px
}
.pd-point .tick svg{width:12px;height:12px}
.pd-point p{font-size:.96rem;line-height:1.55}
.pd-point strong{font-weight:700}

/* ---------- order to first review: timeline ---------- */
.pd-flow{display:grid;gap:clamp(24px,3vw,56px)}
.pd-q .pd-steps{margin-top:-6px}
@media(min-width:900px){.pd-flow{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);align-items:start}
  .pd-flow-head{position:sticky;top:96px}}
.pd-steps{display:grid;gap:0}
.pd-step{display:grid;grid-template-columns:auto 1fr;gap:16px;padding-block:18px}
.pd-step + .pd-step{border-top:1px solid var(--line)}
.pd-step .n{
  width:32px;height:32px;border-radius:50%;background:var(--ink);color:var(--onink);
  display:grid;place-items:center;font-family:Syne,sans-serif;font-weight:800;font-size:.86rem
}
.pd-step h3{font-size:1.05rem;letter-spacing:-.01em}
.pd-step p{color:var(--muted);font-size:.94rem;line-height:1.55;margin-top:5px}

/* ---------- in the box + delivery ---------- */
.pd-band{background:var(--gray);border-radius:var(--r-lg);padding:clamp(24px,3.4vw,44px)}
.pd-band-grid{display:grid;gap:clamp(22px,3vw,44px)}
@media(min-width:820px){.pd-band-grid{grid-template-columns:1fr 1fr}}
.pd-list{display:grid;gap:11px;margin-top:18px;list-style:none}
.pd-list li{display:flex;gap:10px;font-size:.95rem;line-height:1.5}
.pd-list li::before{content:"";flex:0 0 6px;height:6px;border-radius:50%;background:var(--lime-d);margin-top:8px}
.pd-fact{display:flex;justify-content:space-between;gap:16px;padding-block:11px;font-size:.94rem}
.pd-fact + .pd-fact{border-top:1px solid var(--line)}
.pd-fact span:last-child{color:var(--muted);text-align:right}

/* ---------- add-on offer ---------- */
.pd-addon{
  border:1px solid var(--line);border-radius:var(--r-lg);
  padding:clamp(20px,2.6vw,32px);display:grid;gap:18px;align-items:center
}
@media(min-width:780px){.pd-addon{grid-template-columns:1fr auto}}
.pd-addon h3{font-size:1.2rem;letter-spacing:-.02em}
.pd-addon p{color:var(--muted);font-size:.95rem;line-height:1.55;margin-top:8px;max-width:56ch}
.pd-addon .price{font-family:Syne,sans-serif;font-weight:800;font-size:1.3rem;white-space:nowrap}

/* ---------- also like ---------- */
.pd-also{display:grid;gap:18px;margin-top:clamp(20px,3vw,34px)}
@media(min-width:640px){.pd-also{grid-template-columns:repeat(3,1fr)}}
.pd-card{border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--white);
  transition:box-shadow .22s var(--ease),transform .22s var(--ease)}
.pd-card:hover{box-shadow:0 14px 34px rgba(20,20,22,.09);transform:translateY(-3px)}
.pd-card .shot{aspect-ratio:1/1;background:var(--gray);display:block}
.pd-card .shot img{width:100%;height:100%;object-fit:cover}
.pd-card .body{padding:16px}
.pd-card .name{font-family:Syne,sans-serif;font-weight:800;font-size:1rem;display:block}
.pd-card .cost{margin-top:6px;font-weight:700}
.pd-card .cost s{font-weight:500;color:var(--muted);font-size:.85rem;margin-right:6px}

/* ---------- accordions ---------- */
/* One component for every block below the hero. Collapsing the detail is what
   keeps this page from feeling like a wall: the buy decision sits at the top,
   and anything you only need if you are still deciding is one tap away. */
.pd-faq{max-width:820px;margin-top:clamp(16px,2vw,24px)}
.pd-q{border-top:1px solid var(--line)}
.pd-q:last-child{border-bottom:1px solid var(--line)}
.pd-q button{
  width:100%;display:flex;justify-content:space-between;align-items:center;gap:20px;
  padding:17px 0;text-align:left;font-family:Syne,sans-serif;font-weight:700;font-size:1.02rem
}
.pd-q button:hover{color:var(--muted)}
.pd-q .mark{flex:0 0 auto;font-size:1.3rem;line-height:1;transition:transform .25s var(--ease)}
.pd-q.open .mark{transform:rotate(45deg)}
.pd-q .ans{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .28s var(--ease)
}
.pd-q.open .ans{grid-template-rows:1fr}
.pd-q .ans > div{overflow:hidden}
.pd-q .ans p{color:var(--muted);font-size:.96rem;line-height:1.6;padding-bottom:18px;max-width:70ch}
/* Content other than a paragraph inside an accordion body. */
.pd-q .ans .inner{padding-bottom:20px}
.pd-q .ans .inner > * + *{margin-top:14px}

/* ---------- closing CTA ---------- */
.pd-final{
  background:var(--ink);color:var(--onink);border-radius:var(--r-lg);
  padding:clamp(30px,4.5vw,60px);text-align:center
}
.pd-final h2{font-size:clamp(1.5rem,1.2rem + 1.6vw,2.3rem);letter-spacing:-.025em;max-width:22ch;margin-inline:auto}
.pd-final p{color:var(--onink-mute);margin-top:12px;max-width:50ch;margin-inline:auto;line-height:1.55}
.pd-final .row{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:24px}

/* ---------- sticky mobile buy bar ---------- */
/* Appears only once the real Add to cart button has scrolled away, so the
   primary action is never more than a thumb away on a phone. Desktop keeps
   the button in view beside the gallery, so the bar would be noise there. */
.pd-stickybuy{
  position:fixed;left:0;right:0;bottom:0;z-index:50;
  display:flex;align-items:center;gap:14px;
  padding:11px 16px calc(11px + env(safe-area-inset-bottom));
  background:rgba(253,253,253,.96);backdrop-filter:blur(10px);
  border-top:1px solid var(--line);
  transform:translateY(105%);transition:transform .28s var(--ease);
  pointer-events:none
}
.pd-stickybuy.on{transform:translateY(0);pointer-events:auto}
.pd-stickybuy .lbl{flex:1;min-width:0}
.pd-stickybuy .lbl b{display:block;font-family:Syne,sans-serif;font-size:.95rem;font-weight:800}
.pd-stickybuy .lbl span{display:block;font-size:.74rem;color:var(--muted)}
.pd-stickybuy .btn{flex:0 0 auto;padding:12px 22px}
@media(min-width:980px){.pd-stickybuy{display:none}}

/* ---------- skeleton (holds the exact shape shop.js will fill) ---------- */
.pd-skel{display:grid;gap:clamp(16px,2.5vw,36px);align-items:start}
@media(min-width:980px){.pd-skel{grid-template-columns:minmax(0,1.15fr) minmax(400px,.85fr);gap:clamp(22px,3vw,44px)}}
@media(max-width:979px){
  .pd-skel .stage{max-height:280px;max-width:340px;margin-inline:auto}
  .pd-skel .row{max-width:340px;margin-inline:auto}
}
.pd-skel .blk{background:var(--gray);border-radius:var(--r-lg)}
.pd-skel .stage{aspect-ratio:1/1}
.pd-skel .row{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:10px}
.pd-skel .row i{aspect-ratio:1/1;border-radius:12px;background:var(--gray);display:block}
.pd-skel .line{height:14px;border-radius:7px;background:var(--gray)}
.pd-skel .side{display:grid;gap:14px}
.pd-skel .side .line.tall{height:38px}
.pd-skel .side .line.w70{width:70%}
.pd-skel .side .line.w45{width:45%}
.pd-skel .side .opt{height:78px;border-radius:14px;background:var(--gray)}
.pd-skel .side .cta{height:50px;border-radius:40px;background:var(--gray)}
@media(prefers-reduced-motion:no-preference){
  .pd-skel .blk,.pd-skel .line,.pd-skel .opt,.pd-skel .cta,.pd-skel .row i{
    animation:pd-pulse 1.4s ease-in-out infinite
  }
}
@keyframes pd-pulse{0%,100%{opacity:1}50%{opacity:.55}}

/* ---------- scroll reveal ---------- */
/* Sections fade up once, on entry, to give the page a sense of assembly as you
   scroll. Driven by IntersectionObserver, never a scroll listener.

   The hidden state is gated behind .js-reveal on <html>, which the page only
   adds once it has confirmed IntersectionObserver exists and motion is allowed.
   Without that gate the content is opacity:0 in the stylesheet and stays that
   way for anyone whose JS is slow, blocked or broken. Content must never
   depend on an animation running to be readable. */
@media(prefers-reduced-motion:no-preference){
  .js-reveal .pd-reveal{opacity:0;transform:translateY(18px);
    transition:opacity .6s var(--ease),transform .6s var(--ease)}
  .js-reveal .pd-reveal.seen{opacity:1;transform:none}
}

/* ---------- reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  .pd-card:hover{transform:none}
  .pd-stickybuy{transition:none}
  .pd-q .ans{transition:none}
  .js-reveal .pd-reveal{opacity:1;transform:none}
}
