/* Creative Media Minds - generated by build.sh on 2026-11-02.
   Edit the files in css/, not this one. */

/* ===== css/vendor/sizes.min.css ===== */
:where(html){--size-000:-.5rem;--size-00:-.25rem;--size-1:.25rem;--size-2:.5rem;--size-3:1rem;--size-4:1.25rem;--size-5:1.5rem;--size-6:1.75rem;--size-7:2rem;--size-8:3rem;--size-9:4rem;--size-10:5rem;--size-11:7.5rem;--size-12:10rem;--size-13:15rem;--size-14:20rem;--size-15:30rem;--size-px-000:-8px;--size-px-00:-4px;--size-px-1:4px;--size-px-2:8px;--size-px-3:16px;--size-px-4:20px;--size-px-5:24px;--size-px-6:28px;--size-px-7:32px;--size-px-8:48px;--size-px-9:64px;--size-px-10:80px;--size-px-11:120px;--size-px-12:160px;--size-px-13:240px;--size-px-14:320px;--size-px-15:480px;--size-fluid-1:max(.5rem,min(1vw,1rem));--size-fluid-2:max(1rem,min(2vw,1.5rem));--size-fluid-3:max(1.5rem,min(3vw,2rem));--size-fluid-4:max(2rem,min(4vw,3rem));--size-fluid-5:max(4rem,min(5vw,5rem));--size-fluid-6:max(5rem,min(7vw,7.5rem));--size-fluid-7:max(7.5rem,min(10vw,10rem));--size-fluid-8:max(10rem,min(20vw,15rem));--size-fluid-9:max(15rem,min(30vw,20rem));--size-fluid-10:max(20rem,min(40vw,30rem));--size-content-1:20ch;--size-content-2:45ch;--size-content-3:60ch;--size-header-1:20ch;--size-header-2:25ch;--size-header-3:35ch;--size-xxs:240px;--size-xs:360px;--size-sm:480px;--size-md:768px;--size-lg:1024px;--size-xl:1440px;--size-xxl:1920px;--size-relative-000:-.5ch;--size-relative-00:-.25ch;--size-relative-1:.25ch;--size-relative-2:.5ch;--size-relative-3:1ch;--size-relative-4:1.25ch;--size-relative-5:1.5ch;--size-relative-6:1.75ch;--size-relative-7:2ch;--size-relative-8:3ch;--size-relative-9:4ch;--size-relative-10:5ch;--size-relative-11:7.5ch;--size-relative-12:10ch;--size-relative-13:15ch;--size-relative-14:20ch;--size-relative-15:30ch}
/* ===== css/vendor/easings.min.css ===== */
:where(html){--ease-1:cubic-bezier(.25,0,.5,1);--ease-2:cubic-bezier(.25,0,.4,1);--ease-3:cubic-bezier(.25,0,.3,1);--ease-4:cubic-bezier(.25,0,.2,1);--ease-5:cubic-bezier(.25,0,.1,1);--ease-in-1:cubic-bezier(.25,0,1,1);--ease-in-2:cubic-bezier(.50,0,1,1);--ease-in-3:cubic-bezier(.70,0,1,1);--ease-in-4:cubic-bezier(.90,0,1,1);--ease-in-5:cubic-bezier(1,0,1,1);--ease-out-1:cubic-bezier(0,0,.75,1);--ease-out-2:cubic-bezier(0,0,.50,1);--ease-out-3:cubic-bezier(0,0,.3,1);--ease-out-4:cubic-bezier(0,0,.1,1);--ease-out-5:cubic-bezier(0,0,0,1);--ease-in-out-1:cubic-bezier(.1,0,.9,1);--ease-in-out-2:cubic-bezier(.3,0,.7,1);--ease-in-out-3:cubic-bezier(.5,0,.5,1);--ease-in-out-4:cubic-bezier(.7,0,.3,1);--ease-in-out-5:cubic-bezier(.9,0,.1,1);--ease-elastic-out-1:cubic-bezier(.5,.75,.75,1.25);--ease-elastic-out-2:cubic-bezier(.5,1,.75,1.25);--ease-elastic-out-3:cubic-bezier(.5,1.25,.75,1.25);--ease-elastic-out-4:cubic-bezier(.5,1.5,.75,1.25);--ease-elastic-out-5:cubic-bezier(.5,1.75,.75,1.25);--ease-elastic-in-1:cubic-bezier(.5,-0.25,.75,1);--ease-elastic-in-2:cubic-bezier(.5,-0.50,.75,1);--ease-elastic-in-3:cubic-bezier(.5,-0.75,.75,1);--ease-elastic-in-4:cubic-bezier(.5,-1.00,.75,1);--ease-elastic-in-5:cubic-bezier(.5,-1.25,.75,1);--ease-elastic-in-out-1:cubic-bezier(.5,-.1,.1,1.5);--ease-elastic-in-out-2:cubic-bezier(.5,-.3,.1,1.5);--ease-elastic-in-out-3:cubic-bezier(.5,-.5,.1,1.5);--ease-elastic-in-out-4:cubic-bezier(.5,-.7,.1,1.5);--ease-elastic-in-out-5:cubic-bezier(.5,-.9,.1,1.5);--ease-step-1:steps(2);--ease-step-2:steps(3);--ease-step-3:steps(4);--ease-step-4:steps(7);--ease-step-5:steps(10);--ease-elastic-1:var(--ease-elastic-out-1);--ease-elastic-2:var(--ease-elastic-out-2);--ease-elastic-3:var(--ease-elastic-out-3);--ease-elastic-4:var(--ease-elastic-out-4);--ease-elastic-5:var(--ease-elastic-out-5);--ease-squish-1:var(--ease-elastic-in-out-1);--ease-squish-2:var(--ease-elastic-in-out-2);--ease-squish-3:var(--ease-elastic-in-out-3);--ease-squish-4:var(--ease-elastic-in-out-4);--ease-squish-5:var(--ease-elastic-in-out-5);--ease-spring-1:linear(0,0.006,0.025 2.8%,0.101 6.1%,0.539 18.9%,0.721 25.3%,0.849 31.5%,0.937 38.1%,0.968 41.8%,0.991 45.7%,1.006 50.1%,1.015 55%,1.017 63.9%,1.001);--ease-spring-2:linear(0,0.007,0.029 2.2%,0.118 4.7%,0.625 14.4%,0.826 19%,0.902,0.962,1.008 26.1%,1.041 28.7%,1.064 32.1%,1.07 36%,1.061 40.5%,1.015 53.4%,0.999 61.6%,0.995 71.2%,1);--ease-spring-3:linear(0,0.009,0.035 2.1%,0.141 4.4%,0.723 12.9%,0.938 16.7%,1.017,1.077,1.121,1.149 24.3%,1.159,1.163,1.161,1.154 29.9%,1.129 32.8%,1.051 39.6%,1.017 43.1%,0.991,0.977 51%,0.974 53.8%,0.975 57.1%,0.997 69.8%,1.003 76.9%,1);--ease-spring-4:linear(0,0.009,0.037 1.7%,0.153 3.6%,0.776 10.3%,1.001,1.142 16%,1.185,1.209 19%,1.215 19.9% 20.8%,1.199,1.165 25%,1.056 30.3%,1.008 33%,0.973,0.955 39.2%,0.953 41.1%,0.957 43.3%,0.998 53.3%,1.009 59.1% 63.7%,0.998 78.9%,1);--ease-spring-5:linear(0,0.01,0.04 1.6%,0.161 3.3%,0.816 9.4%,1.046,1.189 14.4%,1.231,1.254 17%,1.259,1.257 18.6%,1.236,1.194 22.3%,1.057 27%,0.999 29.4%,0.955 32.1%,0.942,0.935 34.9%,0.933,0.939 38.4%,1 47.3%,1.011,1.017 52.6%,1.016 56.4%,1 65.2%,0.996 70.2%,1.001 87.2%,1);--ease-bounce-1:linear(0,0.004,0.016,0.035,0.063,0.098,0.141,0.191,0.25,0.316,0.391 36.8%,0.563,0.766,1 58.8%,0.946,0.908 69.1%,0.895,0.885,0.879,0.878,0.879,0.885,0.895,0.908 89.7%,0.946,1);--ease-bounce-2:linear(0,0.004,0.016,0.035,0.063,0.098,0.141 15.1%,0.25,0.391,0.562,0.765,1,0.892 45.2%,0.849,0.815,0.788,0.769,0.757,0.753,0.757,0.769,0.788,0.815,0.85,0.892 75.2%,1 80.2%,0.973,0.954,0.943,0.939,0.943,0.954,0.973,1);--ease-bounce-3:linear(0,0.004,0.016,0.035,0.062,0.098,0.141 11.4%,0.25,0.39,0.562,0.764,1 30.3%,0.847 34.8%,0.787,0.737,0.699,0.672,0.655,0.65,0.656,0.672,0.699,0.738,0.787,0.847 61.7%,1 66.2%,0.946,0.908,0.885 74.2%,0.879,0.878,0.879,0.885 79.5%,0.908,0.946,1 87.4%,0.981,0.968,0.96,0.957,0.96,0.968,0.981,1);--ease-bounce-4:linear(0,0.004,0.016 3%,0.062,0.141,0.25,0.391,0.562 18.2%,1 24.3%,0.81,0.676 32.3%,0.629,0.595,0.575,0.568,0.575,0.595,0.629,0.676 48.2%,0.811,1 56.2%,0.918,0.86,0.825,0.814,0.825,0.86,0.918,1 77.2%,0.94 80.6%,0.925,0.92,0.925,0.94 87.5%,1 90.9%,0.974,0.965,0.974,1);--ease-bounce-5:linear(0,0.004,0.016 2.5%,0.063,0.141,0.25 10.1%,0.562,1 20.2%,0.783,0.627,0.534 30.9%,0.511,0.503,0.511,0.534 38%,0.627,0.782,1 48.7%,0.892,0.815,0.769 56.3%,0.757,0.753,0.757,0.769 61.3%,0.815,0.892,1 68.8%,0.908 72.4%,0.885,0.878,0.885,0.908 79.4%,1 83%,0.954 85.5%,0.943,0.939,0.943,0.954 90.5%,1 93%,0.977,0.97,0.977,1);--ease-circ-in:cubic-bezier(.6,.04,.98,.335);--ease-circ-in-out:cubic-bezier(.785,.135,.15,.86);--ease-circ-out:cubic-bezier(.075,.82,.165,1);--ease-cubic-in:cubic-bezier(.55,.055,.675,.19);--ease-cubic-in-out:cubic-bezier(.645,.045,.355,1);--ease-cubic-out:cubic-bezier(.215,.61,.355,1);--ease-expo-in:cubic-bezier(.95,.05,.795,.035);--ease-expo-in-out:cubic-bezier(1,0,0,1);--ease-expo-out:cubic-bezier(.19,1,.22,1);--ease-quad-in:cubic-bezier(.55,.085,.68,.53);--ease-quad-in-out:cubic-bezier(.455,.03,.515,.955);--ease-quad-out:cubic-bezier(.25,.46,.45,.94);--ease-quart-in:cubic-bezier(.895,.03,.685,.22);--ease-quart-in-out:cubic-bezier(.77,0,.175,1);--ease-quart-out:cubic-bezier(.165,.84,.44,1);--ease-quint-in:cubic-bezier(.755,.05,.855,.06);--ease-quint-in-out:cubic-bezier(.86,0,.07,1);--ease-quint-out:cubic-bezier(.23,1,.32,1);--ease-sine-in:cubic-bezier(.47,0,.745,.715);--ease-sine-in-out:cubic-bezier(.445,.05,.55,.95);--ease-sine-out:cubic-bezier(.39,.575,.565,1)}
/* ===== css/vendor/borders.min.css ===== */
:where(html){--border-size-1:1px;--border-size-2:2px;--border-size-3:5px;--border-size-4:10px;--border-size-5:25px;--radius-1:2px;--radius-2:5px;--radius-3:1rem;--radius-4:2rem;--radius-5:4rem;--radius-6:8rem;--radius-drawn-1:255px 15px 225px 15px/15px 225px 15px 255px;--radius-drawn-2:125px 10px 20px 185px/25px 205px 205px 25px;--radius-drawn-3:15px 255px 15px 225px/225px 15px 255px 15px;--radius-drawn-4:15px 25px 155px 25px/225px 150px 25px 115px;--radius-drawn-5:250px 25px 15px 20px/15px 80px 105px 115px;--radius-drawn-6:28px 100px 20px 15px/150px 30px 205px 225px;--radius-round:1e5px;--radius-blob-1:30% 70% 70% 30%/53% 30% 70% 47%;--radius-blob-2:53% 47% 34% 66%/63% 46% 54% 37%;--radius-blob-3:37% 63% 56% 44%/49% 56% 44% 51%;--radius-blob-4:63% 37% 37% 63%/43% 37% 63% 57%;--radius-blob-5:49% 51% 48% 52%/57% 44% 56% 43%;--radius-conditional-1:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-1));--radius-conditional-2:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-2));--radius-conditional-3:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-3));--radius-conditional-4:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-4));--radius-conditional-5:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-5));--radius-conditional-6:clamp(0px,calc(100vw - 100%) * 1e5,var(--radius-6))}
/* ===== css/tokens.css ===== */
/* ==========================================================================
   Design tokens — Creative Media Minds
   Palette from Figma (node 156:540). Type system follows the erfbouwen.nl
   model: FIXED sizes, never fluid.

   WHY NO clamp(): a fluid scale makes every size a range you cannot name,
   so nothing is ever exactly the design value and "pixel perfect" stops
   meaning anything. Each rung is one fixed number, and there is ONE
   breakpoint at 960px where the whole scale steps down. At 960 and above
   every size is the Figma value exactly.

   Each rung carries its size, line-height AND letter-spacing, because a
   type token is all three or it is not a token. The same number can appear
   in two families with different leading — title-4 and body-1 are both
   20px, set at 1.1 and 1.45. That is the point of a rung rather than a size.
   ========================================================================== */

