/* Gemeinsame Komponenten aller Apps im Hub, beschrieben in plattform/DESIGN.html. Jede App lädt
   diese Datei nach /plattform/css/basis.css und vor ihrem eigenen Stylesheet; dort ergänzt sie nur
   Fachliches. Hier stehen keine festen Farben: Alles kommt aus den Tokens in basis.css, die
   Identität (Akzentfarbe, Muster) setzt jede App in ihrem :root. */

/* --- Knöpfe ---------------------------------------------------------------------------------- */

/* Hauptknopf: der eine nächste Schritt. Gleich als <a> und als <button>. */
.knopf {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  background: var(--color-accent);
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.knopf:hover {
  background: var(--color-accent-hover);
  color: var(--color-text);
}

/* Deaktiviert erklärt sich der Knopf über ein .hinweis-still daneben. */
.knopf:disabled {
  background: var(--color-neutral-tint);
  color: var(--color-muted);
  cursor: not-allowed;
}

/* Bestätigt einen Schritt, der etwas abgibt. Nach .knopf, damit es gegen dessen Farben gewinnt. */
.knopf-dunkel {
  background: var(--color-text);
  color: var(--color-surface);
}

.knopf-dunkel:hover {
  background: color-mix(in srgb, var(--color-text) 87%, var(--color-surface));
  color: var(--color-surface);
}

.knopf-zweit {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.knopf-zweit:hover {
  border-color: var(--color-muted);
}

/* Ein Ausweg, kein Angebot: kein Rahmen, keine Fläche. */
.knopf-still {
  border: none;
  background: none;
  color: var(--color-muted);
  text-decoration: none;
}

.knopf-still:hover {
  background: none;
  color: var(--color-text);
}

.knopf-gefahr {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  background: var(--color-danger);
  color: var(--color-surface);
  font: inherit;
  font-weight: 600;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

/* Kündigt einen gefährlichen Schritt an und öffnet seine Rückfrage. */
.knopf-warnung {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-surface);
  color: var(--color-danger);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

/* Auch als Link: Rot bleibt beim Überfahren (sonst gewönne a:hover aus basis.css). */
:is(.knopf-warnung, .knopf-warnung:hover) {
  color: var(--color-danger);
}

:is(.knopf-gefahr, .knopf-gefahr:hover) {
  color: var(--color-surface);
}

/* Nach den Knöpfen, damit inline-flex deren inline-block schlägt. */
.knopf-symbol {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.knopf-symbol svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.text-knopf {
  align-self: flex-start;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 0.875rem;
  color: var(--color-accent-text);
  text-decoration: underline;
  cursor: pointer;
}

/* Öffnet ein Menü mit Zeilenaktionen. */
.mehr-knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 4px;
  color: var(--color-muted);
}

.mehr-knopf:hover {
  background: var(--color-background);
  color: var(--color-text);
}

.reihe-aktion {
  display: inline;
}

.reihe-aktion button {
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-surface);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
}

.reihe-aktion button:hover {
  border-color: var(--color-accent);
}

/* Im Markup steht der Hauptknopf zuerst, damit Enter ihn auslöst; angezeigt wird er rechts. */
.knopfreihe {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  gap: 0.625rem;
}

/* --- Felder ---------------------------------------------------------------------------------- */

.feld {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

.feld label,
.feld-titel {
  font-weight: 600;
}

/* Zusatz in der Beschriftung, etwa „(optional)“. */
.feld-titel span {
  font-weight: 400;
  color: var(--color-muted);
}

.feld :where(input:not([type="checkbox"], [type="radio"], [type="file"]), select, textarea) {
  width: 100%;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
}

.feld .fehlerhaft {
  border-color: var(--color-danger);
}

.feldfehler {
  margin: 0;
  color: var(--color-danger);
  font-size: 0.875rem;
}

.feld-paar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

/* Bildfeld: ohne Skript das normale Datei-Feld, mit Skript (.mit-skript an einem Vorfahren)
   Vorschau und Ablagefläche. */
.bild-ziehen,
.mit-skript .feld input[type="file"],
.mit-skript [data-ohne-skript] {
  display: none;
}

.feld .bild-feld {
  display: flex;
  align-items: center;
  gap: 1rem;
  font-weight: 400;
}

.bild-feld .bild-vorschau,
.bild-feld-auswahl {
  display: none;
}

.mit-skript .bild-feld {
  padding: 0.875rem 1rem;
  border: 1.5px dashed var(--color-border-strong);
  border-radius: 6px;
  cursor: pointer;
}

.mit-skript .bild-feld .bild-vorschau:not([hidden]),
.mit-skript .bild-feld-auswahl {
  display: inline-flex;
}

.mit-skript .bild-ziehen {
  display: inline;
}

.bild-feld:focus-within {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.bild-feld.ziehen-aktiv {
  border-color: var(--color-accent);
}

/* Mit .bild-feld davor: Das Markup trägt auch .avatar, das weiter unten steht und sonst gewönne. */
.bild-feld .bild-vorschau {
  flex-shrink: 0;
  width: 3.5rem;
  height: 3.5rem;
  font-size: 1.125rem;
}

.bild-feld-text {
  display: flex;
  flex-direction: column;
}

.bild-feld-auswahl {
  color: var(--color-accent-text);
  text-decoration: underline;
}

/* --- Auswahl --------------------------------------------------------------------------------- */

/* Segment: zwei bis fünf gleichrangige Optionen; die gewählte liegt weiß auf grauem Grund. */
.segment {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 0.25rem;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: 1.375rem;
}

.segment a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.25rem;
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s, color 0.15s;
}

.segment a:hover {
  color: var(--color-text);
}

.segment a[aria-current="page"] {
  background: var(--color-surface);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--color-text) 12%, transparent),
    0 0 0 1px var(--color-border);
  color: var(--color-text);
  font-weight: 600;
}

.segment a:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Schalter: natives Kontrollkästchen mit role="switch", die ganze Zeile ist die Beschriftung. */
.schalter-liste {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--color-border);
}

