/* ============================================================
   film-veil.css · de vlek (prefix: fv)
   Gedeeld door afspraak-bevestigd.html en ai-training.html.

   Zodra een video speelt, valt er geen waas in één keer over de pagina,
   maar loopt er een vlek vanuit de video naar buiten, zoals olie op water.
   De rand is geen strakke cirkel: drie zachte lobben groeien elk in hun
   eigen tempo en met hun eigen curve, dus de rand vervormt terwijl hij
   uitdijt. De video veert iets naar voren, met een zachte gloed erachter.
   Bij pauze trekt alles terug de video in.

   Gebruik in de HTML:
     data-veil       op de bak om de <video> ([data-reel]); de vlek groeit
                     vanuit het midden daarvan
     data-veil-lift  op het element dat boven de waas uit moet komen, als dat
                     niet de bak zelf is (bijvoorbeeld een podium met een
                     glazen balk erop). Met een media-query als waarde geldt
                     het alleen daar; elders komt de bak zelf omhoog
     data-veil-pop   op de bak: hoe ver de video opveert, standaard 1.035;
                     de afspraakpagina en de intakepagina gebruiken 1.06.
                     Nooit groter dan het scherm toelaat, zie film-veil.js
     data-veil-manual op een bak zonder video: die stuurt de vlek zelf aan
                     met de gebeurtenissen veil:open en veil:close, en krijgt
                     veil:closed terug zodra hij dicht is (ook na Escape of
                     een klik ernaast). Zo doet het intakeformulier het.
   film-veil.js maakt de waaslaag zelf aan.

   Mechaniek: --fv-s1..3 zijn geregistreerde lengtes (@property), dus ze
   laten zich animeren. Ze zijn de straal van drie radial-gradients in het
   masker van de waaslaag. film-veil.js zet het midden van de video
   (--fv-cx/-cy), zijn maat (--fv-w/-h) en hoe ver de vlek moet reiken
   (--fv-reach), en daarna html.fv-focus.

   Het opveren: film-veil.js animeert --fv-pop (1 → data-veil-pop) op het
   opgetilde element. De pagina kiest zelf waar die in `scale` gaat, want sommige
   podia hebben al een eigen scale (de meegroeiende opname op de
   trainingspagina), en een transitie op het element zelf zou vechten met
   die van .reveal.

   Lagen: de waas ligt boven de navigatie (z 100) zodat ook die wegzakt,
   onder de cookiemelding (z 1200). Het opgetilde element daarboven.
   ============================================================ */