:root {
  /* ---- Palette --------------------------------------------------------- */
  /* Two colours, each with one job, everywhere on the page:
     --brand, the deep blue, is the voice -- headings, text, the dark
     surfaces (header mark, planner bands, footer). --accent, the purple,
     is the hand -- only what can be clicked: buttons, links, the
     header's Contact, chosen tags. Both from the hero. White on brand is
     8.2:1, on accent 5.1:1; accent text on white 5.1:1. */
  --brand: #1f5276;
  --accent: #7c6496;
  --accent-strong: #644e7c; /* hover; white on it 7.0:1 */

  /* The hero's pink: brightness only, never a control, and kept out of
     Studio. A deep one for small marks on white (6.4:1). */
  --pink: #f0b6f4;
  --pink-deep: #9b3f8e;

  --blue: #0000ff;          /* focus ring */
  --blush: #f1e5e5;         /* Studio panel */
  --black: #000;
  --white: #fff;

  /* Type in the brand's family: headings in the brand blue itself, body
     text a darker blue for long reading, the softer ones greyed from it.
     On white: 8.2, 11.9, 7.0 and 6.2:1; on blush all above 5.5:1. */
  --ink-strong: var(--brand);  /* headings */
  --ink: #1b3347;              /* body text */
  --ink-soft: #445a6b;         /* intros under a display heading */
  --muted: #4f6272;
  /* Planner (Figma 266:3614). Each phase has a tint (the bar) and a tone
     (the block at the bar's start, its client diamonds, its mobile
     timeline segment) -- the site's own colours: blush, lilac, blue, and
     a green to finish. Black on every tint is above 11:1. The tones are
     decoration; every diamond has its words next to it. */
  /* One family, light to dark, ending in the hero's purple and blue. */
  --phase-1-tint: #f2edf7;  --phase-1-tone: #c9b9dd;   /* pale lilac */
  --phase-2-tint: #e8e0f1;  --phase-2-tone: #a58fc2;   /* lilac */
  --phase-3-tint: #ded5e9;  --phase-3-tone: #7c6496;   /* hero purple */
  --phase-4-tint: #d3e0eb;  --phase-4-tone: #1f5276;   /* hero blue */
  --planner-muted: #656565;  /* the moments: 5.8:1 on white */
  --planner-line: #c4c4c4;
  --paper-line: #ececec;     /* Werkwijze's squared paper */
  --surface: var(--white);
  /* Paper: the hero's grain, faint, for the white of the page. Specks of black at a few per cent, so the white
     stays white. A background layer: put it before the colour. */
  --paper: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  .26 0 0 0 -.1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 240px;
  --field-border: #777;
  --focus-ring: var(--blue);   /* stays the loud blue: it must be seen */

  /* ---- Font ------------------------------------------------------------ */
  --font-sans: "Inter var", system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;

  /* ======================================================================
     SPACING — one doubling scale, used for padding, margin and gap alike.
     6 · 12 · 24 · 48 · 96
     ====================================================================== */
  --space-6: 0.375rem;
  --space-12: 0.75rem;
  --space-24: 1.5rem;
  --space-48: 3rem;
  --space-96: 6rem;

  /* Named roles, so a section's rhythm can change without hunting for
     every 96 in the stylesheet. These are the only values that step. */
  --gutter: var(--space-24);
  --section-y: var(--space-48);
  --section-head-y: var(--space-24);

  /* ======================================================================
     TYPE — mobile rungs (below 960px). Desktop values are in the media
     query at the bottom. Every mobile value is itself a rung, never an
     arbitrary shrink.
     ====================================================================== */

  /* ---- Display: single oversized words. Leading below 1 so the lines
          lock together; tracking pulled in because large type sets loose. */
  --display-1-size: 3.75rem;   /* 60 -> 186 */
  --display-2-size: clamp(3rem, 16.8vw, 4.625rem);   /* up to 74 -> 120 */
  --display-3-size: 2.5rem;    /* 40 ->  96 */
  --display-lh: 0.9;
  --display-ls: -0.02em;

  /* ---- Title: headings. Looked at, not read. --------------------------- */
  --title-1-size: 2.25rem;     /* 36 ->  48 */
  --title-2-size: 1.75rem;     /* 28 ->  36 */
  --title-3-size: 1.25rem;     /* 20 ->  24 */
  --title-4-size: 1.125rem;    /* 18 ->  20 */
  --title-lh: 1.15;
  --title-ls: -0.02em;

  /* ---- Body: everything read as prose or UI text. Fixed at both widths —
          16 is already the floor for comfortable reading and 12 cannot
          shrink further. Tracking is opened up rather than pulled in:
          small type sets tight and needs the air. ---------------------- */
  --body-1-size: 1rem;         /* 16 */
  --body-2-size: 0.875rem;     /* 14 */
  --body-3-size: 0.75rem;      /* 12 */
  --body-lh: 1.45;
  --body-ls: 0.02em;

  /* ---- Editorial: long-form reading. The only body rung that steps, and
          the only one set at 1.6 — a paragraph read for minutes wants more
          room than a label read in a second. --------------------------- */
  --body-editorial-size: 1.125rem;   /* 18 -> 20 */
  --body-editorial-lh: 1.45;
  --body-editorial-ls: 0;

  /* The step from the page edge to the column-2 line. Headings sit on the
     edge; the content under them steps in by this. Written as the distance
     between the two lines, so it narrows with the viewport rather than
     holding a desktop measurement on a small screen. */
  --indent: calc(100vw / 6 - var(--gutter));

  --measure: 62ch;
  --content-max: 1440px;

  --radius-pill: 56px;
  --radius-button: 4px;   /* buttons and chips, as the fields */
  --radius-field: 4px;
  --radius-card: 8px;

  color-scheme: light;
}