.schalter-zeile {
  display: flex;
  align-items: center;
  gap: 1rem;
  cursor: pointer;
}

/* Gesperrt: lässt sich hier nicht umlegen, etwa die eigene Admin-Rolle. */
.schalter-zeile.gesperrt {
  opacity: 0.5;
  cursor: default;
}

.schalter-liste .schalter-zeile {
  gap: 1.25rem;
  padding: 1rem 0;
  border-top: 1px solid var(--color-border);
}

.schalter-text {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.schalter-zeile input {
  appearance: none;
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 24px;
  margin: 0;
  border-radius: 999px;
  background: var(--color-border-strong);
  cursor: pointer;
  transition: background-color 0.15s;
}

.schalter-zeile input::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--color-text) 25%, transparent);
  transition: transform 0.15s;
}

.schalter-zeile input:checked {
  background: var(--color-accent);
}

.schalter-zeile input:checked::before {
  transform: translateX(20px);
}

/* Auswahlfläche: eine von wenigen Optionen mit Erklärung; das Radio bleibt sichtbar. */
.auswahl {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border: 1.5px solid var(--color-border);
  border-radius: 6px;
  cursor: pointer;
}

.auswahl:hover {
  border-color: var(--color-accent);
}

.auswahl:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--color-accent-tint);
}

.auswahl:focus-within {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.auswahl input {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--color-accent-text);
}

.auswahl-text {
  display: flex;
  flex-direction: column;
}

/* --- Karten ---------------------------------------------------------------------------------- */

.karten {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}

.karte {
  padding: 1rem 1.25rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: var(--shadow-flach);
}

.karte h2 {
  margin-top: 0;
  font-size: 1.125rem;
}

.karte a {
  margin-right: 1rem;
}

/* --- Tags, Chips, Livepunkt ------------------------------------------------------------------ */

