/* ===================================================================
   Prism Investment Management — site stylesheet
   Built from the PRISM design system (tokens + component classes),
   adapted from the Claude Design prototype into plain production CSS.
   =================================================================== */

/* Instrument Sans, self-hosted (SIL Open Font License — see /fonts/OFL.txt).
   One variable file per subset covers the whole 400–700 range. */
@font-face{
  font-family:"Instrument Sans";
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url("../fonts/instrument-sans-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Instrument Sans";
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url("../fonts/instrument-sans-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* The engineering page documents these tokens: stack.js reads the first :root
   block, so every token belongs here. */
:root{
  /* Ink + neutrals (from the logo) */
  --ink-900:#1a1a1a;
  --ink-700:#454542;
  --ink-600:#5a5a58;
  --ink-500:#8a8a86;
  --ink-300:#d5d3ce;
  --ink-200:#e2e0dc;
  --ink-100:#eeece8;
  --ink-050:#f6f5f3;
  --paper:#ffffff;

  /* Spectrum, pixel-exact from the logo */
  --spectrum-red:#d93533;
  --spectrum-amber:#fac302;
  --spectrum-green:#81b054;
  --spectrum-cyan:#04b6e6;
  --spectrum-violet:#855891;

  /* Surfaces */
  --surface-page:var(--paper);
  --surface-sunken:var(--ink-050);

  /* Text */
  --text-primary:var(--ink-900);
  --text-secondary:var(--ink-600);
  /* Darker than --ink-500 on purpose: #8a8a86 is 3.47:1 on paper, short of the 4.5:1
     WCAG AA asks of text this size. This is 5.35:1 on paper, 4.91:1 on sunken. */
  --text-tertiary:#6b6b67;
  --text-inverse:var(--paper);
  --text-link:var(--ink-900);
  --text-link-hover:var(--ink-700);

  /* Lines */
  --border-hairline:var(--ink-200);
  --border-field:var(--ink-300);
  --border-inverse:rgba(255,255,255,.20);

  /* Interaction */
  --action-primary:var(--ink-900);
  --action-primary-hover:#000000;
  --action-primary-active:#3a3a37;
  --focus-ring:var(--spectrum-cyan);

  /* Typography */
  --font-sans:"Instrument Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,"Cascadia Mono",Menlo,Consolas,monospace; /* Mono, not Code: no coding ligatures, so a URL's // shows as typed */
  --weight-regular:400;
  --weight-medium:500;
  --weight-semibold:600;
  --text-h1:clamp(30px,3.6vw,42px);
  --text-h2:clamp(22px,2.6vw,30px);
  --text-h3:clamp(17px,2vw,20px);
  --text-body-lg:18px;
  --text-body:16px;
  --text-body-sm:14px;
  --text-label:13px;   /* language toggle, the AFM strip on tablets */
  --text-caption:12px;
  --text-eyebrow:11px;
  --text-fine:11px;    /* fine print: the footer's legal links and colophon, swatch values */
  --leading-h1:1.08;
  --leading-h2:1.16;
  --leading-h3:1.25;
  --leading-body:1.6;
  --tracking-h1:-0.022em;
  --tracking-h2:-0.018em;
  --tracking-h3:-0.012em;
  --tracking-eyebrow:0.16em;
  /* Instrument Sans has a wide "0", so ch runs about 0.67em: 58ch is roughly 75–80
     characters of running text at body size, and fills the content column of the
     section grid exactly. */
  --measure-prose:58ch;

  /* Spacing */
  --space-3:8px;
  --space-4:12px;
  --pad-control-y:10px;
  --pad-control-x:18px;

  /* Layout */
  --site-w:1200px;
  --gutter:40px;
  --col-gap:64px;
  --radius-none:0px;
  --border-width:1px;
  --rule-heavy:3px;    /* the section rule; the current-page bar in the phone menu */
  --rule-strong:2px;   /* the rule over a spec list, a form outcome and the footer */

  /* Elevation */
  --shadow-header:0 1px 2px rgba(26,26,26,.05),0 8px 20px -10px rgba(26,26,26,.16);
  --focus-ring-width:2px;
  --focus-ring-offset:2px;

  /* Motion */
  --dur-fast:120ms;
  --dur-base:180ms;
  --ease-standard:cubic-bezier(.2,0,0,1);
  --dur-slow:220ms;
  --ease-decelerate:cubic-bezier(0,0,.2,1);
  --transition-control:color var(--dur-fast) var(--ease-standard),background-color var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);

  /* Persistent chrome: the AFM strip (measured by main.js, estimated without
     JavaScript in the strip rules) stacked on the header. */
  --header-height:76px;
  --afm-h:0px;
}

/* ————— Base ————— */
*,*::before,*::after{box-sizing:border-box}
/* The scrollbar's space is always reserved: a page that fits the viewport would
   otherwise lose the bar and re-centre everything half a bar's width to the right,
   header included, visibly so during the crossfade. */
html{-webkit-text-size-adjust:100%;scrollbar-gutter:stable}
/* --chrome-h is declared on body, not :root: main.js writes --afm-h onto body, and a
   var() inside a custom property resolves where that property is declared. Sticky
   offsets and the menu overlay read it. */
body{--chrome-h:calc(var(--afm-h) + var(--header-height));margin:0;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;background:var(--surface-page);color:var(--text-primary);font-family:var(--font-sans);font-size:var(--text-body);line-height:var(--leading-body);font-weight:var(--weight-regular);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,h4{margin:0;font-weight:var(--weight-semibold);color:var(--text-primary);text-wrap:balance}
h1{font-size:var(--text-h1);line-height:var(--leading-h1);letter-spacing:var(--tracking-h1)}
h2{font-size:var(--text-h2);line-height:var(--leading-h2);letter-spacing:var(--tracking-h2)}
h3{font-size:var(--text-h3);line-height:var(--leading-h3);letter-spacing:var(--tracking-h3)}
p{margin:0;text-wrap:pretty}
dl,dd,address{margin:0}
address{font-style:normal}
/* A monospace face runs large beside Instrument Sans, so inline code is set a size down. */
code{font-family:var(--font-mono);font-size:.92em}
a{color:var(--text-link);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;text-decoration-color:var(--ink-300);transition:var(--transition-control),text-decoration-color var(--dur-fast) var(--ease-standard),text-underline-offset var(--dur-base) var(--ease-standard)}
a:hover{color:var(--text-link-hover);text-decoration-color:var(--ink-900);text-underline-offset:4px}
::selection{background:var(--ink-900);color:var(--paper)}
a:focus-visible,button:focus-visible,input:focus-visible,[tabindex]:focus-visible{outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:var(--focus-ring-offset)}
img{max-width:100%;display:block}
/* The hidden attribute wins over any display value a component sets. */
[hidden]{display:none !important}
.prism-eyebrow{font-size:var(--text-eyebrow);line-height:1;letter-spacing:var(--tracking-eyebrow);text-transform:uppercase;font-weight:var(--weight-semibold);color:var(--text-secondary);margin:0}

/* Available to assistive technology and search engines, absent from the layout. */
.u-visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

.skip-link{position:absolute;left:-9999px;top:0;z-index:100;background:var(--ink-900);color:var(--text-inverse);padding:12px 20px;font-size:var(--text-body-sm);font-weight:var(--weight-medium);text-decoration:none}
.skip-link:focus{left:0}

/* ————— Layout helpers ————— */
/* The body is a column; main takes the slack, so the footer sits at the bottom of a
   short page. */
main{flex:1 0 auto}
.container{max-width:var(--site-w);margin:0 auto;padding:0 var(--gutter)}
/* The section rule over every page section: the five spectrum colours, 14px each with
   2px of paper between them, then ink to the end. Drawn here rather than written into
   each section, so the templates carry no markup for it. */
.page-section::before{content:"";display:block;height:var(--rule-heavy);background:linear-gradient(to right,
  var(--spectrum-red) 0 14px,transparent 0 16px,
  var(--spectrum-amber) 0 30px,transparent 0 32px,
  var(--spectrum-green) 0 46px,transparent 0 48px,
  var(--spectrum-cyan) 0 62px,transparent 0 64px,
  var(--spectrum-violet) 0 78px,transparent 0 80px,
  var(--ink-900) 0)}

/* ————— AFM exemption mark ————— */
/* Nrgfo art. 2:1: on the internet the mark is the AFM's own image, centred at the top,
   as wide as the page and always visible, in its original proportions — so the image
   spans the full width and its height follows from its shape. The header sticks
   beneath it. Which shape a screen gets is decided in eleventy.config.js (AFM_NOTICE);
   the image carries its own black frame. main.js measures the bar and writes its
   height to --afm-h; until it runs, the same shapes give the height here. 100vw
   includes the reserved scrollbar gutter, so this estimate errs a pixel or two high. */
/* Over the home hero the header is transparent, so the bar floats on the photo and
   carries the header's shadow; main.js toggles this with the header state. */
.afm-strip{position:sticky;top:0;z-index:21;background:var(--paper)}
.afm-strip--floating{box-shadow:var(--shadow-header)}
.afm-strip__image{display:block;width:100%;height:auto}
body.has-afm{--afm-h:calc(100vw * 123 / 586)}
@media (min-width:560px){body.has-afm{--afm-h:calc(100vw * 146 / 1176)}}
@media (min-width:1024px){body.has-afm{--afm-h:calc(100vw * 80 / 2357)}}

/* ————— Header ————— */
/* The hairline alone does not lift a sticky bar off the page once content scrolls
   under it. A shallow shadow does; the hairline stays, so the edge is still crisp
   rather than purely a soft gradient. */
/* Elevation appears only once content slides under the header (main.js sets
   .is-scrolled); at rest on a white page a shadow would sit on nothing. */
.site-header{position:sticky;top:var(--afm-h);z-index:20;background:var(--paper);border-bottom:var(--border-width) solid var(--border-hairline);transition:box-shadow var(--dur-slow) var(--ease-standard)}
.site-header.is-scrolled,.site-header.is-open{box-shadow:var(--shadow-header)}
.site-header__inner{max-width:var(--site-w);margin:0 auto;padding:0 var(--gutter);height:var(--header-height);display:flex;align-items:center;gap:48px}
.site-header__logo{text-decoration:none;flex:none;display:flex;align-items:center}
.site-header__logo img{height:44px;width:auto;display:block}
.site-nav{display:flex;gap:32px;flex:1;justify-content:flex-end;flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.site-nav::-webkit-scrollbar{display:none}
/* The underline grows from the left rather than switching on; currentColor keeps it
   in step with every text-colour state, including the white home variant. */
.site-nav a{position:relative;flex:none;white-space:nowrap;font-size:var(--text-body-sm);font-weight:var(--weight-medium);text-decoration:none;padding-bottom:5px;color:var(--text-secondary);transition:color var(--dur-fast) var(--ease-standard)}
.site-nav a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:currentColor;transform:scaleX(0);transform-origin:0 50%;transition:transform var(--dur-base) var(--ease-standard)}
.site-nav a:hover{color:var(--text-primary)}
.site-nav a[aria-current="page"]{color:var(--ink-900)}
.site-nav a:hover::after,.site-nav a[aria-current="page"]::after{transform:scaleX(1)}

.site-nav-panel{flex:1;display:flex;align-items:center;justify-content:flex-end;gap:32px}

.nav-toggle{display:none;align-items:center;justify-content:center;width:44px;height:44px;margin-right:-10px;padding:0;background:none;border:0;cursor:pointer;color:var(--ink-900)}
.nav-toggle__bars{position:relative;display:block;width:22px;height:12px}
.nav-toggle__bars span{position:absolute;left:0;width:100%;height:2px;background:currentColor;transition:transform var(--dur-base) var(--ease-standard),opacity var(--dur-fast) var(--ease-standard)}
.nav-toggle__bars span:nth-child(1){top:0}
.nav-toggle__bars span:nth-child(2){bottom:0}
.site-header.is-open .nav-toggle__bars span:nth-child(1){transform:translateY(5px) rotate(45deg)}
.site-header.is-open .nav-toggle__bars span:nth-child(2){transform:translateY(-5px) rotate(-45deg)}

.lang-toggle{display:flex;align-items:center;gap:10px;flex:none}
.lang-toggle a{font-size:var(--text-label);font-weight:var(--weight-medium);letter-spacing:.04em;text-decoration:none;color:var(--text-tertiary);transition:color var(--dur-fast) var(--ease-standard)}
.lang-toggle a:hover{color:var(--text-primary)}
.lang-toggle a[aria-current="true"]{color:var(--ink-900)}
.lang-toggle a + a{padding-left:10px;border-left:var(--border-width) solid var(--border-hairline)}

/* Home page: header starts transparent over the hero, then solidifies on scroll */
.site-header--home{background:transparent;border-bottom-color:transparent;box-shadow:none;transition:background-color var(--dur-slow) var(--ease-standard),border-color var(--dur-slow) var(--ease-standard),box-shadow var(--dur-slow) var(--ease-standard)}
.site-header--home.is-scrolled:not(.is-solid){box-shadow:none}
.site-header--home .site-header__logo{opacity:0;pointer-events:none;transition:opacity var(--dur-fast) var(--ease-standard)}
.site-header--home .nav-toggle{color:var(--text-inverse)}
.site-header--home.is-solid{background:var(--paper);border-bottom-color:var(--border-hairline);box-shadow:var(--shadow-header)}
.site-header--home.is-solid .site-header__logo{opacity:1;pointer-events:auto}
.site-header--home.is-solid .nav-toggle{color:var(--ink-900)}

/* White-on-photo link colouring belongs to the inline desktop bar only. Below
   900px these same links sit inside the paper overlay, and these selectors
   ((0,3,0)) would outrank the overlay's own (0,1,0) rules — media queries add no
   specificity — leaving white text on a white ground. */
@media (min-width:901px){
  .site-header--home .site-nav a,.site-header--home .lang-toggle a{color:rgba(255,255,255,.92)}
  .site-header--home .site-nav a:hover,.site-header--home .lang-toggle a:hover{color:var(--text-inverse)}
  .site-header--home .site-nav a[aria-current="page"]{color:var(--text-inverse)}
  .site-header--home .lang-toggle a[aria-current="true"]{color:var(--text-inverse)}
  .site-header--home .lang-toggle a + a{border-left-color:var(--border-inverse)}
  .site-header--home.is-solid .site-nav a,.site-header--home.is-solid .lang-toggle a{color:var(--text-secondary)}
  .site-header--home.is-solid .site-nav a:hover,.site-header--home.is-solid .lang-toggle a:hover{color:var(--text-primary)}
  .site-header--home.is-solid .site-nav a[aria-current="page"]{color:var(--ink-900)}
  .site-header--home.is-solid .lang-toggle a[aria-current="true"]{color:var(--ink-900)}
  .site-header--home.is-solid .lang-toggle a + a{border-left-color:var(--border-hairline)}
}

/* ————— Hero (Home) ————— */
/* Pulled up under the transparent header; the strip above it stays. */
.hero{position:relative;margin-top:calc(var(--header-height) * -1 - 1px);min-height:calc(100vh - var(--afm-h));min-height:calc(100svh - var(--afm-h));display:flex;align-items:center;justify-content:center;overflow:hidden}
/* Under the photo sits a 32px copy of it, inlined by the imagePlaceholder shortcode
   and blurred here, so the first frame shows the scene in soft focus rather than the
   scrim over bare paper. The scale hides the blur's soft edge behind the overflow. */
.hero__lqip{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;filter:blur(24px);transform:scale(1.1)}
.hero__image{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
/* A daylight photo with a bright sky and water needs a fairly deep veil, or the
   reverse logo and the transparent header links wash out against it. */
.hero__scrim{position:absolute;inset:0;background:linear-gradient(to bottom,rgba(26,26,26,.52) 0%,rgba(26,26,26,.34) 22%,rgba(26,26,26,.40) 100%)}
.hero__content{position:relative;z-index:1;width:100%;max-width:var(--site-w);padding:104px var(--gutter);display:flex;flex-direction:column;align-items:center;gap:48px;text-align:center}
.hero__title{margin:0;display:flex}
.hero__logo{height:clamp(64px,13vw,112px);width:auto;display:block}
.hero__lede{font-size:clamp(16px,2.3vw,21px);line-height:1.45;letter-spacing:-0.01em;max-width:46em;margin:0;color:var(--text-inverse);text-wrap:balance}

/* ————— Page sections ————— */
/* Content pages wrap in .container; the home hero does not, so it stays full-bleed
   while every other page gets breathing room above the footer. */
main > .container{padding-bottom:clamp(48px,7vw,88px)}
.page-section{padding:clamp(48px,6vw,72px) 0 0}
.page-section + .page-section{padding-top:clamp(56px,8vw,96px)}

/* The section grid: every section is a label column (heading, eyebrow, portrait)
   beside a content column whose width equals the reading measure, so no page
   carries an empty right half. The section rule above spans both columns. */
.section-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);column-gap:var(--col-gap);row-gap:24px;align-items:start;margin-top:28px}
/* The criteria grid takes 1.5x the prose column (1:7 instead of 5:7 of the same
   track space), so its middle cell starts exactly where the text above starts and
   the three cells are each half a prose measure wide. */
.section-grid--wide{grid-template-columns:minmax(0,1fr) minmax(0,7fr)}
.section-grid__label{position:sticky;top:calc(var(--chrome-h) + 32px)}
.section-grid__label > * + *{margin-top:20px}
.section-grid__content > * + *{margin-top:18px}
.section-grid__content > .lede + :is(.spec, address){margin-top:32px}
.lede{font-size:var(--text-body-lg);line-height:1.55;max-width:var(--measure-prose)}
.prose-stack{display:flex;flex-direction:column;gap:18px;max-width:var(--measure-prose)}
.section-grid__content > p{max-width:var(--measure-prose)}
.error-page__actions{margin-top:32px}

/* Het bedrijf — board */
.portrait{max-width:280px;aspect-ratio:3/4;background:var(--surface-sunken);border:var(--border-width) solid var(--border-hairline);overflow:hidden}
.portrait img{width:100%;height:100%;object-fit:cover;display:block}
/* The name sits one level below the section label but keeps h2's display size:
   semantic level and visual weight are set independently. */
.board__name{font-size:var(--text-h2);line-height:var(--leading-h2);letter-spacing:var(--tracking-h2)}
.section-grid__content > .board__name + p{margin-top:20px}
.board__linkedin{display:flex;gap:8px;align-items:baseline;margin-top:28px;padding-top:20px;border-top:var(--border-width) solid var(--border-hairline);max-width:var(--measure-prose)}
.board__linkedin span{font-size:var(--text-body-sm);color:var(--text-secondary)}
.board__linkedin a{font-size:var(--text-body-sm);font-weight:var(--weight-medium)}

/* Strategie — criteria */
/* Each cell draws its own hairline (1px gap, 1px shadow, so neighbours share one
   line). That way the lone centred cell in the last row sits on its own instead of
   leaving two grey blanks beside it. */
.criteria{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;padding:1px}
.criteria__cell{background:var(--paper);padding:28px 24px;min-height:104px;display:flex;align-items:center;overflow-wrap:anywhere;box-shadow:0 0 0 1px var(--border-hairline)}
.criteria__cell--center{grid-column:2}
.criteria__cell h3{margin:0}

/* Strategie — enquiry band, full bleed, with its own section grid inside */
.enquiry-band{background:var(--surface-sunken);padding:clamp(56px,7vw,88px) 0}
.enquiry-band .section-grid{margin-top:0}
.enquiry-form{display:grid;grid-template-columns:1fr 1fr;gap:24px 32px}
.enquiry-actions{margin-top:32px}
.enquiry-privacy{margin:20px 0 0;max-width:var(--measure-prose);font-size:var(--text-body-sm);line-height:1.6;color:var(--text-secondary)}
.enquiry-confirm,.enquiry-error{font-size:var(--text-body-lg);line-height:1.55;max-width:52ch;padding-top:24px;border-top:var(--rule-strong) solid var(--ink-900)}

/* Spec sheet: key/value rows (engineering, partners, contact) */
.spec{border-top:var(--rule-strong) solid var(--ink-900)}
.spec__row{display:grid;grid-template-columns:minmax(0,160px) minmax(0,1fr);gap:12px 32px;padding:18px 0;border-bottom:var(--border-width) solid var(--border-hairline)}
.spec__key{font-size:var(--text-body-sm);color:var(--text-secondary);padding-top:2px}
.spec__val{font-size:var(--text-body);overflow-wrap:anywhere;font-variant-numeric:tabular-nums}
/* The engineering page reads as a terminal readout: keys and values in the mono face,
   values at the size inline code has in running text. Code inside takes the row's own
   face and size, so it does not shrink a second time. */
.spec--mono :is(.spec__key,.spec__val){font-family:var(--font-mono)}
.spec--mono .spec__val{font-size:calc(var(--text-body) * .92)}
.spec--mono code{font:inherit}
.spec__note{font-size:var(--text-caption);color:var(--text-tertiary);max-width:var(--measure-prose)}

/* Bordered cells rather than a background showing through 1px gaps: a partly
   filled last row would otherwise leave empty grey boxes. */
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:16px}
.swatch{background:var(--paper);border:var(--border-width) solid var(--border-hairline);padding:14px}
.swatch__chip{height:52px;border:var(--border-width) solid var(--border-hairline)}
/* One class per palette token: stack.js lists every spectrum and ink token and stops
   the build if one has no class here. Inline style attributes are blocked by the CSP
   in production, so the colour cannot be set there. */
.swatch__chip--spectrum-red{background:var(--spectrum-red)}
.swatch__chip--spectrum-amber{background:var(--spectrum-amber)}
.swatch__chip--spectrum-green{background:var(--spectrum-green)}
.swatch__chip--spectrum-cyan{background:var(--spectrum-cyan)}
.swatch__chip--spectrum-violet{background:var(--spectrum-violet)}
.swatch__chip--ink-900{background:var(--ink-900)}
.swatch__chip--ink-700{background:var(--ink-700)}
.swatch__chip--ink-600{background:var(--ink-600)}
.swatch__chip--ink-500{background:var(--ink-500)}
.swatch__chip--ink-300{background:var(--ink-300)}
.swatch__chip--ink-200{background:var(--ink-200)}
.swatch__chip--ink-100{background:var(--ink-100)}
.swatch__chip--ink-050{background:var(--ink-050)}
.swatch__chip--paper{background:var(--paper)}
.swatch__name{display:block;font-family:var(--font-mono);font-size:var(--text-caption);font-weight:var(--weight-medium);margin-top:10px}
.swatch__value{display:block;font-family:var(--font-mono);font-size:var(--text-fine);line-height:1.5;color:var(--text-tertiary);margin-top:2px}
.swatch__value + .swatch__value{margin-top:0}

/* ————— Form fields ————— */
.prism-field{display:flex;flex-direction:column;gap:var(--space-3)}
.prism-field__label{font-size:var(--text-caption);font-weight:var(--weight-medium);color:var(--text-primary);letter-spacing:.005em}
.prism-input{font-family:var(--font-sans);font-size:var(--text-body-sm);color:var(--text-primary);background:var(--paper);border:var(--border-width) solid var(--border-field);border-radius:var(--radius-none);padding:var(--pad-control-y) var(--space-4);width:100%;transition:var(--transition-control)}
.prism-input::placeholder{color:var(--text-tertiary)}
.prism-input:hover{border-color:var(--ink-500)}
.prism-input:focus{border-color:var(--ink-900);outline:var(--focus-ring-width) solid var(--focus-ring);outline-offset:0}

/* ————— Button ————— */
.prism-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--font-sans);font-size:var(--text-body-sm);font-weight:var(--weight-medium);letter-spacing:.01em;line-height:1;border-radius:var(--radius-none);border:var(--border-width) solid transparent;padding:var(--pad-control-y) var(--pad-control-x);cursor:pointer;text-decoration:none;white-space:nowrap;transition:var(--transition-control),transform var(--dur-fast) var(--ease-standard)}
.prism-btn:not(:disabled):active{transform:translateY(1px)}
.prism-btn--primary{background:var(--action-primary);color:var(--text-inverse);border-color:var(--action-primary)}
.prism-btn--primary:hover{background:var(--action-primary-hover);border-color:var(--action-primary-hover)}
.prism-btn--primary:active{background:var(--action-primary-active);border-color:var(--action-primary-active)}
.prism-btn svg{flex:none;transition:transform var(--dur-base) var(--ease-standard)}
.prism-btn:not(:disabled):hover svg{transform:translateX(3px)}
.prism-btn:disabled{opacity:.55;cursor:default}

