/* ============================================================================
   Re.lief website — the Recovery identity on a static, zero-JavaScript surface.
   Loaded after theme/primitives.css and theme/semantic.css (synced copies of the
   app's token layers — see scripts/websiteSyncTheme.js). Colours, radii, spacing
   and motion come from those tokens; this file adds only what a marketing page
   needs and the app has no equivalent for: a larger reading type scale, page
   layout, and the shared chrome.
   ============================================================================ */

/* ── Self-hosted faces (P8: no Google CDN, no visitor-IP leak). The fallback
   metrics mirror frontend/src/theme/fonts.css; the conformance test compares the
   size-adjust values so the two cannot drift. ─────────────────────────────── */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/figtree/figtree-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: 'Figtree';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/figtree/figtree-latinext.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;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/fraunces/fraunces-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: 'Fraunces';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/fraunces/fraunces-latinext.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;
}
@font-face {
  font-family: 'Figtree Fallback';
  src: local('Arial'), local('Helvetica Neue'), local('Segoe UI');
  size-adjust: 101.3%;
  ascent-override: 95%;
  descent-override: 25%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Fraunces Fallback';
  src: local('Georgia'), local('Times New Roman');
  size-adjust: 77.5%;
  ascent-override: 92%;
  descent-override: 23%;
  line-gap-override: 0%;
}

:root {
  --font-display: 'Fraunces', 'Fraunces Fallback', Georgia, 'Times New Roman', serif;
  --font-text: 'Figtree', 'Figtree Fallback', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* ── Website type scale — a reading surface, not an app UI. The app's
     --text-* tokens stay at app sizes; these are the site's own. ─────────── */
  --web-text-hero: clamp(34px, 6vw, 54px);
  --web-text-h2: clamp(26px, 3.6vw, 36px);
  --web-text-h3: 21px;
  --web-text-lead: clamp(18px, 2vw, 21px);
  --web-text-body: 17px;
  --web-text-small: 15px;
  --web-text-eyebrow: 13px;

  --web-container: 1080px;
  --web-container-narrow: 730px;
  --web-section-gap: clamp(56px, 9vw, 104px);
  --web-measure: 68ch;

  /* Tells the browser both palettes exist, so scrollbars and any UA-rendered
     control match the page. The visitor's choice narrows it below. */
  color-scheme: light dark;

  /* ── Website-owned colour roles ────────────────────────────────────────────
     The app carries its "ink on the brand fill" role inside the Ionic bridge,
     which this page never activates — so the site owns the role itself. Both
     modes are contrast-checked in test/website.conformance.test.mjs. */
  --web-on-brand: #ffffff;              /* on --brand-interactive (sage-600) */
  --web-brand-hover: var(--sage-700);
}

/* The privacy statement is a document, not a landing page: the marketing
   headline scale reads as shouting over legal prose. */
.page-privacy {
  --web-text-h2: 24px;
}

/* The patient tutorial opts into a larger scale: it is read by people who are
   not comfortable with phones, and by older eyes (story 3). */
.page-patients {
  --web-text-body: 19px;
  --web-text-lead: clamp(20px, 2.2vw, 23px);
  --web-text-h3: 23px;
  --web-text-small: 17px;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--web-text-body);
  line-height: 1.65;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  color: var(--ink);
  line-height: 1.15;
  letter-spacing: -0.022em;
  margin: 0 0 var(--space-4);
  text-wrap: balance;
}
h1 { font-size: var(--web-text-hero); font-weight: 800; }
h2 { font-size: var(--web-text-h2); font-weight: 800; }
h3 { font-size: var(--web-text-h3); font-weight: 700; letter-spacing: -0.012em; }

p { margin: 0 0 var(--space-4); max-width: var(--web-measure); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--brand-interactive);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover { text-decoration-thickness: 2px; }

img { max-width: 100%; height: auto; }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--space-2);
  z-index: 10;
  padding: var(--space-2) var(--space-4);
  background: var(--surface-card);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-2);
}
.skip-link:focus { left: var(--space-4); }

/* ── Layout ──────────────────────────────────────────────────────────────── */
.wrap {
  width: 100%;
  max-width: var(--web-container);
  margin-inline: auto;
  padding-inline: var(--space-5);
}
.wrap-narrow { max-width: var(--web-container-narrow); }

