/* ==========================================================================
   Formulare im geschlossenen Bereich (Fehlermeldung, Verwaltung).
   Ergaenzt style.css — nutzt ausschliesslich dessen Tokens aus :root.
   ========================================================================== */

.form-page { max-width: 46rem; margin-inline: auto; padding-block: calc(var(--nav-h) + 3rem) 4rem; }

.public-form-page { padding-top: calc(var(--nav-h) + 3rem); }
.public-form-title { text-align: left; }
.public-form-lead { margin: 0 0 1.8rem; text-align: left; }
.public-form-submit { margin-top: 1.25rem; }
.public-form-success p { margin: .75rem 0 0; }
.public-form-alternative { margin: 1.2rem 0 0; color: var(--ink-dim); }
.public-form-alternative a, .privacy-note a { color: var(--gold-2); }
.captcha-wrap { margin-top: 1.35rem; min-height: 65px; }
.form-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

.form-card {
  background: linear-gradient(180deg, var(--bg-2), var(--bg-3));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.8rem 1.6rem;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}

/* Der Kartengrund laeuft bis --bg-3 (#123039) hoch. Dort traegt --ink-faint
   nur 3,7:1 und verfehlt die 4,5:1 fuer Kleinschrift — auf dem alten, dunklen
   Braunschwarz war das noch nicht so. Innerhalb der Karten wird die leise
   Schrift deshalb auf die Mitte zwischen --ink-faint und --ink-dim gehoben:
   5,2:1 am hellsten Punkt, und der Rangunterschied zur normalen Schrift
   bleibt erhalten. */
.form-card, .stat { --ink-faint: #8da2a8; }

.field + .field { margin-top: 1.3rem; }
/* Steht ein Hinweistext zwischen zwei Feldern, greift die Geschwister-Regel
   oben nicht mehr — die Felder klebten dann aneinander. */
.field + p + .field,
p + .field { margin-top: 1.3rem; }

/* .field-row zaehlt fuer den Abstand wie ein Feld.
   Bisher galt die Regel nur zwischen zwei .field. Sobald eine .field-row
   danebenstand, fiel der Abstand auf 0 — und weil die Reihe unterhalb von
   34rem auf eine Spalte zusammenklappt, stiess auf dem Handy der Hinweistext
   des letzten Feldes ohne jede Luft an die Beschriftung des naechsten.
   Nachgemessen bei 360 px auf /admin?b=konten: „Anzeigename" endete bei
   y=703, „E-Mail" begann bei y=703, margin-top 0px. Dieselbe Stelle gibt es
   auf /admin?b=einladungen (Rolle -> Notiz) und /bug (Nachstellen -> Wo war
   das?). Am Schreibtisch stehen die Reihen untereinander, dort fehlte der
   Abstand also genauso. */
.field-row + .field-row,
.field + .field-row,
.field-row + .field,
.field-row + p + .field,
.field + p + .field-row,
p + .field-row { margin-top: 1.3rem; }

.field label {
  display: block;
  font-size: .74rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .45rem;
}

/* Bewusst nicht auf [type=text] eingeschraenkt: Passwort- und E-Mail-Felder
   sind genauso Eingaben. Vorher fielen sie durch das Raster und standen in der
   weissen Voreinstellung des Browsers da — auf dem dunklen Grund drei grelle
   Kaesten mitten im Formular. */
.field input:not([type=hidden]),
.field textarea,
.field select {
  width: 100%;
  padding: .7rem .85rem;
  font: inherit;
  color: var(--ink);
  background: rgba(0, 0, 0, .34);
  border: 1px solid var(--line);
  border-radius: 9px;
  transition: border-color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}

.field textarea { min-height: 7.5rem; resize: vertical; line-height: 1.6; }

/* Vorher stand hier ein pauschales outline:none. Schein und Rand tragen gegen
   den Kartengrund aber nur 1,6 bzw. 2,2:1 — als einziger Fokushinweis zu
   wenig. Abgeschaltet wird der Umriss deshalb nur noch dort, wo er nicht
   gebraucht wird (:focus:not(:focus-visible)); Felder, die Tastatureingaben
   annehmen, erfuellen :focus-visible laut Spezifikation immer und behalten
   den Umriss aus style.css (--ember-2, 7,8:1 gegen die Karte). */
.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--line-strong);
  box-shadow: 0 0 0 3px rgba(240, 128, 32, .3);
}
.field input:focus:not(:focus-visible),
.field textarea:focus:not(:focus-visible),
.field select:focus:not(:focus-visible) { outline: none; }

