/* ==========================================================================
   Schouten Design — stijl, versie 3 (2026-10-03)

   Eén systeem voor de hele site (Catalogus: "één stijl, weinig variatie"):
   - één achtergrondkleur, nergens wisselende vlakken
   - elke sectie is een .block: kop links, inhoud rechts, dunne lijn erboven
   - één soort lijst: .rows (rijen met lijnen ertussen)
   - één icoonstijl: lijnen van 1.8px in het blauw, los, zonder vlak
   - één knop (.btn-primary) en één tekstlink (.link-arrow)
   Voeg geen nieuw soort element toe als een bestaand het kan.
   Lees D:\Projects\CATALOGUS.md voordat je hier iets verandert.

   Elke kleur, maat en vorm staat hier één keer. Gebruik var(--naam).

   Contrast (WCAG AA vraagt 4.5:1 voor gewone tekst):
   - tekst #f3f5f8 op #060708 ~19:1, grijs #8f98a8 op #060708 ~7:1
   - blauw #5b8def als tekst op #060708 ~6:1, wit op knopblauw #2563eb ~5.2:1
   ========================================================================== */
:root {
  --bg: #060708;
  --surface: #0f1216;
  --line: #1f242c;
  --line-strong: #2c333e;
  --text: #f3f5f8;
  --text-soft: #b4bccb;
  --muted: #8f98a8;
  --text-dim: #464d59;         /* tekst die nog moet oplichten (Over mij, werkwijze) */
  --accent: #5b8def;          /* blauw voor tekst, iconen, lijnen */
  --accent-strong: #2563eb;   /* blauw voor vlakken met witte tekst erop */
  --accent-hover: #1d4ed8;
  --success: #4ade80;
  --error: #f87171;
  --warning: #fbbf24;          /* websitecheck: kan beter */
  --placeholder: rgba(250, 204, 21, 0.6);
  --bubble-in: #161a20;
  --bubble-out: #1b3a7a;
  --bubble-out-time: #a9c0ef;

  /* Systeemlettertypes: geen Google Fonts, dus geen verzoek naar Google. */
  --font: "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  /* Koppen (h1, h2): Playfair Display, de letter waar het SD-logo uit komt.
     Zelf gehost in /fonts (zie @font-face onder "Basis"), licentie in fonts/OFL.txt. */
  --font-serif: "Playfair Display SD", Georgia, "Times New Roman", serif;
  --font-display: "Segoe UI Variable Display", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 6rem;

  --radius: 12px;
  --radius-small: 8px;
  --container: 1200px;
  --header-height: 72px;
  --icon: 40px;
}

/* ==========================================================================
   Basis
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

/* Eigen kopletter, van onze eigen site geladen (geen Google Fonts). Alleen
   Latijnse tekens, daarom klein. "swap": tekst staat er meteen in de
   reserveletter en wisselt zodra het bestand binnen is. */
@font-face {
  font-family: "Playfair Display SD";
  src: url("/fonts/playfair-display-bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Playfair Display SD";
  src: url("/fonts/playfair-display-bolditalic.woff2") format("woff2");
  font-weight: 700; font-style: italic; font-display: swap;
}

html { scroll-behavior: smooth; scroll-padding-top: var(--header-height); }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Eén typeschaal voor de hele site. */
h1, h2, h3 { font-family: var(--font-display); margin: 0 0 var(--space-2); text-wrap: balance; font-weight: 700; }
h1 { font-size: clamp(2.6rem, 7vw, 5.6rem); line-height: 1.02; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.8rem, 3.4vw, 2.6rem); line-height: 1.1; letter-spacing: -0.01em; }
h1, h2 { font-family: var(--font-serif); }
h3 { font-size: 1.25rem; line-height: 1.25; letter-spacing: -0.015em; font-weight: 650; }
p  { margin: 0 0 var(--space-2); color: var(--muted); }
em { font-style: normal; color: var(--accent); }   /* de enige nadruk: één woord in het blauw */
h1 em, h2 em { font-style: italic; }                 /* in een kop ook schuin, zoals in een tijdschrift */

a { color: var(--accent); }
a:hover { color: var(--text); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 var(--space-2); }
@media (min-width: 760px) { .container { padding: 0 var(--space-4); } }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--space-2); top: -100px; z-index: 100;
  background: var(--accent-strong); color: #fff;
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-small);
}
.skip-link:focus { top: var(--space-1); }

