/* SupportPilot website - tokens and components from /DESIGN.md.
   One stylesheet for all pages; no build step, no framework.
   Discipline borrowed from Linear: surface ladder, hairlines, negative
   display tracking, mono for evidence, ONE accent spent on CTAs only.

   Palette (2026 redesign, direction from the AIDesigner MCP, accent
   revised twice after review). The foundation is a cool slate: the product
   sells verifiability, and slate reads as instrument panel rather than
   consumer urgency. That much has not changed.

   What changed is the accent. The blue #2156b1 was chosen as the amber
   mark's complement, which is correct colour theory and still left the
   brand silent on its own page - the logo spoke amber, the interface spoke
   blue, and nothing tied them together. So the ACTION colour is now the
   logo amber itself (#ffb400, the dominant fill of the paper plane), and
   the blue stays on for READING: links, focus, inline accent words.

   That split is not decoration, it is forced by contrast. Amber carrying
   dark ink is a 9.9:1 button; amber as words on this canvas is 1.7:1 and
   unusable. Blue is the opposite. Rather than compromise both into a
   mid-tone that serves neither, each colour does the job it is good at:
   amber means "do this", blue means "read this". The full exploration and
   the numbers behind it are in docs/brandkit/. */

:root {
  color-scheme: light;
  --canvas: #f6f8fb;
  --surface-1: #ffffff;
  --surface-2: #ffffff;
  --inset: #edf2f9;
  --hairline: #dde3ec;
  --hairline-strong: #b3bfd1;
  --ink: #0e192a;
  --ink-muted: #515f73;
  --ink-faint: #586373;
  /* The action colour is the logo amber. It is a FILL, never words: #ffb400
     as text is 1.7:1 on this canvas, while the same amber carrying dark ink
     is 9.9:1 as a button. Reading colours stay cool (see --accent-text), so
     the page gets a warm call to action without turning yellow. */
  --accent: #ffb400;
  --accent-hover: #e69900;
  --on-accent: #0d1a26;
  /* A light fill needs a drawn edge. WCAG 1.4.11 asks for 3:1 between a
     control and its background, and amber on this canvas is only 1.67:1 - the
     button would dissolve into the page for anyone with low vision, even
     though its LABEL is a comfortable 9.9:1. Darkening the amber until the
     fill itself cleared 3:1 would land on a muddy #ba8300 that is no longer
     the brand. So the fill stays true and the edge does the work: #b77000 is
     3.7:1 on canvas and 3.9:1 on white. */
  --accent-edge: #b77000;
  --success: #1d7a49;
  --warn: #a5701c;
  /* Always-dark panel: the "system speaking" surface (terminal proof,
     closing CTA). Fixed in both themes so the contrast reads the same. */
  --panel-dark: #0e192a;
  --panel-dark-2: #152439;
  --panel-dark-ink: #f1f6fd;
  --panel-dark-muted: #94a2b6;
  --panel-dark-hairline: #253650;
  /* --accent is a SURFACE colour (buttons, fills, borders). --accent-text is
     the same signal used as INK (links, ticks, mono labels). They differ when
     the accent is light: amber on white is 1.6:1 as text but perfectly legible
     as a filled button. Never paint text with --accent directly. */
  /* Links, focus and inline accent words keep the quiet blue. Two signals,
     cleanly split: amber means "do this", blue means "read this". */
  --accent-text: #2156b1;
  /* --mark is the identity colour: the tone the logo already speaks. It marks
     brand moments and evidence (hero badge, gate ring, draft frame, promise
     rule), never actions. It equals the amber accent here because identity and
     action now share one warm tone; --mark-text is its ink form, dark enough
     to be read as words. */
  --mark: var(--accent);
  --mark-text: #8a5a00;
  /* Ambient layer: the three drifting blobs and the hero/section washes.
     Tokenised so a palette change moves the atmosphere with it instead of
     leaving a stale tint behind a new accent.

     The mix is deliberate: two blue blobs carry the surface family and one
     warm blob carries the amber, the same ratio the page itself uses. An
     ambient layer derived purely from the accent turned the background into
     brown fog, which is a different thing from a navy ground with a warm
     glow in it. Hues are set in OKLCH so the layer stays in one family. */
  --blob-1: #e7dccd;
  --blob-2: #d4e5ff;
  --blob-3: #dde5f2;
  --blob-opacity: .55;
  --wash-tint: color-mix(in srgb, var(--inset) 70%, transparent);
  --hero-wash-bottom: color-mix(in srgb, var(--inset) 55%, transparent);
  --r-sm: 4px; --r-md: 6px; --r-lg: 10px; --r-xl: 14px;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.logo-dark { display: none !important; }
.logo-light { display: inline-block !important; }
/* ---- dark scheme ----
   Two entry points into the SAME values: the media query follows the OS
   (guarded so an explicit light choice wins), the [data-theme="dark"]
   attribute is the toggle's explicit choice (set in <head> by theme.js).
   The payloads below are duplicated by necessity (no build step) - when
   editing dark values, change BOTH copies. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --canvas: #091321; --surface-1: #111d2f; --surface-2: #152439;
    --inset: #0d1726; --hairline: #1f2f46; --hairline-strong: #364965;
    --ink: #edf3fc; --ink-muted: #9ca9be; --ink-faint: #8c9cb3;
    --accent: #ffc23a; --accent-hover: #ffd166;
    --on-accent: #08141d;
    /* On a dark ground the amber is 11.6:1 against the canvas on its own, so
       the edge is only there to keep the shape identical between schemes. */
    --accent-edge: var(--accent);
    --success: #46b27a; --warn: #d3a44a;
    --accent-text: #4e92e9;
    --mark: var(--accent);
    --mark-text: var(--accent);
    --blob-1: #594933;
    --blob-2: #213d68;
    --blob-3: #1f2a3a;
    --blob-opacity: .3;
    --wash-tint: color-mix(in srgb, var(--accent) 9%, transparent);
    --hero-wash-bottom: transparent;
  }
  :root:not([data-theme="light"]) .logo-light { display: none !important; }
  :root:not([data-theme="light"]) .logo-dark { display: inline-block !important; }
  :root:not([data-theme="light"]) img.shot { filter: brightness(.92); }
}
:root[data-theme="dark"] {
    color-scheme: dark;
    --canvas: #091321; --surface-1: #111d2f; --surface-2: #152439;
    --inset: #0d1726; --hairline: #1f2f46; --hairline-strong: #364965;
    --ink: #edf3fc; --ink-muted: #9ca9be; --ink-faint: #8c9cb3;
    --accent: #ffc23a; --accent-hover: #ffd166;
    --on-accent: #08141d;
    /* On a dark ground the amber is 11.6:1 against the canvas on its own, so
       the edge is only there to keep the shape identical between schemes. */
    --accent-edge: var(--accent);
    --success: #46b27a; --warn: #d3a44a;
    --accent-text: #4e92e9;
    --mark: var(--accent);
    --mark-text: var(--accent);
    --blob-1: #594933;
    --blob-2: #213d68;
    --blob-3: #1f2a3a;
    --blob-opacity: .3;
    --wash-tint: color-mix(in srgb, var(--accent) 9%, transparent);
    --hero-wash-bottom: transparent;
}
:root[data-theme="dark"] .logo-light { display: none !important; }
:root[data-theme="dark"] .logo-dark { display: inline-block !important; }
:root[data-theme="dark"] img.shot { filter: brightness(.92); }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--canvas); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ---- type scale (DESIGN.md) ---- */
h1 { font-size: clamp(38px, 6vw, 64px); font-weight: 650; line-height: 1.05;
     letter-spacing: -0.034em; margin: 0 0 20px; }
