/* base.css — "sharp" template: precision.
 *
 * A complete, quality-gated design system (hand-rolled BEM, framework-free).
 * The build agent copies this file verbatim into a site's `style.css` and
 * overwrites ONLY the delimited brand-parameter block below — every other rule
 * ships byte-identical, which is how the fixture's Lighthouse/axe pass transfers
 * to every real build. See TEMPLATE.md for the character spec and the
 * brand-parameter contract (which properties to fill, how tints/shades derive).
 *
 * Character: flat, hard-edged, structured — grotesk type, 0-2px radii, hairline
 * borders instead of shadows, high contrast, brisk slide-in motion. Shares the
 * BEM vocabulary of the "soft" template so a site's HTML renders under either
 * stylesheet unchanged. Fonts are self-hosted from the site's own `fonts/`
 * folder — see the generated web-font section below.
 */

/* ── Web fonts (self-hosted, generated) ──────────────────────────────────
 * Regenerate with `node scripts/fetch-template-fonts.mjs`. The files live in
 * the site's own `fonts/` folder, so a page load reaches no third party.
 * Rules for every approved pair are listed; only the pair named in the brand
 * block is ever requested, and a build copies only that pair's files. */

/* archivo-inter */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/archivo-normal-600.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: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/archivo-normal-700.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: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/archivo-normal-800.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: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-normal-400.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: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/inter-normal-600.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: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/inter-normal-700.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;
}

/* barlow */
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-normal-400.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: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-normal-500.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: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-normal-600.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: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-condensed-normal-600.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: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-condensed-normal-700.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;
}

/* spacegrotesk-plex */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-normal-400.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: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-normal-500.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: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-normal-600.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: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/space-grotesk-normal-500.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: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/space-grotesk-normal-600.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: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-grotesk-normal-700.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;
}

/* schibsted-hanken */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/hanken-grotesk-normal-400.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: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/hanken-grotesk-normal-500.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: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/hanken-grotesk-normal-600.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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/schibsted-grotesk-normal-600.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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/schibsted-grotesk-normal-700.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: 'Schibsted Grotesk';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/schibsted-grotesk-normal-800.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;
}



/* ── end web fonts ── */

/* ── Brand parameters (per-site) ─────────────────────────────────────────────
 * The ONLY block the build agent edits. Fill from the extracted brand (logo
 * colours, screenshot palette, tone). Keep every property; adjust its value.
 * Contrast contract: --color-text and --color-muted must hold >= 4.5:1 on
 * --color-surface and --color-surface-alt; --color-on-primary must hold >= 4.5:1
 * on --color-primary; --color-primary used as link text must hold >= 4.5:1 on
 * --color-surface. Fonts must be one of TEMPLATE.md's approved grotesk pairs. */
:root {
  --color-primary: #1b0f53;        /* Kosmos deep indigo — links, primary buttons, flat brand blocks */
  --color-primary-shade: #130a3d;  /* darker primary for hover/active (derive: primary ~15% darker) */
  --color-primary-tint: #e8e7ee;   /* pale block/fill tint (derive: primary mixed ~90% white) */
  --color-on-primary: #ffffff;     /* text/icons on --color-primary blocks */
  --color-accent: #a23fb8;         /* orchid, deepened from the brand lilac #e591f1 so the focus ring holds 5.3:1 on white */
  --color-surface: #ffffff;        /* page background */
  --color-surface-alt: #f3f1f9;    /* cool lavender grey for alternating sections */
  --color-text: #150f2b;           /* near-black indigo body text (high contrast) */
  --color-muted: #4f4a68;          /* muted cool violet-grey for secondary text (>= 4.5:1 on surfaces) */
  --color-border: #d7d3e6;         /* hairline border colour */

  --font-heading: 'Barlow Condensed', 'Arial Narrow', Arial, sans-serif;
  --font-body: 'Barlow', 'Segoe UI', system-ui, -apple-system, sans-serif;
}
/* ── end Brand parameters ──────────────────────────────────────────────────── */

