/* ============================================================
   lab.css — the exhibition floor.
   ============================================================ */
/* Above the flavour list, so its height must not move — see .fv-lock. */
.lab-hero{padding-block:clamp(120px,15vw,220px) clamp(40px,5vw,80px)}
.lab-h{margin-top:16px;line-height:.8}
.lab-toc{display:flex;flex-wrap:wrap;gap:10px;margin-top:clamp(30px,4vw,54px)}
.lab-toc a{display:block;padding:11px 16px;border:var(--rule) solid var(--hair);border-radius:var(--radius);
  transition:background var(--dur) var(--ease),color var(--dur)}
.lab-toc a:hover{background:var(--accent);color:var(--fg-inv);border-color:var(--accent)}

/* ---------- 01 Type lab ---------- */
.typelab{border-top:var(--rule) solid var(--hair)}
.tsets{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(32px,4vw,58px)}
.chip{padding:10px 15px;border:var(--rule) solid var(--hair);border-radius:var(--radius);
  font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;min-height:42px;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur)}
.chip:hover{border-color:var(--fg)}
.chip[aria-pressed="true"]{background:var(--accent);color:var(--fg-inv);border-color:var(--accent)}

.tspec{margin-top:22px;border:var(--rule) solid var(--hair);border-radius:var(--radius);
  background:var(--bg-2);overflow:hidden;
  --ts-disp:'Bodoni Moda',Georgia,serif;--ts-body:'Archivo',sans-serif;
  --ts-dw:400;--ts-bw:300;--ts-track:-.02em;--ts-case:none;--ts-lh:1.02}
.tspec-nav{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:16px clamp(20px,3vw,44px);border-bottom:var(--rule) solid var(--hair)}
.tspec-logo{font-family:var(--ts-disp);font-weight:var(--ts-dw);font-size:clamp(15px,1.5vw,21px);
  letter-spacing:var(--ts-track);text-transform:var(--ts-case)}
.tspec-links{display:flex;gap:20px;color:var(--fg-dim);font-family:var(--ts-body)}
.tspec-hero{padding:clamp(34px,6vw,90px) clamp(20px,3vw,44px);display:grid;gap:18px;max-width:32ch}
.tspec-eyebrow{color:var(--accent)}
.tspec-h{font-family:var(--ts-disp);font-weight:var(--ts-dw);font-size:clamp(2rem,5.4vw,4.6rem);
  line-height:var(--ts-lh);letter-spacing:var(--ts-track);text-transform:var(--ts-case);
  transition:font-size .4s var(--ease)}
.tspec-sub{font-family:var(--ts-body);font-weight:var(--ts-bw);font-size:clamp(1rem,1.3vw,1.2rem);
  color:var(--fg-dim);max-width:38ch;line-height:1.55}
.tspec-cta{font-family:var(--ts-body);font-weight:500;font-size:13px;justify-self:start;
  padding:13px 19px;border:var(--rule) solid var(--accent);color:var(--accent);border-radius:var(--radius)}
.tspec-foot{display:flex;justify-content:space-between;gap:16px;padding:14px clamp(20px,3vw,44px);
  border-top:var(--rule) solid var(--hair);background:var(--bg)}
.tl--lab{margin-top:clamp(28px,3.4vw,48px)}

/* the quiet/loud slider (shared shape with the homepage teaser) */
.tl{border:var(--rule) solid var(--hair);border-radius:var(--radius);overflow:hidden;background:var(--bg-2)}
.tl-stage{padding:clamp(30px,6vw,88px) clamp(22px,4vw,64px);display:grid;gap:18px;
  min-height:clamp(250px,30vw,400px);align-content:center;
  background:var(--tl-bg,transparent);color:var(--tl-fg,inherit);transition:background .3s linear,color .3s linear}
.tl-eyebrow{color:var(--tl-accent,var(--accent));transition:color .3s linear}
.tl-h{font-family:var(--f-grotesk);font-variation-settings:'wdth' var(--tl-wdth,100),'wght' var(--tl-wght,300);
  font-size:var(--tl-size,2.4rem);line-height:var(--tl-lh,1.15);letter-spacing:var(--tl-track,-.01em);
  text-transform:var(--tl-case,none);max-width:24ch;margin:0}
.tl-sub{font-size:15px;color:var(--tl-dim,var(--fg-dim));max-width:38ch}
.tl-ctrl{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:18px;align-items:center;
  padding:16px clamp(22px,4vw,64px);border-top:var(--rule) solid var(--hair);background:var(--bg)}
