/* Radar UI – Tokens und Struktur.
   Werte werden ausschliesslich hier definiert. Siehe DESIGN.md.
   visual-polish.css verwendet diese Tokens, es definiert keine eigenen. */

/* Die Leseschrift von kartschall.com, selbst gehostet (SIL OFL, der Lizenztext
   liegt als EBGaramond-OFL.txt daneben). Sie traegt vorerst nur den Fuss. */
@font-face {
  font-family: "EB Garamond";
  font-style: normal;
  font-weight: 400;
  src: url("/ui/EBGaramond-Regular.woff2") format("woff2");
  font-display: swap;
}
/* Die Titelschrift der Website. Eine feste Instanz, deshalb immer Gewicht 400;
   hoehere Werte erzwingen einen unechten Fettschnitt. Lizenz siehe
   RobotoFlex-OFL.txt daneben. */
@font-face {
  font-family: "Kartschall Titel";
  font-style: normal;
  font-weight: 400;
  src: url("/ui/KartschallTitel.woff2") format("woff2");
  font-display: swap;
}

:root {
  color-scheme: light;
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-synthesis: none;

  /* Schriften der Website. Fallback fuer die Antiqua wie dort Georgia. */
  --serif: "EB Garamond", Georgia, serif;
  --titel: "Kartschall Titel", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Flaeche – neutrales Schwarz-Weiss, keine Farbtoenung */
  --paper: #fcfcfc;        /* dasselbe Papier wie kartschall.com, vorher #f4f4f5 */
  /* Eine Flaeche fuer alles, wie auf der Website. Getoent wird nur ueber --box. */
  --surface: #fcfcfc;
  --surface-soft: #f1f1f1;   /* --box der Website */
  --nav: #17181b;          /* "das Schwarz": Primaerbutton + aktiver Chip. Header ist weiss. */

  /* Seitenrand der Seite, derselbe Wert wie --rand auf kartschall.com. */
  --rand: clamp(1.4rem, 4vw, 4rem);

  /* Text – neutral, warm-/kaltfrei. Tinte wie auf der Website. */
  --ink: #141414;
  --ink-soft: #44474d;
  --muted: #6a6a6a;        /* --leise-fein der Website */
  --leise: #8c8c8c;        /* --leise der Website: Navigation rechts im Kopf */

  /* Linien */
  --line: #e6e6e6;
  --line-strong: #b7bac0;

  /* Akzent: monochrom. Auswahl/Fokus/Primaeraktion = Schwarz, nie Dekoration. */
  --accent: #17181b;
  --accent-strong: #000000;
  --accent-soft: #f1f1f1;   /* --box der Website: getoente Flaeche bei Auswahl */

  /* Lanes: KEINE Farbe mehr. Prioritaet ueber Tinten-Gewicht (schwarz -> grau). */
  --lane-ready: #17181b;
  --lane-review: #44474d;
  --lane-recheck: #44474d;
  --lane-technical: #8b8f96;
  --lane-discovery: #8b8f96;

  /* Ampel-Punkte: die einzigen Farben in der sonst schwarz-weissen Liste.
     Gruen = empfohlen, Amber = ansehen/unsicher, Grau = noch nicht sicher geprueft,
     Rot = NUR das eigene Urteil "nicht passend" (nie ein System-Negativurteil). */
  --dot-good: #2f8f4e;
  --dot-maybe: #c8891a;
  --dot-unknown: #b7bac0;
  --dot-out: #b23b2e;

  /* Rueckmeldung: notice neutral-grau, error als einzige gezielte Farbe (rot, selten). */
  --notice-bg: #f0f0f1;
  --notice-ink: #44474d;
  /* Keine Fehlerflaeche mehr, nur noch die Schriftfarbe. Der Wert bleibt nur
     stehen, falls eine geparkte Regel ihn noch anfasst. */
  --error-bg: #fbeeeb;
  --error-ink: #8a2f22;
  --disabled-bg: #ececee;
  --disabled-ink: #8b8f96;

  /* Typografie: kartschall.com kennt genau zwei Textstufen, --fein .9375rem
     und --lese 1.25rem, dazu die Titelschrift fuer Ueberschriften. Die acht
     Namen hier bleiben stehen, damit nicht siebzig Regeln angefasst werden
     muessen, aber sie zeigen nur noch auf diese zwei Werte. Neue Regeln
     nehmen --text-base fuer Kleingedrucktes und --text-lg fuer Fliesstext. */
  --text-2xs: 0.9375rem;
  --text-xs: 0.9375rem;
  --text-sm: 0.9375rem;
  --text-base: 0.9375rem;   /* --fein */
  --text-md: 1.25rem;
  --text-lg: 1.25rem;       /* --lese */
  --text-xl: 1.25rem;
  --text-2xl: 1.25rem;

  /* Raster: 4px-Basis */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;

  /* Form */
  /* Keine Rundungen: kartschall.css enthaelt kein einziges border-radius. */
  --radius-sm: 0;
  --radius-md: 0;
  --radius-full: 0;
  --shadow-1: 0 1px 2px rgba(16, 32, 25, 0.06);
  --shadow-2: 0 8px 24px rgba(16, 32, 25, 0.10);

  /* Bewegung: uebertraegt Zustand, schmueckt nicht */
  --motion: 160ms;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }
/* Platz fuer die Scrollleiste bleibt immer frei, sonst rutscht die Seite zur
   Seite, sobald Inhalt dazukommt (wie in kartschall.css). */
