/* DE VORMTAAL — de vorm van een doos, als keuze.

   Kleur en letter waren al configuratie. Wat overbleef was groter: de VORM. De
   golfsnede tussen secties, de fotolijstjes anderhalve graad scheef, de
   geschreven stem in de type, het onthaal bij aankomst, de zachte diepte onder
   elke kaart -- dat was de ontwerptaal van één praktijk, en die reisde mee naar
   elke koper. Twee praktijken naast elkaar zagen hetzelfde systeem in twee
   kleuren.

   De eis (eigenaar, 2026-08-29): twee dozen naast elkaar moeten er anders
   uitzien, en alleen de BEDIENING mag bekend voorkomen.

   Daarom: benoemde keuzes. Het product levert elke schakelaar op zijn vlakste
   stand -- rechte secties, platte vlakken, rechte hoeken, rechte kaders, één
   letter, geen beweging. Dat is hoe een doos eruitziet die niemand heeft
   ingericht, en dat hoort saai te zijn. Een praktijkpakket kiest
   (website/vormtaal.py); de keuzes landen als data-vorm-* op <html>.

   Laadt NA site-tokens.css: de schakelaars hebben dezelfde specificiteit als
   :root, dus ze moeten later staan om te winnen. */

/* ── de hoek: hoe een vlak eindigt ─────────────────────────────────────── */
:root                      { --radius: 0px;     --radius-lg: 0px; }
[data-vorm-hoek="zacht"]   { --radius: 0.35rem; --radius-lg: 0.6rem; }
[data-vorm-hoek="rond"]    { --radius: 0.5rem;  --radius-lg: 1.1rem; }

/* ── het vlak: hoe iets op de pagina ligt ──────────────────────────────────
   DIEPTE KOMT UIT LICHT, NIET UIT SCHADUW.

   Er waren twee schaduwen, allebei recht naar beneden, en bijna alles gebruikte
   er een van. Daarmee droeg diepte geen betekenis: een kaart die op de pagina
   ligt en een lade die eroverheen zweeft kregen hetzelfde randje donker.

   Nu een ladder van vier hoogtes met één natuurwet eronder:

   * LICHT KOMT VAN LINKSBOVEN. Overal, altijd, ook in het glas van richting 1.
     Dus valt de schaduw naar rechtsonder, en licht de bovenrand op. Die
     lichtrand is het halve verhaal -- een vlak zonder opgelichte bovenkant leest
     als een gat in de pagina, niet als iets dat erboven ligt.
   * ELKE HOOGTE IS TWEE SCHADUWEN. Een korte, donkere contactschaduw vlak onder
     het vlak, en een wijde, lichte omgevingsschaduw eromheen. Eén schaduw voor
     allebei is de reden dat platte ontwerpen "geplakt" ogen: de contactschaduw
     zegt waar iets de pagina raakt, de omgevingsschaduw hoe hoog het zweeft.
   * HOGER IS ZACHTER EN VERDER. De contactschaduw verdwijnt naarmate iets
     loskomt; de omgevingsschaduw wordt groter en vager. Dat is wat een lade over
     een pagina laat zweven in plaats van erop te liggen.

   De kleuren zijn haar schaduwtokens en een lichtrand uit wit, dus dit blijft
   werken in elk palet. Op de vlakke stand (`plat`) staat de hele ladder op
   `none`: een doos die niemand heeft ingericht heeft geen diepte, en dat hoort
   saai te zijn. */
