/* ============================================================================
   Gemeinsames Aussehen aller Oberflächen.

   Vorher trug jede der sieben Seiten ihre eigene Farbpalette, ihre eigenen
   Knopf- und Feldstile und ihren eigenen Kopfbereich — Zeile für Zeile dieselben
   Werte, siebenmal abgeschrieben. Das ist nicht nur Ballast: die Paletten waren
   bereits leicht auseinandergelaufen (--warn stand an einer Stelle auf #a6641a, an
   anderer auf #b7791f), und beim nächsten Anfassen wären es mehr geworden.

   Hier stehen: Farben, Grundlagen, Kopfbereich, Knöpfe, Felder. Was eine Seite
   wirklich für sich braucht (das Belegraster, der Handbuch-Editor), bleibt dort.
   Geladen mit demselben CSP-Nonce wie das Skript (siehe security.ts).
   ============================================================================ */

/* --- Farben ---------------------------------------------------------------
   Ein Satz Marken, hell und dunkel. Die Seiten sprechen nur über diese Namen —
   damit ändert eine Korrektur die ganze Anwendung und nicht eine Seite davon. */
:root{
  --bg:#f6f7f9; --surface:#fff; --border:#e3e6ea; --text:#1c2530; --text-dim:#5b6673;
  --accent:#2f6feb; --accent-weak:#eaf1fe;
  --ok:#1a8f4c; --ok-weak:#e7f6ec;
  --warn:#b7791f; --warn-weak:#fdf3e2;
  --alert:#c0392b; --alert-weak:#fdecea;
  --shadow:0 1px 3px rgba(20,30,45,.06);
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#12161c; --surface:#1a2029; --border:#2b333f; --text:#e6ebf2; --text-dim:#9aa6b4;
    --accent:#5b9dff; --accent-weak:#1e2a3d;
    --ok:#42c07a; --ok-weak:#16281d;
    --warn:#d9a441; --warn-weak:#2a2214;
    --alert:#e06455; --alert-weak:#2c1a18;
    --shadow:0 1px 3px rgba(0,0,0,.3);
  }
}
/* Ausdrückliche Wahl schlägt die Systemeinstellung (Knopf im Kopfbereich). */
:root[data-theme="light"]{
  --bg:#f6f7f9; --surface:#fff; --border:#e3e6ea; --text:#1c2530; --text-dim:#5b6673;
  --accent:#2f6feb; --accent-weak:#eaf1fe; --ok:#1a8f4c; --ok-weak:#e7f6ec;
  --warn:#b7791f; --warn-weak:#fdf3e2; --alert:#c0392b; --alert-weak:#fdecea;
  --shadow:0 1px 3px rgba(20,30,45,.06);
}
:root[data-theme="dark"]{
  --bg:#12161c; --surface:#1a2029; --border:#2b333f; --text:#e6ebf2; --text-dim:#9aa6b4;
  --accent:#5b9dff; --accent-weak:#1e2a3d; --ok:#42c07a; --ok-weak:#16281d;
  --warn:#d9a441; --warn-weak:#2a2214; --alert:#e06455; --alert-weak:#2c1a18;
  --shadow:0 1px 3px rgba(0,0,0,.3);
}

/* --- Grundlagen ----------------------------------------------------------- */
*{box-sizing:border-box}
/* Platz für den Scrollbalken IMMER freihalten, auch wenn gerade keiner da ist.
   Ohne das verschiebt jeder nachgereichte Inhaltsblock die ganze Seite waagrecht:
   die Seite wird einen Block länger, der Balken erscheint, die nutzbare Breite
   schrumpft um ~15 px — und alles Zentrierte (der 1100er .wrap, die Kacheln, der
   Kopfbereich) rutscht nach links. Das ist das "Springen", das auf Seiten mit
   nachgeladenen Panels auffiel und auf /status nicht, weil dort alles in einem
   Zug gezeichnet wird. */
