/* CAIREBuddy Portal. Ein Stylesheet, keine Abhaengigkeit, kein Build.
   Formularlastige Verwaltung: ruhig, lesbar, auf dem Telefon bedienbar. */

:root {
  --grund: #fbfbfa;
  --flaeche: #ffffff;
  --rand: #dcdcd8;
  --schrift: #1c1c1a;
  --gedaempft: #6b6b66;
  --akzent: #1f5f5b;
  --akzent-schrift: #ffffff;
  --gut: #1f5f2f;
  --gut-grund: #e8f3ea;
  --fehler: #8c2318;
  --fehler-grund: #f7e9e7;
  --radius: 10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --grund: #16171a;
    --flaeche: #1e2024;
    --rand: #33363c;
    --schrift: #e9e9e6;
    --gedaempft: #9a9a94;
    --akzent: #57b6ac;
    --akzent-schrift: #10201e;
    --gut: #8fd39c;
    --gut-grund: #1c2a20;
    --fehler: #f0a79c;
    --fehler-grund: #2c1c1a;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--grund);
  color: var(--schrift);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ------------------------------------------------------------- Kopf, Fuss */

.kopf {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--rand);
  background: var(--flaeche);
}

.marke {
  font-weight: 650;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--schrift);
}

.kopfnav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  font-size: 0.9rem;
}

.kopfnav form { display: flex; gap: 0.4rem; align-items: center; margin: 0; }

.fuss {
  max-width: 60rem;
  margin: 2.5rem auto 3rem;
  padding: 0 1.25rem;
  color: var(--gedaempft);
  font-size: 0.85rem;
}

.inhalt {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.75rem 1.25rem 0;
}

/* Seiten mit Rastern (Kanäle, Geräte) brauchen mehr Breite als ein Lesetext;
   die Lesebreite bleibt in den Absätzen selbst begrenzt (.einleitung, .klein). */
.inhalt.breit { max-width: 80rem; }

/* Seitenkopf: Titel und ein Satz. Alles Weitere steht eingeklappt in der
   Karte (details.erklaerung) -- die Seite erklärt sich auf Nachfrage, nicht
   in fünf Absätzen vor dem ersten Feld. */
.seitenkopf { margin-bottom: 1rem; }
.seitenkopf .einleitung { margin: 0; color: var(--gedaempft); max-width: 60rem; }
.karte > p.klein { max-width: 60rem; }
details.erklaerung { margin: 0.25rem 0 0.75rem; }
details.erklaerung summary { font-size: 0.9rem; color: var(--akzent); }
details.erklaerung p { max-width: 60rem; }

/* ------------------------------------------------------------- Bloecke */

h1 { font-size: 1.5rem; margin: 0 0 0.35rem; }
h2 { font-size: 1.1rem; margin: 0 0 0.6rem; }

.karte {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin: 1.25rem 0;
}

.karte.schmal { max-width: 27rem; margin-inline: auto; }

.nurlesbar { color: var(--gedaempft); font-size: 0.88rem; }

.marker {
  border: 1px solid var(--akzent);
  border-radius: 999px;
  color: var(--akzent);
  font-size: 0.75rem;
  padding: 0.1rem 0.55rem;
}

code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.85em;
}

/* ------------------------------------------------------------- Formulare */

label { display: block; font-size: 0.85rem; color: var(--gedaempft); margin: 0.8rem 0 0.25rem; }

input, select, button {
  font: inherit;
  border-radius: 8px;
  border: 1px solid var(--rand);
  padding: 0.5rem 0.65rem;
  background: var(--grund);
  color: var(--schrift);
  max-width: 100%;
}

input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 1px;
}

input[type="text"], input[type="email"], input[type="password"] { width: 100%; }
input[type="number"] { width: 6rem; }

