/* ============================================================================
   CULTURE CAVE — "THE DESCENT" v2.0
   Interaction layer. Loaded after cave.css.

   v1 built the cave. v2 makes it move: a lantern you carry, chambers that
   reveal as you reach them, rock that catches the light where you touch it,
   and a way to get anywhere in the cave without scrolling for it.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. MOTION + SPACE + ELEVATION SYSTEM
   One easing vocabulary for the whole site. Everything that moves uses these,
   so nothing feels like it came from a different build.
   ------------------------------------------------------------------------- */
:root{
  /* easing */
  --e-out:cubic-bezier(.16,1,.3,1);        /* the smooth one: settles, never bounces */
  --e-in-out:cubic-bezier(.65,0,.35,1);
  --e-spring:cubic-bezier(.34,1.4,.64,1);  /* a touch of overshoot, for entrances */
  --e-snap:cubic-bezier(.4,0,.2,1);

  /* duration */
  --t-1:120ms; --t-2:200ms; --t-3:320ms; --t-4:520ms; --t-5:820ms;

  /* space — a single rhythm */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:22px;
  --s-6:30px; --s-7:42px; --s-8:58px; --s-9:78px; --s-10:104px;

  /* elevation — consistent across themes */
  --el-1:0 1px 2px rgba(12,6,26,.06),0 2px 6px rgba(12,6,26,.04);
  --el-2:0 2px 4px rgba(12,6,26,.06),0 10px 26px rgba(12,6,26,.08);
  --el-3:0 4px 10px rgba(12,6,26,.08),0 22px 54px rgba(12,6,26,.12);
  --el-4:0 8px 20px rgba(12,6,26,.12),0 40px 90px rgba(12,6,26,.2);

  /* pointer position, written by cave-ui.js */
  --mx:50vw; --my:40vh; --min:0;
}
:root[data-theme="dark"]{
  --el-1:0 1px 2px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.4);
  --el-2:0 2px 6px rgba(0,0,0,.55),0 12px 30px rgba(0,0,0,.5);
  --el-3:0 6px 14px rgba(0,0,0,.6),0 26px 60px rgba(0,0,0,.55);
  --el-4:0 10px 24px rgba(0,0,0,.65),0 48px 100px rgba(0,0,0,.6);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --el-1:0 1px 2px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.4);
    --el-2:0 2px 6px rgba(0,0,0,.55),0 12px 30px rgba(0,0,0,.5);
    --el-3:0 6px 14px rgba(0,0,0,.6),0 26px 60px rgba(0,0,0,.55);
    --el-4:0 10px 24px rgba(0,0,0,.65),0 48px 100px rgba(0,0,0,.6);
  }
}

/* ---------------------------------------------------------------------------
   2. TYPE — the display face gets optical tracking, the body gets a measure,
   and microlabels get the size and weight the house rules ask for.
   ------------------------------------------------------------------------- */
.hero h1{letter-spacing:-.006em;line-height:.98}
.phead h1,.band h2,.blk .shead h2{letter-spacing:-.002em}
.blk .shead h2{font-size:clamp(1.72rem,3.3vw,2.45rem);line-height:1.08}
.blk .shead p{font-size:15px;line-height:1.6;max-width:56ch;margin-left:auto;margin-right:auto}
.hero .sub{font-size:clamp(15.5px,1.4vw,17.5px);line-height:1.6;max-width:54ch}

.eyebrow,.fcol h4,.fg h5,.subhd,.crumb,.field label,.mspot .msven{
  font-size:11.6px;letter-spacing:.2em;font-weight:600}
.fcol h4,.fg h5{color:color-mix(in srgb,var(--ink-mut) 55%, var(--ink) 45%)}
.pcard .pc{font-size:11.6px;letter-spacing:.04em}
.vc .vcship{font-size:9.6px;letter-spacing:.16em;color:rgba(255,255,255,.82)}

