/* Landingspagina voor ACCRD, vóór het inloggen. Hergebruikt bewust de kleuren/pillen/font uit
   styles.css (die zijn al 1-op-1 overgenomen van luzex.nl — zie :root daar) i.p.v. een nieuw
   kleurenschema te verzinnen. Alleen de lay-out hier is nieuw, want geen enkele bestaande pagina
   in dit platform heeft een marketing-achtige hero/stappen/kaarten-opzet.

   Kopij in de hero en de stappen-sectie is woordelijk overgenomen van de ACCRD-sectie op
   luzex.nl zelf — geen eigen marketingtekst verzonnen naast wat LuzeX daar al zegt. */

body.welkom-body {
  display: block;
  padding: 0;
  min-height: 100vh;
}

.welkom-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 1080px;
  margin: 0 auto;
  padding: 28px 24px 0;
}

.welkom-header .brand-logo {
  margin-bottom: 0;
}

.pil-knop {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.welkom-header .pil-knop-donker,
.welkom-cta-rij .pil-knop-donker {
  box-shadow: 0 12px 26px rgba(29, 29, 31, 0.26);
}

.pil-knop-donker {
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.16);
}

.pil-knop-donker:hover {
  background: var(--accent-hover);
}

.welkom-tekstlink {
  font-size: 15px;
  font-weight: 600;
}

/* ---------- Hero ---------- */

.welkom-hero {
  max-width: 1080px;
  margin: 0 auto;
  padding: 64px 24px 96px;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 48px;
  align-items: center;
}

.kicker {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.welkom-hero-tekst h1 {
  margin: 0 0 20px;
  font-size: clamp(32px, 4.2vw, 48px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.welkom-lead {
  margin: 0 0 32px;
  font-size: 18px;
  line-height: 1.5;
  color: var(--text-secondary);
  max-width: 46ch;
}

.welkom-cta-rij {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

/* Abstracte kaart-mockup i.p.v. een screenshot van de echte app — geen productiedata in een
   publieke marketingpagina, en geen extra afbeeldingsbestand nodig. */
.welkom-hero-beeld {
  position: relative;
}

.mockup-kaart {
  position: relative;
  background: var(--glas-bg);
  backdrop-filter: var(--glas-blur);
  -webkit-backdrop-filter: var(--glas-blur);
  border: 1px solid var(--glas-rand);
  border-radius: var(--radius-lg);
  box-shadow: var(--glas-schaduw);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* De regels komen van buiten het paneel aanvliegen. Zonder deze regel zweven ze als losse
     streepjes over de pagina in plaats van erin te landen — het paneel is de rand waar het
     werk binnenkomt, dus het knipt. */
  overflow: hidden;
}

.mockup-balk {
  width: 40%;
  height: 10px;
  border-radius: 6px;
  background: var(--text);
}

.mockup-rij {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.mockup-lijn {
  flex: 1;
  height: 8px;
  border-radius: 6px;
  background: var(--border);
}

.mockup-lijn.lang {
  flex: 1.6;
}

.mockup-lijn.licht {
  background: rgba(255, 255, 255, 0.35);
  flex: 1;
}

.mockup-vink {
  color: var(--success);
  font-weight: 700;
  font-size: 15px;
  width: 20px;
  text-align: center;
}

.mockup-vink-leeg {
  color: transparent;
  border: 1.5px dashed var(--border);
  border-radius: 50%;
  width: 14px;
  height: 14px;
}

.mockup-balkknop {
  margin-top: 18px;
  background: var(--accent);
  border-radius: var(--radius);
  padding: 16px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.mockup-pijl {
  color: var(--accent-contrast);
  font-weight: 700;
}

/* ---------- Stappen ---------- */

.welkom-stappen {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px 96px;
}

.badge {
  display: inline-block;
  margin: 0 0 14px;
  padding: 3px 10px;
  border-radius: 9px;
  background: var(--accent-tint);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
}

.welkom-stappen h2,
.welkom-rollen h2 {
  margin: 0 0 32px;
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.stappen-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}

.stap-nummer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--text);
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 12px;
}

.stap h3 {
  margin: 0 0 6px;
  font-size: 17px;
  font-weight: 700;
}

.stap p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 15px;
  line-height: 1.5;
}

/* ---------- Rollen ---------- */

.welkom-rollen {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px 96px;
}

.rollen-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.rollen-grid-twee {
  grid-template-columns: repeat(2, 1fr);
  max-width: 720px;
}

.rol-kaart {
  position: relative;
  background: var(--glas-bg);
  backdrop-filter: var(--glas-blur);
  -webkit-backdrop-filter: var(--glas-blur);
  border: 1px solid var(--glas-rand);
  box-shadow: var(--glas-schaduw);
  border-radius: var(--radius-lg);
  padding: 24px;
}

.rol-kaart h3 {
  margin: 0 0 8px;
  font-size: 17px;
  font-weight: 700;
}

.rol-kaart p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 14.5px;
  line-height: 1.5;
}

/* ---------- Abonnementen ---------- */

.welkom-abonnementen {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px 96px;
}

.welkom-lead-smal {
  max-width: 60ch;
  margin-bottom: 36px;
}

.pakketten-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  max-width: 1080px;
}

.pakket-kaart {
  position: relative;
  background: var(--glas-bg);
  backdrop-filter: var(--glas-blur);
  -webkit-backdrop-filter: var(--glas-blur);
  border: 1px solid var(--glas-rand);
  box-shadow: var(--glas-schaduw);
  border-radius: var(--radius-lg);
  padding: 28px;
}

.pakket-kaart-pro {
  border-color: var(--text);
}

.pakket-kaart h3 {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: 700;
}

.pakket-omschrijving {
  margin: 0 0 20px;
  color: var(--text-secondary);
  font-size: 14.5px;
  line-height: 1.5;
}

.pakket-lijst {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pakket-lijst li {
  font-size: 14.5px;
  line-height: 1.4;
  padding-left: 22px;
  position: relative;
}

.pakket-lijst li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--success);
  font-weight: 700;
}