button, .knopfhaft {
  margin-top: 1rem;
  border: 1px solid var(--akzent);
  background: var(--akzent);
  color: var(--akzent-schrift);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.knopfhaft { padding: 0.5rem 0.9rem; border-radius: 8px; }

/* Eine Hierarchie, überall dieselbe: die EINE Hauptaktion je Karte ist
   gefüllt, Nebenaktionen (Prüfen) tragen den Umriss, Kleinkram (erben,
   wechseln) ist schlicht, Zerstörendes ist rot und nie gefüllt. */
button.zweitrangig {
  margin: 0;
  background: transparent;
  border-color: var(--akzent);
  color: var(--akzent);
}
button.zweitrangig:hover { background: var(--gut-grund); }
button.schlicht {
  margin: 0;
  background: transparent;
  border-color: var(--rand);
  color: var(--schrift);
}
button:disabled { opacity: 0.45; cursor: not-allowed; }

button.gefahr {
  background: transparent;
  border-color: var(--fehler);
  color: var(--fehler);
}

/* Eine Zeile, die auf dem Telefon umbricht. */
.zeile {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: end;
  margin-top: 0.75rem;
}

.zeile label { margin: 0; }
.zeile button { margin: 0; }
.zeile input[type="text"], .zeile input[type="email"] { width: auto; flex: 1 1 14rem; }

/* ------------------------------------------------------------- Meldungen */

.hinweis {
  border: 1px solid var(--rand);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin: 0.75rem 0;
  font-size: 0.9rem;
}

.hinweis.gut { border-color: var(--gut); background: var(--gut-grund); color: var(--gut); }
.hinweis.fehler { border-color: var(--fehler); background: var(--fehler-grund); color: var(--fehler); }

/* ------------------------------------------------------------- Tabellen */

table { width: 100%; border-collapse: collapse; font-size: 0.93rem; }

th, td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--rand);
  vertical-align: middle;
}

th { color: var(--gedaempft); font-weight: 550; font-size: 0.82rem; }
td.rechts, th.rechts { text-align: right; }
tbody tr:last-child td { border-bottom: none; }

a { color: var(--akzent); }

/* ------------------------------------------------------------- Kopplung */

.kopplung {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem;
  align-items: start;
}

.kopplung > div:last-child { flex: 1 1 18rem; }

/* Der QR muss gross sein: 0,3 Megapixel und Festfokus (docs/05). */
.qrfeld {
  background: #ffffff;
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  padding: 0.75rem;
  line-height: 0;
}

.qrfeld svg {
  display: block;
  width: min(19rem, 62vw);
  height: auto;
}

.ziffer {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.4rem;
  letter-spacing: 0.18em;
  width: 8.5rem;
  text-align: center;
}

.puls {
  color: var(--akzent);
  animation: pulsieren 1.4s ease-in-out infinite;
}

@keyframes pulsieren {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .puls { animation: none; opacity: 0.7; }
}

.marker.gesperrt { border-color: var(--fehler); color: var(--fehler); }

details { margin-top: 0.9rem; }
details summary { cursor: pointer; }