/* ── Fixed tokens (the template character — do not edit per site) ──────────── */
:root {
  /* Type scale 1.333 (perfect fourth), fluid via clamp; body line-height 1.5. */
  --step--1: clamp(0.8rem, 0.77rem + 0.13vw, 0.875rem);
  --step-0: clamp(1rem, 0.96rem + 0.18vw, 1.125rem);
  --step-1: clamp(1.33rem, 1.24rem + 0.42vw, 1.6rem);
  --step-2: clamp(1.78rem, 1.6rem + 0.83vw, 2.37rem);
  --step-3: clamp(2.37rem, 2.05rem + 1.5vw, 3.16rem);
  --step-4: clamp(3.16rem, 2.6rem + 2.6vw, 4.21rem);
  --step-5: clamp(3.8rem, 2.9rem + 4.2vw, 5.61rem);
  --leading-body: 1.5;
  --leading-tight: 1.05;

  /* Spacing — tighter, structured grid; section padding 4-5rem. */
  --space-3xs: 0.375rem;
  --space-2xs: 0.625rem;
  --space-xs: 0.9rem;
  --space-s: 1.25rem;
  --space-m: 2rem;
  --space-l: 3rem;
  --space-xl: 4.5rem;
  --section-pad: clamp(3rem, 2.2rem + 3vw, 5rem);
  --container-max: 74rem;

  /* Radii 0-2px everywhere — the sharp character. */
  --radius-s: 0;
  --radius-m: 2px;
  --radius-l: 2px;
  --radius-pill: 2px;

  /* Flat — no box-shadows; hairline borders carry separation. */
  --border-hair: 1px solid var(--color-border);
  --border-strong: 2px solid var(--color-text);

  /* Brisk motion, 200-250ms. */
  --ease-sharp: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-reveal: 240ms;
  --dur-hover: 180ms;

  --header-h: 4.25rem;
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  color: var(--color-text);
  background: var(--color-surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}
input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}
a {
  color: var(--color-primary);
  text-underline-offset: 0.16em;
}
a:hover {
  color: var(--color-primary-shade);
}
h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  line-height: var(--leading-tight);
  font-weight: 700;
  color: var(--color-text);
  letter-spacing: -0.02em; /* tight grotesk headings */
}
h1 {
  font-size: var(--step-4);
}
h2 {
  font-size: var(--step-3);
}
h3 {
  font-size: var(--step-2);
}
ul,
ol {
  padding-left: 1.15em;
}

/* Visible, high-contrast focus ring for keyboard users on every interactive
   element — never remove the outline without an equal-or-better replacement. */
:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

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

/* ── Utilities ───────────────────────────────────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-s);
}
/* Accessible visually-hidden text (labels for icon-only controls, etc.). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Skip link: off-screen until focused, then pinned top-left for keyboard users. */
.skip-link {
  position: absolute;
  left: var(--space-s);
  top: -4rem;
  z-index: 100; /* above the sticky header */
  padding: var(--space-2xs) var(--space-xs);
  background: var(--color-text);
  color: var(--color-surface);
  transition: top var(--dur-hover) var(--ease-sharp);
}
.skip-link:focus {
  top: var(--space-2xs);
  color: var(--color-surface);
}

/* Scroll-reveal: only hidden when JS is active (root .js), so no-JS keeps all
   content visible. main.js adds .is-visible as elements enter the viewport. */
.js [data-reveal] {
  opacity: 0;
  transform: translateX(-22px); /* brisk slide-in from the left */
  transition: opacity var(--dur-reveal) var(--ease-sharp), transform var(--dur-reveal) var(--ease-sharp);
}
.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3xs);
  min-height: 3rem; /* comfortable tap target */
  padding: 0.8rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--radius-m); /* square buttons — the sharp character */
  font-weight: 700;
  font-size: var(--step-0);
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease-sharp), color var(--dur-hover) var(--ease-sharp),
    border-color var(--dur-hover) var(--ease-sharp);
}
.button--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
/* Hover inverts the fill — flat, no lift, no shadow. */
.button--primary:hover {
  background: var(--color-surface);
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.button--ghost {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-border);
}
.button--ghost:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}