h2 { font-size: clamp(28px, 4vw, 44px); font-weight: 650; line-height: 1.1;
     letter-spacing: -0.027em; margin: 0 0 12px; }
h3 { font-size: 24px; font-weight: 600; line-height: 1.2;
     letter-spacing: -0.017em; margin: 0 0 8px; }
h4 { font-size: 18px; font-weight: 600; line-height: 1.3;
     letter-spacing: -0.011em; margin: 0 0 6px; }
p  { margin: 0 0 14px; }
.lead { font-size: 18px; line-height: 1.55; color: var(--ink-muted); max-width: 68ch; }
.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }
.mono { font-family: var(--mono); font-size: .92em; }
.small { font-size: 14px; }
a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--accent-text); text-underline-offset: 3px; }
a:hover { color: var(--accent-text); }

.eyebrow {
  font-family: var(--mono); font-size: 12.5px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 1.2px; color: var(--ink-faint);
  margin: 0 0 14px;
}

/* ---- layout ---- */
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
/* Every section shares ONE container width (.wrap, 1120px). .narrow no
   longer shrinks and re-centres the container - that made hero and FAQ
   sections jump between a centred 780px column and the 1120px grid from
   page to page. It now caps the CONTENT at reading width, left-aligned
   on the same edge as every other section. */
.narrow > * { max-width: 780px; }
section { padding: 104px 0 0; }
section:last-of-type { padding-bottom: 104px; }
.section-pad { padding-bottom: 104px; }
@media (max-width: 720px) { section { padding-top: 64px; } }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 900px) { .grid3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 680px) { .grid2, .grid3 { grid-template-columns: 1fr; } }

/* ---- nav ---- */
header.site {
  position: sticky; top: 0; z-index: 50; height: 60px;
  display: flex; align-items: center;
  background: color-mix(in srgb, var(--canvas) 85%, transparent);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hairline);
}
header.site .wrap { display: flex; align-items: center; justify-content: space-between; width: 100%; }
/* Skip link: first Tab stop on every page, invisible until it has focus,
   then a pill at the bar's left edge (above the sticky bar, z 60 > 50). */
header.site .skip {
  position: absolute; left: 12px; top: 12px; z-index: 60;
  padding: 8px 14px; border-radius: var(--r-md);
  background: var(--accent); color: var(--on-accent);
  font-size: 14px; font-weight: 550; text-decoration: none;
  transform: translateY(-200%); opacity: 0;
}
header.site .skip:focus { transform: none; opacity: 1; }
header.site .brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
/* The lockup's box now includes the taller wordmark (ascenders and
   descenders overshoot the Bildmarke), so the box is ~1.36x the mark's
   height. These heights are chosen so the Bildmarke still renders at its
   previous 26px / 30px - only the Wortmarke grew. */
header.site .brand img { height: 35px; }
/* Footer logo slightly larger than the nav (breathing room at page end). */
footer.site img { height: 41px; }
header.site nav { display: flex; align-items: center; gap: 22px; }
header.site nav a {
  font-size: 14px; font-weight: 500; text-decoration: none; color: var(--ink-muted);
}
header.site nav a:hover, header.site nav a.active { color: var(--ink); }
header.site nav a.cta {
  background: var(--accent); color: var(--on-accent); padding: 8px 16px;
  border-radius: var(--r-md); font-weight: 550;
}
header.site nav a.cta:hover { background: var(--accent-hover); }
/* The primary links live in .links so the SAME markup can be a flex row on
   wide screens (display: contents keeps the nav's gap rhythm) and a panel
   under the bar on narrow ones. The menu button is created by nav.js, so
   without JS the narrow header shows brand + language + CTA and the footer
   still lists every page: no dead control, no unreachable page. */
header.site nav .links { display: contents; }
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; flex: none;
  background: transparent; color: var(--ink-muted);
  border: 1px solid var(--hairline-strong); border-radius: 999px;
  cursor: pointer;
  transition: color .15s ease-out, border-color .15s ease-out;
}
.nav-toggle:hover, .nav-toggle[aria-expanded="true"] { color: var(--ink); border-color: var(--ink-muted); }
.nav-toggle svg { width: 15px; height: 15px; display: block; }
/* Menu breakpoint. The same number sits in nav.js (`width > 860px`); range
   syntax on both sides leaves no gap at fractional widths. */
@media (width <= 860px) {
  header.site nav { gap: 14px; }
  /* DOM order is button, panel, CTA (disclosure: Tab walks from the button
     into the open panel); order paints the button last, right of the CTA. */
  .nav-toggle { display: inline-flex; order: 1; }
  header.site nav .links {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; padding: 8px 0 14px;
    background: var(--canvas); border-bottom: 1px solid var(--hairline);
  }
  header.site nav.open .links { display: flex; }
  header.site nav .links a {
    display: block; padding: 12px 22px; font-size: 16px;
    border-left: 2px solid transparent;
  }
  header.site nav .links a.active { border-left-color: var(--accent); }
  header.site nav .links .tools {
    display: flex; align-items: center; gap: 12px;
    margin: 8px 24px 0; padding-top: 12px; border-top: 1px solid var(--hairline);
  }
  header.site nav .links .tools a {
    display: inline-flex; align-items: center; height: 30px; padding: 0 12px;
    font-size: 13px; border: 1px solid var(--hairline-strong); border-radius: 999px;
  }
}