/* ==========================================================================
   The one breakpoint. At 960px and up every rung is the Figma value exactly.
   ========================================================================== */
@media (min-width: 60rem) {   /* 960px */
  :root {
    --display-1-size: 9.375rem;   /* 150 — steps to 186 at 1500, below */
    --display-2-size: 7.5rem;     /* 120 */
    --display-3-size: 6rem;       /*  96 */

    --title-1-size: 3rem;         /*  48 */
    --title-2-size: 2.25rem;      /*  36 */
    --title-3-size: 1.5rem;       /*  24 */
    --title-4-size: 1.25rem;      /*  20 */

    --body-editorial-size: 1.25rem;  /*  20 */

    --gutter: var(--space-96);
    --section-y: var(--space-96);
    --section-head-y: var(--space-48);
  }
}

/* ==========================================================================
   One extra step, for display-1 only.

   186px is the design value, but "Experiences" needs about 1145px on one
   line at that size and the headline column is only five of six. Below
   roughly 1400px it wraps to four lines and blows the hero's proportions
   apart. So display-1 holds at 150px until 1500, where it steps up to the
   design's 186. 150 is a rung on the same ladder (erfbouwen's o-150), not
   a number invented for this one case.

   This is the only rung with a second breakpoint.
   ========================================================================== */
@media (min-width: 93.75rem) {   /* 1500px */
  :root { --display-1-size: 11.625rem; }   /* 186 */
}

/* ==========================================================================
   Rung classes. Applying a rung applies all three of its properties, so
   they travel together and cannot drift apart.
   ========================================================================== */
.display-1 { font-size: var(--display-1-size); line-height: var(--display-lh); letter-spacing: var(--display-ls); }
.display-2 { font-size: var(--display-2-size); line-height: var(--display-lh); letter-spacing: var(--display-ls); }
.display-3 { font-size: var(--display-3-size); line-height: var(--display-lh); letter-spacing: var(--display-ls); }