/* ── Header / navigation ─────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50; /* above page content, below the skip link */
  background: var(--color-surface);
  border-bottom: var(--border-hair);
  transition: border-color var(--dur-hover) var(--ease-sharp);
}
/* main.js adds --stuck once scrolled off the top; strengthen the hairline. */
.site-header--stuck {
  border-bottom: var(--border-strong);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  min-height: var(--header-h);
}
.site-header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  color: var(--color-text);
  text-decoration: none;
  text-transform: uppercase;
}
.site-header__logo {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-m);
}
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  background: transparent;
  border: var(--border-strong);
  border-radius: var(--radius-m);
  cursor: pointer;
}
.nav__toggle-bars {
  position: relative;
  width: 1.25rem;
  height: 2px;
  background: var(--color-text);
}
.nav__toggle-bars::before,
.nav__toggle-bars::after {
  content: '';
  position: absolute;
  left: 0;
  width: 1.25rem;
  height: 2px;
  background: var(--color-text);
}
.nav__toggle-bars::before {
  top: -6px;
}
.nav__toggle-bars::after {
  top: 6px;
}
.nav__menu {
  list-style: none;
  padding: 0;
  margin: 0;
}
.nav__item {
  margin: 0;
}
.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 3rem;
  padding: 0 var(--space-2xs);
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: var(--step--1);
  border-bottom: 2px solid transparent; /* underline-sweep target */
  transition: border-color var(--dur-hover) var(--ease-sharp), color var(--dur-hover) var(--ease-sharp);
}
.nav__link:hover,
.nav__link--active {
  color: var(--color-primary);
  border-bottom-color: var(--color-accent); /* accent underline sweep */
}