@property --fv-s1 { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --fv-s2 { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --fv-s3 { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --fv-pop { syntax: "<number>"; inherits: true; initial-value: 1; }

.fv {
  --fv-cx: 50vw;
  --fv-cy: 50vh;
  --fv-w: 0px;
  --fv-h: 0px;
  --fv-reach: 150vmax;
  --fv-s1: 0px;
  --fv-s2: 0px;
  --fv-s3: 0px;
  position: fixed;
  inset: 0;
  z-index: 150;
  visibility: hidden;
  pointer-events: none;
  /* terugtrekken: vlot en gelijkmatig, de lobben iets eerder dan de kern */
  transition: --fv-s1 0.95s cubic-bezier(0.4, 0, 0.2, 1),
    --fv-s2 0.8s cubic-bezier(0.4, 0, 0.2, 1),
    --fv-s3 0.85s cubic-bezier(0.4, 0, 0.2, 1);
}
/* De maskers houden bij straal nul drie puntjes van 1px over. Verberg de
   hele laag in rust; fv-on blijft aan tot de terugtrekbeweging klaar is. */
html.fv-on .fv {
  visibility: visible;
}
/* uitlopen: de kern zet rustig in en loopt lang uit, zodat je de rand over
   het scherm ziet stromen. De ene lob schiet vooruit, de andere kruipt
   eerst en haalt dan in. Samen vloeibaar. */
html.fv-focus .fv {
  --fv-s1: var(--fv-reach);
  --fv-s2: var(--fv-reach);
  --fv-s3: var(--fv-reach);
  pointer-events: auto; /* een klik naast de video pauzeert, zie film-veil.js */
  transition: --fv-s1 2.8s cubic-bezier(0.3, 0.1, 0.2, 1),
    --fv-s2 2.2s cubic-bezier(0.25, 0.6, 0.3, 1) 0.05s,
    --fv-s3 2.6s cubic-bezier(0.55, 0, 0.2, 1) 0.12s;
}

/* Elke lob is dicht tot ongeveer de helft van zijn straal en loopt daarna
   zacht uit: de rand is een verloop van scherp naar wazig, geen lijn.
   max(…, 1px) houdt de gradients geldig zolang de straal nog nul is. */
.fv__blur {
  --fv-lob1: radial-gradient(circle max(var(--fv-s1), 1px) at var(--fv-cx) var(--fv-cy),
      #000 55%, transparent 100%);
  --fv-lob2: radial-gradient(
      ellipse max(calc(var(--fv-s2) * 1.3), 1px) max(calc(var(--fv-s2) * 0.72), 1px)
        at calc(var(--fv-cx) + var(--fv-w) * 0.22) calc(var(--fv-cy) - var(--fv-h) * 0.12),
      #000 50%, transparent 100%);
  --fv-lob3: radial-gradient(
      ellipse max(calc(var(--fv-s3) * 0.8), 1px) max(calc(var(--fv-s3) * 1.25), 1px)
        at calc(var(--fv-cx) - var(--fv-w) * 0.24) calc(var(--fv-cy) + var(--fv-h) * 0.16),
      #000 50%, transparent 100%);
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--bg) 62%, transparent);
  -webkit-mask-image: var(--fv-lob1), var(--fv-lob2), var(--fv-lob3);
  mask-image: var(--fv-lob1), var(--fv-lob2), var(--fv-lob3);
}
/* De waas zelf staat alleen aan zolang de vlek leeft (html.fv-on): een
   onzichtbare backdrop-filter kost ook rekenwerk. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  html.fv-on .fv__blur {
    -webkit-backdrop-filter: blur(14px) saturate(70%);
    backdrop-filter: blur(14px) saturate(70%);
  }
}

/* De gloed achter de video: een onzichtbaar vlak op de plek van de video,
   alleen zijn schaduw telt. Hij ligt in de waaslaag, dus onder het
   opgetilde element, en hoeft zo niet in de transities van de pagina.
   Hij groeit mee tot de maat van de vergrote video (--fv-to), met dezelfde
   zachte veer als de video bij een grote vergroting. Via breedte en hoogte
   (--fv-gs), niet via scale: een geschaalde laag knipt de ruime schaduw af
   aan zijn eigen randen, dan staat er een lichte rechthoek onder de video. */
@property --fv-gs { syntax: "<number>"; inherits: false; initial-value: 1; }
.fv__glow {
  --fv-gs: 1;
  position: absolute;
  left: calc(var(--fv-cx) - var(--fv-w) * var(--fv-gs) / 2);
  top: calc(var(--fv-cy) - var(--fv-h) * var(--fv-gs) / 2);
  width: calc(var(--fv-w) * var(--fv-gs));
  height: calc(var(--fv-h) * var(--fv-gs));
  border-radius: var(--r-lg);
  box-shadow: 0 40px 140px -40px var(--accent-glow);
  opacity: 0;
  transition: opacity 0.9s var(--ease-out), --fv-gs 0.85s var(--ease-out);
}
html.fv-focus .fv__glow {
  --fv-gs: var(--fv-to, 1);
  opacity: 1;
  transition: opacity 1.2s var(--ease-out), --fv-gs 1.1s cubic-bezier(0.3, 1.25, 0.5, 1);
}

/* Boven de waas zolang de vlek leeft (fv-on), dus ook terwijl die na een
   pauze nog terugtrekt; anders zakt de video er halverwege onder.
   film-veil.js zet .is-veil-lift alleen op het element dat nu speelt. */
html.fv-on .is-veil-lift {
  position: relative;
  z-index: 160;
}

/* Minder beweging gevraagd, of een browser zonder @property (dan springt
   de straal in één keer): geen vlek, gewoon een rustige overvloeier. */
html[data-motion="off"] .fv__blur,
html.fv-flat .fv__blur {
  -webkit-mask-image: none;
  mask-image: none;
  opacity: 0;
  transition: opacity 0.4s ease;
}
html[data-motion="off"].fv-focus .fv__blur,
html.fv-flat.fv-focus .fv__blur {
  opacity: 1;
}
