/* ==========================================================================
   baken. — landing page.
   Every value is lifted from Baken Landing.dc.html, the visual source of
   truth, except the hero motion layer, which replaces the drawn beacon.
   Shared primitives live in components.css.
   ========================================================================== */

.bkn-page{background:var(--surface-page);color:var(--text-primary)}

/* --------------------------------------------------------------------------
   Type scale used across the page
   -------------------------------------------------------------------------- */

.display-2{margin:0;max-width:22em;font-size:var(--display-2);line-height:1;letter-spacing:var(--ls-display);font-weight:var(--weight-regular)}
.display-3{margin:0;font-size:var(--display-3);line-height:var(--lh-display-tight);letter-spacing:var(--ls-display-2);font-weight:var(--weight-regular)}
.display-4{margin:0;font-size:var(--display-4);line-height:1.04;letter-spacing:var(--ls-display-2);font-weight:var(--weight-regular)}
.display-5{margin:0;font-size:var(--display-5);line-height:1.05;letter-spacing:var(--ls-display-2);font-weight:var(--weight-regular)}
/* The brand's typographic signature: display at 400 with a 600 span inside. */
.display-2 em,.display-3 em,.hero__title em{font-style:normal;font-weight:var(--weight-semibold)}
.balance{text-wrap:balance}
.measure-20{max-width:20em}
.measure-22{max-width:22em}
.measure-24{max-width:24em}

.lede{margin:22px 0 0;max-width:32em;font-size:var(--body-lg);line-height:var(--lh-body);color:rgba(6,10,20,.62);text-wrap:pretty}
.lede--dark{color:rgba(243,239,232,.6)}
.lede--33{max-width:33em}
.lede--34{max-width:34em}

/* Section rhythm. */
.section{padding:var(--section-y) var(--gutter)}
.section--tall{padding:var(--section-y-lg) var(--gutter);position:relative}
.section--ruled{border-bottom:1px solid var(--border-hairline)}
.section--tail{padding:0 var(--gutter) var(--section-y)}
.section--dark{background:var(--surface-dark);color:var(--text-on-dark);position:relative;overflow:hidden}
.section__inner{position:relative}
.section__wash{position:absolute;left:50%;top:0;width:1100px;height:520px;transform:translateX(-50%);background:var(--wash-blue);pointer-events:none}

.split{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--column-gap);align-items:start}

/* Eyebrow variants this page needs. */
.eyebrow--systeem{color:rgba(243,239,232,.45)}
.eyebrow--systeem .eyebrow__rule,.eyebrow--wide.eyebrow--dark .eyebrow__rule{background:rgba(243,239,232,.3)}
.eyebrow--wide{margin-bottom:28px}

/* ==========================================================================
   HERO
   ========================================================================== */

.hero{position:relative;background:var(--surface-dark);color:var(--text-on-dark);overflow:hidden;min-height:100svh;display:flex;flex-direction:column;isolation:isolate}
.hero__wash-blue{position:absolute;inset:0;background:radial-gradient(58% 46% at 68% 40%,rgba(11,73,245,.34),rgba(11,73,245,0) 72%)}
.hero__wash-violet{position:absolute;inset:0;background:radial-gradient(30% 26% at 88% 76%,rgba(104,66,235,.16),transparent 70%)}
.hero__protect{position:absolute;left:0;right:0;bottom:0;height:38%;background:var(--protect-bottom)}

/* --------------------------------------------------------------------------
   Hero motion layer

   The video sits in exactly the box the drawn beacon scene occupied, so the
   hero's proportions are untouched. Two things make it read as part of the
   background rather than as a video placed on top of one:

   1. mix-blend-mode: screen. The clip's frame is near-black at its edges
      (sampled: rgb(0-1, 0-2, 12-15)), and screen(black, backdrop) === backdrop
      exactly. So every dark pixel — which is roughly the left 40% and all four
      corners of the frame — contributes literally nothing. There is no black
      box to hide, because black is mathematically absent. What is left is the
      light, which is what the brand is made of.

   2. A radial mask that reaches full transparency at all four edges. Sized
      `50% 50%` from the centre, so alpha hits exactly 0 at the left, right,
      top and bottom midpoints and is past 0 in the corners. That means no
      boundary can exist anywhere on the frame, whatever the clip does.

   The two work together: the mask guarantees the outline is gone, and screen
   keeps the fade region from ever reading as a dimmed rectangle.
   -------------------------------------------------------------------------- */

