/* De open opmaak van /ai-oplossingen en de detailpagina's van de oplossingen.
   Gedeeld door ai-oplossingen.html en AivoriaPlatform.dc.html, zodat de twee
   niet uit elkaar groeien. De basis (:root-kleuren, lettertypen, reset) staat
   in elk bestand zelf; hier staat alleen wat de secties zelf nodig hebben.

   Uitgangspunt: inhoud staat rechtstreeks op de pagina. Samenhang komt van
   witruimte, uitlijning en dunne lijnen, niet van kaarten. Kaarten blijven
   alleen waar je iets kiest (de prijspakketten). */

:root {
  --lijn: oklch(1 0 0 / 0.1);
  --lijn-sterk: oklch(1 0 0 / 0.18);
  --tekst-2: oklch(0.86 0.012 275);
  --band: oklch(0.095 0.014 275);
  --scherm-bg: oklch(0.13 0.016 275);
  --kop-ruimte: calc(var(--kop-hoogte, 69px) + 1.5rem);
}

/* ── Ritme ─────────────────────────────────────────────────────────────── */
.ob-wrap { max-width: 1280px; margin: 0 auto; padding-inline: 1.5rem; } /* zelfde raster als kop, voet en homepage */
:root { --tot-rand: calc(max(0px, (100vw - 1280px) / 2) + 1.5rem); } /* van de rasterrand tot de schermrand */
.ob-sectie { padding-block: clamp(2.75rem, 6vw, 5rem); }
.ob-sectie-klein { padding-block: clamp(2.5rem, 5vw, 4rem); }
.ob-lijn { border-top: 0; } /* sectiescheiding: alleen witruimte, geen lijn */
.ob-band { background: var(--band); border-top: 1px solid var(--lijn); border-bottom: 1px solid var(--lijn); }
.ob-anker { scroll-margin-top: var(--kop-ruimte); }

/* ── Typografie ────────────────────────────────────────────────────────── */
.ob-label { font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 600; }
.ob-label-stil { font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 600; color: var(--muted); }
.ob-h1 { font-size: clamp(2.5rem, 5.2vw, 4rem); font-weight: 700; line-height: 1.03; letter-spacing: -0.025em; max-width: 13em; }
.ob-regel { display: block; } /* een bewuste regel in een kop */
.ob-h2 { font-size: clamp(1.75rem, 3.2vw, 2.5rem); font-weight: 700; line-height: 1.12; max-width: 17em; }
.ob-h3 { font-size: 1.2rem; font-weight: 600; line-height: 1.3; }
/* De ondertitel onder een productnaam: één zin, iets groter en in de kopletter. */
.ob-sub { margin-top: 0.7rem; font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 1.3rem; font-weight: 500; line-height: 1.35; letter-spacing: -0.01em; max-width: 24em; }
.ob-lead { font-size: 1.15rem; line-height: 1.6; color: var(--tekst-2); max-width: 34em; }
.ob-p { font-size: 1.02rem; line-height: 1.7; color: var(--tekst-2); max-width: 36em; }
.ob-p + .ob-p { margin-top: 1rem; }
.ob-stil { color: var(--muted); }
.ob-tag { display: inline-block; margin-left: 0.6rem; padding: 0.15rem 0.55rem; border-radius: 999px; border: 1px solid oklch(0.65 0.28 340 / 0.5); color: var(--pink); font-size: 0.65rem; letter-spacing: 0.1em; vertical-align: middle; }

