/* ═══════════════════════════════════════════════════════════════════
   Overlays — quick view and the shared lightbox

   UI_UX §7 for the modals, §8 plus CLAUDE.md §9.4 (zoom) for the
   lightbox. Both fill the viewport below 640px.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Quick view ──────────────────────────────────────────────────────
   A modal, not a drawer: it is opened from a grid and closed straight
   back to it, so the back-affordance has to be unambiguous (UI_UX §7.4).
   Fills the viewport at ≤640px per §7.2. */
.qv-btn{
  position:absolute;top:var(--sp-3);right:var(--sp-3);z-index:1;
  width:var(--tap);height:var(--tap);border-radius:var(--r-full);
  background:var(--surface);border:1px solid var(--line);color:var(--ink-2);
  display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}
.qv-btn:hover{border-color:var(--brand);color:var(--brand-ink)}
.qv-btn .ico{width:22px;height:22px}

.qv{position:fixed;top:0;right:0;bottom:0;left:0;inset:0;z-index:var(--z-drawer);display:none;
  align-items:stretch;justify-content:center;background:var(--scrim);padding:0}
.qv.open{display:flex}
.qv-card{background:var(--surface);width:100%;max-width:100%;max-height:100vh;
  border-radius:0;display:flex;flex-direction:column;overflow:hidden;min-width:0}
.qv-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--line);
  padding-top:calc(var(--sp-3) + env(safe-area-inset-top,0px))}
.qv-head b{font-size:.8125rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.qv-body{flex:1 1 auto;overflow-y:auto;padding:var(--sp-4);
  display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-4);min-width:0}
.qv-body h2{font-size:1.25rem;font-weight:800}
.qv-media{aspect-ratio:1/1;background:var(--surface-2);border-radius:var(--r);
  overflow:hidden;display:flex;align-items:center;justify-content:center}
.qv-media img{width:100%;height:100%;object-fit:contain}
.qv-info{display:flex;flex-direction:column;gap:var(--sp-3);min-width:0}
.qv-short{font-size:1rem;line-height:1.6;color:var(--ink-2)}
.qv-specs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-2)}
.qv-spec{background:var(--surface-2);border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-3);min-width:0}
.qv-spec .k{display:block;font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.qv-spec .v{font-size:1rem;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;
  overflow-wrap:anywhere}
/* Sticky action row — §7.3: never scroll to find Add to cart. */
.qv-foot{position:sticky;bottom:0;background:var(--surface);border-top:1px solid var(--line);
  padding:var(--sp-3) var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-2);
  padding-bottom:calc(var(--sp-3) + env(safe-area-inset-bottom,0px))}


/* ── Lightbox (UI_UX §8 + CLAUDE.md §9.4 zoom) ──────────────────── */
.lb{position:fixed;top:0;right:0;bottom:0;left:0;inset:0;z-index:var(--z-lightbox);background:var(--scrim-full);
  display:none;align-items:center;justify-content:center;touch-action:none}
.lb.open{display:flex}
.lb-stage{position:absolute;top:0;right:0;bottom:0;left:0;inset:0;overflow:hidden;
  display:flex;align-items:center;justify-content:center}
.lb-img{max-width:92vw;max-height:82vh;object-fit:contain;cursor:zoom-in;
  transform-origin:center center;transition:transform .18s ease;will-change:transform;
  -webkit-user-select:none;user-select:none;-webkit-user-drag:none}
.lb.zoomed .lb-img{cursor:grab;transition:none}
.lb.zoomed.dragging .lb-img{cursor:grabbing}
.lb-btn{position:absolute;z-index:2;width:56px;height:56px;border-radius:var(--r-full);
  background:var(--lb-chrome);color:var(--lb-ink);
  display:flex;align-items:center;justify-content:center;backdrop-filter:blur(4px)}
.lb-btn:hover{background:var(--lb-chrome-hover)}
.lb-btn .ico{width:30px;height:30px}
.lb-close{top:calc(var(--sp-3) + env(safe-area-inset-top,0px));right:var(--sp-3)}
.lb-zoom{top:calc(var(--sp-3) + env(safe-area-inset-top,0px));left:var(--sp-3)}
.lb-prev{left:var(--sp-2);top:50%;transform:translateY(-50%)}
.lb-next{right:var(--sp-2);top:50%;transform:translateY(-50%)}
/* Position, without ink on the photograph (CLAUDE.md §9.11). The dots
   sit in the letterbox margin, are non-textual, and each one is a real
   control so a customer can jump between two images they are comparing. */
.lb-dots{position:absolute;z-index:2;left:50%;transform:translateX(-50%);
  bottom:calc(var(--sp-4) + env(safe-area-inset-bottom,0px));
  display:flex;align-items:center;gap:var(--sp-1);padding:var(--sp-1) var(--sp-2);
  border-radius:var(--r-full);background:var(--lb-chrome)}
.lb-dot{width:var(--tap);height:28px;display:flex;align-items:center;justify-content:center;
  background:none;border:0;cursor:pointer}
/* The dot is 10px; the 44px button around it is the target (§9.x). */
.lb-dot::before{content:'';width:10px;height:10px;border-radius:var(--r-full);
  background:var(--lb-dot);transition:background .15s ease,transform .15s ease}
.lb-dot[aria-selected="true"]::before{background:var(--brand);transform:scale(1.3)}
.lb-dot:focus-visible{outline:2px solid var(--brand);outline-offset:-4px;border-radius:var(--r-sm)}

.lb[data-single="true"] .lb-prev,
.lb[data-single="true"] .lb-next,
.lb[data-single="true"] .lb-dots{display:none}


@media (min-width:640px){
  /* Above 640 the modal stops filling the viewport (UI_UX §7.2). */
  .qv{align-items:center;padding:var(--sp-5)}
  .qv-card{max-width:840px;max-height:88vh;border-radius:var(--r-lg)}
  .qv-body{grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    /* Do not stretch the columns to match each other: a product with a
       short description should get a short modal, not a tall one with
       the difference left blank. */
    align-items:start}
  /* The 1:1 box still reserves space before decode (CLAUDE.md §6); the
     cap just stops a square image dictating the height of the dialog. */
  .qv-media{max-height:min(50vh,380px)}
  .qv-foot{flex-direction:row}
  .qv-foot .btn{flex:1 1 0}
}
