:root {
  color-scheme: light;
  /* Flächen im Hellmodus. DRITTER ANLAUF, und der Grund steht dazu.
   *
   * Erster Anlauf: neutrales Warmgrau, praktisch weiss. Sven: "das ist mir
   * alles zu weiss".
   * Zweiter Anlauf: ein leiser Stich ins Violett der Marke. Zu zaghaft -
   * "das helle theme hast du immer noch nicht gemacht".
   * Dritter Anlauf: deutlicheres Violett. Jetzt zu grell - "arbeite mit
   * hellen Farben, z.B. Hell grün hell blau oder so! Mach dich mal schlau
   * über natürliche angenehme Farben."
   *
   * WAS "NATÜRLICH UND ANGENEHM" HEISST, und warum es hier Grün wird:
   *
   * Ein Violettstich ist eine Markenfarbe, keine Umgebungsfarbe. Er ist
   * gesättigt, er zieht Aufmerksamkeit, und auf einer ganzen Bildschirm-
   * fläche wirkt genau das anstrengend – dieselbe Farbe, die als Akzent
   * gut ist, ist als Grund zu laut.
   *
   * Was auf einer Fläche ruhig wirkt, ist wenig gesättigt und liegt im
   * Bereich, in dem das Auge ohnehin den ganzen Tag arbeitet: Grüntöne.
   * Sie sind die Farbe von Blattwerk und Stein, das Auge ist darauf
   * eingestellt, und sie brauchen am wenigsten Anpassung. Ein sehr
   * entsättigtes Salbeigrau-Grün ist darum der Grund geworden – nicht das
   * Grün eines Hinweisschilds, sondern das einer verputzten Wand.
   *
   * Blau wäre die zweite Möglichkeit gewesen und ist bewusst NICHT gewählt:
   * Es kühlt aus, es erinnert an jedes andere Verwaltungsprogramm, und der
   * Nachtdienst schaut ohnehin schon auf blaustichige Bildschirme.
   *
   * DIE KARTEN BLEIBEN HELLER ALS DER GRUND, aber nicht reinweiss: Ein
   * reinweisses Blatt auf getöntem Grund ist der hellste Punkt im Bild und
   * zieht den Blick auf sich, statt ihn auf den Inhalt zu lassen.
   *
   * Kontraste nachgerechnet (WCAG, relative Luminanz), nicht geschätzt.
   * Auf --surface-0:  --text-primary 15,33:1 · --text-secondary 7,26:1 ·
   * --text-muted 5,16:1 · --accent-fg 6,62:1.
   * Auf --surface-sunken, der dunkelsten Fläche: --text-muted 4,73:1,
   * über den geforderten 4,5:1. */
  --surface-0: #eaefe9;
  --surface-1: #f3f6f2;
  /* Die hellste Fläche des Hauses. Sie war #fbfcfa, also drei Prozent unter
     Reinweiss – auf einem Bildschirm ist das praktisch Weiss, und Karten
     nehmen den grössten Teil jeder Ansicht ein. Sven, viermal jetzt: "zu
     grell". Sechs Prozent unter Weiss nimmt die Härte, und die Karte hebt
     sich weiterhin sichtbar vom Seitengrund ab (1,10 statt 1,13 – der
     Unterschied liegt unter dem, was ein Auge als Kante braucht, dafür gibt
     es den Rahmen). */
  --surface-2: #f5f9f3;
  --surface-sunken: #dfe6de;
  --border: #cfd8ce;
  --border-strong: #aab5a9;
  --text-primary: #14181a;
  --text-secondary: #454f4e;
  /* Dunkler als das frühere #85837c: Datum, Ort und Kategorie in der
     Rapportliste kamen nur auf 3.4:1 und waren damit kaum lesbar.
     Am 5.8.2026 noch eine Spur dunkler (#6d6b65 → #67655f): Mit den getönten
     Flächen darüber fiel dieselbe Schrift auf --surface-sunken auf 4,37:1 und
     damit unter die geforderten 4,5:1. Jetzt 4,78:1 auf der abgesenkten und
     5,16:1 auf der normalen Fläche – beides mehr als vorher. */
  --text-muted: #5b6564;
  --accent: #6d28d9;
  --accent-ink: #ffffff;
  --accent-fg: #6d28d9;
  --accent-soft: #f2ecff;
  --series-1: #6d28d9;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #2a78d6;
  --series-8: #e34948;
  --good: #0ca30c;
  --warning: #fab219;
  --serious: #ec835a;
  --critical: #d03b3b;
  /* Tinten für TEXT in den Zustandsfarben. Die Flächenwerte darüber sind auf
     hellem Grund zu blass für Schrift (hoch: 2.6:1, niedrig: 2.9:1) – als Tinte
     eine dunklere Ableitung desselben Tons, kein neuer Farbwert. Im Dunkelmodus
     zeigen die Ableitungen in die Gegenrichtung (siehe unten). */
  --good-ink: color-mix(in srgb, var(--good) 62%, #000);
  /* Am 5.8.2026 von #8a6100 abgedunkelt. Grund: .chip.s-in-arbeit setzt als
     einziger Statuschip KEINE eigene Fuellung und steht damit auf
     --surface-sunken, der dunkelsten hellen Flaeche - dort kam die alte Tinte
     auf 4,36:1 und lag unter den geforderten 4,5:1. Die Schwester
     .chip.p-mittel bestand nur, weil ihre 14%-Fuellung die Flaeche aufhellt.
     Korrigiert wird die Tinte und nicht die Flaeche, weil die s-*-Chips
     bewusst neutral bleiben und nur ueber Rand und Schrift sprechen.
     Nachgerechnet: 5,05:1 auf der abgesenkten, 5,51:1 auf der normalen
     Flaeche, 6,24:1 auf der Karte und 5,76:1 in .chip.p-mittel. */
  --warning-ink: #7d5800;
  --serious-ink: color-mix(in srgb, var(--serious) 56%, #000);
  /* --critical-ink war als EINZIGE der vier Zustandstinten nicht abgedunkelt:
     Sie zeigte einfach auf --critical (#d03b3b). Solange der Hellmodus fast
     weiss war, ging das knapp auf. Mit den ruhigen Salbeiflächen fiel sie
     darunter – auf --surface-sunken nur noch 3,6:1, also unter den geforderten
     4,5:1 für Fliesstext. Ausgerechnet die Farbe, in der "Kritisch" steht.
     Dieselbe Rechnung wie bei --good-ink und --serious-ink, nur etwas
     kräftiger, weil Rot dunkler werden muss als Grün, um gleich lesbar zu
     sein. Nachgemessen: 6,16:1 auf --surface-0 und 5,65:1 auf --surface-sunken. */
  --critical-ink: color-mix(in srgb, var(--critical) 62%, #000);
  /* Der Schatten nimmt denselben Stich auf. Ein neutralgrauer Schatten auf
     einem getönten Grund wirkt schmutzig – derselbe Ton wirkt wie Licht. */
  /* Der Schatten nimmt denselben Ton auf. Ein neutralgrauer Schatten auf
     getöntem Grund wirkt schmutzig; derselbe Ton wirkt wie Licht. */
  --shadow: 0 1px 2px rgba(28,42,34,.07), 0 4px 16px rgba(28,42,34,.06);
  --radius: 12px;
  /* Abstands-System. Vorher gab es fuer denselben Zweck 8, 10, 12, 14, 16 und
     24px - teils als Regel, teils als style="margin-top:12px" im Markup. Darum
     sass auf jeder Seite etwas eine Spur anders. Vier Stufen: Wer eine waehlt,
     waehlt damit auch den Abstand zur naechsten. */
  --luft-eng: 8px;
  --luft-liste: 12px;
  --luft-block: 16px;
  --luft-abschnitt: 24px;
  /* Die Spalte, in der die Anwendung lebt - EIN Wert fuer alle Ansichten.
     Vorher waren es fuenf Breiten (1760 in neun Ansichten, 1100 in Home, Chat
     und Notizen, 760 in Zeiten) mit drei verschiedenen Ausrichtungen. Sichtbar
     kaputt war nicht die Breite selbst, sondern dass die Kappe am inneren
     Modul sass, waehrend die Kopfzeile ein Kind der <section> ist: Die
     Ueberschrift "Home" lief bis 1760px weiter, die Karten darunter endeten
     bei 1100px - der Inhalt sah aus wie ein eingesetzter Block statt wie eine
     Seite. Genau das ist der Befund "fuer volle Breite gedacht, wird als Block
     dargestellt".

     Warum 1760 und nicht enger: Der Befund verlangt MEHR Breite, nicht
     weniger. Neun der zwoelf Ansichten stehen heute auf 1760px und wurden nie
     beanstandet; beanstandet wurde die schmale Startseite. Eine engere
     Lesespalte waere fuer Fliesstext richtig - den begrenzt weiter unten aber
     schon eine eigene Regel auf 68 Zeichen, und Karten und Listen sind kein
     Fliesstext. Wer die Anwendung doch in eine engere Spalte setzen will,
     aendert genau diese eine Zahl; alle Ansichten ziehen mit, weil keine mehr
     eine eigene mitbringt. */
  --spalte: 1760px;
  --sidebar-w: 250px;
  /* Schriftskala. Vorher gab es 45 verschiedene Grössen, darunter Nachbarn wie
     .86/.87/.88 – Unterschiede, die kein Auge trennt, die aber jede Änderung zum
     Ratespiel machen. Sechs Stufen für die Anwendung: wer eine wählt, wählt damit
     auch den Abstand zur nächsten. */
  --fs-xs: .72rem;
  --fs-sm: .8rem;
  --fs-md: .88rem;
  --fs-lg: 1rem;
  --fs-xl: 1.25rem;
  --fs-2xl: 1.5rem;
  /* Nur die Titel der Verkaufsseite: dort trägt die Grösse selbst die Wirkung,
     darum mitwachsend statt fest. In der Anwendung haben diese beiden nichts zu suchen. */
  --fs-display: clamp(1.5rem, 3.2vw, 2.1rem);
  --fs-hero: clamp(1.9rem, 4vw, 3.05rem);
  /* Bewegung an einer Stelle festgelegt: gleiche Zeiten, gleiche Kurve.
     Vorher hatte fast jede Regel ihre eigene Dauer zwischen .1s und .6s. */
  --dur-schnell: 120ms;
  --dur-normal: 200ms;
  --dur-ruhig: 280ms;
  --easing: cubic-bezier(0.2, 0, 0, 1);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-0: #100e16;
  --surface-1: #191622;
  --surface-2: #221e2e;
  --surface-sunken: #14121c;
  --border: #322c42;
  --border-strong: #463e5c;
  /* Kein reines Weiss im Dunkelmodus – blendet auf dunklem Grund. Hauch
     Lavendel aus derselben Familie wie die Flächen. */
  --text-primary: #f4f2fb;
  --text-secondary: #c2bdd2;
  --text-muted: #8d879d;
  --accent: #7c3aed;
  --accent-ink: #ffffff;
  --accent-fg: #c4b5fd;
  --accent-soft: #241a3d;
  --series-1: #8b5cf6;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #3987e5;
  --series-8: #e66767;
  /* Auf dunklem Grund ist es umgekehrt: die satten Flächenwerte taugen als
     Tinte, nur Rot ist dort zu dunkel (3.4:1) und wird aufgehellt. */
  /* Nicht var(--good): Der Satz darueber stimmt fuer ungetoente Flaechen, nicht
     fuer die getoenten Fuellungen. .chip.p-niedrig legt 10% Gruen ueber
     --surface-2 und .badge-on 12% - das hellt den Grund auf und frisst die
     Reserve. Gemessen 4,34:1 und 4,22:1, beide unter 4,5:1. Aufgehellt wie
     --critical-ink darunter, nur schwaecher, weil Gruen von sich aus heller
     ist: jetzt 5,46:1 auf .chip.p-niedrig und 5,31:1 auf .badge-on. */
  --good-ink: color-mix(in srgb, var(--good) 80%, #fff);
  --warning-ink: var(--warning);
  --serious-ink: var(--serious);
  --critical-ink: color-mix(in srgb, var(--critical) 72%, #fff);
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 4px 16px rgba(0,0,0,.3);
}

* { box-sizing: border-box; }
/* Ohne das schrumpft ein fieldset nie unter die Breite seines Inhalts –
   auf dem Handy läuft es sonst über den rechten Rand hinaus. */
fieldset { min-inline-size: 0; border: 0; padding: 0; margin: 0; }

/* Harte Sperre gegen seitliches Verrutschen.
   Läuft irgendein Element doch einmal über den rechten Rand, verkleinert
   Safari sonst die ganze Seite, bis sie hineinpasst – dann ist alles winzig.
   Lieber wird das eine Element abgeschnitten als die ganze Seite gestaucht. */
html { overflow-x: hidden; max-width: 100%; -webkit-text-size-adjust: 100%; }
body { overflow-x: hidden; max-width: 100%; }
img, video, canvas, svg, iframe { max-width: 100%; }
pre, code { overflow-wrap: anywhere; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-primary);
  background: var(--surface-0);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
a { color: var(--accent-fg); }
button, input, select, textarea { font: inherit; color: inherit; }

.hidden { display: none !important; }
.muted { color: var(--text-muted); }
.sec { color: var(--text-secondary); }
/* Fliesstext bleibt schmal, Karten und Listen nicht. Betrifft die
   Einleitungsabsaetze von Vorlagen, Unterlagen und Nachweis sowie die
   Erklaertexte in den Einstellungskarten. 68ch, weil darueber der Ruecksprung
   ans naechste Zeilenende unsicher wird - genau der Grund, aus dem eine breite
   Spalte fuer Fliesstext falsch ist, fuer Karten und Listen aber richtig.
   margin: 0 nimmt dem <p> die 1em, die der Browser mitbringt und die neben den
   16px des Rasters sassen; den Abstand nach oben liefert der Rhythmus. */
.app > main > section > p { margin: 0; max-width: 68ch; }
/* Nur max-width, KEIN margin: .rec-oath und andere Absaetze in Karten setzen
   ihren Abstand selbst und sollen ihn behalten. */
.card > .sec { max-width: 68ch; }
/* Nur fürs Vorlesen: im Markup längst verwendet (Filter-Beschriftungen),
   die Regel dazu fehlte aber – die Beschriftungen standen sichtbar in der
   Filterleiste. Übliches Ausblendmuster, das für Screenreader lesbar bleibt. */
.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Schriftgrössen als Klassen – lösen die fest verdrahteten style="font-size:…"
   in index.html und app.js ab. Nur Werte aus der Skala. */
.fs-xs { font-size: var(--fs-xs); }
.fs-sm { font-size: var(--fs-sm); }
.fs-md { font-size: var(--fs-md); }
.fs-lg { font-size: var(--fs-lg); }

/* ---------- Auth ---------- */
.auth-wrap {
  min-height: 100dvh; display: grid; place-items: center; padding: 24px;
  background: radial-gradient(1200px 600px at 50% -10%, var(--accent-soft), var(--surface-0));
}
.auth-card {
  width: 100%; max-width: 400px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 16px; padding: 24px; box-shadow: var(--shadow);
}
.auth-logo { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.auth-logo svg { width: 32px; height: 32px; }
.auth-tabs { display: flex; gap: 4px; background: var(--surface-sunken); padding: 4px; border-radius: 10px; margin-bottom: 16px; }
.auth-tabs button {
  /* Radius konzentrisch: 10 aussen − 4 Innenabstand = 6 innen. */
  flex: 1; border: 0; background: transparent; padding: 8px; border-radius: 6px;
  cursor: pointer; font-weight: 600; color: var(--text-secondary);
}
.auth-tabs button.active { background: var(--surface-2); color: var(--text-primary); box-shadow: var(--shadow); }

/* ---------- App shell ---------- */
.app { display: none; min-height: 100dvh; }
.app.ready { display: block; }

.sidebar {
  position: fixed; inset: 0 auto 0 0; width: var(--sidebar-w);
  background: var(--surface-1); border-right: 1px solid var(--border);
  padding: 16px 12px; display: flex; flex-direction: column; gap: 4px; z-index: 30;
}
.brand { display: flex; align-items: center; gap: 8px; padding: 4px 8px 16px; }
.brand svg { width: 27px; height: 27px; flex: none; }
.brand b { font-size: var(--fs-lg); letter-spacing: -.015em; white-space: nowrap; }
.navbtn {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  border: 0; background: transparent; padding: 8px 12px; border-radius: 9px;
  cursor: pointer; color: var(--text-secondary); font-weight: 400;
}
.navbtn:hover { background: var(--surface-sunken); color: var(--text-primary); }
/* Im Dunkeln hebt Beruehrung HELL hervor, nicht dunkler: Eine noch dunklere
   Flaeche auf dunklem Grund liest sich als Einsinken - als waere der Knopf
   gerade nicht verfuegbar. Licht heisst: hier bist du. */
:root[data-theme="dark"] .navbtn:hover { background: rgba(255, 255, 255, .07); }
.navbtn.active { background: var(--accent-soft); color: var(--accent-fg); font-weight: 600; }
.navbtn svg { width: 18px; height: 18px; flex: none; }

/* Rubriken in der Seitenleiste: leise Zwischentitel, die den Tag gliedern
   (Dienst / Dateien / Administration). Grossbuchstaben und Sperrung machen
   sie als Ordnung erkennbar, die gedaempfte Farbe haelt sie hinter den
   Knoepfen - sie sind Wegweiser, keine Ziele. */
.nav-rubrik {
  margin: 16px 12px 4px;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-muted);
  user-select: none;
}

/* Feine Koernung ueber der ganzen Flaeche. Eine voellig glatte dunkle Flaeche
   wirkt auf guten Bildschirmen steril und zeigt jede Banding-Stufe der
   Verlaeufe; ein Hauch Rauschen bricht beides. Die Kachel kommt aus
   korn.svg, die Deckkraft ist bewusst so tief, dass man die Koernung spuert
   und nicht sieht. fixed statt scroll, sonst rieselt das Korn beim Rollen mit. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2147483000;
  background: url('/korn.svg') repeat;
  opacity: .018;
}
:root[data-theme="dark"] body::after { opacity: .033; }
/* Auf Papier hat Korn nichts verloren. */
@media print { body::after { display: none; } }
.nav-spacer { flex: 1; }
.side-foot { border-top: 1px solid var(--border); padding-top: 12px; font-size: var(--fs-md); }

/* Der Rahmen der Anwendung. OHNE max-width: Die Spalte sitzt eine Ebene
   tiefer, an der Ansicht.

   WARUM an der Ansicht und nicht hier: Die <h1> steht als Kind der <section>,
   der Inhalt daneben in einem Modulbehaelter. Trug das Modul die Kappe
   (heim.css 1100px, zeiten.css 760px), lief die Kopfzeile daneben bis 1760px
   weiter - die Ueberschrift stand bis zu 455px weiter aussen als die Karten
   darunter. An der section teilen sich Kopfzeile und Inhalt dieselbe Kante,
   ohne dass ein Modul davon wissen muss.

   ACHTUNG bei den 24px: chat.css rechnet height: calc(100dvh - 88px), wobei
   88 = 24 oben + 64 unten aus dieser Zeile ist. Wer --luft-abschnitt aendert,
   muss die 88 dort nachziehen. */
main { margin-left: var(--sidebar-w); padding: var(--luft-abschnitt) clamp(16px, 3vw, 48px) 64px; }

/* Die Spalte. margin-inline: auto haelt sie mittig im Platz rechts der
   Seitenleiste - auf jeder Fenstergroesse, nicht erst ab 1900px (die frueher
   dafuer zustaendige Sonderregel weiter unten entfaellt dadurch). */
.app > main > section { max-width: var(--spalte); margin-inline: auto; }

/* Die Livemap ist die einzige Ansicht, deren Inhalt eine Flaeche ist und keine
   Lesespalte. Ausnahmen werden hier benannt, nicht in den Modulen versteckt -
   sonst entstehen wieder fuenf Breiten. */
.app > main > #view-livemap { max-width: none; }

/* Zeiterfassung ist ein Bedienschirm, keine Leseflaeche: ein grosser Knopf und
   eine Uhr. Sie bekommt eine engere Spalte - aber die GANZE Ansicht, damit die
   Kopfzeile "Zeiten" dieselbe Kante hat wie der Knopf darunter. Vorher sass
   die Kappe auf .zt und die Kopfzeile lief daneben weiter.

   760 und nicht 860: Genau diese Zahl traegt .zt in zeiten.css. Solange die
   beiden Kappen verschieden sind, gilt in Wahrheit die engere - die 860 waeren
   eine zweite, wirkungslose Wahrheit, und die Kopfzeile liefe 100px weiter
   nach rechts als der Inhalt darunter. Mit derselben Zahl an der Ansicht ist
   die Kappe in zeiten.css nur noch doppelt gemoppelt: Wer sie dort streicht -
   das gehoert in jene Datei, nicht hierher - aendert damit nichts mehr. */
.app > main > #view-zeiten { max-width: 760px; }

/* Die zweite Kappe der Startseite abschalten. Das ist der Kern von Befund (b),
   und er sitzt in einer fremden Datei.

   heim.css setzt .heim auf 1100px mittig. Die Ansicht traegt aber eine eigene
   Kopfzeile (<div class="topbar"><h1>Home</h1> … "+ Neuer Rapport"), und die
   ist ein Kind der <section>: Sie nimmt die Kante der Ansicht, der Inhalt
   daneben die des Moduls. Auf einem breiten Schirm stehen Ueberschrift und
   Knopf damit 330px weiter aussen als die Karten darunter. Genau das meint
   "fuer volle Breite gedacht, wird als Block dargestellt" - nicht die Breite
   stoert, sondern die fehlende gemeinsame Kante.

   WARUM die Regel hier steht und nicht in heim.css: Diese Spur darf nur
   styles.css aendern. Sie steht darum an der Stelle, an der die Spalte ohnehin
   vergeben wird, und ist so gebaut, dass sie sich selbst erledigt - streicht
   der Eigner von heim.css die Kappe dort, wird diese Zeile folgenlos und kann
   ersatzlos weg. Die Kennung der Ansicht macht sie stark genug (1,1,2 gegen
   0,1,0), sonst gewaenne heim.css, weil es nach styles.css geladen wird.

   NICHT betroffen sind .ch (Chat) und .nz (Notizen), obwohl beide ebenfalls
   1100px tragen: Ihre Ansichten haben gar keine Kopfzeile, es laufen dort also
   keine zwei Kanten auseinander - und beide sind Leseflaechen (Notizen ist ein
   zweispaltiger Editor), denen die volle Spalte schaden wuerde. Ausnahmen
   werden benannt, nicht erschlichen. */
.app > main > #view-dashboard > .heim { max-width: none; margin-inline: 0; }
/* Und der Kartenabstand der Startseite auf die Blockstufe: heim.css haelt dort
   14px - eine freie Zahl, zwei Pixel neben dem Raster, ausgerechnet auf der
   Ansicht, die man am haeufigsten sieht. */
.app > main > #view-dashboard > .heim { gap: var(--luft-block); }

/* Die Verkaufsseite bringt ein zweites <main> mit und erbte bisher die
   Seitenleisten-Kante von oben: 250px Rand fuer eine Leiste, die dort nicht
   steht, dazu der Innenabstand von main auf den von .landing section
   obendrauf. Die Seite stand damit auf 1920px rund 125px aus der Mitte. Sie
   bringt ihre Breiten selbst mit. */
.landing > .lp-main { margin-left: 0; padding: 0; }

.topbar { display: flex; align-items: center; gap: var(--luft-liste); margin-bottom: var(--luft-abschnitt); flex-wrap: wrap; }
.topbar .grow { flex: 1; }

/* ---------- Buttons / inputs ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  text-decoration: none; color: inherit;
  border: 1px solid var(--border-strong); background: var(--surface-2);
  /* Gewicht 500 statt 600: Vorher trug JEDER Knopf Fettschrift, auch der
     harmloseste - dadurch schrie die Oberflaeche an jeder Stelle gleich laut,
     und nichts hob sich mehr ab. Nur der Hauptknopf (.primary) traegt jetzt
     das schwerere Gewicht; er ist die eine Handlung, die gemeint ist. Radius
     8 statt 9 folgt der Hausskala (6/8), 7px Hoehe statt 8 macht die Reihe
     ruhiger, ohne unter die Tippflaeche zu fallen (mit Zeilenhoehe ueber 40px). */
  padding: 7px 14px; border-radius: 8px; cursor: pointer; font-weight: 500;
  white-space: nowrap;
  transition: background var(--dur-schnell) var(--easing), border-color var(--dur-schnell) var(--easing);
}
.btn:hover { background: var(--surface-sunken); }
.btn svg { width: 16px; height: 16px; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.btn.primary:hover { filter: brightness(1.08); }
.btn.danger { color: var(--critical-ink); border-color: var(--border); }
.btn.danger:hover { background: color-mix(in srgb, var(--critical) 10%, transparent); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover { background: var(--surface-sunken); }
.btn.sm { padding: 4px 12px; font-size: var(--fs-md); border-radius: 8px; }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
/* Mit dem Finger gezielt: 44px in beide Richtungen. Gemessen wurden .btn 42px
   hoch, .btn.sm nur 31,1px und das Schliessen-Kreuz im Rapportblatt
   (.btn.ghost.sm) 37,5 x 31,1 - auf Nachtschicht mit Handschuh trifft man das
   nicht. Nur bei grobem Zeigegeraet, damit am Rechner keine Zeile verrutscht;
   min-width greift ausserdem nur bei den schmalen Icon-Knoepfen, breite
   Textknoepfe bleiben, wie sie sind. */
@media (pointer: coarse) {
  .btn, .btn.sm { min-height: 44px; min-width: 44px; }
}

.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 16px; }
.field label { font-size: var(--fs-md); font-weight: 600; color: var(--text-secondary); }
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=datetime-local], input[type=number], select, textarea {
  width: 100%; padding: 8px 12px; border: 1px solid var(--border-strong);
  border-radius: 9px; background: var(--surface-2); outline: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
textarea { resize: vertical; min-height: 92px; line-height: 1.55; }
/* Dieselbe Stufe wie .grid-2 und der Karten-Rhythmus: Wer zwei Bausteine
   nebeneinander stellt, benutzt den Blockabstand. Die 16 stand hier als freie
   Zahl - gleich gross, aber nicht am System angebunden, und genau daraus sind
   die 8/10/12/14/16/24px entstanden, die vorher quer durch die Datei liefen. */
.row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--luft-block); }
.row-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--luft-block); }

.card {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow);
}
/* Der Abstands-Rhythmus einer Ansicht.

   WARUM nicht mehr nur .card + .card: Der Geschwister-Selektor greift genau
   dort nicht, wo app.js seine Karten in einen Behaelter einhaengt. Gemessene
   Nullnaehte, alle vier vom Besitzer als "da ist kein Abstand" gemeldet:
     Nachweis   section > .card (Filter) | section > #recBody > .card.rec-head
     Nachweis   #recBody > .kpis | .card, und #recBody > .grid-2 | .card
     Adminpanel #adminbereich | #cardTeams  -> "Gruppen" klebt an "Betrieb"
     Unterlagen #docPflicht | #docList

   Darum haengt der Rhythmus jetzt an der Ansicht UND an jedem Behaelter ohne
   eigene Klasse. Ein Behaelter ohne Klasse hat keine Meinung zum Abstand - er
   ist nur ein Griff fuer JavaScript (#recBody, #docList, #userList,
   #objListe, #adminbereich). Also gilt in ihm der Rhythmus der Ansicht weiter.
   Behaelter MIT Klasse (.rlist, .tpl-list, .heim, .grid-2, .kpis, .lm, .zt)
   bringen ihren eigenen gap mit und bleiben ausgenommen - sonst zaehlt der
   Abstand doppelt, denn in Flex und Grid kollabieren Abstaende nicht.

   :not(:empty) ist noetig, weil #docPflicht und #recBody vor dem Laden leer
   sind. Ein leerer Behaelter mit Abstand ist ein Loch im Layout. */