/* ── Kolommen ──────────────────────────────────────────────────────────── */
.ob-grid { display: grid; gap: 2rem 3rem; align-items: start; }
.ob-grid-5-7 { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.ob-grid-7-5 { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.ob-grid-4-8 { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
.ob-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ob-onder { align-self: end; }
.ob-midden { align-self: center; }
@media (max-width: 860px) {
  .ob-grid-5-7, .ob-grid-7-5, .ob-grid-4-8, .ob-grid-2 { grid-template-columns: minmax(0, 1fr); }
  .ob-grid { gap: 1.75rem; }
}

/* ── Schermafdrukken ───────────────────────────────────────────────────── */
/* Eén rustige omlijsting: dunne rand, kleine afronding en een zachte schaduw
   om het lichte venster van de donkere pagina te scheiden. Geen kaart, geen
   gekleurd vlak, geen browserframe eromheen. */
.ob-scherm { margin: 0; border-radius: 14px; border: 1px solid var(--lijn-sterk); background: var(--scherm-bg); overflow: hidden; box-shadow: 0 40px 80px -48px rgba(0, 0, 0, 0.9); }
.ob-scherm img { width: 100%; height: auto; display: block; }
.ob-scherm-klein { border-radius: 10px; }
.ob-scherm figcaption { padding: 0.75rem 0 0; font-size: 0.85rem; color: var(--muted); }
/* Een uitsnede die een detail van het grote beeld uitvergroot. Op desktop
   overlapt hij de hoek, op smalle schermen staat hij eronder. */
.ob-compositie { position: relative; }
.ob-detail { position: absolute; right: -1rem; bottom: -1.75rem; width: 42%; max-width: 270px; box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.95); }
@media (max-width: 860px) {
  .ob-detail { position: static; width: 55%; max-width: 240px; margin: 1rem 0 0 auto; }
}

/* Het scherm in de kop staat licht gedraaid, groot, en loopt rechts over de
   rand: de linkerkant staat iets verder weg, de rechterkant komt naar je toe.
   De perspective hoort op de wrapper; de reveal-animatie ook, want die zet een
   eigen transform en zou de draai anders even wegdrukken. Op smalle schermen
   staat het beeld recht en toont <picture> een uitsnede. */
.ob-hero-schuin, .ob-sectie-schuin { overflow: hidden; }
.ob-hero-grid, .ob-beeld-grid { align-items: center; gap: 2.5rem 3rem; }
.ob-schuin-wrap { perspective: 1800px; }
.ob-schuin { width: 138%; max-width: none; transform: rotateY(-16deg) rotateX(3deg); transform-origin: 0% 50%; box-shadow: -24px 48px 100px -36px rgba(0, 0, 0, 0.95); }
/* Gespiegeld: het scherm staat links en loopt links over de rand. */
.ob-schuin-links { transform: rotateY(16deg) rotateX(3deg); transform-origin: 100% 50%; margin-left: -38%; box-shadow: 24px 48px 100px -36px rgba(0, 0, 0, 0.95); }
@media (min-width: 901px) { .ob-beeld-links > .ob-schuin-wrap { order: -1; } }

/* ── Naast de tekst als het past, eronder als het te smal wordt ──────────
   Een complete afdruk naast de tekst is onder 1700px smaller dan 700px en
   dan valt er niets meer van af te lezen (op 1280px zou het 540px zijn).
   Daaronder gaat het beeld daarom onder de tekst, over de volle
   rasterbreedte, en gaat de tekst in twee kolommen mee zodat allebei exact
   dezelfde randen delen — gemeten 0,0px verschil.

   Recht, in die stand. Een gedraaide afbeelding heeft geen verticale randen:
   bij 6 graden loopt de linkerrand 7px weg over de hoogte, en dat ziet het
   oog meteen tegen een kaarsrechte tekstkolom. Naast de tekst speelt dat niet
   omdat er niets is om tegen uit te lijnen; daar blijft de draai staan. */
@media (min-width: 901px) and (max-width: 1699px) {
  .ob-hero-grid, .ob-beeld-grid { grid-template-columns: minmax(0, 1fr); gap: 2.75rem; }
  .ob-beeld-links > .ob-schuin-wrap { order: 0; }
  .ob-schuin-wrap { perspective: none; }
  .ob-schuin, .ob-schuin-links {
    width: 100%; margin-left: 0; transform: none;
    box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.95);
  }
}

/* Het tekstblok in twee kolommen: naam links, uitleg rechts. De "lees meer"
   link staat in de linkerkolom, anders scheelt het 127px in kolomhoogte en
   valt er een gat van 171px onder de naam. */
@media (min-width: 1100px) and (max-width: 1699px) {
  .ob-tekst-2 { display: grid; grid-template-columns: minmax(0, 40fr) minmax(0, 60fr); column-gap: 4rem; align-items: start; }
  .ob-tekst-kop { grid-column: 1; grid-row: 1; }
  .ob-tekst-uitleg { grid-column: 2; grid-row: 1 / span 2; }
  .ob-tekst-link { grid-column: 1; grid-row: 2; align-self: start; margin-top: 1.5rem; }
  /* De eerste alinea van de uitleg heeft een marge om hem los te zetten van
     de naam erboven; naast elkaar staan ze op dezelfde regel, dus daar niet. */
  .ob-tekst-uitleg > :first-child { margin-top: 0 !important; }
}

/* Naast elkaar en op smalle schermen volgt de link gewoon na de uitleg. */
.ob-tekst-link { margin-top: 1.5rem; }

/* Vanaf 1700px past het beeld ernaast. De buitenrand hangt dan aan het
   scherm in plaats van aan de kolom, zodat hij overal even ver van de rand
   blijft en met het scherm meegroeit in plaats van op een vaste breedte te
   blijven staan. De deling door 1,055 compenseert dat het perspectief het
   geschilderde beeld breder maakt dan de layoutbreedte. */
@media (min-width: 1700px) {
  /* Boven 1700px groeit de opzet niet verder mee; er komt alleen ruimte
     omheen. Doorgroeien maakte de afdruk op 2560px 1161px tegen een
     tekstkolom van 592px, en dan overheerst hij.

     Het beeldraster loopt 160px aan weerszijden buiten het gewone raster, zo
     ver dat de afdruk op ongeveer 750px uitkomt. Aan weerszijden even ver,
     want anders steken de gespiegelde secties links verder uit dan de tekst
     en lijkt de kop ingesprongen. Nu delen tekst en beeld dezelfde buitenrand,
     of de sectie nu gespiegeld is of niet. */
  /* Kolommen op maat in plaats van twee gelijke helften: de tekst krijgt wat
     hij nodig heeft en het beeld houdt zijn 750px. Met gelijke helften was de
     tekstkolom 752px terwijl de tekst er 544 van vult (begrensd op 34em voor
     de regellengte), en dat gaf een goot van 256px tussen tekst en beeld —
     twee losse eilanden in plaats van één blok. Nu is die goot 80px.

     Op het overzicht is de grid zelf het rasterelement, dus daar verruimt de
     max-width; in de kop van de detailpagina's zit de grid ín het raster en
     werkt een negatieve marge aan weerszijden. */
  .ob-beeld-grid { max-width: 1470px; grid-template-columns: minmax(0, 36em) minmax(0, 750px); }
  .ob-beeld-links.ob-beeld-grid { grid-template-columns: minmax(0, 750px) minmax(0, 36em); }
  .ob-hero-grid { margin-inline: -95px; grid-template-columns: minmax(0, 36em) minmax(0, 750px); }
  /* Vaste perspectiefafstand (150vw bij 1700px), zodat de draaiing er boven
     de grens niet anders uit gaat zien. */
  .ob-schuin-wrap { perspective: 2550px; }
  /* Gewoon de volle kolom: het perspectief maakt het geschilderde beeld maar
     1% breder dan de layoutbreedte, dus de randen vallen binnen een paar pixels
     samen met de kolom — en daarmee met de tekst in de sectie ernaast. */
  .ob-schuin, .ob-schuin-links { width: 100%; margin-left: 0; }
  /* De kolommen worden 752px breed; de tekst blijft op een leesbare maat. */
  .ob-tekst-kop, .ob-tekst-uitleg { max-width: 34em; }
}
@media (max-width: 900px) {
  .ob-hero-grid, .ob-beeld-grid { grid-template-columns: minmax(0, 1fr); }
  .ob-schuin, .ob-schuin-links { width: 100%; margin-left: 0; transform: none; }
}

/* Een handgeschreven notitie met een pijl naar het scherm, boven een gedraaid beeld (Caveat via Google Fonts). */
.ob-schuin-wrap { position: relative; }
.ob-notitie { position: absolute; left: 6%; top: -3.6rem; z-index: 2; display: flex; align-items: flex-start; gap: 0.4rem; margin: 0; font-family: 'Caveat', 'Segoe Script', cursive; font-size: 1.55rem; font-weight: 600; line-height: 1.1; color: oklch(0.93 0.01 275); transform: rotate(-4deg); white-space: nowrap; }
.ob-notitie svg { flex-shrink: 0; margin-top: 0.7rem; color: var(--pink); }
@media (max-width: 900px) { .ob-notitie { position: static; transform: none; margin: 0 0 0.75rem 0.25rem; font-size: 1.4rem; white-space: normal; } .ob-notitie svg { margin-top: 0.15rem; } }

/* Een staand beeld hoeft de kolom niet te vullen; een smal, hoog beeld staat op ware grootte. */
.ob-staand { max-width: 520px; }
.ob-smal { width: min(100%, 250px); justify-self: start; margin-left: clamp(0px, 6vw, 4rem); }
@media (max-width: 860px) { .ob-smal { margin-left: 0; width: min(100%, 200px); } }

/* ── Lijsten ───────────────────────────────────────────────────────────── */
.ob-lijst { list-style: none; margin: 0; padding: 0; }
.ob-lijst li { display: grid; grid-template-columns: auto 1fr; gap: 0.85rem; align-items: start; padding: 0.45rem 0; font-size: 1rem; line-height: 1.55; color: var(--tekst-2); }
.ob-lijst .ob-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--pink); margin-top: 0.62em; }
.ob-lijst-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 3rem; }
@media (max-width: 700px) { .ob-lijst-2 { grid-template-columns: minmax(0, 1fr); } }

