/* ===========================================================================
   fundament.css — sitebrede componenten die niet bij één pagina horen.

   Aangemaakt 2026-08-31 voor het sitebrede bollensysteem. Dit bestand is
   bewust de kiem van de `fundament.css` uit `werk/01-nu/herindeling-thema.md`:
   bij die herindeling verhuizen de tokens, de kop, de voet en de sitebrede
   helft van home.css hierheen, en krijgt dit bestand zijn `@layer fundament`.

   NOG GEEN @layer. Dat kan pas als beslissing B1 uit de herindeling is gemeten
   (het Kadence-ouderstijlblad laadt ongelaagd mee en zou dan van alles winnen).
   Zet hier dus geen laag omheen voordat die meting is gedaan.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   Het bollensysteem.

   Erika wil de zachte, bewegende bollen uit de hero op elke sectie terugzien.
   De regels staan in `werk/01-nu/blobs-sitebreed.md`; hieronder alleen de
   opmaak. De aantallen, de zijde en de looptijd worden bepaald door
   erika_blobs() in functions.php, want dat is rekenwerk en geen opmaak.

   Waarom een eigen naam (.eblob) naast de bestaande .blob: .blob staat in
   home.css met eigen maten per sectie, dertig keer, en die worden niet
   aangeraakt. Dit systeem komt ernaast te staan. Bij de herindeling groeien de
   twee naar elkaar toe; nu twee namen naast elkaar is minder riskant dan dertig
   bestaande regels omschrijven.
--------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   DE UITLOOP ZONDER filter: blur().

   Gemeten op 2026-09-10: `filter: blur(70px)` op de bollen kostte de site zijn
   soepelheid. De homepage scrollde op 18 beelden per seconde; met alleen de blur
   uit was dat 33. Niet omdat de bollen bewegen (met animaties uit maar blur aan
   bleef het 20), maar omdat de browser die vervaagde vlakken bij elk frame
   opnieuw moet uitrekenen.

   Een masker doet optisch hetzelfde en kost vrijwel niets: gemeten 32 fps, dus
   net zoveel winst als de blur helemaal weghalen.

   DE VORM IS GEMETEN EN NIET GESCHAT. `ruw/gereedschap/` heeft er geen script
   voor; die staat in ~/.claude/tools/shot/erika-bolprofiel.js. Die rendert de
   vervaagde bol, leest de pixels langs een straal en geeft de uitloop terug. Wat
   daaruit kwam:

     - de uitloop is ~135px breed buiten de rand, en dat is nagenoeg CONSTANT
       ongeacht de maat van de bol (gemeten 140, 143, 129, 131, 132 bij de vijf
       maten). Bij blur(56px) op mobiel is het ~108px.
     - op de rand van de cirkel zelf staat de helderheid op 43% van de piek,
       precies zoals een vervaagde rand hoort te vervallen.
     - de uitloop is S-vormig en niet lineair; de stops hieronder volgen de
       gemeten waarden.

   DAAROM WORDEN DE DOZEN GROTER. Een blur loopt buiten zijn element door, een
   masker wordt erop afgeknipt. Elke maat krijgt er dus 2 x 135 = 270px bij, en
   elke uitsprong schuift 135px mee zodat het middelpunt op dezelfde plek blijft.
   `--kern` is de straal van de oorspronkelijke cirkel; daar draait het masker om.

   Zonder maskerondersteuning blijft de blur staan; zie het @supports-blok.
--------------------------------------------------------------------------- */
:root{
  --bol-uitloop: 135px;
}

.eblob{
  position:absolute;
  border-radius:50%;
  pointer-events:none;
  z-index:0;
  filter:blur(70px);
}

/* Kan de browser maskeren, dan gaat de blur eruit en komt het masker ervoor in
   de plaats. Kan hij het niet, dan blijft de regel hierboven gewoon staan en
   ziet de bezoeker precies wat hij altijd zag, alleen trager. */
