/* Martini Vastgoed — motion layer
   Zie MOTION-PLAN.md. Eén idee: alles op deze pagina is opgehangen, het komt
   scheef binnen en zakt recht.

   Dit bestand bezit twee dingen. De from-states, zodat er nooit iets kan
   flitsen voordat JS er is. En de vormen die JS niet kan bezitten zonder ze
   elke frame te herschrijven. Alle bewegende getallen staan in motion.js. */

/* --rv is het enige getal in de clip. Als getal en niet als string, want een
   clip-path-string onder scrub blijft op zijn eindwaarde staan (pitfall 45).
   --dy en --vel zijn de diepte-as: die rijdt op de losse translate-property en
   niet op transform, zodat de gescrubde parallax en de reveal-y van GSAP niet
   dezelfde property claimen (wet 44, één eigenaar per property). */
@property --hy    { syntax: '<length>';     inherits: false; initial-value: 0px; }
@property --hr    { syntax: '<angle>';      inherits: false; initial-value: 0deg; }
@property --dy    { syntax: '<length>';     inherits: false; initial-value: 0px; }
@property --vel   { syntax: '<length>';     inherits: true;  initial-value: 0px; }
@property --dspeed{ syntax: '<number>';     inherits: false; initial-value: 0; }

/* ---------------------------------------------------------------------------
   PARK
   De rust-toestand van alles wat motion.js overneemt.

   Staat hier en niet in JS, want een from-state die pas bestaat als een script
   draait is een flits. motion.js parkeert dezelfde elementen daarna nog een
   keer inline met gsap.set en wisselt .has-motion om naar .motion-ready. Wat
   JS niet heeft overgenomen wordt op dat moment gewoon zichtbaar, dus een init
   die halverwege faalt kan nooit een blok onzichtbaar achterlaten. De
   head-snippet haalt .has-motion er sowieso af als motion.js zich binnen 2,5s
   niet meldt.

   Let op de reikwijdte: deze pagina wordt door Babel in de browser vertaald,
   dus bij eerste paint bestaat er nog geen enkele sectie. Parken op een
   selector die pas later gevuld wordt is precies goed, parken op html of body
   zou de hele pagina laten wachten op een script dat ook kan uitvallen. */
.has-motion [data-hang],
.has-motion [data-settle] { opacity: 0; }

/* ---------------------------------------------------------------------------
   OPHANGEN
   --------------------------------------------------------------------------- */

/* De reis en de scheefstand van een opgehangen blok. Ze staan op de losse
   translate- en rotate-properties, NIET op transform, en dat is draagkrachtig:
   elke kaart, knop en chip in dit ontwerp heeft een hover die transform
   schrijft (translate(-3px,-3px) rotate(-0.5deg)). Zou de entree transform
   pakken, dan springt een kaart zodra je er halverwege de reveal overheen
   gaat. Nu heeft GSAP --hy en --hr, en houdt de hover transform (wet 44).

   Geen clip-path op deze blokken. Ze hebben een harde slagschaduw buiten hun
   eigen doos en clip-path knipt die er zonder pardon af; de reveal zou de
   schaduw laten verdwijnen en dat is precies het kenmerk van dit ontwerp. */
[data-hang], [data-settle] {
  translate: 0 var(--hy, 0px);
  rotate: var(--hr, 0deg);
}

/* Regelmasker voor koppen. De kop knipt, de regel erbinnen rijdt omhoog: twee
   nodes, twee snelheden, en geen property met twee eigenaren. Dit is waar de
   richting van de pagina vandaan komt: alles komt van onderen (wet 3). */
[data-mask] {
  display: block;
  overflow: clip;
  overflow-clip-margin: 0.08em;
}
[data-ln] { display: block; will-change: transform; }

/* Diepte. --vel is de geëasede scrollsnelheid, staat op :root en wordt één
   keer per frame geschreven, door de enige loop op de pagina. */
[data-depth] { translate: 0 calc(var(--dy) + var(--vel) * var(--dspeed)); }

/* De fotoput in een kaart: de put knipt, de foto schaalt. */
[data-well] { overflow: hidden; }
[data-well] > img { will-change: transform; }

/* ---------------------------------------------------------------------------
   DE FILM
   De doos stond op width, height en top per frame. Nu staat hij op eindformaat
   en wordt hij geschaald; de video schaalt tegen zodat het beeld niet uitrekt,
   en de lijst plus de roze slagschaduw zijn een eigen laag die dooft in plaats
   van naar nul te krimpen. Een rand die krimpt is layout, een laag die dooft
   is paint.
   --------------------------------------------------------------------------- */
.mv-takeover #film-box {
  position: absolute;
  inset: 0;
  left: 0; right: 0; top: 0; bottom: 0;
  width: auto; height: auto;
  border: 0;
  box-shadow: none;
  transform-origin: 50% 50%;
  will-change: transform;
}
.mv-takeover #film-box > video { will-change: transform; transform-origin: 50% 50%; }

/* De lijst zelf. inset ring in plaats van border, want een border zit in de
   doos en verandert dus de binnenmaat; een inset ring is alleen verf. */
[data-filmframe] { display: none; }
.mv-takeover [data-filmframe] {
  display: block;
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  box-shadow: inset 0 0 0 3px var(--mv-ink), 14px 14px 0 var(--mv-pink);
}
.mv-takeover [data-filmcap] { will-change: transform, opacity; }

/* ---------------------------------------------------------------------------
   WAT DE OVERNAME UITZET
   --------------------------------------------------------------------------- */

/* De wrapper van de toren heeft een CSS-transitie op transform staan, terwijl
   er ook een muis-parallax op schrijft die zelf al lerpt. Dubbel gedempt is
   ongeveer 400ms achterstand op de muis, en dat valt met een smooth-scrolllaag
   eronder pas echt op. De transitie gaat eruit, de demping blijft in JS. */
.mv-takeover .mvp-tower-wrap { transition: none !important; }

/* .mvp-pre was een eigen mini scroll-engine voor precies drie secties. Die is
   vervangen, dus hij mag niets meer verbergen. */
.mv-takeover .mvp-pre { opacity: 1 !important; transition: none !important; }

/* .mvp-spine zet will-change: transform en haalt het nooit meer weg: een
   gepromote laag voor de hele sessie. Onder de overname doet motion.js het
   werk en mag de laag weg. */
.mv-takeover .mvp-spine { will-change: auto; }

/* ---------------------------------------------------------------------------
   STATE
   --------------------------------------------------------------------------- */

/* Wet 5: sluiten gaat sneller dan openen. Openen is een aanbod, sluiten is een
   besluit dat de lezer al genomen heeft. */
.mv-takeover .mvp-chip,
.mv-takeover .mvpf-link,
.mv-takeover .mvp-sound { transition-duration: .2s; }
.mv-takeover .mvp-chip:active,
.mv-takeover .mvp-sound:active { transition-duration: .08s; }

/* ---------------------------------------------------------------------------
   REDUCED MOTION
   De poort staat om de hele init: met reduce wordt MV_TAKEOVER nooit gezet en
   draaien de componenten hun eigen reduced-motion-tak. Dit blok is het vangnet
   voor het geval een from-state toch ergens blijft hangen.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .has-motion [data-hang],
  .has-motion [data-settle] { opacity: 1; }
  [data-hang], [data-settle] { translate: none; rotate: none; }
  [data-depth] { translate: none; }
  [data-ln] { transform: none !important; }
}