.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"],
.field select[aria-invalid="true"] {
  border-color: var(--ember);
  box-shadow: 0 0 0 2px rgba(240, 128, 32, .2);
}

/* Bewusst ohne .field davor: der Nutzerbereich setzt den Hinweis direkt in
   die Karte, ohne ihn in ein Eingabefeld einzupacken. */
.help { margin: .4rem 0 0; font-size: .82rem; color: var(--ink-faint); }

.field-row { display: grid; gap: 1.3rem; grid-template-columns: 1fr 1fr; }
@media (max-width: 34rem) { .field-row { grid-template-columns: 1fr; } }

/* Meldungen -------------------------------------------------------------- */
.notice {
  margin: 0 0 1.4rem;
  padding: .85rem 1rem;
  border-radius: 9px;
  font-size: .92rem;
  border: 1px solid rgba(240, 128, 32, .45);
  background: rgba(240, 128, 32, .1);
  color: #ffcfb5;
}
/* Gelungen ist tuerkis wie das Blattwerk im Emblem — nicht mehr moosgruen,
   das im Logo nirgends vorkommt. */
.notice.ok { border-color: rgba(79, 179, 191, .45); background: rgba(79, 179, 191, .1); color: #bfe4e8; }
.notice.danger { border-color: rgba(240, 128, 32, .7); background: rgba(192, 64, 16, .16); color: #ffd2bd; }
.notice ul { margin: .4rem 0 0; padding-left: 1.1rem; }
.notice a { color: inherit; }

.confirm-danger h2 { margin: 0 0 .45rem; font: 400 1.25rem/1.25 var(--font-display); color: var(--gold-2); }
.confirm-danger p { margin: .45rem 0 0; }
.confirm-actions { display: flex; flex-wrap: wrap; gap: .65rem; margin-top: 1rem; }
.confirm-actions .btn { justify-content: center; }

.btn-danger {
  color: #ffe0d2;
  background: rgba(192, 64, 16, .22);
  border: 1px solid rgba(240, 128, 32, .72);
}
.btn-danger:hover {
  color: #fff3ec;
  border-color: var(--ember-2);
  background: rgba(192, 64, 16, .34);
  box-shadow: 0 0 20px rgba(240, 128, 32, .25);
}

/* Tabelle der Konten ----------------------------------------------------- */
/* Die Tabelle scrollt waagerecht — nachgemessen bei 360 px: 312 px Kasten,
   824 px Inhalt (Konten), 1154 px (Einladungen). Nur war das nicht zu sehen:
   auf dem Telefon blendet das Betriebssystem den Balken aus, und die Tabelle
   endete einfach mitten in einer Spalte. Die Aktionsknoepfe („Bannen",
   „Loeschen") lagen dabei bei x=581..834 — weit ausserhalb des Bildes, ohne
   jeden Hinweis, dass es dort weitergeht.

   Die vier Verlaeufe sind der uebliche Weg dafuer, ganz ohne Skript:
   die beiden „scroll"-Lagen liegen fest am Rand und glimmen golden, die
   beiden „local"-Lagen fahren mit dem Inhalt mit und decken den Schein zu,
   solange man am Anfang bzw. Ende angekommen ist. Der Schein ist reine
   Dekoration — die Information selbst (abgeschnittene Spalte) bleibt
   sichtbar, es gibt also keine Farbe, die getragen werden muesste. */
.table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background:
    /* Abdecker: fahren mit dem Inhalt */
    linear-gradient(to right, var(--bg) 55%, rgba(7, 19, 26, 0)) left / 28px 100% no-repeat,
    linear-gradient(to left,  var(--bg) 55%, rgba(7, 19, 26, 0)) right / 28px 100% no-repeat,
    /* Kantenschein: bleibt stehen */
    linear-gradient(to right, rgba(217, 168, 78, .30), rgba(217, 168, 78, 0)) left / 22px 100% no-repeat,
    linear-gradient(to left,  rgba(217, 168, 78, .30), rgba(217, 168, 78, 0)) right / 22px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
  /* Duenner, aber sichtbarer Balken, wo das Geraet ueberhaupt einen zeichnet */
  scrollbar-width: thin;
  scrollbar-color: var(--bg-3) transparent;
}
.table-wrap:focus-visible { outline-offset: 4px; }
table.grid { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.grid th, table.grid td { padding: .6rem .7rem; text-align: left; border-bottom: 1px solid var(--line); white-space: nowrap; }
table.grid th { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
table.grid tbody th[scope="row"] {
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  font-weight: 400;
}
table.grid tr:last-child :is(th, td) { border-bottom: 0; }
.badge { display: inline-block; padding: .1rem .5rem; border-radius: 999px; font-size: .72rem; border: 1px solid var(--line-strong); color: var(--gold-2); }
.badge.muted { border-color: var(--line); color: var(--ink-faint); }

/* Pruefsummen und andere lange Zeichenketten ----------------------------- */
.hash {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .74rem;
  color: var(--ink-faint);
  overflow-wrap: anywhere;
}

@media (prefers-reduced-motion: reduce) {
  .field input, .field textarea, .field select { transition: none; }
}

/* ==========================================================================
   Verwaltungsbereich
   ========================================================================== */

.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
  margin: 0 0 2rem;
  border-bottom: 1px solid var(--line);
}

.admin-tabs a {
  padding: .6rem 1rem;
  color: var(--ink-dim);
  text-decoration: none;
  font-size: .9rem;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--dur-1) var(--ease-ember), border-color var(--dur-1) var(--ease-ember);
}

.admin-tabs a:hover { color: var(--ink); }

.admin-tabs a[aria-current="page"] {
  color: var(--gold-2);
  border-bottom-color: var(--ember);
}

.admin-h2 {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.3rem;
}

.admin-section-gap { margin-top: 2.6rem; }
.request-grid .request-message {
  min-width: 18rem;
  max-width: 32rem;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.5;
}

/* Kennzahlen ------------------------------------------------------------- */
.stat-row { display: flex; flex-wrap: wrap; gap: .8rem; margin: 0 0 2.4rem; }

.stat {
  flex: 1 1 8.5rem;
  padding: .9rem 1rem;
  background: linear-gradient(180deg, var(--bg-2), var(--bg-3));
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.stat b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 400;
  color: var(--gold-2);
  line-height: 1.1;
}

.stat span { font-size: .78rem; color: var(--ink-faint); overflow-wrap: anywhere; }

/* Auffaellige Zahlen (Fehlversuche, Sperren) glimmen — nicht schreien. */
.stat-warn { border-color: rgba(240, 128, 32, .4); }
.stat-warn b { color: var(--ember-2); }

/* Ampel im System-Bereich ------------------------------------------------ */
.dot {
  display: inline-block;
  width: .62rem;
  height: .62rem;
  border-radius: 50%;
  vertical-align: middle;
}
.dot.ok      { background: var(--moss); box-shadow: 0 0 8px rgba(79, 179, 191, .5); }
.dot.bad     { background: var(--ember); box-shadow: 0 0 8px rgba(240, 128, 32, .55); }
.dot.neutral { background: var(--ink-faint); opacity: .5; }

/* Aktionsspalte: die Knoepfe sollen umbrechen statt die Tabelle zu sprengen */
table.grid td.actions { white-space: normal; min-width: 16rem; }
table.grid td.actions form { margin: 0 .2rem .25rem 0; }

/* Mit dem Finger bedient ----------------------------------------------------
   Die Knoepfe in der Aktionsspalte und im Bann-Formular tragen im Markup
   style="padding:.28rem .65rem" und messen damit 25 px, das Grundfeld 32 px —
   beides deutlich unter der 44er-Regel und ausgerechnet dort, wo geloescht
   und gebannt wird. min-height steht im Markup nicht, die Regel greift also
   ohne !important.

   Bewusst an (pointer: coarse) gebunden statt an eine Fensterbreite: mit der
   Maus bleibt der kompakte Satz, den die Tabelle am Schreibtisch braucht.

   Das Grundfeld bekommt zusaetzlich 16 px Schriftgroesse. Darunter zoomt
   Safari auf dem iPhone beim Antippen in das Feld hinein und laesst die
   Seite verschoben zurueck; .78rem sind 12,5 px. */
@media (pointer: coarse) {
  /* Bewusst auf alle Knoepfe der Seite bezogen, nicht nur auf die in der
     Tabelle: derselbe kompakte Satz kommt auch ausserhalb vor — „Jetzt
     aufraeumen" (23 px) und „Sitzungen beenden" (25 px) im Wartungs- und
     Systembereich. Die grossen Knoepfe messen ohnehin 53 px, fuer sie
     aendert die Untergrenze nichts. */
  .form-page .btn { min-height: 44px; }
  .ban-form input[type=text] { min-height: 44px; font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .admin-tabs a { transition: none; }
}

/* ==========================================================================
   Einladungen
   ========================================================================== */

/* Der frische Einladungslink.
   Er ist nach dem Verlassen der Seite unwiederbringlich weg — deshalb hebt er
   sich vom uebrigen Kasten ab und glimmt einmal auf, damit er nicht uebersehen
   wird. */
.invite-fresh { border-width: 2px; }

.invite-link {
  margin: .6rem 0 0;
  padding: .7rem .85rem;
  font-size: .92rem;
  color: var(--ink);
  background: rgba(0, 0, 0, .42);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  /* Zum Kopieren gedacht: der ganze Link soll mit einem Doppelklick in der
     Auswahl landen, nicht nur ein Wortstueck davon. */
  user-select: all;
  animation: invite-glow 1.6s var(--ease-ember) 2;
}

@keyframes invite-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217, 168, 78, 0); }
  50%      { box-shadow: 0 0 0 3px rgba(217, 168, 78, .22); }
}