.title-1 { font-size: var(--title-1-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }
.title-2 { font-size: var(--title-2-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }
.title-3 { font-size: var(--title-3-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }
.title-4 { font-size: var(--title-4-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }

.body-1 { font-size: var(--body-1-size); line-height: var(--body-lh); letter-spacing: var(--body-ls); }
.body-2 { font-size: var(--body-2-size); line-height: var(--body-lh); letter-spacing: var(--body-ls); }
.body-3 { font-size: var(--body-3-size); line-height: var(--body-lh); letter-spacing: var(--body-ls); }

.body-editorial {
  font-size: var(--body-editorial-size);
  line-height: var(--body-editorial-lh);
  letter-spacing: var(--body-editorial-ls);
  max-inline-size: var(--measure);
}

/* ==========================================================================
   Spacing utilities. Same five steps, for flex and grid gaps and for the
   common vertical-rhythm case.
   ========================================================================== */
.gap-6 { gap: var(--space-6); }
.gap-12 { gap: var(--space-12); }
.gap-24 { gap: var(--space-24); }
.gap-48 { gap: var(--space-48); }
.gap-96 { gap: var(--space-96); }

.stack { display: flex; flex-direction: column; }
.stack-6 { display: flex; flex-direction: column; gap: var(--space-6); }
.stack-12 { display: flex; flex-direction: column; gap: var(--space-12); }
.stack-24 { display: flex; flex-direction: column; gap: var(--space-24); }
.stack-48 { display: flex; flex-direction: column; gap: var(--space-48); }
.stack-96 { display: flex; flex-direction: column; gap: var(--space-96); }

/* ===== css/base.css ===== */
/* Reset, webfont, element defaults.
   Elements get a sensible rung by default; the rung classes override where
   the design asks for something else. */

@font-face {
  font-family: "Inter var";
  font-style: normal;
  font-weight: 100 900;      /* variable: one file covers every weight used */
  font-display: swap;
  src: url("fonts/Inter-roman.var.woff2") format("woff2");
}

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: 5rem;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  /* Headings take this. A panel that sets light type resets it to
     currentColor, so its headings follow the panel instead. */
  --heading-ink: var(--ink-strong);
  /* Light type on a dark panel looks heavier on macOS, where the browser
     thickens glyphs by default. Each light-type panel in layout.css turns
     that off with -webkit-font-smoothing: antialiased; dark type on white
     keeps the default, which would otherwise go thin and faint. */
  font-family: var(--font-sans);
  font-size: var(--body-1-size);
  line-height: var(--body-lh);
  letter-spacing: var(--body-ls);
  font-synthesis-weight: none;

  /* Dutch compounds get long -- "Toegankelijkheidsverklaring" is 27
     characters and already pushed a column out of the page once. This only
     breaks a word that would otherwise overflow, so ordinary text is
     unaffected, and it inherits, so it covers headings, labels and lists
     everywhere rather than one section at a time. */
  overflow-wrap: break-word;
}

/* Headings carry weight and colour only — the rung class carries the size,
   so a heading's level and its size stay independent. */
h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  color: var(--heading-ink);
}

h3, h4 { font-weight: 500; }

/* Defaults for headings with no rung class applied. */
h1 { font-size: var(--display-3-size); line-height: var(--display-lh); letter-spacing: var(--display-ls); }
h2 { font-size: var(--title-1-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }
h3 { font-size: var(--title-2-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }
h4 { font-size: var(--title-3-size); line-height: var(--title-lh); letter-spacing: var(--title-ls); }

p { margin: 0; text-wrap: pretty; }

:is(h1, h2, h3, h4) { text-wrap: balance; }

a { color: inherit; text-underline-offset: 0.15em; }

/* A link in running text is the accent, like every other thing that can
   be clicked. Links with a class (buttons, nav, tags) style themselves;
   the footer, on the brand blue, keeps its links white. */
main :is(p, li, address) a:not([class]) { color: var(--accent); }
a:hover { text-decoration-thickness: max(0.12em, 2px); }

::selection { background: var(--pink); color: var(--brand); }

/* The page's grain on a layer of its own, fixed behind everything and
   one screen big: it shows wherever a section leaves the white open.
   Its own layer so it can sparkle (layout.css) while only one screen's
   worth is redrawn, not the whole page. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--paper);
  pointer-events: none;
}

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 2px;
}

/* The saturated sections need a light ring to keep it visible. */
.site-footer :focus-visible { outline-color: var(--white); }

img, svg, picture, video {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
}

ul, ol { margin: 0; padding: 0; list-style: none; }

address { font-style: normal; }

.skip-link {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  transform: translateY(-120%);
  z-index: 100;
  padding: var(--space-12) var(--space-24);
  background: var(--brand);
  color: var(--white);
  font-weight: 500;
  text-decoration: none;
}

.skip-link:focus-visible { transform: translateY(0); }

/* hidden always hides, whatever display a component sets. */
[hidden] { display: none !important; }

.visually-hidden:not(:focus):not(:active) {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ===== css/components.css ===== */
/* Buttons, cards, form controls.
   Sizes come from the rungs in tokens.css — no literal font-size here. */

/* --- Button: 56px tall, 4px corners like the fields, 24px label ------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  min-block-size: 56px;
  padding-inline: var(--space-48);
  background: var(--accent);
  color: var(--white);
  border: 2px solid var(--accent);
  border-radius: var(--radius-button);
  font-family: inherit;
  font-size: var(--title-3-size);
  line-height: var(--title-lh);
  letter-spacing: var(--title-ls);
  font-weight: 500;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.12s ease;
}

.btn:hover {
  transform: translateY(-2px);
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
.btn:active { transform: translateY(0); }

/* On the brand blue of the footer: white, with brand type. */
.site-footer .btn {
  background: var(--white);
  color: var(--brand);
  border-color: var(--white);
}

@media (width < 60rem) {
  .btn { padding-inline: var(--space-24); }
}

/* --- Welcome card (QR visitors) ----------------------------------------
   Bottom left, over the page: white, the brand rule along its top, Elma's
   face in a circle, a line of welcome and two ways in. Below 960 it runs
   the full width at the bottom, and the to-top button waits until it is
   closed. It rises in once, a moment after the page. */
.welcome {
  position: fixed;
  inset-block-end: calc(var(--space-24) + env(safe-area-inset-bottom, 0px));
  inset-inline-start: var(--space-24);
  z-index: 30;
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: var(--space-12) var(--space-12);
  align-items: start;
  inline-size: min(26rem, calc(100% - 2 * var(--space-24)));
  padding: var(--space-24) var(--space-12) var(--space-24) var(--space-24);
  background: var(--white);
  color: var(--ink);
  border-block-start: 4px solid var(--brand);   /* square corners: the line runs straight */
  box-shadow: 0 12px 40px rgb(31 82 118 / 0.22);
}

.welcome__face {
  inline-size: 56px;
  block-size: 56px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 72% 22%;
}

.welcome__text { display: flex; flex-direction: column; gap: var(--space-6); }
.welcome__title { color: var(--brand); font-weight: 600; }

.welcome__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-24);
  margin-block-start: var(--space-6);
}
.welcome__links a { color: var(--accent); font-weight: 600; }

.welcome__close {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  margin: calc(-1 * var(--space-12)) 0 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-button);
  color: var(--muted);
  font: inherit;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
}
.welcome__close:hover { color: var(--ink); background: var(--blush); }

@media (prefers-reduced-motion: no-preference) {
  .welcome { animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.8s backwards; }
}

@media (width < 60rem) {
  .welcome {
    inset-inline: var(--space-12);
    inset-block-end: calc(var(--space-12) + env(safe-area-inset-bottom, 0px));
    inline-size: auto;
    grid-template-columns: 48px 1fr auto;
  }
  .welcome__face { inline-size: 48px; block-size: 48px; }
}

body:has(.welcome:not([hidden])) .to-top { display: none; }

/* --- Back to top -------------------------------------------------------
   A 48px square, the accent like every other control, bottom right
   (clear of a phone's home bar). Hidden until the script adds .is-shown,
   then it fades and rises in. */
.to-top {
  position: fixed;
  inset-block-end: calc(var(--space-24) + env(safe-area-inset-bottom, 0px));
  inset-inline-end: var(--space-24);
  z-index: 15;
  display: grid;
  place-items: center;
  inline-size: 48px;
  block-size: 48px;
  background: var(--accent);
  color: var(--white);
  border-radius: var(--radius-button);
  box-shadow: 0 4px 16px rgb(31 82 118 / 0.25);
  font-size: var(--title-3-size);
  font-weight: 600;
  text-decoration: none;
  opacity: 0;
  visibility: hidden;
  translate: 0 12px;
  transition: opacity 0.3s ease, translate 0.3s cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s linear 0.3s, background-color 0.12s ease;
}

.to-top.is-shown {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition-delay: 0s;
}

.to-top:hover { background: var(--accent-strong); }
.to-top:hover > [aria-hidden] { translate: 0 -2px; }
.to-top > [aria-hidden] { transition: translate 0.25s cubic-bezier(0.22, 1, 0.36, 1); }

/* It may lie over the footer's blue: a white ring inside the blue one
   keeps the focus visible on any ground. */
.to-top:focus-visible { box-shadow: 0 0 0 3px var(--white); }

/* --- Service card (Diensten) ------------------------------------------ */
.service { display: flex; flex-direction: column; gap: var(--space-24); }

.service__image {
  inline-size: 100%;
  aspect-ratio: 456 / 192;
  object-fit: cover;
  border-radius: 2px;
}

.service p { max-inline-size: 22rem; }

/* --- Section head ------------------------------------------------------
   Heading and intro, the same in every section (Diensten, Werkwijze,
   Studio, Contact): the display heading, the editorial intro under it at
   one measure. Each section places the head; this is how it looks. */
.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
}

.section-head__intro {
  max-inline-size: 37rem;    /* 595, from the design */
  color: var(--ink-soft);    /* a step back from the heading above it */
}

@media (width < 60rem) {
  .section-head { gap: var(--space-12); }
}

/* --- Planner (Werkwijze) ----------------------------------------------
   Figma node 266:3614. Shared: the phase colours, the bar with its
   number, the moments, and the black band the names sit on. Below that,
   the layout under 1200; the planner grid above it is in layout.css.
   The numbers are decoration -- an ol already tells a screen reader
   "1 of 4". */
.planner { counter-reset: phase; }
.planner__phase { counter-increment: phase; }

/* --tone-ink: the number on the tone. Black on the two light tones,
   white on the purple (5.1:1) and the blue (8.2:1). */
.planner__phase:nth-child(1) { --tint: var(--phase-1-tint); --tone: var(--phase-1-tone); --tone-ink: var(--black); }
.planner__phase:nth-child(2) { --tint: var(--phase-2-tint); --tone: var(--phase-2-tone); --tone-ink: var(--black); }
.planner__phase:nth-child(3) { --tint: var(--phase-3-tint); --tone: var(--phase-3-tone); --tone-ink: var(--white); }
.planner__phase:nth-child(4) { --tint: var(--phase-4-tint); --tone: var(--phase-4-tone); --tone-ink: var(--white); }

/* A bar: the tint, a 44px block of the tone at its start with the phase
   number in it, then the task in 16px semibold. 44px tall, square
   corners, like the band above it. */
.planner__bar {
  --block: 44px;
  position: relative;
  min-block-size: 44px;
  margin: 0;
  padding: calc((44px - 1.45em) / 2) var(--space-12)
           calc((44px - 1.45em) / 2) calc(var(--block) + var(--space-12));
  background:
    linear-gradient(var(--tone), var(--tone)) 0 0 / var(--block) 100% no-repeat,
    var(--tint);
  color: var(--ink);
  font-size: var(--body-1-size);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.02em;
}

.planner__bar::before {
  content: counter(phase);
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  display: grid;
  place-items: center;
  inline-size: var(--block);
  color: var(--tone-ink);
  font-variant-numeric: tabular-nums;
}

/* The task reads as a label: capital first. */
.planner__bar::first-letter { text-transform: uppercase; }

/* A client moment: a diamond in its phase's tone and a short label. The
   legend under the planner, outside any phase, uses ink. */
.planner__moments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-12);
}

.moment {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  color: var(--planner-muted);
  font-size: var(--body-2-size);
  line-height: 1.45;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.moment::before {
  content: "";
  flex: none;
  inline-size: 0.5rem;
  block-size: 0.5rem;
  background: var(--tone, var(--ink));
  rotate: 45deg;
}

/* Close under the planner rather than a full section gap away. */
.planner__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  margin-block-start: calc(-1 * var(--space-24));
}

.planner__note { color: var(--ink-soft); }

/* The name in white on the black band, the duration small beside it. */
.planner__name {
  color: var(--white);
  font-weight: 500;
  line-height: 1.1;
}

.planner__duration {
  color: inherit;
  font-size: 0.75rem;          /* body-3 */
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0.02em;
}

/* Below 1200 the same parts, one phase under the other: its name on a
   blue band from edge to edge, the bar right under it, the moments
   after. The bars step from the left edge to the right one, the
   desktop staircase in small. */
@media (width < 75rem) {
  .planner {
    display: flex;
    flex-direction: column;
    gap: var(--space-24);
    margin-inline: calc(-1 * var(--gutter));
  }

  .planner__name {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-12);
    padding: var(--space-12) var(--gutter);
    background: var(--brand);
    font-size: var(--title-3-size);
  }

  .planner__duration { flex: none; }

  /* The staircase spread over the full width: phase 1 on the left
     gutter, the last on the right one, the two between at even steps.
     --step is the phase's place, 0 to 1; the margin moves the block that
     share of the width, the translate takes the same share of its own
     width back, so its left edge lands at that share of the free room. */
  .planner__task {
    --step: calc((var(--phase) - 1) / 3);
    display: flex;
    flex-direction: column;
    align-items: start;
    gap: var(--space-6);
    /* Its own width, not what is left after the margin: the translate
       brings it back inside, so the margin must not squeeze it. */
    inline-size: max-content;
    max-inline-size: calc(100% - 2 * var(--gutter));
    margin-inline-start: calc(var(--gutter) + var(--step) * (100% - 2 * var(--gutter)));
    translate: calc(var(--step) * -100%) 0;
  }

  .planner__bar { max-inline-size: 100%; }
}