/* Tag: kleiner Zustand. Der Normalfall trägt keinen. */
.tag {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  background: var(--color-accent-tint);
  color: var(--color-accent-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.tag-warnung {
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
}

.tag-gefahr {
  background: var(--color-danger-tint);
  color: var(--color-danger);
}

.tag-neutral {
  background: var(--color-neutral-tint);
  color: var(--color-muted);
}

/* Chip: der Zustand einer ganzen Karte, mit Symbol oder Livepunkt. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 1.875rem;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  background: var(--color-accent-tint);
  color: var(--color-accent-text);
  font-size: 0.875rem;
  font-weight: 600;
}

.chip-warnung {
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
}

/* Neutral: eine Angabe ohne Zustand (Anzahl, Person, Verweis), Prototyp „OPTIHub Nachzug“. */
.chip-neutral {
  background: var(--color-background);
  color: var(--color-text);
  font-weight: 500;
}

.chip svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chip-neutral svg {
  stroke: var(--color-muted);
}

/* Als Link (etwa zur Speisekarte) mit Rand, beim Zeigen dunkler. */
a.chip-neutral {
  border: 1px solid var(--color-border);
  text-decoration: none;
}

a.chip-neutral:hover {
  border-color: var(--color-muted);
  color: var(--color-text);
}

/* Zeigt, dass etwas gerade läuft. */
.livepunkt {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-accent);
  animation: puls 2s ease-in-out infinite;
}

.chip-warnung .livepunkt {
  background: var(--color-warning);
}

@keyframes puls {
  50% {
    opacity: 0.35;
  }
}

/* --- Avatare --------------------------------------------------------------------------------- */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  object-fit: cover;
}

.avatar-initialen {
  background: var(--color-accent-tint);
  color: var(--color-accent-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.avatar-klein {
  width: 1.75rem;
  height: 1.75rem;
  font-size: 0.6875rem;
}

.avatar-mittel {
  width: 2.5rem;
  height: 2.5rem;
  flex-shrink: 0;
}

.avatar-gross {
  width: 6rem;
  height: 6rem;
  font-size: 2rem;
}

/* --- Tabelle --------------------------------------------------------------------------------- */

.tabelle {
  width: 100%;
  border-collapse: collapse;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}

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

.tabelle th {
  font-size: 0.875rem;
  color: var(--color-muted);
}

/* Zeilenköpfe (th scope="row") sind Inhalt, keine Spaltenköpfe. 600 statt der fetten Vorgabe des
   Browsers (DESIGN.html, Kapitel 3: 700 kommt nicht vor). */
.tabelle tbody th {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-text);
}

.tabelle .reihe-aktion + .reihe-aktion {
  margin-left: 0.25rem;
}

/* Letzte Spalte mit den Aktionen einer Zeile: rechtsbündig, Knöpfe nebeneinander. */
.tabelle-aktion {
  text-align: right;
  white-space: nowrap;
}

.tabelle-aktion > * + * {
  margin-left: 0.5rem;
}

.tabelle-aktion form {
  display: inline-block;
  margin: 0;
}

/* Ein schlichter Link als Aktion („Buchungen ansehen“). */
.tabelle-aktion a:not([class]) {
  font-size: 0.875rem;
  font-weight: 600;
}

/* Text nur in der gestapelten Fassung am Handy (Zahl mit Wort, Zeitraum) bzw. nur in der Tabelle. */
.tabelle-handy {
  display: none;
}

/* Gestapelte Zeilen am Handy (DESIGN.html, Kapitel 5; Prototyp „OPTIHub Nachzug“): Zeilenkopf
   oben, die übrigen Zellen darunter in einer Zeile mit Trennpunkt, Aktionen als Knöpfe darunter.
   Eine einzelne Aktion als ⋯-Knopf steht rechts über alle Zeilen. Spaltenköpfe entfallen. */
@media (max-width: 30rem) {
  .tabelle-stapel {
    position: relative;
  }

  .tabelle-stapel,
  .tabelle-stapel tbody {
    display: block;
  }

  /* Unsichtbar, aber für Vorlesewerkzeuge da: Sie nennen weiter die Spalte jeder Zelle. */
  .tabelle-stapel thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .tabelle-stapel tr {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.375rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--color-border);
  }

  .tabelle-stapel tr:last-child {
    border-bottom: none;
  }

  .tabelle-stapel :is(th, td) {
    padding: 0;
    border: none;
  }

  .tabelle-stapel tbody th {
    flex-basis: 100%;
    font-size: 1rem;
  }

  .tabelle-stapel td {
    font-size: 0.875rem;
    color: var(--color-muted);
  }

  .tabelle-stapel td:not(.tabelle-aktion) ~ td:not(.tabelle-aktion, .tabelle-breit, .tabelle-zeile)::before {
    content: "· ";
  }

  /* Eine Zelle mit vielen Tags bekommt eine eigene Zeile, sonst bräche sie hinter dem Punkt um. */
  .tabelle-stapel .tabelle-zeile {
    flex-basis: 100%;
  }

  .tabelle-stapel .tabelle-handy {
    display: inline;
  }

  .tabelle-stapel .tabelle-breit {
    display: none;
  }

  .tabelle-stapel .tabelle-aktion {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
    white-space: normal;
  }

  .tabelle-stapel .tabelle-aktion > * + * {
    margin-left: 0;
  }

  .tabelle-stapel tr:has(.tabelle-aktion > .mehr-knopf) {
    padding-right: 3.75rem;
  }

  .tabelle-stapel .tabelle-aktion:has(> .mehr-knopf) {
    position: absolute;
    top: 50%;
    right: 0.5rem;
    flex-basis: auto;
    margin: 0;
    transform: translateY(-50%);
  }
}