.section { padding-block: var(--web-section-gap); }
/* Only two PLAIN sections in a row share a gap: the first one's bottom padding is
   open page, so the second needs none of its own. A tinted band's padding sits inside
   its coloured area, so it can neither borrow from nor lend to its neighbours — both
   the band and whatever follows it keep their own. */
.section:not(.section-tinted) + .section:not(.section-tinted) { padding-top: 0; }
.section-tinted {
  background: var(--surface-raised);
  border-block: 1px solid var(--line);
}

.eyebrow {
  font-size: var(--web-text-eyebrow);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 var(--space-3);
}

.lead {
  font-size: var(--web-text-lead);
  line-height: 1.5;
  color: var(--ink);
}

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

/* The brand dot after a section title — the motif's second and only other home
   (M3: the wordmark and the page title, nowhere else). */
.title-dot::after {
  content: "";
  display: inline-block;
  width: 0.3em;
  height: 0.3em;
  margin-left: 0.16em;
  border-radius: var(--radius-pill);
  background: var(--brand-interactive);
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  transition: transform var(--motion-fast) var(--ease-soft),
              background-color var(--motion-fast) var(--ease-soft);
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--brand-interactive);
  color: var(--web-on-brand);
}
.btn-primary:hover { background: var(--web-brand-hover); }
.btn-secondary {
  background: var(--surface-card);
  color: var(--ink);
  border-color: var(--line-strong);
}
.btn-secondary:hover { background: var(--surface-raised); }
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* ── Header ──────────────────────────────────────────────────────────────── */
.site-header {
  background: var(--surface-page);
  border-bottom: 1px solid var(--line);
}
.site-header > .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-6);
  padding-block: var(--space-4);
}
.brand {
  font-size: var(--web-text-h3);
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}
/* The brand dot — the motif, in the wordmark and nowhere else on the page. */
.dot { color: var(--brand-interactive); }

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-5);
}
.site-nav a {
  color: var(--ink);
  font-size: var(--web-text-small);
  font-weight: 600;
  text-decoration: none;
  padding-block: var(--space-2);
}
.site-nav a:hover { color: var(--brand-interactive); }
.site-nav .btn {
  min-height: 42px;
  padding-inline: var(--space-5);
  font-size: var(--web-text-small);
  color: var(--web-on-brand);
}
.site-nav .btn:hover { color: var(--web-on-brand); }

/* ── Colour-scheme switch ────────────────────────────────────────────────────
   Three radios, no script. The inputs stay in the accessibility tree and keep
   their native arrow-key behaviour; only their pixels are hidden, so the control
   is fully keyboard-operable. Each label carries its name in text for screen
   readers, visually hidden behind the icon. */
.theme-switch {
  display: flex;
  gap: 2px;
  margin: 0;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
}
.theme-switch legend,
.theme-switch label span,
.theme-switch input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.theme-switch label {
  display: grid;
  place-items: center;
  width: 32px;
  height: 28px;
  border-radius: var(--radius-pill);
  color: var(--ink-muted);
  cursor: pointer;
  transition: background-color var(--motion-fast) var(--ease-soft),
              color var(--motion-fast) var(--ease-soft);
}
.theme-switch label:hover { color: var(--ink); background: var(--surface-raised); }
.theme-switch svg { width: 16px; height: 16px; }
.theme-switch input:checked + label {
  background: var(--brand-interactive);
  color: var(--web-on-brand);
}
.theme-switch input:focus-visible + label {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
  margin-top: var(--web-section-gap);
  background: var(--surface-raised);
  border-top: 1px solid var(--line);
  padding-block: var(--space-7);
  font-size: var(--web-text-small);
}
.site-footer p { max-width: none; }
.footer-brand { font-weight: 700; color: var(--ink); }
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  list-style: none;
  margin: var(--space-4) 0;
  padding: 0;
}
.footer-links a { color: var(--ink); }
.footer-meta { color: var(--ink-muted); margin: 0; }

/* Placeholder awaiting a user decision (legal entity — go-live story). Visible
   on purpose: the site cannot go public while this still renders. */
/* Ink on the amber surface, not amber on amber: the amber pair sits at 4.49:1,
   just under AA (the conformance test pins this). Colour is carried by the
   surface and the dashed border, never by the text alone (M3). */
.pending {
  background: var(--status-warning-surface);
  border: 1px dashed var(--status-warning-base);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-2);
  color: var(--ink-900);
  font-weight: 700;
}

/* ── Cards + prose blocks ────────────────────────────────────────────────── */
.card {
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--elevation-1);
}
.card h3 { margin-bottom: var(--space-2); }
.card p { font-size: var(--web-text-small); color: var(--ink-muted); }