/* --- Link list (Design / Development / Branding / ...) ---------------- */
/* Running text, the items parted by a dot. The dot is decoration: the
   "/ ''" alt text keeps screen readers from reading it out. */
.linklist__items {
  display: flex;
  flex-wrap: wrap;
  row-gap: var(--space-6);
}

.linklist__items li:not(:last-child)::after {
  content: "\00b7" / "";
  margin-inline: 0.55em;
  color: var(--muted);
}

/* --- Form ------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--space-6); }

.field > label { font-weight: 500; color: var(--ink); }

.input,
.select,
.textarea {
  inline-size: 100%;
  min-block-size: 44px;          /* WCAG 2.5.8 target size */
  padding: 0.6rem 11px;
  background: var(--white);
  color: var(--ink);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-field);
  font-family: inherit;
  /* 16px, not the design's 15px: iOS Safari zooms the page whenever an
     input is focused below 16px. body-3 removes that jump. */
  font-size: var(--body-1-size);
  line-height: var(--body-lh);
  letter-spacing: var(--body-ls);
}

.input::placeholder,
.textarea::placeholder { color: var(--muted); }

.textarea { min-block-size: 96px; resize: vertical; }

.input:user-invalid,
.textarea:user-invalid { border-color: #c0003f; border-width: 2px; }

/* --- Tags --------------------------------------------------------------
   Checkboxes drawn as chips. The input stays in the page and in the
   accessibility tree -- only visually hidden -- so it keeps its role,
   its checked state and its keyboard behaviour. The label is the visible
   control, and the focus ring is drawn on it. */
.tags { border: 0; margin: 0; padding: 0; }

.tags > legend {
  padding: 0;
  font-weight: 500;
  color: var(--ink);
}

.tags__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
  margin-block-start: var(--space-6);
}

.tags__input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
  pointer-events: none;
}

.tags__tag {
  display: flex;
  align-items: center;
  min-block-size: 44px;          /* target size, as the nav links */
  padding-inline: var(--space-24);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-button);
  cursor: pointer;
  user-select: none;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.tags__tag:hover { border-color: var(--accent); }

.tags__input:checked + .tags__tag {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--white);
}

/* The input is invisible, so its focus ring has to appear on the label. */
.tags__input:focus-visible + .tags__tag {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

/* Checked state must not rest on colour alone (WCAG 1.4.1). */
.tags__input:checked + .tags__tag::before {
  content: "";
  inline-size: 0.7em;
  block-size: 0.4em;
  margin-inline-end: 0.5em;
  border-inline-start: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  rotate: -45deg;
  translate: 0 -0.15em;
}

/* Hidden from sight and from assistive tech — no person should be offered
   it. Not display:none, which some bots deliberately skip. */
.honeypot {
  position: absolute;
  inset-inline-start: -9999px;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
}

/* --- Notices ---------------------------------------------------------- */
.notice {
  padding: var(--space-24);
  border-inline-start: 4px solid var(--blue);
  background: var(--blush);
  border-radius: var(--radius-field);
}

.notice--error { border-inline-start-color: #c0003f; }
.notice--success { border-inline-start-color: var(--blue); }

/* ===== css/layout.css ===== */
/* Page structure. One breakpoint: 960px.

   The Figma file is absolutely positioned on a 1440px canvas. This rebuilds
   it in normal flow, with the desktop numbers matching the design exactly at
   960px and up. Below that, a single-column arrangement. */

/* --- Header: three colour bands ---------------------------------------- */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: 1fr;
  min-block-size: 60px;
  background: var(--white);
  transition:
    translate 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.3s ease,
    box-shadow 0.3s ease;
}

/* Headroom, as on nike.com (assets/js/animations.js sets the classes):
   scrolling down slides the header away, any scroll up brings it back,
   and at the top of the page it is always there. Once the page has moved,
   a hairline separates it from what scrolls under it. */
.site-header.is-hidden { translate: 0 -100%; }
.site-header.is-scrolled.is-solid { box-shadow: 0 1px 0 rgb(0 0 0 / 0.08); }

@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-header__mark,
  .site-header__cta { transition: none; }   /* still hides, but at once */
}

.site-header__mark {
  display: flex;
  align-items: center;
  padding-inline: var(--space-24);
  background: var(--brand);
}

/* The bands fade in rather than snap when the home header turns solid. */
.site-header__mark,
.site-header__cta {
  transition: background-color 0.4s ease, color 0.4s ease, padding 0.35s ease;
}

.site-header__mark img {
  inline-size: 132px;
  transition:
    inline-size 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    margin 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    scale 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .site-header__mark:hover img { scale: 1.04; }
}

.site-header__cta {
  display: flex;
  align-items: center;
  /* It is a flex row, so the content is pushed to the trailing edge rather
     than text-aligned -- text-align has nothing to act on here. */
  justify-content: flex-end;
  gap: var(--space-6);
  padding-inline: var(--space-48);
  background: var(--accent);
  color: var(--white);
  font-weight: 500;
  text-decoration: none;
}

.site-header__nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-block-size: 60px;
  padding-inline: var(--gutter) var(--space-24);
}

.site-header__nav ul { display: flex; flex-wrap: wrap; gap: var(--space-12) var(--space-48); }
.site-header__nav a { text-decoration: none; }

.site-header__nav a:hover,
.site-header__nav a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

/* On the home page it lies on the hero: the same header, all white on
   a clear ground, until two thirds of the hero have scrolled by (is-solid,
   animations.js) -- then the bands fade back in. */
body:has(.hero) .site-header {
  position: fixed;
  inset-inline: 0;
}

body:has(.hero) .site-header:not(.is-solid),
body:has(.hero) .site-header:not(.is-solid) :is(.site-header__mark, .site-header__cta) {
  background: transparent;
  color: var(--white);
}