/* ---------- Contact ---------- */

/* Zelfde donkerbruin als de contactsectie op luzex.nl zelf (#3b2e24) — geen losstaand
   kleurexperiment, letterlijk overgenomen (zie getComputedStyle-onderzoek bij het bouwen). */
.welkom-contact {
  background: #3b2e24;
  color: #ece6df;
  border-radius: var(--radius-lg);
  max-width: 1080px;
  margin: 0 auto 96px;
  padding: 64px 48px;
  text-align: center;
}

.welkom-contact h2 {
  margin: 0 0 12px;
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.welkom-contact-lead {
  margin: 0 0 40px;
  color: rgba(236, 230, 223, 0.7);
  font-size: 16px;
}

.contact-form {
  max-width: 480px;
  margin: 0 auto;
  text-align: left;
}

.contact-form .veld {
  margin-bottom: 20px;
}

.contact-form label {
  display: block;
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(236, 230, 223, 0.65);
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  border-radius: 16px;
  border: 1px solid rgba(236, 230, 223, 0.28);
  background: rgba(255, 255, 255, 0.07);
  color: #ece6df;
  font-family: inherit;
  font-size: 15px;
  resize: vertical;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: rgba(236, 230, 223, 0.45);
}

.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: rgba(236, 230, 223, 0.6);
}

.pil-knop-licht {
  background: #ece6df;
  color: #3b2e24;
  border: none;
  cursor: pointer;
  width: 100%;
  justify-content: center;
}

.pil-knop-licht:hover {
  background: #ffffff;
}

.welkom-contact .error,
.welkom-contact .success {
  text-align: center;
}

/* ---------- Footer ---------- */

.welkom-footer {
  max-width: 1080px;
  margin: 0 auto;
  padding: 32px 24px 48px;
}

.welkom-footer .brand-logo {
  margin-bottom: 0;
}

.footer-boven {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 32px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--border);
}