/* Mobile-first: nav collapses behind the toggle; expands to a row at >= 48rem. */
@media (max-width: 47.99rem) {
  .nav__menu {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    flex-direction: column;
    gap: 0;
    padding: var(--space-2xs) var(--space-s) var(--space-s);
    background: var(--color-surface);
    border-bottom: var(--border-strong);
  }
  .nav__menu--open {
    display: flex;
  }
  .nav__link {
    width: 100%;
    border-bottom: var(--border-hair);
  }
}
@media (min-width: 48rem) {
  .nav__toggle {
    display: none;
  }
  .nav__menu {
    display: flex;
    align-items: center;
    gap: var(--space-s);
  }
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  padding-block: var(--section-pad);
  border-bottom: var(--border-strong);
  overflow: hidden;
  background: var(--color-surface);
  /* Flat diagonal primary wash — directional, not soft-glow, in keeping with
     the hard-edged character. Derived from brand tokens via color-mix();
     browsers without color-mix() keep the solid surface. */
  background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 7%, var(--color-surface)), var(--color-surface) 55%);
}
.hero__inner {
  display: grid;
  gap: var(--space-l);
  align-items: center;
}
.hero__body {
  min-width: 0; /* grid child: keep a long word from blowing out the text column */
}
.hero__kicker {
  display: inline-block;
  margin-bottom: var(--space-2xs);
  padding: var(--space-3xs) var(--space-2xs);
  background: var(--color-primary); /* bold flat block — sharp character */
  color: var(--color-on-primary);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--step--1);
}
.hero__title {
  /* Below --step-5: at the full display step a 13-character Finnish word ("painopalvelua")
     is wider than the hero column at 375px and at the narrowest two-column width, and breaks.
     This is the largest size at which it still fits. --step-5 itself is unchanged. */
  font-size: clamp(3.57rem, 2.73rem + 3.95vw, 5.27rem);
  overflow-wrap: break-word;
  /* Finnish compounds routinely run past 20 characters ("ympäristöystävällistä"). One cannot
     fit unbroken in a hero column at display size — it would take body-copy size to fit. Left
     unhyphenated the browser still breaks the word, it just breaks it silently, which reads
     worse than a hyphen. So hyphenate, but only from 16 characters up, leaving at least 5
     letters before and 4 after the break. The 13-14 character words that a Finnish tagline
     is full of ("painopalvelua") are kept whole by the title size instead, so they never get
     the hyphen that made the first live site look broken. A 16+ character business name will
     be hyphenated; a visible hyphen is still the better of the two possible breaks. Safari
     before 17 ignores the 16-character floor and applies only the 5/4 limits. */
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 16 5 4;
  -webkit-hyphenate-limit-before: 5;
  -webkit-hyphenate-limit-after: 4;
  max-width: 15ch;
  text-transform: uppercase;
}
.hero__text {
  margin-top: var(--space-s);
  font-size: var(--step-1);
  color: var(--color-muted);
  max-width: 46ch;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-m);
}
.hero__media {
  border: var(--border-strong); /* hard-edged framed hero */
  overflow: hidden;
  animation: hero-slide var(--dur-reveal) var(--ease-sharp) both;
}
.hero__art {
  width: 100%;
  height: auto;
}
@media (min-width: 56rem) {
  .hero__inner {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

/* ── Section scaffolding ─────────────────────────────────────────────────── */
.section {
  padding-block: var(--section-pad);
  border-bottom: var(--border-hair); /* visible section rules — structured grid */
}
.section--alt {
  background: var(--color-surface-alt);
}
.section__head {
  max-width: 52ch;
  margin-bottom: var(--space-l);
}
.section__kicker {
  display: inline-block;
  margin-bottom: var(--space-2xs);
  padding-bottom: var(--space-3xs);
  border-bottom: 2px solid var(--color-accent); /* accent underline on the kicker */
  font-weight: 700;
  color: var(--color-primary);
  text-transform: uppercase; /* uppercase kicker labels — sharp character */
  letter-spacing: 0.08em;
  font-size: var(--step--1);
}
.section__title {
  font-size: var(--step-3);
  text-transform: uppercase;
}
.section__lead {
  margin-top: var(--space-s);
  color: var(--color-muted);
  font-size: var(--step-1);
}

/* ── Cards (numbered service grid — the sharp treatment) ─────────────────── */
.card-grid {
  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  border-top: var(--border-hair);
  border-left: var(--border-hair);
  counter-reset: card; /* drives the numbered ::before on each card */
}
@media (min-width: 40rem) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 60rem) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.card {
  position: relative; /* positions the numeric counter badge */
  counter-increment: card;
  padding: var(--space-m);
  background: var(--color-surface);
  border-right: var(--border-hair);
  border-bottom: var(--border-hair);
  transition: background-color var(--dur-hover) var(--ease-sharp);
}
.card::before {
  content: counter(card, decimal-leading-zero);
  position: absolute;
  top: var(--space-s);
  right: var(--space-m);
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--step-1);
  color: var(--color-border);
}
.card:hover {
  background: var(--color-surface-alt); /* flat fill shift, no lift */
}
.card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: var(--space-s);
  background: var(--color-primary-tint);
  color: var(--color-primary);
  border-radius: var(--radius-m);
}
.card__title {
  font-size: var(--step-1);
  margin-bottom: var(--space-2xs);
  text-transform: uppercase;
}
.card__text {
  color: var(--color-muted);
}
/* The reset at the top of this file removes every margin, so a card holding more
   than a title and one paragraph (a photo, a second paragraph, a line of links)
   would stack its pieces flush against each other. This spaces each piece from the
   one above it. The gap equals the title's own bottom margin, and the two overlap
   rather than add up, so the space under a title stays as it was. */
.card > * + * {
  margin-top: var(--space-2xs);
}
/* The icon is an inline box, so its bottom margin does not overlap the next
   piece's top margin. It already sets the space beneath it, so the piece that
   follows adds none. */
.card__icon + * {
  margin-top: 0;
}

/* ── Gallery ─────────────────────────────────────────────────────────────── */
.gallery {
  display: grid;
  gap: var(--space-2xs);
  grid-template-columns: 1fr;
}
@media (min-width: 40rem) {
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 60rem) {
  .gallery {
    grid-template-columns: repeat(3, 1fr);
  }
}
.gallery__item {
  overflow: hidden;
  border: var(--border-hair);
}
.gallery__image {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--dur-hover) var(--ease-sharp);
}
.gallery__item:hover .gallery__image {
  transform: scale(1.03);
}