html { background: var(--paper); scrollbar-gutter: stable; }
body {
  margin: 0;
  min-width: 320px;
  color: var(--ink);
  background: var(--paper);
  font-size: var(--text-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
/* Auf jedem Geraet steht der Fuss bei kurzer Seite am unteren Rand des
   sichtbaren Fensters und rutscht nur nach unten, wenn der Inhalt waechst.
   Sonst sprang er bei jeder Aenderung der Liste hoch und runter
   (Nutzerentscheidung 13.09.2026). svh = Hoehe mit eingeblendeter Browserleiste,
   damit er am Handy ohne Scrollen zu sehen ist; nicht unter den Rand schieben. */
body { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
body > main, body > .auth-surface { flex: 1 0 auto; }
button, input { font: inherit; }
button, a, summary { -webkit-tap-highlight-color: transparent; }
button:focus-visible, a:focus-visible, input:focus-visible, summary:focus-visible, [tabindex="-1"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
button:disabled {
  cursor: not-allowed;
  color: var(--disabled-ink);
  background: var(--disabled-bg);
  border-color: var(--line);
}
a { color: inherit; }
h1, h2, h3, h4, p, dl, dd { margin-top: 0; }
h1, h2, h3 { text-wrap: balance; }
[hidden] { display: none !important; }

.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;
}

/* ---------- App-Shell ---------- */

/* Keine klebende Leiste und kein eigener Hintergrund: nur die Markenzeile,
   darunter dieselbe Haarlinie wie ueber dem Fuss, auf der Breite des Inhalts. */
.app-header { background: var(--paper); }
/* Kopf wie auf kartschall.com: links die Marke, rechts die Bereiche, beides in
   der Leseschrift auf der kleinen Stufe. Die Marke laeuft bewusst NICHT in der
   Titelschrift; kleiner Text ist dort immer Antiqua (DESIGN.md). */
.app-header__inner {
  /* Aufbau wie auf kartschall.com: Spalte hoechstens 1180px, darin der Rand.
     Die Breite ist der Inhalt OHNE Polster, sonst laeuft die Linie ueber den
     Rand hinaus. Ueber 1180px waechst nur der Weissraum aussen. */
  width: calc(min(1180px, 100%) - 2 * var(--rand));
  margin: 0 auto;
  padding-top: var(--rand);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: var(--space-4) var(--space-6);
  font-family: var(--serif);
  font-size: var(--text-base);
}
.wordmark {
  color: var(--ink);
  font-weight: 400;
  text-decoration: none;
}
/* Tippflaeche wie auf der Website: Polster nur auf Touch, per negativem Rand
   wieder herausgerechnet, damit die Kopfzeile ihre Hoehe behaelt. */
@media (pointer: coarse) {
  .wordmark, .app-header__back { padding-block: 0.7rem; margin-block: -0.7rem; }
}
.lead-card__micro-label,
.worklist-filter-group__label {
  color: var(--muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.shell {
  width: calc(min(1180px, 100%) - 2 * var(--rand));
  margin: 0 auto;
  /* Abstand Kopflinie zum Inhalt wie .kopf { margin-bottom } auf der Website.
     Unten kein eigenes Polster, den Abstand zur Fusslinie traegt der Fuss. */
  padding-block: clamp(2.5rem, 5vw, 3.5rem) 0;
}

/* ---------- Market Setup ---------- */

/* Kein Strich zwischen Suche und Liste. Linien gibt es nur unter der Marke und
   ueber dem Fuss, alles dazwischen trennt Weissraum. */
.search-panel {
  display: block;
  padding: 0 0 var(--space-6);
}
.search-intro { margin-bottom: var(--space-6); }
.search-controls { min-width: 0; }
/* Wortgleich die h1-Regel aus kartschall.css, Zeile 97: --gross ist
   clamp(2.6rem, 6vw, 4rem), Zeilenhoehe .92, Gewicht 400, weil die Titelschrift
   eine feste Instanz ist. Ab etwa 1067 px Fensterbreite steht sie fest auf
   4rem, also 64 px, und wird nur auf schmalen Geraeten kleiner. */
h1 {
  max-width: 20ch;
  margin-bottom: var(--space-3);
  font-family: var(--titel);
  font-size: clamp(2.6rem, 6vw, 4rem);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: 0.008em;
}
/* Fliesstext, also dieselbe Schrift, Groesse und Farbe wie die Namen in der
   Liste: Antiqua auf Lesegroesse in Tinte. */
.search-intro__copy {
  max-width: 52ch;
  margin-bottom: 0;
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.5;
}
/* Region-first: Ortsfeld ueber die volle Breite, Button rechts, Branche darunter. */
.search-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
/* Basis 0: das Feld nimmt nur den Platz neben dem Knopf, auch am Handy. Der
   Text laeuft beim Tippen im Feld nach links weg wie im Kontaktformular. */
.search-form .field { flex: 1 1 0; }
.search-form__heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-6); margin-bottom: var(--space-2); }
.search-form__heading label { flex-shrink: 0; margin: 0; }
.search-form__hint-toggle { display: inline-flex; align-items: center; justify-content: flex-end; gap: var(--space-2); min-height: 44px; padding: 0; border: 0; background: none; color: var(--muted); font-family: var(--serif); font-size: var(--text-base); cursor: pointer; transition: color 300ms ease; }
.search-form__hint-toggle:hover, .search-form__hint-toggle[aria-expanded="true"] { color: var(--ink); }
.search-form__privacy-hint { position: fixed; inset: auto; top: var(--hint-top); left: var(--hint-left); box-sizing: border-box; width: min(360px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow-y: auto; margin: 0; padding: var(--space-5); border: 1px solid var(--line); background: var(--paper); box-shadow: 0 4px 16px rgb(0 0 0 / 10%); font-family: var(--serif); font-feature-settings: "lnum" 1, "pnum" 1; }
.search-form__privacy-hint:popover-open { animation: location-hint-appear 160ms var(--ease); }
.search-form__hint-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
.search-form__privacy-hint h2 { margin: 0; font: inherit; }
.search-form__privacy-hint p { margin: 0 0 var(--space-3); }
@keyframes location-hint-appear { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .search-form__privacy-hint:popover-open { animation: none; } .search-form__hint-toggle { transition: none; } }
.search-optional { order: 3; flex: 1 0 100%; }
.search-optional > summary {
  width: fit-content;
  cursor: pointer;
  color: var(--ink-soft);
  font-size: var(--text-xs);
  font-weight: 600;
  list-style: none;
}
.search-optional > summary::-webkit-details-marker { display: none; }
.search-optional > summary:hover { color: var(--ink); }
.search-optional[open] > summary { margin-bottom: var(--space-2); }
.field { min-width: 0; }
/* Feldbeschriftung wie im Kontaktformular: Antiqua auf der kleinen Stufe,
   grau, ohne Fettung. */
.field label {
  display: block;
  margin-bottom: 0.35rem;
  font-family: var(--serif);
  font-size: var(--text-base);
  font-weight: 400;
  color: var(--muted);
}
/* Ein Rezept fuer alle Bedienelemente: dasselbe Polster, dieselbe Stufe,
   dieselbe Hoehe. Der Fokus schwaerzt nur die Linie, kein zweiter Ring. */
/* Eingabefelder tragen die Lesegroesse wie im Kontaktformular; die Region bleibt
   das einzige Suchkriterium. Der Innenabstand steht in em statt in
   rem: .55rem auf 20px sind .44em, .65rem sind .52em. So bleibt das Verhaeltnis
   von Luft zu Buchstaben gleich, egal auf welcher Stufe das Feld steht. */
.field input {
  width: 100%;
  padding: 0.44em 0.52em;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.4;
}
.field input::placeholder { color: var(--muted); opacity: 1; }
/* Wie im Kontaktformular: kein Hover, nur der Fokus schwaerzt die Linie. */
.field input:focus, .field input:focus-visible { outline: none; border-color: var(--ink); }
/* Eingabe und Startaktion stehen getrennt nebeneinander. */
.search-box {
  display: flex;
  gap: var(--space-3);
}
.search-box input { flex: 1 1 0; min-width: 0; }
/* Groesse, Schriftfarbe und gedrueckter Zustand wie .senden im Kontaktformular. */
.search-box__submit {
  flex: 0 0 auto;
  padding: 0.44em 0.52em;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--leise);
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.55;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
@media (hover: hover) { .search-box__submit:hover:not(:disabled) { color: var(--ink); } }
.search-box__submit:active:not(:disabled) { color: var(--ink); background: var(--accent-soft); }
/* Fokus: der Knopfrahmen wird schwarz, die Aktion unterstrichen wie
   die Links der Rechtsseiten; so sieht man, ob Feld oder Knopf gemeint ist. */
.search-box__submit:focus-visible {
  outline: none;
  border-color: var(--ink);
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
/* Gesperrt wie eine gesperrte Auswahl (.view-option:disabled): nur blasser,
   keine fremden Grautoene. */
.search-box__submit:disabled { opacity: 0.45; color: var(--leise); background: transparent; cursor: default; }

/* ---------- Buttons ---------- */

.button, .detail-button, .lane-filter {
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease), color var(--motion) var(--ease);
}
.button { padding: var(--space-2) var(--space-4); }
.button:active:not(:disabled),
.detail-button:active:not(:disabled),
.lane-filter:active:not(:disabled) { transform: scale(0.99); }

/* Der .senden aus deinem Kontaktformular: Rahmen statt Flaeche, Antiqua, grau
   und beim Zeigen schwarz. Gedrueckt toent sich der Grund. Weisse Schrift
   kommt auf der Website nirgends vor. */
.button--primary {
  min-height: 0;
  padding: 0.44em 0.52em;
  border-color: var(--line);
  background: transparent;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.55;
  font-weight: 400;
  /* Wie .senden in kontakt.php: ohne Wartezeit, 0.15s. Die verzoegerte Regel
     aus kartschall.css gilt dort nur fuer Links, der Knopf ueberschreibt sie. */
  transition: background-color 0.15s ease, color 0.15s ease;
}
@media (hover: hover) {
  .button--primary:hover:not(:disabled) { color: var(--ink); background: transparent; }
}
.button--primary:active:not(:disabled) {
  background: var(--accent-soft);
  color: var(--ink);
  transform: none;
  transition-duration: 0.05s;
  transition-delay: 0s;
}

/* Sekundaer: alles andere Handeln. */
.button--secondary, .detail-button, .lane-filter {
  color: var(--ink);
  background: transparent;
}
.button--secondary:hover:not(:disabled),
.detail-button:hover:not(:disabled) { background: var(--surface-soft); border-color: var(--ink-soft); }

.helper {
  max-width: 74ch;
  margin: var(--space-2) 0 0;
  color: var(--muted);
  font-size: var(--text-xs);
}
/* Die Ergebnisansage steht direkt unter dem Suchfeld; der Laufstatus folgt gesammelt. */
.search-context { display: grid; gap: var(--space-2); width: 100%; margin-bottom: var(--space-5); }
.search-context:not(:has(> :not([hidden]))) { display: none; }
.search-context:has(#status-box:not([hidden])) #run-explanation { display: none; }
.search-summary {
  margin-top: var(--space-3);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-6);
  font-family: var(--serif);
  font-size: var(--text-base);
  color: var(--muted);
}
.search-summary__zeile { margin: 0; }
/* Leiser Textknopf statt Kasten, wie die Links im Fuss. */
.textlink {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.textlink:hover { color: var(--ink); }

/* ---------- Rueckmeldung ---------- */

/* Kein Kasten und keine Marke davor, sondern zwei Zeilen Text: was gerade
   geschieht, darunter klein und grau die Nebensache. Nur ein Fehler bekommt
   eine Flaeche, weil er sonst untergeht. */
.status-box {
  margin-top: 0;
}
/* Ein Fehler traegt nur die Schriftfarbe, keine Flaeche. kontakt.php macht es
   genauso: dort wechselt die Beschriftung von Grau auf Tinte, mehr nicht. */
.status-box[data-tone="error"] { color: var(--error-ink); }
.status-box__message {
  margin: 0;
  /* Ohne Lesebreite, damit eine Meldung in einer Zeile stehen bleibt. Sie ist
     kein Fliesstext, sondern ein Satz, der einmal gelesen wird. */
  max-width: none;
  font-family: var(--serif);
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: 1.5;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
/* Die Laufzeit ist die einzige echte Fussnote, deshalb als Einzige klein. */
.status-box__elapsed,
.status-box__detail {
  margin: var(--space-1) 0 0;
  max-width: 52ch;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.8;
  font-feature-settings: "lnum" 1, "pnum" 1;
}

/* Sichtbarer Ladezustand ueber die volle Spalte. Spur in --box, Riegel in
   Tinte. 2px reichen: der schwarze Riegel ueber die volle Breite ist von den
   hellgrauen Haarlinien nicht zu verwechseln. */
.search-progress {
  margin-top: var(--space-3);
  height: 2px;
  background: var(--surface-soft);
  overflow: hidden;
}
.search-progress > span {
  display: block;
  width: 40%;
  height: 100%;
  background: var(--ink);
  animation: search-progress-slide 1.4s ease-in-out infinite;
}
/* Sobald eine Zahl feststeht, zeigt die Leiste den echten Stand. Die Fuellung
   gleitet dann nach, statt hin und her zu wandern. */
.search-progress[data-known="true"] > span {
  width: var(--fortschritt, 0%);
  animation: none;
  transition: width 250ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* Ohne Bewegung steht die Leiste still. Mit bekanntem Stand zeigt sie ihn
   weiterhin, nur ohne Gleiten; ohne Stand fuellt sie sich ganz. */
@media (prefers-reduced-motion: reduce) {
  .search-progress > span { width: 100%; animation: none; }
  .search-progress[data-known="true"] > span { width: var(--fortschritt, 0%); transition: none; }
}
@keyframes search-progress-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(350%); }
}

/* ---------- Ergebnisbereich ---------- */

.results-section { padding-top: 0; }
.results-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-6);
  margin-bottom: var(--space-4);
}
/* Stufe der Registertitel von index.html (Webdesign, Editor, Search), woertlich
   uebernommen; nicht die groessere h1-Stufe --gross. */
.results-heading h2 {
  margin-bottom: 0;
  font-family: var(--titel);
  font-size: clamp(1.6rem, min(4.44vw, 7.11svh), 5.25rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.008em;
}
/* Sicht-Umschalter: zwei Segmente, aktives gefüllt. Feste Größe, rechts oben,
   immer sichtbar (kein Menü, kein Verrutschen). */
/* Auswahl wie im Kontaktformular: ein Rahmen um die ganze Gruppe, innen keine
   Trennstriche, die Punkte selbst rahmenlos. Damit liest es sich als EIN Feld
   mit mehreren Moeglichkeiten und nicht als loser Text. */
.view-switch {
  display: flex;
  flex-wrap: wrap;
  max-width: 100%;
  border: 1px solid var(--line);
}
.view-switch::-webkit-scrollbar { display: none; }
/* Die Auswahl steht ueber der Liste in deren Spalte und bleibt beim Scrollen
   oben stehen; so weiss man auch in Zeile 40, welche Gruppe man sieht. In der
   Spalte ueberdeckt sie die Karte daneben nicht. */
.results-toolbar {
  position: sticky;
  top: 0;
  z-index: 1;
  padding-bottom: var(--space-4);
  background: var(--paper);
}
.results-toolbar .view-switch { width: fit-content; }
.view-option { flex: 0 0 auto; white-space: nowrap; }

.run-explanation {
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.5;
}
.run-explanation p { margin: 0; }
.run-explanation__headline { margin: 0; font-weight: 600; }
.run-explanation__facts {
  display: grid;
  gap: var(--space-1);
  margin: var(--space-2) 0 0;
  padding: 0;
  color: var(--muted);
  font-size: var(--text-sm);
  list-style: none;
}
.run-explanation__queue { margin-top: var(--space-2); }
.run-explanation__queue summary { cursor: pointer; font-weight: 600; }
.run-explanation__queue .run-explanation__facts { list-style: decimal; padding-left: 1.35rem; }

/* Repeat-Search Delta-Kopf (nur bei vergleichbarem Wiederholungslauf sichtbar). */
.repeat-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 8px 0 4px;
}
.repeat-summary__text { margin: 0; font-size: 0.95rem; color: var(--text-muted, #555); }
/* Die .option aus kontakt.php, auf der kleinen Stufe. Innenabstand in em,
   damit das Verhaeltnis zur Schrift dasselbe bleibt. */
.view-option {
  padding: 0.44em 0.52em;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.55;
  font-weight: 400;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
/* Am Finger bleiben die kleinen Schalter gross genug, so wie kartschall.css es
   macht. Feld und Knopf nicht: im Kontaktformular sind sie auch am Handy 48px. */
@media (pointer: coarse) {
  .view-option { padding-block: 0.7rem; }
}
.view-option[aria-pressed="true"] { background: var(--accent-soft); color: var(--ink); }
.view-option:hover:not([aria-pressed="true"]) { color: var(--ink); }
.view-option:active { color: var(--ink); }

/* Worklist-Overview: Markup aktuell nicht ausgeliefert, Regeln bleiben geparkt. */
.worklist-overview {
  display: grid;
  grid-template-columns: minmax(230px, .75fr) minmax(0, 2fr);
  margin-bottom: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.worklist-overview__summary { padding: var(--space-5); }
.worklist-overview__total { display: flex; align-items: baseline; gap: var(--space-2); }
.worklist-overview__total strong { font-size: var(--text-2xl); line-height: 1.15; letter-spacing: -0.02em; }
.worklist-overview__total span { color: var(--ink-soft); font-size: var(--text-sm); font-weight: 500; }
.worklist-overview__summary p { max-width: 35ch; margin: var(--space-3) 0 0; color: var(--muted); font-size: var(--text-2xs); }
.worklist-overview__metrics {
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin: 0;
}
.overview-metric {
  min-width: 0;
  display: flex;
  flex-direction: column-reverse;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-3);
  border-left: 1px solid var(--line);
}
.overview-metric dt { color: var(--muted); font-size: var(--text-2xs); }
.overview-metric dd { margin: 0; font-size: var(--text-lg); font-weight: 600; line-height: 1.25; letter-spacing: -0.015em; }

/* Filter auf eigener voller Zeile: beim Öffnen rutscht der Knopf nicht, das
   Panel klappt in-flow darunter auf (kein schwebendes Menü). */
.worklist-toolbar { min-width: 0; flex: 1 0 100%; }
.worklist-filter-toggle {
  width: fit-content;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  cursor: pointer;
  font-size: var(--text-xs);
  font-weight: 600;
  transition: background var(--motion) var(--ease), border-color var(--motion) var(--ease);
}
.worklist-filter-toggle:hover { background: var(--surface); border-color: var(--ink-soft); }
.worklist-toolbar[open] .worklist-filter-toggle { background: var(--surface); }
.worklist-filter-group {
  min-width: 0;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}
.worklist-filter-group__label { display: block; margin: 0 0 var(--space-2); }
.lane-filters { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.lane-filter {
  min-height: 32px;
  padding: var(--space-1) var(--space-3);
  border-color: transparent;
  border-radius: var(--radius-full);
  color: var(--ink-soft);
  font-size: var(--text-xs);
}
.lane-filter:hover:not(:disabled) { border-color: var(--line-strong); background: var(--surface); }
.lane-filter[aria-pressed="true"] {
  color: #fff;
  background: var(--nav);
  border-color: var(--nav);
}
.ranking-note {
  max-width: 52ch;
  margin: var(--space-1) 0 0;
  color: var(--muted);
  font-size: var(--text-2xs);
  line-height: 1.45;
}
/* Punkt-Legende im Filter: erklaert die Ampel einmal, verstaendlich fuer jeden. */
.filter-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); margin: var(--space-3) 0 0; padding: 0; list-style: none; }
.filter-legend__item { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--ink-soft); font-size: var(--text-xs); }
.filter-legend__dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; }

/* ---------- Worklist ---------- */

/* Ohne Karte nutzt die Liste die volle Breite, mit Karte teilt sie die Zeile
   mit ihr. Die Zeilen bleiben dabei stehen; nur der rechte Rand des Kastens
   folgt der Breite. */
.workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6) var(--space-12);
  align-items: start;
}
.workspace--with-detail { grid-template-columns: minmax(0, 1fr) minmax(390px, 0.72fr); }
@media (min-width: 961px) {
  /* Beim Schliessen bleibt die Hoehe der letzten Karte stehen (misst
     client.js); die Seite wird nicht kuerzer, der Bildschirm springt nicht. */
  .workspace { min-height: calc(var(--detail-offset, 0px) + var(--detail-card-height, 0px)); }
}
.results-column { min-width: 0; }
/* Hoechstens eine ruhige Zeile, kein gestrichelter Kasten: dieselbe kleine
   graue Stufe wie die Zeile ueber der Liste. */
.empty-state {
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
}
.empty-state p {
  max-width: 52ch;
  margin: 0;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.8;
}

/* Liste = ein zusammenhaengender Block mit Trennlinien, keine einzeln
   schwebenden Boxen. Jede Zeile ist ein einziger Knopf mit dem Namen. Kein
   Punkt, keine Zahl, kein Pfeil: welche Gruppe man sieht, sagt die Auswahl
   darueber, und dass die Zeile klickbar ist, zeigt die Toenung. */
.lead-list { min-width: 0; }
.checkpoint-list-section + .checkpoint-list-section { margin-top: var(--space-8); }
/* Ein Kasten je Gruppe. Unter "Mit Mängeln" steht ueber jedem Kasten seine
   Stufe, klein und grau wie "Ort oder Region" ueber dem Suchfeld. Getrennt
   wird ueber Weissraum, nicht ueber einen Strich. */
.lead-rows {
  border: 1px solid var(--line);
  background: var(--surface);
  overflow: hidden;
}
.lead-group + .lead-group { margin-top: var(--space-6); }
.checkpoint-list-section__title,
.lead-group__title {
  margin: 0 0 0.35rem;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: 1.55;
}
.lead-card {
  border-bottom: 1px solid var(--line);
  transition: background var(--motion) var(--ease);
}
.lead-card:last-child { border-bottom: 0; }
.lead-card:has(.candidate-save) { display: flex; align-items: center; }
.lead-card:has(.candidate-save) .lead-card__open { flex: 1; min-width: 0; }
.candidate-save {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-width: 44px; min-height: 44px; padding: 10px; flex-shrink: 0;
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font: inherit;
}
.lead-card > .candidate-save { margin-right: var(--space-3); }
/* Die Aussparung unten zieht das optische Gewicht nach oben; 1px gleicht es aus. */
.candidate-save svg { display: block; width: 20px; height: 20px; transform: translateY(1px); fill: transparent; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; transition: fill 300ms ease, color 300ms ease; }
.candidate-save { transition: color 300ms ease, opacity 300ms ease; }
.candidate-save--detail { position: absolute; top: calc(var(--space-8) - 8px); right: calc(var(--space-8) - 12px); }
.candidate-save[aria-pressed="true"] { color: var(--ink); }
.candidate-save[aria-pressed="true"] svg { fill: currentColor; }
.candidate-save:disabled { opacity: 0.5; cursor: wait; background: transparent; }
.candidate-save:focus-visible { outline: 2px solid var(--ink); outline-offset: -3px; }
.candidate-feedback { color: var(--muted); font-family: var(--serif); font-size: var(--text-base); line-height: 1.55; }
.candidate-feedback:empty { display: none; }
.results-heading:has(.candidate-feedback.sr-only) { margin-bottom: 0; }
.candidate-actions { margin-top: var(--space-4); font-family: var(--serif); font-size: var(--text-base); line-height: 1.8; }
.candidate-actions__row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-5); }
.candidate-actions .link-button { min-height: 44px; margin: 0; padding: 0; }
.candidate-report { display: grid; gap: var(--space-2); margin-top: var(--space-3); }
.candidate-report__reasons { min-width: 0; margin: 0; padding: 0; border: 0; }
.candidate-report__reasons legend { padding: 0; margin-bottom: var(--space-2); }
.candidate-report__option { display: flex; align-items: center; gap: var(--space-2); min-height: 44px; cursor: pointer; }
.candidate-report__option input { width: 16px; height: 16px; margin: 0; flex-shrink: 0; accent-color: var(--ink); }
.candidate-report__reasons:disabled .candidate-report__option { color: var(--muted); cursor: wait; }
.candidate-actions button:disabled { color: var(--muted); cursor: default; background: transparent; }
.candidate-actions button[aria-busy="true"] { cursor: wait; }
@media (hover: hover) { .candidate-save:hover { color: var(--ink); } }
@media (prefers-reduced-motion: reduce) { .candidate-save svg { transition: none; } }
/* Zeigen und Antippen toenen die ganze Zeile mit --box, wie die angeklickte
   Auswahl im Kontaktformular. Am Finger gibt es kein Zeigen; dort gibt
   :active die Rueckmeldung (DESIGN.md: Touch ist kein Hover). */