/* The box no longer hangs off the right edge (the design's -5% was sized for
   the drawn beacon, which was centred in its box). */
.hero__media{
  position:absolute;right:0;top:calc(50% + 34px);
  width:min(52vw,720px);aspect-ratio:1;transform:translateY(-50%);
  pointer-events:none;
}
.hero__video{
  position:absolute;inset:0;width:100%;height:100%;
  display:block;object-fit:cover;
  /* The island is not centred in the clip — its content sits in the right
     ~two thirds of the square frame, so mapping the frame straight onto the
     box pushed the lighthouse past the viewport. This slides the composition
     back inside without resizing or cropping it. The mask transforms with the
     element, so it stays aligned and no new seam appears. */
  transform:translateX(-11%);
  background:transparent;border:0;outline:0;
  mix-blend-mode:screen;
  -webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 0 60%,rgba(0,0,0,.72) 78%,rgba(0,0,0,.24) 91%,transparent 100%);
          mask-image:radial-gradient(ellipse 50% 50% at 50% 50%,#000 0 60%,rgba(0,0,0,.72) 78%,rgba(0,0,0,.24) 91%,transparent 100%);
  /* Held at 0 until the first frame is decodable, so there is never a poster
     flash, a black rectangle or a half-painted frame. landing.js adds
     .is-ready on canplay. */
  opacity:0;transition:opacity 1.4s var(--ease-beacon);
  pointer-events:none;
}
.hero__video.is-ready{opacity:1}
/* No scripting: show it anyway rather than leave the hero half-empty. */
html:not(.js) .hero__video{opacity:1}

/* Hero content. */
.hero__body{position:relative;z-index:10;flex:1;display:flex;align-items:flex-end;width:100%;padding:14vh var(--gutter) 7vh}
.hero__text{max-width:min(700px,46vw);animation:bkn-rise 1s var(--ease-beacon) both}
.hero__eyebrow{align-items:center;margin:0 0 34px}
.hero__eyebrow .eyebrow__rule{width:34px;background:rgba(243,239,232,.35)}
.hero__title{margin:0;font-size:var(--display-1);line-height:.95;letter-spacing:var(--ls-display);font-weight:var(--weight-regular);text-wrap:balance}
.hero__lead{margin:30px 0 0;max-width:30em;font-size:clamp(16px,1.3vw,19px);line-height:var(--lh-body-tight);color:var(--text-on-dark-secondary);text-wrap:pretty}
.hero .actions{align-items:center}
/* The hero's secondary button sits a shade dimmer and lifts to full sand. */
.btn--secondary-hero{color:rgba(243,239,232,.8)}
.btn--secondary-hero:hover{color:var(--text-on-dark);border-color:rgba(243,239,232,.6)}

/* ==========================================================================
   01 — Waar groei weglekt
   ========================================================================== */

.keyed-list{display:grid;gap:0;border-top:1px solid var(--border-rule)}
.keyed-row{display:flex;gap:20px;align-items:baseline;padding:22px 0;border-bottom:1px solid var(--border-rule)}
.keyed-row--last{border-bottom:0}
.keyed-row__key{font-family:var(--font-mono);font-size:var(--mono-label);color:var(--text-faint);flex:none}
.keyed-row__title{font-size:18px;font-weight:var(--weight-medium);letter-spacing:var(--ls-title-sm)}
.keyed-row__body{margin-top:6px;font-size:var(--body-sm);line-height:var(--lh-body-tight);color:rgba(6,10,20,.58)}
#lek .lede{margin:0 0 40px;max-width:var(--measure-text);color:rgba(6,10,20,.64)}