/* Iconen: één stijl. .icon = in de tekst, .icon-lg = in een rij. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon, .icon-lg { flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.icon { width: 1.25em; height: 1.25em; }
.icon-lg { width: var(--icon); height: var(--icon); color: var(--accent); }

/* Alles wat nog geen echte inhoud is (gele stippellijn). render.js zet hem
   automatisch op gegevens die nog niet in het profiel staan. */
.placeholder { outline: 1px dashed var(--placeholder); outline-offset: 3px; }

/* ==========================================================================
   Knop en tekstlink: de enige twee manieren om iets te laten doen.
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6em;
  padding: 0.9em 1.6em; border-radius: 999px; border: 0;
  font: inherit; font-weight: 600; font-size: 1rem;
  text-decoration: none; cursor: pointer;
  transition: background-color 0.15s;
}
.btn-primary { background: var(--accent-strong); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); color: #fff; }
.btn-small { padding: 0.55em 1.15em; font-size: 0.95rem; }
.btn[disabled] { opacity: 0.6; cursor: wait; }

.link-arrow { color: var(--text); font-weight: 600; text-decoration: none; border-bottom: 1px solid var(--line-strong); padding-bottom: 2px; }
.link-arrow::after { content: " →"; color: var(--accent); }
.link-arrow:hover { border-color: var(--accent); color: var(--text); }

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }

/* ==========================================================================
   Header
   ========================================================================== */