/* ---- buttons ---- */
.btn {
  display: inline-block; font-weight: 550; font-size: 14.5px; line-height: 1.2;
  padding: 11px 20px; border-radius: var(--r-md); text-decoration: none;
  border: 1px solid transparent; cursor: pointer;
  transition: background .15s ease-out, border-color .15s ease-out, color .15s ease-out;
}
.btn.primary {
  background: var(--accent); color: var(--on-accent);
  border-color: var(--accent-edge);
}
.btn.primary:hover { background: var(--accent-hover); color: var(--on-accent); }
.btn.secondary { background: var(--surface-1); color: var(--ink); border-color: var(--hairline-strong); }
.btn.secondary:hover { border-color: var(--ink-muted); color: var(--ink); }
.cta-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 26px; }
.cta-note { font-family: var(--mono); font-size: 12px; color: var(--ink-faint); margin-top: 14px; }

/* ---- panels / cards ---- */
.panel {
  background: var(--surface-1); border: 1px solid var(--hairline);
  border-radius: var(--r-lg); padding: 24px;
}
.panel h4 { margin-top: 2px; }
.inset {
  background: var(--inset); border: 1px solid var(--hairline);
  border-radius: var(--r-md); padding: 16px;
}
.proof {
  background: var(--inset); border: 1px solid var(--hairline);
  border-radius: var(--r-md); padding: 14px 16px;
  font-family: var(--mono); font-size: 13px; line-height: 1.6;
  color: var(--ink-muted); overflow-x: auto; white-space: pre;
}
.proof .ok { color: var(--success); }
.proof .hl { color: var(--ink); }

img.shot {
  width: 100%; display: block;
  border: 1px solid var(--hairline-strong); border-radius: var(--r-md);
}
figure { margin: 0; }
figure.framed {
  background: var(--surface-1); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); padding: 20px;
}
figcaption { font-family: var(--mono); font-size: 12px; color: var(--ink-faint); margin-top: 10px; }

/* ---- badges / steps / tables ---- */
.badge {
  display: inline-block; font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .6px; padding: 3px 10px; border-radius: 999px;
  background: var(--inset); color: var(--ink-muted); border: 1px solid var(--hairline);
}
.badge.good { color: var(--success); }

.step { display: flex; gap: 16px; padding: 18px 0; border-bottom: 1px solid var(--hairline); }
.step:last-child { border-bottom: 0; }
.step .num { font-family: var(--mono); font-size: 14px; color: var(--accent-text); min-width: 28px; padding-top: 2px; }

table { width: 100%; border-collapse: collapse; font-size: 15px; margin: 18px 0 0; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--hairline); vertical-align: top; }
th { font-family: var(--mono); font-size: 11.5px; text-transform: uppercase; letter-spacing: 1px; color: var(--ink-faint); font-weight: 600; }
td.num, th.num { font-family: var(--mono); }

/* ---- pricing ---- */
.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: start; }
@media (max-width: 900px) { .tiers { grid-template-columns: 1fr; } }
.tier {
  background: var(--surface-1); border: 1px solid var(--hairline);
  border-radius: var(--r-lg); padding: 28px;
}
.tier.featured { background: var(--surface-2); border-color: var(--accent); }
.tier .price { font-family: var(--mono); font-size: 34px; font-weight: 600; margin: 10px 0 2px; }
.tier .per { font-family: var(--mono); font-size: 12.5px; color: var(--ink-faint); }
.tier ul { list-style: none; padding: 0; margin: 18px 0 0; }
.tier li { padding: 7px 0; border-bottom: 1px solid var(--hairline); font-size: 14.5px; }
.tier li:last-child { border-bottom: 0; }
.tier .btn { margin-top: 18px; width: 100%; text-align: center; }

/* ---- FAQ ---- */
details {
  border-bottom: 1px solid var(--hairline); padding: 4px 0;
}
details summary {
  cursor: pointer; font-weight: 600; font-size: 16px; padding: 14px 0;
  list-style: none; display: flex; justify-content: space-between; align-items: center;
}
details summary::-webkit-details-marker { display: none; }
details summary::after { content: "+"; font-family: var(--mono); color: var(--ink-faint); }
details[open] summary::after { content: "–"; }
details .a { padding: 0 0 16px; color: var(--ink-muted); max-width: 68ch; }

/* ---- footer ---- */
footer.site {
  margin-top: 104px; border-top: 1px solid var(--hairline);
  padding: 56px 0 64px; color: var(--ink-muted); font-size: 14px;
}
footer.site .cols { display: flex; justify-content: space-between; gap: 32px; flex-wrap: wrap; }
footer.site a { color: var(--ink-muted); text-decoration: none; }
footer.site a:hover { color: var(--ink); }
footer.site .col { display: flex; flex-direction: column; gap: 8px; }

/* ---- scroll reveal ----
   Progressive enhancement: hidden-until-revealed applies ONLY under html.js
   (set by reveal.js as its first statement). No JS, blocked JS, a crawler,
   reader mode, a screenshot before the observer fires: full content. */
html.js .reveal { opacity: 0; transform: translateY(8px);
  transition: opacity .45s cubic-bezier(.16,1,.3,1), transform .45s cubic-bezier(.16,1,.3,1); }
html.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ---- page ambient: ONE background layer for the whole page ----
   A single fixed layer behind all content (mitbeziehung technique, taken
   further): the blobs live once per page and travel subtly WITH the
   scroll, so the atmosphere flows across section boundaries instead of
   restarting per section. Apple-motion discipline: the scroll offset is
   direct manipulation (no easing lag), the idle drift is a slow
   ease-in-out breathe, reduced-motion shows a static glow.

   Rhythm: sections marked .wash carry an opaque standing gradient that
   COVERS the fixed layer - resting points that counteract the parallax
   (the reader gets calm ground between moving passages). */
.page-ambient {
  position: fixed; inset: 0; overflow: hidden;
  pointer-events: none; z-index: 0;
}
body > main, body > header, body > footer { position: relative; z-index: 1; }
.blob {
  position: absolute; border-radius: 50%;
  filter: blur(70px); opacity: var(--blob-opacity);
  will-change: transform;
}
.blob .core {
  position: absolute; inset: 0; border-radius: 50%;
  animation: blob-breathe var(--dur, 30s) ease-in-out var(--delay, 0s) infinite alternate;
}
.blob.b1, .blob.b1 .core { background: var(--blob-1); }
.blob.b2, .blob.b2 .core { background: var(--blob-2); }
.blob.b3, .blob.b3 .core { background: var(--blob-3); }
.blob.b1 { width: 460px; height: 460px; }
.blob.b2 { width: 400px; height: 400px; }
.blob.b3 { width: 520px; height: 520px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .blob { filter: blur(80px); }
}
:root[data-theme="dark"] .blob { filter: blur(80px); }
@keyframes blob-breathe {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(40px, -30px) scale(1.08); }
  100% { transform: translate(-30px, 25px) scale(0.95); }
}
@media (max-width: 767px) {
  .blob .core { animation: none; }
  .blob { filter: blur(44px); }
}
@media (prefers-reduced-motion: reduce) {
  .blob .core { animation: none; }
}