/* numbers align in columns wherever they are compared */
.hstats .s b,.pcard .price,.summary .line,.summary .tot,.drop .cd b{font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------------------------
   3. THE LANTERN — you carry a light through the cave.
   Two layers: a warm pool that follows the pointer, and a faint cool rim just
   outside it so the pool has an edge instead of dissolving.
   ------------------------------------------------------------------------- */
.lamp{position:fixed;inset:0;z-index:898;pointer-events:none;opacity:0;
  transition:opacity var(--t-4) var(--e-out);
  mix-blend-mode:plus-lighter;
  background:
    radial-gradient(circle 190px at var(--mx) var(--my),
      rgba(255,232,196,.10), rgba(255,214,160,.045) 42%, transparent 72%),
    radial-gradient(circle 420px at var(--mx) var(--my),
      rgba(var(--glow-v),.05), transparent 70%);
}
.lamp.on{opacity:1}
:root[data-theme="dark"] .lamp{
  background:
    radial-gradient(circle 210px at var(--mx) var(--my),
      rgba(255,226,178,.16), rgba(255,196,120,.07) 44%, transparent 72%),
    radial-gradient(circle 520px at var(--mx) var(--my),
      rgba(var(--glow-v),.13), rgba(var(--glow-m),.05) 52%, transparent 74%);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .lamp{
    background:
      radial-gradient(circle 210px at var(--mx) var(--my),
        rgba(255,226,178,.16), rgba(255,196,120,.07) 44%, transparent 72%),
      radial-gradient(circle 520px at var(--mx) var(--my),
        rgba(var(--glow-v),.13), rgba(var(--glow-m),.05) 52%, transparent 74%);
  }
}
/* the vignette eases off around the lantern, so the light genuinely opens the dark */
body.fine .cave-vig{
  -webkit-mask-image:radial-gradient(circle 340px at var(--mx) var(--my),rgba(0,0,0,.35),#000 78%);
  mask-image:radial-gradient(circle 340px at var(--mx) var(--my),rgba(0,0,0,.35),#000 78%)}
body:not(.fine) .lamp{display:none}

/* ---------------------------------------------------------------------------
   4. REVEAL — a chamber lights up as you reach it.
   Nothing slides in from the side; everything rises and resolves, which is what
   reads as sophisticated rather than animated.
   ------------------------------------------------------------------------- */
[data-rv]{opacity:0;transform:translate3d(0,22px,0);filter:blur(7px);
  transition:opacity var(--t-5) var(--e-out),transform var(--t-5) var(--e-out),filter var(--t-4) var(--e-out);
  transition-delay:calc(var(--i,0) * 62ms);will-change:opacity,transform}
[data-rv].in{opacity:1;transform:none;filter:none}
[data-rv="scale"]{transform:translate3d(0,26px,0) scale(.975)}
[data-rv="scale"].in{transform:none}
[data-rv="rise"]{transform:translate3d(0,34px,0)}

/* ---------------------------------------------------------------------------
   5. ROCK CATCHES THE LIGHT — pointer-tracked specular on cards.
   A card is a slab of wet stone: it should brighten where your lantern falls,
   and lean very slightly toward it.
   ------------------------------------------------------------------------- */
.tilt{transform-style:preserve-3d;
  transition:transform var(--t-3) var(--e-out),box-shadow var(--t-3) var(--e-out)}
.tilt.live{transition:transform var(--t-1) linear,box-shadow var(--t-3) var(--e-out)}
.spec{position:relative;isolation:isolate}
.spec::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
  border-radius:inherit;opacity:0;
  transition:opacity var(--t-3) var(--e-out);
  background:radial-gradient(circle 240px at var(--cx,50%) var(--cy,50%),
    rgba(255,255,255,.20), rgba(255,255,255,.06) 38%, transparent 66%)}
.spec:hover::after,.spec:focus-within::after{opacity:1}
:root[data-theme="dark"] .spec::after{
  background:radial-gradient(circle 260px at var(--cx,50%) var(--cy,50%),
    rgba(var(--glow-v),.26), rgba(var(--glow-m),.09) 40%, transparent 68%)}
@media (prefers-reduced-motion:reduce){
  [data-rv]{opacity:1!important;transform:none!important;filter:none!important;transition:none}
  .tilt{transform:none!important;transition:none}
  .spec::after{display:none}
}

/* card hover, unified */
.vc,.pcard,.cell,.tier,.mspot,.vchip{
  transition:transform var(--t-3) var(--e-out),box-shadow var(--t-3) var(--e-out),
             border-color var(--t-2) var(--e-out)}
.pcard:hover,.cell:hover{box-shadow:var(--el-3);border-color:var(--violet-lt)}
.pcard .im img,.cell.photo .ph img{transition:transform var(--t-4) var(--e-out)}
.pcard:hover .im img{transform:scale(1.045)}

/* ---------------------------------------------------------------------------
   6. THE SMART HEADER — a rock ledge that draws back when you are moving down
   the passage and comes forward the moment you turn around.
   ------------------------------------------------------------------------- */
header.top{transition:transform var(--t-3) var(--e-out),
  background-color var(--t-3) var(--e-out),box-shadow var(--t-3) var(--e-out),
  padding var(--t-3) var(--e-out)}
header.top::after{transition:opacity var(--t-3) var(--e-out)}
header.top .row{transition:padding var(--t-3) var(--e-out)}
/* Only the background, the shadow and a translate change on scroll. The header
   is position:sticky, so it still occupies its space in flow: changing its
   HEIGHT would shorten the document and jump everything below it. Translating
   it costs no layout, so the reveal stays perfectly smooth. */
body.hd-stuck header.top{
  background:color-mix(in srgb,var(--surface) 92%,transparent);
  box-shadow:0 10px 34px -18px rgba(12,6,26,.55),
             0 1px 0 0 rgba(var(--glow-v),calc(.34 * var(--lume)))}
body.hd-hide header.top{transform:translateY(-104%)}
body.hd-hide header.top::after{opacity:0}

/* ---------------------------------------------------------------------------
   7. THE DESCENT RAIL — where you are in the cave, and a way to jump.
   A vein of mineral down the right edge that fills as you go, with a marker
   per chamber. Labels appear on hover; the whole thing is keyboard reachable.
   ------------------------------------------------------------------------- */
.descent{position:fixed;right:clamp(10px,1.6vw,26px);top:50%;transform:translateY(-50%);
  z-index:70;display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:12px 8px;border-radius:999px;
  background:color-mix(in srgb,var(--surface) 86%,transparent);
  border:1px solid var(--line-strong);
  -webkit-backdrop-filter:blur(14px) saturate(1.2);backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:var(--el-3),inset 0 1px 0 rgba(255,255,255,.06);
  opacity:0;transform:translateY(-50%) translateX(14px);pointer-events:none;
  transition:opacity var(--t-4) var(--e-out),transform var(--t-4) var(--e-out)}
.descent.on{opacity:1;transform:translateY(-50%) translateX(0);pointer-events:auto}
.descent .vein{position:absolute;left:50%;top:12px;bottom:12px;width:2px;margin-left:-1px;
  background:color-mix(in srgb,var(--line-strong) 90%,transparent);border-radius:2px;overflow:hidden}
.descent .vein i{position:absolute;left:0;right:0;top:0;height:var(--depth,0%);
  background:linear-gradient(180deg,var(--violet),var(--magenta) 60%,var(--cyan));
  box-shadow:0 0 12px rgba(var(--glow-m),.7);transition:height var(--t-2) linear}
.dmark{position:relative;z-index:2;display:block;width:26px;height:26px;border:0;padding:0;
  background:none;cursor:pointer;display:grid;place-items:center}
.dmark::before{content:"";width:7px;height:7px;border-radius:50%;
  background:color-mix(in srgb,var(--ink-mut) 70%,var(--line-strong));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--surface) 88%,transparent);
  transition:background var(--t-2) var(--e-out),transform var(--t-3) var(--e-spring)}
.dmark:hover::before{background:var(--violet);transform:scale(1.35)}
.dmark.on::before{background:var(--magenta);transform:scale(1.55);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--surface) 88%,transparent),0 0 16px rgba(var(--glow-m),.95)}
.dmark .lb{position:absolute;right:calc(100% + 12px);top:50%;transform:translateY(-50%) translateX(6px);
  white-space:nowrap;font-family:var(--mono);font-size:10.8px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:5px 10px;
  box-shadow:var(--el-2);opacity:0;pointer-events:none;
  transition:opacity var(--t-2) var(--e-out),transform var(--t-2) var(--e-out)}