/* ==========================================================================
   02 — Eén verbonden groeisysteem
   ========================================================================== */

.layers{margin-top:var(--stack-gap);display:grid;gap:0;border-top:1px solid var(--border-on-dark-rule)}
.layer{display:grid;grid-template-columns:64px minmax(180px,1fr) minmax(240px,1.6fr);gap:24px;align-items:baseline;padding:30px 0;border-bottom:1px solid var(--border-on-dark-rule)}
.layer--last{border-bottom:0}
.layer__num{font-family:var(--font-mono);font-size:var(--mono-label);color:var(--blue-soft)}
.layer__title{font-size:var(--title-lg);font-weight:var(--weight-medium);letter-spacing:var(--ls-title)}
.layer__body{margin:0;font-size:var(--body);line-height:var(--lh-body-tight);color:var(--text-on-dark-tertiary)}

/* ==========================================================================
   03 — Diensten
   ========================================================================== */

.link-ghost--plain{display:inline;gap:normal}
.diensten__head{display:flex;flex-wrap:wrap;gap:24px;align-items:flex-end;justify-content:space-between}

/* An editorial carousel rather than a list: large portrait frames on a
   horizontal track, the label sitting directly underneath. No card chrome,
   no borders, no shadow — the photograph is the element.

   The rail deliberately runs past the right edge. Three frames sit fully in
   view and the fourth is cut roughly in half, which is what says "there is
   more here" — so nothing fades or masks that fourth frame. */
.carousel{
  margin-top:var(--stack-gap);
  /* Hold the measure's left edge, then bleed out past the section gutter. */
  padding-left:max(0px, calc((100% - var(--measure)) / 2));
  margin-right:calc(var(--gutter) * -1);
}
.carousel__viewport{overflow-x:hidden;overflow-y:visible}
.carousel__track{display:flex;gap:18px}

/* 28% + an 18px gap puts three frames in view and cuts the fourth at ~45%. */
.svc{flex:0 0 28%;display:block;color:var(--text-primary)}
.svc:hover{color:var(--text-primary)}
.svc:focus-visible{outline:2px solid var(--accent);outline-offset:6px;border-radius:var(--radius-xs)}

/* The frames are 3:4 and the source files are 0.747, so cover crops by well
   under a percent — nothing of the artwork is lost. */
.svc__frame{display:block;position:relative;overflow:hidden;aspect-ratio:3/4;border-radius:var(--radius-xs);background:var(--surface-dark)}
.svc__img{display:block;width:100%;height:100%;object-fit:cover;object-position:center;transition:transform .45s var(--ease-beacon)}
.svc:hover .svc__img,.svc:focus-visible .svc__img{transform:scale(1.03)}

.svc__meta{display:flex;align-items:baseline;gap:10px;margin-top:16px}
.svc__num{font-family:var(--font-mono);font-size:var(--mono-label);color:var(--text-faint);transition:color var(--dur)}
.svc__name{font-size:var(--title-sm);font-weight:var(--weight-medium);letter-spacing:var(--ls-title-sm);transition:transform var(--dur) var(--ease-beacon)}
.svc__arrow{margin-left:auto;color:var(--accent);opacity:0;transform:translateX(-6px);transition:opacity var(--dur),transform var(--dur) var(--ease-beacon)}
.svc:hover .svc__num,.svc:focus-visible .svc__num{color:var(--accent)}
.svc:hover .svc__name,.svc:focus-visible .svc__name{transform:translateX(2px)}
.svc:hover .svc__arrow,.svc:focus-visible .svc__arrow{opacity:1;transform:translateX(0)}

/* Square controls under the rail, right-aligned so they stack under the CTA.
   Architectural rather than the usual round carousel buttons: a hairline box
   on the cream ground that picks up the action blue on hover. The explicit
   margin shorthand keeps .measure's `margin:0 auto` from resetting the top. */