.footer-merk {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.footer-tagline {
  margin: 0;
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1.5;
  max-width: 32ch;
}

.footer-kolom {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.footer-kop {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.footer-kolom a {
  font-size: 14px;
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer-inaanbouw {
  font-size: 14px;
  color: var(--text-tertiary);
}

.footer-copyright {
  margin: 20px 0 0;
  color: var(--text-tertiary);
  font-size: 12px;
}

@media (max-width: 760px) {
  .welkom-hero {
    grid-template-columns: 1fr;
    padding-top: 40px;
  }

  .welkom-hero-beeld {
    order: -1;
  }

  .stappen-grid,
  .rollen-grid,
  .pakketten-grid {
    grid-template-columns: 1fr;
  }

  .welkom-contact {
    padding: 40px 24px;
  }

  .footer-boven {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---------- Liquid Glass op de landingspagina ----------

   De tokens komen uit styles.css; hier worden ze niet opnieuw gedefinieerd. Dat is geen
   gemakzucht maar de afspraak: wie een bestaand token herdefinieert, laat de twee kopieën
   van dit ontwerp uiteenlopen en dan is samenvoegen niet meer mogelijk. Wat hier bij komt,
   komt er alleen bij. */

/* Het licht achter het glas. Vier vlekken, elk met een eigen traagheid, zodat het beeld
   nooit precies herhaalt. Ze staan op de body en niet in de pagina: het is achtergrond. */
.welkom-body::before,
.welkom-body::after,
.welkom-hero::before,
.welkom-hero::after {
  content: "";
  position: fixed;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  filter: blur(80px);
  will-change: transform;
}

.welkom-body::before {
  /* Rechts en niet links. De tekstkolom van de hero staat links, en een terracotta vlek
     die daar onderdoor loopt drukt de kicker naar 3,46:1 (gemeten). Rechts staat het
     mockup-paneel, en dat is glas: daar mag dezelfde vlek juist vol doorkomen. */
  width: 620px;
  height: 620px;
  right: -180px;
  top: -200px;
  background: var(--glas-licht-terracotta);
  opacity: 0.55;
  animation: zweef-a 17s ease-in-out infinite alternate;
}

.welkom-body::after {
  width: 540px;
  height: 540px;
  right: -260px;
  top: 220px;
  background: var(--glas-licht-olijf);
  opacity: 0.42;
  animation: zweef-b 21s ease-in-out infinite alternate;
}

/* Diep bruin is de enige vlek die tekst echt kan breken: onder glas houdt de leadtekst
   4,53:1 tot opaciteit 0,35 en daarna niet meer. Vandaar 0,34, en onderaan de pagina,
   ver van de lopende tekst. */
.welkom-hero::before {
  width: 700px;
  height: 700px;
  right: -220px;
  bottom: -320px;
  background: var(--glas-licht-diep);
  opacity: 0.34;
  animation: zweef-c 24s ease-in-out infinite alternate;
}

.welkom-hero::after {
  /* Zand is de enige vlek die links mag staan: licht op licht kost de leadtekst niets
     (gemeten bovengrens 1,00 tegenover 0,63 voor terracotta). */
  width: 460px;
  height: 460px;
  left: -160px;
  top: 60px;
  background: var(--glas-licht-zand);
  opacity: 0.60;
  animation: zweef-a 19s ease-in-out infinite alternate-reverse;
}

@keyframes zweef-a {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(90px, -60px, 0) scale(1.14); }
}

@keyframes zweef-b {
  0% { transform: translate3d(0, 0, 0) scale(1.08); }
  100% { transform: translate3d(-110px, 70px, 0) scale(0.94); }
}

@keyframes zweef-c {
  0% { transform: translate3d(0, 0, 0) scale(0.96); }
  100% { transform: translate3d(60px, 90px, 0) scale(1.2); }
}

/* De glans hoort bij het materiaal, niet bij de twee animaties hieronder. Hij loopt alleen
   over het ene hero-paneel: meer dan één glans tegelijk en het wordt een casino. */
.mockup-kaart::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: var(--glas-glans);
  background-size: 280% 100%;
  opacity: 0.55;
  animation: glas-glans 9s cubic-bezier(0.45, 0, 0.2, 1) infinite;
}

/* ---------- Animatie 1: losse regels worden één factuur ----------
   Zeven seconden. De regels komen scheef aanvliegen, landen recht in het paneel, de balken
   trekken strak en de vinkjes zetten zich. De
   scheefstand per regel staat in de pagina als --dx/--dy/--r: dat is gegeven, geen stijl. */

.mockup-rij {
  animation: regel-landen 7s cubic-bezier(0.16, 0.84, 0.26, 1) var(--beurt, 0s) infinite;
  will-change: transform, opacity;
}

@keyframes regel-landen {
  0% { transform: translate(var(--dx), var(--dy)) rotate(var(--r)); opacity: 0; filter: blur(3px); }
  9% { opacity: 1; filter: blur(0); }
  50%, 92% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(0, 0) rotate(0deg); opacity: 0; }
}

.mockup-rij .mockup-lijn {
  animation: balk-strak 7s cubic-bezier(0.16, 0.84, 0.26, 1) var(--beurt, 0s) infinite;
}

@keyframes balk-strak {
  0% { flex-grow: 0.46; }
  50%, 100% { flex-grow: 1; }
}

.mockup-rij .mockup-vink {
  animation: vink-zetten 7s cubic-bezier(0.2, 0.7, 0.2, 1) var(--beurt, 0s) infinite;
}

@keyframes vink-zetten {
  0%, 52% { opacity: 0; transform: scale(0.6); }
  68%, 92% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}

/* ---------- Animatie 2: de stroom door ACCRD ----------
   Negen seconden. Op de donkerbruine baan reist een lichtpunt van hoofdaannemer naar
   onderaannemer naar uitbetaling, en elke stap licht op als het werk aankomt. De baan is
   dezelfde #3b2e24 als de contactsectie hieronder: één donkere kleur op deze pagina. */

.welkom-stappen {
  position: relative;
  background: #3b2e24;
  color: #f5efe7;
  border-radius: var(--radius-lg);
  padding: 56px 40px 64px;
  margin-bottom: 96px;
  overflow: hidden;
}

.welkom-stappen .badge {
  background: rgba(255, 255, 255, 0.14);
  color: #e3d3c0;
}

/* Gemeten op de baan met glas erover: #d8c6b2 haalt 4,16:1 boven een olijfvlek van 0,34 en
   zakt daaronder. Deze twee kleuren zitten daar ruim boven — #e3d3c0 op de donkerste plek
   die de vlekken maken: 5,6:1. */
.welkom-stappen .stap p {
  color: #e3d3c0;
}

.welkom-stappen .stap-nummer {
  border-color: rgba(255, 255, 255, 0.55);
  color: #f5efe7;
}

.welkom-stappen::before {
  content: "";
  position: absolute;
  width: 520px;
  height: 520px;
  left: -180px;
  top: -220px;
  border-radius: 50%;
  filter: blur(90px);
  background: var(--glas-licht-terracotta);
  /* 0,25 is de gemeten bovengrens voor #d8c6b2-achtige tekst op deze baan; de referentie
     gaf 0,44, en dat haalt 3,37:1. Het ontwerp verliest hier van de meting. */
  opacity: 0.16;
  animation: zweef-a 19s ease-in-out infinite alternate;
  pointer-events: none;
}

.welkom-stappen::after {
  content: "";
  position: absolute;
  width: 460px;
  height: 460px;
  right: -160px;
  bottom: -220px;
  border-radius: 50%;
  filter: blur(90px);
  background: var(--glas-licht-olijf);
  opacity: 0.16;
  animation: zweef-b 23s ease-in-out infinite alternate;
  pointer-events: none;
}

/* Het spoor is zelf de baan waarop het werk reist: de marge staat hier en niet op de lijn,
   zodat het lichtpunt in procenten van diezelfde baan kan bewegen. Reken je in pixels, dan
   klopt de afstand op één schermbreedte en op geen enkele andere. */
.stappen-spoor {
  position: relative;
  height: 34px;
  margin: 0 16% 22px;
}

.stappen-spoor-lijn {
  position: absolute;
  left: 0;
  right: 0;
  top: 16px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.75));
  transform-origin: left;
  animation: spoor 9s cubic-bezier(0.45, 0, 0.2, 1) infinite;
}

.stappen-werk {
  position: absolute;
  left: 0;
  top: 4px;
  margin-left: -13px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #fdf8f2;
  box-shadow: 0 0 26px 8px rgba(255, 236, 214, 0.55);
  animation: werk-reist 9s cubic-bezier(0.45, 0, 0.2, 1) infinite;
  will-change: transform;
}

@keyframes spoor {
  0%, 6% { transform: scaleX(0); }
  32%, 40% { transform: scaleX(0.5); }
  62%, 100% { transform: scaleX(1); }
}

/* In procenten van de baan, niet in pixels: de drie stappen staan in een grid dat met het
   scherm meeschaalt, en een vaste 450px landt op een telefoon naast de kaart. */
@keyframes werk-reist {
  0% { left: 0; opacity: 0; }
  4%, 10% { left: 0; opacity: 1; }
  32%, 40% { left: 50%; opacity: 1; }
  62%, 74% { left: 100%; opacity: 1; }
  82%, 100% { left: 100%; opacity: 0; }
}

.welkom-stappen .stap {
  position: relative;
  background: linear-gradient(142deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.05) 48%, rgba(255, 255, 255, 0.11));
  backdrop-filter: blur(26px) saturate(150%);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.20);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.34), 0 22px 50px rgba(0, 0, 0, 0.30);
  border-radius: 22px;
  padding: 24px 26px;
  animation: stap-oplichten 9s cubic-bezier(0.2, 0.7, 0.2, 1) infinite;
}