.site-header {
  position: sticky; top: 0; z-index: 50; height: var(--header-height);
  background: rgba(6, 7, 8, 0.9); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.header-inner { height: 100%; display: flex; align-items: center; justify-content: space-between; }

.brand-mark { height: 40px; width: auto; display: block; overflow: visible; }

/* Het logo komt binnen bij elke paginalading (~1,2 s, één keer):
   1. de S zakt zacht op zijn plek,
   2. de D schuift van achter de S naar rechts (het masker in het logo houdt hem
      verborgen zolang hij achter de S zit, dus hij lijkt eruit te komen),
   3. de naam volgt.
   Bij "minder beweging" (prefers-reduced-motion) zet de regel onder "Basis" alle
   animaties uit en staat alles meteen goed: de beginstand zit alleen in de keyframes. */
.brand-mark .sd-s, .brand-mark .sd-d { transform-box: fill-box; transform-origin: 50% 100%; }
.brand-mark .sd-s { animation: sd-s-in 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.brand-mark .sd-d { animation: sd-d-in 0.75s cubic-bezier(0.2, 0.8, 0.2, 1) 0.3s both; }
.brand-name { animation: sd-name-in 0.5s ease-out 0.75s both; }

@keyframes sd-s-in {
  from { opacity: 0; transform: translateY(-14%) scale(0.92); }
  to   { opacity: 1; transform: none; }
}
@keyframes sd-d-in {
  from { transform: translateX(-62%); }
  to   { transform: none; }
}
@keyframes sd-name-in {
  from { opacity: 0; transform: translateX(-0.5rem); }
  to   { opacity: 1; transform: none; }
}

.brand { display: inline-flex; align-items: center; gap: 0.65rem; font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; letter-spacing: -0.03em; color: var(--text); text-decoration: none; }
.brand-sub { color: var(--muted); font-weight: 500; }
.brand:hover { color: var(--text); }

.site-nav ul { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: var(--space-4); }
.site-nav a:not(.btn) { color: var(--muted); text-decoration: none; font-weight: 500; }
.site-nav a:not(.btn):hover { color: var(--text); }
/* De pagina waar je bent licht op: <body data-page="diensten"> + data-nav="diensten". */
[data-page="diensten"] .site-nav [data-nav="diensten"] { color: var(--text); }

.nav-toggle {
  display: none; width: 44px; height: 44px; position: relative; cursor: pointer;
  background: none; border: 1px solid var(--line-strong); border-radius: var(--radius-small);
}
.nav-toggle-bar, .nav-toggle-bar::before, .nav-toggle-bar::after {
  position: absolute; left: 11px; width: 20px; height: 2px; background: var(--text); content: ""; transition: transform 0.2s;
}
.nav-toggle-bar { top: 21px; }
.nav-toggle-bar::before { left: 0; top: -6px; }
.nav-toggle-bar::after  { left: 0; top: 6px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 760px) {
  .nav-toggle { display: block; }
  .site-nav { display: none; position: absolute; top: var(--header-height); left: 0; right: 0; background: var(--bg); border-bottom: 1px solid var(--line); padding: var(--space-2); }
  .site-nav.is-open { display: block; }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav a:not(.btn) { display: block; padding: 0.75rem 0; }
  .site-nav .btn { margin-top: var(--space-1); }

  /* Het menu schuift open en de items komen kort na elkaar binnen (2026-10-29).
     @starting-style is de stand waar de browser vandaan animeert zodra .is-open
     erop komt; "display ... allow-discrete" laat het menu bij sluiten eerst
     vervagen voordat het weg is. Kent de browser dit niet, dan opent het menu
     gewoon in één keer, zoals eerst. */
  .site-nav {
    opacity: 0; transform: translateY(-0.5rem);
    transition: opacity 0.25s ease-out, transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), display 0.3s allow-discrete;
  }
  .site-nav.is-open { opacity: 1; transform: none; }
  .site-nav li { transition: opacity 0.3s ease-out, transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
  .site-nav li:nth-child(2) { transition-delay: 0.04s; }
  .site-nav li:nth-child(3) { transition-delay: 0.08s; }
  .site-nav li:nth-child(4) { transition-delay: 0.12s; }
  @starting-style {
    .site-nav.is-open { opacity: 0; transform: translateY(-0.5rem); }
    .site-nav.is-open li { opacity: 0; transform: translateY(-0.4rem); }
  }
}

/* ==========================================================================
   Opening. Op de hoofdpagina (.hero) en op elke dienstpagina (.page-head):
   dezelfde opbouw, alleen de hoofdpagina heeft de foto erbij.
   ========================================================================== */
.hero, .page-head { padding: var(--space-6) 0 var(--space-5); }
.hero-inner { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 300px); gap: var(--space-5); align-items: end; }
@media (max-width: 900px) { .hero-inner { grid-template-columns: 1fr; } }

.lead { font-size: clamp(1.15rem, 1.6vw, 1.35rem); line-height: 1.55; color: var(--text-soft); max-width: 40rem; margin-bottom: var(--space-4); }
.hero h1, .page-head h1 { max-width: 15ch; margin-bottom: var(--space-4); }
.page-head h1 { font-size: clamp(2.4rem, 6vw, 4.6rem); }

/* Persoonlijke regel onder de knoppen: hoe snel en hoe je Zyon bereikt. */
.reach { margin: var(--space-4) 0 0; font-size: 0.95rem; color: var(--muted); }

.portrait { margin: 0; }
/* De foto is 2:3; in de hero tonen we 4:5 en houden we het hoofd in beeld. */
.portrait-img {
  display: block; width: 100%; height: auto; aspect-ratio: 4 / 5;
  object-fit: cover; object-position: 50% 0;
  background: var(--surface); border-radius: var(--radius);
}
.portrait figcaption { margin-top: var(--space-1); font-size: 0.9rem; color: var(--muted); }
.portrait figcaption strong { color: var(--text); font-weight: 600; }
@media (max-width: 900px) { .portrait { max-width: 240px; } }

/* Kruimelpad op dienstpagina's: waar je bent, en terug. */
.crumbs { margin: 0 0 var(--space-3); font-size: 0.95rem; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--text); }

/* ==========================================================================
   Blok: de enige sectievorm. Kop links (blijft staan tijdens scrollen),
   inhoud rechts, dunne lijn erboven.
   ========================================================================== */
.block { position: relative; padding: var(--space-6) 0; }
/* De lijn boven elk blok is een los element (geen border), zodat hij zich
   tijdens het scrollen kan trekken: zie "Beweging" onderaan. */
.block::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--line); transform-origin: left; }
.block-inner { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--space-3) var(--space-5); align-items: start; }
.block-head { position: sticky; top: calc(var(--header-height) + var(--space-4)); }
.block-head p { max-width: 22rem; }
/* Lange Nederlandse woorden (Procesautomatisering) mogen afbreken in plaats van uit de kolom te steken. */
.block-head h2 { font-size: clamp(1.8rem, 2.6vw, 2.4rem); hyphens: auto; overflow-wrap: break-word; }
.block-body > p { max-width: 42rem; font-size: 1.1rem; color: var(--text-soft); }
@media (max-width: 860px) {
  .block-inner { grid-template-columns: 1fr; }
  .block-head { position: static; }
}
/* Telefoon: halve witruimte tussen blokken en boven de opening, anders is het
   op een klein scherm vooral leeg scrollen. */