/* --- Hinweise -------------------------------------------------------------------------------- */

/* Rückmeldung nach einer Aktion; bleibt stehen, bis die Seite neu lädt. Mit data-toast macht
   /plattform/js/toast.js daraus einen Toast (unten). */
.hinweis {
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--color-accent);
  background: var(--color-background);
}

.hinweis-fehler {
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--color-danger);
  background: var(--color-background);
}

/* Rückmeldung mit Aufstellung darunter: der Satz fett, die Liste normal. */
:is(.hinweis, .hinweis-warnung, .hinweis-fehler) > p {
  margin: 0;
  font-weight: 600;
}

/* Gespeichert, aber noch nicht überall angekommen. */
.hinweis-warnung {
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--color-warning);
  background: var(--color-background);
}

.hinweis-still {
  color: var(--color-muted);
  font-size: 0.875rem;
}

/* Folgen eines Schritts vor der Bestätigung. Farbig ist nur die Überschrift. */
.warnblock {
  display: flex;
  align-items: flex-start;
  gap: 0.875rem;
  padding: 1rem;
  border-left: 3px solid;
  border-radius: 6px;
}

.warnblock svg {
  flex-shrink: 0;
  margin-top: 1px;
}

.warnblock strong {
  font-weight: 600;
}

.warnblock p {
  margin: 0.25rem 0 0;
  color: var(--color-text);
}

.warnblock-warnung {
  background: var(--color-warning-tint);
  border-color: var(--color-warning);
  color: var(--color-warning-text);
}

.warnblock-gefahr {
  background: var(--color-danger-tint);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.warnblock-gesperrt {
  background: var(--color-neutral-tint);
  border-color: var(--color-muted);
  color: var(--color-muted);
}

/* --- Toast ----------------------------------------------------------------------------------- */

/* Erfolgsmeldung unten rechts, verschwindet nach 5 s (/plattform/js/toast.js, Prototyp
   „OPTIHub Toasts“). Fehler und Warnungen werden nie zum Toast. */
.toast-bereich {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 50;
  max-width: min(25rem, calc(100vw - 1.5rem));
}

.toast {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.375rem 0.375rem 0.375rem 1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: var(--shadow-karte);
  animation: toast-ein 0.2s ease-out;
  transition: opacity 0.2s;
}

.toast-weg {
  opacity: 0;
}

.toast-zeichen {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--color-accent-tint);
}

.toast-zeichen svg {
  width: 0.875rem;
  height: 0.875rem;
  fill: none;
  stroke: var(--color-accent-text);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.toast-text {
  flex: 1;
  margin: 0;
  line-height: 1.4;
}

.toast-schliessen {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--color-muted);
  cursor: pointer;
}

.toast-schliessen:hover {
  color: var(--color-text);
}

.toast-schliessen svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
}