.welkom-stappen .stap:nth-child(2) { animation-delay: 3s; }
.welkom-stappen .stap:nth-child(3) { animation-delay: 6s; }

@keyframes stap-oplichten {
  0%, 4% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
  /* 0,08 en niet 0,10: de opgelichte stap is het slechtste geval van deze animatie, want
     daar wordt de ondergrond lichter terwijl de tekst licht blijft. Nagerekend haalt
     #e3d3c0 op de opgelichte kaart boven de zwaarste vlek 4,76:1; met 0,10 was dat 4,15:1. */
  10%, 30% { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.55); transform: translateY(-6px); }
  40%, 100% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
}

/* Terugval en stilte: dezelfde twee regels als in styles.css, want deze pagina heeft zijn
   eigen glas en zijn eigen beweging. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mockup-kaart,
  .rol-kaart,
  .pakket-kaart {
    background: var(--glas-vast);
  }

  .welkom-stappen .stap {
    background: rgba(255, 255, 255, 0.14);
  }

  .welkom-body::before,
  .welkom-body::after,
  .welkom-hero::before,
  .welkom-hero::after {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .welkom-body::before,
  .welkom-body::after,
  .welkom-hero::before,
  .welkom-hero::after,
  .mockup-kaart::after,
  .mockup-rij,
  .mockup-rij .mockup-lijn,
  .mockup-rij .mockup-vink,
  .stappen-spoor-lijn,
  .stappen-werk,
  .welkom-stappen .stap {
    animation: none !important;
  }

  /* Stil betekent niet onaf: zonder beweging hoort het eindbeeld te staan, niet het begin. */
  .stappen-spoor-lijn { transform: scaleX(1); }
  .stappen-werk { left: 100%; }
}

@media (max-width: 860px) {
  .welkom-stappen {
    padding: 40px 22px 48px;
  }

  /* Op één kolom reist het werk niet meer van links naar rechts; dan is het spoor een
     bewering die niet klopt en gaat het weg. */
  .stappen-spoor {
    display: none;
  }
}