@media (max-width: 760px) {
  .block { padding: var(--space-5) 0; }
  .hero, .page-head { padding: var(--space-5) 0 var(--space-4); }
}

/* ==========================================================================
   Rijen: de enige lijstvorm. Icoon of label | inhoud | (pijl).
   ========================================================================== */
.rows { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); counter-reset: step; }
.rows > li { border-bottom: 1px solid var(--line); }
.row, .row-link {
  display: grid; grid-template-columns: var(--icon) minmax(0, 1fr) auto;
  gap: var(--space-1) var(--space-3); align-items: start;
  padding: var(--space-3) 0;
}
.row-link {
  color: var(--text); text-decoration: none;
  /* Hover: een blauwe lijn schuift van links over de lijn onder de rij. Het is
     een achtergrond van 1px hoog die van 0 naar 100% breed gaat. */
  background: linear-gradient(var(--accent), var(--accent)) left bottom / 0 1px no-repeat;
  transition: background-size 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.row-link:hover { background-size: 100% 1px; }
.row-link:hover { color: var(--text); }
.row-link:hover h3 { color: var(--accent); }
.row h3, .row-link h3 { margin: 0 0 0.3rem; transition: color 0.15s; }
.row p, .row-link p { margin: 0; }
.row-link::after { content: "→"; color: var(--accent); font-size: 1.3rem; line-height: 1; padding-top: 0.25rem; transition: transform 0.15s; }
.row-link:hover::after { transform: translateX(4px); }
.row-link.no-arrow::after { content: none; }
.row .sub { margin-top: var(--space-1); color: var(--text-soft); font-size: 0.95rem; }

/* Een genummerde rij (werkwijze): het nummer staat waar anders het icoon staat. */
.rows.steps > li { counter-increment: step; }
.rows.steps .row::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-serif); font-weight: 700; font-size: 1.5rem; line-height: 1.1; color: var(--accent);
}

/* Contactmanieren: dezelfde rijen, iets grotere tekst. */
.contact-ways .row-link { align-items: center; font-size: 1.25rem; font-weight: 600; }
.contact-ways .row-link > span { display: flex; flex-direction: column; line-height: 1.3; }
.contact-ways small { color: var(--muted); font-size: 0.85rem; font-weight: 500; }

/* Vanaf-prijs (uit PCC). In een dienstrij een regel onder de tekst, op een
   dienstpagina onder de inleiding. Het bedrag in de kopletter. */
.row-price, .price-from { margin: var(--space-1) 0 0; color: var(--muted); font-size: 0.9rem; }
.row-price strong, .price-from strong { font-family: var(--font-serif); font-size: 1.15rem; color: var(--text); font-variant-numeric: tabular-nums; }
.page-head .price-from { margin: 0 0 var(--space-3); font-size: 1rem; }
.page-head .price-from strong { font-size: 1.5rem; }

/* ==========================================================================
   Veelgestelde vragen (partials/vragen.html). Dezelfde lijnen als .rows;
   het plusje draait naar een min en het antwoord glijdt in beeld.
   ========================================================================== */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); padding: var(--space-3) 0; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary h3 { margin: 0; font-size: 1.1rem; transition: color 0.15s; }