/* ————— Footer ————— */
/* One line under a strong rule, as over every spec list: the logo mark and the
   registration details on the left, the legal pages, the version and the credit on
   the right, all in caption type. */
.site-footer{background:var(--paper);color:var(--text-primary)}
.site-footer__inner{max-width:var(--site-w);margin:0 auto;padding:64px var(--gutter) 0}
.site-footer__bar{display:flex;align-items:center;justify-content:space-between;gap:32px;border-top:var(--rule-strong) solid var(--ink-900);padding:24px 0}
.site-footer__id{display:flex;align-items:center;gap:14px}
.site-footer__id img{height:28px;width:auto;display:block}
/* Every line on a 24px pitch, and every link one line tall: a 24px target without
   padding, and the stacked lines on a phone stay evenly spaced. */
.site-footer__company,.site-footer__links{margin:0;font-size:var(--text-caption);line-height:24px;color:var(--text-tertiary)}
.site-footer__links a{display:inline-block;color:inherit}
.site-footer__links a:hover{color:var(--text-primary)}
.site-footer__sep{margin:0 3px;color:var(--ink-300)}

/* ————— Motion ————— */
/* Motion here confirms something that just happened: a page arrived, a control was
   used. Every element moves once; only opacity and transform change, so nothing
   shifts; every keyframe ends on the static design, so a reduced-motion visitor
   (durations forced to .01ms below) simply sees the finished page. Page content itself
   does not animate: the crossfade between pages is a section's arrival. */