.carousel__nav{display:flex;justify-content:flex-end;gap:10px;margin:clamp(28px,3vw,44px) auto 0}
.cbtn{
  width:46px;height:46px;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-core);font-size:16px;line-height:1;
  color:var(--text-primary);
  background:transparent;
  border:1px solid var(--border-strong);
  border-radius:2px;
  cursor:pointer;
  transition:color var(--dur),border-color var(--dur),background var(--dur)
}
.cbtn:hover:not(:disabled){color:var(--accent);border-color:var(--accent)}
.cbtn:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.cbtn:disabled{opacity:.28;cursor:default}

/* ==========================================================================
   04 — Werkwijze
   ========================================================================== */

/* Het stappenraster komt uit workflow.css. De intro staat hier op .55 zoals
   in het ontwerp, iets lichter dan de standaard .lede. */
#werkwijze .lede{margin:26px 0 0;color:rgba(6,10,20,.55)}

/* ==========================================================================
   05 — Bewijs
   ========================================================================== */

.proof{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:clamp(32px,5vw,72px);align-items:center}
.proof__list{margin-top:34px;display:grid;gap:14px;max-width:32em}
.proof__item{display:flex;gap:14px;align-items:center;font-size:var(--body);color:rgba(6,10,20,.72)}
.proof__dot{display:block;width:5px;height:5px;border-radius:var(--radius-round);background:var(--blue);flex:none}
.placeholder{border:1px dashed var(--border-strong);background:var(--hatch);min-height:440px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;text-align:center;padding:32px}
.placeholder__dot{display:block;width:9px;height:9px;border-radius:var(--radius-round);background:var(--blue);box-shadow:0 0 0 5px rgba(11,73,245,.14),0 0 20px 5px rgba(11,73,245,.5)}
.placeholder__label{font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;color:var(--text-tertiary);max-width:22em;line-height:1.7}

/* ==========================================================================
   06 — Volgende stap
   ========================================================================== */

.contact__beam{position:absolute;left:50%;top:0;width:2px;height:150px;transform:translateX(-50%);background:var(--beam)}
.contact__wash{position:absolute;left:50%;top:0;width:760px;height:440px;transform:translateX(-50%);background:var(--wash-blue-strong);pointer-events:none}
.contact__box{max-width:44rem}
.contact__title{margin:0;font-size:clamp(30px,4.4vw,60px);line-height:1.01;letter-spacing:var(--ls-display);font-weight:var(--weight-regular)}
#contact .lede{margin:26px 0 0;color:rgba(243,239,232,.64)}
.actions--contact{margin-top:42px}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* The design's own rule for the hero scene: below 900px it drops to the
   bottom-right, scales down and drops to 60% opacity so it sits behind the
   text rather than beside it. The motion layer follows it exactly, which is
   what keeps the hero from growing on a phone. */
/* --------------------------------------------------------------------------
   Hero op mobiel: het eiland krijgt een eigen zone bóven de tekst.
   Volgorde wordt navigatie -> beeld -> eyebrow -> kop -> tekst -> knoppen.
   Het beeld staat dus niet meer naast of achter de kop maar erboven, en
   blijft in de flow zodat de hero met de inhoud meegroeit.
   -------------------------------------------------------------------------- */
