/*
 * neura-3d viewer — opmaak voor het `product-3d`-blok.
 *
 * Poort van het goedgekeurde AR-prototype (design/ar-prototype), maar
 * merk-neutraal: elke kleur loopt via de gb-/brand-tokenlaag met de
 * prototype-waarde als fallback, zodat het blok op elke site de eigen
 * accentkleur pakt en op Grill Bill er exact zo uitziet als het prototype.
 *
 * De tokens hangen aan de blok-sectie (`.nb--product-3d`), de rest gebruikt de
 * eigen `n3d-`-prefix: dit bestand wordt naast de blokken-CSS geladen en mag
 * daar niets van raken.
 */
.nb--product-3d {
  --n3d-accent: var(--gb-ember, var(--gb-flame, var(--brand-accent, #F39019)));
  --n3d-bg:     var(--gb-charcoal, var(--brand-bg-base, #0A0908));
  --n3d-panel:  var(--gb-coal, #161616);
  --n3d-sheet:  #262421;
  --n3d-line:   rgba(255, 255, 255, .08);
  --n3d-text:   var(--gb-cream, var(--brand-text, #EEE7DB));
  --n3d-muted:  rgba(238, 231, 219, .5);
  --n3d-mono:   var(--gb-font-mono, ui-monospace, "JetBrains Mono", monospace);
  color: var(--n3d-text);
}
.nb--product-3d *, .nb--product-3d *::before, .nb--product-3d *::after { box-sizing: border-box; }

.n3d-head { margin: 0 0 14px; }
.n3d-title { font-size: clamp(22px, 2.4vw, 30px); line-height: 1.1; margin: 0 0 8px; font-weight: 700; }
.n3d-intro { margin: 0; color: rgba(238, 231, 219, .78); max-width: 60ch; }

.n3d-wrap { position: relative; }
.n3d-stage {
  position: relative; background: var(--n3d-panel); border: 1px solid var(--n3d-line);
  border-radius: 6px; aspect-ratio: 4 / 5; overflow: hidden;
}
@media (min-width: 901px) { .n3d-stage { aspect-ratio: 16 / 10; } }
.n3d-stage model-viewer {
  width: 100%; height: 100%; display: block; position: relative; z-index: 1;
  background: transparent; --poster-color: transparent;
  /* Op `auto` pakte de browser élke veeg over het model als paginascroll en brak
     hij de pointer-reeks af (pointercancel): het model draaide op mobiel in
     stapjes van een paar graden. `pan-y` laat een horizontale veeg volledig bij
     ons (rondom draaien zonder haperen) en houdt verticaal vegen als paginascroll,
     zodat een kader dat het halve scherm vult de pagina niet op slot zet. */
  touch-action: pan-y; -webkit-user-select: none; user-select: none;
}
.n3d-bg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }

.n3d-pill,
.n3d-lid, .n3d-fs, .n3d-fsclose {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font-family: var(--n3d-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--n3d-text); background: rgba(10, 9, 8, .62); border: 1px solid var(--n3d-line);
  border-radius: 999px; padding: 8px 12px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.n3d-lid { position: absolute; left: 24px; top: 46px; z-index: 3; }
.n3d-lid:hover, .n3d-lid[data-lid="open"] { border-color: var(--n3d-accent); }
.n3d-lid svg, .n3d-fs svg, .n3d-fsclose svg { width: 13px; height: 13px; }
.n3d-fs { position: absolute; right: 22px; top: 18px; z-index: 3; }
.n3d-fs:hover { border-color: var(--n3d-accent); }
.n3d-fsclose { position: absolute; right: 22px; top: 18px; z-index: 4; display: none; }
.n3d-fsclose:hover { border-color: var(--n3d-accent); }
.n3d-lid:focus-visible, .n3d-fs:focus-visible, .n3d-fsclose:focus-visible,
.n3d-chip:focus-visible { outline: 2px solid var(--n3d-text); outline-offset: 2px; }

/* lightbox: de hele wrap verhuist naar de overlay en weer terug */
.n3d-overlay {
  position: fixed; inset: 0; z-index: 100; background: var(--n3d-bg);
  display: none; flex-direction: column; padding: 14px; gap: 10px;
}
.n3d-overlay.is-open { display: flex; }
.n3d-overlay .n3d-wrap { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.n3d-overlay .n3d-stage { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; }
.n3d-overlay .n3d-fs { display: none; }
.n3d-overlay .n3d-fsclose { display: inline-flex; }
.n3d-overlay .n3d-bgbar { justify-content: center; }
body.n3d-fs-open { overflow: hidden; }
.n3d-wrap.is-placeholder {
  min-height: 200px; border: 1px dashed var(--n3d-line); border-radius: 6px; display: grid;
  place-items: center; font-family: var(--n3d-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--n3d-muted);
}

/* chips-rijen (desktop, buiten de stage) */
.n3d-bgbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.n3d-bgbar .n3d-lbl {
  font-family: var(--n3d-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--n3d-muted); margin-right: 4px;
}
.n3d-chip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font: 500 12px inherit; color: rgba(238, 231, 219, .78);
  background: var(--n3d-panel); border: 1px solid var(--n3d-line); border-radius: 999px; padding: 7px 12px;
}
.n3d-chip:hover { color: var(--n3d-text); }
.n3d-chip.is-on { border-color: var(--n3d-accent); color: var(--n3d-text); box-shadow: 0 0 0 1px rgba(243, 144, 25, .25) inset; }
.n3d-chip.is-off { opacity: .55; text-decoration: line-through; }
.n3d-chip .n3d-sw { width: 14px; height: 14px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .15); }
.n3d-chip svg { width: 14px; height: 14px; }
.n3d-chip input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.n3d-lightchip { gap: 8px; cursor: default; }
.n3d-lightchip input { width: 110px; accent-color: var(--n3d-accent); margin: 0; }
.n3d-lightchip output { font-family: var(--n3d-mono); font-size: 10px; color: var(--n3d-muted); min-width: 34px; }

/* AR-knop in de model-viewer-slot */
.n3d-ar {
  position: absolute; right: 16px; bottom: 16px;
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--n3d-accent); color: #140a00; border: 0; border-radius: 999px;
  padding: 12px 18px; font: 600 14px inherit; cursor: pointer;
  box-shadow: 0 8px 24px rgba(243, 144, 25, .28);
}
.n3d-ar svg { width: 18px; height: 18px; }
.n3d-ar:focus-visible { outline: 2px solid var(--n3d-text); outline-offset: 3px; }

.n3d-arhint {
  display: none; position: absolute; left: 50%; bottom: 72px; transform: translateX(-50%); z-index: 7;
  max-width: 86%; padding: 10px 14px; border-radius: 12px; background: rgba(10, 9, 8, .82);
  color: var(--n3d-text); font-size: 13px; line-height: 1.4; text-align: center;
}
.n3d-arhint.is-on { display: block; }

/* Kaal muiswiel boven het model: de pagina scrolt, deze hint zegt kort hoe zoomen wel gaat. */
.n3d-zoomhint {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 8;
  max-width: 86%; padding: 10px 16px; border-radius: 12px; background: rgba(10, 9, 8, .82);
  color: var(--n3d-text); font-size: 14px; line-height: 1.4; text-align: center;
  pointer-events: none; opacity: 0; transition: opacity .25s ease;
}
.n3d-zoomhint.is-on { opacity: 1; }
/* Hero op desktop: het model staat rechts van de kop, de hint dus ook. */
@media (min-width: 901px) { .n3d--hero .n3d-zoomhint { left: 70%; } }
@media (prefers-reduced-motion: reduce) { .n3d-zoomhint { transition: none; } }

.n3d-hud { position: absolute; inset: 14px; pointer-events: none; z-index: 2; }
.n3d-hud i { position: absolute; width: 14px; height: 14px; border-color: var(--n3d-muted); border-style: solid; border-width: 0; }
.n3d-hud .tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.n3d-hud .tr { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.n3d-hud .bl { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; }
.n3d-hud .br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }
.n3d-hint {
  position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 2;
  font-family: var(--n3d-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--n3d-muted); white-space: nowrap; pointer-events: none; transition: opacity .4s;
}
.n3d-stage.is-touched .n3d-hint { opacity: 0; }
.n3d-loading {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; text-align: center; padding: 24px;
  font-family: var(--n3d-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--n3d-muted); background: var(--n3d-panel); transition: opacity .5s; pointer-events: none;
}
.n3d-stage.is-ready .n3d-loading { opacity: 0; }
/* Nog niet gestart (viewer.js laadt het model pas na de eerste interactie): alleen de poster. */
.n3d-loading[data-n3d-idle] { color: transparent; }

/* maten-strip */
.n3d-dims {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border: 1px solid var(--n3d-line); border-radius: 6px; overflow: hidden; margin-top: 12px;
}
.n3d-dims div { padding: 12px 14px; border-right: 1px solid var(--n3d-line); }
.n3d-dims div:last-child { border-right: 0; }
.n3d-dims b { display: block; font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
.n3d-dims span {
  font-family: var(--n3d-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--n3d-muted);
}

/* Foto-schuifjes: in de lade, direct onder de achtergrond-chips (viewer.js zet ze
   daar neer). Ingeklapt tot er een achtergrond gekozen is; dan schuiven ze uit via
   grid-template-rows 0fr → 1fr, zodat de hoogte animeert zonder vaste maat. */
.n3d-sheet .n3d-phototools {
  display: grid; grid-template-rows: 0fr; opacity: 0; transform: translateY(-6px);
  /* visibility: ingeklapt ook uit de tab-volgorde (anders bedient een toetsenbord
     onzichtbare schuifjes); de vertraging laat de inklap-animatie eerst aflopen. */
  visibility: hidden;
  transition: grid-template-rows .32s ease, opacity .24s ease, transform .32s ease, visibility 0s .32s;
}
.n3d-sheet .n3d-phototools-in { min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.n3d-wrap.has-photo .n3d-sheet .n3d-phototools {
  grid-template-rows: 1fr; opacity: 1; transform: none; visibility: visible;
  transition: grid-template-rows .32s ease, opacity .24s ease, transform .32s ease, visibility 0s;
}
.n3d-sheet .n3d-phototools label {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid #3a3733; font-size: 14px;
}
.n3d-sheet .n3d-phototools label:first-child { margin-top: 6px; }
.n3d-sheet .n3d-phototools input[type=range] { flex: 1; max-width: 180px; accent-color: var(--n3d-accent); margin: 0; }
.n3d-sheet .n3d-phototools .n3d-note { display: block; font-size: 12px; line-height: 1.45; color: rgba(238, 231, 219, .78); padding: 8px 0 2px; }
@media (prefers-reduced-motion: reduce) {
  .n3d-sheet .n3d-phototools, .n3d-wrap.has-photo .n3d-sheet .n3d-phototools { transition: none; }
}

/* opties-knop + lade/bottom sheet */
.n3d-opt {
  display: none; position: absolute; left: 12px; bottom: 12px; z-index: 6;
  border-radius: 20px; border: 0; background: rgba(28, 26, 23, .92); color: var(--n3d-text);
  align-items: center; justify-content: center; cursor: pointer;
}
.n3d-fs, .n3d-opt { width: 40px; height: 40px; padding: 0; border-radius: 20px; justify-content: center; gap: 0; }
.n3d-fs svg, .n3d-opt svg { width: 18px; height: 18px; animation: n3d-grow 2.4s ease-in-out infinite; }
@keyframes n3d-grow { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.22); } }
.n3d-wrap.sheet-open .n3d-opt svg { animation: none; }
@media (prefers-reduced-motion: reduce) { .n3d-fs svg, .n3d-opt svg { animation: none; } }

.n3d-sheetbg { display: none; position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .45); }
.n3d-sheet {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 61; max-height: 72vh; overflow: auto;
  background: var(--n3d-sheet); color: var(--n3d-text); border-radius: 18px 18px 0 0;
  padding: 8px 18px calc(18px + env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform .28s ease;
  scrollbar-width: thin; scrollbar-color: rgba(243, 144, 25, .85) transparent;
}
.n3d-sheet::-webkit-scrollbar { width: 6px; }
.n3d-sheet::-webkit-scrollbar-track { background: transparent; }
.n3d-sheet::-webkit-scrollbar-thumb { background: rgba(243, 144, 25, .85); border-radius: 3px; }
.n3d-sheet .n3d-grip { width: 38px; height: 4px; border-radius: 2px; background: #4a463f; margin: 4px auto 10px; }
.n3d-sheet h4 {
  margin: 14px 0 4px; font: 10px/1 var(--n3d-mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--n3d-muted);
}
.n3d-sheet .n3d-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0;
  border-bottom: 1px solid #3a3733; font-size: 14px;
}
.n3d-sheet .n3d-row:last-child { border-bottom: 0; }
.n3d-sheet .n3d-row input[type=range] { flex: 1; max-width: 180px; accent-color: var(--n3d-accent); }
.n3d-sheet .n3d-seg { display: flex; gap: 4px; background: #1c1a17; border-radius: 9px; padding: 3px; }
.n3d-sheet .n3d-seg button { border: 0; background: transparent; color: var(--n3d-muted); font: 500 12px/1 inherit; padding: 7px 10px; border-radius: 7px; cursor: pointer; }
.n3d-sheet .n3d-seg button.is-on { background: #3a3733; color: var(--n3d-text); }
.n3d-sheet .n3d-toggle {
  position: relative; width: 38px; height: 22px; border-radius: 11px; background: #4a463f; border: 0;
  flex: none; transition: background .2s; cursor: pointer;
}
.n3d-sheet .n3d-toggle::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 9px;
  background: #fff; transition: transform .2s;
}
.n3d-sheet .n3d-toggle.is-on { background: var(--n3d-accent); }
.n3d-sheet .n3d-toggle.is-on::after { transform: translateX(16px); }
.n3d-sheet .n3d-chips { display: flex; gap: 6px; overflow-x: auto; padding: 6px 0 4px; scrollbar-width: none; scroll-behavior: smooth; }
.n3d-sheet .n3d-chips::-webkit-scrollbar { height: 0; }
.n3d-sheet .n3d-chips button {
  flex: none; border: 1px solid #44413c; background: transparent; color: var(--n3d-text);
  font: 12px/1 inherit; padding: 8px 12px; border-radius: 16px; white-space: nowrap; cursor: pointer;
}
.n3d-sheet .n3d-chips button.is-on { border-color: var(--n3d-accent); }
.n3d-sheet .n3d-lidrow button {
  border: 1px solid var(--n3d-line); background: rgba(255, 255, 255, .06); color: var(--n3d-text);
  font: 500 12px/1 inherit; padding: 9px 14px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
}
.n3d-sheet .n3d-lidrow button.is-open { border-color: var(--n3d-accent); }
.n3d-sheet .n3d-sub { display: block; font-size: 11px; color: var(--n3d-muted); }
.n3d-sheet .n3d-close, .n3d-sheet .n3d-fsmirror {
  position: absolute; top: 10px; width: 32px; height: 32px; border-radius: 16px; border: 0;
  background: #3a3733; color: var(--n3d-text); display: grid; place-items: center; cursor: pointer;
}
.n3d-sheet .n3d-close { right: 12px; font-size: 16px; }
.n3d-sheet .n3d-fsmirror { right: 52px; }
.n3d-sheet .n3d-fsmirror svg { width: 15px; height: 15px; }
.n3d-wrap.sheet-open .n3d-sheetbg { display: block; }
.n3d-wrap.sheet-open .n3d-sheet { display: block; transform: translateY(0); }

/* AR-only sectie: alleen zichtbaar zolang de wrap `ar-active` heeft (ar-status "presenting") */
.n3d-sheet h4.ar-only,
.n3d-sheet .n3d-row.ar-only { display: none; }
.n3d-wrap.ar-active .n3d-sheet h4.ar-only { display: block; }
.n3d-wrap.ar-active .n3d-sheet .n3d-row.ar-only { display: flex; }

/* delen */
.n3d-sheet .n3d-qrrow { align-items: flex-start; gap: 14px; }
.n3d-sheet .n3d-qr { background: var(--n3d-text); padding: 6px; border-radius: 6px; width: 104px; height: 104px; flex: none; display: grid; place-items: center; }
.n3d-sheet .n3d-qr canvas, .n3d-sheet .n3d-qr img { width: 92px; height: 92px; display: block; image-rendering: pixelated; }
.n3d-sheet .n3d-qrrow p { margin: 0; font-size: 12px; line-height: 1.45; color: rgba(238, 231, 219, .78); }
.n3d-sheet .n3d-share { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 0 4px; }
.n3d-sheet .n3d-share a, .n3d-sheet .n3d-share button {
  display: inline-flex; align-items: center; gap: 7px; border: 1px solid #44413c; background: transparent;
  color: var(--n3d-text); font: 12px/1 inherit; padding: 9px 12px; border-radius: 16px;
  text-decoration: none; cursor: pointer;
}
.n3d-sheet .n3d-share svg { width: 14px; height: 14px; }
.n3d-sheet .n3d-share .is-ok { border-color: var(--n3d-accent); }
/* De QR wijst naar deze pagina: op het toestel zelf is dat zinloos. */
.n3d-wrap.is-touch .n3d-qrrow, .n3d-wrap.is-touch .n3d-fsmirror,
.n3d-wrap.ar-active .n3d-qrrow, .n3d-wrap.ar-active .n3d-fsmirror { display: none; }

/* ── QR-kaart linksonder in de stage (desktop) ──────────────────────────────
   viewer.js bouwt 'm alleen op een muis-apparaat; deze regels verbergen 'm
   bovendien tijdens een AR-sessie en op touch, net als het QR-rijtje in de lade.
   Linksonder botst niet met de opties-knop (linksboven) of volledig scherm
   (rechtsboven). */
.n3d-qrcard {
  position: absolute; left: 14px; bottom: 14px; z-index: 5; transition: left .28s ease;
  display: flex; flex-direction: column; align-items: center; gap: 8px; width: 132px;
  padding: 12px 12px 10px; border-radius: 14px;
  background: rgba(28, 26, 23, .92); color: var(--n3d-text);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .35);
}
.n3d-qrcard-code { background: var(--n3d-text); padding: 6px; border-radius: 6px; display: grid; place-items: center; }
.n3d-qrcard-code canvas, .n3d-qrcard-code img { width: 84px; height: 84px; display: block; image-rendering: pixelated; }
.n3d-qrcard p { margin: 0; font-size: 11px; line-height: 1.35; text-align: center; color: rgba(238, 231, 219, .82); }
.n3d-qrcard-x {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 11px; background: transparent; color: rgba(238, 231, 219, .7); cursor: pointer;
}
.n3d-qrcard-x:hover { color: var(--n3d-text); background: rgba(238, 231, 219, .12); }
.n3d-qrcard-x svg { width: 13px; height: 13px; }
.n3d-qrcard.is-collapsed { display: none; }

/* Ingeklapt: dezelfde hoek, alleen nog een ronde pil met het QR-icoon. */
.n3d-qrpill {
  display: none; position: absolute; left: 14px; bottom: 14px; z-index: 5; transition: left .28s ease;
  width: 40px; height: 40px; padding: 0; border: 0; border-radius: 20px;
  align-items: center; justify-content: center; cursor: pointer;
  background: rgba(28, 26, 23, .92); color: var(--n3d-text);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .3);
}
.n3d-qrpill.is-on { display: inline-flex; }
.n3d-qrpill:hover { color: var(--n3d-accent); }
.n3d-qrpill svg { width: 19px; height: 19px; }
.n3d-qrcard:focus-visible, .n3d-qrcard-x:focus-visible, .n3d-qrpill:focus-visible {
  outline: 2px solid var(--n3d-accent); outline-offset: 2px;
}
/* Nooit boven een AR-camerabeeld of op een toestel waar de QR naar zichzelf wijst. */
.n3d-wrap.is-touch .n3d-qrcard, .n3d-wrap.is-touch .n3d-qrpill,
.n3d-wrap.ar-active .n3d-qrcard, .n3d-wrap.ar-active .n3d-qrpill { display: none; }
@media (hover: none) and (pointer: coarse), (max-width: 720px) {
  .n3d-qrcard, .n3d-qrpill { display: none !important; }
}

/* mobiel: chips-rijen weg, alles in de bottom sheet */
@media (hover: none) and (pointer: coarse), (max-width: 720px) {
  .n3d-bgbar { display: none !important; }
  .n3d-opt { display: inline-flex; }
  .n3d-lid, .n3d-fs { display: none; }
  .n3d-sheet { display: block; }
}
/* Mobiel: viewer.js verhuist de lade + achtergrond naar <body> (.n3d-portal) zolang
   hij open staat. Binnen een fotokader met een eigen containing block (transform,
   overflow) schoof een position:fixed-lade anders onder het kader uit en stond de
   sluitknop buiten beeld. De portal-wrap spiegelt de klassen van de echte wrap
   (sheet-open, has-photo, ar-active, is-touch), dus alle regels hierboven gelden. */
.n3d-portal { position: fixed; inset: 0; z-index: 1000; pointer-events: none; }
.n3d-portal > * { pointer-events: auto; }
.n3d-portal .n3d-sheetbg { z-index: 1000; }
.n3d-portal .n3d-sheet { z-index: 1001; max-height: min(72vh, calc(100dvh - 56px)); overscroll-behavior: contain; }
body.n3d-sheet-open { overflow: hidden; }
/* desktop: dezelfde inhoud als lade links, niet-modaal zodat je kunt blijven draaien */
@media (min-width: 721px) and (hover: hover) {
  .n3d-bgbar { display: none !important; }
  .n3d-lid { display: none; }
  .n3d-opt { display: inline-flex; top: 46px; left: 24px; bottom: auto; }
  .n3d-sheet {
    display: block; position: absolute; top: 0; bottom: 0; left: 0; right: auto; width: 300px;
    max-height: none; border-radius: 0 18px 18px 0; padding: 52px 18px 18px;
    transform: translateX(-24px); opacity: 0; pointer-events: none;
    transition: transform .28s ease, opacity .28s ease;
    background: rgba(28, 26, 23, .94);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    box-shadow: 8px 0 30px rgba(0, 0, 0, .35);
  }
  .n3d-wrap.sheet-open .n3d-sheet { transform: none; opacity: 1; pointer-events: auto; }
  /* De niet-modale lade is 300px breed en z-index 61: die legt zich volledig over
     de QR-kaart linksonder heen. In fullscreen gaat de lade automatisch open, dus
     zonder deze regel is de kaart daar nooit zichtbaar. Schuif hem mee naar rechts. */
  .n3d-wrap.sheet-open .n3d-qrcard, .n3d-wrap.sheet-open .n3d-qrpill { left: 314px; }
  .n3d-sheet .n3d-grip { display: none; }
  .n3d-sheetbg { display: none !important; }
}

/* AR: "Opnieuw plaatsen" laat de vloerhoogte opnieuw meten (viewer.js rearmFloor).
   Alleen tijdens een AR-sessie én als de interne model-viewer-haak gevonden is. */
.n3d-rescan {
  display: none; position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 7;
  align-items: center; gap: 8px; padding: 10px 16px; border-radius: 999px;
  background: rgba(10, 9, 8, .82); color: var(--n3d-text); border: 1px solid var(--n3d-accent);
  font: 600 13px inherit; cursor: pointer;
}
.n3d-rescan svg { width: 16px; height: 16px; }
.n3d-wrap.ar-active.can-rescan .n3d-rescan { display: inline-flex; }
.n3d-intro>p { margin: 0 0 .6em; }
.n3d-intro>:last-child { margin-bottom: 0; }
.n3d-intro ul, .n3d-intro ol { margin: .3em 0 .6em; padding-left: 1.4em; }

/* ── lamp: dimmer, vergelijken, maatvoering (alleen bij model3d.light/compare/annotations) ──
   Alles op de stage zelf: in een fotokader (Grill Bill, Hilox) zijn de chipsrijen onder
   de stage verborgen. Gloed en maatlijnen liggen boven het model maar vangen geen klikken. */
.n3d-bg { transition: filter .6s ease; }
.n3d-stage.is-lit .n3d-bg { filter: brightness(.07) saturate(.5); }
.n3d-glow, .n3d-annot { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; overflow: visible; }
.n3d-glow i { position: absolute; display: block; border-radius: 50%; mix-blend-mode: screen; opacity: 0; will-change: transform, opacity; }
.n3d-annot line { fill: none; }
.n3d-annot .n3d-adim, .n3d-annot .n3d-aext, .n3d-annot .n3d-aref {
  stroke: #f4f1ea; filter: drop-shadow(0 0 1.2px rgba(0, 0, 0, .9));
}
.n3d-annot .n3d-adim { stroke-width: 1.3; }
.n3d-annot .n3d-aext { stroke-width: .9; opacity: .7; }
.n3d-annot .n3d-aref { stroke-width: 1.1; stroke-dasharray: 6 4; opacity: .85; }
.n3d-annot .n3d-aaccent { stroke: var(--n3d-accent); stroke-width: 1.8; filter: drop-shadow(0 0 3px rgba(0, 0, 0, .6)); }
.n3d-annot .n3d-apt { fill: var(--n3d-accent); stroke: #fff; stroke-width: 1.5; }
.n3d-annot marker path { fill: #f4f1ea; }
.n3d-annot .n3d-albl rect { fill: rgba(16, 15, 14, .86); stroke: rgba(255, 255, 255, .14); }
.n3d-annot .n3d-albl text { font: 600 12px var(--n3d-mono); fill: var(--n3d-text); font-variant-numeric: tabular-nums; }
.n3d-annot .n3d-albl.is-accent rect { fill: var(--n3d-accent); stroke: none; }
.n3d-annot .n3d-albl.is-accent text { fill: #140a00; }
.n3d-annot .n3d-albl.is-soft text { font-weight: 500; }
.n3d-annot .n3d-albl.is-tag text { font: 600 11px inherit; }

.n3d-modebar {
  position: absolute; top: 18px; left: 50%; transform: translateX(-50%); z-index: 4;
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; max-width: calc(100% - 150px);
}
.n3d-mode {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer; white-space: nowrap;
  font: 600 12px inherit; color: var(--n3d-text); background: rgba(10, 9, 8, .62);
  border: 1px solid var(--n3d-line); border-radius: 999px; padding: 8px 13px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.n3d-mode .n3d-dot { width: 8px; height: 8px; border-radius: 50%; background: rgba(238, 231, 219, .35); transition: background .3s, box-shadow .3s; }
.n3d-mode[aria-pressed="true"] { border-color: var(--n3d-accent); }
.n3d-mode[aria-pressed="true"] .n3d-dot { background: var(--n3d-accent); box-shadow: 0 0 6px var(--n3d-accent); }
.n3d-mode:focus-visible, .n3d-dial:focus-visible { outline: 2px solid var(--n3d-accent); outline-offset: 3px; }

.n3d-cmpinfo {
  position: absolute; top: 62px; left: 50%; transform: translate(-50%, -6px); z-index: 4;
  width: min(360px, calc(100% - 32px)); padding: 12px 14px; border-radius: 12px;
  background: rgba(16, 15, 14, .86); color: var(--n3d-text); font-size: 13px; line-height: 1.45;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 0; visibility: hidden; transition: opacity .3s ease, transform .3s ease, visibility 0s .3s; pointer-events: none;
}
.n3d-cmpinfo strong { display: block; font-size: 14px; margin-bottom: 3px; }
.n3d-cmpinfo p { margin: 0; color: rgba(238, 231, 219, .82); }
.n3d-wrap.is-compare .n3d-cmpinfo { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition: opacity .3s ease, transform .3s ease, visibility 0s; }

.n3d-dimmer {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 4;
  display: flex; align-items: center; gap: 14px; padding: 9px 18px 9px 9px; border-radius: 999px;
  background: rgba(16, 15, 14, .78); color: var(--n3d-text); border: 1px solid var(--n3d-line);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  -webkit-user-select: none; user-select: none;
}
.n3d-dial { position: relative; width: 76px; height: 76px; flex: none; border-radius: 50%; cursor: grab; touch-action: none; }
.n3d-dial:active { cursor: grabbing; }
.n3d-dial svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.n3d-dial .n3d-dial-bg { fill: none; stroke: rgba(238, 231, 219, .16); stroke-width: 4; stroke-linecap: round; }
.n3d-dial .n3d-dial-fg { fill: none; stroke: rgba(238, 231, 219, .55); stroke-width: 4; stroke-linecap: round; transition: stroke .3s; }
.n3d-dimmer.is-on .n3d-dial-fg { stroke: var(--n3d-accent); filter: drop-shadow(0 0 3px var(--n3d-accent)); }
.n3d-dial .n3d-dial-tick { stroke: rgba(238, 231, 219, .4); stroke-width: 1.5; }
.n3d-dial .n3d-dial-lbl { font: 600 8px var(--n3d-mono); fill: rgba(238, 231, 219, .55); }
.n3d-knob {
  position: absolute; inset: 14px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #5a5e66, #34373d 55%, #23252a);
  box-shadow: 0 4px 10px rgba(0, 0, 0, .5), inset 0 -2px 4px rgba(0, 0, 0, .4), inset 0 2px 3px rgba(255, 255, 255, .12);
  transition: box-shadow .15s ease;
}
.n3d-dimmer.is-pressed .n3d-knob { box-shadow: 0 1px 4px rgba(0, 0, 0, .4), inset 0 2px 5px rgba(0, 0, 0, .45); }
.n3d-knob-grip { position: absolute; inset: 0; border-radius: 50%; background: repeating-conic-gradient(rgba(255, 255, 255, .05) 0 4deg, transparent 4deg 12deg); }
.n3d-knob-mark {
  position: absolute; left: 50%; top: 6px; width: 4px; height: 12px; margin-left: -2px; border-radius: 2px;
  background: rgba(238, 231, 219, .55); transition: background .3s, box-shadow .3s;
}
.n3d-dimmer.is-on .n3d-knob-mark { background: var(--n3d-accent); box-shadow: 0 0 6px var(--n3d-accent); }
.n3d-dimread { display: flex; flex-direction: column; gap: 4px; min-width: 112px; }
.n3d-dimread strong { font: 700 20px/1 inherit; font-variant-numeric: tabular-nums; }
.n3d-dimread span { font-size: 11px; line-height: 1.3; color: var(--n3d-muted); }
.n3d-wrap.is-dims .n3d-hint, .n3d-wrap.is-compare .n3d-hint { opacity: 0; }
/* desktop: rechtsonder, zodat het midden vrij blijft voor het product en de maten (de AR-knop staat hier niet) */
@media (min-width: 721px) and (hover: hover) {
  .n3d-dimmer { left: auto; right: 16px; transform: none; }
}
/* tijdens AR: niets van de lampbediening over het camerabeeld */
.n3d-wrap.ar-active .n3d-dimmer, .n3d-wrap.ar-active .n3d-modebar, .n3d-wrap.ar-active .n3d-cmpinfo,
.n3d-wrap.ar-active .n3d-glow, .n3d-wrap.ar-active .n3d-annot { display: none; }
@media (hover: none) and (pointer: coarse), (max-width: 720px) {
  /* boven de AR-knop en de opties-knop (beide onderaan) */
  .n3d-dimmer { bottom: 70px; gap: 10px; padding: 6px 14px 6px 6px; }
  .n3d-dial { width: 62px; height: 62px; }
  .n3d-knob { inset: 12px; }
  .n3d-dimread { min-width: 0; }
  .n3d-dimread strong { font-size: 17px; }
  .n3d-modebar { top: 12px; max-width: calc(100% - 24px); flex-wrap: nowrap; gap: 6px; }
  .n3d-mode { padding: 7px 11px; gap: 6px; }
  .n3d-cmpinfo { top: 56px; font-size: 12px; }
}
/* smal scherm: viewer.js zet de kaart onder het kader (buiten de stage) */
.n3d-wrap > .n3d-cmpinfo {
  position: static; transform: none; width: auto; margin-top: 10px; display: none;
  border: 1px solid var(--n3d-line); background: var(--n3d-panel); opacity: 1; visibility: visible;
}
.n3d-wrap.is-compare > .n3d-cmpinfo { display: block; transform: none; }
@media (max-width: 720px) {
  .n3d-wrap.is-compare .n3d-dimread span, .n3d-wrap.is-dims .n3d-dimread span { display: none; }
  .n3d-stage.has-lamp-ui .n3d-hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .n3d-bg, .n3d-cmpinfo, .n3d-knob, .n3d-dial-fg { transition: none; }
}

/* ── hero-stand (layout: 'hero') ─────────────────────────────────────────────
   Volle-breedte openingssectie: de stage vult de hele sectie, het model draait als
   achtergrond (viewer.js zet de camera zo dat het op desktop rechts van de tekst
   staat en op mobiel midden-onder), kop/prijs liggen eroverheen. De tekstlaag vangt
   geen klikken, zodat slepen over de kop het model gewoon draait; alleen het
   prijsblok, de knoppen en de sterren zijn klikbaar. Hoogte: één scherm min de
   site-header (--n3d-hero-chrome, een thema kan hem zetten; bewust niet gemeten in JS,
   want dat zou de sectie na het laden laten verspringen). */
.nb--product-3d.n3d--hero {
  position: relative; isolation: isolate; overflow: hidden; padding: 0;
  height: calc(100svh - var(--n3d-hero-chrome, 72px)); min-height: 560px; max-height: 1100px;
  background: radial-gradient(70% 60% at 64% 56%, color-mix(in srgb, var(--n3d-text) 13%, var(--n3d-bg)) 0%, var(--n3d-bg) 75%);
  --n3d-hero-x: max(20px, calc((100% - var(--n3d-hero-max, 1240px)) / 2 + 20px));
}
.n3d--hero .n3d-wrap, .n3d--hero .n3d-stage { position: absolute; inset: 0; }
.n3d--hero .n3d-stage { border: 0; border-radius: 0; aspect-ratio: auto; background: transparent; }
.n3d--hero .n3d-loading { background: transparent; }
.n3d--hero .n3d-hero-poster {
  position: absolute; top: 6%; right: 0; width: 60%; height: 88%; object-fit: contain; display: block;
}
.n3d--hero .n3d-bgbar, .n3d--hero .n3d-hint, .n3d--hero .n3d-dims { display: none !important; }

.n3d-hero-in {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  display: flex; flex-direction: column;
  padding: clamp(18px, 3vh, 32px) var(--n3d-hero-x) clamp(20px, 3.4vh, 32px);
  transition: opacity var(--brand-duration-fast, 150ms) var(--brand-easing-default, ease);
}
/* Desktop-lade open: de tekst zou er anders bovenop liggen. */
.n3d--hero:has(.n3d-wrap.sheet-open) .n3d-hero-in { opacity: 0; }
.n3d-hero-top { display: flex; justify-content: flex-end; min-height: 18px; }
.n3d-hero-rating {
  pointer-events: auto; display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--n3d-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--n3d-muted);
}
.n3d-hero-stars { color: var(--n3d-accent); letter-spacing: 2px; }
.n3d-hero-copy { margin-top: clamp(16px, 7vh, 88px); max-width: min(560px, 44%); }
.n3d-hero-title {
  margin: 0; color: var(--n3d-text); font-weight: 700; line-height: 1.02; letter-spacing: -.025em; text-wrap: balance;
  font-family: var(--font-display, var(--brand-font-display, var(--brand-font-heading, inherit)));
  font-size: clamp(40px, 6.2vw, 84px);
}
.n3d-hero-title em { font-style: italic; color: var(--n3d-accent); font-weight: inherit; }
.n3d-hero-intro { margin-top: 16px; max-width: 32em; font-size: clamp(17px, 1.6vw, 21px); line-height: 1.5; color: rgba(238, 231, 219, .82); }
.n3d-hero-intro > p { margin: 0 0 .5em; }
.n3d-hero-intro > :last-child { margin-bottom: 0; }
.n3d-hero-bottom { margin-top: auto; display: flex; }
.n3d-hero-price {
  pointer-events: auto; display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 16px 18px 16px 20px; border-radius: calc(var(--brand-radius, 12px) + 6px);
  background: color-mix(in srgb, var(--n3d-bg) 82%, transparent); border: 1px solid var(--n3d-line);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.n3d-hero-p { font-size: 34px; font-weight: 700; letter-spacing: -.02em; line-height: 1; color: var(--n3d-text); font-variant-numeric: tabular-nums; }
.n3d-hero-was { color: var(--n3d-muted); font-size: 16px; }
.n3d-hero-note { display: block; margin-top: 6px; font-size: 14px; color: var(--n3d-accent); }
.n3d-hero-cta {
  display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 28px;
  border-radius: var(--brand-radius-full, 999px); background: var(--n3d-accent); color: var(--brand-text-on-primary, #140a00);
  font-weight: 600; font-size: 17px; text-decoration: none;
  transition: transform var(--brand-duration-fast, 150ms) var(--brand-easing-default, ease), filter var(--brand-duration-fast, 150ms) var(--brand-easing-default, ease);
}
.n3d-hero-cta:hover { filter: brightness(1.08); transform: translateY(-1px); }
.n3d-hero-cta:focus-visible, .n3d-hero-rating:focus-visible { outline: 2px solid var(--n3d-text); outline-offset: 3px; }
.n3d-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Bediening (opties, deksel, AR) in dezelfde rij als het prijsblok. Tot het model er is
   onzichtbaar maar met gereserveerde ruimte: geen verschuiving als ze verschijnen. De
   eigen AR-slotknop van model-viewer blijft weg; de hero-AR-knop doet hetzelfde. */
.n3d--hero .n3d-ar { display: none !important; }
.n3d-hero-bottom { justify-content: space-between; align-items: flex-end; gap: 16px; }
/* Rechtsonder staat de chatknop (24px van de rand, 56px breed): de knoppenrij houdt daar
   afstand van, ook als de sectie-marge kleiner is dan die knop. */
.n3d-hero-ctl {
  pointer-events: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end;
  margin-right: max(0px, calc(96px - var(--n3d-hero-x)));
}
.n3d--hero:not(.n3d-hero-live) .n3d-hero-ctl { visibility: hidden; }
.n3d-hero-btn {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; cursor: pointer;
  font: 500 15px inherit; color: var(--n3d-text); border-radius: var(--brand-radius-full, 999px);
  background: color-mix(in srgb, var(--n3d-bg) 62%, transparent); border: 1px solid var(--n3d-line);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: border-color var(--brand-duration-fast, 150ms) var(--brand-easing-default, ease);
}
.n3d-hero-btn[hidden] { display: none; }
.n3d-hero-btn svg { width: 18px; height: 18px; flex: none; }
.n3d-hero-btn:hover, .n3d-hero-btn[data-lid="open"] { border-color: var(--n3d-accent); }
.n3d-hero-btn:focus-visible { outline: 2px solid var(--n3d-text); outline-offset: 2px; }
.n3d-hero-opt { width: 44px; padding: 0; justify-content: center; }
.n3d-hero-ar { background: var(--n3d-accent); color: var(--brand-text-on-primary, #140a00); border-color: transparent; font-weight: 600; }
/* QR-popover boven de AR-knop (desktop). Geen permanente kaart: die viel onder de
   chatballon rechtsonder. De rechterrand valt samen met die van de knoppenrij, en die
   houdt al 96px afstand tot de rand van de sectie; viewer.js schuift hem bovendien
   naar links als hij toch in de chatzone zou vallen. */
.n3d-hero-ctl { position: relative; }
.n3d-hero-qr {
  position: absolute; right: 0; bottom: calc(100% + 10px); z-index: 6; width: 132px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 12px 12px 10px; border-radius: 14px;
  background: rgba(28, 26, 23, .94); color: var(--n3d-text);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .35);
}
.n3d-hero-qr[hidden] { display: none; }
.n3d-hero-qr-code { background: var(--n3d-text); padding: 6px; border-radius: 6px; display: grid; place-items: center; min-width: 96px; min-height: 96px; }
.n3d-hero-qr-code canvas, .n3d-hero-qr-code img { width: 84px; height: 84px; display: block; image-rendering: pixelated; }
.n3d-hero-qr p { margin: 0; font-size: 11px; line-height: 1.35; text-align: center; color: rgba(238, 231, 219, .82); }
.n3d-hero-qr-x {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 11px; background: transparent; color: rgba(238, 231, 219, .7); cursor: pointer;
  font: 400 18px/1 inherit;
}
.n3d-hero-qr-x:hover { color: var(--n3d-text); background: rgba(238, 231, 219, .12); }
.n3d-hero-qr-x:focus-visible { outline: 2px solid var(--n3d-accent); outline-offset: 2px; }
/* Nooit boven een AR-camerabeeld of op een toestel waar de QR naar zichzelf wijst. */
@media (hover: none) and (pointer: coarse), (max-width: 720px) {
  .n3d-hero-qr { display: none !important; }
}

@media (max-width: 900px) {
  .nb--product-3d.n3d--hero { height: calc(92svh - var(--n3d-hero-chrome, 64px)); min-height: 520px; }
  .n3d--hero .n3d-hero-poster { top: 30%; width: 100%; height: 46%; }
  .n3d-hero-top { justify-content: flex-start; }
  .n3d-hero-copy { margin-top: 10px; max-width: 100%; }
  .n3d-hero-title { font-size: clamp(34px, 9.5vw, 52px); }
  .n3d-hero-intro { font-size: 16px; max-width: 22em; margin-top: 10px; }
  .n3d-hero-price { width: 100%; justify-content: space-between; gap: 12px; padding: 12px 12px 12px 16px; }
  .n3d-hero-p { font-size: 26px; }
  .n3d-hero-was { font-size: 14px; }
  .n3d-hero-note { font-size: 13px; }
  .n3d-hero-cta { min-height: 48px; padding: 0 20px; font-size: 16px; }
  /* knoppenrij boven het prijsblok, over de volle breedte; het geheel staat boven de
     chatknop rechtsonder (24px + 56px), anders valt die over de koopknop */
  .n3d-hero-in { padding-bottom: 92px; }
  .n3d-hero-bottom { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
  .n3d-hero-ctl { justify-content: flex-start; margin-right: 0; }
  .n3d-hero-btn { min-height: 40px; padding: 0 14px; font-size: 14px; }
  .n3d-hero-opt { width: 40px; padding: 0; }
  .n3d-hero-ar { margin-left: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .n3d-hero-in, .n3d-hero-cta, .n3d-hero-btn { transition: none; }
  .n3d-hero-cta:hover { transform: none; }
}