/* Op zwart telt elk van deze vlekken drie keer zo zwaar; dezelfde meting als in styles.css. */
@media (prefers-color-scheme: dark) {
  .welkom-body::before { opacity: 0.18; }
  .welkom-body::after { opacity: 0.15; }
  .welkom-hero::before { opacity: 0.30; }
  .welkom-hero::after { opacity: 0.10; }
}

/* ---------- Nog twee keer hetzelfde gebaar, maar gestuurd door de scrollbalk ----------

   De hero-animatie hierboven loopt in een lus: hij begint wanneer de pagina laadt en
   herhaalt zich of je kijkt of niet. Deze twee doen hetzelfde gebaar — los aankomen,
   recht landen — maar hun voortgang hangt aan hoe ver jij gescrold bent. Scroll je
   halverwege, dan staat de animatie halverwege; scroll je terug, dan gaat hij terug.

   Dat kan met animation-timeline: view(), dat de voortgang koppelt aan de reis die het
   element door het scherm maakt. Chrome en Safari kennen het; Firefox nog niet. Daarom
   staat alles in @supports en is de ruststand het EINDbeeld: waar het niet werkt, staat
   gewoon de afgebouwde pagina en mist alleen de beweging. Nooit andersom — een animatie
   die niet draait mag geen halve pagina achterlaten.

   Ze tellen ook niet mee voor de twee lopende animaties per pagina: zonder scrollen
   beweegt hier niets. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* De twee rolkaarten komen van hun eigen kant aanschuiven en landen naast elkaar. */
    .rol-kaart {
      animation: kaart-landen linear both;
      animation-timeline: view();
      /* cover en niet entry: het "entry"-bereik is even lang als het element zelf, dus bij
         een kaart van 300px was de animatie na 300px scrollen al klaar terwijl de kaart
         nog 900px in beeld bleef. Gemeten: klaar na 28% van de zichtbare reis. Het
         cover-bereik is de hele passage door het scherm; 20% tot 60% daarvan valt precies
         in het midden — begonnen als je hem ziet, klaar voordat hij weggaat. */
      animation-range: cover 20% cover 60%;
    }

    /* Kant en draaiing apart, niet uitgerekend uit elkaar: een lengte maal een hoek is
       ongeldige CSS, en dan valt de hele transform-regel stil weg — de kaart vervaagt dan
       wel maar komt nergens vandaan. */
    .rollen-grid .rol-kaart:nth-child(1) { --kant: -60px; --draai: -2.4deg; }
    .rollen-grid .rol-kaart:nth-child(2) { --kant: 60px; --draai: 2.4deg; }
    .rollen-grid .rol-kaart:nth-child(3) { --kant: 0px; --draai: 0deg; }

    @keyframes kaart-landen {
      from { opacity: 0; transform: translate(var(--kant, 0px), 26px) rotate(var(--draai, 0deg)); }
      to { opacity: 1; transform: none; }
    }

    /* De regels van de pakketvergelijking komen één voor één binnen, van onder naar boven
       afgeteld. Elke regel begint iets later dan de vorige door zijn eigen bereik op te
       schuiven — met scrollen bestaat animation-delay niet, het bereik ís de vertraging. */
    .pakket-lijst li {
      animation: regel-binnen linear both;
      animation-timeline: view();
    }

    .pakket-lijst li:nth-child(1) { animation-range: cover 22% cover 56%; }
    .pakket-lijst li:nth-child(2) { animation-range: cover 26% cover 60%; }
    .pakket-lijst li:nth-child(3) { animation-range: cover 30% cover 64%; }
    .pakket-lijst li:nth-child(4) { animation-range: cover 34% cover 68%; }
    .pakket-lijst li:nth-child(5) { animation-range: cover 38% cover 72%; }

    @keyframes regel-binnen {
      from { opacity: 0; transform: translateX(-22px); }
      to { opacity: 1; transform: none; }
    }

    /* Het vinkje ervoor zet zich pas als de regel geland is. */
    .pakket-lijst li::before {
      animation: vink-binnen linear both;
      animation-timeline: view();
      animation-range: cover 32% cover 74%;
      transform-origin: center;
    }

    @keyframes vink-binnen {
      0%, 40% { opacity: 0; transform: scale(0.5); }
      100% { opacity: 1; transform: none; }
    }
  }
}