@keyframes toast-ein {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

@keyframes toast-blende {
  from {
    opacity: 0;
  }
}

/* --- Dialoge --------------------------------------------------------------------------------- */

/* Natives <dialog> oder Popover; ohne Skript öffnet es über popovertarget. */
.dialog {
  width: 56.25rem;
  max-width: calc(100% - 2rem);
  max-height: calc(100% - 2rem);
  margin: auto;
  padding: 0;
  overflow: auto;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: var(--shadow-karte);
}

.dialog::backdrop {
  background: color-mix(in srgb, var(--color-text) 40%, transparent);
}

/* Vom Server offen geliefert und (noch) nicht modal, etwa ohne Skript: über der Seite statt im
   Fluss. Das Skript macht ihn danach modal. */
.dialog[open]:not(:modal) {
  position: fixed;
  inset: 0;
  z-index: 40;
}

.dialog-inhalt {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.dialog-schliessen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-end;
  width: 32px;
  height: 32px;
  margin: 1rem 1rem 0;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
}

.dialog-schliessen:hover {
  background: var(--color-background);
  color: var(--color-text);
}

.dialog-schritt {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 0 2rem 1.5rem;
}

.dialog-schritt:not([hidden]) {
  flex-grow: 1;
}

.dialog-schritt h3 {
  margin: 0;
  font-size: 1.125rem;
}

.dialog-schritt p {
  margin: 0;
}

.dialog-fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 2rem;
  border-top: 1px solid var(--color-border);
}

/* Großer Dialog: links Titel und Schritte, rechts Inhalt und Fußleiste. */
.dialog-raster {
  display: grid;
  grid-template-columns: 17.5rem minmax(0, 1fr);
  min-height: 36.25rem;
}

.dialog-seite {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 1.5rem;
  background: var(--color-background);
  border-right: 1px solid var(--color-border);
}

.dialog-seite h2 {
  margin: 0;
  font-size: 1.375rem;
  line-height: 1.3;
}

.dialog-schritte {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--color-muted);
}

.dialog-schritte li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.dialog-kreis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border: 1.5px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
  font-size: 0.875rem;
  font-weight: 600;
}

.dialog-kreis svg,
.dialog-schritte li[data-fertig] .dialog-kreis span {
  display: none;
}

.dialog-schritte li[data-fertig] .dialog-kreis svg {
  display: block;
}

.dialog-schritte li[aria-current] .dialog-kreis,
.dialog-schritte li[data-fertig] .dialog-kreis {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-text);
}

.dialog-schritte li[aria-current] {
  color: var(--color-text);
  font-weight: 600;
}

.dialog-schritt-text {
  display: flex;
  flex-direction: column;
}

.dialog-schritt-text span {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--color-muted);
}

/* Schmaler Dialog: eine Spalte mit Kopf. */
.dialog-schmal {
  width: 38.75rem;
}

.dialog-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem 1rem 0 2rem;
}

.dialog-kopf h2 {
  margin: 0;
  font-size: 1.375rem;
  line-height: 1.3;
}

.dialog-kopf .dialog-schliessen {
  align-self: flex-start;
  margin: 0;
}

/* Rückfrage vor einem Schritt, der sich nicht zurücknehmen lässt. */
.dialog-frage .dialog-inhalt {
  gap: 1.375rem;
  padding: 1.5rem 1.5rem 1.25rem;
}

.dialog-frage .dialog-fuss {
  justify-content: flex-end;
  padding: 0;
  border-top: none;
}

.frage-kopf {
  display: flex;
  align-items: flex-start;
  gap: 0.875rem;
}

.frage-kopf h2 {
  margin: 0;
  font-size: 1.25rem;
  line-height: 1.25;
}

.frage-kopf p {
  margin: 0.375rem 0 0;
  color: var(--color-muted);
  text-wrap: pretty;
}

.frage-symbol {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
}

.frage-symbol-haken {
  background: var(--color-accent-tint);
  color: var(--color-accent-text);
}

.frage-symbol-warnung {
  background: var(--color-warning-tint);
  color: var(--color-warning-text);
}