@keyframes nav-panel-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes rise-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes hero-focus{from{opacity:0;filter:blur(14px)}to{opacity:1;filter:blur(0)}}

/* Home: the logo and the lede come into focus over the photo, out of a blur and
   without moving, on the first page of a visit only (head.js sets .is-first-visit on
   <html> before first paint; coming back from another page they are simply there).
   The backwards fill hides them through their delay and then hands back to the static
   styles, so no filter lingers on the text once they are sharp. Usually the photo is
   already there and, decoded synchronously, simply in the first frame. If main.js
   finds it still loading it holds the photo and the text back (.is-loading) until it
   arrives; the photo then fades over its blurred preview (.is-late) and the text
   focuses after it. Without JavaScript the browser paints the photo when it can. */
.is-first-visit .hero__title{animation:hero-focus 1s var(--ease-decelerate) .25s backwards}
.is-first-visit .hero__lede{animation:hero-focus 1s var(--ease-decelerate) .5s backwards}
.hero.is-loading .hero__image,.hero.is-loading .hero__title,.hero.is-loading .hero__lede{animation:none;opacity:0}
.hero.is-late .hero__image{animation:fade-in 600ms var(--ease-decelerate) both}

/* The enquiry outcome fades in when main.js reveals it (display none → block restarts
   the animation, as with the menu panel). */