/* ---------- De hero-tekening aan de scrollbalk ----------

   Dezelfde omzetting als op luzex.nl, en om dezelfde reden: een lus die uit zichzelf
   herhaalt vraagt aandacht die je niet gegeven hebt, terwijl een animatie die met je
   meescrolt precies zo ver komt als jij wilt.

   De tijdlijn hangt hier aan de pagina (scroll()) en niet aan het element (view()), zoals
   bij de rolkaarten verderop. De hero staat al in beeld als de pagina laadt, dus er is
   geen binnenkomst om aan te meten — wat telt is hoe ver je gescrold bent.

   Twee dingen die op luzex.nl misgingen en hier meteen goed staan: de regels beginnen
   zichtbaar in plaats van doorzichtig (anders staat er bij scrollstand nul een leeg
   paneel, en dat leest als een pagina die nog laadt), en hun scheefstand begint op 42%
   van de afstand die de lus gebruikte, zodat ze binnen de rand van het paneel blijven —
   het paneel knipt, dus wat verder weg begint is bij scrollstand nul gewoon weg.

   Zonder ondersteuning voor scroll-tijdlijnen (Firefox) blijft de lus van zeven seconden
   hierboven staan; daar draait hij gewoon op de klok. */

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .mockup-rij {
      animation: regel-landen-scroll linear both;
      animation-timeline: scroll(root block);
      /* In pixels en niet in vh. Een vh-bereik groeit mee met de schermhoogte, maar de
         scrollstand waarop het paneel uit beeld verdwijnt doet dat niet: die ligt vast in
         de opmaak, op 560px, en is op 1440x900, 1920x1080 en 1512x760 exact gelijk. Met
         38vh liep de laatste regel op een scherm van 1080px hoog door tot 540 — twintig
         pixels voor de rand, en op een nog hoger scherm eroverheen.

         Hoe ver dan wel? De animatie hoort af te zijn als het paneel net over de helft van
         het scherm is. Dit paneel is klein (208px) en staat hoog (op 339), dus het is bij
         het laden al bijna op die hoogte — vandaar een korter bereik dan op luzex.nl. Met
         240px stond de onderkant nog maar op een derde van het scherm. */
      animation-range: 0 80px;
    }

    /* Met een scroll-tijdlijn bestaat animation-delay niet: het bereik ís de vertraging. */
    .mockup-rij:nth-of-type(2) { animation-range: 15px 95px; }
    .mockup-rij:nth-of-type(3) { animation-range: 30px 110px; }
    .mockup-rij:nth-of-type(4) { animation-range: 45px 125px; }
    .mockup-rij:nth-of-type(5) { animation-range: 60px 140px; }

    @keyframes regel-landen-scroll {
      0% {
        /* 0,26 en niet de 0,42 van luzex.nl: dat paneel is 4:5 en hoog, dit paneel is laag
           en breed. Met dezelfde factor worden de bovenste en onderste regel door de rand
           afgesneden en lijkt de kaart half leeg. */
        transform: translate(calc(var(--dx) * 0.26), calc(var(--dy) * 0.26)) rotate(var(--r));
        opacity: 0.55;
      }
      30% { opacity: 1; }
      100% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
    }

    .mockup-rij .mockup-lijn {
      animation: balk-strak-scroll linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 80px;
    }

    @keyframes balk-strak-scroll {
      from { flex-grow: 0.46; }
      to { flex-grow: 1; }
    }

    .mockup-rij .mockup-vink {
      animation: vink-zetten-scroll linear both;
      animation-timeline: scroll(root block);
      animation-range: 120px 200px;
    }

    @keyframes vink-zetten-scroll {
      from { opacity: 0; transform: scale(0.6); }
      30% { opacity: 1; }
      to { opacity: 1; transform: none; }
    }
  }
}

/* ---------- De huisstijl gelijktrekken met luzex.nl ----------

   Waarom de twee uiteenliepen, gemeten en niet gegokt: de kleuren en de vormen zijn al
   jaren gelijk (#cfc6bc, #1d1d1f, pilknoppen van 980px), maar de TYPOGRAFIE en het RITME
   niet. Dat komt doordat deze pagina op styles.css rijdt, en dat is de stylesheet van het
   ingelogde platform — een interfaceschaal: 14px basis, koppen van 16px, secties van 64px.
   luzex.nl heeft een eigen ontwerpsysteem met een marketingschaal: 15px basis, h1 tot 66px,
   secties van 96 tot 128px, een kolom van 1200px.

   Deze landingspagina is geen interface maar een etalage, dus hij hoort de marketingschaal
   te dragen. Gemeten stond het zo:

                      luzex.nl      accrd.luzex.nl
     basis            15px          14px
     h1               66px          48px
     sectiekop        44px          28px
     lopende tekst    18px          13px
     kolombreedte     1200px        1080px
     sectieruimte     96–128px      64–96px

   De andere kant op gelijktrekken kan niet: styles.css is gedeeld met het hele platform én
   met SCRNN, en daar de basis van 14px naar 15px tillen verandert achtendertig
   werkschermen om één etalage te laten kloppen. Alles hieronder staat daarom op
   .welkom-body en raakt niets buiten deze pagina. */

.welkom-body {
  font-size: 15px;
  line-height: 1.55;
}

/* De kolom en het ritme van luzex.nl: breder en rustiger. */
.welkom-hero,
.welkom-stappen,
.welkom-rollen,
.welkom-abonnementen,
.welkom-contact,
.welkom-header,
.welkom-footer {
  max-width: 1200px;
}