.dmark:hover .lb,.dmark:focus-visible .lb{opacity:1;transform:translateY(-50%) translateX(0)}
@media(max-width:1100px){.descent{display:none}}

/* on narrow screens the descent becomes a hairline across the top */
.dbarline{position:fixed;left:0;top:0;height:2px;z-index:80;width:var(--depth,0%);
  background:linear-gradient(90deg,var(--violet),var(--magenta) 60%,var(--cyan));
  box-shadow:0 0 10px rgba(var(--glow-m),.8);transition:width var(--t-1) linear;display:none}
@media(max-width:1100px){.dbarline{display:block}}

/* ---------------------------------------------------------------------------
   8. THE WAYFINDER — command palette. Cmd/Ctrl+K, or / anywhere.
   A marketplace with 31 vendors and 1,000+ genetics should never make you
   navigate to search.
   ------------------------------------------------------------------------- */
.wf-ov{position:fixed;inset:0;z-index:1400;display:grid;place-items:start center;
  padding:clamp(48px,11vh,140px) 18px 24px;
  background:color-mix(in srgb,var(--void) 62%,transparent);
  -webkit-backdrop-filter:blur(10px) saturate(.9);backdrop-filter:blur(10px) saturate(.9);
  opacity:0;transition:opacity var(--t-3) var(--e-out)}