/* Een rij open items met een dunne lijn erboven (geen kaarten). */
.ob-rij { display: grid; gap: 2rem; list-style: none; margin: 0; padding: 0; }
.ob-rij > * { padding-top: 0; }
.ob-rij-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.5rem 3rem; }
.ob-rij-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ob-rij-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ob-rij p { margin-top: 0.6rem; color: var(--tekst-2); line-height: 1.65; }
.ob-rij .ob-h3 + p { margin-top: 0.75rem; }
@media (max-width: 860px) { .ob-rij-2, .ob-rij-3, .ob-rij-4 { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; } }

/* Genummerde stappen: een rij met dunne lijnen erboven. */
.ob-stappen { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem; }
.ob-stappen li { border-top: 1px solid var(--lijn-sterk); padding-top: 1.25rem; }
.ob-stap-nr { font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 0.85rem; letter-spacing: 0.1em; }
.ob-stappen p { margin-top: 0.6rem; color: var(--tekst-2); line-height: 1.6; font-size: 0.98rem; }
@media (max-width: 860px) { .ob-stappen { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ob-stappen { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; } }

/* Een proces van invoer naar uitkomst: drie stappen met een pijl ertussen. */
.ob-proces { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr); gap: 1.5rem; align-items: start; list-style: none; margin: 0; padding: 0; }
.ob-proces-stap { border-top: 1px solid var(--lijn-sterk); padding-top: 1.25rem; }
.ob-proces-stap h3 { margin-top: 0.75rem; }
.ob-proces-stap p { margin-top: 0.6rem; color: var(--tekst-2); line-height: 1.6; font-size: 0.98rem; }
.ob-proces-pijl { color: var(--muted); padding-top: 3.1rem; font-size: 1.1rem; }
@media (max-width: 860px) {
  .ob-proces { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .ob-proces-pijl { padding: 0; width: fit-content; transform: rotate(90deg); }
}

/* De inhoudsopgave in de kop van het overzicht. */
.ob-index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--lijn-sterk); }
.ob-index li { border-bottom: 1px solid var(--lijn); }
.ob-index a { display: grid; grid-template-columns: 3.25rem minmax(0, 1fr) auto; gap: 1rem; align-items: baseline; padding: 0.95rem 0; text-decoration: none; color: inherit; }
.ob-index-key { font-family: 'Space Grotesk', system-ui, sans-serif; font-weight: 700; font-size: 0.78rem; letter-spacing: 0.08em; color: var(--muted); }
.ob-index-naam { font-weight: 600; font-size: 1.05rem; }
.ob-index-sub { display: block; color: var(--muted); font-size: 0.9rem; margin-top: 0.15rem; }
.ob-index-pijl { color: var(--muted); transition: transform 0.24s; }
.ob-index a:hover .ob-index-naam { text-decoration: underline; text-underline-offset: 4px; }
.ob-index a:hover .ob-index-pijl { transform: translateX(4px); }