.invite-mail { margin: .6rem 0 0; font-size: .88rem; color: var(--moss-2); }
.invite-mail.bad { color: var(--ember-2); }

/* ==========================================================================
   Bann
   ========================================================================== */

/* Grund und Schaltflaeche in einer Zeile — beides gehoert zu einem Klick. */
.ban-form { display: inline-flex; gap: .3rem; align-items: center; }

.ban-form input[type=text] {
  width: 11rem;
  padding: .28rem .5rem;
  font: inherit;
  font-size: .78rem;
  color: var(--ink);
  background: rgba(0, 0, 0, .34);
  border: 1px solid var(--line);
  border-radius: 7px;
  transition: border-color var(--dur-1) var(--ease-ember);
}
.ban-form input[type=text]:focus { border-color: var(--line-strong); }
.ban-form input[type=text]:focus:not(:focus-visible) { outline: none; }
.ban-form .btn { padding: .28rem .65rem; font-size: .78rem; }

/* Der Grund ist ein Satz, kein Schluesselwort: er darf umbrechen, waehrend der
   Rest der Tabelle in einer Zeile bleibt. */
.ban-reason {
  display: inline-block;
  max-width: 18rem;
  white-space: normal;
  color: var(--ember-2);
  font-size: .84rem;
}

@media (prefers-reduced-motion: reduce) {
  .invite-link { animation: none; }
  .ban-form input[type=text] { transition: none; }
}