.tl-ctrl output{color:var(--accent);min-width:8ch;text-align:right}
input[type="range"]{appearance:none;height:2px;background:var(--hair);border-radius:2px;width:100%}
input[type="range"]::-webkit-slider-thumb{appearance:none;width:22px;height:22px;border-radius:50%;
  background:var(--accent);border:0;cursor:grab}
input[type="range"]::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--accent);border:0;cursor:grab}
@media (max-width:640px){.tl-ctrl{grid-template-columns:1fr;gap:10px}.tl-ctrl output{text-align:left}
  .tspec-links{display:none}}

/* ---------- 02 Motion lab ---------- */
.motionlab{border-top:var(--rule) solid var(--hair)}
.mlab{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px;
  margin-top:clamp(34px,4.4vw,64px);border:var(--rule) solid var(--hair)}
.mcell{padding:clamp(20px,2.4vw,34px);border:var(--rule) solid var(--hair);display:grid;
  grid-template-rows:auto 1fr auto;gap:18px}
.mcell-head{display:flex;align-items:baseline;gap:14px}
.mcell-head h3{letter-spacing:-.03em;margin-right:auto}
.mcell-try{color:var(--accent);border:var(--rule) solid var(--accent);padding:5px 9px;border-radius:var(--radius)}
.mcell-stage{position:relative;min-height:clamp(190px,20vw,260px);border-radius:var(--radius);
  background:var(--bg-2);overflow:hidden;display:grid;place-items:center;isolation:isolate}
.mcell-note{font-size:14px;color:var(--fg-dim);line-height:1.5;max-width:46ch}
@media (max-width:820px){.mlab{grid-template-columns:1fr}}

/* demo internals */
.d-magnet{width:100%;height:100%;display:grid;place-items:center;position:relative}
.d-magbtn{padding:19px 30px;background:var(--accent);color:var(--fg-inv);border-radius:var(--radius);
  font-family:var(--f-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;will-change:transform}
.d-reveal{padding:26px;width:100%}
.d-reveal p{font-family:var(--f-disp);font-variation-settings:'wdth' 84,'wght' 760;
  font-size:clamp(1.5rem,3.4vw,2.6rem);line-height:1.02;letter-spacing:-.04em;text-transform:uppercase}
.d-reveal .mask-line>span{transition-duration:.9s}
.d-replay{margin-top:16px;font-family:var(--f-mono);font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--accent);border-bottom:1px solid currentColor;padding-bottom:3px}
.d-para{position:absolute;inset:0}
.d-para i{position:absolute;border-radius:var(--radius);will-change:transform;display:block}
.d-para .p1{inset:18% 8% 18% 52%;background:color-mix(in srgb,var(--accent) 80%,transparent)}
.d-para .p2{inset:32% 30% 12% 22%;background:color-mix(in srgb,var(--fg) 22%,transparent)}
.d-para .p3{inset:12% 62% 44% 10%;background:color-mix(in srgb,var(--accent-2) 60%,transparent)}
.d-para .p4{inset:0;background:repeating-linear-gradient(90deg,var(--hair) 0 1px,transparent 1px 40px)}
.d-warp,.d-three{width:100%;height:100%;display:block}
.d-assemble{position:absolute;inset:0;padding:18px;display:grid;gap:6px;
  grid-template:'a a b' 1fr 'c d b' 1fr 'e e e' .55fr/1fr 1fr 1fr}
.d-assemble i{background:color-mix(in srgb,var(--fg) 12%,transparent);border-radius:var(--radius);
  opacity:0;transform:translateY(18px) scale(.94);transition:opacity .5s var(--ease),transform .6s var(--ease)}
.d-assemble.on i{opacity:1;transform:none}
.d-assemble i:nth-child(1){grid-area:a;background:color-mix(in srgb,var(--accent) 70%,transparent)}
.d-assemble i:nth-child(2){grid-area:b;transition-delay:.12s}
.d-assemble i:nth-child(3){grid-area:c;transition-delay:.24s}
.d-assemble i:nth-child(4){grid-area:d;transition-delay:.36s}
.d-assemble i:nth-child(5){grid-area:e;transition-delay:.48s;background:color-mix(in srgb,var(--accent-2) 45%,transparent)}
.d-trans{width:100%;height:100%;position:relative;display:grid;place-items:center;overflow:hidden}
.d-trans-a{font-family:var(--f-disp);font-variation-settings:'wdth' 80,'wght' 800;
  font-size:clamp(1.4rem,3vw,2.2rem);letter-spacing:-.04em;text-transform:uppercase;z-index:2}