:root {
  --shadow-soft: none; --shadow-card: none;
  --hoogte-1: none; --hoogte-2: none; --hoogte-3: none; --hoogte-4: none;
  --hoogte-4-rechtsvast: none;
  --lichtrand: none;
}
[data-vorm-vlak="zacht"] {
  /* De opgelichte rand hoort BIJ de hoogte, niet ernaast: hoe hoger iets ligt,
     hoe meer licht de bovenkant vangt. Door hem in de ladder te zetten krijgt
     elk onderdeel dat al `--shadow-card` gebruikte de lichtrand gratis, zonder
     dat er ook maar één selector bij komt. */
  --lichtrand: color-mix(in srgb, var(--white) 58%, transparent);
  --lichtrand-hoog: color-mix(in srgb, var(--white) 78%, transparent);

  /* Elke trede is TWEE schaduwen met verschillende taken, en dat onderscheid is
     de hele truc:

       CONTACT -- klein, kort, en het enige deel dat een RICHTING heeft. Het
       licht komt van linksboven, dus hij valt een paar pixels naar rechtsonder.
       Hij zegt waar het vlak de pagina raakt.

       OMGEVING -- groot, vaag, en met opzet ZONDER richting (nul verschuiving,
       negatieve spread). Hij zegt hoe hoog iets zweeft.

     Dat de omgevingsschaduw geen kant op wijst is geen slordigheid maar de
     reparatie van een echte fout: met een gerichte omgevingsschaduw viel die van
     de lade rechts van het scherm af -- fysiek correct en visueel niets. Een
     paneel tegen een schermrand heeft een schaduw nodig die alle kanten op gaat,
     anders zweeft het nergens. */

  /* 1 — ligt op de pagina. Bijna alleen contact. */
  --hoogte-1:
    inset 0 1px 0 var(--lichtrand),
    0 1px 1px var(--schaduw-kleur-zacht),
    0 2px 6px -2px var(--schaduw-kleur-zacht);
  /* 2 — komt omhoog: een kaart die iets is. */
  --hoogte-2:
    inset 0 1px 0 var(--lichtrand),
    1px 2px 2px -1px var(--schaduw-kleur-zacht),
    0 8px 20px -8px var(--schaduw-kleur);
  /* 3 — zweeft over de inhoud: een balk, een paneel. */
  --hoogte-3:
    inset 0 1px 0 var(--lichtrand-hoog),
    1px 3px 4px -2px var(--schaduw-kleur-zacht),
    0 16px 36px -12px var(--schaduw-kleur);
  /* 4 — zweeft over alles: een lade, een venster. */
  --hoogte-4:
    inset 0 1px 0 var(--lichtrand-hoog),
    2px 5px 8px -3px var(--schaduw-kleur-zacht),
    0 32px 72px -20px var(--schaduw-kleur);
  /* Een paneel dat tegen de RECHTERrand hangt vangt het licht op zijn linkerkant
     -- daar is zijn bovenkant, ruimtelijk gezien. Zijn eigen bovenrand ligt
     buiten beeld, dus een lichtlijn daar is een lijn die niemand ziet. */
  --hoogte-4-rechtsvast:
    inset 1px 0 0 var(--lichtrand-hoog),
    -2px 5px 8px -3px var(--schaduw-kleur-zacht),
    0 32px 72px -20px var(--schaduw-kleur);

  /* Wat er al was, nu op de ladder -- elk `var(--shadow-soft)` in de sjablonen
     verhuist zo mee zonder dat er een selector bij komt. */
  --shadow-soft: var(--hoogte-1);
  --shadow-card: var(--hoogte-2);
}

/* De twee bovenste treden hebben geen bestaand token om op mee te liften, dus
   die worden hier toegewezen. Het zijn precies de dingen die ergens ÓVER heen
   liggen -- en dat was nou juist wat je aan de oude schaduwen niet kon zien. */
[data-vorm-vlak="zacht"] body.app .cal-daypanel,
[data-vorm-vlak="zacht"] body.scrolled .site-nav__inner { box-shadow: var(--hoogte-3); }
/* De uitgelichte balk op het ledenscherm had een eigen, richtingloze schaduw.
   Hij is het grootste opgetilde vlak van de app, dus hij hoort op de ladder. */