.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-top: var(--space-6);
}

.stack > * + * { margin-top: var(--space-6); }

/* ── Device frames — screenshots of the real demo, never a mock ──────────── */
.device-phone,
.device-browser {
  background: var(--surface-card);
  border: 1px solid var(--line-strong);
  box-shadow: var(--elevation-3);
  overflow: hidden;
}
.device-phone {
  border-radius: var(--radius-xl);
  padding: var(--space-2);
  max-width: 300px;
}
.device-phone img { border-radius: var(--radius-lg); display: block; }
.device-browser { border-radius: var(--radius-lg); }
.device-browser img { display: block; }
/* The window bar: three dots, drawn in CSS so no image is needed. */
.device-browser::before {
  content: "";
  display: block;
  height: 26px;
  background:
    radial-gradient(circle 4px at 16px 13px, var(--line-strong) 98%, transparent 100%),
    radial-gradient(circle 4px at 34px 13px, var(--line-strong) 98%, transparent 100%),
    radial-gradient(circle 4px at 52px 13px, var(--line-strong) 98%, transparent 100%),
    var(--surface-raised);
  border-bottom: 1px solid var(--line);
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  display: grid;
  gap: var(--space-7);
  align-items: center;
  grid-template-columns: 1fr;
}
.hero-art {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: var(--space-4);
}
.hero-art .device-browser { flex: 1 1 60%; min-width: 0; }
.hero-art .device-phone { flex: 0 0 172px; }
.hero-aside { font-size: var(--web-text-small); margin-top: var(--space-5); }

/* On a phone, a 1280px-wide portal screenshot shrinks to something nobody can read.
   Show the phone screen alone there — the portal appears full-size further down. */
@media (max-width: 719px) {
  .hero-art .device-browser { display: none; }
  .hero-art .device-phone { flex: 0 1 240px; }
  .step-art .device-browser { margin-inline: calc(var(--space-5) * -1); border-radius: 0; }
}

@media (min-width: 900px) {
  .hero { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
}

/* ── Numbered steps ──────────────────────────────────────────────────────── */
.steps { counter-reset: step; }
.step {
  display: grid;
  gap: var(--space-5);
  align-items: center;
  padding-block: var(--space-6);
  grid-template-columns: 1fr;
}
.step + .step { border-top: 1px solid var(--line); }

/* Every step's art gets roughly the same height, so the three steps share one
   rhythm instead of rows of 524, 341 and 306px with the text floating in the middle
   of an empty column.

   The two kinds of screenshot reach that height differently. A portal capture is
   1280x633 and is cropped to the frame — anchored LEFT, so what goes is the
   right-hand source panel and never the chart, the patient name or the trend figure
   the copy points at. */
.step-art .device-browser { max-width: none; }
.step-art .device-browser img {
  height: var(--step-art-height, 300px);
  width: 100%;
  object-fit: cover;
  object-position: top left;
}

/* A phone screen is never cropped: cutting a phone in half reads as a broken image
   rather than a design choice (user decision 2026-08-04). Instead the step shows the
   two screens the sentence is actually about, side by side, scaled to about the same
   height as a portal frame. Fixed height with automatic width keeps both whole. */
.phone-pair {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
}
.phone-pair .device-phone {
  max-width: none;
  padding: var(--space-1);
}
.phone-pair img {
  height: var(--phone-pair-height, 320px);
  width: auto;
}

@media (max-width: 599px) {
  .phone-pair { --phone-pair-height: 240px; }
}

.step-body h3 { display: flex; align-items: baseline; gap: var(--space-3); }
.step-body h3::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--font-display);
  font-size: 1.6em;
  color: var(--brand-interactive);
  line-height: 1;
}
.step .device-phone { margin-inline: auto; }

@media (min-width: 820px) {
  .step { grid-template-columns: 1.15fr 1fr; gap: var(--space-8); align-items: center; }
  .step:nth-child(even) .step-art { order: -1; }
}

/* ── The problem section ─────────────────────────────────────────────────────
   Three observations, then the turn. Each observation gets its own column with a
   rule above it, so the section reads as three distinct facts rather than one
   paragraph block — and the closing line answers all three at once. */
.problem-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
  margin-top: var(--space-6);
}
.problem-grid p {
  margin: 0;
  max-width: none;
  padding-top: var(--space-5);
  border-top: 2px solid var(--line-strong);
  font-size: var(--web-text-body);
  line-height: 1.5;
  color: var(--ink);
}