body:has(.hero) .site-header:not(.is-solid) {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* …and with the big wordmark of the design (Figma 271:4154, 35 from the
   left; a little bigger than its 283), its top level with the tops of
   the menu's letters. It hangs below the bar; the links stay on the top
   line. Scrolling shrinks it back into its black block. */
@media (min-width: 60rem) {
  body:has(.hero) .site-header > * { align-self: start; min-block-size: 60px; }

  /* When the menu wraps (below about 1150) its first line keeps the
     single-line position, so the wordmark still lines up with it. */
  body:has(.hero) .site-header__nav {
    align-items: flex-start;
    padding-block-start: calc((60px - 1lh) / 2);
  }

  body:has(.hero) .site-header:not(.is-solid) .site-header__mark {
    padding-inline-start: clamp(1rem, 2.43vw, 35px);
  }

  body:has(.hero) .site-header:not(.is-solid) .site-header__mark img {
    inline-size: clamp(132px, 22.2vw, 320px);    /* 320 at 1440; the design has 283 */
    max-inline-size: none;   /* wider than its column; nothing sits there */
    flex: none;
    margin-block-start: 24px;   /* the menu's cap height line */
  }
}

/* --- Hero --------------------------------------------------------------
   After Figma node 271:4045, a 16:9 slide: a blue-to-pink colour field,
   the portrait darkened onto it from the right. Across the bottom, like
   a magazine's cover line, the promise (the h1), huge; above it on the
   left the name tag and the line that explains it. All type white.
   Earlier heroes: git tags hero-v1, home-v2 and home-v3.

   Sizes and insets are shares of the 1440 x 809 frame, so the
   composition scales with the window. */
.hero {
  position: relative;
  isolation: isolate;     /* the portrait darkens the field, nothing else */
  overflow: clip;
  block-size: clamp(36rem, 56.25vw, 100svh);   /* 16:9, within the screen */

  /* Everything stands on the promise, which stands on the bottom edge,
     --foot above it, and grows upward: the hero is as tall as the
     screen allows, so nothing is placed from the top, where a short
     window would run it into the type. */
  --foot: calc(1.67vw + 5px);                 /* 29 at 1440 */
  --promise: clamp(2.75rem, 6.67vw, 6rem);    /* 96 at 1440 */
  /* One design pixel at 1440, less below it: the name tag scales in it,
     type included, so it keeps its shape. */
  --px: min(0.06944vw, 1px);
  --hero-tag: var(--brand);
  background: #2279b6;    /* under the field while it loads */
  color: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.hero__sky,
.hero__photo {
  position: absolute;
  inset-block-start: 0;
  z-index: -1;
  block-size: 100%;
  object-fit: cover;
}

.hero__sky {
  inset-inline-start: 0;
  inline-size: 100%;
  background: url("img/hero-sky.jpg") center / cover no-repeat;
}

/* The grain. The sky image is the colour alone, smooth, so it can move
   with the parallax without its grain swimming; the grain lies over it
   here, still, a little coarser than a screen pixel, as in the
   design's field. Over the portrait too, under the type. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.4' intercept='-.7'/%3E%3CfeFuncG type='linear' slope='2.4' intercept='-.7'/%3E%3CfeFuncB type='linear' slope='2.4' intercept='-.7'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 240px;
  opacity: 0.18;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* The grain sparkles: about ten times a second the tile jumps to another
   place, so the specks never sit still -- film grain, not drift. Jumps,
   not a glide (steps), which is what made the earlier moving grain look
   like it was swimming. Not for anyone who asks
   for less motion. The page's grey grain (base.css) and the footer's
   do the same. */
@keyframes sparkle {
  0%   { background-position: 0 0; }
  14%  { background-position: -73px 41px; }
  28%  { background-position: 57px -88px; }
  42%  { background-position: -119px -23px; }
  57%  { background-position: 96px 112px; }
  71%  { background-position: -31px 67px; }
  85%  { background-position: 140px -51px; }
  100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .hero::after,
  body::before,
  .site-footer { animation: sparkle 0.7s steps(1, end) infinite; }
}

/* 1289 of 1440, flush right, at 80% and darken, as in the design. */
.hero__photo {
  inset-inline-end: 0;
  inline-size: 89.5%;
  object-position: 70% 50%;
  opacity: 0.8;
  mix-blend-mode: darken;
}

/* Tag, line, then the promise under them (order: the source keeps
   tag, promise, line). 35 from the left at 1440, scaling with it, and
   the full width for the promise. */
.hero__intro {
  position: absolute;
  inset-block-end: var(--foot);
  inset-inline-start: calc(2.5% - 1px);
  inline-size: 95%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: max(16px, 24 * var(--px));
}

/* The promise: one sentence to a line, huge, set tight -- the cover
   line. A little more space above it than between tag and line. */
.hero__title {
  order: 2;
  margin: max(8px, 12 * var(--px)) 0 0;
  color: inherit;
  font-size: var(--promise);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: -0.03em;
  white-space: nowrap;
}

.hero__lead { order: 1; }

.hero__title span { display: block; }

/* The first line sets up, the second lands: title-1 over 150px. The
   150 holds at 1440 and up and narrows with the screen below that, so
   the line never runs off it; never under display-3. */
.hero__title span:first-child { font-size: var(--title-1-size); }
.hero__title span + span {
  font-size: max(var(--display-3-size), min(9.375rem, 10.42vw));
}

/* The footer repeats the pair, in proportion to its own size. */
.site-footer__promise span:first-child { font-size: 0.72em; }
.site-footer__promise span + span { font-size: 1.3em; }

/* Big letters carry more room before their first stroke, so the second
   line sat visibly to the right of the first. Pulled back by that room,
   both lines start on one edge. */
.hero__title span + span,
.site-footer__promise span + span { margin-inline-start: -0.03em; }

.hero__lead {
  max-inline-size: 28.54vw;   /* 411 at 1440 */
  font-weight: 500;
}

/* 326 x 53 of deep blue, its text 20 in from the left. Positioned only
   to carry its colour layer. */
.hero__byline {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-24);
  min-inline-size: calc(326 * var(--px));
  min-block-size: calc(53 * var(--px));
  padding: var(--space-6) calc(20 * var(--px));
  color: var(--white);
  font-size: max(15px, 20 * var(--px));
  font-weight: 500;
  text-decoration: none;
}

/* Its arrow on the far right, like the call to action's. */
.hero__byline .hero__arrow { margin-inline-start: auto; }

/* The tag's blue multiplies onto the picture, so the portrait and the
   field show through it. On a layer of its own, under the words: on the
   link itself the blend would take the white type with it. The link
   starts no stacking context, so the layer sits in the hero's, over the
   photo, and blends with it. */
.hero__byline::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--hero-tag);
  mix-blend-mode: multiply;
  transition: opacity 0.25s ease;
}

/* The tag's arrow: bold, 20 in from the right of its box, and it steps
   forward when the link is pointed at. */
.hero__arrow {
  font-weight: 700;
  transition: translate 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.hero__byline:is(:hover, :focus-visible) .hero__arrow { translate: 4px 0; }

.hero__byline:hover::before { opacity: 0.85; }

/* --- Subhero -----------------------------------------------------------
   Under the hero: the note on the left at the page gutter, the black
   wordmark on the right. */
.subhero {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-48) var(--space-96);
  padding: 80px var(--gutter) var(--space-48);
}

.subhero__note { max-inline-size: 33.625rem; }   /* 538 */

.subhero__mark {
  inline-size: clamp(200px, 21.9vw, 315px);      /* 315 at 1440 */
  block-size: auto;
  margin-block-start: 22px;
}

/* Hangs below the header on the column 3/4 boundary, so it is present on
   every page rather than only over the hero. Not over the current hero:
   it cut a white notch into the squared paper there. */
body:has(.hero) .site-header__arrow { display: none; }


.site-header__arrow {
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 50%;
  translate: -50% 0;
  /* Half a column wide (a column is 100vw/6), capped at its drawn size of
     120 x 64. That lands exactly on 120 at 1440 and scales down below it.
     aspect-ratio keeps the height, and the viewBox matches these numbers,
     so the shape is never stretched. */
  inline-size: min(120px, calc(100vw / 12));
  aspect-ratio: 120 / 64;
  color: var(--white);
  pointer-events: none;
}



/* --- Sections ---------------------------------------------------------- */
/* The plain one-column pages: 404 and the contact handler's replies. */
.section {
  padding: var(--section-y) var(--gutter);
  max-inline-size: var(--content-max);
  margin-inline: auto;
}


/* --- Accessibility statement -------------------------------------------
   One reading column: the section head, then each part a short heading
   over its text, ruled off from the one before, as in Afspraken. */
.statement {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  margin-inline: 0;
}

.statement__part {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  max-inline-size: 48rem;
  padding-block-start: var(--space-24);
  border-block-start: 2px solid var(--brand);
}

.statement__part h2 { color: var(--ink-strong); }

.statement__list {
  padding-inline-start: 1.25em;
  list-style: disc;
}
.statement__list li + li { margin-block-start: var(--space-6); }
.statement__list li::marker { color: var(--accent); }

.statement__date { color: var(--muted); }


/* --- Diensten ----------------------------------------------------------
   Heading and intro as in every other section, then one card per
   service, side by side from 960, and the call to action under them.

   A card, after nojiggery.co: the brand blue, 8px corners, the photo on
   top toned in the house colours -- grey, multiplied onto a purple to
   blue field, so three unrelated photos read as one set -- fading into
   the blue, and the title lying over that fade, the text under it.
   ---------------------------------------------------------------------- */
.diensten {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter);
}

.diensten__cards { display: grid; gap: var(--space-24); }

.dienst {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-card);
  background: var(--brand);
  color: var(--white);
  --heading-ink: currentColor;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.dienst__image {
  position: relative;
  isolation: isolate;     /* the photo multiplies onto the field only */
  display: block;
  aspect-ratio: 4 / 3;
  /* The hero's field in small: pink, purple, blue. */
  background: linear-gradient(160deg, var(--pink) 0%, var(--accent) 45%, var(--brand) 90%);
}

.dienst__image img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.1) brightness(1.15);
  mix-blend-mode: multiply;
}

/* Into the blue of the card, where the title lies. */
.dienst__image::after {
  content: "";
  position: absolute;
  inset: 40% 0 0;
  background: linear-gradient(transparent, var(--brand));
}

.dienst__body {
  position: relative;     /* over the fade */
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  margin-block-start: calc(-1 * var(--space-48));
  padding: 0 var(--space-24) var(--space-48);
}

.dienst__body p { color: rgb(255 255 255 / 0.85); }   /* 6.4:1 on the blue */

.diensten__cta { display: flex; margin: 0; }

/* --- Werkwijze ---------------------------------------------------------
   Heading and intro as in every other section, then the planner, on
   plain white: the planner's own column rules are the only lines. */
/* Studio's panel sits this far in from the page; Werkwijze's paper runs
   on into the strip above it. */
main { --studio-inset: var(--space-24); }

.werkwijze {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter);
  background: var(--white);
}

/* The squared paper: 30px squares in faint grey, under the planner, its
   key and the button, out to the section's edges and down to its end. */
.werkwijze__plan {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  /* Down to Studio's panel: the strip around the panel's top is paper
     too, so Studio takes no top margin and this runs on by its inset. */
  margin: 0 calc(-1 * var(--gutter)) calc(-1 * var(--section-y));
  padding: 0 var(--gutter) calc(var(--section-y) + var(--studio-inset));
  background-color: var(--white);
  background-image:
    linear-gradient(to right, var(--paper-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--paper-line) 1px, transparent 1px);
  background-size: 30px 30px;
}


/* --- Studio ------------------------------------------------------------
   A blush panel, inset 24px from the page. Heading and lead as in every
   other section, the note under the lead, and a 16:9 frame, made for
   video, up to 640 wide (beside the two paragraphs from 960). */