.faq summary:hover h3 { color: var(--accent); }
.faq summary::after {
  content: ""; flex-shrink: 0; width: 14px; height: 14px;
  background: linear-gradient(var(--accent), var(--accent)) center / 14px 2px no-repeat,
              linear-gradient(var(--accent), var(--accent)) center / 2px 14px no-repeat;
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details > p { margin: 0; padding: 0 0 var(--space-3); color: var(--text-soft); max-width: 62ch; }
.faq details[open] > p { animation: rise-in 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }

/* ==========================================================================
   Gratis websitecheck (partials/websitecheck.html, main.js setupWebsiteCheck).
   ========================================================================== */
.check-form label { display: block; font-weight: 600; margin-bottom: var(--space-1); }
.check-row { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.check-row input {
  flex: 1 1 240px; min-width: 0; font: inherit; color: var(--text); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.7rem 1.2rem;
}
.check-row input:focus { border-color: var(--accent); outline: none; }
.check-row input[aria-invalid="true"] { border-color: var(--error); }
.check-status { margin: var(--space-2) 0 0; min-height: 1.6em; color: var(--muted); }
.check-status.is-error { color: var(--error); }
.check-results { list-style: none; margin: var(--space-2) 0 var(--space-3); padding: 0; border-top: 1px solid var(--line); }
.check-results li { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 3rem; gap: 0.4rem var(--space-2); align-items: center; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.check-results .what { font-weight: 600; }
.check-results .bar { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; }
.check-results .bar i { display: block; height: 100%; width: 0; border-radius: inherit; background: var(--c); transition: width 0.9s cubic-bezier(0.2, 0.8, 0.2, 1); }
.check-results .score { text-align: right; font-family: var(--font-serif); font-weight: 700; font-size: 1.2rem; color: var(--c); font-variant-numeric: tabular-nums; }
.check-results .why { grid-column: 2 / span 2; margin: 0; color: var(--muted); font-size: 0.9rem; }
.check-results .good { --c: var(--success); }
.check-results .fair { --c: var(--warning); }
.check-results .poor { --c: var(--error); }
.check-note { margin: var(--space-2) 0 0; color: var(--muted); font-size: 0.85rem; }
@media (max-width: 560px) {
  .check-results li { grid-template-columns: minmax(0, 1fr) 3rem; }
  .check-results .bar { grid-column: 1 / span 2; grid-row: 2; }
  .check-results .why { grid-column: 1 / span 2; }
}

/* ==========================================================================
   Rekenvoorbeeld en besparingscalculator (elke dienstpagina, partials/besparing.html).
   Een optelling: omschrijving links, bedrag rechts, lijnen zoals .rows.
   Het totaal (.sum-total) is de enige regel in het blauw.
   ========================================================================== */
.sum { list-style: none; margin: 0 0 var(--space-2); padding: 0; border-top: 1px solid var(--line); }
.sum li {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-1) var(--space-3);
  flex-wrap: wrap; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); color: var(--text-soft);
}
.sum strong { font-family: var(--font-serif); font-size: 1.15rem; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sum .sum-total { color: var(--text); font-weight: 600; }
.sum .sum-total strong { font-size: 1.6rem; color: var(--accent); }
.sum-intro { margin: 0 0 var(--space-2); }
.sum-note { margin: 0 0 var(--space-2); color: var(--muted); font-size: 0.85rem; max-width: 62ch; }
.calc-form { margin-bottom: var(--space-2); }
/* Startkorting onder de diensten op home: één regel, het woord vooraan in het blauw. */
.offer { margin: var(--space-3) 0 0; color: var(--text-soft); }
.offer strong { color: var(--accent); }

/* ==========================================================================
   Contact: rijen en formulier onder elkaar in de rechterkolom.
   ========================================================================== */
.contact { display: grid; gap: var(--space-5); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
@media (max-width: 520px) { .field-row { grid-template-columns: 1fr; } }
.field { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: var(--space-2); }
.field label { font-weight: 600; font-size: 0.95rem; }
.optional { color: var(--muted); font-weight: 400; }
.field input, .field select, .field textarea {
  font: inherit; color: var(--text); width: 100%;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-small);
  padding: 0.8rem 0.95rem;
}
.field textarea { resize: vertical; min-height: 140px; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); outline: none; }
.field [aria-invalid="true"] { border-color: var(--error); }
.field-check { flex-direction: row; align-items: flex-start; gap: 0.6rem; }
.field-check input { width: 18px; height: 18px; margin-top: 0.25rem; accent-color: var(--accent-strong); flex-shrink: 0; }
.field-check label { font-weight: 400; color: var(--muted); }
/* Honeypot: van het scherm geschoven, niet display:none (sommige bots slaan dat over). */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-status { margin: var(--space-2) 0 0; min-height: 1.6em; font-weight: 500; }
.form-status.is-success { color: var(--success); }
.form-status.is-error { color: var(--error); }

/* ==========================================================================
   Voorbeeldgesprek (alleen op de pagina AI-integratie). Zelfde lijnen en
   kleuren als de rest; de bubbels zijn het enige ronde.
   ========================================================================== */
.chat { margin: var(--space-3) 0 0; border: 1px solid var(--line); border-radius: var(--radius); max-width: 440px; }
.chat-head { display: flex; align-items: center; gap: 0.7rem; padding: 0.9rem 1.1rem; border-bottom: 1px solid var(--line); }
.chat-head .icon { width: 28px; height: 28px; color: var(--accent); }
.chat-head span { display: flex; flex-direction: column; line-height: 1.25; }
.chat-head small { color: var(--muted); font-size: 0.8rem; }
.chat-log { list-style: none; margin: 0; padding: 1.1rem; display: flex; flex-direction: column; gap: 0.55rem; }
.msg { max-width: 82%; padding: 0.55rem 0.8rem 0.4rem; border-radius: 14px; font-size: 0.95rem; line-height: 1.45; }
.msg time { display: block; text-align: right; font-size: 0.7rem; color: var(--muted); margin-top: 2px; }
.msg.in  { align-self: flex-start; background: var(--bubble-in); border-bottom-left-radius: 4px; }
.msg.out { align-self: flex-end; background: var(--bubble-out); border-bottom-right-radius: 4px; }
.msg.out time { color: var(--bubble-out-time); }
/* Waar een assistent zijn antwoord vandaan haalt (voorbeeld AI-assistent). */
.chat + .link-arrow { display: inline-block; margin-top: var(--space-3); }
.msg-source { display: block; margin-top: 0.35rem; font-size: 0.75rem; color: var(--bubble-out-time); }

/* ==========================================================================
   Footer en zwevende WhatsApp-knop
   ========================================================================== */
.site-footer { padding: var(--space-4) 0 var(--space-6); border-top: 1px solid var(--line); }
.footer-inner { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); }
.footer-inner p { margin: 0; font-size: 0.95rem; }
.footer-inner strong { color: var(--text); }