.wf-ov.on{opacity:1}
.wf{width:min(680px,100%);border-radius:20px;overflow:hidden;position:relative;
  background:var(--surface);border:1px solid var(--line-strong);
  box-shadow:var(--el-4),0 0 0 1px rgba(var(--glow-v),.16),
             0 0 70px rgba(var(--glow-v),calc(.3 * var(--lume)));
  transform:translateY(-14px) scale(.985);opacity:.4;
  transition:transform var(--t-4) var(--e-spring),opacity var(--t-3) var(--e-out)}
.wf-ov.on .wf{transform:translate3d(0,0,0);opacity:1}
/* the lit lip along the top of the slab */
.wf::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:3;
  background:linear-gradient(90deg,transparent,rgba(var(--glow-m),.85),transparent)}
.wf-in{display:flex;align-items:center;gap:12px;padding:16px 18px;
  border-bottom:1px solid var(--line)}
.wf-in svg{width:19px;height:19px;color:var(--violet);flex:none}
.wf-in input{flex:1;min-width:0;background:none;border:0;outline:none;font-family:inherit;
  font-size:17px;color:var(--ink);letter-spacing:-.005em}
.wf-in input::placeholder{color:var(--ink-mut)}
.wf-esc{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;color:var(--ink-mut);
  border:1px solid var(--line-strong);border-radius:6px;padding:4px 8px;flex:none}
.wf-body{max-height:min(56vh,460px);overflow:auto;overscroll-behavior:contain;
  scrollbar-width:thin}