.app > main > section > * + *:not(:empty),
.app > main > section > div:not([class]) > * + *:not(:empty) {
  margin-top: var(--luft-block);
}

/* Bleibt fuer Karten in Blaettern und Overlays, wohin der Rhythmus oben nicht
   reicht - aber am selben Token statt an einer freien Zahl. */
.card + .card { margin-top: var(--luft-block); }

/* Karten, die als Rasterkinder NEBENEINANDER stehen, brauchen keinen Abstand
   nach oben - den traegt der gap. Ohne diese Zeile sitzt auf dem Nachweis die
   rechte Karte ("Nach Status") 16px tiefer als die linke ("Nach Prioritaet")
   und ist 16px kuerzer, weil der Zuschlag innerhalb der Rasterzelle wirkt. */
.grid-2 > .card + .card,
.charts > .card + .card,
.row > .card + .card { margin-top: 0; }

/* Der letzte Baustein in einer Karte gibt seinen Aussenabstand ab. Sonst
   addiert er sich auf den Innenabstand der Karte - die Karte steht dann unten
   32px und oben 16px offen. Betrifft heute die Filterkarte auf dem Nachweis
   und #cardTeams; dort steht deswegen style="margin-bottom:0" im Markup. */
.card > *:last-child { margin-bottom: 0; }

/* ---------- Filter bar ---------- */
.filters { display: flex; gap: var(--luft-eng); flex-wrap: wrap; align-items: center; margin-bottom: var(--luft-block); }
/* Ein Filter ist eine Zeile ausgerichteter Bedienelemente. Bringt eines davon
   einen eigenen Aussenabstand mit, sitzt es aus der Achse - im Flexlayout
   kollabieren Abstaende nicht. Genau deshalb stehen auf dem Nachweis drei
   style="margin:0" im Markup und .chipbtns traegt ein margin-top, das dort
   stoert. Diese Zeile loest alle vier ab. */
.filters > * { margin: 0; }
.filters input, .filters select { width: auto; padding: 8px 12px; border-radius: 8px; font-size: var(--fs-lg); }
.filters .search { flex: 1; min-width: 190px; }