.studio {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  margin: 0 var(--studio-inset) var(--studio-inset);
  /* Less the 24px inset, so the content lands on the same line as every
     other section. */
  padding: var(--section-y) calc(var(--gutter) - var(--space-24));
  background: var(--blush);
}


/* The frame clips; the image or video inside is sized past it so the
   scroll can move it without showing an edge (see animations.js). */
.studio__media {
  inline-size: 100%;
  max-inline-size: 640px;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  max-block-size: 80svh;
  background: var(--black);    /* behind a video until it plays */
}

.studio__media-item {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.studio__note { max-inline-size: 640px; }

/* The year, big, in the brand blue, the label small above it. */
.studio__since {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  color: var(--brand);
}

.studio__since-label { font-weight: 500; }

.studio__year {
  font-size: var(--display-2-size);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* --- Link lists -------------------------------------------------------
   One row per group, ruled off above and below: the name on the left, the
   services as running text on the right (below 960, under the name). */
.linklists {
  padding-block: var(--section-y);
  padding-inline: var(--gutter);
}

.linklist {
  display: grid;
  gap: var(--space-12);
  padding-block: var(--space-24);
  border-block-start: 1px solid var(--planner-line);
  /* A grid item's automatic minimum is its min-content -- for a list, the
     longest word ("Toegankelijkheidsverklaring") -- which pushed the page
     wider. This lets the column be narrower than a word. */
  min-inline-size: 0;
}

.linklist:last-child { border-block-end: 1px solid var(--planner-line); }

/* --- Afspraken (expect) --------------------------------------------------
   What working together is like: six short points, each under a rule
   with its number. One column, two from 600, three from 960. */
.expect {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter);
  counter-reset: expect;
}

.expect__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: var(--space-48);
}

.expect__item {
  counter-increment: expect;
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  padding-block-start: var(--space-24);
  border-block-start: 2px solid var(--brand);
}

/* 01, 02 ... small, over the title. Decoration: an ol already counts. */
.expect__item::before {
  content: counter(expect, decimal-leading-zero) / "";
  color: var(--pink-deep);
  font-size: var(--body-2-size);
  font-weight: 600;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

.expect__item p { color: var(--ink-soft); max-inline-size: 26rem; }

/* --- Vragen (FAQ) -------------------------------------------------------
   Heading and intro, then one ruled row per question, as the link lists
   above, to two thirds of the width. The question is the summary; a
   plus in the accent turns to a cross when it is open. */
.faq {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter);
}

.faq__list { max-inline-size: 56rem; }

.faq__item { border-block-start: 1px solid var(--planner-line); }
.faq__item:last-child { border-block-end: 1px solid var(--planner-line); }

.faq__item summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-24);
  padding-block: var(--space-24);
  color: var(--ink-strong);
  cursor: pointer;
  list-style: none;
}

.faq__item summary::-webkit-details-marker { display: none; }

.faq__item summary::after {
  content: "+" / "";
  flex: none;
  color: var(--accent);
  font-size: 1.5em;
  font-weight: 400;
  line-height: 0.6;
  transition: rotate 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq__item[open] summary::after { rotate: 45deg; }
.faq__item summary:hover { color: var(--accent); }

.faq__item p {
  max-inline-size: 46rem;
  padding-block-end: var(--space-24);
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .faq__item summary::after { transition: none; }
}

/* --- Contact -----------------------------------------------------------
   Heading, intro and the direct lines (mail, WhatsApp) first; then the
   form. Side by side from 960. */
.contact {
  display: grid;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter);
  align-items: start;
}

.contact__links { display: flex; flex-wrap: wrap; gap: var(--space-12) var(--space-48); }

.contact__form { display: flex; flex-direction: column; gap: var(--space-24); }

.contact__row {
  display: grid;
  gap: var(--space-12);
  /* Two equal fields. The design's 362 + 458 totals 820, which does not
     fit in half a screen. */
  grid-template-columns: 1fr;
}

.contact__submit { margin-block-start: var(--space-12); }
.contact__privacy { color: var(--muted); }
.contact__privacy a { color: var(--accent); }

/* --- Footer ------------------------------------------------------------
   In the house style: the brand blue with the page's grain, white type
   (8.2:1), the promise as a sign-off, then a ruled row of columns as in
   Afspraken. Below 960 the columns go two by two, the mark across. */
.site-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
  padding: var(--section-y) var(--gutter) var(--space-24);
  background: var(--paper), var(--brand);
  color: var(--white);
  --heading-ink: currentColor;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

.site-footer__top {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
}

/* The hero's cover line, smaller: each sentence on its own line. */
.site-footer__promise {
  font-size: clamp(2.5rem, 5.5vw, 5rem);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.03em;
}
.site-footer__promise span { display: block; }

/* A step back from the white: still 6.5:1 on the blue. */
.site-footer__lead { max-inline-size: 30rem; color: rgb(255 255 255 / 0.82); }

.site-footer__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-48) var(--space-24);
  padding-block-start: var(--space-24);
  border-block-start: 2px solid rgb(255 255 255 / 0.3);
}

.site-footer__mark { grid-column: 1 / -1; inline-size: 187px; }

.site-footer__label {
  margin-block-end: var(--space-12);
  color: rgb(255 255 255 / 0.75);   /* 5.6:1 */
  font-weight: 500;
}

/* Link targets 32px tall, above the 24 of WCAG 2.5.8. */
.site-footer__list a {
  display: inline-flex;
  align-items: center;
  min-block-size: 32px;
}

.site-footer__location { font-style: normal; line-height: 32px; }

/* Business details on the left, the statement and the other language
   on the right; one under the other when there is no room. */
.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-12) var(--space-48);
  padding-block-start: var(--space-24);
  border-block-start: 1px solid rgb(255 255 255 / 0.2);
}

.site-footer__legal { color: rgb(255 255 255 / 0.75); }

.site-footer__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-24);
}

.site-footer__meta a { text-decoration: underline; text-underline-offset: 0.2em; }

/* ==========================================================================
   960px and up.
   ========================================================================== */


/* ==========================================================================
   Below 960px. One breakpoint, one set of overrides.
   ========================================================================== */

/* ==========================================================================
   960px and up.

   Every media block lives at the foot of this file, after the base rules.
   A media query adds no specificity, so a base rule written later in the
   source beats it -- which is how the sections kept their gutter and
   ignored their column placement on desktop.
   ========================================================================== */
@media (min-width: 60rem) {

  /* minmax(0, …): an equal third each, whatever the photos' own widths
     -- with plain 1fr they pushed the page wider than the window. */
  .diensten__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Contact: two halves, the heading side and the form. The heading side
     stays in view while the form scrolls past it. */
  .contact {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--space-96);
  }

  .contact__head {
    position: sticky;
    inset-block-start: var(--space-96);
  }

  .contact__row { grid-template-columns: repeat(2, 1fr); }


  /* Footer: the mark takes the wide first column of the ruled row. */
  .site-footer { gap: var(--space-96); padding-block-end: var(--space-48); }

  .site-footer__cols { grid-template-columns: 2fr 1fr 1fr 1fr; }
  .site-footer__mark { grid-column: auto; }


  /* Subhero, measured against the 1440 frame. Its note starts at 104
     and its wordmark ends at 1311 -- 8 and 33 in from the gutter -- and
     Diensten's heading sits 206 under the note. */

  /* On a tall screen the subhero shows under the hero on arrival, and
     then the hero's left column moves in to the page gutter (96), so
     the two start on one line. The hero is 16:9 at most, and the
     subhero's first line shows from about 1440 x 920 -- a screen
     narrower than 1.58 : 1. */
  @media (max-aspect-ratio: 158/100) {
    .hero__intro { inset-inline-start: var(--gutter); }
  }
  .subhero {
    padding: 80px calc(var(--gutter) + 33px) 77px calc(var(--gutter) + 8px);
  }
  .subhero__mark { margin-block-start: 21px; }

  /* Afspraken: three a row, so the six make two even rows. */
  .expect__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Name on the left third, services from there; both rows' text starts
     on the same line, row after row. */
  .linklist {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    column-gap: var(--space-48);
    align-items: baseline;
    padding-block: var(--space-48);
  }

  /* Studio: the heading across the top; under it the lead and the note
     together on the left, the frame beside them on the right, all three
     starting on one line. */
  .studio {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 640px);
    grid-template-rows: auto auto auto 1fr;
    column-gap: var(--space-96);
    row-gap: var(--space-24);
  }

  .studio__head  { display: contents; }
  .studio__title { grid-column: 1 / -1; margin-block-end: var(--space-24); }
  .studio__head .section-head__intro { grid-area: 2 / 1; }
  .studio__note  { grid-area: 3 / 1; max-inline-size: 37rem; }
  .studio__since { grid-area: 4 / 1; margin-block-start: var(--space-24); }
  .studio__media { grid-area: 2 / 2 / 5 / 3; align-self: start; }

  /* Blue mark block is a fixed 216px; the purple band takes 35% and
     white fills the rest, which lands on the design's 216 / 504 / 720 at
     1440. Below this width the header stacks and the mark is a full-width
     row, so the fixed size applies here only. */
  /* Same six columns as the hero, so the bands line up with its cells:
     mark on column 1, the purple band on 2-3, nav on 4-6. */
  .site-header { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .site-header__mark { grid-column: 1; }
  .site-header__cta  { grid-column: 2 / 4; }
  .site-header__nav  { grid-column: 4 / 7; }
}