.wf-body::-webkit-scrollbar{width:8px}
.wf-body::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px}
/* a fade at whichever end still has results past it, so the list never just stops */
.wf{--fade-t:0;--fade-b:0}
.wf-body{position:relative;
  -webkit-mask-image:linear-gradient(180deg,
    rgba(0,0,0,calc(1 - var(--fade-t) * .88)) 0,#000 22px,
    #000 calc(100% - 22px),rgba(0,0,0,calc(1 - var(--fade-b) * .88)) 100%);
  mask-image:linear-gradient(180deg,
    rgba(0,0,0,calc(1 - var(--fade-t) * .88)) 0,#000 22px,
    #000 calc(100% - 22px),rgba(0,0,0,calc(1 - var(--fade-b) * .88)) 100%)}
.wf-grp{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  font-weight:600;color:var(--ink-mut);padding:14px 18px 7px}
.wf-it{display:flex;align-items:center;gap:13px;padding:9px 18px;cursor:pointer;
  border-left:2px solid transparent;transition:background var(--t-1) linear}
.wf-it .th{width:38px;height:38px;border-radius:9px;flex:none;object-fit:cover;
  background:var(--well) center/cover no-repeat;border:1px solid var(--line)}
/* rows that are places rather than things get a mark, not an empty tile */
/* a listing with no photo gets quiet stone, not a borrowed icon */
.wf-it .th.blank{background:
  linear-gradient(135deg,color-mix(in srgb,var(--well) 60%,var(--ground2)),var(--well))}
.wf-it .th.ic{display:grid;place-items:center;background:var(--wash);color:var(--violet);
  border-color:color-mix(in srgb,var(--violet) 26%,transparent)}
.wf-it .th.ic svg{width:17px;height:17px}
.wf-it.sel .th.ic{background:var(--violet);color:#fff;border-color:transparent}
.wf-it .tx{min-width:0;flex:1}
.wf-it .n{display:block;font-size:14.6px;font-weight:600;color:var(--ink);line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-it .m{display:block;font-family:var(--mono);font-size:11.4px;color:var(--ink-mut);
  margin-top:3px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wf-it .go{font-family:var(--mono);font-size:11px;color:var(--ink-mut);opacity:0;flex:none}
.wf-it.sel{background:var(--wash);border-left-color:var(--magenta)}
.wf-it.sel .go{opacity:1;color:var(--ink-violet)}
.wf-it.sel .n{color:var(--ink-violet)}
.wf-empty{padding:30px 18px 34px;text-align:center;color:var(--ink-mut);font-size:13.5px}
.wf-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:11px 18px;border-top:1px solid var(--line);background:var(--well);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;color:var(--ink-mut)}
.wf-foot kbd{font-family:inherit;border:1px solid var(--line-strong);border-radius:5px;
  padding:2px 6px;color:var(--ink-2);background:var(--surface)}
@media(max-width:560px){
  .wf-ov{padding-top:16px}
  .wf-in input{font-size:16px}
  .wf-foot{display:none}
}

/* The header carries more than it used to: nav, search, the shortcut hint, the
   theme lantern, account, saved and cart. Buy the search field room back out of
   the padding rather than letting it collapse to three letters. */
.top .navlinks a{padding:8px 12px}
.top .icons{gap:14px}
.top .search{position:relative;min-width:168px;max-width:340px}
/* nothing in the icon cluster may compress or wrap: a two-line Cart pill is
   the first thing that gives way when the row runs out of room */
.top .icons>*{flex:none;white-space:nowrap}
@media(max-width:1200px){
  .top .search{min-width:104px}
  .top .navlinks a{padding:8px 9px;font-size:13.5px}
  .top .row{gap:18px}
}
/* The base stylesheet only folds the nav into the burger at 960px, so between
   there and about 1060 the row has more in it than it can hold and the Cart
   pill is the piece that gets cut. Drop the search field through that band:
   the wayfinder is still on Ctrl K and in the burger menu. */
@media(min-width:961px) and (max-width:1060px){
  .top .search{display:none}
  .top .navlinks a{padding:8px 7px;font-size:13px}
  .top .row{gap:14px}
  .top .icons{gap:11px}
}
/* The base site swaps to the burger at 960px, but the row now carries a lantern
   as well, and between about 960 and 1040 the cart pill is pushed off the edge.
   Hand that band to the mobile menu instead, where everything fits. */
@media(max-width:1040px){
  .abar{display:none}
  .navlinks{display:none}
  .top .search{display:none}
  .top .icons{display:none}
  .burger{display:flex}
  .brand{margin-right:auto}
  .top .row{gap:12px}
  header.top.open .mobnav{display:flex}
  header.top.open .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  header.top.open .burger span:nth-child(2){opacity:0}
  header.top.open .burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}

/* Saved, as the heart it already meant */
.top .icons a.saved.ic-only{position:relative;display:grid;place-items:center;
  width:38px;height:38px;border-radius:50%;color:var(--ink-2);
  border:1px solid transparent;transition:color var(--t-2) var(--e-out),
  background var(--t-2) var(--e-out),border-color var(--t-2) var(--e-out)}
.top .icons a.saved.ic-only:hover{color:var(--magenta);background:var(--wash);
  border-color:color-mix(in srgb,var(--magenta) 28%,transparent)}
.top .icons a.saved.ic-only svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.9}
.top .icons a.saved.ic-only .n{position:absolute;top:-1px;right:-1px;min-width:16px;height:16px;
  padding:0 4px;border-radius:999px;background:var(--grad2);color:#fff;
  font-family:var(--mono);font-size:9.5px;font-weight:700;line-height:16px;text-align:center;
  box-shadow:0 2px 8px rgba(var(--glow-m),.5)}
.top .icons a.saved.ic-only .n:empty,
.top .icons a.saved.ic-only .n[style*="display: none"]{display:none}
.top .icons a.saved.ic-only::after{display:none}
.top .search .kbd{position:absolute;right:11px;top:50%;transform:translateY(-50%);
  font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--ink-mut);
  border:1px solid var(--line-strong);border-radius:5px;padding:2px 6px;pointer-events:none;
  background:var(--surface)}
.top .search input{padding-right:70px;cursor:pointer;text-overflow:ellipsis}
@media(max-width:1330px){.top .search .kbd{display:none}.top .search input{padding-right:16px}}

/* ---------------------------------------------------------------------------
   9. SKELETONS — a seam of mineral running through the stone while it loads.
   ------------------------------------------------------------------------- */
.sk{position:relative;overflow:hidden;background:var(--well);border-radius:10px}
.sk::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,
    color-mix(in srgb,var(--surface) 88%,transparent) 42%,
    rgba(var(--glow-v),calc(.2 * var(--lume))) 52%,
    color-mix(in srgb,var(--surface) 88%,transparent) 62%,transparent);
  animation:seam 1.5s var(--e-in-out) infinite}
@keyframes seam{100%{transform:translateX(100%)}}
@media (prefers-reduced-motion:reduce){.sk::after{animation:none;opacity:.5;transform:none}}
.skcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;box-shadow:var(--el-1)}
.skcard .a{height:138px;border-radius:0}
.skcard .b{padding:14px;display:grid;gap:9px}
.skcard .b i{display:block;height:11px;border-radius:5px}
.skcard .b i:nth-child(1){width:82%}
.skcard .b i:nth-child(2){width:46%}
.skcard .b i:nth-child(3){width:62%;margin-top:3px}