[data-vorm-vlak="zacht"] body.app .dash-feat { box-shadow: var(--hoogte-2); }
[data-vorm-vlak="zacht"] .install-gate__card { box-shadow: var(--hoogte-4); }
[data-vorm-vlak="zacht"] body.app .site-nav__drawer { box-shadow: var(--hoogte-4-rechtsvast); }
/* Glas: een laag die op de pagina lijkt te zweven -- doorschijnend, met een
   fijne lichtrand erboven en diepte eronder. Vraagt backdrop-filter; waar dat
   ontbreekt blijft de kaart gewoon een kaart. */
[data-vorm-vlak="glas"] {
  --shadow-soft: 0 1px 2px var(--schaduw-kleur-zacht), 0 8px 24px -8px var(--schaduw-kleur);
  --shadow-card: 0 1px 1px var(--schaduw-kleur-zacht), 0 18px 48px -16px var(--schaduw-kleur);
}

/* ── de stem: hoe de typografie klinkt ─────────────────────────────────────
   De LETTERS waren al configuratie -- welk lettertype, dat komt uit haar
   pakket. Wat niet configuratie was, is de TOON: hoe groot een kop staat ten
   opzichte van de tekst eronder, hoeveel lucht ertussen zit, hoe strak de
   letters op elkaar staan. Die getallen stonden vast in de code, en het waren de
   getallen van één praktijk.

   Dat is waar twee praktijken echt uit elkaar gaan lopen. Kleur zie je meteen;
   toon voel je een pagina lang. Een praktijk die rust uitstraalt heeft weinig
   verschil tussen kop en tekst en veel lucht; een praktijk die stellig wil
   klinken heeft groot verschil en strakke regels. Zelfde letters, andere stem.

   Vier standen, elk één samenhangende set. De maten worden AFGELEID uit een
   basis en een verhouding -- niet los ingetikt -- want dat is wat een schaal
   een schaal maakt: h3 is de basis maal de verhouding, h2 die maal de
   verhouding, h1 nog een keer. Verander de verhouding en de hele pagina
   verschuift mee, in de juiste onderlinge maat.

   `neutraal` is de vlakke stand: weinig verschil, geen spatiëring, rechte
   regelafstand. Zo ziet een doos eruit die niemand heeft ingericht. */
:root {
  /* TWEE schalen, geen één. Een koptekst in een hero en een titel op een kaart
     zijn verschillende instrumenten: het eerste roept, het tweede benoemt. Met
     één verhouding over alle vier de trappen moet je kiezen tussen een kleine
     hero of enorme kaarttitels -- de oude, vaste maten waren precies daarom geen
     schaal: van h2 naar h3 zat een sprong van 1,93 en van h1 naar h2 van 1,33.
     Nu een DISPLAY-schaal (h1, h2) en een TEKST-schaal (h3, h4), en de stem zet
     ze allebei. */
  --kop-basis: clamp(1.7rem, 3vw, 2.2rem);
  --tekst-basis: 1rem;
  --schaal: 1.2;
  --schaal-tekst: 1.15;
  --kop-lijn: 1.25;
  --kop-spatie: 0;
  --kop-marge: 0.6em;
  --tekst-lijn: 1.6;
  --label-spatie: 0.06em;
}
/* Weinig verschil, veel lucht. Voor een praktijk die rust wil uitstralen. */
[data-vorm-stem="rustig"] {
  --kop-basis: clamp(1.7rem, 3.1vw, 2.3rem);
  --tekst-basis: 1.02rem;
  --schaal: 1.16;
  --schaal-tekst: 1.12;
  --kop-lijn: 1.3;
  --kop-spatie: 0.01em;
  --kop-marge: 0.75em;
  --tekst-lijn: 1.75;
  --label-spatie: 0.1em;
}
/* Groot verschil tussen kop en tekst, ruime regels. Uitgesproken, warm. */
[data-vorm-stem="warm"] {
  --kop-basis: clamp(1.9rem, 3.66vw, 2.7rem);
  --tekst-basis: 1.05rem;
  --schaal: 1.33;
  --schaal-tekst: 1.33;
  --kop-lijn: 1.15;
  --kop-spatie: 0.005em;
  --kop-marge: 0.6em;
  --tekst-lijn: 1.65;
  --label-spatie: 0.08em;
}
/* Strakke regels, koppen dicht op elkaar, labels wijd uit elkaar. Zakelijk. */
[data-vorm-stem="strak"] {
  --kop-basis: clamp(2rem, 3.9vw, 2.9rem);
  --tekst-basis: 1rem;
  --schaal: 1.26;
  --schaal-tekst: 1.25;
  --kop-lijn: 1.05;
  --kop-spatie: -0.015em;
  --kop-marge: 0.5em;
  --tekst-lijn: 1.5;
  --label-spatie: 0.16em;
}