.enquiry-confirm,.enquiry-error{animation:rise-in 500ms var(--ease-decelerate) both}

/* Pages dissolve into one another instead of flashing white; the strip and header
   are named so they stay put while the content changes. Firefox ignores this. */
@view-transition{navigation:auto}
.afm-strip{view-transition-name:afm-strip}
.site-header{view-transition-name:site-header}

/* ————— Responsive ————— */
@media (max-width:1024px){
  :root{--gutter:32px;--col-gap:48px}
  .site-header__inner{gap:32px}
  .site-nav{gap:24px}
  /* The footer stacks centred, one fact per line on the same 24px pitch: the legal
     name in semibold, the KvK number, the legal pages, then the version and the
     credit. The separators between what are now separate lines go. From here, not
     900px: the English line ("Chamber of Commerce (KvK)") needs about 950px. */
  .site-footer__bar{flex-direction:column;gap:0;text-align:center}
  .site-footer__id{flex-direction:column;gap:12px}
  .site-footer__id img{height:24px}
  .site-footer__name{font-weight:var(--weight-semibold)}
  .site-footer__company > span,.site-footer__group{display:block}
  .site-footer__company > .site-footer__sep,.site-footer__sep--group{display:none}
}

/* Below this width the primary navigation collapses behind the toggle and the
   section grid stacks: label above content. */
