/* ── PRODUCT VIEW ───────────────────────────────────────────────────────
   The window that opens when someone clicks a product card: every photo we
   have on top, colour choices and a live 3D preview underneath, and a hand-off
   to the quote form that carries the exact filament per part.

   Loaded only by products.html. Tokens come from site.css.
   ────────────────────────────────────────────────────────────────────── */

.pv-scrim{
  position:fixed;inset:0;z-index:80;display:flex;justify-content:center;
  background:rgba(20,17,13,.62);backdrop-filter:blur(3px);
  padding:clamp(.5rem,2vw,2rem);overflow-y:auto;overscroll-behavior:contain;
  animation:pvIn .18s ease-out;
}
@keyframes pvIn{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.pv-scrim{animation:none}}
body.pv-open{overflow:hidden}

.pv{
  position:relative;width:min(1080px,100%);align-self:flex-start;
  background:var(--cream);border:1px solid var(--line-2);border-radius:16px;
  box-shadow:0 40px 80px -40px rgba(30,15,5,.7);overflow:hidden;
}
.pv-x{
  position:absolute;top:.6rem;right:.6rem;z-index:3;width:2.2rem;height:2.2rem;
  border-radius:50%;border:1px solid var(--line-3);background:var(--paper);
  color:var(--ink);font-size:1rem;line-height:1;cursor:pointer;
}
.pv-x:hover{background:var(--crimson);border-color:var(--crimson);color:#fff}

.pv-head{padding:1.3rem clamp(1rem,3vw,1.8rem) .9rem;border-bottom:1px solid var(--line)}
.pv-head .tag{font-family:var(--mono);font-size:.6rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--crimson)}
.pv-head h2{font-size:clamp(1.25rem,2.6vw,1.7rem);font-weight:800;letter-spacing:-.015em;margin:.25rem 0 .3rem}
.pv-head p{color:var(--ink-soft);font-size:.9rem;max-width:70ch}

/* photos */
.pv-gal{padding:clamp(1rem,3vw,1.5rem);display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:.9rem}
/* Every one of the 1391 gallery photos is portrait at 1:1.221 — there is not a
   single landscape shot in the library. The stage was 4/3 landscape with
   object-fit:cover, so a 1100x1342 photo went into a 624x468 box scaled to the
   width and 39% of its height was thrown away: the top of the product and,
   usually, whatever it was standing on. That is what "too zoomed in" was.
   Cover is also why the thumbnail of a shot could show more of it than the
   stage did.

   Portrait box, and contain rather than cover. 4/5 is within 2% of the photos'
   own shape so the letterbox is a couple of pixels in practice, but contain
   means nothing is ever cropped — including any future photo that doesn't
   match. The stage column is narrower than it was (see .pv-gal) because a
   portrait box gets tall fast: capping the height instead would have re-opened
   the same wound sideways, mounting a 459px-wide photo in a 624px box. */
.pv-stage{position:relative;background:var(--cream-2);border:1px solid var(--line);
  border-radius:12px;overflow:hidden;aspect-ratio:4/5}