/* ---------------------------------------------------------------------------
   10. FOCUS + TOAST + SCROLLBAR — the details that read as finish
   ------------------------------------------------------------------------- */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--violet);outline-offset:3px;border-radius:6px}
.vc:focus-visible,.pcard:focus-visible,.cell:focus-visible{outline-offset:4px}

#cc-toast{background:var(--surface)!important;color:var(--ink)!important;
  border:1px solid var(--line-strong);box-shadow:var(--el-3)!important;
  font-family:var(--mono);letter-spacing:.02em;
  transition:opacity var(--t-3) var(--e-out),transform var(--t-3) var(--e-out)!important}

html{scrollbar-color:var(--line-strong) transparent}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px;
  border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--violet);background-clip:content-box}

/* ---------------------------------------------------------------------------
   11. PAGE TRANSITION — you step through the cave mouth into the next chamber
   ------------------------------------------------------------------------- */
/* Leaving a page fades out, which is safe: it is user-initiated and short.
   Arriving does NOT fade in. An entrance animation on <body> with fill-mode
   `both` holds its from-state (opacity:0) for as long as the main thread is
   busy, and on a cold load that is long enough to blank the entire page. The
   arrival is handled per-element by the reveal instead, which can only ever
   hide things that are off screen. */
body{opacity:1}
body.pg-out{opacity:0;transform:translateY(-6px);
  transition:opacity 200ms var(--e-snap),transform 200ms var(--e-snap)}
@media (prefers-reduced-motion:reduce){
  body.pg-out{transition:none;opacity:1;transform:none}
}

/* ---------------------------------------------------------------------------
   12. QUICK LOOK — a niche opens beside the grid.
   Browsing a marketplace should not mean a full page load per curiosity. The
   drawer carries everything needed to decide and to buy, and hands off to the
   full listing when the visitor wants the rest.
   ------------------------------------------------------------------------- */
.qv-ov{position:fixed;inset:0;z-index:1300;
  background:color-mix(in srgb,var(--void) 58%,transparent);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  opacity:0;transition:opacity var(--t-3) var(--e-out)}