@media (max-width:900px){
  .nav-toggle{display:inline-flex}
  .site-header__inner{gap:16px;justify-content:space-between}

  /* Paper overlay filling everything below the header. It deliberately starts at
     the header's bottom edge and sits below it in the stack (header is z-index 20),
     so the logo and the bar never move or resize when the menu opens. */
  .site-nav-panel{position:fixed;top:var(--chrome-h);left:0;right:0;bottom:0;z-index:15;display:none;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:0;padding:0;background:var(--surface-page);overflow-y:auto;overscroll-behavior:contain}
  /* display, not visibility/opacity: a zero-duration visibility transition can be
     left mid-flight, which would keep the closed menu's links focusable. The
     entrance is a keyframe animation instead, which runs cleanly on display change. */
  .site-header.is-open .site-nav-panel{display:flex;animation:nav-panel-in var(--dur-base) var(--ease-standard) both}

  .site-nav{flex:1;flex-direction:column;justify-content:flex-start;gap:0;overflow:visible;padding:12px var(--gutter) 0}
  .site-nav a{font-size:clamp(22px,6.4vw,28px);font-weight:var(--weight-semibold);letter-spacing:-.02em;color:var(--ink-900);padding:15px 0;border-bottom:var(--border-width) solid var(--border-hairline);border-left:var(--rule-heavy) solid transparent}
  .site-nav a::after{content:none}
  .site-nav a:hover{color:var(--ink-900)}
  .site-nav a[aria-current="page"]{color:var(--ink-900);border-bottom-color:var(--border-hairline);border-left-color:var(--ink-900);padding-left:14px}

  /* Each code is a 44px square target for a thumb (as text alone "NL" is 20px wide).
     The 12px side padding moves into the links, and out of the gap and the row's left
     padding, so the codes sit where they did. The rule between them is drawn as a 34px
     line rather than a border, which would now run the full 44px. */
  .lang-toggle{gap:0;padding:17px var(--gutter) 23px calc(var(--gutter) - 12px);justify-content:flex-start;border-top:var(--border-width) solid var(--border-hairline)}
  .lang-toggle a{display:flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0 12px;font-size:var(--text-body-sm);color:var(--text-tertiary)}
  .lang-toggle a:hover{color:var(--text-primary)}
  .lang-toggle a[aria-current="true"]{color:var(--ink-900)}
  .lang-toggle a + a{padding-left:12px;border-left:0;background:linear-gradient(var(--border-hairline),var(--border-hairline)) left center / var(--border-width) 34px no-repeat}

  .site-header--home.is-open{background:var(--paper);border-bottom-color:var(--border-hairline);box-shadow:var(--shadow-header)}
  .site-header--home.is-open .site-header__logo{opacity:1;pointer-events:auto}
  .site-header--home.is-open .nav-toggle{color:var(--ink-900)}

  .section-grid{grid-template-columns:1fr;row-gap:20px}
  .section-grid__label{position:static}
  .portrait{max-width:220px}
  .enquiry-form{grid-template-columns:1fr}
  /* 16px keeps iOS Safari from zooming the viewport when a field takes focus. */
  .prism-input{font-size:var(--text-body)}
  /* Buttons and fields render 36px tall at desktop padding — fine for a pointer,
     short of the 44px guideline for touch. Raising the shared control padding
     lifts both to 44px without touching the type. */
  :root{--pad-control-y:14px}
}