/* The one serif moment on this page (M3 reserves Fraunces for pain numerals and a
   single hero moment): the sentence the whole section builds towards. */
.problem-turn {
  margin-top: var(--space-8);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(23px, 3.2vw, 32px);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--brand-interactive);
  max-width: 22ch;
}

@media (min-width: 760px) {
  .problem-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
}

/* ── Closing bands ───────────────────────────────────────────────────────── */
.band {
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: var(--space-7) var(--space-6);
  text-align: center;
}
.band p { margin-inline: auto; }
.band .btn-row { justify-content: center; }

/* ── The offer ───────────────────────────────────────────────────────────────
   Two months free. Stated once in the hero and once at the request form; never
   as a banner or a countdown. */
.offer-badge {
  display: inline-block;
  background: var(--accent-surface);
  color: var(--terra-700);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-3);
  margin-right: var(--space-2);
  font-size: var(--web-text-small);
  font-weight: 700;
}
.offer { margin-top: var(--space-6); }

/* ── Demo-request form ───────────────────────────────────────────────────────
   Posts to a Google Form through a hidden frame, so the visitor never leaves the
   page (see website/assets/form.js and the privacy page). */
.form-wrap { margin-top: var(--space-7); max-width: 32rem; }
.form-wrap iframe {
  display: none;
}
.field { margin-bottom: var(--space-5); }
.field label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--web-text-small);
  font-weight: 700;
}
.field input {
  width: 100%;
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  font: inherit;
  color: var(--ink);
  background: var(--surface-card);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
}
.field input::placeholder { color: var(--ink-muted); }
.field input:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
  border-color: var(--brand-interactive);
}
.form-wrap button { width: 100%; }
.form-note {
  margin-top: var(--space-4);
  font-size: var(--web-text-small);
}

/* Announced to screen readers when it appears (role="status" in the markup). */
.form-success {
  display: none;
  background: var(--status-success-surface);
  border: 1px solid var(--status-success-border);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-6);
  color: var(--ink-900);
  font-weight: 700;
}
.form-success.is-visible { display: block; }

/* ── Patient tutorial ────────────────────────────────────────────────────────
   Read by people who are not comfortable with phones, and by older eyes: bigger
   type, one action per line, generous targets, nothing competing for attention. */