/* Dezelfde inhoudsopgave als rij van vier, onder de kop. */
.ob-index-rij { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 2.5rem; }
.ob-index-rij li { border-bottom: 0; }
.ob-index-rij a { display: block; padding: 1.25rem 0 0.5rem; }
.ob-index-rij .ob-index-naam { display: block; margin-top: 0.5rem; }
.ob-index-rij .ob-index-pijl { display: inline-block; margin-left: 0.4rem; }
@media (max-width: 860px) { .ob-index-rij { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 2rem; } .ob-index-rij li { border-bottom: 1px solid var(--lijn); } }
@media (max-width: 560px) { .ob-index-rij { grid-template-columns: minmax(0, 1fr); } }

/* Het voorbeeldproces in het kort: drie rijen met de fase links. */
.ob-proces-kort { list-style: none; margin: 0; padding: 0; }
.ob-proces-kort li { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: 1rem; padding: 0.75rem 0; }
.ob-proces-kort h3 { font-size: 1.05rem; font-weight: 600; }
.ob-proces-kort p { margin-top: 0.35rem; color: var(--tekst-2); line-height: 1.55; font-size: 0.95rem; }
@media (max-width: 560px) { .ob-proces-kort li { grid-template-columns: minmax(0, 1fr); gap: 0.35rem; } }