/* Standing gradient sections: opaque ground that hides the fixed layer -
   resting points between moving passages. Top/bottom edges fade from
   transparent so the moving glow hands over softly instead of being cut
   by a hard horizontal line (caught in visual review). */
section.wash {
  position: relative;
  background:
    linear-gradient(to bottom,
      transparent 0%,
      var(--canvas) 120px,
      var(--canvas) calc(100% - 120px),
      transparent 100%),
    radial-gradient(ellipse 80% 60% at 50% 10%,
      var(--wash-tint) 0%, transparent 60%);
}

section.hero, .cta-panel-wrap { position: relative; }

/* ---- forms (trial request) ---- */
form label { display: block; font-size: 13px; color: var(--ink-muted); margin: 0 0 5px; }
form input, form select, form textarea {
  width: 100%; box-sizing: border-box;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--hairline-strong); border-radius: var(--r-md);
  padding: 10px 12px; font-size: 15px; font-family: inherit;
}
form input:focus, form select:focus, form textarea:focus {
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent);
}
form textarea { resize: vertical; }
form .btn { border: none; cursor: pointer; font-size: 14.5px; }

/* ---- hero gradient wash (mitbeziehung splash technique, brand tones) ----
   A radial ellipse + vertical linear gradient UNDER the blobs: the hero
   gets depth without a single image byte. Light mode: warm paper glow;
   dark mode: the deep ink wash from the reference. */
section.hero .ambient::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 70% 55% at 50% 40%,
      color-mix(in srgb, var(--accent) 7%, transparent) 0%, transparent 70%),
    linear-gradient(to bottom,
      transparent 0%,
      var(--hero-wash-bottom) 100%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) section.hero .ambient::before {
    background:
      radial-gradient(ellipse 70% 55% at 50% 40%,
        color-mix(in srgb, var(--accent) 9%, transparent) 0%, transparent 70%),
      linear-gradient(to bottom,
        var(--canvas) 0%,
        color-mix(in srgb, var(--canvas) 82%, var(--surface-1)) 50%,
        var(--surface-1) 100%);
  }
}
:root[data-theme="dark"] section.hero .ambient::before {
  background:
    radial-gradient(ellipse 70% 55% at 50% 40%,
      color-mix(in srgb, var(--accent) 9%, transparent) 0%, transparent 70%),
    linear-gradient(to bottom,
      var(--canvas) 0%,
      color-mix(in srgb, var(--canvas) 82%, var(--surface-1)) 50%,
      var(--surface-1) 100%);
}

/* ---- horizontal group (submit button + reassurance line) ----
   Used by both forms since they were written; it was never defined, so the
   button and its note stacked instead of sitting side by side. */
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

/* ---- alerts (form errors, status messages) ----
   Was missing entirely: the trial form rendered its error into an unstyled
   div, so a failed submit looked like stray text. */
.alert-box {
  border: 1px solid var(--warn); border-left-width: 3px;
  background: color-mix(in srgb, var(--warn) 7%, var(--surface-1));
  border-radius: var(--r-md); padding: 12px 14px; font-size: 14.5px;
}
.alert-box.good { border-color: var(--success);
  background: color-mix(in srgb, var(--success) 7%, var(--surface-1)); }
.ok-text { color: var(--success); }
.err-text { color: var(--warn); }
.hairline { height: 1px; background: var(--hairline); }

/* ---- signup: form first, reassurance beside it ----
   DesignMD "split signup with benefits": the form is the primary task and
   comes first in the DOM, so on a phone nobody scrolls past marketing to
   reach the fields. */
.signup-split {
  display: grid; grid-template-columns: 1.35fr 1fr; gap: 28px; align-items: start;
}
@media (max-width: 900px) { .signup-split { grid-template-columns: 1fr; } }
.signup-aside {
  background: var(--inset); border: 1px solid var(--hairline);
  border-radius: var(--r-lg); padding: 24px;
}
.signup-steps {
  list-style: none; display: flex; gap: 18px; flex-wrap: wrap;
  margin: 0 0 22px; padding: 0 0 16px; border-bottom: 1px solid var(--hairline);
  font-size: 13.5px; color: var(--ink-faint);
}
.signup-steps li { display: flex; align-items: center; gap: 7px; }
.signup-steps li span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 999px; font-family: var(--mono);
  font-size: 11px; border: 1px solid var(--hairline-strong);
}
.signup-steps li.on { color: var(--ink); }
.signup-steps li.on span {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
.slug-row { display: flex; align-items: stretch; }
.slug-row input {
  border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: 0;
}
.slug-suffix {
  display: flex; align-items: center; padding: 0 12px;
  background: var(--inset); color: var(--ink-muted);
  border: 1px solid var(--hairline-strong); border-left: 0;
  border-radius: 0 var(--r-md) var(--r-md) 0; font-size: 13.5px; white-space: nowrap;
}
@media (max-width: 520px) {
  .slug-row { flex-direction: column; }
  .slug-row input { border-radius: var(--r-md); border-right: 1px solid var(--hairline-strong); }
  .slug-suffix { border-left: 1px solid var(--hairline-strong); border-radius: var(--r-md); margin-top: 6px; }
}
.consent { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.consent input { width: auto; margin-top: 3px; accent-color: var(--accent); }
.check-list { list-style: none; margin: 14px 0 0; padding: 0; font-size: 14.5px; }
.check-list li {
  position: relative; padding-left: 26px; margin-bottom: 12px;
  color: var(--ink-muted); line-height: 1.5;
}
.check-list li b { color: var(--ink); font-weight: 600; }
.check-list li::before {
  content: "✓"; position: absolute; left: 0; top: 0;
  color: var(--accent-text); font-family: var(--mono); font-size: 13px;
}

/* ---- provisioning status ---- */
.status-steps { list-style: none; margin: 26px 0 0; padding: 0; font-size: 15px; }
.status-steps li {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; color: var(--ink-faint);
  border-bottom: 1px solid var(--hairline);
}
.status-steps li:last-child { border-bottom: 0; }
.status-steps li .tick { font-family: var(--mono); width: 16px; }
.status-steps li.done { color: var(--ink-muted); }
.status-steps li.done .tick { color: var(--success); }
.status-steps li.current { color: var(--ink); }
.status-steps li.current .tick { color: var(--accent-text); animation: pulse-tick 1.6s ease-in-out infinite; }
@keyframes pulse-tick { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
  .status-steps li.current .tick { animation: none; }
}

/* ---- legal pages (imprint, privacy, terms) ----
   These used .todo and .dim, which never existed in this stylesheet: the
   pages rendered as unstyled black text on the canvas. They are read by
   people deciding whether to trust us with a mailbox password, so they get
   the same typographic care as the rest. */
.legal h2 { font-size: 20px; margin: 34px 0 8px; letter-spacing: -0.012em; }
.legal h2.legal-part {
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: 1.4px; text-transform: uppercase; color: var(--ink-faint);
  margin: 48px 0 6px; padding-top: 18px; border-top: 1px solid var(--hairline);
}
.legal p.dim { color: var(--ink-muted); font-size: 15px; max-width: 74ch; }
.legal .lead { margin-bottom: 28px; }
.todo {
  border: 1px dashed var(--warn); border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warn) 6%, var(--surface-1));
  color: var(--ink-muted); font-family: var(--mono); font-size: 12.5px;
  line-height: 1.7; padding: 14px 16px; margin: 24px 0;
}