/* ── Testimonial ─────────────────────────────────────────────────────────── */
.testimonial {
  max-width: 46ch;
  margin-inline: auto;
  padding: var(--space-l);
  text-align: left;
  border-left: 4px solid var(--color-accent); /* hard accent rule */
  background: var(--color-surface-alt);
  /* The accent bleeds a short way in from the rule, then flattens out.
     Token-derived; browsers without color-mix() keep the solid fill. */
  background: linear-gradient(90deg, color-mix(in srgb, var(--color-accent) 7%, var(--color-surface-alt)), var(--color-surface-alt) 45%);
}
.testimonial__quote {
  font-family: var(--font-heading);
  font-size: var(--step-2);
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.testimonial__author {
  display: block;
  margin-top: var(--space-s);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-primary);
}

/* ── FAQ ─────────────────────────────────────────────────────────────────── */
.faq {
  max-width: 52rem;
  margin-inline: auto;
  border-top: var(--border-hair);
}
.faq__item {
  padding: var(--space-s) 0;
  border-bottom: var(--border-hair);
}
.faq__question {
  font-size: var(--step-1);
  margin-bottom: var(--space-2xs);
  text-transform: uppercase;
}
.faq__answer {
  color: var(--color-muted);
}
/* An answer longer than one paragraph (two paragraphs, or a paragraph and a list)
   needs the same spacing as a card: with every margin reset, its pieces would run
   together. */
.faq__answer > * + * {
  margin-top: var(--space-2xs);
}

/* ── Contact form (posts via mailto — no runtime dependency) ─────────────── */
.contact-form {
  display: grid;
  gap: var(--space-s);
  max-width: 40rem;
}
.contact-form__field {
  display: grid;
  gap: var(--space-3xs);
}
.contact-form__label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: var(--step--1);
}
.contact-form__input,
.contact-form__textarea {
  width: 100%;
  padding: 0.8rem 0.9rem;
  background: var(--color-surface);
  border: var(--border-hair);
  border-radius: var(--radius-m);
}
.contact-form__input:focus,
.contact-form__textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: inset 0 0 0 1px var(--color-primary);
}
.contact-form__textarea {
  min-height: 8rem;
  resize: vertical;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
  padding-block: var(--space-xl) var(--space-l);
  background: var(--color-text);
  /* A steel cast of the primary at the top of the block settles into the
     near-black — both endpoints stay far darker than the light text, so the
     footer's >= 4.5:1 inversion holds. Browsers without color-mix() keep the
     solid block. */
  background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary) 16%, var(--color-text)), var(--color-text) 45%);
  color: var(--color-surface);
}
.site-footer__inner {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) {
  .site-footer__inner {
    grid-template-columns: repeat(3, 1fr);
  }
}
/* The footer inverts: a light `color` on the near-black block. The global h1-h4 rule sets
   `color: var(--color-text)`, which is more specific than inheritance and would paint the
   headings the same near-black as the block behind them (a 1:1 contrast — invisible).
   Inherit instead, so any heading added to the footer follows the inversion. */