/* ---------- Report list ---------- */
/* Die Rapportliste ist eine Liste, keine Kartenstapelung: Listenstufe, nicht
   Blockstufe. Derselbe Wert wie .kpis und .user-item - vorher eine freie 12. */
.rlist { display: flex; flex-direction: column; gap: var(--luft-liste); }
.ritem {
  position: relative;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; cursor: pointer; box-shadow: var(--shadow);
  transition: transform var(--dur-schnell) var(--easing), border-color var(--dur-schnell) var(--easing);
}
.ritem:hover { transform: translateY(-1px); border-color: var(--border-strong); }
/* Priorität als kurzes Tick auf Höhe der Titelzeile statt als Farbbalken über
   die volle Kantenhöhe. Der Name der Priorität steht als Chip in derselben
   Zeile – Farbe ist hier nie der einzige Träger, das Tick dient nur dem
   schnellen Abtasten der Liste am linken Rand. */
.ritem::before {
  content: ""; position: absolute; left: -1px; top: 15px;
  width: 3px; height: 16px; border-radius: 2px; background: var(--border-strong);
}
.ritem[data-prio="kritisch"]::before { background: var(--critical); }
.ritem[data-prio="hoch"]::before { background: var(--serious); }
.ritem[data-prio="mittel"]::before { background: var(--warning); }
.ritem[data-prio="niedrig"]::before { background: var(--good); }

/* DIE KARTE TRÄGT DENSELBEN TON WIE IHR STRICH — nur sehr leise.
 *
 * Sven: "Immer noch alles zu grell beim hellen modus[,] diese rapporte
 * könnten hell gelb hellgrün sein[,] ganz leicht transparente farbe[,]
 * angenehm wie links dieser kleine strich."
 *
 * Er hat auf die richtige Stelle gezeigt. Der Strich war die einzige Farbe
 * auf einer sonst fast weissen Karte — und fast weiss ist genau das, was auf
 * einem hellen Bildschirm blendet. Jetzt läuft die Farbe des Strichs über die
 * ganze Karte, mit zehn Prozent.
 *
 * ZEHN PROZENT, nicht mehr, und der Grund ist gerechnet:
 * Bei 10% liegt der gedämpfteste Text auf der ungünstigsten Fläche (kritisch)
 * noch bei 5,09:1 — über den geforderten 4,5:1. Bei 20% fiele er darunter,
 * und die Liste sähe aus wie ein Warnschild.
 *
 * Die Farbe steht NIE allein: Der Strich bleibt, der Chip mit dem Namen der
 * Priorität bleibt. Wer Rot und Grün nicht unterscheidet, liest weiter das
 * Wort — der Ton ist nur die Abkürzung fürs Auge beim Überfliegen.
 *
 * IM HELLEN MODUS zehn Prozent der reinen Farbe. */
:root:not([data-theme="dark"]) .ritem[data-prio="kritisch"] { background: color-mix(in srgb, var(--critical) 10%, var(--surface-2)); }
:root:not([data-theme="dark"]) .ritem[data-prio="hoch"]     { background: color-mix(in srgb, var(--serious) 10%, var(--surface-2)); }
:root:not([data-theme="dark"]) .ritem[data-prio="mittel"]   { background: color-mix(in srgb, var(--warning) 10%, var(--surface-2)); }
:root:not([data-theme="dark"]) .ritem[data-prio="niedrig"]  { background: color-mix(in srgb, var(--good) 10%, var(--surface-2)); }

/* IM DUNKELMODUS WIRD DIE FARBE ERST ABGEDUNKELT, DANN AUFGETRAGEN.
 *
 * Der erste Versuch liess den Dunkelmodus einfach aus, und das war der
 * bequeme Weg, nicht der richtige. Sven: "Darkmode natürlich dynamisch auch
 * anpassen."
 *
 * Warum es nicht einfach dieselbe Zeile sein kann: Im Dunkelmodus ist der
 * Text HELL und die Fläche DUNKEL. Jede reine Farbe ist heller als
 * --surface-2 (#221e2e) — sie aufzutragen hellt die Fläche auf und nimmt dem
 * hellen Text Kontrast. Gemessen: --text-muted liegt ohne Ton bei 4,71:1,
 * also knapp über der Grenze; mit zehn Prozent reiner Farbe fällt er auf 3,94
 * bis 4,35 und damit darunter. Ausgerechnet die gedämpfte Zeile, in der Ort
 * und Uhrzeit stehen.
 *
 * Die Lösung ist, den Farbstich vom Helligkeitsgewinn zu trennen: Die Farbe
 * wird zuerst auf 28 % gegen Schwarz gemischt — dann ist sie so dunkel wie
 * die Fläche — und erst dieses Ergebnis wird mit 22 % aufgetragen. Es kommt
 * Farbe dazu, aber kaum Helligkeit.
 *
 * Nachgerechnet, alle über 4,5:1:
 *   niedrig 4,67 · hoch 4,67 · mittel 4,53 · kritisch 4,78
 *   Haupttext überall über 14:1.
 * Der Grenzfall ist Gelb (mittel) mit 4,53 — Gelb ist die hellste der vier
 * Farben und darum die, die am meisten Helligkeit mitbringt. Wer diese Werte
 * anfasst, rechnet bitte dort nach. */