/* ============================================================
   2026 redesign additions
   ------------------------------------------------------------
   Direction generated with the AIDesigner MCP and then ported by
   hand into these tokens, so the site keeps its no-build,
   one-stylesheet constraint (no Tailwind CDN, no icon font).
   ============================================================ */

/* ---- dark panel: the surface where the SYSTEM speaks ----
   Used for the terminal proof block and the closing CTA. Fixed in both
   themes: the point of these blocks is that they look like machine
   output, and machine output should not change costume with the OS. */
.panel-dark {
  background: var(--panel-dark);
  color: var(--panel-dark-ink);
  border: 1px solid var(--panel-dark-hairline);
  border-radius: var(--r-xl);
}
.panel-dark h2, .panel-dark h3, .panel-dark h4 { color: var(--panel-dark-ink); }
.panel-dark .muted, .panel-dark .small.muted { color: var(--panel-dark-muted); }
.panel-dark a { color: var(--panel-dark-ink); text-decoration-color: var(--accent-text); }
.panel-dark .btn.secondary {
  background: transparent; color: var(--panel-dark-ink);
  border-color: var(--panel-dark-hairline);
}
.panel-dark .btn.secondary:hover { border-color: var(--panel-dark-muted); color: var(--panel-dark-ink); }

/* Closing CTA: one accent glow from the top, nothing else. */
.cta-final {
  position: relative; overflow: hidden;
  padding: 56px 40px; text-align: center;
}
.cta-final::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 70% at 50% 0%,
    color-mix(in srgb, var(--accent) 26%, transparent) 0%, transparent 70%);
}
.cta-final > * { position: relative; }
@media (max-width: 680px) { .cta-final { padding: 36px 22px; } }

/* ---- pipeline: mail -> draft+evidence -> human -> sent ----
   The one structural idea on the page: the promise "AI drafts, human
   decides" is a sequence, so it is drawn as a sequence. The human gate
   is the only accent-ringed node, because it is the only step the
   customer is being asked to trust. */
.pipeline {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch; gap: 0; margin-top: 36px;
}
.pipe-card {
  background: var(--surface-1); border: 1px solid var(--hairline);
  border-radius: var(--r-lg); padding: 16px;
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
}
.pipe-card .pipe-label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--ink-faint);
}
.pipe-card .pipe-head {
  font-family: var(--mono); font-size: 11.5px; color: var(--ink-muted);
  border-bottom: 1px solid var(--hairline); padding-bottom: 8px;
}
.pipe-card .pipe-body { font-size: 13px; line-height: 1.5; color: var(--ink); }
.pipe-card.is-draft { border-color: color-mix(in srgb, var(--mark) 55%, var(--hairline)); }

/* The gate node: accent ring + the two mono verbs under it. */
.pipe-gate {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 10px; padding: 0 18px; text-align: center;
}
.pipe-gate .ring {
  width: 44px; height: 44px; border-radius: 999px;
  border: 2px solid var(--mark); background: var(--surface-1);
  display: flex; align-items: center; justify-content: center;
  color: var(--mark-text); font-family: var(--mono); font-size: 12px; font-weight: 600;
}
.pipe-gate .gate-label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--ink-muted); line-height: 1.7;
}
.pipe-arrow {
  align-self: center; display: flex; align-items: center;
  min-width: 40px; padding: 0 10px;
}
.pipe-arrow i {
  display: block; flex: 1; height: 1px;
  background-image: linear-gradient(to right, var(--hairline-strong) 50%, transparent 50%);
  background-size: 7px 1px; background-repeat: repeat-x;
}
.pipe-arrow::after {
  content: ""; width: 6px; height: 6px; margin-left: -3px;
  border-top: 1px solid var(--hairline-strong);
  border-right: 1px solid var(--hairline-strong);
  transform: rotate(45deg);
}
@media (max-width: 900px) {
  .pipeline { grid-template-columns: 1fr; gap: 12px; }
  .pipe-arrow { min-height: 24px; justify-content: center; padding: 0; }
  .pipe-arrow i {
    flex: none; width: 1px; height: 22px;
    background-image: linear-gradient(to bottom, var(--hairline-strong) 50%, transparent 50%);
    background-size: 1px 7px; background-repeat: repeat-y;
  }
  .pipe-arrow::after { margin: -3px 0 0 -3px; transform: rotate(135deg); }
  .pipe-gate { padding: 4px 0; }
}

/* ---- evidence strip: what the draft is standing on ----
   Every claim in a draft is traceable to a row in the customer's own
   system. This makes that legible without a screenshot. */