/* ── Links en acties ───────────────────────────────────────────────────── */
.ob-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; text-decoration: none; transition: gap 0.24s; }
.ob-link:hover { gap: 11px; }
.ob-acties { display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem; align-items: center; }
.ob-tekstlink { color: white; text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--lijn-sterk); transition: text-decoration-color 0.2s; }
.ob-tekstlink:hover { text-decoration-color: white; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; border-radius: 4px; }

/* ── Veelgestelde vragen ───────────────────────────────────────────────── */
.ob-faq { border-top: 1px solid var(--lijn-sterk); }
.ob-faq-item { border-bottom: 1px solid var(--lijn); }
.ob-faq-q { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1.15rem 0; background: none; border: 0; color: white; font: 500 1.05rem/1.4 'Inter', system-ui, sans-serif; text-align: left; cursor: pointer; }
.ob-faq-chevron { flex-shrink: 0; color: var(--muted); transition: transform 0.3s cubic-bezier(.22, 1, .36, 1); }
.ob-faq-item.open .ob-faq-chevron { transform: rotate(180deg); }
.ob-faq-a-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.34s cubic-bezier(.22, 1, .36, 1); }
.ob-faq-item.open .ob-faq-a-wrap { grid-template-rows: 1fr; }
.ob-faq-a-inner { overflow: hidden; }
.ob-faq-a { padding: 0 0 1.25rem; color: var(--tekst-2); line-height: 1.65; max-width: 36em; }

/* ── Afsluiting ────────────────────────────────────────────────────────── */
.ob-slot { text-align: center; max-width: 640px; margin: 0 auto; padding-top: 1rem; }
.ob-slot .ob-h2 { margin-inline: auto; }
.ob-slot .ob-lead { margin: 1rem auto 0; }
.ob-slot .ob-acties { justify-content: center; margin-top: 2rem; }

/* ── Brede schermen ────────────────────────────────────────────────────── */
/* Vanaf 1500px mogen koppen, intro's en de gedraaide schermen groter; de
   leesbreedte van lopende tekst blijft door de max-width in em gelijk. */