:root[data-theme="dark"] .ritem[data-prio="kritisch"] {
  background: color-mix(in srgb, color-mix(in srgb, var(--critical) 28%, #000) 22%, var(--surface-2));
}
:root[data-theme="dark"] .ritem[data-prio="hoch"] {
  background: color-mix(in srgb, color-mix(in srgb, var(--serious) 28%, #000) 22%, var(--surface-2));
}
:root[data-theme="dark"] .ritem[data-prio="mittel"] {
  background: color-mix(in srgb, color-mix(in srgb, var(--warning) 28%, #000) 22%, var(--surface-2));
}
:root[data-theme="dark"] .ritem[data-prio="niedrig"] {
  background: color-mix(in srgb, color-mix(in srgb, var(--good) 28%, #000) 22%, var(--surface-2));
}
.ritem-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ritem-head .ref { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-sm); color: var(--text-muted); }
.ritem-title { font-weight: 600; }
.ritem-meta { display: flex; gap: 12px; flex-wrap: wrap; font-size: var(--fs-md); color: var(--text-muted); margin-top: 4px; }
.ritem-excerpt { font-size: var(--fs-md); color: var(--text-secondary); margin-top: 8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.chip {
  display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); font-weight: 600;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border-strong);
  background: var(--surface-sunken); color: var(--text-secondary); white-space: nowrap;
}
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.chip.p-kritisch { color: var(--critical-ink); border-color: color-mix(in srgb, var(--critical) 45%, transparent); background: color-mix(in srgb, var(--critical) 10%, transparent); }
.chip.p-hoch { color: var(--serious-ink); border-color: color-mix(in srgb, var(--serious) 45%, transparent); background: color-mix(in srgb, var(--serious) 10%, transparent); }
.chip.p-mittel { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 55%, transparent); background: color-mix(in srgb, var(--warning) 14%, transparent); }
.chip.p-niedrig { color: var(--good-ink); border-color: color-mix(in srgb, var(--good) 45%, transparent); background: color-mix(in srgb, var(--good) 10%, transparent); }
.chip.s-erledigt { color: var(--good-ink); border-color: color-mix(in srgb, var(--good) 40%, transparent); }
.chip.s-offen { color: var(--accent-fg); border-color: color-mix(in srgb, var(--accent-fg) 45%, transparent); }
/* Der dritte Status hatte als einziger keine Regel und fiel auf Grau zurück. */
.chip.s-in-arbeit { color: var(--warning-ink); border-color: color-mix(in srgb, var(--warning) 55%, transparent); }

.empty { text-align: center; padding: 48px 24px; color: var(--text-muted); }
.empty svg { width: 44px; height: 44px; opacity: .4; margin-bottom: 8px; }

/* Leerzustaende aus leer.js, dichte Fassung: eine Zeile Fliesstext INNERHALB
   einer Karte, eines Formulars, eines Aufklappers. Der grosse Kasten braucht
   hier nichts - er erbt Abstand, Zentrierung und Farbe von .empty.

   Warum diese drei Zeilen ueberhaupt: Die dichte Fassung ersetzt an rund
   zwanzig Stellen Markup, das seinen Abstand als style-Attribut mitbrachte
   (etwa style="margin-bottom:8px" in der Kalenderliste). Der Abstand gehoert
   ins Stylesheet und nicht ins Attribut - die Projektregel verbietet
   style-Attribute, und ein Leerzustand ohne Abstand klebt am Nachbarn.

   580 statt 700 beim Titel: die semibold-Stufe der Design-Referenz. <b> waere
   sonst der einzige Fettdruck der Anwendung, der aus der Reihe faellt. */
.leer-dicht { display: block; margin: 6px 0 8px; }
.leer-dicht .leer-titel { color: var(--text-primary); font-weight: 580; }

/* ---------- Dashboard ---------- */
/* margin-bottom bleibt bewusst stehen, obwohl der Rhythmus oben den Abstand
   nach unten schon liefert: .kpis wird auch in zeiten.js innerhalb von .zt-monat
   verwendet, wohin der Rhythmus nicht reicht. Doppelt zaehlt es nicht - zwei
   benachbarte Aussenabstaende im normalen Fluss fallen zusammen (16 statt 32). */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--luft-liste); margin-bottom: var(--luft-block); }
.kpi { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.kpi .label { font-size: var(--fs-sm); color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
/* fs-2xl statt fs-display: die mitwachsenden Grössen gehören der
   Verkaufsseite, in der Anwendung gilt die Skala (siehe Token-Kommentar). */
.kpi .value { font-size: var(--fs-2xl); font-weight: 600; letter-spacing: -.02em; margin-top: 4px; font-variant-numeric: tabular-nums; }
.kpi .value.warn { color: var(--critical-ink); }
/* Kartenraster wie .grid-2 - und weil .charts > .card + .card oben den
   Zuschlag innerhalb der Rasterzelle abschaltet, traegt hier ausschliesslich
   dieser gap den Abstand. Er gehoert deshalb an denselben Wert. */
.charts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--luft-block); }
@media (min-width: 1500px) { .charts { grid-template-columns: repeat(3, 1fr); } }
.chart-card { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.chart-card h3 { margin-bottom: 16px; }
.bar-row { display: grid; grid-template-columns: 116px 1fr 34px; align-items: center; gap: 8px; margin-bottom: 8px; font-size: var(--fs-md); }
.bar-row .track { display: block; background: var(--surface-sunken); border-radius: 4px; height: 14px; overflow: hidden; }
.bar-row .fill { display: block; height: 14px; border-radius: 4px; transition: width var(--dur-ruhig) var(--easing); min-width: 3px; }
.bar-row .num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text-secondary); font-weight: 600; }
.spark { width: 100%; height: auto; display: block; }
.ic { width: 13px; height: 13px; vertical-align: -2px; margin-right: 3px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Detail / Modal ---------- */
.overlay { position: fixed; inset: 0; background: rgba(11,11,11,.45); backdrop-filter: blur(3px); z-index: 50; display: grid; place-items: center; padding: 24px; }
.sheet {
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 16px;
  width: 100%; max-width: 780px; max-height: 92dvh; overflow: auto; box-shadow: 0 24px 60px rgba(0,0,0,.3);
}
.sheet-head { position: sticky; top: 0; background: var(--surface-1); border-bottom: 1px solid var(--border); padding: 16px 24px; display: flex; align-items: center; gap: 8px; z-index: 2; }
.sheet-body { padding: 24px; }
.sheet-foot { position: sticky; bottom: 0; background: var(--surface-1); border-top: 1px solid var(--border); padding: 12px 24px; display: flex; gap: 8px; justify-content: flex-end; }

.dl { display: grid; grid-template-columns: 152px 1fr; gap: 8px 16px; font-size: var(--fs-lg); }
.dl dt { color: var(--text-muted); font-weight: 600; font-size: var(--fs-md); }
.dl dd { margin: 0; }
.prose { white-space: pre-wrap; line-height: 1.6; }
.block { margin-top: 16px; }
.block h3 { color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; font-size: var(--fs-sm); margin-bottom: 8px; }

.thumbs { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.thumb { position: relative; width: 104px; }
.thumb img, .thumb .pdf {
  width: 104px; height: 104px; object-fit: cover; border-radius: 9px;
  border: 1px solid var(--border); background: var(--surface-sunken); display: grid; place-items: center;
}
.thumb .del {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--surface-2); cursor: pointer; line-height: 1; padding: 0;
}
/* Sichtbar bleibt der 22px-Knopf, getroffen werden 44px. Ohne das trifft
   man auf dem Handy neben das Kreuz und löscht nichts. */
.thumb .del::before {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; min-width: 100%; min-height: 100%;
}
.thumb .cap { font-size: var(--fs-xs); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--text-primary); color: var(--surface-1); padding: 12px 16px;
  border-radius: 12px; z-index: 100; box-shadow: var(--shadow); font-size: var(--fs-lg); font-weight: 600;
}
.toast.err { background: var(--critical); color: #fff; }
.err-msg { color: var(--critical-ink); font-size: var(--fs-md); margin-bottom: 12px; }

.switch-row { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.switch-row input { width: 44px; height: 25px; appearance: none; background: var(--border-strong); border-radius: 999px; position: relative; cursor: pointer; transition: background var(--dur-normal) var(--easing); flex: none; }
/* Der Schalter ist nur 25px hoch. Ein unsichtbarer Streifen darüber und
   darunter bringt die Trefferfläche auf 44px, ohne dass sich am Schalter
   selbst etwas ändert. */
.switch-row input::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); height: 44px; }
.switch-row input::after { content: ""; position: absolute; top: 3px; left: 3px; width: 19px; height: 19px; border-radius: 50%; background: #fff; transition: transform var(--dur-normal) var(--easing); box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.switch-row input:checked { background: var(--good); }
.switch-row input:checked::after { transform: translateX(19px); }

.tpl-list { display: flex; flex-direction: column; gap: var(--luft-eng); }
.tpl-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); }

.fab { display: none; }

/* ---------- Mobile ---------- */
@media screen and (max-width: 860px) {
  body { font-size: 16px; }
  .sidebar {
    inset: auto 0 0 0; width: auto; height: 62px; flex-direction: row; border-right: 0;
    border-top: 1px solid var(--border); padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
    justify-content: space-around; align-items: center;
  }
  /* Rubriken sind Wegweiser der hohen Leiste - in der Fusszeile waeren sie
     Fremdkoerper zwischen den Knoepfen. */
  .brand, .nav-spacer, .side-foot, .nav-rubrik { display: none; }
  .navbtn {
    flex-direction: column; gap: 3px; font-size: var(--fs-xs); padding: 6px 2px;
    justify-content: center; align-items: center; text-align: center; font-weight: 600;
    min-width: 0; flex: 1;
  }
  .navbtn span { overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  /* Kurzbezeichnung auf dem Handy */
  .navbtn[data-short] span { font-size: 0; }
  .navbtn[data-short] span::after { content: attr(data-label); font-size: var(--fs-xs); letter-spacing: -.01em; }
  /* "Neu" liegt auf dem Handy auf dem runden Knopf unten rechts.
     Vorlagen, Benutzer und Unterlagen wandern unter "Mehr" – sonst quetschen
     sich sieben Knöpfe in die Leiste und die Beschriftungen brechen ab.
     Unterlagen fliegt als Einziges der Alltagsziele raus, weil Unterlagen im
     Einsatz ohnehin über das Objekt-Detailblatt aufgeschlagen werden;
     Rundgang, Rapporte und Dienste sind die eigentlichen Feldwege. */
  .navbtn[data-view="new"],
  .navbtn[data-view="templates"],
  .navbtn[data-view="record"],
  .navbtn[data-view="docs"],
  .navbtn[data-view="users"] { display: none; }
  /* Der Unterlagen-Kurzweg in "Weitere Bereiche" trägt noch nur-desktop aus
     der Zeit, als Unterlagen in der Fussleiste lag. Bis das Markup nachzieht,
     schaltet ihn diese Ausnahme auf dem Handy frei. */
  .mehr-links .nur-desktop { display: inline-flex; }
  .navbtn svg { width: 21px; height: 21px; }
  .navbtn.active { background: transparent; }
  main { margin-left: 0; padding: 16px 12px calc(86px + env(safe-area-inset-bottom)); }
  .row, .row-3, .charts { grid-template-columns: 1fr; }
  .dl { grid-template-columns: 1fr; gap: 2px 0; }
  .dl dd { margin-bottom: 8px; }
  .sheet { max-width: none; max-height: 100dvh; height: 100dvh; border-radius: 0; border: 0; }
  .overlay { padding: 0; }
  /* Auf dem Handy zählt jeder Millimeter Breite – engere Innenabstände,
     damit kein Rahmen mehr über den rechten Rand hinausläuft. */
  .sheet-head { padding: 12px; }
  .sheet-body { padding: 12px 12px 16px; }
  .fs { padding: 12px 12px 4px; margin-bottom: 12px; }
  .fs > legend { padding: 0 4px; margin-left: -4px; }
  .sheet-foot {
    padding: 12px 12px calc(12px + env(safe-area-inset-bottom));
    flex-wrap: wrap; gap: 8px;
  }
  .sheet-foot > div[style*="flex:1"] { display: none; }
  .sheet-foot .btn { flex: 1; min-width: 0; justify-content: center; }
  #eSaveTpl { order: 3; flex-basis: 100%; }
  .draft-box { padding: 12px; }
  .blur-canvas-wrap { padding: 4px; max-height: 52vh; }

  /* Anmeldeprotokoll: untereinander statt in vier Spalten */
  .act-row { grid-template-columns: 20px 1fr; gap: 4px 12px; }
  .act-row > *:nth-child(3), .act-row > *:nth-child(4) { grid-column: 2; }
  .user-item { flex-wrap: wrap; }
  .user-item .btn, .user-item .user-role { flex: 1; min-width: 130px; }
  .fab {
    display: grid; place-items: center; position: fixed; right: 16px;
    bottom: calc(76px + env(safe-area-inset-bottom)); width: 56px; height: 56px; border-radius: 50%;
    background: var(--accent); color: #fff; border: 0; box-shadow: 0 6px 20px rgba(109,40,217,.45);
    z-index: 25; cursor: pointer;
  }
  .fab svg { width: 26px; height: 26px; }
  .topbar h1 { font-size: var(--fs-xl); width: 100%; }
  .topbar { gap: 8px; margin-bottom: 16px; }
  .topbar-actions { display: flex; gap: 8px; width: 100%; }
  .topbar-actions .btn { flex: 1; justify-content: center; }
  .kpis { grid-template-columns: 1fr 1fr; }

  /* Filter: Suche über die volle Breite, der Rest ordentlich zu zweit */
  .filters { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .filters .search { grid-column: 1 / -1; min-width: 0; }
  .filters input, .filters select { width: 100%; }
  .filters > button, .filters > .btn { grid-column: 1 / -1; }

  /* Alles hat denselben Innenabstand – nichts sitzt mehr aus der Achse */
  .card, .ritem { border-radius: 12px; }
  .lic-table { font-size: var(--fs-md); }
  .lic-table td, .lic-table th { padding-right: 8px; }
  .rec-sign { grid-template-columns: 1fr; }
  .seg label { padding: 8px 12px; font-size: var(--fs-md); }
  .when-row input[type=datetime-local] { min-width: 0; }
}

/* Hier stand eine Sonderregel ab 1900px, die den Inhalt ueber einen
   berechneten linken Innenabstand mittig hielt. Sie war der Notbehelf gegen
   genau das Problem, das jetzt .app > main > section loest: margin-inline:auto
   haelt den Inhalt auf JEDER Fenstergroesse mittig, nicht erst ab 1900px. Die
   harte 1760 darin waere ausserdem eine zweite Wahrheit neben --spalte. */

/* ---------- Druck / PDF ---------- */
@media print {
  /* druck.css schreibt die Grundfarben auf Schwarz um, kennt die
     Tinten-Ableitungen aber nicht – ohne diese Zeile druckt --warning-ink
     braun und im Dunkelmodus --critical-ink grau. */
  :root, :root[data-theme="dark"] {
    --good-ink: #000; --warning-ink: #000; --serious-ink: #000; --critical-ink: #000;
  }
  /* Das Prioritäts-Tick ist Bildschirmsprache; auf Papier trägt der Chip
     die Aussage in Textform. */
  .ritem::before { display: none; }
  .sidebar, .topbar, .filters, .fab, .sheet-head .btn, .sheet-foot, .thumb .del, .no-print { display: none !important; }
  /* Ist ein Rapport geöffnet, wird NUR dieser gedruckt – nicht die Liste dahinter. */
  body.modal-open .app { display: none !important; }
  html, body { height: auto !important; overflow: visible !important; background: #fff; }
  body { font-size: 10.5pt; }
  main { margin: 0; padding: 0; max-width: none; }
  /* Muss mit, seit die Spalte an der section haengt: sonst druckt jede Ansicht
     in einem 1760px-Kasten mitten auf dem Blatt. Selbe Spezifitaet wie die
     Regel dort oben, sonst greift der Ruecksetzer nicht. */
  .app > main > section { max-width: none; margin-inline: 0; }
  /* Zeiten braucht die eigene Zeile: Seine engere Spalte haengt an der Kennung
     der Ansicht und ist damit staerker (1,1,1) als der Ruecksetzer darueber
     (0,1,2). Ohne sie druckt das Monatsblatt in einer 760px-Spalte, waehrend
     rechts daneben ein Drittel des Blattes leer bleibt. Gleiche Spezifitaet
     wie dort, aber spaeter in der Datei - also gewinnt sie.
     #view-livemap braucht nichts: Es steht schon auf none. */
  .app > main > #view-zeiten { max-width: none; }
  .overlay { position: static; background: none; padding: 0; backdrop-filter: none; display: block; }
  .sheet { max-width: none; max-height: none; height: auto; box-shadow: none; border: 0; overflow: visible; background: #fff; }
  .sheet-head { position: static; border-bottom: 2px solid #000; padding: 0 0 8px; background: none; }
  .sheet-body { padding: 12px 0 0; }
  .dl { gap: 6px 16px; }
  .block { margin-top: 12px; }
  .card, .ritem, .chart-card, .kpi { box-shadow: none; border: 1px solid #bbb; break-inside: avoid; }
  .ritem { page-break-inside: avoid; }
  .thumb img { width: 150px; height: auto; }
  .print-head { display: block !important; border-bottom: 2px solid #000; margin-bottom: 14px; padding-bottom: 8px; }
  a[href]:after { content: ""; }
  @page { margin: 14mm; }
}
.print-head { display: none; }

/* ---------- Nachträge / Verlauf ---------- */
.ritem-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; padding-top: 8px; border-top: 1px dashed var(--border); }
.disclose {
  display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent;
  color: var(--text-secondary); font-size: var(--fs-md); font-weight: 600; cursor: pointer;
  padding: 4px 8px; border-radius: 7px;
}
.disclose:hover { background: var(--surface-sunken); color: var(--text-primary); }
.disclose .caret { transition: transform var(--dur-normal) var(--easing); display: inline-block; }
.disclose[aria-expanded="true"] .caret { transform: rotate(90deg); }
.quick { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }

.entries { margin: 12px 0 0 12px; padding-left: 12px; border-left: 2px solid var(--border); display: none; }
.entries.open { display: block; }
.entry { padding: 8px 0; font-size: var(--fs-md); }
.entry + .entry { border-top: 1px solid var(--border); }
.entry-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.entry-kind { font-weight: 600; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--accent-fg); }
.entry-time { color: var(--text-muted); font-size: var(--fs-sm); }
.entry-text { color: var(--text-secondary); white-space: pre-wrap; margin-top: 2px; }
.entry-status { font-size: var(--fs-sm); color: var(--text-muted); }
.entry-del { border: 0; background: transparent; color: var(--text-muted); cursor: pointer; font-size: var(--fs-sm); padding: 0 4px; margin-left: auto; position: relative; }
/* Das Kreuz ist knapp 16px breit – die Trefferfläche wächst unsichtbar
   auf 44px, das Schriftbild der Zeile bleibt unverändert. */
.entry-del::before {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; min-width: 100%; min-height: 100%;
}
.entry-del:hover { color: var(--critical-ink); }
.entry-add { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.entry-add input { flex: 1; min-width: 180px; padding: 8px 12px; font-size: var(--fs-md); }
.entry-add select { width: auto; padding: 8px 12px; font-size: var(--fs-md); }

/* ---------- Dienste ---------- */
.shift-day { margin-bottom: 16px; }
.shift-day h3 { color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; font-size: var(--fs-sm); margin-bottom: 8px; }
/* Bewusst ohne Farbkante links: sie war bei jedem Dienst gleich violett und
   trug damit keine Information. Der laufende Dienst hebt sich über die
   Fläche (accent-soft) und sein Abzeichen ab. */
.shift {
  display: flex; align-items: center; gap: 12px; background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: 8px; box-shadow: var(--shadow);
}
.shift-time { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 116px; font-size: var(--fs-lg); }
.shift-body { flex: 1; min-width: 0; }
.shift-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shift-meta { font-size: var(--fs-sm); color: var(--text-muted); }
.shift.now { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.shift-badge { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--accent-fg); }

.cal-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-2); margin-bottom: 8px; }
.cal-swatch { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.steps { padding-left: 16px; line-height: 1.75; font-size: var(--fs-md); }
.steps code { background: var(--surface-sunken); padding: 1px 5px; border-radius: 4px; font-size: var(--fs-sm); }

@media print {
  .ritem-foot, .disclose, .quick, .entry-add, .entry-del { display: none !important; }
  .entries { display: block !important; }
}

@media screen and (max-width: 860px) {
  .entry-add { flex-direction: column; align-items: stretch; }
  .entry-add select, .entry-add input, .entry-add .btn { width: 100%; }
  .entries.open { padding-bottom: 8px; }
  .filters input[type=date] { flex: 1; min-width: 0; }
  .quick { width: 100%; margin-left: 0; }
  .quick .btn { flex: 1; }

  .shift { flex-wrap: wrap; row-gap: 4px; padding: 12px 16px; }
  .shift-time { order: 1; width: auto; min-width: 0; font-size: var(--fs-md); }
  .shift-badge { order: 2; margin-left: auto; }
  .shift-body { order: 4; flex-basis: 100%; min-width: 100%; }
  .shift-title { white-space: normal; }
  .shift .btn { order: 5; margin-left: auto; }
}

/* Live-Anzeige */
.live-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--good); margin-right: 8px; vertical-align: 1px;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent);
  transition: background var(--dur-normal) var(--easing), box-shadow var(--dur-normal) var(--easing);
}
.live-dot.off { background: var(--text-muted); box-shadow: none; }
/* Atmen statt blinken: Die Verbindung ist ein Dauerzustand, kein Ereignis.
   Ein Blinken zieht den Blick immer wieder weg; ein langsames Auf- und
   Abschwellen bestaetigt "es lebt", ohne zu stoeren. Vier Sekunden liegen
   deutlich unter dem Puls, den man als Hektik empfindet. Nur der verbundene
   Punkt atmet - ein ausgefallener Punkt soll ruhig und tot aussehen. */
@keyframes lebt-atmen {
  0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--good) 16%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--good) 28%, transparent); }
}
.live-dot:not(.off) { animation: lebt-atmen 4s var(--easing) infinite; }
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none !important; } }

/* ================= Homepage ================= */
.landing { min-height: 100dvh; background: var(--surface-0); }
.landing.hidden { display: none !important; }

.lp-head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px clamp(16px, 5vw, 48px); max-width: 1200px; margin: 0 auto;
}
.lp-brand { display: flex; align-items: center; gap: 8px; }
.lp-brand svg { width: 34px; height: 34px; }
.lp-brand b { font-size: var(--fs-xl); letter-spacing: -.015em; }

.lp-hero {
  max-width: 1300px; margin: 0 auto;
  display: grid; grid-template-columns: minmax(320px, 1fr) 1.05fr;
  gap: clamp(24px, 5vw, 64px); align-items: center;
}
.lp-hero h1 {
  font-size: var(--fs-hero); line-height: 1.09; letter-spacing: -.03em;
  margin-bottom: 16px; font-weight: 700; text-wrap: balance;
}
/* Ab dieser Breite passt jede Zeile am Stück – kein hässlicher Umbruch mitten im Satz */
@media (min-width: 1080px) { .lp-hero h1 .zeile { white-space: nowrap; } }
.lp-lead { font-size: var(--fs-xl); color: var(--text-secondary); max-width: 46ch; line-height: 1.6; }
.lp-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 24px; }
.lp-cta { padding: 12px 24px; font-size: var(--fs-xl); border-radius: 11px; }
.lp-cta svg { width: 19px; height: 19px; }
.lp-cta small { display: block; font-size: var(--fs-xs); opacity: .8; font-weight: 400; }
.lp-note { font-size: var(--fs-md); margin-top: 16px; max-width: 46ch; }

.lp-shot { display: grid; place-items: center; }

/* Die Sektion selbst ist ein normaler Block – das Raster steckt in .lp-feat-grid. */
.lp-features { max-width: 1240px; margin: 0 auto; }

.lp-install { max-width: 1140px; margin: 0 auto; }
.lp-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; }
.lp-steps b { display: block; margin-bottom: 4px; }
.lp-steps p { font-size: var(--fs-md); color: var(--text-secondary); margin: 0; line-height: 1.55; }

.lp-foot {
  border-top: 1px solid var(--border); padding: 24px clamp(16px, 5vw, 64px);
  font-size: var(--fs-md); color: var(--text-muted);
}

/* ---------- Anmeldung / Zwei-Faktor ---------- */
.tfa-icon { display: grid; place-items: center; margin: 4px 0 12px; color: var(--accent-fg); }
.tfa-icon svg { width: 42px; height: 42px; }
.tfa-lead { text-align: center; color: var(--text-secondary); font-size: var(--fs-lg); margin: 0 0 16px; }
.tfa-input {
  font-size: var(--fs-2xl); letter-spacing: .35em; text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 600;
}