.evidence { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.evidence-item {
  display: flex; align-items: center; gap: 8px;
  background: var(--inset); border: 1px solid var(--hairline);
  border-radius: var(--r-sm); padding: 7px 10px;
  font-family: var(--mono); font-size: 11.5px; color: var(--ink-muted);
}
.evidence-item .tick { color: var(--success); }

/* Confidence chip: mono, success-tinted, never decorative. */
.confidence {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .6px;
  text-transform: uppercase; padding: 3px 9px; border-radius: 999px;
  color: color-mix(in srgb, var(--success) 70%, var(--ink));
  background: color-mix(in srgb, var(--success) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
}

/* ---- stat band: three numbers, hairline separated ---- */
.statband {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border: 1px solid var(--hairline); border-radius: var(--r-lg);
  background: var(--surface-1); overflow: hidden;
}
.statband > div { padding: 22px 24px; border-left: 1px solid var(--hairline); }
.statband > div:first-child { border-left: 0; }
.statband .n {
  font-family: var(--mono); font-size: 28px; font-weight: 600;
  letter-spacing: -0.02em; color: var(--ink); display: block; margin-bottom: 4px;
}
.statband .k { font-size: 13.5px; color: var(--ink-muted); line-height: 1.45; }
@media (max-width: 760px) {
  .statband { grid-template-columns: 1fr; }
  .statband > div { border-left: 0; border-top: 1px solid var(--hairline); }
  .statband > div:first-child { border-top: 0; }
}

/* ---- numbered step cards (Der Ablauf) ----
   The step number is a large quiet mono figure, not a coloured circle:
   it orders the reading without spending accent on decoration. */
.stepcard { display: flex; gap: 18px; align-items: flex-start; }
.stepcard .idx {
  font-family: var(--mono); font-size: 30px; font-weight: 500; line-height: 1;
  color: color-mix(in srgb, var(--mark-text) 85%, transparent);
  flex: none; padding-top: 2px;
}

/* Accent-topped card: used to mark the one card that carries the promise. */
.panel.is-accent { border-top: 2px solid var(--mark); }

/* Card footer strip: a small mono status line closing a trust card. */
.panel-foot {
  margin: 18px -24px -24px; padding: 10px 24px;
  border-top: 1px solid var(--hairline); background: var(--inset);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--success);
}
.panel { display: flex; flex-direction: column; }
.panel > .panel-foot { margin-top: auto; }

/* ---- terminal proof, dark variant ---- */
.proof.dark {
  background: var(--panel-dark); border-color: var(--panel-dark-hairline);
  color: var(--panel-dark-muted); border-radius: var(--r-lg); padding: 20px 22px;
}
.proof.dark .hl { color: var(--panel-dark-ink); }
.proof-head {
  display: flex; justify-content: space-between; gap: 16px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--panel-dark-muted);
  border-bottom: 1px solid var(--panel-dark-hairline);
  padding-bottom: 10px; margin-bottom: 14px;
}

/* ---- hero refinements ---- */
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: 1.1px; text-transform: uppercase;
  color: var(--mark-text); padding: 4px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--mark) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--mark) 30%, transparent);
  margin: 0 0 18px;
}
.hero-badge::before {
  content: ""; width: 5px; height: 5px; border-radius: 999px; background: var(--mark);
}

/* Focus visibility: the old sheet only styled form focus. */
a:focus-visible, .btn:focus-visible, summary:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm);
}
/* Any muted/lead prose inside the always-dark panel, regardless of which
   page authored it, resolves against the panel rather than the canvas. */
.panel-dark .cta-note, .panel-dark .lead, .panel-dark .muted,
.panel-dark .small, .panel-dark .faint { color: var(--panel-dark-muted); }

/* In dark mode the canvas is already near-black, so the dark panel would
   disappear. Lift it one step and keep the accent glow doing the work. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .panel-dark { background: var(--panel-dark-2); border-color: var(--hairline-strong); }
  :root:not([data-theme="light"]) .proof.dark { background: var(--panel-dark-2); border-color: var(--hairline-strong); }
}
:root[data-theme="dark"] .panel-dark { background: var(--panel-dark-2); border-color: var(--hairline-strong); }
:root[data-theme="dark"] .proof.dark { background: var(--panel-dark-2); border-color: var(--hairline-strong); }

/* Narrow phones: the brand lockup plus "EN" plus the CTA collided at 390px.
   Below 520px the bar hides the language switch (with JS it lives in the
   menu panel's tools row; without JS the footer carries it, rendered from
   nav.json) and the CTA gets a shorter target. The child selector matters:
   once nav.js has moved the link into .links .tools it must stay visible. */
@media (max-width: 520px) {
  header.site nav > a[data-setlang] { display: none; }
  header.site nav { gap: 10px; }
  header.site .brand img { height: 25px; }
  header.site nav a.cta { padding: 7px 11px; font-size: 13.5px; white-space: nowrap; }
}

/* The proof strip is pre-formatted machine output and must not reflow, so
   on narrow screens it scrolls horizontally inside its own rounded box
   instead of pushing the page wide. */
.proof.dark { overflow: hidden; }
.proof.dark > div[style*="pre"] { overflow-x: auto; padding-bottom: 4px; }
@media (max-width: 560px) {
  .proof, .proof.dark { font-size: 11.5px; padding: 14px 14px; }
  .proof-head { flex-wrap: wrap; gap: 4px 12px; }
}

/* The dark panel is fixed in both themes, so the light-theme --success and
   --ink-faint (tuned for a near-white canvas) fail contrast on it. Give
   the panel its own semantic pair. */
.panel-dark .ok, .proof.dark .ok { color: #4cc98a; }
.panel-dark .faint, .proof.dark .faint { color: var(--panel-dark-muted); }

/* ============================================================
   2026 motion layer
   ------------------------------------------------------------
   Inspired by an aurora/glass reference hero, translated into this
   system's own vocabulary: no aurora, no glass, no new colours - the
   existing tokens simply learn to move. Every effect is a whisper,
   every effect dies under prefers-reduced-motion, and pointer effects
   exist only for fine pointers.
   ============================================================ */

/* Shimmer word inside a display headline: a blue glint travels through
   ONE word per hero - the reading colour doing its job with a pulse.
   Fallback (no animation support, reduced motion): solid accent text. */
.shine {
  color: var(--accent-text);
  background: linear-gradient(105deg,
    var(--ink) 0%, var(--ink) 32%,
    var(--accent-text) 50%,
    var(--ink) 68%, var(--ink) 100%);
  background-size: 260% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shine-slide 7s ease-in-out infinite;
}
@keyframes shine-slide {
  0%, 20%   { background-position: 100% 0; }
  60%, 100% { background-position: 0% 0; }
}

/* Hero badge: the dot becomes a quiet LED - a soft ping every few
   seconds, like a status light that says "live", not an alarm. */
.hero-badge::before { animation: led-ping 3.2s cubic-bezier(.16,1,.3,1) infinite; }
@keyframes led-ping {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mark) 45%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Primary CTA: lifts 2px and gains a warm glow on hover - the one
   place the page is allowed to glow, because it is the one action. */
.btn { transition: background .15s ease-out, border-color .15s ease-out,
       color .15s ease-out, transform .15s ease-out, box-shadow .2s ease-out; }
.btn.primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 22px -10px color-mix(in srgb, var(--accent) 65%, transparent);
}
.btn.primary:active { transform: translateY(0); box-shadow: none; }