html{scrollbar-gutter:stable}
body{
  margin:0; background:var(--bg); color:var(--text);
  font:14px/1.55 system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}
/* 12px als Untergrenze: darunter wird eine Anwendung, in der jemand acht Stunden
   Belege prüft, anstrengend. Die Marken heißen weiter "muted", nur eben lesbar. */
.muted{color:var(--text-dim);font-size:12.5px}
.err{color:var(--alert);font-size:13px;min-height:18px;margin-top:8px}
.spacer{flex:1}

/* --- Kopfbereich ----------------------------------------------------------
   Auf jeder Seite derselbe: Name, dieselbe Navigation in derselben Reihenfolge,
   dann Seitenaktionen, Benutzer, Theme, Abmelden. Wer die Seite wechselt, findet
   alles dort, wo es vorher war. */
header{
  position:sticky; top:0; z-index:20; display:flex; align-items:center; gap:10px;
  padding:12px 20px; border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--surface) 92%,transparent); backdrop-filter:blur(8px);
}
header h1{font-size:15px;margin:0;font-weight:800;letter-spacing:.01em;white-space:nowrap}
nav{display:flex;gap:4px;flex-wrap:wrap}
nav a{
  text-decoration:none;color:var(--text);border:1px solid var(--border);background:transparent;
  padding:6px 12px;border-radius:8px;font-weight:700;font-size:12.5px;white-space:nowrap;
}
nav a:hover{border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
nav a.active{background:var(--accent);color:#fff;border-color:transparent}
.who{font-size:12.5px;color:var(--text-dim);white-space:nowrap}
.who-rollen{opacity:.75}

/* --- Knöpfe ---------------------------------------------------------------- */
button{
  font:inherit; cursor:pointer; border-radius:8px; border:1px solid var(--border);
  background:var(--surface); color:var(--text); padding:6px 12px; font-weight:600;
  white-space:nowrap;
}
button:hover{border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
button:disabled{opacity:.5;cursor:not-allowed}
button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent); outline-offset:1px;
}
button.primary{background:var(--accent);color:#fff;border-color:transparent}
button.ok{background:var(--ok);color:#fff;border-color:transparent}
button.danger{color:var(--alert);border-color:color-mix(in srgb,var(--alert) 45%,transparent)}
button.btn-ghost{background:transparent}
button.sm{padding:4px 9px;font-size:12px}

/* --- Felder ---------------------------------------------------------------- */
input,select,textarea{
  background:var(--bg); color:var(--text); border:1px solid var(--border);
  border-radius:8px; padding:7px 10px; font:inherit;
}
input:focus,select:focus,textarea:focus{border-color:var(--accent)}
label{font-size:12.5px}

/* --- Anmeldekarte ----------------------------------------------------------
   Zum gemeinsamen Markup (NUI.login) gehört das gemeinsame Aussehen. Vorher stand
   die Karte in sechs Seiten im <style>-Block, in leicht auseinandergelaufenen
   Fassungen: 340 oder 360 px breit, 22 oder 26 px Innenabstand, mit oder ohne
   Beschriftungsstil — je nachdem, von welcher Seite gerade abgeschrieben wurde. */
.login{
  max-width:360px; margin:12vh auto; padding:26px;
  background:var(--surface); border:1px solid var(--border); border-radius:14px; box-shadow:var(--shadow);
}
.login h2{margin:0 0 4px;font-size:17px}
.login label{
  display:block; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  color:var(--text-dim); margin:14px 0 4px;
}
.login input,.login select{width:100%}
.login button{width:100%;margin-top:16px}
.login .nui-oder{margin:14px 0 8px;text-align:center}

/* --- Kurzmeldung -----------------------------------------------------------
   Eine Rückmeldung, die von selbst wieder geht. Lag in vier Seiten als Kopie. */
#toast{
  position:fixed; bottom:22px; left:50%; z-index:40; max-width:80vw;
  transform:translateX(-50%) translateY(20px); opacity:0; transition:.2s;
  background:var(--text); color:var(--bg); padding:10px 18px; border-radius:10px;
  font-size:13px; font-weight:600; pointer-events:none;
}
#toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
#toast.err{background:var(--alert);color:#fff}

/* --- Marken ----------------------------------------------------------------
   Ein Zustand als Wort mit Farbe, nicht als Farbe allein: Rot und Grün sind für
   einen Teil der Belegschaft dasselbe. Der Punkt davor ist die dritte Kodierung
   (Form), damit die Marke auch in Graustufen und im Ausdruck lesbar bleibt.

   EINE Fassung. Vorher gab es drei: 12 px inline-block hier, 11 px inline-flex
   mit Punkt im Board, 11 px inline-block mit Aussenabstand in der
   Nutzerverwaltung — und dazu .action-pill, .phase und .env, die dasselbe sind
   und anders heissen. Dieselbe Marke sah auf drei Seiten verschieden aus.

   TÖNE statt Fachbegriffen: ein Modul benennt seine Zustände fachlich
   (offen/geprüft/gebucht, Entwurf/aktiv/beendet) und ordnet sie EINEM dieser
   fünf Töne zu, statt eine eigene Farbregel zu schreiben. So bleibt "gelb heisst
   wartet" über alle Module dasselbe. */
.pill{
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  padding:2px 9px;border-radius:99px;font-size:11.5px;font-weight:700;
  border:1px solid transparent;background:var(--accent-weak);color:var(--accent);
}
.pill .dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:0 0 auto}
.pill.info {background:var(--accent-weak);color:var(--accent);border-color:color-mix(in srgb,var(--accent) 30%,transparent)}
.pill.ok   {background:var(--ok-weak);   color:var(--ok);    border-color:color-mix(in srgb,var(--ok) 30%,transparent)}
.pill.warn {background:var(--warn-weak); color:var(--warn);  border-color:color-mix(in srgb,var(--warn) 30%,transparent)}
.pill.alert,.pill.off,.pill.bad{background:var(--alert-weak);color:var(--alert);border-color:color-mix(in srgb,var(--alert) 30%,transparent)}
.pill.neutral,.pill.plain{background:var(--bg);color:var(--text-dim);border-color:var(--border)}

/* ===========================================================================
   BAUSTEINE FÜR MODULSEITEN
   ---------------------------------------------------------------------------
   Ab hier steht, was jede Modulseite braucht: Seitengerüst, Panel, Tabelle,
   Formular, Kleinteile. Eine neue Modulseite soll KEINEN eigenen <style>-Block
   für diese Dinge mehr mitbringen — Vorlage: public/_vorlage-modul.html.

   Warum überhaupt: Modul 01 und 02 sind mit zwei Vokabularen für dieselbe Sache
   entstanden (.panel gegen .card, .feld gegen .field, fünf Seitenbreiten). Bei
   .field war es schlimmer als unschön — in den Einstellungen bedeutet die Klasse
   "Beschriftung links, Steuerelement rechts", im Audit-Log "Beschriftung über
   der Eingabe". Wer die eine Seite als Vorlage nahm, bekam auf der anderen ein
   anderes Layout, ohne dass jemand einen Fehler gemacht hätte.
   =========================================================================== */

/* --- Seitengerüst ----------------------------------------------------------
   Zwei Bauformen, mehr braucht es nicht:

   .wrap        — die Seite scrollt als Ganzes, Inhalt mittig begrenzt.
                  Für Formulare, Übersichten, Listen ohne Detailbereich.
   .wrap.voll   — die Seite füllt das Fenster, jede Zone scrollt für sich.
                  Für Arbeitsflächen mit Liste OBEN und Detail DARUNTER (Board,
                  Verträge): sonst wandert beim Lesen des Details die Liste aus
                  dem Bild.

   Die Breite ist eine Entscheidung, keine Zufallszahl: 1100 px für Tabellen mit
   vielen Spalten, 820 px für Fliesstext und Formulare (darüber wird eine Zeile
   zur Suchaufgabe). Vorher gab es 1100, 1080, 1000 und 820 nebeneinander — ohne
   dass ein Unterschied gemeint war. */
.wrap{max-width:1100px;margin:0 auto;padding:22px 18px 60px}
.wrap.schmal{max-width:820px}
.wrap.voll{
  max-width:none;margin:0;padding:14px 18px 18px;
  flex:1;min-height:0;display:flex;flex-direction:column;gap:14px;overflow:hidden;
}
/* Nur die Vollbild-Bauform braucht das — sonst verliert eine normale Seite ihr
   natürliches Scrollen. Die Seite setzt dafür <body class="blatt">.
   Die Kette muss durchgehen: der Kopfbereich wird von NUI.kopf() INNERHALB von
   #app gezeichnet, also muss auch #app eine Flex-Spalte sein. Fehlt das eine
   Glied, ist .wrap.voll wirkungslos und die Seite scrollt doch als Ganzes. */
html:has(body.blatt){height:100%}
body.blatt{height:100vh;display:flex;flex-direction:column;overflow:hidden;margin:0}
body.blatt > #app{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}
body.blatt header{flex:0 0 auto}

/* --- Panel -----------------------------------------------------------------
   Der eine Container. Hiess auf der Hälfte der Seiten .card, mit anderem
   Innenabstand (14/18 statt 12/16) — deshalb sahen zwei nebeneinanderliegende
   Module unterschiedlich "dicht" aus. */
.panel{background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow)}
.panel + .panel{margin-top:14px}
.panel.aus{opacity:.6}
.panel-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 16px;border-bottom:1px solid var(--border)}
.panel-h h2{font-size:13.5px;margin:0;font-weight:700}
.panel-b{padding:12px 16px}
/* Panel OHNE Kopfzeile: der Inhalt sitzt direkt drin und braucht das Polster
   selbst. Sonst müsste jede solche Stelle ein leeres .panel-b umschliessen —
   oder, was vorher geschah, .panel lokal mit padding neu definieren. */