.wa-float {
  position: fixed; right: var(--space-3); bottom: var(--space-3); z-index: 60;
  width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent-strong); color: #fff; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  transition: background-color 0.2s;
}
.wa-float:hover { background: var(--accent-hover); color: #fff; }
.wa-float .icon { width: 28px; height: 28px; }

/* ==========================================================================
   Tekstpagina's (privacyverklaring, bedankpagina, 404)
   ========================================================================== */
.page { padding: var(--space-5) var(--space-2) var(--space-6); max-width: 760px; }
.page h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.page h2 { font-size: 1.35rem; margin-top: var(--space-4); }
.page li { color: var(--muted); }

/* Over mij: de bio uit het profiel, iets groter dan gewone tekst. */
.about-bio { margin-bottom: var(--space-4); }
.about-bio p { font-size: 1.15rem; color: var(--text-soft); max-width: 42rem; }

/* Een icoon boven een blokkop (pagina AI-integratie). */
.block-head .icon-lg { display: block; margin-bottom: var(--space-2); }

/* ==========================================================================
   Beweging (2026-10-05). Subtiel en strak (Catalogus): kort, alleen bij
   binnenkomen en scrollen, niets dat blijft bewegen.

   Vaste regel: de beginstand (onzichtbaar, verschoven) staat alléén in de
   keyframes, met "both". Zet de browser animaties uit (prefers-reduced-motion,
   regel onder "Basis"), of kent hij iets niet, dan staat alles gewoon goed.
   ========================================================================== */

/* 1. Opening. Het logo komt binnen (header), daarna de kop woord voor woord,
      dan een blauwe lijn onder het blauwe woord, dan de rest. Op de
      hoofdpagina staat elk woord in een .w; op dienstpagina's komt de kop als
      geheel. */
.hero h1 .w { display: inline-block; animation: rise-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.hero h1 .w:nth-child(1) { animation-delay: 0.35s; }
.hero h1 .w:nth-child(2) { animation-delay: 0.41s; }
.hero h1 .w:nth-child(3) { animation-delay: 0.47s; }
.hero h1 .w:nth-child(4) { animation-delay: 0.53s; }
.hero h1 .w:nth-child(5) { animation-delay: 0.59s; }
.hero h1 .w:nth-child(6) { animation-delay: 0.65s; }
.hero h1 .w:nth-child(7) { animation-delay: 0.71s; }
.hero h1 .w:nth-child(8) { animation-delay: 0.77s; }
.hero h1 .w:nth-child(9) { animation-delay: 0.83s; }

.page-head h1 { animation: rise-in 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) 0.3s both; }

.hero .lead, .page-head .lead { animation: rise-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) 0.95s both; }
.hero .actions, .page-head .actions, .hero .reach { animation: rise-in 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) 1.1s both; }
.hero .portrait { animation: fade-in 1s ease-out 0.6s both; }