/* De vier trappen, afgeleid in plaats van ingetikt. */
:root {
  --kop-1: calc(var(--kop-basis) * var(--schaal));
  --kop-2: var(--kop-basis);
  --kop-3: calc(var(--tekst-basis) * var(--schaal-tekst));
  --kop-4: var(--tekst-basis);
}

/* ── de beweging: één natuurwet ────────────────────────────────────────────
   Er stonden veertien verschillende duren in dit systeem (0,15 · 0,16 · 0,18 ·
   0,2 · 0,22 · 0,25 · 0,3 · 0,35 · 0,45 · 0,7 seconde, en 280ms) en vier
   verschillende curves. Niemand had die gekozen; ze waren ontstaan. Het
   resultaat is dat twee dingen die tegelijk gebeuren nét niet samen bewegen, en
   dat voelt onaf zonder dat je kunt aanwijzen waarom.

   Twee snelheden, en meer niet:

     SNEL -- iets reageert onder je vinger. Kleur, rand, een knop die indrukt.
     Hier mag je geen beweging zien; je mag alleen merken dat het niet hakkelt.

     TRAAG -- iets legt een AFSTAND af. Een paneel dat opent, een kaart die
     omslaat, een lade die binnenschuift. Hier is de beweging de uitleg: ze
     vertelt waar het vandaan kwam.

   Eén curve voor allebei: sterk afremmend. Dat is wat "duur" leest -- iets komt
   binnen met vaart en legt zich neer. En één tegenhanger voor wat WEGGAAT:
   versnellend. Dingen die vertrekken hoeven niet netjes te landen, en een exit
   die even lang duurt als een entree voelt traag.

   De omslag van een kaart is de enige uitzondering, en hij is afgeleid in plaats
   van verzonnen: een halve draai in de ruimte heeft meer tijd nodig dan een
   paneel dat verschuift. Keer traag, geen los getal.

   Wie beweging heeft uitgezet krijgt overal nul. Dat staat hier één keer, in
   plaats van bij elke regel opnieuw. */
:root {
  --curve: cubic-bezier(0.22, 1, 0.36, 1);
  --curve-uit: cubic-bezier(0.4, 0, 1, 1);
  --beweging-snel: 140ms;
  --beweging-traag: 280ms;
  --beweging-omslag: calc(var(--beweging-traag) * 1.6);
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --beweging-snel: 0ms;
    --beweging-traag: 0ms;
    --beweging-omslag: 0ms;
  }
}

/* ── het kader: hoe een foto hangt ─────────────────────────────────────── */
:root                       { --tilt-a: 0deg; --tilt-b: 0deg; --tilt-c: 0deg; --tilt-lift: 0px; }
[data-vorm-kader="gedraaid"] {
  --tilt-a: -1.6deg; --tilt-b: 1.8deg; --tilt-c: -0.8deg;
  --tilt-lift: clamp(10px, 2.4vw, 30px);
}

/* ── het accent: of er een tweede, geschreven stem in de type zit ──────── */
:root                        { --font-accent: var(--font-display); }
[data-vorm-accent="schrift"] { --font-accent: var(--font-script); }