@media (hover: hover) {
  .lead-card:hover { background: var(--accent-soft); }
}
.lead-card:active, .lead-card--selected { background: var(--accent-soft); }
.lead-card__open.detail-button {
  width: 100%;
  min-height: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-6);
  padding: var(--space-4) var(--space-5);
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
.lead-card__open.detail-button:active { transform: none; }
/* Die Liste schneidet ueberstehende Umrisse ab, deshalb liegt der Fokus innen. */
.lead-card__open.detail-button:focus-visible { outline-offset: -2px; }
.lead-card__title { min-width: 0; overflow-wrap: anywhere; }

/* Zaehler an den Ansichten: eine leere Kategorie bleibt sichtbar statt zu verschwinden. */
.view-option__count {
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
.view-option__count { opacity: 0.6; }
/* Eine leere Ansicht bleibt weiss. Die generische Regel fuer gesperrte Knoepfe
   legt sonst --disabled-bg darunter, und dann sieht die Null aus wie ein
   ausgegrauter Kasten neben den anderen. Die Blaesse allein reicht. */
.view-option:disabled { opacity: 0.45; cursor: default; background: transparent; }
.lead-card__meta {
  margin: var(--space-1) 0 0;
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.5;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
.lead-card__status {
  margin-left: auto;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.35;
  text-align: right;
}
.lead-card__judgement {
  display: inline-block;
  margin-left: var(--space-3);
  padding: 2px var(--space-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  color: var(--ink-soft);
  font-size: var(--text-2xs);
}

/* Bei geoeffnetem Detail wird die Liste schmaler; das gestapelte Layout bleibt. */

/* ---------- Lead Detail ---------- */

/* Die Karte: dieselbe Flaeche wie die Seite, nur ein grauer Rahmen trennt sie
   von der Liste. Innen stehen ausschliesslich Stile, die kartschall.com schon
   hat: Garamond 32 schwarz (Zwischentitel auf Impressum und Datenschutz),
   Garamond 20 schwarz (Lesetext), Garamond 15 grau (Fuss). Keine Etiketten,
   kein Farbpunkt und keine eigene Scrollleiste: die Karte steht als Ganzes da.
   Eine kurze Karte klebt 24px unter dem Fensterrand, eine hoehere erst, wenn
   ihr unteres Ende 24px ueber dem Fensterrand steht (Hoehe misst client.js). */
.lead-detail {
  position: sticky;
  top: min(var(--space-6), calc(100vh - var(--detail-height, 0px) - var(--space-6)));
  padding: var(--space-8);
  border: 1px solid var(--line);
  background: var(--paper);
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.5;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
.lead-detail p { margin: 0; }
/* Die Karte beginnt auf der Hoehe des ersten Kastens der Liste, nicht auf der
   Hoehe der Auswahl darueber; so bilden beide Oberkanten eine Linie. Den
   Abstand misst client.js, weil er je nach Auswahl (mit oder ohne
   Stufen-Beschriftung) wechselt. Nur nebeneinander, nicht gestapelt. */
@media (min-width: 961px) {
  .workspace--with-detail .lead-detail { margin-top: var(--detail-offset, 0px); }
}
/* Beim Oeffnen stellt sich erst die Liste um, dann blendet die Karte ein; beim
   Schliessen blendet erst die Karte aus, dann wird die Liste breit (client.js
   wartet so lange). Kaemen beide im selben Moment, saehe es kurz so aus, als
   lege sich die Karte ueber die Liste. Wechselt nur der Inhalt, bleibt die
   Karte stehen. */
@media (min-width: 961px) {
  .lead-detail:not([hidden]) { animation: detail-in 160ms var(--ease) 80ms both; }
  .lead-detail.lead-detail--leaving { animation: detail-out 140ms linear both; }
}
@keyframes detail-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes detail-out {
  from { opacity: 1; }
  to { opacity: 0; }
}
/* Am Handy laeuft die Karte mit dem Finger, und die Nachbarkarte steht schon
   daneben, eine Kartenbreite und einen Spalt weit weg. Sie haengt in derselben
   Karte, deshalb bewegt sie sich mit (Nutzerwunsch 13.09.2026). */
@media (max-width: 960px) {
  /* Die Nachbarkarte liegt neben der Bahn und wird dort abgeschnitten, statt
     die Seite seitlich scrollbar zu machen. clip statt hidden, damit kein
     eigener Scrollbereich entsteht. */
  .mobile-detail-open .workspace { overflow-x: clip; }
  /* Senkrecht scrollt der Browser selbst, waagerecht gehoert der Finger dem
     Wischen. Sonst scrollt die Seite bei schraegem Wischen mit und die Karte
     ruckelt nach oben oder unten. */
  .lead-detail { touch-action: pan-y; }
  .lead-detail--settling { transition: transform 200ms var(--ease); }
  /* Die Nachbarkarte haengt lose neben der Karte und schiebt den Fuss erst nach
     dem Wechsel an seinen Platz. Waehrend des Wischens blendet er deshalb kurz
     aus, statt ueberdeckt zu werden und danach zu rutschen. */
  .app-footer { transition: opacity 120ms var(--ease); }
  .detail-swiping .app-footer { opacity: 0; }
  /* Die Nachbarkarte muss Pixel fuer Pixel so stehen wie die echte Karte nach
     dem Wechsel, sonst springt der Inhalt beim Tauschen. Deshalb erbt sie das
     Polster (am schmalen Handy kleiner) und rechnet den 1px-Rahmen der Karte
     mit ein, weil absolute Lage am Polsterrand misst. Die Hoehe setzt client.js. */
  .lead-detail__peek {
    position: absolute;
    width: calc(100% + 2px);
    padding: inherit;
    border: 1px solid var(--line);
    background: var(--paper);
  }
  .lead-detail__peek--next { left: calc(100% + 25px); }
  .lead-detail__peek--prev { right: calc(100% + 25px); }
}
@media (prefers-reduced-motion: reduce) {
  .lead-detail:not([hidden]), .lead-detail.lead-detail--leaving { animation: none; }
  .lead-detail--settling { transition: none; }
}
/* Schliessen ist Bedienung: grau wie die Links im Fuss, beim Zeigen schwarz. */
.close-button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-base);
  line-height: 1.8;
  cursor: pointer;
  transition: color var(--motion) var(--ease);
}
@media (hover: hover) { .close-button:hover { color: var(--ink); } }
/* Wie h2 auf den Rechtsseiten der Website: Garamond auf --sub, Gewicht 400.
   Eine Zeile Lesetext Abstand zum Schliessen. */
.lead-detail__title {
  margin: calc(1.5 * var(--text-lg)) 0 0;
  font-size: clamp(1.75rem, 2.6vw, 2rem);
  font-weight: 400;
  line-height: 1.25;
  overflow-wrap: break-word;
  hyphens: auto;
}
/* Wird beim Oeffnen fokussiert (Ansage), ist aber kein Tab-Ziel. */
.lead-detail__title:focus, .lead-detail__title:focus-visible { outline: none; }
/* Innerhalb einer Gruppe keine Luft, zwischen Gruppen eine Zeile Lesetext. */
.detail-group { margin-top: calc(1.5 * var(--text-lg)); }
/* Links wie im Fliesstext der Rechtsseiten: Tinte, feine Unterstreichung. */
.detail-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
/* Kontaktwege nur in der Lesestufe (Garamond 20 schwarz), alles linksbuendig:
   der Bezeichner als eigene Zeile, darunter seine Werte ohne Einzug, zwischen
   den Gruppen ein kleiner Abstand (Nutzerentscheidung 13.09.2026). Verworfen,
   nicht wieder einbauen: zwei Spalten (gequetscht), Bezeichner klein/grau oder
   in der feinen Stufe (falsche Verwendung der Website-Schriften), Liste ohne
   Bezeichner (unaufgeraeumt). */
.detail-register { margin: 0; }
.detail-register > div + div { margin-top: 0.75rem; }
.detail-register dd { margin: 0; overflow-wrap: anywhere; }
/* Ein Link auf die Website steht auf einer eigenen Zeile, nicht im Satz.
   Der Abstand ist derselbe wie zwischen den uebrigen Bloecken der Karte. */
.lead-detail .detail-action { margin-top: calc(1.5 * var(--text-lg)); }
/* Der Lizenzhinweis ist Kleingedrucktes, wie der Fuss der Website. */
.lead-detail .detail-credit { margin-top: calc(1.5 * var(--text-lg)); }
.lead-detail .detail-credit,
.search-form__privacy-hint {
  color: var(--muted);
  font-size: var(--text-base);
  line-height: 1.8;
}

/* Rueckmeldung (nur Produktmodus): dieselbe Auswahl wie die Ansichten. */
.detail-judgement .view-switch { width: fit-content; margin-top: var(--space-3); }
.lead-detail .judgement-status { min-height: 1.8em; margin-top: var(--space-2); color: var(--muted); font-size: var(--text-base); line-height: 1.8; }
.judgement-status[data-state="failed"] { color: var(--error-ink); }

/* Am Finger bleiben die leisen Textknoepfe gross genug; die Luft wird per
   negativem Rand herausgerechnet, das Satzbild bleibt gleich. */
@media (pointer: coarse) {
  .close-button { padding-block: 0.7rem; margin-block: -0.7rem; }
}
@media (max-width: 680px) {
  .search-form__heading { gap: var(--space-2); }
  .search-form__privacy-hint { top: 50%; left: 50%; transform: translate(-50%, -50%); padding: var(--space-5); }
  .lead-detail { padding: var(--space-5); }
  .candidate-save--detail { top: calc(var(--space-5) - 8px); right: calc(var(--space-5) - 12px); }
}

/* ---------- Responsiv: strukturell, nie fluide Typografie ---------- */

@media (max-width: 1120px) {
  .worklist-overview { grid-template-columns: minmax(210px, .68fr) minmax(0, 1.8fr); }
  .worklist-overview__metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .overview-metric:nth-child(4) { border-top: 1px solid var(--line); }
  .overview-metric:nth-child(5) { border-top: 1px solid var(--line); }
  .workspace--with-detail { grid-template-columns: minmax(0, 1fr) minmax(360px, .8fr); }
}

@media (max-width: 960px) {
  .search-panel { grid-template-columns: 1fr; gap: var(--space-5); }
  .worklist-overview { grid-template-columns: 1fr; }
  .worklist-overview__metrics { border-top: 1px solid var(--line); }
  .overview-metric:first-child { border-left: 0; }
  .worklist-toolbar { width: 100%; }
  .workspace--with-detail { grid-template-columns: 1fr; }
  .lead-detail { position: relative; top: auto; max-height: none; overflow: visible; }
}

@media (max-width: 680px) {
  .app-header__inner { min-height: 52px; gap: var(--space-3); }
  .search-panel { gap: var(--space-4); padding-bottom: var(--space-5); }
  .button { width: 100%; }
  .search-summary { align-items: stretch; flex-direction: column; gap: var(--space-2); }
  .search-summary .button { width: auto; align-self: flex-start; }
  .status-box { grid-template-columns: 1fr; gap: var(--space-1); }
  .results-section { padding-top: 0; }
  .results-heading { align-items: start; flex-direction: column; gap: var(--space-1); }
  .worklist-overview { display: none; }
  #personal-workflow-filter-group { display: none; }
  .lane-filters { width: 100%; }
  .lane-filter { flex: 1 1 auto; }
  /* Am Handy laeuft die Auswahl ueber die volle Breite der Liste darunter;
     die Punkte teilen sich den Rest, statt rechts einen Spalt zu lassen. */
  .results-toolbar .view-switch { width: 100%; }
  /* Weniger Polster seitlich, damit alle drei auch auf 360-375px in eine Zeile
     passen; der freie Rest verteilt sich, der Text bleibt mittig. Vorher fehlten
     auf 375px zwei Pixel und "Ungeklärt" rutschte breit in eine zweite Zeile. */
  .results-toolbar .view-option { flex: 1 1 auto; padding-inline: 0.3em; }
  .lead-card__open.detail-button { gap: var(--space-1) var(--space-3); padding: var(--space-4); }

  .mobile-detail-open .search-panel,
  .mobile-detail-open .results-heading,
  .mobile-detail-open .run-explanation,
  .mobile-detail-open .worklist-overview,
  .mobile-detail-open .worklist-toolbar { display: none !important; }
  .mobile-detail-open .results-column {
    position: absolute !important;
    width: 0 !important;
    height: 0 !important;
    min-width: 0 !important;
    overflow: hidden !important;
    pointer-events: none !important;
  }
  .mobile-detail-open .lead-list {
    width: 0 !important;
    height: 0 !important;
    overflow: hidden !important;
    border: 0 !important;
  }
  .mobile-detail-open .results-section { padding-top: 0; }
  /* Kopflinie bis Karte so weit wie Karte bis Fusslinie (.app-footer margin-top). */
  .mobile-detail-open .shell { padding-top: clamp(2rem, 5vw, 3rem); }
  .mobile-detail-open .workspace { display: block; }
  .mobile-detail-open .lead-detail { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
  .button:active, .detail-button:active, .lane-filter:active { transform: none; }
}

/* Globaler Legal-Footer und Rechtsseiten. Tokens siehe oben; keine neuen Werte. */
/* Fuss wie auf kartschall.com: die Haarlinie laeuft auf der Breite des Inhalts
   (dieselbe Formel wie .shell, vorher 980px in der Seitenmitte und damit an
   keiner Kante der Seite), darunter steht alles linksbuendig in der
   Leseschrift der Website, klein und grau. */
.app-footer {
  width: calc(min(1180px, 100%) - 2 * var(--rand));
  /* Wie .fuss auf der Website: 2 bis 3rem ueber der Linie, 1rem darunter, dann
     der Seitenrand der Seite. */
  margin: clamp(2rem, 5vw, 3rem) auto var(--rand);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  align-items: baseline;
  justify-content: flex-start;
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.8;
  font-feature-settings: "lnum" 1, "pnum" 1;
  color: var(--muted);
}
/* Abstaende wie .fuss in kartschall.css (--fuge, am Finger 1.6rem 1.9rem). */
.app-footer__nav { display: flex; flex-wrap: wrap; gap: 1.6rem; }
@media (max-width: 560px) { .app-footer__nav { gap: 0.9rem; } }
@media (pointer: coarse) { .app-footer__nav { gap: 1.6rem 1.9rem; } }/* Wie auf der Website: grau, ohne Unterstreichung, beim Zeigen schwarz. */
.app-footer__nav a { color: inherit; text-decoration: none; }
.app-footer__nav a:hover { color: var(--ink); }

/* Rechtsseiten im Satz von kartschall.com (kartschall.css, .rechtstext): der
   Titel direkt unter der Kopflinie, eine Lesespalte von 33em, Zwischentitel in
   der Antiqua, Abschnitte ueber Weissraum getrennt. Kopf und Fuss laufen ueber
   die ganze Breite, die Spalte beginnt unter der Wortmarke. */
.legal {
  width: calc(min(1180px, 100%) - 2 * var(--rand));
  margin: 0 auto;
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
}
.legal > * { max-width: calc(33 * var(--text-lg)); margin-block: 0; }
.legal > * + * { margin-top: 0.7em; }
/* Der Weg zurueck steht rechts im Kopf, dort wo die Website ihre Bereiche hat. */
.app-header__back { margin-left: auto; color: var(--leise); text-decoration: none; }
.app-header__back:hover { color: var(--ink); }
.legal h1 { margin-bottom: 1rem; }
/* Wie .rechtstext h2: Antiqua auf --sub, davor der Abstand einer section. */
.legal h2 {
  margin: calc(3 * var(--text-lg)) 0 0.5em;
  font-family: var(--serif);
  font-size: clamp(1.75rem, 2.6vw, 2rem);
  font-weight: 400;
  line-height: 1.25;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
/* Fliesstext wie .lese: Antiqua, Lesegroesse, Tinte. */
.legal p, .legal li {
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.5;
  /* Ziffern auf Versalhoehe, sonst setzt EB Garamond Mediaevalziffern und
     "1 bis 10" liest sich wie "i bis io". Wie auf kartschall.com. */
  font-feature-settings: "lnum" 1, "pnum" 1;
  hyphens: auto;
  text-wrap: pretty;
}
/* Die Website kennt keine Aufzaehlungspunkte: Punkte stehen wie Absaetze. */
.legal ul { font-size: var(--text-lg); }
.legal ul { padding: 0; list-style: none; }
.legal li + li { margin-top: 0.7em; }
/* Die Rechtsseiten kennen nur zwei Textstufen, den Zwischentitel und den
   Fliesstext. Keine Bezeichner, keine Kapitaelchen, keine Fettung. */
.legal code { font: inherit; }
.legal a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
/* Kleingedrucktes am Ende: Antiqua auf der kleinen Stufe, grau. */
.legal .legal__meta {
  margin-top: calc(3 * var(--text-lg));
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.8;
}
.legal__pending { background: var(--notice-bg); color: var(--notice-ink); border-radius: var(--radius-md); padding: var(--space-4); margin: 0 0 var(--space-4); max-width: 68ch; }

/* --- Anmeldung (nur Produktmodus) und Konto-Leiste --- */
/* Dieselbe Karte wie Kontodaten und Zahlungen, auf der weissen Seitenflaeche. */
.auth-surface {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: var(--space-6);
}
body:has(.auth-surface:not([hidden])) > .app-header,
body:has(.auth-surface:not([hidden])) > .app-footer { display: none; }
.auth-layout { display: grid; gap: var(--space-4); width: min(32rem, 100%); }
.auth-legal { display: flex; justify-content: center; align-items: center; gap: 0.55rem; color: var(--muted); font-family: var(--serif); font-size: var(--text-base); line-height: 1.8; }
.auth-legal a { color: inherit; text-decoration: none; }
.auth-legal a:hover { color: var(--ink); }
.auth-intro { max-width: 52ch; margin: 0; font-family: var(--serif); font-size: var(--text-lg); line-height: 1.5; }
.auth-card h1 { max-width: none; }
.auth-card .account-dialog__heading h1 { min-width: 0; margin: 0; }
.auth-card .close-button { flex-shrink: 0; white-space: nowrap; text-decoration: none; }
/* Feldnamen bleiben erhalten. Alle Rueckmeldungen stehen in derselben Flaeche. */
.auth-form input[aria-invalid="true"] { border-color: var(--ink); }
.account-feedback { padding: var(--space-4); background: var(--accent-soft); color: var(--ink); font-family: var(--serif); font-size: var(--text-lg); line-height: 1.5; }
.account-feedback:empty { display: none; }
.account-feedback > p { margin: 0; }
.account-feedback > p + p { margin-top: var(--space-2); }
.auth-form { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-5); }
.auth-form .field { width: 100%; }
/* Der Knopf bleibt so breit wie sein Wort, auch auf dem Handy. */
.auth-form .button { width: auto; }
.auth-switch { display: flex; flex-wrap: wrap; gap: 1rem; }
/* Wie die Links im Fuss: Antiqua, klein, grau, beim Zeigen schwarz. */
.link-button, .account-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font-family: var(--serif);
  font-size: var(--text-base);
  line-height: 1.8;
  cursor: pointer;
  transition: color var(--motion) var(--ease);
}
@media (hover: hover) { .link-button:hover, .account-link:hover { color: var(--ink); } }
@media (pointer: coarse) { .link-button, .account-link { padding-block: 0.7rem; margin-block: -0.7rem; } }
/* Konto-Links im Kopf wie .kopf-nav auf kartschall.com: rechtsbuendig, --leise,
   Zeilenhoehe 1.55, Abstand --fuge (1.6rem, bis 560px .9rem). */
.account-bar { margin-left: auto; display: flex; flex-wrap: wrap; align-items: baseline; gap: 1.6rem; }
.account-card, .account-dialog { color: var(--ink); border: 1px solid var(--line); padding: var(--space-6); background: var(--paper, #fff); font-family: var(--serif); font-size: var(--text-lg); }
.account-card { width: min(32rem, 100%); }
.account-dialog { width: min(32rem, calc(100% - 3rem)); }
.account-dialog--auth { border: 0; padding: 0; background: transparent; }
.account-dialog::backdrop { background: var(--paper, #fff); }
.account-card > *, .account-dialog > * { margin: 0; }
.account-card > * + *, .account-dialog > * + * { margin-top: var(--space-4); }
.account-dialog > p:empty { margin: 0; }
.account-dialog__heading { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; }
/* Wie Anbieter/Kontakt auf den Rechtsseiten von kartschall.com. */
.account-dialog__heading :is(h1, h2) {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.75rem, 2.6vw, 2rem);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0.008em;
  font-feature-settings: "lnum" 1, "pnum" 1;
}
.account-dialog__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 1rem; }
.progress-entry { margin-left: auto; color: var(--leise); }
.progress-entry { text-decoration: none; white-space: nowrap; }
.progress-page {
  font-family: var(--serif);
  font-size: var(--text-lg);
  line-height: 1.5;
  font-feature-settings: "lnum" 1, "pnum" 1;
  color: var(--ink);
}
.progress-page h1 { min-width: 0; overflow-wrap: anywhere; }
#progress-title:focus { outline: none; }
/* Eine Spalte in voller Breite, alles auf einer linken Kante: Umschalter, ein
   Satz mit den Zahlen, der Verlauf. Titelschrift nur in der Ueberschrift und im
   Abschluss-Link, alles andere Antiqua 20px wie auf kartschall.com. */
.progress-content { margin-top: var(--space-8); }
.progress-summary { margin: 0; font-size: var(--text-lg); line-height: 1.5; }
.progress-summary__talks { color: var(--muted); }
#progress-chart { display: block; width: 100%; height: clamp(200px, 26vw, 300px); margin-top: var(--space-8); }
.progress-feedback { font-family: var(--serif); font-size: var(--text-base); color: var(--muted); line-height: 1.8; letter-spacing: 0.02em; }
.progress-empty { margin: var(--space-3) 0 0; }
/* Nebenaktionen wie "Live ansehen →" auf kartschall.com: 15px, grau, in einer Zeile unter dem Verlauf. */
.progress-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--space-2) var(--space-6); }
.progress-links { display: flex; flex-wrap: wrap; gap: 0 1.6rem; }
@media (max-width: 560px) { .progress-links { gap: 0 0.9rem; } }
.progress-links .link-button:disabled { background: none; color: var(--muted); opacity: 0.45; cursor: default; }
.progress-feedback { margin: var(--space-2) 0 0; }
.progress-feedback:empty { display: none; }
#progress-clear-yes { color: var(--ink); }
.personal-progress { margin-top: calc(1.5 * var(--text-lg)); }
.personal-progress__label { margin: 0; }
.progress-marks { display: grid; gap: var(--space-1); }
.progress-mark { display: flex; position: relative; align-items: center; gap: var(--space-3); width: fit-content; cursor: pointer; white-space: nowrap; }
@media (pointer: coarse) { .progress-mark { min-height: 44px; } }
.progress-mark input { position: absolute; inset: 0 auto 0 0; width: 20px; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.progress-check { position: relative; display: block; flex: 0 0 16px; width: 16px; height: 16px; border: 1px solid var(--muted); }
.progress-mark input:checked + .progress-check { border-color: var(--ink); }
.progress-mark input:checked + .progress-check::after { content: ""; position: absolute; width: 8px; height: 4px; top: 4px; left: 3px; border-left: 1px solid var(--ink); border-bottom: 1px solid var(--ink); transform: rotate(-45deg); }
.progress-mark input:focus-visible + .progress-check { outline: 2px solid var(--ink); outline-offset: 3px; }
.progress-mark input[aria-invalid="true"] + .progress-check { border-color: var(--error-ink); }
@media (hover: hover) { .progress-mark:hover .progress-check { border-color: var(--ink); } }
.personal-progress > .progress-feedback { margin-bottom: var(--space-3); }
html:has(.progress-page:not([hidden])), body:has(.progress-page:not([hidden])) { overflow-x: clip; }
.account-bar .account-link { color: var(--leise); line-height: 1.55; }
@media (max-width: 560px) { .account-bar { gap: 0.9rem; } }
.lead-card__judgement--useful { background: var(--accent-soft, var(--surface-soft)); }