@media (max-width:900px){
  .hero{min-height:0}
  .site-header{order:1}
  .hero__media{order:2}
  .hero__body{order:3}

  /* Vierkant en volle breedte: de bron is 2880x2880, dus er wordt niets
     bijgesneden. De verschuiving haalt het eiland - dat in de rechterhelft
     van het frame zit - terug naar het midden, iets rechts uitgebalanceerd. */
  /* De negatieve ondermarge trok de tekst het beeld in: de eyebrow kwam
     precies op de onderste lichtstreep te liggen. Hij is nu klein genoeg om
     de lege onderrand van het frame weg te nemen, maar niet zo groot dat de
     tekst het eiland weer raakt. */
  .hero__media{
    position:relative;right:auto;top:auto;bottom:auto;transform:none;
    width:100%;aspect-ratio:1;margin:6px 0 -10px;opacity:1;
  }
  /* Uitlijnen op de vuurtoren zelf, niet op het frame en niet op het
     zwaartepunt van het eiland. De lamp — het bovenste punt van de toren —
     staat op 67,9% van de bronbreedte (gemeten op een frame van 1440px:
     zwaartepunt van de helderste pixels in de bovenste rijen, 68,07% bij
     drempel 120 en 67,79% bij drempel 160).

     Met transform-origin in het midden geldt
        schermX(f) = B/2 + (f·B − B/2)·s + t·B
     en omdat .hero__media de volle breedte beslaat valt B/2 samen met het
     midden van het scherm. schermX(0,679) = B/2 geeft
        t = −s · (0,679 − 0,5) = −1,04 · 0,179 = −0,186
     Dat is onafhankelijk van de schermbreedte, dus het klopt op 375, 390 en
     430 even goed. De inhoud loopt van 31,3% tot 99,2% van het frame en
     blijft daarmee tussen x=51px en x=355px op een scherm van 430px: niets
     valt buiten beeld en er wordt niets bijgesneden. */
  .hero__video{transform:translateX(-18.6%) scale(1.04)}

  /* Lucht tussen het beeld en het label. */
  .hero__eyebrow{margin-top:6px}

  /* De onderbescherming bestond om tekst boven het beeld leesbaar te houden.
     Nu ze elkaar niet meer overlappen zou hij de tekst alleen verduisteren. */
  .hero__protect{display:none}

  .hero__body{flex:none;align-items:flex-start;padding:0 var(--gutter) clamp(56px,10vw,84px)}
  .hero__text{max-width:100%}
  .hero__title{font-size:clamp(34px,9.2vw,46px);line-height:1.02}
  .hero__lead{margin-top:20px;max-width:34em}
  .hero .actions{margin-top:28px;gap:10px}
}

/* Tablet: een vierkant op volle breedte wordt daar 750px hoog en verdringt
   de tekst. Begrensd en gecentreerd houdt het de compositie in verhouding. */
@media (min-width:601px) and (max-width:900px){
  .hero__media{width:min(100%,560px);margin-inline:auto;margin-bottom:-3vh}
  .hero__title{font-size:clamp(40px,6vw,52px)}
}

/* Smalle telefoons: knoppen op volle breedte in plaats van half afbrekend. */
@media (max-width:430px){
  .hero .actions{display:grid;grid-template-columns:1fr}
  .hero .actions .btn{justify-content:center}
}

/* Phone. The layer rows stop being a three-column grid — 64px + 180 + 240
   cannot survive a 375px screen — and stack instead. */
@media (max-width:640px){
  .layer{grid-template-columns:40px 1fr;gap:8px 18px}
  .layer__body{grid-column:2}
  .placeholder{min-height:320px}
}

/* ---- Diensten gallery ---------------------------------------------------
   Laptop keeps all five in the row and only tightens the gap. From tablet
   down the grid becomes a snapping rail that bleeds into the gutters, so the
   next frame is always partly visible — that peek is the affordance, which
   is why the scrollbar is hidden rather than relied on. */
/* Only the frame width changes across breakpoints — the rail, the bleed and
   the controls stay put. Part of the next frame is always cut off, at every
   size, so the horizontal gesture is never in doubt. */
@media (max-width:1180px){
  .carousel__track{gap:14px}
  .svc{flex-basis:36%}                           /* ~2.7 frames in view */
}
@media (max-width:900px){
  /* Touch takes over here: the rail scrolls natively and snaps. The arrows
     drive the very same scroll position, so both paths stay in agreement. */
  .carousel__viewport{
    overflow-x:auto;
    scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none;
  }
  .carousel__viewport::-webkit-scrollbar{display:none}
  .svc{flex-basis:52%;scroll-snap-align:start}   /* ~1.9 frames in view */
}
@media (max-width:600px){
  .svc{flex-basis:82%}                           /* ~1.25 frames in view */
}

/* Keep the video clear of the CTA row on short phones. */
@media (max-width:900px) and (max-height:720px){
  .hero__media{width:min(80vw,420px);bottom:-18%}
}