.need {
  margin-top: var(--space-7);
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.need h2 { font-size: var(--web-text-h3); margin-bottom: var(--space-3); }

.tstep + .tstep { margin-top: var(--space-8); }
.tstep h2 {
  font-size: clamp(23px, 3vw, 30px);
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}
.tnum {
  flex: 0 0 auto;
  font-family: var(--font-display);
  color: var(--brand-interactive);
}
.tstep h3 {
  font-size: var(--web-text-body);
  font-weight: 700;
  margin: var(--space-6) 0 var(--space-2);
}
.tstep ol {
  margin: 0 0 var(--space-4);
  padding-left: 1.4em;
  max-width: var(--web-measure);
}
.tstep li { margin-bottom: var(--space-3); }
.tstep li::marker { font-weight: 700; color: var(--brand-interactive); }

/* The line that says "it is fine if this goes wrong" — always visible, never
   an aside in small print. */
.reassure {
  background: var(--surface-raised);
  border-left: 3px solid var(--brand-interactive);
  border-radius: 0;
  padding: var(--space-4) var(--space-5);
  margin-top: var(--space-5);
}

.tshots {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

.faq h3 {
  margin-top: var(--space-6);
  margin-bottom: var(--space-2);
}
.faq .closing {
  margin-top: var(--space-7);
  font-size: var(--web-text-lead);
  font-weight: 700;
  color: var(--brand-interactive);
}

.handout-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-6);
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.handout-card > div { flex: 1 1 260px; }
.handout-card h2 { font-size: var(--web-text-h3); }
.handout-card img {
  border-radius: var(--radius-md);
  background: var(--porcelain-card);
}
.handout-url {
  font-weight: 700;
  font-size: var(--web-text-lead);
  color: var(--brand-interactive);
}

/* ── Dark mode, and the visitor's choice ─────────────────────────────────────
   The app switches palettes on an Ionic class the website never carries, so the
   same dark roles are re-mapped here from the SAME primitives (no new values, no
   forked hex — see semantic.css's dark block).

   Three radios in the header decide when that happens, with no JavaScript at all:
   "Systeem" is checked in the markup, so the site follows the operating system
   until the visitor says otherwise. Light needs no rule — it is the base palette,
   so choosing it simply stops both dark rules from matching.

   `light-dark()` would express this in one declaration per role instead of two
   blocks, and was tried first: it turns out that inside a custom property it does
   NOT re-resolve when :has() changes color-scheme (verified in-browser — a direct
   light-dark() use flipped correctly while the tokens stayed dark). Hence the two
   blocks below. They must stay identical; the conformance suite compares them.

   `data-theme` on <html> is the second way in. theme.js sets it from the ?theme
   parameter while the head is still parsing, so a visitor who carried "donker"
   over from the previous page never sees a flash of light. The radios remain the
   no-JavaScript path and keep working on their own; the media rule below excludes
   any page that already carries the attribute, so the two never fight. */
:root[data-theme="licht"],
:root:has(#theme-light:checked) { color-scheme: light; }
:root[data-theme="donker"],
:root:has(#theme-dark:checked) { color-scheme: dark; }

/* The system says dark and the visitor has not overridden it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]):has(#theme-system:checked) {
    --surface-page: var(--dark-page);
    --surface-card: var(--dark-card);
    --surface-raised: var(--dark-raised);
    --line: var(--dark-line);
    --ink: var(--dark-ink);
    --ink-muted: var(--dark-ink-muted);
    --brand-interactive: var(--sage-400);
    --focus-ring: var(--sage-400);
    --elevation-1: var(--elevation-1-dark);
    --elevation-2: var(--elevation-2-dark);
    --elevation-3: var(--elevation-3-dark);
    /* The dark brand fill is a LIGHT sage, so its ink flips to warm dark ink —
       the same inversion the app's dark bridge makes. */
    --web-on-brand: var(--ink-900);
    --web-brand-hover: var(--sage-300);
  }
}

/* The visitor asked for dark, whatever the system says. */
:root[data-theme="donker"],
:root:has(#theme-dark:checked) {
  --surface-page: var(--dark-page);
  --surface-card: var(--dark-card);
  --surface-raised: var(--dark-raised);
  --line: var(--dark-line);
  --ink: var(--dark-ink);
  --ink-muted: var(--dark-ink-muted);
  --brand-interactive: var(--sage-400);
  --focus-ring: var(--sage-400);
  --elevation-1: var(--elevation-1-dark);
  --elevation-2: var(--elevation-2-dark);
  --elevation-3: var(--elevation-3-dark);
  /* The dark brand fill is a LIGHT sage, so its ink flips to warm dark ink —
     the same inversion the app's dark bridge makes. */
  --web-on-brand: var(--ink-900);
  --web-brand-hover: var(--sage-300);
}

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

/* ── Print ───────────────────────────────────────────────────────────────────
   A practice prints /patienten and hands it to a patient, so the printed page
   must be the tutorial and nothing else: black on white, no navigation, steps
   unbroken across page breaks, and the QR plus the short URL at the end so the
   paper leads back to the live page. */
@media print {
  :root {
    --surface-page: #ffffff;
    --surface-card: #ffffff;
    --surface-raised: #ffffff;
    --ink: #000000;
    --ink-muted: #333333;
    --brand-interactive: #000000;
    --line: #999999;
    --line-strong: #666666;
    --elevation-1: none;
    --elevation-2: none;
    --elevation-3: none;
    --web-section-gap: 16px;
  }
  @page { margin: 14mm; }

  body { font-size: 11.5pt; line-height: 1.45; }
  .site-header,
  .site-footer,
  .skip-link,
  .btn-row,
  .tshots { display: none; }

  .section { padding-block: 0; }
  .section + .section { margin-top: 10mm; }
  .section-tinted { border: 0; }
  .wrap, .wrap-narrow { max-width: none; padding-inline: 0; }

  h1 { font-size: 20pt; }
  h2 { font-size: 14pt; }
  h3 { font-size: 11.5pt; }
  .title-dot::after { display: none; }

  /* Never split a step across two sheets — half an instruction is worse than none. */
  .tstep, .need, .handout-card { break-inside: avoid; page-break-inside: avoid; }
  .tstep { border-bottom: 1px solid var(--line); padding-bottom: 5mm; }
  .reassure { border-left: 2px solid var(--ink); }

  .card, .need, .handout-card { box-shadow: none; }
  .handout-card { border: 1px solid var(--line); }
  a { text-decoration: none; color: inherit; }
}