@media (min-width: 75rem) {   /* 1200px */
  /* --- Planner ---------------------------------------------------------
     Figma node 266:3614. Its own breakpoint: four columns need about
     1200px to breathe. Below that it stays the stacked list from
     components.css.

     Runs edge to edge, out of the section's padding: a gutter, the four
     phases, a gutter. The phase columns keep the design's widths (272 :
     336 : 374 : 266 of the 1248 between the gutters), so the first rule
     falls on the same 96px line as the heading. minmax(0, …) so a bar
     running long never widens its column.

     Rows: the blue band with the phase names, one row per phase -- its
     bar, its moments under it, a staircase -- and a short tail for the
     column rules to end in.

     Each li is a subgrid spanning the whole planner, so its name, bar and
     rule can sit in different rows while the list stays a list. */
  .planner {
    --rule: 2px;
    display: grid;
    grid-template-columns:
      var(--gutter)
      minmax(0, 272fr) minmax(0, 336fr) minmax(0, 374fr) minmax(0, 266fr)
      var(--gutter);
    grid-template-rows: auto repeat(4, auto) var(--space-24);
    margin-inline: calc(-1 * var(--gutter));
  }

  .planner__phase {
    display: grid;
    grid-column: 1 / -1;
    grid-row: 1 / -1;
    grid-template-columns: subgrid;
    grid-template-rows: subgrid;
    /* The lis lie on top of each other; let clicks and text selection
       through to whichever one actually has content there. */
    pointer-events: none;
  }

  .planner__phase > * { pointer-events: auto; }

  /* The band: brand blue, edge to edge, behind the names. */
  .planner__phase:first-child::after {
    content: "";
    grid-column: 1 / -1;
    grid-row: 1;
    background: var(--brand);
  }

  /* The column rule on this phase's leading edge, top to bottom: thin
     and light, a guide rather than a line to read. */
  .planner__phase::before {
    content: "";
    grid-column: calc(var(--phase) + 1);
    grid-row: 1 / -1;
    border-inline-start: var(--rule) solid var(--planner-line);
  }

  /* The name in the band, its duration small under it. A long name
     ("Overleg & inventarisatie") wraps and the band grows with it -- a
     phase name is never cut off. */
  .planner__name {
    grid-column: calc(var(--phase) + 1);
    grid-row: 1;
    align-self: end;
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: relative;
    z-index: 1;
    padding: var(--space-12) var(--space-12) var(--space-12) calc(var(--space-12) + var(--rule));
    font-size: clamp(1.5rem, 2vw, 2rem);     /* 29 at 1440, 32 from 1600 */
  }

  .planner__duration { opacity: 0.8; }

  /* The bar fills its own column, from rule to rule, and runs on into
     the next one if its task needs more, on one line, like a bar in a
     Gantt chart (over the rule it crosses, so none cuts its text). Its
     moments sit right under it, from its start. */
  .planner__task {
    grid-column: calc(var(--phase) + 1);
    grid-row: calc(var(--phase) + 1);
    justify-self: start;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-6);
    /* Its column less the rule it starts after; the full 100% would push
       the last bar past the page edge and scroll the page sideways. */
    min-inline-size: calc(100% - var(--rule));
    margin-inline-start: var(--rule);
    padding-block: var(--space-6);
    position: relative;
    z-index: 1;
  }

  .planner__bar { min-inline-size: 100%; white-space: nowrap; }

  /* The last has no next column: it runs on to the page edge and wraps
     there if it must. */
  .planner__phase:last-child .planner__task { grid-column: 5 / -1; }
  .planner__phase:last-child .planner__bar { white-space: normal; }

  .planner__moments { padding-inline-start: var(--space-12); }

  .planner__foot { margin-block-start: calc(-1 * var(--space-24)); }
}

/* ==========================================================================
   Below 960px.
   ========================================================================== */
@media (width < 60rem) {

  .site-header { position: static; }   /* single column is the base */
  .site-header__mark,
  .site-header__cta { padding-block: var(--space-12); }
  .site-header__cta { padding-inline: var(--gutter); }
  .site-header__nav {
    justify-content: flex-start;
    padding: var(--space-12) var(--gutter);
  }
  .site-header__nav ul { gap: var(--space-24); }

  /* Home: over the hero the contact band would only stack a third row;
     the nav sits on the right of the mark instead. */
  body:has(.hero) .site-header { grid-template-columns: auto 1fr; }
  body:has(.hero) .site-header__cta { display: none; }
  body:has(.hero) .site-header__nav { justify-content: flex-end; padding-inline-start: 0; }
  body:has(.hero) .site-header__nav ul { gap: var(--space-12) 16px; justify-content: flex-end; }

  /* Hero: everything under each other on the gutter, in source order
     -- the name tag, the promise, the line -- and
     gathered at the bottom of a screen-high hero, over the portrait
     cropped to the face. Out of absolute positioning: in flow, nothing
     can land on top of anything else, whatever the text length. */
  .hero {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--space-24);
    block-size: auto;
    min-block-size: clamp(36rem, 100svh, 52rem);
    padding: 140px var(--gutter) var(--space-24);   /* clear of the header */
  }
  .hero__photo { inline-size: 100%; object-position: 68% 30%; }

  .hero__intro {
    position: static;
    inline-size: auto;
    align-items: stretch;
    gap: var(--space-24);
  }
  /* In source order here: tag, promise, line. */
  .hero__intro > * { order: 0; }
  .hero__title { margin: 0; white-space: normal; }
  .hero__lead { max-inline-size: none; }

  .hero__byline {
    min-inline-size: 0;
    min-block-size: 53px;
    padding-inline: 20px;
    font-size: var(--body-editorial-size);
  }

  .subhero { padding-block: var(--space-48) 0; }

  /* The design's smaller button: 45 tall, 20/600, text from the left. */
  .diensten__cta .btn {
    min-block-size: 45px;
    min-inline-size: min(283px, 100%);
    justify-content: flex-start;
    padding-inline: 32px;
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.1;
  }

  .werkwijze { padding-block-start: var(--space-96); }




  /* A 12px inset here, so 12 back on the padding: 24 from the edge, like
     everything else at this width. */
  main { --studio-inset: var(--space-12); }
  .studio {
    gap: var(--space-24);
    padding-inline: calc(var(--gutter) - var(--space-12));
  }
  .studio__media { aspect-ratio: 4 / 3; }
}


/* ==========================================================================
   Motion. Small and once: things arrive, then hold still. All of it sits
   behind prefers-reduced-motion: no-preference, and the scroll reveals
   behind .has-reveal too, which assets/js/animations.js sets -- without
   the script nothing is ever hidden.
   ========================================================================== */
@keyframes rise {
  from { opacity: 0; translate: 0 24px; }
}

@keyframes settle {
  from { opacity: 0; scale: 1.04; }
}

@media (prefers-reduced-motion: no-preference) {
  /* The hero on arrival: the portrait settles, then the promise rises
     line by line, then the lead. The name tag is left alone -- its blue
     multiplies onto the photo, and moving it would cut it loose from
     the picture for as long as it moved. "backwards": nothing is left
     on the elements afterwards. */
  .hero__photo { animation: settle 1.4s cubic-bezier(0.22, 1, 0.36, 1) backwards; }
  .hero__title span { animation: rise 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.15s backwards; }
  .hero__title span + span { animation-delay: 0.3s; }
  .hero__lead { animation: rise 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.45s backwards; }

  /* Scroll reveals: up 24px and in, a group's members one after the
     other (--reveal-i, set by the script). */
  .has-reveal .reveal {
    transition:
      opacity 0.8s ease,
      translate 0.9s cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: calc(var(--reveal-i, 0) * 90ms);
  }
  .has-reveal .reveal:not(.is-in) { opacity: 0; translate: 0 24px; }

  /* The planner's bars grow from their start, phase after phase, as a
     plan being drawn. */
  .has-reveal .planner .planner__bar {
    transition: clip-path 0.8s cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: calc(var(--phase) * 150ms);
  }
  .has-reveal .planner:not(.is-in) .planner__bar { clip-path: inset(0 100% 0 0); }

  /* A button's arrow steps forward, as the hero tag's does. */
  .btn > [aria-hidden] { transition: translate 0.25s cubic-bezier(0.22, 1, 0.36, 1); }
  .btn:is(:hover, :focus-visible) > [aria-hidden] { translate: 4px 0; }
}

/* On paper everything shows, seen or not. */
@media print {
  .has-reveal .reveal { opacity: 1 !important; translate: none !important; }
  .has-reveal .planner .planner__bar { clip-path: none !important; }
}