/* Der Avatar in der Vorschau: nur so viel, dass die Wahl sichtbar wird. */
.gesichtwahl { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.gesichtwahl label {
  margin: 0;
  border: 1px solid var(--rand);
  border-radius: 8px;
  padding: 0.35rem 0.7rem;
  cursor: pointer;
  color: var(--schrift);
  font-size: 0.9rem;
}

.gesichtwahl input { position: absolute; opacity: 0; pointer-events: none; }
.gesichtwahl input:checked + span { font-weight: 650; color: var(--akzent); }

/* Ein Feldsatz nur zum Abschalten, nicht zum Umranden. */
fieldset.blank { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.blank[disabled] { opacity: 0.75; }

/* ------------------------------------------------------------- Modelle */

textarea {
  font: inherit;
  width: 100%;
  border-radius: 8px;
  border: 1px solid var(--rand);
  padding: 0.55rem 0.7rem;
  background: var(--grund);
  color: var(--schrift);
  resize: vertical;
}

textarea:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }

.gut { color: var(--gut); }

/* Zustandsmarke -- das Muster "Tag" aus dem GOV.UK Design System: helle
   Fläche, dunkle Schrift, damit sie nicht wie ein Knopf aussieht; Zeichen
   UND Farbe, damit Farbe nie allein trägt; ein Adjektiv, kein Verb. */
.zustandsmarke {
  display: inline-block;
  padding: 0.12rem 0.55rem;
  border-radius: 6px;
  font-size: 0.82rem;
  font-weight: 550;
  line-height: 1.4;
  white-space: nowrap;
}
.zustandsmarke.gut { background: var(--gut-grund); color: var(--gut); }
.zustandsmarke.fehler { background: var(--fehler-grund); color: var(--fehler); }
.zustandsmarke.offen { background: var(--flaeche); color: var(--gedaempft); border: 1px solid var(--rand); }
.fehlerfalz > summary { list-style: none; }
.fehlerfalz > summary::-webkit-details-marker { display: none; }
.fehlerfalz > summary .klein { text-decoration: underline; text-underline-offset: 2px; }
.schlecht { color: var(--fehler); }

/* Ankreuzfelder sollen nicht als Blockelement mit Abstand erscheinen. */
label > input[type="checkbox"] { width: auto; margin-right: 0.35rem; }

/* --------------------------------------------------- Kanäle und Verbindungen */

/* Ohne diese Regel stapeln sich Knöpfe in einer Zelle untereinander und die
   Zeile wird viermal so hoch wie ihr Inhalt. */
.knoepfe { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }

/* `button` trägt margin-top: 1rem — richtig unter einem Formular, falsch in
   einer Tabellenzelle: dort hing der Knopf eine Zeilenhöhe unter seinem
   Inhalt und die Zeile wurde entsprechend hoch. */
.knoepfe button, table button { margin-top: 0; }

/* Die Zustandsspalte. Ein Wort sichtbar, die Begründung eingeklappt: ein
   HTTP-400 eines Anbieters sind zweihundert Zeichen JSON, und die haben in
   einer Tabellenzeile nichts verloren — auf der Seite aber schon. */
.zustand { min-width: 8.5rem; max-width: 18rem; }
.zustand .zustandstext {
  display: block;
  margin-top: 0.2rem;
  overflow-wrap: anywhere;
}
.fehlerfalz > summary { cursor: pointer; font-weight: 550; }
.fehlerfalz > p { margin: 0.25rem 0 0; }

/* ------------------------------------------------------ KI: Kanäle */

/* Kein <table> mehr: sechs Kanäle mit Auswahlfeldern, Stellwerten und einem
   Prüfergebnis passen in keine Tabellenzeile, ohne dass die Spalten springen.
   Ein Raster mit drei festen Spuren -- Name, Einstellungen, Zustand -- hält
   jede Zeile gleich breit, egal wie lang ein Fehlertext ist. */
.kanalliste { display: grid; grid-template-columns: 1fr; }
.kanal {
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr) 16rem;
  gap: 0.5rem 1.5rem;
  align-items: start;
  padding: 1rem 0;
  border-top: 1px solid var(--rand);
}
.kanal-kopf { border-top: none; padding: 0 0 0.2rem; color: var(--gedaempft); font-weight: 550; font-size: 0.82rem; }
.kanalname { font-weight: 550; }
.kanalname .klein { font-weight: 400; display: block; margin-top: 0.15rem; }

/* Die Einstellungen eines Kanals: Verbindung und Modell nebeneinander, die
   Stellwerte (Stimme, Rate, Sprache) darunter. Jedes Feld trägt seine
   Beschriftung klein darüber -- nicht als Tabellenkopf drei Zeilen weiter oben. */