.d-shutter{position:absolute;inset:0;background:var(--accent);z-index:3;transform:translateY(101%);
  transition:transform .5s cubic-bezier(.86,0,.07,1)}
.d-trans.go .d-shutter{transform:none}
.d-micro{display:grid;grid-template-columns:repeat(2,auto);gap:16px;place-content:center;place-items:center}
.d-toggle{width:64px;height:32px;border-radius:999px;background:var(--hair);position:relative;
  transition:background .3s var(--ease)}
.d-toggle i{position:absolute;top:4px;left:4px;width:24px;height:24px;border-radius:50%;background:var(--fg);
  transition:transform .34s cubic-bezier(.34,1.56,.64,1)}
.d-toggle[aria-pressed="true"]{background:var(--accent)}
.d-toggle[aria-pressed="true"] i{transform:translateX(32px);background:var(--fg-inv)}
.d-heart{width:52px;height:52px;display:grid;place-items:center;border:var(--rule) solid var(--hair);
  border-radius:50%;transition:border-color .3s,background .3s}
.d-heart svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;transition:fill .3s,transform .4s cubic-bezier(.34,1.56,.64,1)}
.d-heart[aria-pressed="true"]{border-color:var(--accent);color:var(--accent)}
.d-heart[aria-pressed="true"] svg{fill:currentColor;transform:scale(1.18)}
.d-count{display:flex;align-items:center;gap:2px;border:var(--rule) solid var(--hair);border-radius:var(--radius)}
.d-count button{width:38px;height:38px;display:grid;place-items:center;font-size:16px}
.d-count button:hover{background:var(--accent);color:var(--fg-inv)}
.d-count output{width:44px;text-align:center;font-family:var(--f-mono);font-size:13px}
.d-ripple{position:relative;overflow:hidden;padding:15px 22px;border:var(--rule) solid var(--hair);
  border-radius:var(--radius);font-family:var(--f-mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase}
.d-ripple span{position:absolute;border-radius:50%;background:color-mix(in srgb,var(--accent) 55%,transparent);
  transform:translate(-50%,-50%) scale(0);animation:rip .6s var(--ease) forwards;pointer-events:none}
@keyframes rip{to{transform:translate(-50%,-50%) scale(1);opacity:0}}

/* ---------- 03 Colour ---------- */
.colourlab{border-top:var(--rule) solid var(--hair)}
.cgrid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:2px;margin-top:clamp(32px,4vw,58px)}
.cs-swatch{display:grid;text-align:left}
.cs-swatch i{display:block;height:clamp(110px,13vw,190px);background:var(--c);
  border:var(--rule) solid var(--hair);transition:transform .45s var(--ease)}
.cs-swatch:hover i{transform:scale(1.025)}
.cs-swatch b{font:500 13px/1.4 var(--f-body);padding-top:11px;font-weight:600}
.cs-swatch span{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.12em;color:var(--fg-dim);padding-top:3px}
.cs-swatch.copied span{color:var(--accent)}
.cs-swatch.copied span::after{content:' · copied'}
@media (max-width:900px){.cgrid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:520px){.cgrid{grid-template-columns:repeat(2,1fr)}}

/* ---------- 04 Cursors ---------- */
.cursorlab{border-top:var(--rule) solid var(--hair)}
.czones{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2px;margin-top:clamp(32px,4vw,58px)}
.czone{padding:clamp(24px,3vw,44px);border:var(--rule) solid var(--hair);background:var(--bg-2);
  display:grid;gap:12px;align-content:center;min-height:clamp(150px,16vw,210px);
  transition:background var(--dur) var(--ease)}
.czone:hover{background:var(--accent);color:var(--fg-inv)}
.czone:hover .mono{color:color-mix(in srgb,var(--fg-inv) 70%,transparent)}
.czone-c{font-size:clamp(1.5rem,3.4vw,2.8rem);letter-spacing:-.04em}
.czones-note{margin-top:22px}
@media (max-width:760px){.czones{grid-template-columns:1fr}}

.lab-out{border-top:var(--rule) solid var(--hair)}
.lab-out-in{display:grid;grid-template-columns:1.3fr auto;gap:clamp(24px,4vw,60px);align-items:end}
@media (max-width:820px){.lab-out-in{grid-template-columns:1fr}}

