.wp3d-wrap {
  position: relative;
  /* Width: always fill the container (WooCommerce column / section) the viewer
     is embedded in, so it becomes full-width wherever it is called. */
  width: 100%;
  /* Height: derived from the width via aspect-ratio instead of a fixed pixel/vh
     clamp. This lets the viewer scale cleanly at any container width. Override
     the ratio per embed/theme with the --wp3d-aspect custom property. */
  aspect-ratio: var(--wp3d-aspect, 4 / 3);
  height: auto;
  /* Cap the computed height on very wide containers so the viewer never grows
     unusably tall. Override with --wp3d-max-height. */
  max-height: var(--wp3d-max-height, 720px);
  background:
    radial-gradient(circle at 50% 20%, rgba(255,255,255,.96) 0, rgba(246,242,236,.82) 32%, transparent 67%),
    linear-gradient(145deg, #f4f1ec 0%, #ddd5c9 100%);
  overflow: hidden;
  /* Rounded corners are kept by default; bound to a var so a specific embed can
     disable them (e.g. --wp3d-radius: 0) without touching the plugin CSS. */
  border-radius: var(--wp3d-radius, 18px);
  isolation: isolate;
  --wp3d-green: #4A5135;
}
.wp3d-viewer {
  display: block; width: 100%; height: 100%;
  --poster-color: transparent;
  --progress-bar-color: transparent;
  --progress-mask: transparent;
}
.wp3d-realtime-canvas {
  display: block;
  width: 100%;
  height: 100%;
  filter: brightness(.97) contrast(1.25) saturate(1.18);
}
.wp3d-wrap:not(.wp3d-ready) .wp3d-hotspot { display: none; }
/* Nordik-style marker: translucent frosted disc with a solid inner dot. */
.wp3d-hotspot {
  position: relative;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.9);
  background: rgba(255,255,255,.28);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  box-shadow: 0 2px 8px rgba(0,0,0,.22);
  display: grid; place-items: center;
  cursor: pointer; padding: 0;
  transition: transform .18s ease, background .18s ease;
}
.wp3d-hotspot::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.06);
}
/* Pulse ring on a pseudo-element: only transform + opacity animate (composited).
   No will-change — an infinite hint would pin a permanent GPU layer per hotspot,
   which is what bogged down compositing over the large desktop canvas. */