.qv-ov.on{opacity:1}

.qv{position:fixed;top:0;right:0;bottom:0;width:min(468px,100vw);z-index:1301;will-change:transform;
  display:flex;flex-direction:column;
  background:var(--surface);border-left:1px solid var(--line-strong);
  box-shadow:var(--el-4),-1px 0 0 0 rgba(var(--glow-v),.2),
             -30px 0 90px rgba(var(--glow-v),calc(.24 * var(--lume)));
  transform:translateX(102%);transition:transform var(--t-4) var(--e-out)}
.qv.on{transform:translate3d(0,0,0)}
/* the lit seam where the niche was cut */
.qv::before{content:"";position:absolute;left:0;top:0;bottom:0;width:1px;z-index:3;
  background:linear-gradient(180deg,transparent,rgba(var(--glow-m),.75) 30%,
    rgba(var(--glow-c),.6) 70%,transparent)}

.qv-top{display:flex;align-items:center;gap:12px;padding:14px 16px;
  border-bottom:1px solid var(--line);flex:none}
.qv-top .lbl{font-family:var(--mono);font-size:10.8px;letter-spacing:.2em;
  text-transform:uppercase;font-weight:600;color:var(--ink-mut)}
.qv-x{margin-left:auto;width:34px;height:34px;border-radius:50%;border:1px solid var(--line-strong);
  background:var(--well);color:var(--ink-2);display:grid;place-items:center;cursor:pointer;
  transition:color var(--t-2) var(--e-out),background var(--t-2) var(--e-out)}
.qv-x:hover{color:var(--ink);background:var(--wash)}
.qv-x svg{width:15px;height:15px}

.qv-body{flex:1;overflow:auto;overscroll-behavior:contain;padding:0 0 var(--s-8)}
.qv-hero{position:relative;aspect-ratio:1;background:var(--well);overflow:hidden;
  border-bottom:1px solid var(--line)}
.qv-hero img{width:100%;height:100%;object-fit:cover;display:block}
.qv-thumbs{position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:6px;z-index:2}
.qv-thumbs button{flex:0 1 62px;aspect-ratio:1;min-width:0;padding:0;cursor:pointer;
  border:1.5px solid rgba(255,255,255,.6);border-radius:8px;background:#fff center/cover no-repeat;
  opacity:.82;transition:opacity var(--t-2) var(--e-out),transform var(--t-2) var(--e-out)}
.qv-thumbs button:hover,.qv-thumbs button.on{opacity:1;border-color:#fff;transform:translateY(-2px)}
.qv-flag{position:absolute;top:12px;left:12px;z-index:2;font-family:var(--mono);font-size:9.6px;
  letter-spacing:.14em;text-transform:uppercase;font-weight:600;color:#fff;
  background:rgba(var(--glow-v),.62);border:1px solid rgba(255,255,255,.34);border-radius:999px;
  padding:4px 11px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}

.qv-in{padding:var(--s-5) var(--s-5) 0}
.qv-ven{font-family:var(--mono);font-size:11.4px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-mut);display:flex;align-items:center;gap:8px}
.qv-in h3{font-family:var(--display);font-size:22px;line-height:1.18;margin:9px 0 0;color:var(--ink)}
.qv-price{font-family:var(--mono);font-size:22px;color:var(--ink);margin-top:12px;
  display:flex;align-items:baseline;gap:10px}