.welkom-hero {
  padding: clamp(72px, 8vw, 128px) 24px clamp(72px, 8vw, 112px);
  gap: clamp(28px, 5vw, 64px);
}

.welkom-stappen,
.welkom-rollen,
.welkom-abonnementen {
  padding-bottom: clamp(76px, 8vw, 125px);
}

/* De koppen. Dezelfde clamp-waarden als luzex.nl, zodat ze op elke schermbreedte
   hetzelfde meeschalen en niet alleen op 1440px toevallig gelijk zijn. */
.welkom-hero-tekst h1 {
  font-size: clamp(40px, 5.6vw, 66px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin-bottom: 20px;
}

.welkom-stappen h2,
.welkom-rollen h2,
.welkom-abonnementen h2,
.welkom-contact h2 {
  font-size: clamp(30px, 3.6vw, 44px);
  line-height: 1.12;
  letter-spacing: -0.025em;
}

/* Kaarttitels blijven kaartgroot — die zijn op luzex.nl ook niet meegegroeid. Alleen de
   sprong van 17 naar 20px, zodat een rolkaart en een pakketkaart dezelfde maat hebben. */
.rol-kaart h3 {
  font-size: 20px;
}

/* De lopende tekst. 13px was de maat van een interfacebijschrift; 17px is wat luzex.nl
   voor een alinea gebruikt. */
.welkom-lead {
  font-size: 18px;
  line-height: 1.6;
  max-width: 44ch;
}

.stap p,
.rol-kaart p,
.pakket-omschrijving,
.pakket-lijst li,
.welkom-contact-lead {
  font-size: 17px;
  line-height: 1.6;
}

.welkom-stappen .stap p {
  font-size: 15.5px;
}

/* Het bovenschrift: luzex.nl zet die in het diepbruin, niet in grijs. Gemeten haalt
   #3b2e24 op de achtergrond 8,9:1 — ruim boven de norm, en donkerder dan het grijs dat
   hier stond (4,58:1). */
.kicker {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--glas-licht-diep);
}

/* De knoppen: zelfde maat en zelfde raakvlak als op luzex.nl. */
.pil-knop {
  min-height: 44px;
  font-size: 15px;
  padding: 13px 26px;
}

/* Het logo is 232px breed en vast; naast een knop die met de marketingschaal meegroeide
   paste dat op een telefoon niet meer, en ze schoven over elkaar heen. Onder 560px krimpt
   het merk mee. De verhouding blijft staan (aspect-ratio doet de hoogte), dus het logo
   vervormt niet. */
@media (max-width: 560px) {
  .welkom-header {
    gap: 12px;
    padding-top: 20px;
  }

  .welkom-header .brand-logo {
    width: min(58vw, 180px);
  }

  .welkom-header .pil-knop {
    padding: 11px 18px;
    font-size: 14px;
  }
}

/* ---------- De zwevende balk ----------

   Hetzelfde onderdeel als op luzex.nl: een pil van glas die bovenaan blijft hangen, met
   het merk links, de secties in het midden en de belangrijkste actie rechts. Daar is dat
   "Neem contact op", hier "Inloggen" — dat is wat iemand op deze pagina komt doen.

   Geen taalwissel: ACCRD is eentalig Nederlands. Een knop die maar één stand heeft is
   geen keuze maar meubilair.

   De balk zweeft binnen de kolom en plakt niet tegen de bovenrand van het scherm; dat is
   wat hem een pil laat lijken in plaats van een werkbalk. */

.welkom-balkhouder {
  position: sticky;
  top: 0;
  z-index: 30;
  padding: 16px clamp(16px, 3vw, 24px) 0;
}

.welkom-balk {
  max-width: 1200px;
  margin: 0 auto;
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 32px);
  padding: 8px 8px 8px 22px;
  border-radius: var(--radius-pill);
  background: var(--glas-bg);
  backdrop-filter: var(--glas-blur);
  -webkit-backdrop-filter: var(--glas-blur);
  border: 1px solid var(--glas-rand);
  box-shadow: var(--glas-schaduw);
}

/* Het logo stond als los blok in de oude koptekst en had daar een ondermarge; in een pil
   die op hoogte uitgelijnd is, duwt die marge het merk omhoog. */
.welkom-balk .brand-logo {
  /* De breedte staat nu in styles.css; hier alleen wat de balk zelf nodig heeft. */
  margin-bottom: 0;
  flex-shrink: 0;
}

.welkom-nav {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.8vw, 28px);
  flex-grow: 1;
}

.welkom-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 4px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  letter-spacing: -0.01em;
}

.welkom-nav a:hover,
.welkom-nav a:focus-visible {
  color: var(--text);
}

.welkom-balk .pil-knop {
  flex-shrink: 0;
  padding: 11px 22px;
}

/* De balk hangt over de pagina heen, dus een sectie die je aanklikt moet onder de balk
   vandaan komen. Zonder dit staat de kop van elke sectie achter het glas. */