/* ---------- Sicherheit ---------- */
.sec-block { padding: 16px 0; border-top: 1px solid var(--border); }
.sec-block:first-of-type { border-top: 0; padding-top: 8px; }
.sec-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.sec-row > div:first-child { flex: 1; min-width: 200px; }

.badge-on, .badge-off {
  display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-sm); font-weight: 700;
  padding: 2px 8px; border-radius: 999px;
}
.badge-on { color: var(--good-ink); background: color-mix(in srgb, var(--good) 12%, transparent); }
.badge-off { color: var(--text-muted); background: var(--surface-sunken); }

.codes-warn {
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
  border-radius: 8px; padding: 12px 16px; font-size: var(--fs-md); line-height: 1.55;
}
.codes-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; margin-top: 12px;
}
.codes-grid span {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-xl); font-weight: 600;
  background: var(--surface-sunken); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px; text-align: center; letter-spacing: .04em;
}

.act-row {
  display: grid; grid-template-columns: 20px 160px 1fr auto; gap: 12px; align-items: center;
  font-size: var(--fs-md); padding: 8px 0; border-bottom: 1px solid var(--border);
}
.act-row:last-child { border-bottom: 0; }
.act-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--good); }
.act-dot.bad { background: var(--critical); }

.user-item {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--surface-2); border: 1px solid var(--border);
  /* 12px statt 8px: Die Zeilen lagen 8px auseinander und die Karte darunter
     ebenfalls 8px - beides unterhalb des Rasters. Jetzt liegen die Zeilen auf
     der Listenstufe, der Abstand zur naechsten Karte kommt vom Rhythmus. */
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: var(--luft-liste); box-shadow: var(--shadow);
}
.user-item.off { opacity: .55; }
.user-main { flex: 1; min-width: 190px; }
.user-name { font-weight: 600; }
.user-meta { font-size: var(--fs-md); color: var(--text-muted); }
.pw-result {
  background: var(--surface-sunken); border: 1px solid var(--border-strong);
  border-radius: 8px; padding: 12px 16px; font-size: var(--fs-md);
}
.pw-result code {
  font-size: var(--fs-xl); font-weight: 700; letter-spacing: .04em;
  background: var(--surface-2); padding: 3px 8px; border-radius: 6px; user-select: all;
}

@media print {
  body.printing-codes .app > *:not(main),
  body.printing-codes main > section:not(#view-settings),
  body.printing-codes #view-settings > *:not(#cardSecurity),
  body.printing-codes #cardSecurity > *:not(#tfaCodes),
  body.printing-codes #tfaCodes button { display: none !important; }
}

/* ---------- Pflichtfelder ---------- */
.req::after { content: " *"; color: var(--critical-ink); font-weight: 700; }
.form-hint { font-size: var(--fs-sm); color: var(--text-muted); margin: -8px 0 16px; }
.form-hint b { color: var(--critical-ink); }

/* ---------- Formular in Abschnitten ---------- */
.fs { border: 1px solid var(--border); border-radius: 12px; padding: 16px 16px 4px; margin-bottom: 16px; background: var(--surface-1); }
.fs > legend {
  font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); padding: 0 8px; margin-left: -8px;
}

/* ---------- Datum & Uhrzeit ---------- */
.when-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.when-row input[type=datetime-local] { flex: 1; min-width: 200px; }
.chipbtns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.chipbtn {
  border: 1px solid var(--border-strong); background: var(--surface-2); color: var(--text-secondary);
  border-radius: 999px; padding: 4px 12px; font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
}
.chipbtn:hover { background: var(--accent-soft); color: var(--accent-fg); border-color: var(--accent); }

/* ---------- Segment-Auswahl statt Dropdown ---------- */
.seg { display: flex; gap: 4px; flex-wrap: wrap; }
.seg input { position: absolute; opacity: 0; width: 0; height: 0; }
.seg label {
  border: 1px solid var(--border-strong); background: var(--surface-2);
  border-radius: 9px; padding: 8px 12px; font-size: var(--fs-md); font-weight: 600;
  cursor: pointer; color: var(--text-secondary); transition: all var(--dur-schnell) var(--easing); user-select: none;
}
.seg label:hover { border-color: var(--accent); }
.seg input:checked + label { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.seg input:focus-visible + label { box-shadow: 0 0 0 3px var(--accent-soft); }
.seg.prio input:checked + label[data-v="niedrig"] { background: var(--good); border-color: var(--good); color: #fff; }
.seg.prio input:checked + label[data-v="mittel"] { background: var(--warning); border-color: var(--warning); color: #3a2a00; }
.seg.prio input:checked + label[data-v="hoch"] { background: var(--serious); border-color: var(--serious); color: #3a1500; }
.seg.prio input:checked + label[data-v="kritisch"] { background: var(--critical); border-color: var(--critical); color: #fff; }

/* ---------- Verbindungsstatus ---------- */
.offline-bar {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 24px; z-index: 120;
  background: var(--critical); color: #fff; padding: 12px 16px; border-radius: 12px;
  font-size: var(--fs-md); font-weight: 600; box-shadow: var(--shadow); display: flex; gap: 12px; align-items: center;
}
.offline-bar button { border: 1px solid rgba(255,255,255,.5); background: transparent; color: #fff; border-radius: 7px; padding: 4px 12px; cursor: pointer; font-weight: 600; }

/* ---------- Ortsvorschläge (swisstopo) ---------- */
.sugwrap { position: relative; }
.suggest {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 40; margin-top: 4px;
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: 10px; box-shadow: var(--shadow); overflow: hidden; max-height: 260px; overflow-y: auto;
}
.suggest button {
  display: block; width: 100%; text-align: left; border: 0; background: transparent;
  padding: 8px 12px; font-size: var(--fs-lg); color: var(--text-primary); cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.suggest button:last-child { border-bottom: 0; }
.suggest button:hover, .suggest button:focus-visible { background: var(--accent-soft); color: var(--accent-fg); outline: none; }
.suggest b { color: var(--accent-fg); }

/* ---------- KI-Entwurf ---------- */
.ai-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.ai-row .muted { font-size: var(--fs-sm); }
.draft-box {
  /* Der Kasten sitzt im Abschnitt .fs, der ebenfalls 12px hat. Gleicher
     Radius innen wie aussen wirkt ineinandergeschoben – innen muss kleiner
     sein. */
  margin: 12px 0 4px; border: 1px solid var(--accent); border-radius: 10px;
  background: var(--accent-soft); padding: 16px;
}
.draft-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; margin-bottom: 8px; }
.draft-head b { color: var(--accent-fg); }
.draft-head .muted { font-size: var(--fs-sm); }
.draft-text {
  background: var(--surface-1); border: 1px solid var(--border-strong); border-radius: 9px;
  padding: 12px; font-size: var(--fs-lg); line-height: 1.6; white-space: pre-wrap;
  min-height: 90px; color: var(--text-primary);
}
.draft-text:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.draft-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.draft-warn {
  margin-top: 12px; font-size: var(--fs-sm); line-height: 1.5; color: var(--text-secondary);
  border-left: 2px solid var(--warning); padding-left: 12px;
}

/* ---------- Verpixeln / Schwärzen ---------- */
.blur-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.blur-canvas-wrap {
  border: 1px solid var(--border-strong); border-radius: 10px; background: var(--surface-2);
  padding: 8px; overflow: auto; max-height: 62vh; display: flex; justify-content: center;
}
.blur-canvas-wrap canvas {
  max-width: 100%; height: auto; cursor: crosshair; touch-action: none;
  /* Konzentrisch: 10 aussen − 8 Innenabstand = 2 innen. */
  border-radius: 2px; display: block;
}

/* ---------- Mehrfachauswahl ---------- */
.pick { display: flex; align-items: center; margin-right: 2px; cursor: pointer; position: relative; }
/* Das Kästchen misst 17px. Die Beschriftung fängt die Berührung auf
   44px ab – sichtbar bleibt alles gleich, der Griff wird nur grösser. */
.pick::before {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; min-width: 100%; min-height: 100%;
}
.pick input { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; margin: 0; }
.ritem.picked { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }

.sel-bar {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 24px; z-index: 110;
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  background: var(--surface-1); border: 1px solid var(--accent);
  border-radius: 12px; padding: 12px 16px; box-shadow: var(--shadow);
}
.sel-bar b { font-size: var(--fs-md); margin-right: 4px; white-space: nowrap; }
@media (max-width: 640px) { .sel-bar { left: 12px; right: 12px; transform: none; justify-content: center; } }

/* ---------- Sammel-Ausdruck ---------- */
#printArea { display: none; }
.print-cover h1 { font-size: var(--fs-2xl); margin: 0 0 6px; }
.print-note { font-size: var(--fs-md); color: var(--text-secondary); margin-top: 6px; }
.print-report h2 { font-size: var(--fs-xl); margin: 0 0 10px; }
.print-report h3 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); margin: 14px 0 4px; }

@media print {
  body.printing-selection .app,
  body.printing-selection #modalRoot,
  body.printing-selection .sel-bar,
  body.printing-selection .offline-bar { display: none !important; }
  body.printing-selection #printArea { display: block !important; }
  body.printing-selection .print-cover { padding-bottom: 14px; border-bottom: 2px solid #000; margin-bottom: 18px; }
  body.printing-selection .print-report { break-inside: auto; page-break-after: always; }
  body.printing-selection .print-report:last-child { page-break-after: auto; }
  body.printing-selection .print-report h2 { border-bottom: 1px solid #999; padding-bottom: 4px; }
  body.printing-selection .prose { white-space: pre-wrap; }
  body.printing-selection .entry { margin: 6px 0; font-size: var(--fs-md); }
  body.printing-selection .entry-text { white-space: pre-wrap; margin-top: 2px; }
}

/* ---------- Leistungsnachweis ---------- */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--luft-block); }
@media (max-width: 860px) { .grid-2 { grid-template-columns: 1fr; } }
.bars { margin-top: 4px; }
.rec-head h2 { margin-top: 0; }
.rec-seal .dl dd.ok { color: var(--good-ink); font-weight: 600; }
.rec-seal .dl dd.bad { color: var(--critical-ink); font-weight: 700; }
/* Die Prüfsumme steht jetzt vollständig da – alle 64 Zeichen statt der
   halben, mit der niemand prüfen konnte. Das hat eine Folge fürs Auge, die
   mitgelöst gehört: Als fettes, extragrosses Inline-Element brach der Wert
   auf einem schmalen Gerät über vier Zeilen um, und der gepolsterte
   Hintergrundkasten zerfiel dabei in ausgefranste Fragmente mit Rundung an
   jedem Stück.

   Darum ein eigener Block statt eines Inline-Kastens: ruhige Schrift statt
   Fettdruck (eine Prüfsumme ist ein Beleg, keine Schlagzeile), feste Breite
   in Zeichen, damit die Vierergruppen sauber untereinander stehen, und
   Ligaturen aus – sonst verschmilzt eine Schrift „ff“ oder „fi“ optisch,
   und wer von Hand vergleicht, verzählt sich genau dort. Dieselbe Haltung
   wie auf dem Papier (druck.css). */
.rec-seal code {
  display: block;
  width: 22ch;
  max-width: 100%;
  margin-top: 6px;
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: 1.7;
  letter-spacing: .04em;
  font-variant-ligatures: none;
  overflow-wrap: anywhere;
  background: var(--surface-2);
  padding: 8px 10px;
  border-radius: 8px;
  user-select: all;
}
.rec-oath {
  /* Zitatstrich wie überall: 2px in Randfarbe, kein Akzent – der Text ist
     eine nüchterne Erklärung, keine Hervorhebung. */
  margin-top: 16px; font-size: var(--fs-md); line-height: 1.6; color: var(--text-secondary);
  border-left: 2px solid var(--border); padding-left: 12px;
}
.rec-sign { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; margin-top: 32px; }
.rec-sign div { font-size: var(--fs-sm); color: var(--text-muted); }
.rec-sign span { display: block; border-bottom: 1px solid var(--text-muted); height: 34px; margin-bottom: 4px; }
@media (max-width: 640px) { .rec-sign { grid-template-columns: 1fr; gap: 24px; } }

@media print {
  body.printing-record .app > *:not(main),
  body.printing-record main > section:not(#view-record),
  body.printing-record #view-record .topbar-actions,
  body.printing-record #view-record > .card:first-of-type,
  body.printing-record .sel-bar,
  body.printing-record .offline-bar,
  body.printing-record #modalRoot { display: none !important; }
  body.printing-record .card { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; }
  body.printing-record .grid-2 { grid-template-columns: 1fr 1fr; }
  body.printing-record .rec-seal { break-before: auto; break-inside: avoid; }
}

/* Zweite Ebene über einem offenen Formular (z.B. Verpixeln) */
.overlay.stacked { z-index: 60; background: rgba(11,11,11,.55); }

/* ---------- Logo-Zeichen ---------- */
.brandmark { display: inline-flex; flex: none; }
.brandmark svg { width: 100%; height: 100%; display: block; }
.brand .brandmark { width: 27px; height: 27px; }
.auth-logo .brandmark { width: 32px; height: 32px; }

/* ---------- Farbwahl (Einstellungen) ---------- */
/* Begrenzte Breite: auf volle Spaltenbreite gezogen sah das Farbfeld aus
   wie ein Fortschrittsbalken, nicht wie ein Eingabefeld. */
input[type=color] { width: 96px; height: 40px; padding: 3px; border: 1px solid var(--border-strong); border-radius: 9px; background: var(--surface-2); cursor: pointer; }

/* ---------- Lizenz ---------- */
.lic-state { border-radius: 8px; padding: 12px 16px; font-size: var(--fs-lg); }
.lic-state.ok { background: color-mix(in srgb, var(--good) 12%, transparent); border: 1px solid color-mix(in srgb, var(--good) 40%, transparent); }
.lic-state.bad { background: color-mix(in srgb, var(--critical) 12%, transparent); border: 1px solid color-mix(in srgb, var(--critical) 45%, transparent); }
.lic-state div { margin-top: 4px; color: var(--text-secondary); font-size: var(--fs-md); }
.lic-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: var(--fs-lg); }
.lic-table th {
  text-align: left; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); border-bottom: 1px solid var(--border); padding: 8px 12px 8px 0;
}
.lic-table td { padding: 8px 12px 8px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.lic-table tr.current td { background: var(--accent-soft); }

/* ---------- Gruppen ---------- */
.team-item { border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; margin-bottom: 8px; }
.team-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.team-members { display: flex; gap: 8px; flex-wrap: wrap; }
.team-members .chip button {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  margin-left: 4px; padding: 0 2px; opacity: .6; font-size: var(--fs-sm); position: relative;
}
/* Kleinstes Ziel der Oberfläche – unsichtbar auf 44px gebracht, damit man
   ein Mitglied nicht dreimal antippen muss. */
.team-members .chip button::before {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; min-width: 100%; min-height: 100%;
}
.team-members .chip button:hover { opacity: 1; color: var(--critical-ink); }

/* ---------- Serverauswahl auf der Anmeldeseite ---------- */
.server-pick { border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; margin-bottom: 16px; }
.server-current { font-size: var(--fs-md); margin: 2px 0 8px; }
.server-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.server-list .btn { justify-content: flex-start; }
/* Die zwei Wege der Anmeldung optisch trennen: Firma und Privat. */
.server-weg { display: flex; flex-direction: column; gap: 8px; padding: 10px 0; }
.server-weg + .server-weg { border-top: 1px solid var(--border); }
.server-weg-kopf { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--text-secondary); font-weight: 600; }
.server-weg-privat { padding-top: 0; }

/* ---------- Wiederhergestellter Entwurf ---------- */
.draft-restore {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: 8px; padding: 12px 16px; margin-bottom: 16px;
}
.draft-restore .muted { font-size: var(--fs-sm); }

/* ---------- Firmenkopf auf dem Ausdruck ---------- */
.print-firma { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.print-mark { width: 34px; height: 34px; flex: none; }
.print-mark svg { width: 100%; height: 100%; display: block; }
.print-firma b { font-size: var(--fs-xl); }
.print-firma .muted { font-size: var(--fs-sm); }

/* ---------- KI-Verbrauch ---------- */
.ai-usage { border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; }
.ai-usage > div:first-child { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.ai-usage b { font-size: var(--fs-xl); }
.ai-usage .track { display: block; height: 8px; background: var(--surface-sunken); border-radius: 999px; overflow: hidden; }
.ai-usage .fill { display: block; height: 100%; border-radius: 999px; }
.user-role { width: auto; padding: 4px 8px; font-size: var(--fs-md); border-radius: 8px; }

/* ---------- Lizenzhinweis ---------- */
.lic-bar {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 24px; z-index: 105;
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap; max-width: min(760px, calc(100vw - 32px));
  background: var(--critical); color: #fff; padding: 12px 16px; border-radius: 12px; box-shadow: var(--shadow);
  font-size: var(--fs-md);
}
.lic-bar.mild { background: var(--warning); color: #3a2a00; }
.lic-bar span { opacity: .92; }
.lic-bar .btn { border-color: rgba(255,255,255,.55); background: transparent; color: inherit; }
.lic-bar .btn:hover { background: rgba(255,255,255,.16); }
@media print { .lic-bar { display: none !important; } }

/* ==================== Verkaufsseite ==================== */

.lp-nav { display: flex; gap: 16px; margin-left: auto; margin-right: 16px; }
.lp-nav a { color: var(--text-secondary); text-decoration: none; font-size: var(--fs-lg); font-weight: 400; }
.lp-nav a:hover { color: var(--accent-fg); }
@media (max-width: 900px) { .lp-nav { display: none; } }

.lp-eyebrow {
  display: inline-block; font-size: var(--fs-sm); font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--accent-fg); background: var(--accent-soft);
  padding: 4px 12px; border-radius: 999px; margin-bottom: 16px;
}

.lp-sec-head { max-width: 720px; margin: 0 auto 32px; text-align: center; }
.lp-sec-head h2 { font-size: var(--fs-display); margin-bottom: 8px; }
.lp-sec-head p { color: var(--text-secondary); font-size: var(--fs-xl); line-height: 1.65; margin: 0; }

.landing section { padding: clamp(48px, 7vw, 64px) clamp(16px, 5vw, 64px); }
.landing section.lp-hero { padding-top: clamp(32px, 5vw, 64px); padding-bottom: clamp(32px, 6vw, 64px); }

/* ---------- Beweisteil der Startseite ---------- */
/* Bewusst ohne eigene Kartengestaltung: Der Abschnitt benutzt .lp-feat-grid und
   .lp-feat, damit er dieselbe Breite, dieselben Abstände und dieselbe
   Einblendung bekommt wie die Funktionskarten – app.js beobachtet genau diese
   Klassen. Hier steht nur, was dort fehlt: die Bahn und die zentrierte Taste. */
.lp-beweis { max-width: 1240px; margin: 0 auto; }
.lp-beweis-aktion { justify-content: center; margin-top: 32px; }

/* ---------- Video ---------- */
.lp-video-wrap {
  position: relative; max-width: 980px; margin: 0 auto;
  border-radius: 16px; overflow: hidden; background: #0b0b0b;
  box-shadow: 0 20px 60px rgba(11,11,11,.22); aspect-ratio: 16 / 10;
}
.lp-video-wrap video { width: 100%; height: 100%; object-fit: cover; display: block; cursor: pointer; }
.lp-video-play {
  position: absolute; inset: 0; margin: auto; width: 78px; height: 78px;
  border: 0; border-radius: 50%; background: rgba(255,255,255,.94); color: #111;
  cursor: pointer; display: grid; place-items: center; box-shadow: 0 8px 30px rgba(0,0,0,.35);
  transition: transform var(--dur-schnell) var(--easing);
}
.lp-video-play:hover { transform: scale(1.07); }
/* HIDDEN MUSS GEWINNEN.
   Der Knopf trägt display:grid. Das Attribut hidden setzt im Browser nur
   display:none mit der schwächsten Spezifität – die Regel darüber schlägt es.
   promo.js setzte also brav start.hidden = true, und der weisse Kreis blieb
   trotzdem 43 Sekunden lang mitten im laufenden Video stehen. */
.lp-video-play[hidden] { display: none; }
.lp-video-play svg { width: 34px; height: 34px; margin-left: 4px; }
.lp-video-cc {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 32px 24px 16px;
  background: linear-gradient(transparent, rgba(0,0,0,.82));
  color: #fff; font-size: var(--fs-lg); line-height: 1.5; pointer-events: none;
}
.lp-video-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; max-width: 980px; margin: 16px auto 0;
}
.lp-vstep {
  text-align: left; border: 1px solid var(--border); background: var(--surface-2);
  border-radius: 11px; padding: 12px; cursor: pointer; transition: all var(--dur-schnell) var(--easing);
  display: flex; flex-direction: column; gap: 4px;
}
.lp-vstep:hover { border-color: var(--accent); }
.lp-vstep.active { border-color: var(--accent); background: var(--accent-soft); }
.lp-vstep b { font-size: var(--fs-md); }
.lp-vstep span { font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.45; }

/* ---------- Funktionen ---------- */
.lp-feat-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px; max-width: 1100px; margin: 0 auto;
}
@media (min-width: 1150px) { .lp-feat-grid { grid-template-columns: repeat(3, 1fr); } }
.lp-feat {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px;
}
.lp-feat-ic {
  display: grid; place-items: center; width: 42px; height: 42px; margin-bottom: 16px;
  border-radius: 11px; background: var(--accent-soft); color: var(--accent-fg);
}
.lp-feat-ic svg { width: 22px; height: 22px; }
.lp-feat:hover .lp-feat-ic { background: var(--accent); color: var(--accent-ink); }
.lp-feat { transition: border-color var(--dur-schnell) var(--easing), transform var(--dur-schnell) var(--easing); }
.lp-feat:hover { border-color: var(--accent); transform: translateY(-2px); }
.lp-feat h3 { font-size: var(--fs-xl); margin-bottom: 8px; }
.lp-feat p { color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.62; margin: 0; }
.lp-feat code { font-size: var(--fs-md); background: var(--surface-sunken); padding: 1px 5px; border-radius: 4px; }

/* ---------- Sicherheit ---------- */
.lp-sec-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: 16px; max-width: 1160px; margin: 0 auto;
}
/* Ohne Akzentkante links: die Karten stehen gleichwertig nebeneinander,
   eine Dauer-Hervorhebung an jeder Karte hebt nichts mehr hervor. */
.lp-sec-card {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px;
}
.lp-sec-card h3 { font-size: var(--fs-xl); margin-bottom: 12px; }
.lp-sec-card ul { margin: 0; padding-left: 16px; }
.lp-sec-card li { color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.6; margin-bottom: 8px; }
.lp-sec-card code { font-size: var(--fs-md); background: var(--surface-sunken); padding: 1px 5px; border-radius: 4px; }
.lp-honest {
  max-width: 860px; margin: 32px auto 0; padding: 16px 24px;
  border: 1px dashed var(--border-strong); border-radius: 12px;
  color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.65;
}
.lp-honest b { color: var(--text-primary); }

/* ---------- Betriebsarten ---------- */
.lp-host-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px; max-width: 1160px; margin: 0 auto; align-items: start;
}
.lp-host {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px;
}
.lp-host.featured {
  border-color: var(--accent); border-width: 2px;
  box-shadow: 0 10px 34px color-mix(in srgb, var(--accent) 16%, transparent);
}
.lp-host-badge {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent-fg); margin-bottom: 8px;
}
.lp-host h3 { font-size: var(--fs-xl); margin-bottom: 8px; }
.lp-host p { color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.62; margin: 0 0 16px; }
.lp-host ul { margin: 0; padding-left: 16px; }
.lp-host li { font-size: var(--fs-md); line-height: 1.55; margin-bottom: 8px; color: var(--text-secondary); }