@supports (mask-image: radial-gradient(#000, transparent)) or (-webkit-mask-image: radial-gradient(#000, transparent)) {
  .eblob{
    filter:none;
    -webkit-mask-image:radial-gradient(circle,#000 0,#000 calc(var(--kern) - var(--bol-uitloop)),rgba(0,0,0,.853) calc(var(--kern) - var(--bol-uitloop) * .62),rgba(0,0,0,.664) calc(var(--kern) - var(--bol-uitloop) * .31),rgba(0,0,0,.431) var(--kern),rgba(0,0,0,.224) calc(var(--kern) + var(--bol-uitloop) * .31),rgba(0,0,0,.078) calc(var(--kern) + var(--bol-uitloop) * .62),transparent calc(var(--kern) + var(--bol-uitloop))); mask-image:radial-gradient(circle,#000 0,#000 calc(var(--kern) - var(--bol-uitloop)),rgba(0,0,0,.853) calc(var(--kern) - var(--bol-uitloop) * .62),rgba(0,0,0,.664) calc(var(--kern) - var(--bol-uitloop) * .31),rgba(0,0,0,.431) var(--kern),rgba(0,0,0,.224) calc(var(--kern) + var(--bol-uitloop) * .31),rgba(0,0,0,.078) calc(var(--kern) + var(--bol-uitloop) * .62),transparent calc(var(--kern) + var(--bol-uitloop)));
  }
}

/* Maat volgt de sectiehoogte. De negatieve marge is de helft van de diameter:
   daarmee staat de bol gecentreerd op zijn `top`-percentage zonder transform.
   Transform kan hier niet: de drift-animaties gebruiken die zelf. */
.eblob--xs{ --kern: 90px; width:450px; height:450px; margin-top:-225px }
.eblob--s { --kern:130px; width:530px; height:530px; margin-top:-265px }
.eblob--m { --kern:170px; width:610px; height:610px; margin-top:-305px }
.eblob--l { --kern:210px; width:690px; height:690px; margin-top:-345px }
.eblob--xl{ --kern:260px; width:790px; height:790px; margin-top:-395px }

/* Zijde. De bol hangt deels buiten de sectie; hoe groter, hoe verder. De sectie
   knipt hem af met overflow:hidden, en dat is precies de bedoeling: een bol die
   helemaal binnen het vlak valt leest als een vlek, een die over de rand loopt
   leest als licht dat van buiten komt. */
/* Elke uitsprong is 135px verder naar buiten dan voorheen, want de doos is aan
   die kant 135px gegroeid. Het middelpunt van de bol staat daardoor nog op
   precies dezelfde plek als met de blur. */
.eblob--links.eblob--xs { left:-185px } .eblob--rechts.eblob--xs { right:-185px }
.eblob--links.eblob--s  { left:-205px } .eblob--rechts.eblob--s  { right:-205px }
.eblob--links.eblob--m  { left:-225px } .eblob--rechts.eblob--m  { right:-225px }
.eblob--links.eblob--l  { left:-245px } .eblob--rechts.eblob--l  { right:-245px }
.eblob--links.eblob--xl { left:-275px } .eblob--rechts.eblob--xl { right:-275px }

/* Kleur per band. Dit zijn de tinten die al in het thema staan; er komt geen
   nieuwe kleur bij. Op een lichte band wisselen roze en groen elkaar af, zodat
   twee bollen in dezelfde sectie nooit dezelfde kleur hebben. */
.eblob--roze     { background:#e8c8d8; opacity:.50 }
.eblob--groen    { background:#c5d8c5; opacity:.50 }
.eblob--paars    { background:#5a4170; opacity:.50 }
.eblob--dieppaars{ background:#382650; opacity:.28 }
.eblob--teal     { background:#5a8a80; opacity:.40 }
.eblob--diepteal { background:#1f3f3a; opacity:.35 }

/* Looptijd. Zes waarden die al in het thema voorkwamen, als cyclus. Twee bollen
   die tegelijk in beeld staan lopen daardoor nooit synchroon; dat is wat het
   levend houdt in plaats van mechanisch. De twee keyframes bewegen de andere
   kant op en wisselen elkaar ook af. */
.eblob--t1{ animation:drift  14s ease-in-out infinite }
.eblob--t2{ animation:drift2 18s ease-in-out infinite }
.eblob--t3{ animation:drift  22s ease-in-out infinite }
.eblob--t4{ animation:drift2 24s ease-in-out infinite }
.eblob--t5{ animation:drift  26s ease-in-out infinite }
.eblob--t6{ animation:drift2 28s ease-in-out infinite }

/* Op een telefoon gaat elke maat een stap omlaag: een bol van 520px is daar
   breder dan het scherm en wordt een vlak in plaats van een gloed. De kleur en
   de plaatsing blijven, dus de stemming blijft gelijk en de drukte verdwijnt.
   Zelfde afweging als bij .hero-deco, dat onder 880px helemaal uit gaat. */
@media (max-width:880px){
  /* Mobiel was de blur 56 in plaats van 70; de gemeten uitloop is daar 108px.
     Elke maat krijgt er 2 x 108 = 216px bij en elke uitsprong schuift 108 mee. */
  --bol-uitloop: 108px;
  .eblob{ filter:blur(56px) }
  .eblob--s { --kern: 95px; width:406px; height:406px; margin-top:-203px }
  .eblob--m { --kern:125px; width:466px; height:466px; margin-top:-233px }
  .eblob--l { --kern:150px; width:516px; height:516px; margin-top:-258px }
  .eblob--xl{ --kern:180px; width:576px; height:576px; margin-top:-288px }
  .eblob--xs{ --kern: 70px; width:356px; height:356px; margin-top:-178px }
  .eblob--links.eblob--xs,.eblob--rechts.eblob--xs{ left:auto;right:auto }
  .eblob--links.eblob--xs { left:-153px }
  .eblob--rechts.eblob--xs{ right:-153px }
  .eblob--links.eblob--s,.eblob--links.eblob--m  { left:-168px }
  .eblob--links.eblob--l,.eblob--links.eblob--xl { left:-188px }
  .eblob--rechts.eblob--s,.eblob--rechts.eblob--m  { right:-168px }
  .eblob--rechts.eblob--l,.eblob--rechts.eblob--xl { right:-188px }
  /* Vanaf de derde bol in een hoge sectie: uit. Op een telefoon staat een hoge
     sectie over meerdere schermen verdeeld en zijn drie tot vijf bollen niet
     rijk maar rommelig. */
  .eblob--extra{ display:none }
}

/* Geen will-change: veertig vervaagde vlakken met een eigen compositorlaag kost
   meer geheugen dan de animatie oplevert. De bestaande .blob in home.css heeft
   het wel; dat zijn er tien en die blijven zoals ze zijn. */

@media (prefers-reduced-motion: reduce){
  .eblob{ animation:none }
}

/* De bollen die met inline stijl in de sjablonen staan (over-erika,
   werkgebied). Die hadden geen klasse en hun maten stonden in het
   style-attribuut; ze zijn 2 x 135px gegroeid en hun uitsprong is 135px
   meegeschoven, zodat het middelpunt bleef staan. !important omdat een
   inline filter anders van dit stijlblad wint.

   Ellips en geen cirkel: hun border-radius wisselt tussen 50% en de
   organische var(--blob-1..3), dus het masker moet de doos volgen. */
@supports (mask-image: radial-gradient(#000, transparent)) or (-webkit-mask-image: radial-gradient(#000, transparent)) {
  .bol-zacht{
    filter:none !important;
    -webkit-mask-image: radial-gradient(ellipse closest-side, #000 0,#000 22%,rgba(0,0,0,.853) 38%,rgba(0,0,0,.664) 52%,rgba(0,0,0,.431) 65%,rgba(0,0,0,.224) 78%,rgba(0,0,0,.078) 90%,transparent 100%);
            mask-image: radial-gradient(ellipse closest-side, #000 0,#000 22%,rgba(0,0,0,.853) 38%,rgba(0,0,0,.664) 52%,rgba(0,0,0,.431) 65%,rgba(0,0,0,.224) 78%,rgba(0,0,0,.078) 90%,transparent 100%);
  }
}
