/* =====================================================================
   3D-SCHILDERIJ — herbruikbare component
   ---------------------------------------------------------------------
   Een schilderij als echt 3D-object: een doos van 6 vlakken binnen een
   `preserve-3d`-context. De bijbehorende JS (js/painting3d.js) bouwt de
   HTML en zet alleen twee getallen: --rx en --ry (rotatie in graden).
   Al het andere (draaiing, schaduw, glans) wordt hieronder uit die twee
   getallen afgeleid.

   Assen (CSS): x naar rechts, y naar beneden, z naar de kijker.
     rotateY(+)  → linkerrand komt naar voren → LINKERzijkant zichtbaar
     rotateY(-)  → rechterrand komt naar voren → RECHTERzijkant zichtbaar
     rotateX(-)  → bovenrand komt naar voren  → BOVENkant zichtbaar
     rotateX(+)  → onderrand komt naar voren  → ONDERkant zichtbaar
   ===================================================================== */

.p3d {
  /* --- Afmetingen ---------------------------------------------------- */
  /* Echte diepte van het doek. 40 mm = gallery-wrapped canvas. */
  --depth-mm: 40;
  /* Echte breedte in mm. JS zet dit per werk uit "afmetingen" in works.json. */
  --width-mm: 800;
  /* Verhouding diepte ÷ breedte. Wordt berekend uit de twee waarden hierboven.
     Wil je voor alle werken één vaste dikte? Vervang de calc door een getal,
     bijvoorbeeld:  --dikte: 0.05;  */
  --dikte: calc(var(--depth-mm) / var(--width-mm));
  /* Breedte ÷ hoogte van het schilderij (JS zet dit per werk). */
  --ratio: 0.8;
  /* Breedte op het scherm. De context (bv. de portfoliotegel) overschrijft dit. */
  --w: 300px;
  --h: calc(var(--w) / var(--ratio));
  --d: calc(var(--w) * var(--dikte));

  /* --- Kleuren van de vlakken (placeholders) ------------------------- */
  /* Placeholder: een stille tint per werk (JS zet --face-front uit "kleur" in works.json).
     De zijkanten zijn dezelfde tint, een stap donkerder, zodat het doek rustig blijft. */
  --face-front: #aeb9c0;                                                        /* voorkant, wordt vervangen door de afbeelding */
  --face-left: color-mix(in oklab, var(--face-front) 72%, #1d2733);             /* linkerzijkant  */
  --face-right: color-mix(in oklab, var(--face-front) 58%, #1d2733);            /* rechterzijkant */
  --face-top: color-mix(in oklab, var(--face-front) 84%, #ffffff);              /* bovenkant      */
  --face-bottom: color-mix(in oklab, var(--face-front) 64%, #1d2733);           /* onderkant      */
  --face-back: #d4d9dc;                                                         /* achterkant (ruw linnen) */

  /* --- Actuele rotatie in graden (zonder eenheid; JS zet deze) -------- */
  --rx: 0;
  --ry: 0;

  position: relative;
  display: block;
  width: var(--w);
  height: var(--h);
  /* Perspectief schaalt mee met de schermgrootte van het schilderij,
     zodat het effect op mobiel en desktop hetzelfde aanvoelt. */
  perspective: calc(var(--w) * 4);
  /* Het oogpunt schuift mee met de rotatie (dus met de muis): kijk je van
     links, dan staat je oog ook links van het doek. Daardoor wordt de 40 mm
     diepe zijkant goed zichtbaar, zonder de echte diepte te overdrijven.
     De voorkant ligt in rust in het vlak z = 0 en verschuift dus niet. */
  perspective-origin:
    calc(50% - var(--ry) * 6%)
    calc(50% + var(--rx) * 7%);
  transition: perspective-origin 0.8s cubic-bezier(0.22, 0.8, 0.24, 1);
}

/* De doos zelf. Eerst draaien rond het middelpunt van de doos, daarna een
   halve diepte naar achteren, zodat de voorkant in rust precies in het vlak
   van de muur/tegel ligt. */
.p3d__object {
  position: absolute;
  inset: 0;
  display: block;
  transform-style: preserve-3d;
  transform:
    translateZ(calc(var(--d) * -0.5))
    rotateX(calc(var(--rx) * 1deg))
    rotateY(calc(var(--ry) * 1deg));
  /* Gebruikt bij terugkeren naar rust, toetsenbordfocus en touch.
     Tijdens het volgen van de muis doet JS de easing (zie .is-tracking). */
  transition: transform 0.8s cubic-bezier(0.22, 0.8, 0.24, 1);
}

.p3d__face {
  position: absolute;
  display: block;
  overflow: hidden;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* Licht valt van linksboven: elk zijvlak krijgt een eigen schaduwtint. */
.p3d__face::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* --- Voor- en achterkant: W × H ---------------------------------------- */
.p3d__face--front,
.p3d__face--back {
  inset: 0;
}

.p3d__face--front {
  transform: translateZ(calc(var(--d) * 0.5));
  background-color: var(--face-front);
  /* lege doeken: getint, geprepareerd linnen (verdwijnt achter een foto) */
  background-image: url("../assets/img/linnen.png");
  background-size: 256px;
  background-blend-mode: multiply;
}

.p3d__face--back {
  transform: rotateY(180deg) translateZ(calc(var(--d) * 0.5));
  background: var(--face-back);
}

/* --- Linker- en rechterzijkant: D × H ------------------------------------ */
.p3d__face--left,
.p3d__face--right {
  top: 0;
  height: 100%;
  width: var(--d);
  left: calc(50% - var(--d) * 0.5);
}

.p3d__face--left {
  transform: rotateY(-90deg) translateZ(calc(var(--w) * 0.5));
  background: var(--face-left);
}
.p3d__face--left::after { background: linear-gradient(90deg, rgba(40, 25, 10, 0.16), rgba(40, 25, 10, 0.04)); }

.p3d__face--right {
  transform: rotateY(90deg) translateZ(calc(var(--w) * 0.5));
  background: var(--face-right);
}
.p3d__face--right::after { background: linear-gradient(90deg, rgba(30, 15, 10, 0.06), rgba(30, 15, 10, 0.2)); }

/* --- Boven- en onderkant: W × D ----------------------------------------- */
.p3d__face--top,
.p3d__face--bottom {
  left: 0;
  width: 100%;
  height: var(--d);
  top: calc(50% - var(--d) * 0.5);
}

.p3d__face--top {
  transform: rotateX(90deg) translateZ(calc(var(--h) * 0.5));
  background: var(--face-top);
}
.p3d__face--top::after { background: rgba(255, 255, 255, 0.1); }

.p3d__face--bottom {
  transform: rotateX(-90deg) translateZ(calc(var(--h) * 0.5));
  background: var(--face-bottom);
}
.p3d__face--bottom::after { background: rgba(20, 20, 40, 0.22); }

/* --- Echte afbeelding --------------------------------------------------- */
.p3d__face--front img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Gallery wrap: de zijkanten tonen de rand van de afbeelding, gespiegeld,
   zodat het beeld ononderbroken "om de hoek" doorloopt — zoals bij een
   doek dat om het spieraam is gespannen. Alleen actief als er een afbeelding
   is; zonder afbeelding blijven de gekleurde placeholdervlakken zichtbaar.
   Liever een effen zijkant? Verwijder dit blok en geef de --face-*
   variabelen hierboven de gewenste kleur. */
.p3d__edge {
  position: absolute;
  display: block;
  background-size: cover;
  background-position: center;
}
.p3d__face--left .p3d__edge {
  top: 0; left: 0; width: var(--w); height: 100%;
  transform-origin: calc(var(--d) * 0.5) 50%;
  transform: scaleX(-1);
}
.p3d__face--right .p3d__edge {
  top: 0; left: calc(var(--d) - var(--w)); width: var(--w); height: 100%;
  transform-origin: calc(var(--w) - var(--d) * 0.5) 50%;
  transform: scaleX(-1);
}
.p3d__face--top .p3d__edge {
  left: 0; top: 0; width: 100%; height: var(--h);
  transform-origin: 50% calc(var(--d) * 0.5);
  transform: scaleY(-1);
}
.p3d__face--bottom .p3d__edge {
  left: 0; top: calc(var(--d) - var(--h)); width: 100%; height: var(--h);
  transform-origin: 50% calc(var(--h) - var(--d) * 0.5);
  transform: scaleY(-1);
}

/* --- Geen lijst --------------------------------------------------------- */
/* Het doek hangt zonder lijst: de foto loopt door over de zijkanten (gallery wrap,
   zie .p3d__edge). Alleen een heel zacht randje licht, zodat de rand van het linnen leest. */
.p3d__face--front::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  pointer-events: none;
}

/* --- Glans op de voorkant (volgt de rotatie, dus de muis) ---------------- */
.p3d__face--front::after {
  background: radial-gradient(
    circle at calc(50% - var(--ry) * 2.6%) calc(45% + var(--rx) * 6%),
    rgba(255, 255, 255, 0.28),
    rgba(255, 255, 255, 0) 55%
  );
  mix-blend-mode: soft-light;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.p3d.is-hovered .p3d__face--front::after { opacity: 1; }

/* --- Meebewegende schaduw op de muur ------------------------------------ */
/* Licht komt van boven/voren. Draait het schilderij naar links open
   (--ry > 0), dan schuift de schaduw naar rechts, en omgekeerd. */
.p3d__shadow {
  position: absolute;
  inset: 2% 3% 0;
  display: block;
  background: rgba(58, 46, 34, 0.28);
  border-radius: 2px;
  filter: blur(calc(var(--w) * 0.05));
  transform:
    translate(
      calc(var(--w) * 0.0045 * var(--ry)),
      calc(var(--w) * (0.045 - 0.0045 * var(--rx)))
    );
  transition: transform 0.8s cubic-bezier(0.22, 0.8, 0.24, 1);
  will-change: transform;
}
/* Strakkere contactschaduw direct onder de rand */
.p3d__shadow::before {
  content: "";
  position: absolute;
  inset: 0 -1% 4%;
  background: rgba(40, 30, 22, 0.35);
  filter: blur(calc(var(--w) * 0.012));
  transform: translate(calc(var(--w) * -0.002 * var(--ry)), calc(var(--w) * -0.03));
}

/* Tijdens het volgen van de muis doet JS de easing: CSS-transitions uit. */
.p3d.is-tracking,
.p3d.is-tracking .p3d__object,
.p3d.is-tracking .p3d__shadow {
  transition: none;
}

/* --- Touchapparaten (geen hover): lichte vaste tilt ---------------------- */
@media (hover: none) {
  .p3d {
    --rx: -4;
    --ry: -11;
  }
}

/* --- Minder beweging gewenst: geen animatie ------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .p3d,
  .p3d__object,
  .p3d__shadow,
  .p3d__face--front::after {
    transition: none;
  }
}