.wp3d-hotspot::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.6); pointer-events: none;
  animation: wp3d-pulse 2.2s ease-out infinite;
}
.wp3d-hotspot:hover, .wp3d-hotspot.wp3d-active { transform: scale(1.18); background: rgba(255,255,255,.5); }
/* Hover/focus label showing the hotspot title (desktop pointers only). */
.wp3d-hotspot-label {
  position: absolute; left: 50%; bottom: calc(100% + 10px); z-index: 6;
  transform: translateX(-50%) translateY(4px);
  white-space: nowrap; padding: 6px 11px; border-radius: 8px;
  background: #fff; color: #2b2620; font-size: 12.5px; font-weight: 600; line-height: 1;
  box-shadow: 0 6px 18px rgba(30,24,16,.18); pointer-events: none;
  opacity: 0; visibility: hidden;
  transition: opacity .16s ease, transform .16s ease, visibility .16s ease;
}
.wp3d-hotspot-label::after {
  content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #fff;
}
.wp3d-hotspot:hover .wp3d-hotspot-label,
.wp3d-hotspot:focus-visible .wp3d-hotspot-label {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
@media (hover: none) { .wp3d-hotspot-label { display: none; } }
@keyframes wp3d-pulse {
  0%   { transform: scale(1);   opacity: .6; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}
/* While the camera is moving, drop the pulse entirely so nothing animates
   over the WebGL canvas — this is the frame the desktop was choking on. */
.wp3d-interacting .wp3d-hotspot::after { animation: none; opacity: 0; }
.wp3d-interacting .wp3d-hotspot { transition: none; }

/* Contact shadow: a soft multiply ellipse painted over the (opaque) realtime
   canvas at the model's base, so the sauna reads as resting on the floor. The
   model rotates in place around its vertical axis, so a fixed footprint holds. */
/* Directional contact shadow at the model's base: light from the top-left, so the
   soft shadow spreads to the bottom-right. Rendered on top of the opaque WebGL
   canvas (a true floor shadow can't be seen at the level camera). Pure CSS —
   reliable across GPUs. Tunable via the custom properties. */
.wp3d-shadow {
  position: absolute;
  left: var(--wp3d-shadow-x, 56%); bottom: var(--wp3d-shadow-y, 6%); z-index: 3;
  width: var(--wp3d-shadow-w, 60%); height: var(--wp3d-shadow-h, 10%);
  transform: translateX(-50%) skewX(-16deg);
  background: radial-gradient(ellipse at 36% 42%,
    rgba(20,16,10,.44) 0%, rgba(20,16,10,.22) 38%, rgba(20,16,10,0) 72%);
  filter: blur(6px);
  pointer-events: none; opacity: 0; transition: opacity .5s ease .1s;
}
.wp3d-ready .wp3d-shadow { opacity: 1; }
/* The real model-shaped THREE shadow replaces the CSS ellipse when it renders. */
.wp3d-rt-shadow .wp3d-shadow { display: none; }

/* Toolbar (ruler / dimensions toggle) — bottom-left, appears once the 3D view is ready. */
.wp3d-toolbar { position: absolute; left: 16px; bottom: 16px; z-index: 4; display: flex; gap: 8px; }
.wp3d-wrap:not(.wp3d-ready) .wp3d-toolbar { display: none; }
.wp3d-tool {
  width: 42px; height: 42px; display: grid; place-items: center;
  border: 1px solid rgba(40,36,30,.12); border-radius: 12px;
  background: rgba(255,255,255,.92); color: #4a4035;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: 0 4px 14px rgba(30,24,16,.12);
  cursor: pointer; transition: background .18s ease, color .18s ease, transform .12s ease;
}
.wp3d-tool:hover { background: #fff; transform: translateY(-1px); }
.wp3d-tool:active { transform: translateY(0); }
.wp3d-tool[aria-pressed="true"] { background: var(--wp3d-green, #4A5135); color: #fff; border-color: transparent; }
.wp3d-tool:focus-visible { outline: 3px solid #2271b1; outline-offset: 2px; }

/* Dimension overlay — 2D dashed guides framing the model at the front view. */
.wp3d-dims {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility .3s ease;
}
.wp3d-dim-on .wp3d-dims { opacity: 1; visibility: visible; }
.wp3d-dim-on .wp3d-hotspot { display: none; }
/* Guides are drawn by JS (projected 3D bounding-box edges). */
.wp3d-dims-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.wp3d-dims-svg line { stroke: rgba(40,36,30,.65); stroke-width: 1.5; stroke-dasharray: 5 4; }
.wp3d-dims-svg line.wp3d-dim-cap { stroke-dasharray: none; stroke-width: 1.5; }
.wp3d-dims-labels { position: absolute; inset: 0; }
.wp3d-dim-label { position: absolute; transform: translate(-50%, -50%); }
.wp3d-dim-label b {
  display: inline-block; white-space: nowrap; padding: 4px 8px; border-radius: 5px;
  background: #2b2620; color: #fff; font-size: 12px; font-weight: 600; line-height: 1;
  box-shadow: 0 3px 10px rgba(20,15,10,.2);
}
.wp3d-card-backdrop {
  position: absolute; inset: 0; z-index: 4;
  background: linear-gradient(90deg, rgba(20,17,13,.05), rgba(20,17,13,.38));
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .28s ease, visibility .28s ease;
}
.wp3d-card-backdrop.wp3d-open { opacity: 1; visibility: visible; pointer-events: auto; }
.wp3d-card {
  position: absolute; right: clamp(18px, 3vw, 36px); top: 50%;
  width: min(360px, calc(100% - 48px)); max-height: calc(100% - 48px);
  overflow: auto; overscroll-behavior: contain;
  background: #fff; border-radius: 18px;
  box-shadow: 0 24px 70px rgba(32,25,17,.24);
  opacity: 0; transform: translate(24px,-50%) scale(.97); pointer-events: none;
  transition: opacity .25s ease, transform .32s cubic-bezier(.2,.8,.2,1); z-index: 5;
}
.wp3d-card.wp3d-open { opacity: 1; transform: translate(0,-50%) scale(1); pointer-events: auto; }
.wp3d-card-handle { display: none; }

.wp3d-card-top { position: relative; padding: 20px 22px 16px; }
.wp3d-card-close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px;
  display: grid; place-items: center; border: 0; border-radius: 50%; background: transparent;
  font-size: 24px; line-height: 1; color: #9a9089; cursor: pointer;
  transition: color .18s ease, background .18s ease;
}
.wp3d-card-close:hover { color: #241f19; background: #f1ede7; }
.wp3d-card-title { margin: 0 34px 8px 0; font-size: 19px; line-height: 1.25; font-weight: 700; letter-spacing: -.01em; color: #2b2620; }
.wp3d-card-body { font-size: 14px; line-height: 1.6; color: #6b6259; }
.wp3d-card-body p { margin: 0 0 10px; }
.wp3d-card-body p:last-child { margin-bottom: 0; }
.wp3d-card-body img { display: block; max-width: 100%; height: auto; border-radius: 8px; margin: 10px 0; }
.wp3d-card-body a { color: #8d5915; font-weight: 650; text-underline-offset: 3px; }
.wp3d-card-body ul, .wp3d-card-body ol { margin: 8px 0; padding-left: 1.25em; }

.wp3d-card-media { position: relative; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; background: #efe9e1; }
.wp3d-card-image { width: 100%; height: 100%; object-fit: cover; display: block; }
.wp3d-card-image[hidden] { display: none; }
.wp3d-card-dots[hidden] { display: none; }
.wp3d-card-media-fallback { position: absolute; inset: 0; background: radial-gradient(120% 120% at 50% 20%, #f0e5d6 0%, #d9c6ab 100%); }
.wp3d-card-dots {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  display: flex; gap: 6px; padding: 6px 10px; border-radius: 999px;
  background: rgba(255,255,255,.92);
  box-shadow: 0 2px 8px rgba(20,15,10,.12);
}
.wp3d-dot { width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%; background: #cabfb1; cursor: pointer; transition: background .18s ease, transform .18s ease; }
.wp3d-dot:hover { transform: scale(1.2); }
.wp3d-dot-on { background: #6b6259; }

.wp3d-card-nav { display: flex; gap: 10px; padding: 14px 16px 16px; }
.wp3d-card-nav[hidden] { display: none; }
.wp3d-nav {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 14px; border: 1px solid #e3ded6; border-radius: 12px;
  background: #fff; color: #3a342d; font: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; transition: background .18s ease, border-color .18s ease, transform .12s ease;
}
.wp3d-nav:hover:not(:disabled) { background: #faf7f2; border-color: #d6cfc4; }
.wp3d-nav:active:not(:disabled) { transform: translateY(1px); }
.wp3d-nav:disabled { opacity: .4; cursor: default; }
.wp3d-nav-ic { display: inline-flex; color: #6b6259; }
.wp3d-nav-ic svg { display: block; }
.wp3d-card-close:focus-visible, .wp3d-hotspot:focus-visible,
.wp3d-nav:focus-visible, .wp3d-dot:focus-visible { outline: 3px solid #2271b1; outline-offset: 2px; }
/* Loading / launch screen — calm neutral card with the green "Explore in 3D" call-to-action. */
.wp3d-poster {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; width: 100%; height: 100%; padding: 28px; box-sizing: border-box;
  color: #6f6a60; text-align: center; font-size: 14px; background: #ecebe6;
}
.wp3d-poster-icon {
  display: grid; place-items: center; gap: 2px;
  width: 92px; height: 92px; margin-bottom: 10px; border-radius: 50%;
  color: #fff; background: var(--wp3d-green, #4A5135);
  box-shadow: 0 16px 34px rgba(74,81,53,.34);
}
.wp3d-poster-icon > span { font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.wp3d-poster strong { color: #33352a; font-size: clamp(20px,2.6vw,26px); line-height: 1.2; font-weight: 700; }
.wp3d-poster-sub { max-width: 320px; line-height: 1.55; color: #7c776d; }
.wp3d-poster-dots {
  position: absolute; width: 96px; height: 60px; opacity: .55; pointer-events: none;
  background-image: radial-gradient(rgba(74,81,53,.30) 1.4px, transparent 1.4px);
  background-size: 12px 12px;
}
.wp3d-poster-dots-tr { top: 22px; right: 22px; }
.wp3d-poster-dots-bl { bottom: 62px; left: 22px; }
.wp3d-poster-foot {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 12px; font-size: 12.5px; color: #8a857b;
  border-top: 1px solid rgba(40,36,30,.07);
}
.wp3d-launch {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 46px; margin-top: 14px; padding: 0 26px; border: 0; border-radius: 8px;
  color: #fff; background: var(--wp3d-green, #4A5135); box-shadow: 0 10px 24px rgba(74,81,53,.28);
  font: inherit; font-weight: 700; font-size: 13.5px; letter-spacing: .04em; text-transform: uppercase;
  cursor: pointer; transition: transform .18s ease, background .18s ease;
}
.wp3d-launch:hover { background: #3c412b; transform: translateY(-1px); }
.wp3d-launch-arrow { font-size: 16px; line-height: 1; }
.wp3d-launch:focus-visible { outline: 3px solid #2271b1; outline-offset: 3px; }
.wp3d-launch:disabled { opacity: .65; cursor: wait; transform: none; }
.wp3d-load-status { min-height: 20px; color: var(--wp3d-green, #4A5135); font-size: 13px; font-weight: 650; }
.wp3d-ready .wp3d-poster { display: none; }
/* The hint pill belongs to the live 3D view; the poster has its own footer. */
.wp3d-wrap:not(.wp3d-ready) .wp3d-hint { display: none; }
.wp3d-spinner { width: 34px; height: 34px; border: 3px solid rgba(74,81,53,.25); border-top-color: var(--wp3d-green, #4A5135); border-radius: 50%; animation: wp3d-spin 1s linear infinite; }
.wp3d-loading .wp3d-poster-icon { animation: wp3d-pulse 1.4s infinite; }
@keyframes wp3d-spin { to { transform: rotate(360deg); } }
.wp3d-hint {
  position: absolute; right: 24px; bottom: 24px; font-size: 13px; color: #8a8177;
  background: rgba(255,255,255,.7); padding: 8px 14px; border-radius: 20px; pointer-events: none;
}
@media (max-width: 520px) {
  .wp3d-wrap {
    /* Portrait phones: switch to a taller aspect so the model is not too short
       in a narrow column. Height still follows aspect-ratio from .wp3d-wrap
       above (no fixed pixel height); min-height is just a safety floor. */
    --wp3d-aspect: 3 / 4;
    min-height: 460px;
    border-radius: 14px;
    /* Let the drop-down card extend below the viewer box. */
    overflow: visible;
  }
  .wp3d-viewer { height: calc(100% - env(safe-area-inset-bottom, 0px)); border-radius: 14px; overflow: hidden; }
  .wp3d-hint { display: none; }
  .wp3d-toolbar { left: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
  .wp3d-card-backdrop { background: rgba(20,17,13,.38); }
  .wp3d-card {
    /* The card emerges from the middle of the viewer and drops out below the
       container, expanding the page down (JS sets the wrap's margin-bottom). No
       inner scroll — the card shows its full height; the model's top half stays
       visible above it. */
    left: 0; right: 0; top: 50%; bottom: auto; width: auto;
    max-height: none; overflow: visible;
    border: 0; border-radius: 16px 16px 16px 16px; padding: 0;
    transform: none; opacity: 0; visibility: hidden;
    box-shadow: 0 -6px 30px rgba(25,20,15,.16);
    transition: opacity .25s ease, visibility .25s ease;
  }
  .wp3d-card.wp3d-open { transform: none; opacity: 1; visibility: visible; }
  /* No dark overlay needed — the card no longer covers the model. */
  .wp3d-card-backdrop, .wp3d-card-backdrop.wp3d-open { background: transparent; }
  .wp3d-card-handle { display: none; }
  .wp3d-card-top { padding: 14px 20px 14px; }
  .wp3d-card-title { font-size: 20px; margin-bottom: 8px; }
  .wp3d-card-body { font-size: 15px; line-height: 1.6; }
  .wp3d-card-media { aspect-ratio: 16 / 10; }
  .wp3d-card-close { top: 10px; right: 12px; width: 36px; height: 36px; }
  .wp3d-card-nav { padding: 12px 16px calc(16px + env(safe-area-inset-bottom, 0px)); }
}
/* Touch devices: larger tap targets for hotspots, and keep the toolbar clear
   of the bottom-sheet card while it is open. */
@media (pointer: coarse) {
  .wp3d-hotspot { width: 30px; height: 30px; }
  .wp3d-hotspot::before { width: 9px; height: 9px; }
}
.wp3d-card-visible .wp3d-toolbar { opacity: 0; pointer-events: none; transition: opacity .2s ease; }
@media (prefers-reduced-motion: reduce) {
  .wp3d-card, .wp3d-card-backdrop, .wp3d-hotspot { transition: none; animation: none; }
  .wp3d-hotspot::after { animation: none; opacity: 0; }
}