.qv-price .stk{font-size:11.4px;letter-spacing:.1em;text-transform:uppercase;color:var(--emerald)}
.qv-price .stk.out{color:var(--ink-mut)}
.qv-desc{margin-top:14px;font-size:14.2px;line-height:1.62;color:var(--ink-2);
  max-height:150px;overflow:hidden;position:relative;
  -webkit-mask-image:linear-gradient(#000 62%,transparent);
  mask-image:linear-gradient(#000 62%,transparent)}
.qv-desc.all{max-height:none;-webkit-mask-image:none;mask-image:none}
.qv-more{margin-top:8px;background:none;border:0;padding:6px 0;cursor:pointer;
  font-family:var(--mono);font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-violet)}
.qv-more:hover{color:var(--magenta)}
.qv-field{margin-top:var(--s-5)}
.qv-field label{display:block;font-family:var(--mono);font-size:11.4px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--ink-2);margin-bottom:8px}
.qv-field select{width:100%;background:var(--well);border:1px solid var(--line-strong);
  border-radius:var(--r-ctrl);color:var(--ink);padding:12px 13px;font-family:inherit;
  font-size:14.5px;outline:none}
.qv-field select:focus{border-color:var(--violet);box-shadow:0 0 0 3px var(--wash)}

.qv-foot{flex:none;padding:var(--s-4) var(--s-5) calc(var(--s-4) + env(safe-area-inset-bottom,0px));
  border-top:1px solid var(--line);background:var(--surface);display:grid;gap:10px}
.qv-row{display:flex;gap:10px;align-items:stretch}
.qv-qty{display:inline-flex;align-items:center;border:1px solid var(--line-strong);
  border-radius:var(--r-ctrl);overflow:hidden;flex:none;background:var(--surface)}
.qv-qty button{width:40px;border:0;background:none;font-size:17px;color:var(--ink-2);cursor:pointer}
.qv-qty button:hover{background:var(--well);color:var(--ink)}
.qv-qty span{min-width:38px;text-align:center;font-family:var(--mono);font-size:15px}
.qv-add{flex:1;display:flex;align-items:center;justify-content:center;gap:9px;border:0;
  border-radius:var(--r-ctrl);background:var(--grad2);color:#fff;font-family:inherit;
  font-weight:700;font-size:14.6px;padding:14px 18px;cursor:pointer;
  box-shadow:0 8px 26px rgba(var(--glow-m),.36);
  transition:transform var(--t-2) var(--e-out),box-shadow var(--t-2) var(--e-out)}
.qv-add:hover{transform:translateY(-1px);box-shadow:0 12px 34px rgba(var(--glow-m),.5)}
.qv-add:disabled{opacity:.5;cursor:default;transform:none;box-shadow:none}
.qv-full{text-align:center;font-family:var(--mono);font-size:11.2px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--ink-violet);padding:4px}
.qv-full:hover{color:var(--magenta)}
.qv-load{padding:60px 20px;text-align:center;color:var(--ink-mut);font-family:var(--mono);font-size:12.5px}

/* the trigger, beside the wishlist heart */
.pcard .peek{position:absolute;top:9px;right:49px;z-index:3;width:34px;height:34px;padding:0;
  border-radius:50%;border:1px solid var(--line);
  background:color-mix(in srgb,var(--surface) 84%,transparent);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  display:grid;place-items:center;cursor:pointer;color:var(--ink-mut);
  box-shadow:0 2px 8px rgba(6,3,16,.18);
  transition:transform var(--t-2) var(--e-out),color var(--t-2) var(--e-out)}
.pcard .peek:hover{transform:scale(1.08);color:var(--violet)}
.pcard .peek svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.9}

/* On a phone the niche takes the whole screen and slides up from the floor.
   Sizing a fixed element from its offsets alone (top:auto with bottom:0, or a
   top inset with bottom:0 and no height) makes Chromium drop the entire frame
   and paint nothing but the root background, so the sheet is pinned on all four
   sides like the desktop drawer and simply changes which edge it enters from. */
@media(max-width:640px){
  .qv{top:0;left:0;right:0;bottom:0;width:auto;height:auto;
    border-left:0;border-radius:0;transform:translateY(100%);
    background:var(--surface);
    -webkit-backdrop-filter:none;backdrop-filter:none;
    box-shadow:none}
  .qv.on{transform:translate3d(0,0,0)}
  .qv::before{left:0;right:0;top:0;bottom:auto;width:auto;height:1px;
    background:linear-gradient(90deg,transparent,rgba(var(--glow-m),.8),transparent)}
  .qv-top{padding-top:calc(14px + env(safe-area-inset-top,0px))}
  .qv-foot{background:var(--surface)}
  .qv-hero{aspect-ratio:4/3}
  .pcard .peek{right:47px}
}

@media (prefers-reduced-motion:reduce){
  .qv,.qv-ov{transition:none}
}