.pv-stage img{width:100%;height:100%;object-fit:contain;display:block}
.pv-count{position:absolute;left:.6rem;bottom:.6rem;background:rgba(28,26,23,.82);
  color:#fff;font-family:var(--mono);font-size:.65rem;padding:.2rem .55rem;border-radius:99px}
.pv-nav{position:absolute;top:50%;transform:translateY(-50%);width:2.1rem;height:2.1rem;
  border-radius:50%;border:0;background:rgba(28,26,23,.6);color:#fff;cursor:pointer;font-size:1rem}
.pv-nav:hover{background:rgba(28,26,23,.9)}
.pv-nav.prev{left:.5rem}.pv-nav.next{right:.5rem}
/* Match the stage rather than a fixed 26rem. The stage is portrait now, so a
   fixed cap left a bank of dead cream beside it AND made the thumbs scroll
   while there was room to show them all. 100% is the grid row, i.e. the stage. */
.pv-thumbs{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;align-content:start;
  max-height:100%;overflow:auto}
.pv-thumbs button{padding:0;line-height:0;border:2px solid transparent;background:var(--paper);
  border-radius:8px;overflow:hidden;cursor:pointer;aspect-ratio:1}
.pv-thumbs button.on{border-color:var(--crimson)}
/* Square buttons, contained photos: a thumbnail that crops differently from
   the stage sends you clicking after a detail that isn't there. */
.pv-thumbs img{width:100%;height:100%;object-fit:contain}
@media(max-width:760px){
  .pv-gal{grid-template-columns:1fr}
  .pv-thumbs{grid-template-columns:repeat(5,1fr);max-height:none}
}

/* colours */
.pv-colour{border-top:1px solid var(--line);background:var(--cream-2);
  padding:clamp(1rem,3vw,1.5rem)}
.pv-colour > h3{font-size:1.05rem;font-weight:800;letter-spacing:-.01em}
.pv-colour > p.hint{color:var(--ink-soft);font-size:.85rem;margin-top:.2rem}
.pv-work{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:1rem;margin-top:.9rem}
@media(max-width:860px){.pv-work{grid-template-columns:1fr}}

.pv-3d{position:relative;background:
  radial-gradient(120% 90% at 50% 8%,#fff 0%,#efe8da 62%,#ded4c0 100%);
  border:1px solid var(--line);border-radius:12px;aspect-ratio:4/3;
  overflow:hidden;touch-action:none}
.pv-3d canvas{display:block;width:100%;height:100%}
.pv-3d .msg{position:absolute;inset:0;display:grid;place-items:center;text-align:center;
  font-family:var(--mono);font-size:.72rem;color:var(--ink-soft);padding:1.4rem;line-height:1.7}
.pv-3dtools{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.5rem}

.pv-panel{background:var(--paper);border:1px solid var(--line);border-radius:12px;
  padding:.85rem;display:flex;flex-direction:column;min-width:0}
.pv-panel h4{font-family:var(--mono);font-size:.62rem;letter-spacing:.15em;
  text-transform:uppercase;color:var(--ink-soft);margin-bottom:.5rem}
.pv-slots{display:flex;flex-direction:column;gap:.15rem;max-height:13rem;overflow:auto}
.pv-slot{display:flex;align-items:center;gap:.55rem;width:100%;text-align:left;
  padding:.36rem .45rem;border:1px solid transparent;background:none;border-radius:8px;
  cursor:pointer;font:inherit;font-size:.85rem;color:var(--ink)}
.pv-slot:hover{background:var(--cream-2)}
.pv-slot.on{border-color:var(--crimson);background:var(--cream)}
.pv-slot .dot{width:1.35rem;height:1.35rem;border-radius:6px;flex:none;
  border:1px solid rgba(0,0,0,.22)}
.pv-slot .nm{font-weight:600;line-height:1.2}
.pv-slot .fil{display:block;font-family:var(--mono);font-size:.6rem;color:var(--ink-soft);font-weight:400}
.pv-slot .rm{margin-left:auto;border:0;background:none;cursor:pointer;color:var(--ink-soft);font-size:.8rem}
.pv-slot .rm:hover{color:var(--crimson)}

.pv-swwrap{margin-top:.7rem;border-top:1px solid var(--line);padding-top:.7rem}
.pv-brands{display:flex;gap:.35rem;margin-bottom:.5rem;flex-wrap:wrap}
.pv-sw{display:grid;grid-template-columns:repeat(auto-fill,minmax(1.9rem,1fr));gap:.32rem;
  max-height:11rem;overflow:auto}
.pv-sw button{aspect-ratio:1;border-radius:6px;border:1px solid rgba(0,0,0,.22);cursor:pointer;padding:0}
.pv-sw button.on{outline:2px solid var(--crimson);outline-offset:2px}
.pv-add{margin-top:.55rem}

.pvbtn{font-family:var(--mono);font-size:.66rem;padding:.32rem .62rem;border:1px solid var(--line-3);
  background:var(--paper);border-radius:99px;cursor:pointer;color:var(--ink)}
.pvbtn:hover{background:var(--cream-2)}
.pvbtn.on{background:var(--crimson);border-color:var(--crimson);color:#fff}

.pv-foot{border-top:1px solid var(--line);background:var(--paper);
  padding:clamp(.9rem,2.5vw,1.2rem) clamp(1rem,3vw,1.5rem);
  display:flex;gap:1rem;align-items:center;flex-wrap:wrap}
.pv-foot .sum{flex:1 1 18rem;min-width:0}
.pv-foot .sum b{display:block;font-size:.85rem}
.pv-foot .sum span{font-family:var(--mono);font-size:.66rem;color:var(--ink-soft);
  display:block;margin-top:.15rem;overflow-wrap:anywhere}
.pv-foot .go{display:inline-flex;align-items:center;gap:.5rem;background:var(--crimson);
  color:#fff;border:0;border-radius:99px;padding:.7rem 1.25rem;font-weight:700;
  font-size:.9rem;cursor:pointer;text-decoration:none}
.pv-foot .go:hover{background:var(--crimson-d)}
/* Confirms the add on the button itself. The toast can be missed on a tall
   screen; the control you just pressed changing under your finger cannot be. */
.pv-foot .go.added{background:var(--ok)}

/* Quantity + Add to cart travel together so the number you're about to buy is
   never more than one control away from the button that buys it. */
.pv-buy{display:flex;align-items:center;gap:.6rem;flex:0 0 auto}
.pv-qty{display:flex;align-items:center;gap:.25rem}
.pvq{width:34px;height:34px;border:1px solid var(--line-3);background:var(--paper);
  border-radius:8px;cursor:pointer;font-size:1.05rem;line-height:1;color:var(--ink)}
.pvq:hover{border-color:var(--crimson);color:var(--crimson)}
.pvqn{width:3rem;height:34px;text-align:center;font-family:var(--mono);font-size:.85rem;
  border:1px solid var(--line-3);border-radius:8px;background:var(--paper);color:var(--ink)}
.pvq:focus-visible,.pvqn:focus-visible{outline:2px solid var(--crimson);outline-offset:1px}
/* The quote route stays available on priced products — some people want to ask
   about a set before they buy it — but it stops competing with Add to cart. */
.pv-alt{flex:0 0 auto;background:none;border:0;cursor:pointer;color:var(--ink-soft);
  font:inherit;font-size:.78rem;text-decoration:underline;padding:.4rem .2rem}
.pv-alt:hover{color:var(--crimson)}
@media(max-width:560px){
  .pv-foot{gap:.7rem}
  .pv-buy{flex:1 1 100%}
  .pv-buy .go{flex:1 1 auto;justify-content:center}
  .pv-alt{flex:1 1 100%;text-align:center}
}

.card{cursor:pointer}
.card .card-img::after{
  content:'View & pick colors';position:absolute;left:.5rem;bottom:.5rem;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.06em;
  background:rgba(28,26,23,.82);color:#fff;padding:.22rem .5rem;border-radius:99px;
  opacity:0;transition:opacity .18s ease;
}
.card:hover .card-img::after,.card:focus-within .card-img::after{opacity:1}

/* Price disclaimer. Small, but it sits directly under the headline claim and
   uses the body colour rather than a muted grey — a price caveat nobody reads
   is worse than no caveat, because it reads as a promise. */
.price-note{
  margin-top:.9rem;max-width:72ch;font-size:.82rem;line-height:1.55;
  color:var(--ink);background:var(--paper);border-left:3px solid var(--crimson);
  border-radius:0 8px 8px 0;padding:.6rem .85rem;
}
.price-note b{color:var(--crimson)}
.pv-price{font-family:var(--mono);font-size:1.15rem;font-weight:700;color:var(--ink)}
.pv-price small{display:block;font-family:var(--sans);font-size:.68rem;font-weight:400;
  color:var(--ink-soft);margin-top:.15rem;max-width:34ch;line-height:1.4}

.pv-nomodel{position:absolute;left:.6rem;bottom:.6rem;background:rgba(28,26,23,.82);
  color:#fff;font-family:var(--mono);font-size:.62rem;padding:.24rem .6rem;border-radius:99px}