.panel.pad{padding:16px 18px 18px}
.panel-f{padding:10px 16px;border-top:1px solid var(--border);display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* In der Vollbild-Bauform scrollt der Rumpf, nicht die Seite. */
.wrap.voll .panel{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.wrap.voll .panel + .panel{margin-top:0}
.wrap.voll .panel-h,.wrap.voll .panel-f{flex:0 0 auto}
.wrap.voll .panel-b{flex:1;min-height:0;overflow:auto}

/* Zwei Panels nebeneinander (Beleg | Buchung, Vertragsdaten | Entwurf).
   Flex statt Grid, damit ein zugeklapptes Panel die Breite abgeben kann. */
.split{display:flex;gap:14px;min-height:0}
.split > .panel{flex:1 1 0;min-width:0}
.wrap.voll > .split{flex:1;min-height:0}
@media (max-width:900px){ .split{flex-direction:column} }

/* --- Tabelle ---------------------------------------------------------------
   Lag fünfmal in den Seiten, mit 13 px hier und 12,5 px dort, 8/10 px Polster
   hier und 7/8 px dort. Für den Betrachter ist das keine Gestaltung, sondern
   ein Ruckeln beim Seitenwechsel. */
.panel table,table.tabelle{width:100%;border-collapse:collapse;font-size:13px}
.panel th,table.tabelle th{
  text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--text-dim);font-weight:700;padding:6px 10px;border-bottom:1px solid var(--border);
}
.panel td,table.tabelle td{padding:8px 10px;border-bottom:1px solid var(--border);vertical-align:top}
/* Zahlen rechts und mit gleich breiten Ziffern — sonst lassen sich Beträge
   untereinander nicht vergleichen, und genau dafür steht die Spalte da. */
.panel td.n,.panel th.n,table.tabelle td.n,table.tabelle th.n{text-align:right;font-variant-numeric:tabular-nums}
/* Kopfzeile bleibt beim Scrollen stehen — in einer Liste mit 200 Belegen ist
   eine weggescrollte Spaltenüberschrift eine Ratearbeit. */
.wrap.voll .panel-b table thead th{position:sticky;top:0;background:var(--surface);z-index:1}
/* Eine breite Tabelle scrollt IN SICH, nicht die Seite. Ohne das schiebt eine
   Tabelle mit sieben Spalten auf dem Telefon die ganze Seite waagrecht — und
   damit auch den Kopfbereich und jeden Text daneben. Das Board hatte diese
   Zeile, das Audit-Log nicht, und genau dort rutschte die Seite. Wer eine
   Tabelle einbaut, die breit werden kann, umschliesst sie hiermit. */
.tbl-wrap{overflow-x:auto}
.panel tbody tr.klick{cursor:pointer}
.panel tbody tr.klick:hover{background:var(--accent-weak)}
.panel tbody tr.sel{background:var(--accent-weak);box-shadow:inset 3px 0 0 var(--accent)}
.mono{font-family:ui-monospace,Menlo,monospace;font-size:11.5px}

/* --- Kleinteile ------------------------------------------------------------ */
/* Leerer Zustand: sagt, was zu tun ist, statt nur "keine Daten". */
.empty{padding:26px 12px;text-align:center;color:var(--text-dim);font-size:13px}
/* Zwischenüberschrift innerhalb eines Panels. */
.sec{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--text-dim);font-weight:700;margin:16px 0 7px}
.sec:first-child{margin-top:0}
/* Beschriftung links, Wert rechts — die Standardform für Stammdaten. */
.kv{display:grid;grid-template-columns:auto 1fr;gap:5px 14px;font-size:13px;align-items:baseline;margin:0}
.kv dt{color:var(--text-dim);white-space:nowrap}
.kv dd{margin:0;text-align:right;font-weight:600}
/* Knopfreihe am Ende eines Panels. */
.actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
/* Ein Satz, der etwas erklärt oder warnt — im Ton der Marken. */
.hinweis{font-size:12.5px;padding:9px 11px;border-radius:9px;margin-bottom:10px}
.hinweis.info{background:var(--accent-weak);color:var(--accent)}
.hinweis.ok{background:var(--ok-weak);color:var(--ok)}
.hinweis.warn{background:var(--warn-weak);color:var(--warn)}
.hinweis.alert,.hinweis.bad{background:var(--alert-weak);color:var(--alert)}
/* Filterreihe (Statuszähler). Ein Zähler auf dem Knopf, damit man nicht erst
   klicken muss, um zu erfahren, dass nichts dahinter liegt. */