/* De lijn onder het blauwe woord in de kop tekent zich van links naar rechts. */
.hero h1 em, .page-head h1 em { position: relative; display: inline-block; }
.hero h1 em::after, .page-head h1 em::after {
  content: ""; position: absolute; left: 0.04em; right: 0.04em; bottom: 0.02em; height: 0.055em;
  background: var(--accent); border-radius: 1px; transform-origin: left;
  animation: line-draw 0.7s cubic-bezier(0.65, 0, 0.35, 1) 1.15s both;
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(0.6rem); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes line-grow { from { transform: scaleY(0); } to { transform: none; } }
@keyframes step-light { from { color: var(--line-strong); } to { color: var(--accent); } }
@keyframes line-draw { from { transform: scaleX(0); } to { transform: none; } }
@keyframes icon-draw {
  from { stroke-dasharray: 1; stroke-dashoffset: 1; }
  to   { stroke-dasharray: 1; stroke-dashoffset: 0; }
}

/* 2 en 3. Tijdens het scrollen. Geen JavaScript: de browser koppelt de animatie
   aan hoe ver een element in beeld is (animation-timeline: view()). Lees
   "entry 0% entry 140px" als: begin zodra de bovenkant onderin het scherm
   verschijnt, klaar als hij 140px in beeld is. Browsers die dit nog niet kennen
   (Firefox) slaan het hele blok over en tonen alles meteen. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* De lijn boven een blok trekt zich van links naar rechts. */
    .block::before {
      animation: line-draw linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 220px;
    }
    /* Kop, tekst en elke rij schuiven zacht omhoog in beeld. */
    .block-head, .block-body > :not(.rows), .rows > li {
      animation: rise-in cubic-bezier(0.2, 0.8, 0.2, 1) both;
      animation-timeline: view();
      animation-range: entry 0% entry 140px;
    }
    /* Lijniconen tekenen zichzelf (pathLength="1" in het icoon, footer.html). */
    .icon-lg {
      animation: icon-draw cubic-bezier(0.65, 0, 0.35, 1) both;
      animation-timeline: view();
      animation-range: entry 40px entry 200px;
    }
    /* Werkwijze als tijdlijn: links een blauwe lijn die meegroeit terwijl je
       langs de stappen scrolt, en elk nummer licht op als je erbij bent. */
    .rows.steps { position: relative; padding-left: var(--space-3); }
    .rows.steps::before, .rows.steps::after {
      content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--line);
    }
    .rows.steps::after {
      background: var(--accent); transform-origin: top;
      animation: line-grow linear both;
      animation-timeline: view();
      animation-range: entry 60% cover 65%;
    }
    .rows.steps .row::before {
      animation: step-light linear both;
      animation-timeline: view();
      animation-range: entry 100% cover 40%;
    }
    /* (2026-10-29) Op de lijn een bolletje per stap dat blauw wordt, en de
       titel van de stap licht op, op hetzelfde moment als het nummer. */
    .rows.steps > li { position: relative; }
    .rows.steps > li::before {
      content: ""; position: absolute; width: 10px; height: 10px; border-radius: 50%;
      left: calc(1px - var(--space-3) - 5px); top: calc(var(--space-3) + 0.8rem - 5px);
      background: var(--bg); border: 2px solid var(--line-strong);
      animation: dot-light linear both;
      animation-timeline: view();
      animation-range: entry 100% cover 40%;
    }
    .rows.steps .row h3 {
      animation: text-light linear both;
      animation-timeline: view();
      animation-range: entry 100% cover 40%;
    }

    /* (2026-10-29) Over mij: de woorden van de bio lichten op terwijl je leest.
       main.js (setupReadingText) zet elk woord in een .wd met --k = zijn plek
       in de tekst (0 eerste woord, 1 laatste). Alle woorden volgen dezelfde
       tijdlijn (--bio, de hele bio); elk woord krijgt een eigen stukje ervan. */
    .about-bio { view-timeline: --bio; }
    .about-bio .wd {
      animation: text-light linear both;
      animation-timeline: --bio;
      animation-range: cover calc(12% + var(--k) * 38%) cover calc(16% + var(--k) * 38%);
    }
  }
}
@keyframes dot-light { to { background: var(--accent); border-color: var(--accent); } }
@keyframes text-light { from { color: var(--text-dim); } }