.einstellungen {
  display: grid;
  grid-template-columns: minmax(9rem, 13rem) minmax(0, 1fr);
  gap: 0.5rem 0.75rem;
}
.einstellungen .feld { display: flex; flex-direction: column; gap: 0.15rem; margin: 0; min-width: 0; }
.einstellungen .feld > .klein:first-child { line-height: 1.25; color: var(--gedaempft); font-size: 0.82rem; }
.einstellungen .feld > .klein:not(:first-child) { color: var(--gedaempft); margin-top: 0.15rem; }
.einstellungen .feld.schmal input { width: 7rem; }
.einstellungen select, .einstellungen input[type="text"] { width: 100%; min-width: 0; }
.einstellungen #modelle-llm > .klein, .einstellungen [id^="modelle-"] > .klein { margin-top: 0.2rem; }

/* Zustand und Prüfknopf in einer Spur. Ein Fehlertext bleibt eingeklappt
   (teile/pruefzustand.html) und wird hier zusätzlich auf drei Zeilen begrenzt --
   die ganze HTTP-Antwort eines Anbieters gehört nicht in die Spalte. */
.kanalzustand { display: flex; flex-direction: column; gap: 0.6rem; align-items: flex-start; }
.kanalzustand button { margin: 0; }
.zustand { min-width: 0; max-width: 100%; }
.zustand .zustandstext {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  margin-top: 0.2rem;
}
.fehlerfalz[open] .zustandstext { -webkit-line-clamp: unset; display: block; }

/* Die Leiste: speichern und prüfen für alles zugleich, samt Meldung daneben.
   Sie klebt am unteren Rand, solange die Kanäle im Bild sind -- wer unten
   ändert, muss nicht nach oben scrollen, und wer oben prüft, sieht die Antwort. */
.kanalleiste {
  position: sticky; bottom: 0;
  display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap;
  margin-top: 0.5rem; padding: 0.7rem 0 0.4rem;
  background: var(--flaeche); border-top: 1px solid var(--rand);
}
.kanalmeldung { flex: 1 1 16rem; min-width: 0; }
.zeilenmeldung { display: inline-block; margin: 0; padding: 0.35rem 0.6rem; font-size: 0.9rem; }

/* HTMX: während einer Anfrage zeigt der Knopf drei Punkte und nimmt nichts an. */
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { display: inline; }
button.htmx-request { opacity: 0.65; pointer-events: none; }

/* Verbindungen: eine Zeile je Endpunkt, vier Spuren. */
.verbindungsliste { display: grid; grid-template-columns: 1fr; }
.verbindung {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) 15rem auto;
  gap: 0.4rem 1.25rem; align-items: center;
  padding: 0.7rem 0; border-top: 1px solid var(--rand);
}
.verbindung:first-child { border-top: none; }
.verbindung-kopf { display: flex; flex-wrap: wrap; gap: 0.35rem 0.6rem; align-items: baseline; min-width: 0; }
.verbindung-kopf code { overflow-wrap: anywhere; }
.verbindung .knoepfe { justify-content: flex-end; }

@media (max-width: 60rem) {
  .kanal, .verbindung { grid-template-columns: 1fr; gap: 0.5rem; }
  .kanal-kopf { display: none; }
  .einstellungen { grid-template-columns: 1fr; }
  .kanalleiste { position: static; }
}

/* --------------------------------------------------------------- Skills */

/* Ein Skilltext ist Anweisungstext: Umbrueche und Einrueckungen bedeuten
   etwas, also <pre>. Aber ohne waagerechtes Scrollen -- ein Absatz, den man
   nur mit der Maus lesen kann, wird nicht gelesen. */
.skilltext {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0.4rem 0;
  padding: 0.6rem 0.75rem;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: 8px;
  font-size: 0.9rem;
}

/* Eine fruehere Fassung sieht anders aus als die geltende -- sonst liest
   jemand den Verlauf und haelt ihn fuer den Stand. */
.skilltext.alt { background: transparent; color: var(--gedaempft); }

textarea { width: 100%; font: inherit; border-radius: 8px;
           border: 1px solid var(--rand); padding: 0.5rem 0.65rem;
           background: var(--grund); color: var(--schrift); }