/* --- Seitenkopf ------------------------------------------------------------------------------ */

/* Titel mit Zusatz links, Hauptknopf der Seite rechts. */
.seitenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.seitenkopf-titel {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.seitenkopf-titel h1 {
  margin: 0;
}

.seitenkopf-titel span {
  font-size: 0.9375rem;
  color: var(--color-muted);
}

/* --- Leerzustand ----------------------------------------------------------------------------- */

/* Steht in einer Karte: Titel, ein Satz, der erste Schritt; mit .skelett daneben zweispaltig. */
.leerkarte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 3rem 3.5rem;
}

.leerkarte:has(> .skelett) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 20rem;
  align-items: center;
  gap: 2.5rem;
}

/* Symbol über Titel und Satz. */
.leerkarte > svg {
  width: 40px;
  height: 40px;
  margin-bottom: 0.75rem;
  fill: none;
  stroke: var(--color-muted);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.leerkarte h2 {
  margin: 0 0 0.5rem;
  font-size: 1.75rem;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.leerkarte p {
  margin: 0;
  max-width: 34rem;
  color: var(--color-muted);
  text-wrap: pretty;
}

.leerkarte .knopf {
  margin-top: 1.25rem;
}

/* Drei verblassende Listenzeilen deuten an, was hier einmal stehen wird. */
.skelett {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 1.125rem;
  border: 1px dashed var(--color-border);
  border-radius: 6px;
}

.skelett span {
  display: block;
  height: 2.5rem;
  background:
    linear-gradient(var(--color-neutral-tint), var(--color-neutral-tint)) 54px 8px / 60% 10px
      no-repeat,
    linear-gradient(var(--color-background), var(--color-background)) 54px 26px / 38% 8px no-repeat,
    linear-gradient(var(--color-background), var(--color-background)) 0 0 / 40px 40px no-repeat;
}

.skelett span:nth-child(2) {
  opacity: 0.6;
}

.skelett span:nth-child(3) {
  opacity: 0.3;
}

/* --- Fehlerseite ----------------------------------------------------------------------------- */

/* Eine ganze Seite geht nicht (DESIGN.html, Kapitel 6; Prototyp „OPTIHub Fehlerseite“): Symbol im
   Kreis, Titel, ein Satz, ein Knopf, mittig. .fehlerseite ist die Karte einzeln auf dem Grund; in
   einer anderen Karte (Anmeldeseiten des Hubs) reicht .fehlerseite-inhalt. */
.fehlerseite-inhalt {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.fehlerseite {
  gap: 1.5rem;
  width: 32rem;
  max-width: 100%;
  margin: 3rem auto 0;
  padding: 2.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: var(--shadow-karte);
}

/* Kein Blatt hinter der Fehlerseite: Die Karte liegt allein auf dem Grund. */
.app-main:has(> .fehlerseite) {
  margin-top: 3rem;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
}

.fehlerseite-inhalt h1 {
  margin: 0;
  font-weight: 600;
}

.fehlerseite-inhalt p {
  margin: 0;
}

.fehlerseite-text {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.fehlerseite-symbol {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-background);
  border: 1px solid var(--color-border);
}

.fehlerseite-symbol svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: var(--color-muted);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.fehlerseite-hinweis {
  font-size: 0.875rem;
  color: var(--color-muted);
}

@media (max-width: 30rem) {
  .app-main:has(> .fehlerseite) {
    width: calc(100% - 2rem);
    margin-top: 2rem;
  }
}

/* --- Anmeldeseite --------------------------------------------------------------------------- */

/* Anmeldung per Link im Hub und unter der Domain jeder App (DESIGN.html, Kapitel 5; Prototypen
   „OPTIHub Anmeldung“ und „OPTIHub App-Anmeldung“): Logo über einer Karte, ohne Kopfzeile. Unter
   der Domain einer App kommen Akzent und Muster aus deren app.css, das Logo aus ihren Bildern. */
.anmeldung-inhalt {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 40px;
  padding: 64px 32px;
}

.anmeldung-logo {
  display: block;
  width: 320px;
  max-width: 100%;
  height: auto;
}

.anmeldung-karte {
  display: flex;
  flex-direction: column;
  gap: 32px;
  width: 480px;
  max-width: 100%;
  padding: 40px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: var(--shadow-karte);
}

.anmeldung-karte h1 {
  margin: 0;
}

.anmeldung-text {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
}

.anmeldung-text p {
  margin: 0;
}

.anmeldung-karte .hinweis-fehler {
  margin: 0;
}

.formular {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
}

/* Logo einer App: gleiche Höhe wie das OPTINVEST-Logo des Hubs, Breite nach dem Seitenverhältnis. */
.anmeldung-logo-app {
  width: auto;
  height: 148px;
}

/* Unter der Karte einer App: Die Anmeldung läuft über OPTINTERN und gilt für alle Apps. */
.anmeldung-hinweis {
  max-width: 480px;
  margin: 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--color-muted);
}

/* Zweiter Faktor (Prototyp „OPTIHub Zweiter Faktor“): Einrichten, Code eingeben, Erfolg. Dieselbe
   Karte wie die Anmeldung, im Look des Hubs oder der App. */
.faktor-schritte {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.faktor-schritte > li {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 4px 12px;
}

.faktor-nummer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1.5px solid var(--color-border-strong);
  border-radius: 50%;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-muted);
}

.faktor-schritt-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 3px;
}