@media (min-width: 1500px) {
  .ob-h1 { font-size: clamp(2.5rem, 5.2vw, 4.6rem); }
  .ob-h2 { font-size: clamp(1.75rem, 3.2vw, 2.9rem); }
  .ob-sub { font-size: 1.45rem; }
  .ob-lead { font-size: 1.25rem; }
  .ob-p { font-size: 1.08rem; }
  .ob-lijst li { font-size: 1.05rem; }
  .ob-sectie { padding-block: 5.5rem; }
  .ob-notitie { font-size: 1.75rem; top: -4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ob-link, .ob-index-pijl, .ob-faq-chevron, .ob-faq-a-wrap, .ob-tekstlink { transition: none; }
}

/* --- Tijdlijn ---------------------------------------------------------
   De stappen scrollen langs; het scherm ernaast blijft staan en wisselt mee.
   Zonder JS blijft alles leesbaar: elke stap heeft zijn eigen beeld eronder.
   De klassen is-actief en is-gehad worden door initTijdlijn() in site-fx.js
   gezet. */
.ob-tl-grid { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2.5rem; }
.ob-tl-stappen { position: relative; list-style: none; margin: 0; padding: 0; }
/* Eén doorlopende lijn van het midden van de eerste stip tot dat van de
   laatste, met daaroverheen dezelfde lijn in kleur die met het scrollen
   meegroeit. De maten komen van initTijdlijn(): ze hangen af van de hoogte van
   de stappen, en die staat pas na de opmaak vast. */
.ob-tl-stappen::before,
.ob-tl-stappen::after {
  content: ''; position: absolute; left: 15px; width: 2px; border-radius: 2px;
  top: var(--tl-spoor-top, 18px);
}
.ob-tl-stappen::before { height: var(--tl-spoor-h, 0px); background: var(--lijn); }
/* De gegroeide lijn heeft drie lagen: een lichtpunt op de kop, een glans die
   erlangs zakt, en het verloop zelf. --grad loopt horizontaal en zou op een
   lijn van 2px als één vlakke kleur uitkomen, vandaar het eigen verloop. */
.ob-tl-stappen::after {
  height: var(--tl-lijn, 0px);
  background-image:
    radial-gradient(closest-side, oklch(1 0 0 / 0.95), oklch(1 0 0 / 0)),
    linear-gradient(180deg, transparent, oklch(1 0 0 / 0.55) 50%, transparent),
    linear-gradient(180deg, oklch(0.5 0.27 265), oklch(0.55 0.28 320));
  background-size: 420% 14px, 100% 120px, 100% 100%;
  background-position: -160% 100%, 0 0, 0 0;
  background-repeat: no-repeat;
  box-shadow: 0 0 14px oklch(0.55 0.28 300 / 0.45);
  animation: tlGlans 2.8s linear infinite;
}
@keyframes tlGlans {
  from { background-position: -160% 100%, 0 -120px, 0 0; }
  to   { background-position: -160% 100%, 0 100%, 0 0; }
}
/* De stappen liggen boven de lijn, anders loopt hij dwars over de nummers. De
   stap krijgt geen achtergrond, dus tussen de stippen blijft de lijn zichtbaar. */
.ob-tl-stap { position: relative; z-index: 1; padding-left: 3.25rem; padding-bottom: 2.75rem; }
.ob-tl-stap:last-child { padding-bottom: 0; }
.ob-tl-nr {
  position: absolute; left: 0; top: 0.15rem; width: 32px; height: 32px;
  border-radius: 999px; display: grid; place-items: center;
  font-size: 0.85rem; font-weight: 600; color: var(--muted);
  border: 1px solid var(--lijn-sterk); background: var(--bg);
  transition: color 0.3s, border-color 0.3s, background 0.3s,
              transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.ob-tl-stap.is-gehad .ob-tl-nr,
.ob-tl-stap.is-actief .ob-tl-nr { color: #fff; border-color: transparent; background: var(--grad); }
/* De stip van de stap die aan de beurt is krijgt een ring die rustig ademt,
   zodat het meegroeien van de lijn ergens op uitkomt. */
.ob-tl-stap.is-actief .ob-tl-nr { animation: tlPuls 2.8s ease-in-out infinite; }
@keyframes tlPuls {
  0%, 100% { box-shadow: 0 0 0 5px oklch(0.55 0.24 285 / 0.2); }
  50% { box-shadow: 0 0 0 10px oklch(0.55 0.24 285 / 0.06); }
}
.ob-tl-titel { font-size: 1.2rem; font-weight: 600; line-height: 1.3; margin: 0.3rem 0 0; }
/* De knop staat als gewone tekst in de kop; het vlak eroverheen maakt de hele
   stap aanklikbaar. Alleen waar het vaste kader staat, want daaronder scrol je
   toch al naar de stap die je aanwijst. */
.ob-tl-ga {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.ob-tl-ga:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; border-radius: 4px; }
.ob-tl-tekst { margin-top: 0.6rem; color: var(--tekst-2); line-height: 1.65; max-width: 34em; }
/* De schermen zijn aanklikbaar: dan opent de vergroting met het hele beeld. */
.ob-tl-stap-beeld {
  display: block; width: 100%; margin-top: 1.25rem; padding: 0; cursor: zoom-in;
  appearance: none; background: var(--scherm-bg); border: 1px solid var(--lijn-sterk);
  border-radius: 14px; overflow: hidden; box-shadow: 0 40px 80px -48px rgba(0, 0, 0, 0.9);
}
.ob-tl-stap-beeld img { display: block; width: 100%; height: auto; }
.ob-tl-stap-beeld:focus-visible, .ob-tl-lagen:focus-visible { outline: 2px solid var(--pink); outline-offset: 4px; }
.ob-tl-badge {
  position: absolute; left: 1rem; bottom: 1rem; z-index: 2;
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.4rem 0.7rem; border-radius: 999px;
  background: oklch(0.12 0.012 275 / 0.82); color: var(--fg);
  border: 1px solid oklch(1 0 0 / 0.16); font-size: 0.78rem;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; transition: opacity 0.25s;
}
.ob-tl-lagen:hover .ob-tl-badge, .ob-tl-lagen:focus-visible .ob-tl-badge { opacity: 1; }
/* Zonder muis is er geen hover om de hint mee tevoorschijn te halen, en dan is
   niet te zien dat je het scherm kunt opendrukken. */
@media (hover: none) {
  .ob-tl-badge { opacity: 1; }
}
.ob-tl-beeld { display: none; }

/* Pas vanaf 1200px twee kolommen. Daaronder blijft er voor het kader te weinig
   breedte over en is het scherm onleesbaar klein; de gestapelde weergave geeft
   er een beeld van bijna de volle kolombreedte. */
@media (min-width: 1200px) {
  /* De tekstkolom is smal gehouden zodat het scherm zoveel mogelijk breedte
     krijgt: de tekst erin is toch al klein. */
  .ob-tl-grid { grid-template-columns: minmax(0, 18em) minmax(0, 1fr); gap: 2.5rem; align-items: start; }
  /* Het vaste kader toont het beeld, dus het beeld onder elke stap is dubbelop.
     display:none houdt die bij loading="lazy" ook buiten het netwerk. */
  .ob-tl-stap-beeld { display: none; }
  /* Het dimmen zit op de tekst, niet op de hele stap: een doorzichtige stap
     laat de lijn dwars door de stip heen schijnen. */
  .ob-tl-stap { padding-bottom: 4.5rem; cursor: pointer; }
  .ob-tl-stap.is-actief { cursor: default; }
  /* De tekst van de stap die aan de beurt is komt een paar pixels omhoog, de
     alinea een tel na de titel. Dat maakt het wisselen zichtbaar zonder dat er
     iets verspringt: de opmaak blijft staan, alleen de weergave beweegt. Het
     scherm zelf wisselt met een gewone overvloeier; dat mag rustig blijven. */
  .ob-tl-titel, .ob-tl-tekst {
    opacity: 0.45; transform: translateY(11px);
    transition: opacity 0.4s ease, transform 0.6s cubic-bezier(0.24, 0.86, 0.26, 1);
  }
  .ob-tl-tekst { transition-delay: 0.08s; }
  .ob-tl-stap.is-actief .ob-tl-titel,
  .ob-tl-stap.is-actief .ob-tl-tekst { opacity: 1; transform: none; }
  .ob-tl-stap:not(.is-actief):hover .ob-tl-titel,
  .ob-tl-stap:not(.is-actief):hover .ob-tl-tekst { opacity: 0.75; }
  .ob-tl-stap.is-actief .ob-tl-nr { transform: scale(1.1); }
  .ob-tl-ga::after { content: ''; position: absolute; inset: 0; }
  .ob-tl-stap.is-actief .ob-tl-ga { cursor: default; }
  /* Ruimte onder de laatste stap. Een sticky element wordt weggeduwd zodra de
     onderkant van zijn kolom in beeld komt; zonder deze ruimte schuift het
     scherm al omhoog terwijl je de laatste stappen nog leest. */
  .ob-tl-stappen { padding-bottom: clamp(6rem, 40vh, 24rem); }
  /* Het kader loopt door tot de rechterrand van het venster: dat levert de
     breedte op om het scherm zo groot mogelijk te tonen. Het beeld past er
     helemaal in, want een schermafdruk waarvan een derde wegvalt leest als
     afgeknipt. Wie meer detail wil, klikt hem open.

     De sticky kolom is zo hoog als het venster en centreert het kader daarin,
     zodat het op ooghoogte staat naast de stap die op dat moment actief is. */
  /* De kolom loopt buiten het raster door naar de rechterrand, maar houdt daar
     de gewone paginamarge aan: het scherm staat zo helemaal in beeld in plaats
     van tegen de rand geplakt. De kolom is zo hoog als de stappenlijst; het
     beeld erin plakt. Niet andersom (een vensterhoge plakkolom met het beeld in
     het midden): dan hangt het beeld bij het binnenkomen een paar honderd pixels
     lager dan de eerste stap, en staat daarnaast een gat. */
  .ob-tl-beeld {
    display: block;
    /* De grid staat op align-items: start voor de stappenlijst; deze kolom moet
       juist de volle rijhoogte krijgen, anders heeft het plakkende beeld erin
       geen ruimte om in te schuiven. */
    align-self: stretch;
    margin-right: calc(1.5rem - var(--tot-rand));
  }
  /* aspect-ratio bepaalt de hoogte uit de breedte; max-width knijpt de breedte
     terug op lage vensters, zodat het kader nooit hoger wordt dan het scherm.
     Alle beelden zijn even groot, dus het kader springt niet tussen stappen. */
  /* --tl-plak zet initTijdlijn(): de plaklijn waarop het beeld midden in het
     venster uitkomt. Dat hangt af van de hoogte van het beeld, en die volgt uit
     de breedte van de kolom — niet in CSS uit te rekenen. De fallback is de
     stand zonder script. */
  .ob-tl-lagen {
    position: sticky; top: var(--tl-plak, calc(var(--kop-hoogte, 69px) + 3rem));
    /* Links in de kolom, tegen de tekst aan. Rechts uitlijnen zou op een heel
       breed scherm een gat van honderden pixels tussen de tekst en het beeld
       trekken zodra de breedterem hieronder aanslaat; nu valt die ruimte
       rechts weg, waar ze als paginamarge leest. */
    margin: 0 auto 0 0; overflow: hidden; padding: 0;
    appearance: none; background: none; border: 0; cursor: zoom-in; display: block; width: 100%;
    aspect-ratio: 1729 / 910;
    /* Twee remmen op de breedte, want de kolom loopt buiten het raster door en
       zonder rem groeit het kader eindeloos mee.

       De eerste is de opname zelf: die is 1729px breed, en groter vertonen blaast
       hem op. Op 3440px liep het kader tot 2008px, oftewel 116% — zichtbaar wazig.
       Is het scherm breed genoeg, dan staat de opname er dus op ware grootte op
       en helemaal in beeld.

       De tweede is de hoogte van het venster, want bij een brede lage verhouding
       vulde het kader het scherm bijna helemaal: op 2560x1080 bleef er 93px
       lucht over, op 1920x900 87 en op 1440x700 nog 50. 10rem laat overal
       minstens 80px over zonder het kader onnodig klein te maken. De gewone
       16:9- en 16:10-maten raakt hij niet; daar is de kolom smaller dan wat de
       hoogte toelaat. */
    max-width: min(1729px, calc((100svh - var(--kop-hoogte, 69px) - 10rem) * 1729 / 910));
    /* Overal ronde hoeken: het kader staat vrij in beeld, niet half buiten de
       rand zoals toen het tegen de schermrand aan liep. */
    border-radius: 14px;
    box-shadow: 0 40px 80px -48px rgba(0, 0, 0, 0.9);
  }
  .ob-tl-lagen img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; max-width: none;
    opacity: 0; transition: opacity 0.45s ease;
  }
  .ob-tl-lagen img.is-zichtbaar { opacity: 1; }
}

/* De vergroting: het hele scherm, passend in het venster. */
/* Dicht tenzij hij open staat. Niet via het hidden-attribuut: de dc-runtime
   laat een kaal attribuut zonder waarde vallen, en dan staat hij meteen open. */
.ob-licht { display: none; }
.ob-licht.is-open {
  /* Boven de kop, die sinds de veilige-zone-laag op 9999 staat; een
   vergroting hoort alles af te dekken. */
  position: fixed; inset: 0; z-index: 10000; display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: oklch(0.05 0.01 275 / 0.9);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.ob-licht-vak { margin: 0; display: grid; justify-items: center; }
.ob-licht-vak img {
  display: block; max-width: min(100%, 1729px); max-height: 80svh;
  width: auto; height: auto; border-radius: 14px;
  border: 1px solid var(--lijn-sterk); box-shadow: 0 50px 110px -40px #000;
}
.ob-licht-vak figcaption { margin-top: 1rem; color: var(--tekst-2); font-size: 0.95rem; text-align: center; }
.ob-licht-sluit {
  position: absolute; top: clamp(0.75rem, 2vw, 1.5rem); right: clamp(0.75rem, 2vw, 1.5rem);
  width: 42px; height: 42px; display: grid; place-items: center; cursor: pointer;
  border-radius: 999px; background: oklch(0.12 0.012 275 / 0.8); color: var(--fg);
  border: 1px solid var(--lijn-sterk);
}
.ob-licht-sluit:hover { background: oklch(0.18 0.012 275 / 0.9); }
.ob-licht-sluit:focus-visible { outline: 2px solid var(--pink); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .ob-tl-titel, .ob-tl-tekst, .ob-tl-nr, .ob-tl-lagen img { transition: none; }
  /* Geen schuiven of schalen; het dimmen en het wisselen blijven. */
  .ob-tl-titel, .ob-tl-tekst, .ob-tl-stap.is-actief .ob-tl-nr { transform: none; }
  /* De lijn groeit nog steeds mee met het scrollen; alleen de glans die er
     vanzelf langs zakt en het ademen van de ring gaan eruit. */
  .ob-tl-stappen::after { animation: none; }
  .ob-tl-stap.is-actief .ob-tl-nr { animation: none; box-shadow: 0 0 0 5px oklch(0.55 0.24 285 / 0.2); }
}