/* 108px en niet 92px: de balk eindigt op 81px, en met 92 kwam de kop van een sectie op
   elf pixels van het glas te staan. Dat leest als tegen de rand geplakt. */
#werkwijze,
#rollen,
#pakketten,
#contact {
  scroll-margin-top: 108px;
}

/* De hero begon met ruimte voor een koptekst die nu boven de pagina zweeft. */
.welkom-hero {
  padding-top: clamp(44px, 5vw, 76px);
}

/* Op een telefoon passen vier sectielinks niet naast het merk en de knop. De links gaan
   dan weg: ze zijn een snelkoppeling, geen inhoud — scrollen brengt je op dezelfde plek.
   De knop blijft, want dat is waarvoor iemand hier is. */
@media (max-width: 760px) {
  .welkom-nav {
    display: none;
  }

  .welkom-balk {
    justify-content: space-between;
    padding-left: 16px;
    gap: 8px;
  }

  .welkom-balk .brand-logo {
    width: min(38vw, 120px);
  }

  /* Zonder .welkom-nav ertussen delen logo, taalwissel en "Inloggen" één smalle rij. Beide
     buren hebben flex-shrink: 0 (zie hierboven/.pil-knop), dus zonder deze regel valt alle
     krimpdruk op de taalwissel — die knijpt dan tot vrijwel onzichtbaar in plaats van gewoon
     compacter te worden. */
  .welkom-balk .taal {
    flex-shrink: 0;
    padding: 2px;
  }

  .welkom-balk .taal button {
    padding: 4px 8px;
    font-size: 11.5px;
  }

  .welkom-balk .pil-knop {
    padding: 9px 14px;
    font-size: 13.5px;
  }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .welkom-balk {
    background: var(--glas-vast);
  }
}

/* ---------- De stroom door ACCRD aan de scrollbalk ----------

   De laatste lus die nog op een klok liep. Het lichtpunt reist nu van hoofdaannemer naar
   onderaannemer naar uitbetaling terwijl de baan door het scherm komt, en elke stap licht
   op op het moment dat het punt er is. Scroll je terug, dan gaat het werk terug.

   De tijdlijn hangt hier aan de baan zelf (view()) en niet aan de pagina (scroll()), anders
   dan bij de hero: deze sectie staat halverwege de pagina, dus de reis die hij door het
   scherm maakt is precies de maat die je wilt. De hero heeft die reis niet — die staat er
   al als je aankomt.

   Elke stap krijgt zijn eigen stuk van het bereik in plaats van een vertraging: met een
   scroll-tijdlijn bestaat animation-delay niet.

   Daarmee beweegt er op deze pagina niets meer uit zichzelf, op de glans over het
   hero-paneel na. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .welkom-stappen {
      view-timeline-name: --stroom;
      view-timeline-axis: block;
    }

    .stappen-spoor-lijn {
      animation: spoor-scroll linear both;
      animation-timeline: --stroom;
      animation-range: cover 15% cover 72%;
    }

    @keyframes spoor-scroll {
      from { transform: scaleX(0); }
      to { transform: scaleX(1); }
    }

    .stappen-werk {
      animation: werk-scroll linear both;
      animation-timeline: --stroom;
      animation-range: cover 15% cover 72%;
    }

    @keyframes werk-scroll {
      from { left: 0; opacity: 1; }
      to { left: 100%; opacity: 1; }
    }

    /* De drie stappen lichten op als het punt bij ze is. Alle vier de animaties delen
       ÉÉN bereik en de timing zit in de keyframes, niet in aparte bereiken per stap.
       Dat laatste probeerde ik eerst en het werkte niet betrouwbaar: bereiken als
       "entry 78% cover 36%" lopen in de verkeerde volgorde en leveren dan een stap op
       die nooit aangaat. Met één bereik staat het punt op 50% ook precies bij stap twee.

       Het punt reist links 0% -> 100%; stap 1 staat op 0% van de baan, stap 2 op 50% en
       stap 3 op 100%. Daar liggen de drie momenten hieronder op. */
    .welkom-stappen .stap {
      animation-timeline: --stroom;
      animation-range: cover 15% cover 72%;
      animation-timing-function: linear;
      animation-fill-mode: both;
    }

    .welkom-stappen .stap:nth-child(1) { animation-name: stap-een; }
    .welkom-stappen .stap:nth-child(2) { animation-name: stap-twee; }
    .welkom-stappen .stap:nth-child(3) { animation-name: stap-drie; }

    @keyframes stap-een {
      0%, 2% { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.55); transform: translateY(-6px); }
      16% { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.55); transform: translateY(-6px); }
      30%, 100% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
    }

    @keyframes stap-twee {
      0%, 36% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
      44%, 60% { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.55); transform: translateY(-6px); }
      70%, 100% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
    }

    @keyframes stap-drie {
      0%, 80% { background-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0.20); transform: translateY(0); }
      90%, 100% { background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.55); transform: translateY(-6px); }
    }
  }
}

.divider-glass {
  height: 1px;
  border: 0;
  margin: 32px 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.15);
}