/* 10. Dienst vliegt open (js/page-reveal.js). Bij een klik van een dienstrij
       naar de dienstpagina groeit de titel uit de rij naar de grote kop, en
       terug weer andersom. fit-content: de overgang schaalt het blok van de
       tekst, niet de lege ruimte ernaast. */
.row-link h3, .page-head h1 { width: fit-content; }
::view-transition-group(dienst-titel) { animation-duration: 0.5s; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); }
.is-page-swap .page-head h1 { animation: none; }

/* ==========================================================================
   Kennismaking plannen (partials/plannen.html, main.js setupPlanner).
   Dag, dagdeel en manier kiezen; WhatsApp opent met het bericht al klaar.
   Keuzes zijn echte keuzerondjes, getekend als pil (zelfde rand als de
   invoer van de websitecheck).
   ========================================================================== */
.planner { display: grid; gap: var(--space-3); }
.planner h3, .planner p { margin: 0; }
.planner fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.planner legend { padding: 0; margin-bottom: var(--space-1); font-weight: 600; font-size: 0.95rem; }
.choices { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.choices label { position: relative; cursor: pointer; }
.choices input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.choices span {
  display: inline-block; padding: 0.45em 1em; border: 1px solid var(--line-strong); border-radius: 999px;
  color: var(--muted); transition: border-color 0.15s, color 0.15s;
}
.choices label:hover span { color: var(--text); }
.choices input:checked + span { border-color: var(--accent); color: var(--text); }
.choices input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 3px; }
.planner-preview { padding-left: var(--space-2); border-left: 2px solid var(--accent); color: var(--text-soft); }
.planner .btn { justify-self: start; }

/* 5. Vloeiende paginawissel tussen pagina's van deze site (View Transitions).
      Header en WhatsApp-knop blijven staan, de inhoud vervaagt en schuift
      omhoog. Bij een wissel komt het logo niet opnieuw binnen: js/page-reveal.js
      zet dan .is-page-swap op <html>. Browsers zonder ondersteuning laden de
      pagina gewoon zoals altijd. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.site-header { view-transition-name: site-header; }
.wa-float { view-transition-name: wa-float; }
::view-transition-old(root) { animation: 0.18s ease-in both fade-out; }
::view-transition-new(root) { animation: 0.35s cubic-bezier(0.2, 0.8, 0.2, 1) both rise-in; }
@keyframes fade-out { to { opacity: 0; } }

.is-page-swap .brand-mark .sd-s,
.is-page-swap .brand-mark .sd-d,
.is-page-swap .brand-name { animation: none; }

/* 7. Voorbeeldgesprek dat zichzelf afspeelt (main.js, setupChatDemos).
      .is-waiting zet main.js er pas op als JavaScript werkt; zonder staat het
      hele gesprek er meteen. De berichten houden hun plek, zodat niets
      verspringt. Tijdens het "typen" staat er "typt…" in de kop, zoals in
      WhatsApp. */
.chat.is-waiting .msg { opacity: 0; transform: translateY(0.5rem); transition: opacity 0.35s ease-out, transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.chat.is-waiting .msg.is-shown { opacity: 1; transform: none; }
.chat-head small.is-typing { color: var(--accent); }

/* 8. Muis op een dienstrij: het icoon tekent zich opnieuw (de lijn onder de rij
      en de pijl stonden er al). Alleen met een echte muis: op een telefoon
      blijft een "hover" anders hangen na een tik. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .row-link:hover .icon-lg {
    animation: icon-draw 0.8s cubic-bezier(0.65, 0, 0.35, 1) both;
    animation-timeline: auto;
  }
}

/* ==========================================================================
   Feedbackpagina (preview/feedback.html, alleen in de testversie).
   Zelfde velden en keuzepillen als het formulier en de planner.
   ========================================================================== */
.feedback { display: grid; gap: var(--space-5); margin-top: var(--space-4); }
.feedback fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--space-2); }
.feedback legend { padding: 0; margin-bottom: var(--space-2); font-family: var(--font-serif); font-weight: 700; font-size: 1.4rem; color: var(--text); }
.feedback fieldset > p { margin: 0; }
.feedback .field { margin-bottom: 0; }
.field-label { font-weight: 600; font-size: 0.95rem; }
.feedback .btn { justify-self: start; }