/* ── De golf-band: sectie met organische randen, geen rechte lijn. Een keuze
   in het vormpakket (data-vorm-band="golf"), niet de vorm van het product. ── */
[data-vorm-band="golf"] .section.section--band {
  
  /* Wave bite in FIXED pixels (owner-bug 2026-07-06: the old single mask
     scaled with section height — 5% of a tall mobile section = 200px+ and
     the wave ate the bottom card row). Three mask layers union: top wave
     strip + solid middle + bottom wave strip; the bite is --band-bite on
     every viewport, and the padding buys it out exactly. */
  --band-bite: 90px;
  -webkit-mask-image:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0,50 C12,15 22,75 34,55 C48,30 58,80 70,55 C82,30 92,70 100,40 L100,101 L0,101 Z" fill="black"/></svg>'),
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0,-1 L100,-1 L100,55 C88,90 76,35 64,60 C50,85 40,30 28,55 C16,80 8,35 0,65 Z" fill="black"/></svg>'),
    linear-gradient(var(--black), var(--black));
  mask-image:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0,50 C12,15 22,75 34,55 C48,30 58,80 70,55 C82,30 92,70 100,40 L100,101 L0,101 Z" fill="black"/></svg>'),
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0,-1 L100,-1 L100,55 C88,90 76,35 64,60 C50,85 40,30 28,55 C16,80 8,35 0,65 Z" fill="black"/></svg>'),
    linear-gradient(var(--black), var(--black));
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% var(--band-bite), 100% var(--band-bite), 100% calc(100% - var(--band-bite) * 2 + 4px);
  mask-size: 100% var(--band-bite), 100% var(--band-bite), 100% calc(100% - var(--band-bite) * 2 + 4px);
  -webkit-mask-position: top, bottom, 0 calc(var(--band-bite) - 2px);
  mask-position: top, bottom, 0 calc(var(--band-bite) - 2px);
  padding-top: calc(var(--band-bite) + 1.75rem);
  padding-bottom: calc(var(--band-bite) + 2.25rem);
}

/* ── De schuine band: een diagonale snee. ── */
[data-vorm-band="schuin"] .section.section--band {
  --band-bite: 56px;
  -webkit-clip-path: polygon(0 var(--band-bite), 100% 0, 100% calc(100% - var(--band-bite)), 0 100%);
  clip-path: polygon(0 var(--band-bite), 100% 0, 100% calc(100% - var(--band-bite)), 0 100%);
  padding-top: calc(var(--band-bite) + 1.75rem);
  padding-bottom: calc(var(--band-bite) + 2.25rem);
}

/* ── De boog: één rustige kromming boven en onder. ── */
[data-vorm-band="boog"] .section.section--band {
  --band-bite: 64px;
  -webkit-mask-image:
    radial-gradient(140% var(--band-bite) at 50% 100%, var(--black) 99%, transparent 100%),
    radial-gradient(140% var(--band-bite) at 50% 0, var(--black) 99%, transparent 100%),
    linear-gradient(var(--black), var(--black));
  mask-image:
    radial-gradient(140% var(--band-bite) at 50% 100%, var(--black) 99%, transparent 100%),
    radial-gradient(140% var(--band-bite) at 50% 0, var(--black) 99%, transparent 100%),
    linear-gradient(var(--black), var(--black));
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% var(--band-bite), 100% var(--band-bite), 100% calc(100% - var(--band-bite) * 2 + 4px);
  mask-size: 100% var(--band-bite), 100% var(--band-bite), 100% calc(100% - var(--band-bite) * 2 + 4px);
  -webkit-mask-position: top, bottom, 0 calc(var(--band-bite) - 2px);
  mask-position: top, bottom, 0 calc(var(--band-bite) - 2px);
  padding-top: calc(var(--band-bite) + 1.75rem);
  padding-bottom: calc(var(--band-bite) + 2.25rem);
}