/* Ghost/secondary CTA with .arrow: the arrow slides right on hover. */
.btn.arrow::after {
  content: "→"; display: inline-block; margin-left: 8px;
  transition: transform .18s cubic-bezier(.16,1,.3,1);
}
.btn.arrow:hover::after { transform: translateX(3px); }

/* Cursor-following spotlight on cards: a faint warm radial that trails
   the pointer (JS sets --mx/--my). Fine pointers only; the gradient is
   6% accent, closer to a sheet of light than a torch. */
@media (hover: hover) and (pointer: fine) {
  .panel, .tier { position: relative; }
  .panel::after, .tier::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    pointer-events: none; opacity: 0; transition: opacity .35s ease-out;
    background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--accent) 6%, transparent) 0%, transparent 70%);
  }
  .panel:hover::after, .tier:hover::after { opacity: 1; }
}

/* Pipeline: the dashed connectors march slowly from mail to sent -
   the promise drawn as motion. Only while JS is alive. */
html.js .pipe-arrow i { animation: pipe-flow 1.6s linear infinite; }
@keyframes pipe-flow { to { background-position: 7px 0; } }
@media (max-width: 900px) {
  html.js .pipe-arrow i { animation-name: pipe-flow-v; }
}
@keyframes pipe-flow-v { to { background-position: 0 7px; } }

/* The human gate breathes: a slow ring expanding from the one node the
   reader is asked to trust. Same rhythm family as the LED ping. */
html.js .pipe-gate .ring { animation: gate-breathe 3.2s cubic-bezier(.16,1,.3,1) infinite; }
@keyframes gate-breathe {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mark) 35%, transparent); }
  70%  { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Pointer-depth parallax (hero pipeline): each [data-depth] child eases
   toward a pointer offset proportional to its depth (lerp in JS). The
   transform lives on the element; max travel is single-digit px. */
[data-depth] { will-change: transform; }

/* Reduced motion: every member of the motion layer stops. */
@media (prefers-reduced-motion: reduce) {
  .shine { animation: none; background: none;
    -webkit-text-fill-color: currentColor; color: var(--accent-text); }
  .hero-badge::before, html.js .pipe-arrow i, html.js .pipe-gate .ring { animation: none; }
  .btn.primary:hover { transform: none; box-shadow: none; }
  .btn.arrow:hover::after { transform: none; }
  .panel::after, .tier::after { display: none; }
  [data-depth] { transform: none !important; }
}

/* ---- comparison table (Ihre Alternativen / Your alternatives) ----
   Three columns of prose do not survive a phone. Below 720px the table
   restacks into labelled blocks: the header row disappears and each cell
   carries its column name from data-label, so the reading order stays
   "option -> what it costs -> with SupportPilot" instead of degrading
   into a horizontal scroll the reader will not perform. */
.cmp { width: 100%; border-collapse: collapse; font-size: 15px; margin: 18px 0 0; }
.cmp th, .cmp td {
  text-align: left; padding: 12px 14px;
  border-bottom: 1px solid var(--hairline); vertical-align: top;
}
.cmp th {
  font-family: var(--mono); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 1px; color: var(--ink-faint); font-weight: 600;
}
@media (max-width: 720px) {
  .cmp, .cmp tbody, .cmp tr, .cmp td { display: block; width: 100%; }
  .cmp thead, .cmp tr:first-child th { display: none; }
  .cmp tr {
    border-bottom: 1px solid var(--hairline);
    padding: 6px 0 14px;
  }
  .cmp tr:last-child { border-bottom: 0; }
  .cmp td { border-bottom: 0; padding: 4px 0; }
  .cmp td[data-label]::before {
    content: attr(data-label);
    display: block; margin-bottom: 3px;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
    text-transform: uppercase; color: var(--ink-faint);
  }
  .cmp td:first-child { padding-top: 10px; }
  .cmp td:first-child b { font-size: 16px; }
}

/* ============================================================
   chart cards (lieflat-charts grammar, brand palette)
   ------------------------------------------------------------
   Hand-written SVG only - no chart library, no external request.
   Card anatomy follows the skill: conclusion-title (h4), one-line
   sub with the legend, the figure, a mono source line. Colours are
   the site's own CUSTOM roles: blue = data (reading colour), amber
   = the one hero element, greys = furniture. Numbers on charts are
   the product's real defaults or clearly-labelled examples - the
   no-invented-numbers rule applies to charts doubly.
   ============================================================ */
.chart svg { width: 100%; height: auto; display: block; margin-top: 14px; }
.chart-sub {
  font-size: 13.5px; color: var(--ink-muted); margin: 2px 0 0;
}
.chart-src {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--ink-faint); margin: 12px 0 0;
}
/* Text inside the SVG scales with the figure: a 640-unit viewBox renders
   at ~1070px on desktop (x1.67). Sizes below are USER UNITS chosen so the
   rendered result lands on the site's caption/mono sizes (11-13.5px), and
   the type rule of the site holds inside the chart: words in the sans
   (labels, notes), numbers and values in the mono. */
.chart text { font-family: var(--sans); fill: var(--ink-muted); }
.chart .lbl { font-size: 8px; fill: var(--ink); }
.chart .lbl-sm { font-size: 7px; fill: var(--ink-muted); }
.chart .val { font-family: var(--mono); font-size: 7.5px; font-weight: 600; fill: var(--ink); }
.chart .tick-lbl { font-family: var(--mono); font-size: 6.5px; fill: var(--ink-faint); }
.chart .note { font-size: 7px; fill: var(--ink-faint); }
/* Narrow figures (sidebar) render near 1:1 and keep natural sizes. */
.chart.compact .lbl { font-size: 12.5px; }
.chart.compact .lbl-sm { font-size: 11px; }
.chart.compact .val { font-size: 11.5px; }
.chart.compact .tick-lbl { font-size: 10px; }
.chart.compact .note { font-size: 10.5px; }
/* Below 640px the figure shrinks under x1; grow the units so labels keep
   roughly the same rendered size as on desktop. */