/* ---------- Erscheinungsbild ---------- */
.lp-brand-demo {
  display: grid; grid-template-columns: 300px 1fr; gap: 24px;
  max-width: 1000px; margin: 0 auto; align-items: start;
}
@media (max-width: 800px) { .lp-brand-demo { grid-template-columns: 1fr; } }
.lp-brand-picker { display: flex; flex-direction: column; gap: 8px; }
.lp-brand-pick {
  display: flex; align-items: center; gap: 12px; text-align: left; cursor: pointer;
  border: 1px solid var(--border-strong); background: var(--surface-2);
  border-radius: 11px; padding: 8px 12px; font-weight: 600; font-size: var(--fs-lg);
  transition: all var(--dur-schnell) var(--easing);
}
.lp-brand-pick:hover { border-color: var(--b); }
.lp-brand-pick.active { border-color: var(--b); background: var(--bs); color: #111; }
.lp-brand-pick-mark { width: 28px; height: 28px; flex: none; }
.lp-brand-pick-mark svg { width: 100%; height: 100%; display: block; }

.lp-brand-preview {
  border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  background: var(--surface-2); box-shadow: var(--shadow);
}
.lp-prev-head {
  display: flex; align-items: center; gap: 12px;
  background: var(--b); color: #fff; padding: 16px;
}
.lp-prev-mark { width: 34px; height: 34px; flex: none; filter: brightness(0) invert(1); }
.lp-prev-mark svg { width: 100%; height: 100%; display: block; }
.lp-prev-head b { font-size: var(--fs-xl); }
.lp-prev-tag { font-size: var(--fs-sm); opacity: .85; }
.lp-prev-body { padding: 16px; }
.lp-prev-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.lp-prev-chip {
  font-family: ui-monospace, monospace; font-size: var(--fs-xs); background: var(--bs);
  color: #111; padding: 2px 8px; border-radius: 999px;
}
.lp-prev-meta { font-size: var(--fs-md); color: var(--text-muted); margin-bottom: 16px; }
.lp-prev-bar { height: 8px; background: var(--surface-sunken); border-radius: 999px; overflow: hidden; margin-bottom: 16px; }
.lp-prev-bar span { display: block; height: 100%; background: var(--b); border-radius: 999px; }
.lp-prev-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.lp-prev-btn {
  font-size: var(--fs-md); font-weight: 600; padding: 8px 12px; border-radius: 9px;
  border: 1px solid var(--border-strong); color: var(--text-secondary);
}
.lp-prev-btn.primary { background: var(--b); border-color: var(--b); color: #fff; }
.lp-brand-note { text-align: center; max-width: 720px; margin: 24px auto 0; }

/* ---------- Preise ---------- */
.lp-price-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 16px; max-width: 1180px; margin: 0 auto; align-items: stretch;
}
.lp-price {
  position: relative; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 14px; padding: 24px; display: flex; flex-direction: column;
}
.lp-price.featured { border-color: var(--accent); border-width: 2px; }
.lp-price.test { background: var(--accent-soft); border-color: var(--accent); }
.lp-price-badge {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: var(--accent-ink); font-size: var(--fs-xs); font-weight: 700;
  padding: 3px 12px; border-radius: 999px; white-space: nowrap;
}
.lp-price h3 { font-size: var(--fs-xl); margin-bottom: 8px; }
.lp-price-amount { font-size: var(--fs-display); font-weight: 700; letter-spacing: -.02em; }
.lp-price-amount small { font-size: var(--fs-md); font-weight: 400; color: var(--text-muted); }
.lp-price-sub { font-size: var(--fs-md); color: var(--text-muted); margin-bottom: 12px; }
.lp-price ul { margin: 0 0 16px; padding-left: 16px; flex: 1; }
.lp-price li { font-size: var(--fs-md); line-height: 1.55; margin-bottom: 8px; color: var(--text-secondary); }
.lp-price .btn { width: 100%; }
.lp-price-note { max-width: 860px; margin: 32px auto 0; text-align: center; }
.lp-price-note p { font-size: var(--fs-lg); line-height: 1.65; color: var(--text-secondary); }

/* ---------- Abschluss ---------- */
.lp-cta-final {
  text-align: center; background: var(--accent) !important; color: var(--accent-ink);
}
.lp-cta-final h2 { font-size: var(--fs-display); margin-bottom: 8px; }
.lp-cta-final p { opacity: .92; margin: 0 0 24px; font-size: var(--fs-xl); }
.lp-cta-final .lp-actions { justify-content: center; }
/* Der Knopf steht hier auf WEISS, nicht auf dunklem Grund. --accent-fg ist die
   aufgehellte Fassung für dunkle Flächen und ergab auf Weiss gemessene 1.85:1 –
   der wichtigste Knopf der Seite war praktisch unlesbar, während der zweitrangige
   daneben wie der Hauptknopf wirkte. --accent ist der satte Ton und gehört hierher. */
.lp-cta-final .btn.primary { background: #fff; border-color: #fff; color: var(--accent); font-weight: 600; }
.lp-cta-final .btn.primary:hover { background: #fff; border-color: #fff; filter: brightness(.96); }
.lp-cta-final .ghost-invert { background: transparent; border-color: rgba(255,255,255,.6); color: #fff; }
.lp-cta-final .ghost-invert:hover { background: rgba(255,255,255,.14); }

.lp-install-actions { justify-content: center; margin-top: 24px; }
.lp-foot { display: flex; gap: 16px; justify-content: space-between; flex-wrap: wrap; }
.lp-foot-links { display: flex; gap: 16px; }

/* ---------- Nur auf dem Handy sichtbar ---------- */
/* Schwelle 860 wie die App-Schale (nicht 820 wie die Startseite): vorher gab
   es ein totes Band 821–860, in dem die Seitenleiste schon zur Fussleiste
   geworden war, die Karte "Weitere Bereiche" aber noch fehlte – Vorlagen und
   Nachweis waren dort unerreichbar. */
.nur-handy { display: none; }
@media (max-width: 860px) { .nur-handy { display: block; } }
.mehr-links { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.mehr-links .btn { flex: 1; min-width: 130px; justify-content: flex-start; }

/* ==================== Bühne: weiche Verläufe ==================== */
.landing { position: relative; overflow-x: clip; }
.lp-glow { position: absolute; inset: 0 0 auto 0; height: 1200px; pointer-events: none; z-index: 0; overflow: hidden; }
.lp-blob { position: absolute; border-radius: 50%; filter: blur(90px); opacity: .5; }
.lp-blob.a {
  width: 640px; height: 640px; right: -140px; top: -220px;
  background: radial-gradient(circle at 40% 40%, var(--accent), transparent 68%);
  animation: schweben 22s ease-in-out infinite;
}
.lp-blob.b {
  width: 520px; height: 520px; left: -180px; top: 180px;
  background: radial-gradient(circle at 60% 40%, color-mix(in srgb, var(--accent) 70%, #3b82f6), transparent 66%);
  opacity: .34; animation: schweben 28s ease-in-out infinite reverse;
}
.lp-blob.c {
  width: 700px; height: 460px; left: 42%; top: 620px;
  background: radial-gradient(ellipse at 50% 50%, color-mix(in srgb, var(--accent) 55%, #ec4899), transparent 70%);
  opacity: .22; animation: schweben 34s ease-in-out infinite;
}
@keyframes schweben {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  33% { transform: translate3d(-40px, 36px, 0) scale(1.08); }
  66% { transform: translate3d(34px, -26px, 0) scale(.95); }
}
.landing > header, .landing > section, .landing > footer { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) { .lp-blob { animation: none; } }

/* Sektionen bekommen keinen harten Farbwechsel, sondern eine weiche Kante */
.landing section.lp-security, .landing section.lp-pricing {
  background: color-mix(in srgb, var(--surface-1) 82%, transparent);
  backdrop-filter: blur(6px);
}

/* ==================== Logo, das hereinfliegt ==================== */
.lp-brand svg { overflow: visible; }
.lp-brand .mk-schild {
  transform-origin: 256px 256px;
  animation: mk-flug .9s cubic-bezier(.2,.9,.25,1.05) both;
}
.lp-brand .mk-rand {
  stroke-dasharray: 1200; stroke-dashoffset: 1200;
  animation: mk-zeichnen 1.1s ease-out .25s both;
}
.lp-brand .mk-z {
  transform-origin: 256px 244px;
  animation: mk-z-rein .6s cubic-bezier(.2,.9,.25,1.05) .5s both;
}
.lp-brand b { animation: mk-text .7s ease-out .55s both; display: inline-block; }
@keyframes mk-flug {
  from { transform: translateY(-38px) rotate(-16deg) scale(.55); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes mk-zeichnen { to { stroke-dashoffset: 0; } }
@keyframes mk-z-rein {
  from { transform: scale(.3) translateY(20px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@keyframes mk-text {
  from { transform: translateX(-14px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .lp-brand .mk-schild, .lp-brand .mk-rand, .lp-brand .mk-z, .lp-brand b { animation: none; stroke-dashoffset: 0; }
}

/* Überschrift zeilenweise aufziehen */
.lp-hero h1 .zeile { display: inline-block; animation: zeile-rein .8s cubic-bezier(.2,.9,.25,1) both; }
.lp-hero h1 .z1 { animation-delay: .18s; }
.lp-hero h1 .z2 { animation-delay: .3s; color: var(--accent-fg); }
.lp-hero .lp-lead { animation: zeile-rein .8s ease-out .42s both; }
.lp-hero .lp-actions { animation: zeile-rein .8s ease-out .54s both; }
.lp-hero .lp-eyebrow { animation: zeile-rein .7s ease-out .08s both; }
@keyframes zeile-rein {
  from { transform: translateY(18px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .lp-hero h1 .zeile, .lp-hero .lp-lead, .lp-hero .lp-actions, .lp-hero .lp-eyebrow { animation: none; }
}

/* ==================== Aufnahmen im Hero ==================== */
.lp-stack { position: relative; animation: stapel-rein 1s cubic-bezier(.2,.9,.25,1) .35s both; }
@keyframes stapel-rein {
  from { transform: translateY(34px) scale(.96); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.lp-stack-back {
  width: 100%; height: auto; display: block; border-radius: 14px;
  border: 1px solid var(--border); box-shadow: 0 30px 70px rgba(11,11,11,.28);
}
:root[data-theme="dark"] .lp-stack-back { box-shadow: 0 30px 70px rgba(0,0,0,.6); }
.lp-stack .lp-phone {
  position: absolute; right: -26px; bottom: -34px; width: 172px;
  background: #0b0b0f; border: 6px solid #1b1b22; border-radius: 24px;
  padding: 0; overflow: hidden; box-shadow: 0 24px 50px rgba(11,11,11,.4);
}
.lp-stack .lp-phone img { width: 100%; height: auto; display: block; }
.lp-phone-notch {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 62px; height: 15px; background: #1b1b22; border-radius: 0 0 10px 10px; z-index: 2;
}

/* ==================== Funktionsbühne ==================== */
.lp-stage { max-width: 1240px; margin: 0 auto; }
.lp-stage-row {
  display: grid; grid-template-columns: minmax(280px, 400px) 1fr;
  gap: clamp(16px, 4vw, 48px); align-items: center;
  margin-bottom: clamp(48px, 7vw, 64px);
}
.lp-stage-row.kehr { grid-template-columns: 1fr minmax(280px, 400px); }
.lp-stage-row.kehr .lp-stage-card { order: 2; }
.lp-stage-row.kehr .lp-stage-bild { order: 1; }
.lp-stage-row:last-child { margin-bottom: 0; }

.lp-stage-card {
  background: color-mix(in srgb, var(--surface-2) 88%, transparent);
  border: 1px solid var(--border); border-radius: 16px;
  padding: 24px; backdrop-filter: blur(8px);
}
.lp-tag {
  display: inline-block; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent-fg); background: var(--accent-soft);
  padding: 4px 12px; border-radius: 999px; margin-bottom: 12px;
}
.lp-stage-card h3 { font-size: var(--fs-2xl); margin-bottom: 12px; letter-spacing: -.015em; }
.lp-stage-card p { color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.68; margin: 0; }
.lp-stage-card code { font-size: var(--fs-md); background: var(--surface-sunken); padding: 1px 6px; border-radius: 5px; }

.lp-stage-bild { margin: 0; position: relative; }
.lp-stage-bild::after {
  content: ""; position: absolute; inset: 10% 6%; z-index: -1; border-radius: 50%;
  background: radial-gradient(ellipse, var(--accent), transparent 66%);
  filter: blur(60px); opacity: .3;
}
.lp-stage-bild img {
  width: 100%; height: auto; display: block; border-radius: 14px;
  border: 1px solid var(--border); box-shadow: 0 24px 60px rgba(11,11,11,.24);
  transition: transform var(--dur-ruhig) var(--easing);
}
:root[data-theme="dark"] .lp-stage-bild img { box-shadow: 0 24px 60px rgba(0,0,0,.55); }
.lp-stage-row:hover .lp-stage-bild img { transform: translateY(-5px) scale(1.012); }

@media (max-width: 900px) {
  .lp-stage-row, .lp-stage-row.kehr { grid-template-columns: 1fr; gap: 16px; }
  .lp-stage-row.kehr .lp-stage-card { order: 1; }
  .lp-stage-row.kehr .lp-stage-bild { order: 2; }
  .lp-stage-card { padding: 16px; }
  .lp-stage-card h3 { font-size: var(--fs-xl); }
}

/* Beim Hereinscrollen sanft einblenden.
   Wichtig: Das Verstecken hängt an .anim-bereit, das erst per JavaScript
   gesetzt wird. Bleibt JavaScript stehen, ist die Seite trotzdem lesbar –
   sie animiert dann einfach nicht. */
body.anim-bereit .lp-stage-row,
body.anim-bereit .lp-feat,
body.anim-bereit .lp-sec-card,
body.anim-bereit .lp-host,
body.anim-bereit .lp-price {
  opacity: 0; transform: translateY(22px);
  transition: opacity var(--dur-ruhig) var(--easing), transform var(--dur-ruhig) var(--easing);
}
body.anim-bereit .sichtbar { opacity: 1 !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
  body.anim-bereit .lp-stage-row, body.anim-bereit .lp-feat, body.anim-bereit .lp-sec-card,
  body.anim-bereit .lp-host, body.anim-bereit .lp-price { opacity: 1; transform: none; transition: none; }
}
/* Hochformat-Aufnahmen (der Formulardialog) nicht auf volle Breite ziehen */
.lp-stage-bild.hoch { display: flex; justify-content: center; }
.lp-stage-bild.hoch img { max-width: 460px; }
@media (max-width: 900px) { .lp-stage-bild.hoch img { max-width: 340px; } }

/* ==================== Mehrseitige Startseite ==================== */
.lp-main { position: relative; z-index: 1; }
.lp-page { animation: seite-rein .35s ease-out both; }
@keyframes seite-rein { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .lp-page { animation: none; } }

.lp-head .lp-brand { text-decoration: none; color: inherit; }
.lp-nav a.aktiv { color: var(--accent-fg); font-weight: 600; }
.lp-nav a { position: relative; padding: 4px 0; }
.lp-nav a.aktiv::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 2px; background: var(--accent); border-radius: 2px;
}
.lp-menu { display: none; padding: 8px 12px; }
.lp-menu svg { width: 20px; height: 20px; }

/* Kontakt als reiner Icon-Knopf in der Kopfzeile: quadratisch, gleiche Hoehe
   wie der Anmelden-Knopf daneben, nur ohne Text. */
.lp-kontakt { display: inline-flex; align-items: center; justify-content: center; padding: 9px 11px; margin-right: 8px; }
.lp-kontakt svg { width: 20px; height: 20px; display: block; }
/* Zweite Fusszeilen-Reihe (Rechtliches) etwas leiser und mit feiner Trennlinie
   von der Produktnavigation darueber abgesetzt. */
.lp-foot-recht { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); opacity: .85; }

.lp-seitenkopf {
  max-width: 900px; margin: 0 auto; text-align: center;
  padding: clamp(32px, 5vw, 48px) clamp(16px, 5vw, 64px) 0;
}
.lp-seitenkopf h1 {
  font-size: var(--fs-hero); letter-spacing: -.028em;
  margin: 16px 0 12px; line-height: 1.12;
}
.lp-seitenkopf p { color: var(--text-secondary); font-size: var(--fs-xl); line-height: 1.65; margin: 0; }
.lp-zurueck {
  display: inline-block; font-size: var(--fs-md); font-weight: 600;
  color: var(--text-muted); text-decoration: none;
}
.lp-zurueck:hover { color: var(--accent-fg); }

/* ---------- Wegweiser auf der Startseite ---------- */
.lp-teaser-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px; max-width: 1100px; margin: 0 auto;
}
.lp-teaser-karte {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: color-mix(in srgb, var(--surface-2) 88%, transparent);
  border: 1px solid var(--border); border-radius: 15px; padding: 24px;
  transition: border-color var(--dur-schnell) var(--easing), transform var(--dur-schnell) var(--easing); backdrop-filter: blur(8px);
}
.lp-teaser-karte:hover { border-color: var(--accent); transform: translateY(-3px); }
.lp-teaser-ic {
  display: grid; place-items: center; width: 42px; height: 42px; margin-bottom: 16px;
  border-radius: 11px; background: var(--accent-soft); color: var(--accent-fg);
}
.lp-teaser-ic svg { width: 22px; height: 22px; }
.lp-teaser-karte h3 { font-size: var(--fs-xl); margin-bottom: 8px; }
.lp-teaser-karte p { color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.6; margin: 0 0 16px; flex: 1; }
.lp-teaser-mehr { font-size: var(--fs-md); font-weight: 600; color: var(--accent-fg); }

/* ---------- Handy ---------- */
@media (max-width: 900px) {
  .lp-menu { display: inline-flex; }
  /* Marke, Menü und Anmelden bleiben in einer Zeile – sonst rutscht
     der Anmelden-Knopf auf eine zweite und der Kopf wird doppelt hoch. */
  .lp-head { position: relative; flex-wrap: wrap; align-items: center; gap: 12px; }
  .lp-nav {
    display: none; order: 9; width: 100%; flex-direction: column; gap: 0;
    margin: 8px 0 0; border-top: 1px solid var(--border);
  }
  .lp-nav.offen { display: flex; }
  .lp-nav a { padding: 12px 2px; border-bottom: 1px solid var(--border); font-size: var(--fs-lg); }
  .lp-nav a.aktiv::after { display: none; }
  .lp-head .lp-brand { flex: 1; min-width: 0; }
  .lp-head .lp-brand b { font-size: var(--fs-lg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .lp-anmelden { padding: 8px 12px; font-size: var(--fs-lg); }
  .lp-eyebrow { font-size: var(--fs-xs); letter-spacing: .07em; }

  /* Zuerst die Botschaft, dann das Bild – nicht umgekehrt */
  .lp-hero { grid-template-columns: 1fr; }
  .lp-shot { order: 2; }
  .lp-hero-text { order: 1; }
  .lp-actions .btn { flex: 1; justify-content: center; }
  .lp-stack { max-width: 460px; margin: 0 auto; }
  .lp-stack .lp-phone { right: -6px; bottom: -14px; width: 92px; }
  .lp-foot-links { flex-wrap: wrap; gap: 12px 16px; }
}
@media (max-width: 470px) {
  /* Lieber nur das Zeichen als ein abgeschnittener Name */
  .lp-head .lp-brand b { display: none; }
  .lp-head .lp-brand { flex: 0 0 auto; }
  .lp-head { justify-content: flex-start; }
  .lp-anmelden { margin-left: auto; }
}

@media (max-width: 560px) {
  /* Auf kleinen Geräten ist das Bildschirmfoto ohnehin nicht lesbar –
     dann lieber nur das Handy zeigen, sauber mittig. */
  .lp-stack-back { display: none; }
  .lp-stack { max-width: 210px; }
  .lp-stack .lp-phone { position: static; width: 100%; margin: 0 auto; }
  .lp-video-steps { grid-template-columns: 1fr 1fr; }
  .lp-vstep span { display: none; }
}

/* ---------- Unterlagen ---------- */
.doc-pflicht {
  display: flex; flex-direction: column; gap: 4px;
  background: color-mix(in srgb, var(--warning) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 55%, transparent);
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: 16px;
}
.doc-pflicht span { font-size: var(--fs-md); color: var(--text-secondary); }
.doc-gruppe { margin-bottom: 24px; }
.doc-gruppe h3 {
  font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-muted); margin-bottom: 8px;
}
.doc-item {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: 8px; box-shadow: var(--shadow);
}
.doc-item.alt { opacity: .62; border-style: dashed; box-shadow: none; }
.doc-ic {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center;
  border-radius: 10px; background: var(--accent-soft); color: var(--accent-fg);
}
.doc-ic svg { width: 20px; height: 20px; }
.doc-body { flex: 1; min-width: 0; }
.doc-kopf { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.doc-kopf b { font-size: var(--fs-lg); }
.doc-note { font-size: var(--fs-md); color: var(--text-secondary); margin-bottom: 4px; line-height: 1.5; }
.doc-meta { font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.5; }
.doc-tasten { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; }

/* ---- Datei-Explorer (Unterlagen) -------------------------------------
   Objekte sind Ordner, Unterlagen die Dateien darin. Ein Motiv, ein
   Rasterschritt, eine Kantenfarbe - "aus einem Guss". Tiefe kommt aus der
   Flaeche und einer Haarlinie, nicht aus Schlagschatten. */
.dx-raster { display: grid; gap: 12px; }
.dx-ordner-raster { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.dx-datei-raster { grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }

.dx-ordner {
  position: relative; text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: 4px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 16px 16px 14px;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.dx-ordner:hover { border-color: var(--accent); transform: translateY(-1px); }
.dx-ordner:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dx-name { font-size: var(--fs-lg); font-weight: 580; color: var(--text-primary); }
.dx-unter { font-size: var(--fs-sm); color: var(--text-muted); }
.dx-badge {
  position: absolute; top: 12px; right: 12px; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 999px; background: var(--accent); color: var(--accent-ink);
  font-size: var(--fs-xs); font-weight: 600; display: grid; place-items: center;
}

.dx-ic { flex: none; display: grid; place-items: center; }
.dx-ic svg { width: 26px; height: 26px; display: block; }
.dx-ic-ordner { color: #d0a24e; }
.dx-ic-ordner svg { width: 30px; height: 30px; }
.dx-ic-klein svg { width: 18px; height: 18px; }
.dx-ic-pdf { color: #cf6a5a; }
.dx-ic-bild { color: #5aa17f; }
.dx-ic-wort { color: #5b82c4; }
.dx-ic-tabelle { color: #5fa35f; }
.dx-ic-text, .dx-ic-datei { color: var(--text-secondary); }

.dx-datei {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px 16px;
  transition: border-color .15s ease, transform .15s ease;
}
.dx-datei:hover { border-color: var(--accent); transform: translateY(-1px); }
.dx-datei.alt { opacity: .6; border-style: dashed; }
.dx-datei-ober { display: flex; gap: 12px; align-items: flex-start; }
.dx-datei-ober .dx-ic {
  width: 44px; height: 44px; border-radius: 10px; background: var(--surface-0);
  border: 1px solid var(--border);
}
.dx-datei-titel { flex: 1; min-width: 0; }
.dx-datei-titel b {
  display: block; font-size: var(--fs-lg); line-height: 1.3; margin-bottom: 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dx-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.dx-note { font-size: var(--fs-md); color: var(--text-secondary); line-height: 1.5; }
.dx-meta { font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.5; }
.dx-tasten { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }

.dx-pfad {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px; font-size: var(--fs-lg);
}
.dx-pfad b { font-weight: 580; }
.dx-sep { color: var(--text-muted); }
.dx-zurueck {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
  background: none; border: none; color: var(--text-secondary);
  font-size: var(--fs-md); padding: 4px 6px; border-radius: 6px;
}
.dx-zurueck:hover { color: var(--accent-fg); background: var(--accent-soft); }
.dx-zurueck svg { width: 16px; height: 16px; }
@media (max-width: 560px) { .dx-datei-raster, .dx-ordner-raster { grid-template-columns: 1fr; } }

/* Hinweiskasten: Fläche trägt die Betonung, keine Akzentkante. */
.doc-hinweis {
  background: var(--accent-soft);
  border-radius: 8px; padding: 12px 16px; margin-bottom: 16px;
  font-size: var(--fs-md); line-height: 1.55; color: var(--text-secondary);
}
.leser { margin: 8px 0 0; padding-left: 16px; font-size: var(--fs-lg); }
.leser li { margin-bottom: 4px; }
.leser .muted { font-size: var(--fs-sm); margin-left: 8px; }
@media (max-width: 820px) {
  .doc-item { flex-wrap: wrap; }
  .doc-tasten { width: 100%; }
  .doc-tasten .btn { flex: 1; min-width: 110px; justify-content: center; }
}
/* Gegenstück zu .nur-handy. Bisher fehlte die Einblendung ganz – der
   "Unterlagen"-Knopf in "Weitere Bereiche" war nirgends sichtbar. */
.nur-desktop { display: none; }
@media (min-width: 861px) { .nur-desktop { display: inline-flex; } }

/* ---------- Zugewiesene Dienste ---------- */
.shift-tasten { display: flex; gap: 8px; flex-wrap: wrap; }
.shift-note {
  font-size: var(--fs-md); color: var(--text-secondary); margin-top: 4px;
  border-left: 2px solid var(--border); padding-left: 12px;
}
.shift-title .chip { margin-left: 8px; font-size: var(--fs-xs); }
@media (max-width: 820px) {
  .shift { flex-wrap: wrap; }
  .shift-tasten { width: 100%; margin-top: 8px; }
  .shift-tasten .btn { flex: 1; min-width: 110px; justify-content: center; }
}

/* ---------- Dienstplan einlesen ---------- */
.im-vorlage {
  background: var(--surface-sunken); border-radius: 8px; padding: 12px 16px;
  margin-bottom: 16px; font-size: var(--fs-md); line-height: 1.7;
}
.im-vorlage code { background: var(--surface-2); padding: 2px 7px; border-radius: 5px; font-size: var(--fs-sm); }
.im-vorlage .muted { font-size: var(--fs-sm); margin-top: 4px; }
.im-ergebnis { border-radius: 8px; padding: 12px 16px; margin-top: 16px; font-size: var(--fs-lg); }
.im-ergebnis.gut { background: color-mix(in srgb, var(--good) 13%, transparent); border: 1px solid color-mix(in srgb, var(--good) 45%, transparent); }
.im-ergebnis.schlecht { background: color-mix(in srgb, var(--critical) 12%, transparent); border: 1px solid color-mix(in srgb, var(--critical) 45%, transparent); }
.im-ergebnis div { margin-top: 4px; font-size: var(--fs-md); color: var(--text-secondary); }
.im-fehler { margin: 12px 0 0; padding-left: 16px; font-size: var(--fs-md); }
.im-fehler li { margin-bottom: 8px; }
.im-fehler .muted { font-size: var(--fs-sm); font-family: ui-monospace, monospace; }

/* ---------- Fokus sichtbar ---------- */
/* Bisher gab es nur Einzelfälle (Eingabefelder, Vorschlagsliste, Segmente);
   alles andere hängt am Systemring des Browsers, der auf dunklem Grund fast
   verschwindet. :where() hält das Gewicht bei null, damit die vorhandenen
   Sonderregeln weiter vorgehen. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent-fg);
  outline-offset: 2px;
}
/* Der Ring liegt ausserhalb des Elements. Wo das Umfeld gefüllt ist, ginge
   Violett auf Rot oder Violett unter – dort weiss. */
.offline-bar button:focus-visible,
.lic-bar .btn:focus-visible,
.lp-cta-final .btn:focus-visible {
  outline-color: #fff;
}

/* ---------- Weniger Bewegung ---------- */
/* Wer im Betriebssystem "Bewegung reduzieren" gesetzt hat, bekam bisher nur
   auf der Startseite Ruhe. Ab hier gilt das für die ganze Oberfläche.
   Der Block steht bewusst am Schluss, damit er alles Vorherige übersteuert. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  /* Ausnahme: reines Ein- und Ausblenden bleibt. Eine Blende schiebt nichts
     über den Bildschirm und ist darum unbedenklich – sie ist aber oft der
     einzige Hinweis darauf, dass sich ein Zustand geändert hat. Alles
     andere (Verschieben, Skalieren, Farbwechsel) fällt aus der Liste der
     übergebenen Eigenschaften und springt sofort. */
  *, *::before, *::after {
    transition-property: opacity !important;
    transition-duration: var(--dur-schnell) !important;
  }
}

/* ---------- Prüfkette ---------- */
/* Der Beweisteil bekommt bewusst eine eigene, ruhige Sprache: keine Farbe
   ausser dem Zustand, Prüfsummen immer im gleichen Schnitt und in Vierergruppen.
   Wer zwei Summen vergleicht, soll das ohne Lupe können. */
.chain-state { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.chain-state .muted { font-size: var(--fs-md); }
.chain-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.chain-hint { font-size: var(--fs-sm); line-height: 1.5; margin: 0; }

.siegel {
  border: 1px solid var(--border-strong); border-radius: 8px; padding: 16px;
  background: var(--surface-1); margin-bottom: 16px;
}
.siegel-kopf {
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 1px solid var(--border); padding-bottom: 8px; margin-bottom: 12px;
}
.siegel-summe { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 8px; }
.siegel-summe .muted { font-size: var(--fs-xs); margin-bottom: 4px; }
.siegel-summe code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-sm); line-height: 1.7; word-spacing: .1em; overflow-wrap: anywhere;
  display: block; color: var(--text-primary);
}

.protokoll-auf { cursor: pointer; font-weight: 600; font-size: var(--fs-lg); }
.protokoll { list-style: none; margin: 0; padding: 0; }
.protokoll li {
  border-left: 2px solid var(--border); padding: 8px 0 8px 12px; margin-left: 4px;
}
/* Akzent nur am jüngsten Eintrag: markiert die Spitze der Kette, also den
   Stand, gegen den die nächste Prüfsumme rechnet – Information, kein Schmuck. */
.protokoll li:last-child { border-left-color: var(--accent); }
.protokoll-kopf { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: var(--fs-md); }
.protokoll code { font-family: ui-monospace, monospace; font-size: var(--fs-xs); word-spacing: .08em; }

@media print { .siegel { border-color: #000; } .protokoll-auf { display: none; } }

/* ---------- Herkunft eines übernommenen Vorschlags ---------- */
/* Kein Warnton, keine Farbe: Dass beim Formulieren geholfen wurde, ist kein
   Makel, der auffallen muss – aber es gehört nachvollziehbar dokumentiert.
   Darum dieselbe ruhige Sprache wie beim Prüfsiegel. */
.herkunft { border-left: 2px solid var(--border); padding-left: 12px; }
.herkunft .muted { font-size: var(--fs-md); line-height: 1.55; margin: 0 0 8px; }
.herkunft-roh {
  white-space: pre-wrap; font-size: var(--fs-md); color: var(--text-secondary);
  background: var(--surface-sunken); border-radius: 8px; padding: 12px; margin-top: 8px;
}
.draft-bestaetigung {
  display: flex; gap: 8px; align-items: flex-start; margin: 12px 0;
  font-size: var(--fs-md); line-height: 1.45; cursor: pointer;
}
.draft-bestaetigung input { margin-top: 2px; flex: none; }
@media print { .herkunft details { display: block; } .herkunft summary { display: none; } }

/* ---------- Auswahlleiste: ein Element statt sechs Knöpfe ---------- */
/* Die Zahl ist selbst der Weg zurück – ein eigener "Auswahl aufheben"-Knopf
   daneben wäre eine zweite Art, dasselbe zu sagen. */
.sel-zahl {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; color: inherit; cursor: pointer;
  font-size: var(--fs-md); padding: 8px 12px; border-radius: 8px;
}
.sel-zahl:hover { background: rgba(255,255,255,.12); }
.sel-zahl b { font-size: var(--fs-xl); }
.sel-x { opacity: .6; font-size: var(--fs-sm); margin-left: 2px; }
.sel-zahl:hover .sel-x { opacity: 1; }

/* Kein Knopf, sondern eine Eigenschaft dessen, was gleich hinausgeht. */
.sel-anon {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: var(--fs-md); padding: 8px 12px; user-select: none;
}
.sel-anon input { flex: none; }

.sel-rest { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.sel-weiter { position: relative; display: inline-flex; }
.sel-weiter .btn.primary { border-radius: 8px 0 0 8px; }
.sel-mehr { border-radius: 0 8px 8px 0; border-left: 1px solid rgba(255,255,255,.25); padding: 8px 12px; }

.sel-menu {
  position: absolute; bottom: calc(100% + 8px); right: 0; z-index: 30;
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: 10px; box-shadow: var(--shadow); padding: 4px; min-width: 190px;
}
.sel-menu button {
  /* Radius konzentrisch: 10 aussen − 4 Innenabstand = 6 innen. */
  display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 8px 12px; border-radius: 6px; cursor: pointer; font-size: var(--fs-md);
  color: var(--text-primary);
}
.sel-menu button:hover, .sel-menu button:focus-visible { background: var(--surface-sunken); }

/* ---------- Verweise in den Zusammenhang ----------
   Eine Angabe im Rapport, die weiterführt: Objekt, Ort, Dienst,
   Wiedervorlage. Sie ist zuerst Text und erst danach ein Knopf – darum kein
   Rahmen, keine Fläche, kein eigenes Gewicht. Was sie unterscheidet, ist eine
   Haarlinie darunter, die beim Zeigen die Akzentfarbe annimmt.
   Bewusst kein text-decoration: Die Linie soll ruhiger liegen und nicht durch
   die Unterlängen laufen. */
.verweis {
  appearance: none; background: none; border: 0; border-radius: 0;
  padding: 0; margin: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
  border-bottom: 1px solid var(--border-strong);
}
.verweis:hover { color: var(--accent-fg); border-bottom-color: var(--accent-fg); }

/* Wo ein Sprung in der Dienstliste gelandet ist. Kein Blinken, kein Rahmen:
   eine Spur Fläche und eine Kante an der Anschlagseite. Die Klasse wird nach
   vier Sekunden wieder entfernt (sprungMarkieren), das Ausblenden übernimmt
   der Übergang.
   Für die Objekte-Ansicht braucht es hier nichts: Dort setzt der Sprung
   .obj-karte.gewaehlt – dieselbe Klasse, die die Ansicht auch bei einem Klick
   auf die Landkarte setzt, gestaltet in objekte-ansicht.css. */
.verweis-ziel {
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent-fg);
  border-radius: 6px;
  transition: background .6s ease-out, box-shadow .6s ease-out;
}
.shift-day h3.verweis-ziel { padding: 4px 8px; margin-left: -8px; }

/* ---------- Anhang-Vorschau ----------
   Breiter als ein Rapportblatt, weil ein Foto sonst kleiner wäre als die
   Vorschaukachel, aus der man kommt. */
.sheet.vorschau { max-width: 1100px; }
.vorschau-buehne {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-sunken); padding: 16px;
}
.vorschau-bild { max-width: 100%; max-height: 78dvh; border-radius: 8px; }
.vorschau-doc { width: 100%; height: 78dvh; border: 0; background: var(--surface-2); }

/* Auf Papier ist ein Verweis nur Text. Ein Rapport im Ordner soll aussehen wie
   ein Rapport, nicht wie ein Ausdruck einer Webseite. */
@media print {
  /* DIESE ZEILE RETTET VIER ANGABEN AUF DEM PAPIER.
     druck.css blendet beim Drucken pauschal jeden button aus - richtig, denn
     auf Papier laesst sich nichts druecken. Objekt, Ort, Dienst und
     Wiedervorlage sind seit der Verlinkung aber genau solche Knoepfe: Sie
     verschwanden mitsamt ihrem TEXT, und der Ausdruck trug vier leere Felder,
     wo vorher Angaben standen.
     Bei einem Beweisdokument ist das der schlimmste denkbare Fehler - das
     Papier sagte weniger als der Bildschirm, ohne dass es jemandem auffiel.
     Die Klasse gewinnt gegen den nackten Elementnamen (0,2,0 gegen 0,0,1),
     darum genuegt diese eine Zeile, und druck.css bleibt unberuehrt. */
  .verweis { display: inline !important; border-bottom: 0; color: inherit; }
  .verweis-ziel { background: none; box-shadow: none; }
}