.faktor-schritt-text strong {
  font-weight: 600;
}

.faktor-schritt-text p {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--color-muted);
}

.faktor-schritt-text .code-feld {
  margin-top: 8px;
}

/* Weiß auch auf getöntem Grund, damit Kameras den Code sicher lesen. */
.faktor-qr {
  width: 168px;
  height: 168px;
  margin-top: 8px;
  padding: 8px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 6px;
}

.faktor-qr svg {
  display: block;
  width: 100%;
  height: 100%;
}

.faktor-geheimnis {
  margin-top: 4px;
  font-size: 0.875rem;
}

.faktor-geheimnis summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--color-accent-text);
}

.faktor-geheimnis p {
  margin: 8px 0 0;
  font-size: 0.875rem;
  color: var(--color-muted);
}

.faktor-schluessel {
  display: block;
  margin-top: 8px;
  padding: 10px 12px;
  font-family: var(--font-mono);
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  word-spacing: 0.4em;
  color: var(--color-text);
  background: var(--color-background);
  border-radius: 4px;
  user-select: all;
}

/* Sechs Ziffern: Monospace, gesperrt, so breit wie der Code. */
.code-feld input {
  width: 11ch;
  font-family: var(--font-mono);
  font-size: 1.375rem;
  letter-spacing: 0.3em;
  text-align: center;
}

.code-feld input:disabled {
  background: var(--color-background);
  color: var(--color-muted);
  cursor: not-allowed;
}

/* Unter dem Formular: wer angemeldet ist, und der Ausweg. */
.faktor-konto {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
  font-size: 0.875rem;
  color: var(--color-muted);
}

.faktor-konto p,
.faktor-konto form {
  margin: 0;
}

.faktor-konto .text-knopf {
  display: inline;
}

.faktor-erfolg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-accent-tint);
  color: var(--color-accent-text);
}

@media (max-width: 30rem) {
  .anmeldung-inhalt {
    gap: 32px;
    padding: 32px 16px;
  }

  .anmeldung-logo {
    width: 240px;
  }

  .anmeldung-karte {
    gap: 24px;
    padding: 24px;
  }

  .anmeldung-karte :is(input, .knopf) {
    min-height: 44px;
  }

  .anmeldung-logo-app {
    width: auto;
    height: 112px;
  }
}

/* --- Bewegung und Handy ---------------------------------------------------------------------- */

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

  .toast {
    animation-name: toast-blende;
  }
}

/* Am Handy über die Breite, über der Tab-Leiste (basis.css, .app-nav). */
@media (max-width: 30rem) {
  .toast-bereich {
    right: 0.75rem;
    bottom: 5rem;
    left: 0.75rem;
    max-width: none;
  }
}

@media (max-width: 62rem) {
  .leerkarte:has(> .skelett) {
    grid-template-columns: minmax(0, 1fr);
  }

  .skelett {
    display: none;
  }
}