/* ══════════ Six voices ══════════════════════════════════════
   The switcher is a genuinely good trick, but it used to strobe:
   hovering a row re-themed the page, the heading above the list
   re-typeset in the new flavour, the list slid up to 272px while
   the cursor stayed put, a different row landed under the cursor,
   its hover fired, and the two flavours ping-ponged at frame rate.

   The cure is structural, not a damper. Nothing above .flav-list is
   allowed to change size when data-flavor changes, and no row is
   allowed to change height. With the geometry frozen there is no
   layout shift, so there is nothing to re-trigger the hover.
   js/core.js adds two more belts: the swap is driven by real pointer
   movement rather than mouseenter, and the list is scroll-anchored.
   ------------------------------------------------------------ */

/* Two locks.

   .fv-lock-text pins only the metrics body text INHERITS, because
   body{font-weight:var(--body-wght)} resolves on <body> — an ancestor of
   anything we lock — so overriding the custom property alone leaves text
   inheriting the flavour's weight and re-wrapping by ~32px.

   .fv-lock adds the display tokens on top, freezing a subtree completely.
   It goes on everything above .flav-list. The list itself gets only the
   text lock, so the six words still re-typeset — that IS the demo. */
.fv-lock-text{
  --body-wght:400;
  --body-track:0;
  font-weight:var(--body-wght);
  letter-spacing:var(--body-track);
}
.fv-lock{
  --f-disp:var(--f-grotesk);
  --f-body:var(--f-grotesk);
  --disp-wght:800;
  --disp-wdth:78;
  --disp-track:-0.035em;
  --disp-lh:0.84;
  --disp-case:uppercase;
  --disp-style:normal;
  --body-wght:400;
  --body-track:0;
  font-weight:var(--body-wght);
  letter-spacing:var(--body-track);
}
/* [data-flavor="luxury"] .disp and [data-flavor="organic"] .disp set
   font-variation-settings outright, which would drop 'wdth' back to
   100 and re-wrap the heading. Out-specify them inside the lock. */
.fv-lock .disp,
[data-flavor] .fv-lock .disp{
  font-variation-settings:'wdth' var(--disp-wdth),'wght' var(--disp-wght);
}

.flav{border-top:var(--rule) solid var(--hair);
  /* --pad-y swings 70px→220px across flavours; this band can't. */
  padding-block:clamp(70px,9vw,150px)}
.flav-head{max-width:70ch}
.flav-list{margin-top:clamp(38px,5vw,72px);border-top:var(--rule) solid var(--hair)}
.flav-row{border-bottom:var(--rule) solid var(--hair)}

/* A fixed row box. The hover state (description, LIVE badge) animates
   inside it rather than growing it. */
.flav-btn{--flav-row:clamp(78px,7.6vw,116px);
  display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,26ch) auto;
  align-items:center;gap:clamp(14px,2.6vw,44px);width:100%;text-align:left;
  height:var(--flav-row);padding-block:0;overflow:hidden;
  transition:background var(--dur) var(--ease),padding-inline var(--dur) var(--ease)}
.flav-btn:hover,.flav-btn:focus-visible{background:var(--bg-2);padding-inline:clamp(8px,1.4vw,26px)}
.flav-num{color:var(--accent);flex:none}
.flav-word{font-size:clamp(2.1rem,6.4vw,5.6rem);line-height:1;
  transition:color var(--dur) var(--ease),translate var(--dur) var(--ease)}
.flav-btn:hover .flav-word{color:var(--accent)}
.flav-note{font-size:14px;line-height:1.5;color:var(--fg-dim);opacity:0;translate:0 6px;
  max-height:100%;overflow:hidden;
  transition:opacity .4s var(--ease),translate .4s var(--ease)}
.flav-btn:hover .flav-note,.flav-btn:focus-visible .flav-note{opacity:1;translate:0}
.flav-mark{flex:none;color:var(--fg-dim);opacity:0;transition:opacity .3s}
.flav-btn:hover .flav-mark{opacity:1}
.flav-btn[aria-pressed="true"] .flav-num{color:var(--fg)}
.flav-btn[aria-pressed="true"] .flav-word::after{content:'';display:inline-block;width:.28em;height:.28em;
  background:var(--accent);border-radius:var(--radius);margin-left:.22em;vertical-align:.12em}
.flav-foot{margin-top:26px}
@media (max-width:1000px){
  .flav-btn{grid-template-columns:auto minmax(0,1fr) auto}
  .flav-note{display:none}
}
}