@media (max-width: 640px) {
  .chart .lbl { font-size: 11px; }
  .chart .lbl-sm { font-size: 10px; }
  .chart .val { font-size: 10.5px; }
  .chart .tick-lbl { font-size: 9px; }
  .chart .note { font-size: 9.5px; }
}
.chart .grid { stroke: var(--hairline); stroke-width: 1; }
.chart .axis { stroke: var(--hairline-strong); stroke-width: 1; }
.chart .bar-data { fill: var(--accent-text); }
.chart .bar-hero { fill: var(--accent); stroke: var(--accent-edge); stroke-width: 1; }
.chart .bar-mut { fill: var(--hairline-strong); }
.chart .line-data { stroke: var(--accent-text); stroke-width: 2; fill: none; }
.chart .line-hero { stroke: var(--accent-edge); stroke-width: 2; fill: none; }
.chart .area-data { fill: color-mix(in srgb, var(--accent-text) 10%, transparent); }
.chart .cap-line { stroke: var(--accent-edge); stroke-width: 1.5; stroke-dasharray: 5 4; }
.chart .dot-data { fill: var(--accent-text); }
.chart .dot-hero { fill: var(--accent); stroke: var(--accent-edge); stroke-width: 1; }
.chart .danger { fill: var(--danger, #c0392b); }
/* Unit grammar (lieflat Basics/Lupi): rungs are canvas-coloured hairlines
   drawn OVER a bar so every unit stays countable; soft fills carry the
   upper end of a range; the tally board counts dots and ticks. */
.chart .rung { stroke: var(--surface-1); stroke-width: 1.5; }
.chart .bar-soft { fill: color-mix(in srgb, var(--accent-text) 28%, transparent); }
.chart .bar-hero-soft { fill: color-mix(in srgb, var(--accent) 38%, transparent); stroke: var(--accent-edge); stroke-width: 1; stroke-dasharray: 3 3; }
.chart .dot-off { fill: none; stroke: var(--hairline-strong); stroke-width: 1; }
.chart .dot-fail { fill: var(--danger, #c0392b); }
.chart .tick-data { stroke: var(--accent-text); stroke-width: 2; stroke-linecap: round; }
.chart .lbl-sm { font-size: 11px; fill: var(--ink-muted); }

/* Entrance: bars grow, lines draw - driven by the same .reveal.in the
   rest of the page uses, so charts animate exactly once, on scroll-in. */
.chart .grow { transform-box: fill-box; transform-origin: left center; }
.chart .grow-v { transform-box: fill-box; transform-origin: center bottom; }
html.js .reveal .chart .grow { transform: scaleX(0); }
html.js .reveal .chart .grow-v { transform: scaleY(0); }
html.js .reveal.in .chart .grow { transform: scaleX(1);
  transition: transform .8s cubic-bezier(.16,1,.3,1); }
html.js .reveal.in .chart .grow-v { transform: scaleY(1);
  transition: transform .8s cubic-bezier(.16,1,.3,1); }
html.js .reveal .chart .draw { stroke-dasharray: 1000; stroke-dashoffset: 1000; }
html.js .reveal.in .chart .draw { stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.6s cubic-bezier(.16,1,.3,1) .2s; }
html.js .reveal .chart .fade { opacity: 0; }
html.js .reveal.in .chart .fade { opacity: 1; transition: opacity .6s ease-out .9s; }
@media (prefers-reduced-motion: reduce) {
  html.js .reveal .chart .grow { transform: none; }
  html.js .reveal .chart .grow-v { transform: none; }
  html.js .reveal .chart .draw { stroke-dasharray: none; stroke-dashoffset: 0; }
  html.js .reveal .chart .fade { opacity: 1; }
}

/* ---- hero spot illustration ----
   One small flat brand illustration floating beside a subpage hero.
   Decorative only (empty alt, aria-hidden), hidden below 960px where it
   would compete with the text column, and slightly translucent so the
   ambient layer still reads through. */
section.hero .wrap { position: relative; }
.hero-spot {
  position: absolute; right: 24px; top: 8px;
  width: clamp(160px, 18vw, 250px); opacity: .92;
  pointer-events: none;
}
@media (max-width: 960px) { .hero-spot { display: none; } }
/* Same illustration role beside a narrow section (e.g. the FAQ): the
   .narrow content cap leaves the right third of the container free. */
.wrap.has-spot { position: relative; }
.section-spot {
  position: absolute; right: 24px; top: 40px;
  width: clamp(140px, 16vw, 210px); opacity: .9;
  pointer-events: none;
}
@media (max-width: 960px) { .section-spot { display: none; } }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero-spot, :root:not([data-theme="light"]) .section-spot { opacity: .8; }
}
:root[data-theme="dark"] .hero-spot, :root[data-theme="dark"] .section-spot { opacity: .8; }

/* ---- light/dark toggle (injected by theme.js) ----
   Icon-only pill in the nav; shows the scheme a click switches TO. The
   existing button:focus-visible rule covers focus. No JS, no button. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; flex: none;
  background: transparent; color: var(--ink-muted);
  border: 1px solid var(--hairline-strong); border-radius: 999px;
  cursor: pointer;
  transition: color .15s ease-out, border-color .15s ease-out;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-muted); }
.theme-toggle svg { width: 15px; height: 15px; display: block; }

/* ---- trial capacity (Testplätze) ----
   The number is real (GET <signupApi>/capacity) or absent; never a placeholder
   that looks like data. Slots are drawn as instrument marks, amber = free,
   because a free slot is the thing the reader can act on. Elements carrying
   data-cap-when="open|full|unknown" are toggled by capacity.js; without JS
   or without the API the "unknown" copy stays, which is honest by default. */
[hidden] { display: none !important; }
.capacity { display: flex; flex-direction: column; gap: 12px; }
.capacity .n {
  font-family: var(--mono); font-size: 36px; font-weight: 600; line-height: 1;
  letter-spacing: -0.02em; color: var(--ink);
}
.capacity .n small {
  font-size: 14px; font-weight: 500; letter-spacing: 0; color: var(--ink-faint); margin-left: 8px;
}
.capacity[data-state="full"] .n { color: var(--warn); }
.slots { display: flex; flex-wrap: wrap; gap: 5px; }
.slot {
  width: 20px; height: 10px; border-radius: 3px;
  background: var(--inset); border: 1px solid var(--hairline-strong);
}
.slot.free { background: var(--accent); border-color: var(--accent-edge); }
.cap-rule { font-family: var(--mono); font-size: 12px; color: var(--ink-faint); line-height: 1.6; }
.stage-label {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .6px; text-transform: uppercase;
  color: var(--ink-faint); margin: 12px 0 0;
}
.panel > .btn.stage-cta { margin-top: 16px; align-self: flex-start; }
.choice { display: grid; gap: 10px; margin-top: 12px; }
.choice label {
  display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px;
  border: 1px solid var(--hairline); border-radius: var(--r-md); background: var(--surface-1);
  cursor: pointer; font-size: 14.5px;
}
.choice label:has(input:checked) { border-color: var(--accent-edge); background: var(--inset); }
.choice input { width: auto; flex: none; margin: 3px 0 0; accent-color: var(--accent); }

.narrow-col { max-width: 760px; }