.site-footer :is(h1, h2, h3, h4) {
  color: inherit;
}
.site-footer__heading {
  font-family: var(--font-heading);
  font-size: var(--step-1);
  margin-bottom: var(--space-s);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.site-footer__link {
  display: block;
  padding: var(--space-3xs) 0;
  color: var(--color-surface);
  text-decoration: none;
}
.site-footer__link:hover {
  color: var(--color-accent);
}
.site-footer__legal {
  margin-top: var(--space-l);
  padding-top: var(--space-s);
  border-top: 1px solid color-mix(in srgb, var(--color-surface) 30%, transparent);
  color: color-mix(in srgb, var(--color-surface) 78%, transparent);
  font-size: var(--step--1);
}

/* ── Legal page ──────────────────────────────────────────────────────────── */
.legal {
  max-width: 62ch;
  margin-inline: auto;
  padding-block: var(--section-pad);
}
.legal__title {
  margin-bottom: var(--space-m);
  text-transform: uppercase;
}
.legal__body > * + * {
  margin-top: var(--space-s);
}
.legal__body h2 {
  font-size: var(--step-2);
  margin-top: var(--space-l);
  text-transform: uppercase;
}

/* ── Cookie banner (used only when a site sets cookies; main.js dismisses) ── */
.cookie-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80; /* above content, below the skip link */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  background: var(--color-surface);
  border-top: var(--border-strong);
}
.cookie-banner__text {
  flex: 1 1 16rem;
  color: var(--color-muted);
  font-size: var(--step--1);
}
.cookie-banner__actions {
  display: flex;
  gap: var(--space-2xs);
}

/* ── Demo banner (pre-contract preview marker) ───────────────────────────── */
.demo-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90; /* above the cookie banner */
  padding: var(--space-2xs) var(--space-s);
  text-align: center;
  /* near-black block, not accent: white-on-accent orange fails 4.5:1 at this
     size — the text slot uses --color-text bg so contrast is guaranteed. */
  background: var(--color-text);
  color: var(--color-surface);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--step--1);
}
/* The banner inverts like the footer: a light `color` on the near-black block.
   The global `a { color: var(--color-primary) }` rule would print its link in
   navy on near-black (1.6:1, illegible) — override with the same light surface
   token the banner text already uses. */
.demo-banner a {
  color: var(--color-surface);
}
.demo-banner a:hover {
  color: var(--color-accent);
}

/* ── Error (404) page ────────────────────────────────────────────────────── */
.error-page {
  display: grid;
  place-content: center;
  gap: var(--space-s);
  min-height: 60vh;
  padding: var(--section-pad) var(--space-s);
  text-align: center;
}
.error-page__code {
  font-family: var(--font-heading);
  font-size: var(--step-5);
  color: var(--color-primary);
  letter-spacing: -0.03em;
}
.error-page__title {
  font-size: var(--step-3);
  text-transform: uppercase;
}
.error-page__text {
  color: var(--color-muted);
  max-width: 40ch;
  margin-inline: auto;
}

/* ── Motion keyframes ────────────────────────────────────────────────────── */
/* hero-slide: the hero media slides in briskly from the left on load.
   Transform-only — no opacity fade — so the hero media paints immediately and
   never delays Largest Contentful Paint. */
@keyframes hero-slide {
  from {
    transform: translateX(-28px);
  }
  to {
    transform: none;
  }
}
/* sweep-in: a brisk left-to-right wipe for optional accent underlines. */
@keyframes sweep-in {
  from {
    transform: scaleX(0);
    transform-origin: left;
  }
  to {
    transform: scaleX(1);
    transform-origin: left;
  }
}

/* ── Map, click-to-load (only on a page with a confirmed street address) ──── */
/* The block reserves its space up front and holds only plain markup: nothing is
   requested from Google until the visitor presses the button, at which point
   main.js swaps the placeholder for the map frame. */
.map-embed {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--color-surface-alt);
  border: var(--border-hair);
  border-radius: var(--radius-m);
}
@media (min-width: 45rem) {
  .map-embed {
    aspect-ratio: 16 / 9;
  }
}
.map-embed__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-s);
  text-align: center;
}
/* The small print that tells the visitor what pressing the button will load. */
.map-embed__note {
  max-width: 44ch;
  color: var(--color-muted);
  font-size: var(--step--1);
}
/* Hidden without JavaScript, where pressing it could only do nothing; the link
   below it opens the same location in that case. */
.map-embed__load {
  display: none;
}
.js .map-embed__load {
  display: inline-flex;
}
.map-embed__link {
  font-size: var(--step--1);
}
.map-embed__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* ── Site-specific composition ── */
/* Article and info prose keeps a readable line length instead of spanning the full container. */
.legal__body {
  max-width: 68ch;
}