.chips{display:flex;gap:4px;flex-wrap:wrap}
.chips button{padding:4px 10px;font-size:12px;border-radius:99px}
.chips button.on{background:var(--accent);color:#fff;border-color:transparent}

/* Fuss einer seitenweise geladenen Liste ("Mehr laden"). Die grossen Listen
   kommen seit paging.ts nicht mehr vollstaendig; der Knopf steht unter der
   Tabelle, weil dort das Ende der geladenen Menge sichtbar ist. */
.mehr{display:flex;justify-content:center;padding:12px 0}

/* --- Formular --------------------------------------------------------------
   EIN .feld. Die englische Schreibweise .field ist absichtlich nicht belegt:
   sie bedeutete auf zwei Seiten Verschiedenes, und ein Name, der zweierlei
   heisst, ist schlimmer als zwei Namen. */
.feld{margin-bottom:11px}
.feld > label{display:block;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-dim);margin-bottom:3px}
.feld input,.feld select,.feld textarea{width:100%}
.feld .help{font-size:12px;color:var(--text-dim);margin-top:3px}
/* Zwei/drei Felder nebeneinander; auf schmalen Fenstern untereinander. */
.zwei{display:grid;grid-template-columns:1fr 1fr;gap:11px}
.drei{display:grid;grid-template-columns:repeat(3,1fr);gap:11px}
@media (max-width:640px){ .zwei,.drei{grid-template-columns:1fr} }
/* Beschriftung links, Steuerelement rechts — die Form der Einstellungsseite. */
.feld-breit{display:grid;grid-template-columns:1fr auto;gap:6px 16px;align-items:center;padding:12px 0;border-top:1px solid var(--border)}
.feld-breit:first-child{border-top:none}
.feld-breit .lbl{font-weight:600}
.feld-breit .help{grid-column:1;font-size:12px;color:var(--text-dim);margin-top:2px}
.feld-breit .ctl{grid-column:2;grid-row:1;justify-self:end}
@media (max-width:820px){ .feld-breit{grid-template-columns:1fr} .feld-breit .ctl{grid-column:1;justify-self:start} }
/* Ankreuzfeld mit erklärender Unterzeile — ein Schalter, der eine Folge hat,
   soll sie benennen. */