@media (max-width: 30rem) {
  /* Touch-Ziele mindestens 44 px. */
  :is(.knopf, .knopf-zweit, .knopf-gefahr, .knopf-warnung) {
    padding-top: 0.625rem;
    padding-bottom: 0.625rem;
  }

  .segment a {
    min-height: 44px;
  }

  .seitenkopf .knopf-symbol {
    justify-content: center;
    width: 100%;
  }

  .mehr-knopf {
    width: 44px;
    height: 44px;
  }

  .feld-paar {
    grid-template-columns: minmax(0, 1fr);
  }

  .feld :where(input:not([type="checkbox"], [type="radio"], [type="file"]), select) {
    min-height: 44px;
  }

  .mit-skript .bild-feld {
    padding: 0;
    border: none;
  }

  /* Ziehen gibt es am Handy nicht; der Knopf genügt. */
  .mit-skript .bild-ziehen {
    display: none;
  }

  .bild-feld .bild-vorschau {
    width: 4rem;
    height: 4rem;
  }

  .bild-feld-auswahl {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    color: var(--color-text);
    font-weight: 600;
    text-decoration: none;
  }

  .schalter-liste .schalter-zeile {
    gap: 1rem;
    min-height: 44px;
    padding: 0.875rem 0;
  }

  .auswahl {
    min-height: 44px;
  }

  .leerkarte {
    padding: 1.75rem 1.25rem;
  }

  .leerkarte h2 {
    font-size: 1.375rem;
  }

  /* Dialoge im Vollbild: oben Kreuz und Titel, darunter die Schritte als Kreise, der Inhalt
     scrollt, die Fußleiste bleibt unten. */
  .dialog {
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    border: none;
    border-radius: 0;
  }

  /* Die Rückfrage bleibt eine Karte über der Seite. fit-content, weil inset: 0 auto aushebelt. */
  .dialog.dialog-frage {
    width: calc(100% - 2rem);
    height: fit-content;
    border: 1px solid var(--color-border);
    border-radius: 6px;
  }

  .dialog-frage .dialog-inhalt {
    display: flex;
  }

  /* Beide Knöpfe gleich breit; passen sie nicht nebeneinander, stehen sie untereinander. */
  .dialog-frage .dialog-fuss {
    flex-wrap: wrap;
    padding: 0;
  }

  .dialog-frage .dialog-fuss > * {
    flex: 1 1 auto;
    justify-content: center;
  }

  .dialog-raster {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    height: 100%;
    min-height: 0;
  }

  .dialog-seite,
  .dialog-inhalt {
    display: contents;
  }

  .dialog-seite h2 {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
    font-size: 1.25rem;
  }

  .dialog-schliessen {
    grid-column: 1;
    grid-row: 1;
    width: 44px;
    height: 44px;
    margin: 0.5rem 0.25rem 0;
  }

  .dialog-schritte {
    grid-column: 1 / -1;
    grid-row: 2;
    flex-direction: row;
    gap: 1.25rem;
    margin: 0.5rem 1rem 0;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 0.875rem;
  }

  .dialog-schritte li {
    align-items: center;
    gap: 0.5rem;
  }

  .dialog-kreis {
    width: 24px;
    height: 24px;
    font-size: 0.8125rem;
  }

  .dialog-schritt-text span {
    display: none;
  }

  .dialog-schritt {
    grid-column: 1 / -1;
    overflow-y: auto;
    padding: 1.25rem 1rem;
  }

  .dialog-fuss {
    grid-column: 1 / -1;
    padding: 0.75rem 1rem;
  }

  .dialog-fuss > button {
    flex: 1;
    min-height: 44px;
  }

  .dialog-schmal {
    width: 100%;
  }

  .dialog-kopf {
    padding: 1rem 0.5rem 0 1rem;
  }

  .dialog-schmal .dialog-schritt {
    padding: 0 1rem 1rem;
  }

  .dialog-schmal .dialog-fuss {
    padding: 1rem;
  }

  .dialog-schmal button {
    min-height: 44px;
  }
}