@media (max-width:640px){
  :root{--gutter:20px;--header-height:64px}
  /* Only the mark stays pinned on phones: bar plus header would take a fifth of the
     screen. The header scrolls with the page and docks again while the menu is open,
     so the fixed overlay lines up with its bottom edge. */
  .site-header{position:static}
  .site-header.is-open{position:sticky;top:var(--afm-h)}
  .criteria{grid-template-columns:1fr}
  .criteria__cell{min-height:0;padding:22px 20px}
  .criteria__cell--center{grid-column:auto}
  .spec__row{grid-template-columns:1fr;gap:6px}
  /* Board: the name above the photo, and the photo the full width of the screen. The
     two columns give up their boxes, so eyebrow, name, photo and text form one stack;
     the spacing comes from the columns' own margins instead of the grid gap. */
  .section-grid--board{row-gap:0}
  .section-grid--board > .section-grid__label,.section-grid--board > .section-grid__content{display:contents}
  .section-grid--board .prism-eyebrow{order:-2}
  .section-grid--board .board__name{order:-1;margin-top:20px}
  .section-grid--board .portrait{max-width:none;margin-inline:calc(-1 * var(--gutter));border-inline:0}
  /* The lede's forced break splits two sentences on wide screens; at phone width it
     left a short orphan line, so the sentences run on and the rag is balanced instead. */
  .hero__break{display:none}
  .hero__content{padding:88px var(--gutter);gap:36px}
  .enquiry-band{padding:48px 0}
  .site-footer__inner{padding:48px var(--gutter) 0}
}

/* Paper does not scroll: print the finished page, never a paused entrance. */
@media print{*,*::before,*::after{animation:none !important;transition:none !important}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-delay:0s !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;transition-delay:0s !important;scroll-behavior:auto !important}
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none !important}
  .hero.is-loading .hero__title,.hero.is-loading .hero__lede{opacity:1}
}