.schalter{display:flex;align-items:flex-start;gap:9px;padding:7px 0;font-size:13px}
.schalter input{margin-top:3px}
.schalter .sub{display:block;color:var(--text-dim);font-size:11.5px;font-weight:400}
/* Schiebeschalter für Ja/Nein. */
.switch{position:relative;width:44px;height:24px;display:inline-block}
.switch input{opacity:0;width:0;height:0}
.slider{position:absolute;inset:0;background:var(--border);border-radius:99px;transition:.15s;cursor:pointer}
.slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.15s}
.switch input:checked + .slider{background:var(--accent)}
.switch input:checked + .slider:before{transform:translateX(20px)}

/* --- Dialog ---------------------------------------------------------------- */
.modal-bg{position:fixed;inset:0;background:rgba(10,15,22,.5);display:none;align-items:center;justify-content:center;z-index:30;padding:16px}
.modal-bg.show{display:flex}
.modal{
  background:var(--surface);border:1px solid var(--border);border-radius:14px;box-shadow:var(--shadow);
  max-width:600px;width:100%;padding:20px;max-height:calc(100vh - 32px);overflow-y:auto;overscroll-behavior:contain;
}
.modal.schmal{max-width:440px}
.modal h3{margin:0 0 4px}

/* --- Drucken ---------------------------------------------------------------
   Gedruckt wird der INHALT, nicht die Anwendung: Navigation, Filter und Knöpfe
   gehören nicht auf Papier, und die Zonen dürfen nicht mehr einzeln scrollen,
   sonst endet der Ausdruck nach der ersten Bildschirmhöhe. */
@media print{
  header,.chips,.actions,.modal-bg,#toast,.nicht-drucken{display:none !important}
  body.blatt,.wrap.voll,.split,.panel{
    display:block !important;overflow:visible !important;height:auto !important;max-height:none !important;
  }
  .panel{border:0;box-shadow:none}
  .wrap.voll .panel-b{overflow:visible !important}
}

/* --- Schmale Fenster -------------------------------------------------------
   Die Kopfzeile darf umbrechen, statt die Seite waagrecht zu schieben. Der
   .spacer nimmt dabei eine ganze Zeile ein und erzwingt den Umbruch genau dort,
   wo im Breitbild der Zwischenraum sitzt. */
@media (max-width:820px){
  header{flex-wrap:wrap;row-gap:8px;padding:10px 12px}
  header .spacer{flex:0 0 100%;height:0}
  .who{flex:0 0 100%}
  /* Auf schmalen Fenstern zaehlt jeder Millimeter Textbreite. Diese zwei Zeilen
     standen in sechs Seiten als Kopie. */
  .wrap{padding-left:12px;padding-right:12px}
}
