/**
 * Wiederverwendbare UI-Komponenten.
 *
 * Die Hauptnavigation stand von Phase 7.3 bis 8.2 hier (.menuitem/.main-nav/
 * a.menu, dazu .forum-nav .menuitem fuer die breiteren Forum-Kacheln). Mit dem
 * Shell-Umbau in Phase 8.3 ist sie nach layout.css gewandert und heisst dort
 * .site-nav/.site-nav__link -- Navigation ist Seiten-Chrome, keine
 * wiederverwendbare Komponente, und die alten Regeln beschrieben durchweg den
 * 86px-Kachelraster des Tabellenlayouts von 2003. Mit ihnen entfallen
 * --color-hover (der gruene Block beim Hover) und der letzte Konsument der
 * --frame-width-*-Tokens.
 */

/**
 * Phase 7.5 (FRONTEND.md): wiederverwendbare Bausteine fuer die "einfachen"
 * oeffentlichen Fragmente (Heimat, Ueber-uns-Uebersicht, Links, Login,
 * Funstuff, Fehlerseiten, Galerie-Platzhalter). Sie ersetzten dort die reinen
 * Layout-<table>s -- aber als 1:1-Nachbildung: fuenf verschiedene Text/Bild-
 * Zweispalter (.home-row .about-row .links-row .news-row .members-row), jeder
 * mit eigenen, per getBoundingClientRect() aus dem Browser-Tabellenlayout von
 * 2003 zurueckgemessenen Abstaenden (43px/28px links in der Mitgliederliste,
 * 148px/94px beim Login, "30px 0 0 20px" bei Ueber-uns/Links, flex-basis 180px
 * in den Linkspalten) und einer Bildspalte mit flex-shrink:0, die am Handy nur
 * ueber den Media-Query-Notausgang aus 8.3 nicht ueber den Text rutschte.
 *
 * Phase 8.5 (REDESIGN.md) fasst das zu gemeinsamen Bausteinen zusammen:
 *
 *   .page-split   Inhaltsspalte + Bildspalte, stapelt unter 40rem -- ersetzt
 *                 alle fuenf Zweispalter samt ihrer Sonderabstaende
 *   .page-figure  Seitenfoto; die Groesse kommt aus dem CSS statt aus
 *                 height="290" im Markup
 *   .tile-grid    gegliederte Bloecke (Startseite) statt <br>-Abstaenden
 *   .card-list    Karten (News)
 *   .badge-list   Gruppen mit Rang-Badge (Mitgliederliste)
 *   .prose        Fliesstext (Impressum, Geschichten, Satzung)
 *
 * Damit steht in diesem Block kein zurueckgemessener px-Wert mehr; alle
 * Abstaende kommen aus der 4px-Skala.
 */

/* --- Seitenkopf eines Fragments ----------------------------------------- */

/* Fragmenttitel. Bis 8.5 hatte im oeffentlichen Bereich nur die Satzung eine
   <h1>; Startseite, News, Mitglieder, Links und die Fehlerseiten begannen mit
   nackten <b>-Zeilen oder direkt mit Inhalt. */
.page-title {
  margin-top: 0;
  text-align: left;
}

.page-lead {
  margin: calc(var(--space-3) * -1) 0 var(--space-8);
  color: var(--color-text-muted);
  font-size: var(--fs-lg);
  text-align: left;
}

/* Fusszeile eines Fragments (Disclaimer-Link + Besucherzaehler auf der
   Startseite). */
.page-meta {
  margin: var(--space-8) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  text-align: left;
}

/* --- Fliesstext --------------------------------------------------------- */

/* Ersetzt die <br><br>-Absatztrennung im Impressum und in der Detailansicht
   der Geschichten. --measure haelt die Zeilenlaenge lesbar (in 8.2 als Token
   gesetzt, im 605px-Rahmen damals noch wirkungslos). */
.prose {
  max-width: var(--measure);
  margin-inline: auto;
  text-align: left;
}

.prose p,
.prose ul,
.prose ol,
.prose dl {
  margin: 0 0 var(--space-4);
}

.prose > :last-child {
  margin-bottom: 0;
}

/* --- Zweispalter Inhalt/Bild -------------------------------------------- */

/* Ein Baustein fuer alle fuenf ehemaligen *-row-Varianten. Die Bildspalte
   schrumpft nicht (auto), die Inhaltsspalte darf es (minmax(0,1fr)) -- genau
   das fehlte den Flex-Varianten, deren min-width:auto den Text am Handy auf
   ~40px zusammendrueckte. */
.page-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-8);
  align-items: start;
  text-align: left;
}

.page-split__main {
  min-width: 0;
}

/* Seitenfotos (nk_quirinus2 / nk_balkon / nk_ot / nk_voigt / nk_bl / nk_tb /
   nk_quirin). Bis 8.5 stand die Hoehe als height="290" im Markup -- drei der
   sieben Bilder trugen sie, die anderen liefen in Originalgroesse. Jetzt
   durchgaengig aus dem CSS, und damit auch am Handy skalierbar. */
.page-figure {
  margin: 0;
}

.page-figure img {
  display: block;
  width: auto;
  height: auto;
  max-height: 18rem;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

/* --- Kacheln (Startseite) ----------------------------------------------- */

/* Die Startseite bestand aus vier Absaetzen, die per <br><br><br> auseinander
   gehalten wurden: Begruessung, Gruendungsjahr, News-Hinweis, Countdown. Die
   beiden letzten sind Kennzahlen und stehen jetzt als Kacheln. */
.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-4);
  text-align: left;
}

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  background: var(--brand-50);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--brand-600);
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
  transition: background-color var(--transition), box-shadow var(--transition);
}

a.tile:hover {
  background: var(--brand-100);
  box-shadow: var(--shadow-sm);
  color: var(--color-text);
}

.tile__label {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--brand-700);
}

.tile__value {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-tight);
}

.tile__hint {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

/* --- Karten (News) ------------------------------------------------------ */

.card-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  text-align: left;
}

.card {
  padding: var(--space-4) var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

/* Datums-Chip. Vorher trug .news-item ein "border-bottom: 1px dashed #000"
   als einzige Gliederung, das Datum stand als nackte Zeile darueber. */
.card__date {
  display: inline-block;
  margin: 0 0 var(--space-2);
  padding: 0 var(--space-2);
  background: var(--brand-100);
  border-radius: 999px;
  color: var(--brand-800);
  font-size: var(--fs-xs);
}

.card__title {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-lg);
}

.card__text {
  margin: 0;
}

.card__actions {
  margin: var(--space-3) 0 0;
  font-size: var(--fs-sm);
}

/* --- Gruppen mit Badge (Mitgliederliste) -------------------------------- */

/* Vorher zwei feste Namensspalten, die Raenge als Textmarker "[Oberleutnant]"
   in einem Absatz mit <br>-getrennten Namen. Jetzt je Rang eine Gruppe mit
   echter Ueberschrift.
   Mehrspaltensatz statt Grid: die Gruppen sind sehr unterschiedlich lang (ein
   Oberleutnant gegen 13 Schuetzen), ein Raster wuerde jede Zeile auf die
   hoechste Gruppe aufziehen und Loecher lassen. columns fliesst stattdessen. */
.badge-list {
  columns: 13rem auto;
  column-gap: var(--space-8);
  text-align: left;
}

.badge-group {
  break-inside: avoid;
  margin-bottom: var(--space-6);
}

.badge-group__title {
  margin: 0 0 var(--space-3);
}

/* Rang-Badge. Ersetzt sowohl die "[...]"-Textmarker der Mitgliederliste als
   auch das reine Fettschreiben als Gruppenmarke. --font-sans, weil die
   Ueberschriften-Schrift (Georgia) in Versalien auf so kleiner Stufe unruhig
   wird. */
.rank-badge {
  display: inline-block;
  padding: 0 var(--space-3);
  background: var(--brand-100);
  border: 1px solid var(--brand-600);
  border-radius: 999px;
  color: var(--brand-800);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .03em;
}

.name-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.name-list li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* --- Linklisten --------------------------------------------------------- */

/* Ersetzt .plain-list im ganzen Baum (Ueber uns, Links, Geschichten-Uebersicht,
   seit 8.6 auch das Adminmenue und die Aufzaehlungen des Mitgliederbereichs). */
.link-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.link-list li::before {
  content: "\2013\a0";
  color: var(--color-text-muted);
}

.link-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-6);
  align-items: start;
  text-align: left;
}

.link-group__title {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-lg);
}

/* Zurueck-Link ueber/unter einem Detailtext (Geschichten). Vorher "[<a>...</a>]"
   in einer <br><br>-Kette. */
.link-back {
  margin: 0 0 var(--space-6);
  font-size: var(--fs-sm);
  text-align: left;
}

.link-back--bottom {
  margin: var(--space-6) 0 0;
}

/* --- Hinweisbox --------------------------------------------------------- */

/* Fehlerseiten (401/403/404/500/na), Impressum-Ansprechpartner,
   Galerie-Platzhalter, dazu die beiden Upload-Formulare der Galerie
   (--wide, s. 8.7). Bis 8.4 ein reines inline-block ohne Flaeche, dessen
   Zentrierung aus dem text-align des Containers kam. */
.notice-box {
  max-width: var(--measure);
  margin-inline: auto;
  padding: var(--space-4) var(--space-6);
  background: var(--brand-50);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--brand-600);
  border-radius: var(--radius);
  text-align: left;
  font-size: var(--fs-lg);
}

.notice-box > :first-child {
  margin-top: 0;
}

.notice-box > :last-child {
  margin-bottom: 0;
}

/* --wide traegt Formulare (Galerie-Upload), keinen Fliesstext -- die
   Zeilenlaengen-Bremse der Basisklasse waere hier kontraproduktiv. */
.notice-box--wide {
  width: 95%;
  max-width: none;
}

.text-center {
  text-align: center;
}

.text-left {
  text-align: left;
}

.text-right {
  text-align: right;
}

/* .plain-list (Bullet-Liste mit reduziertem Einzug, Phase 7.5) ist mit 8.6
   entfallen -- ihre letzte Fundstelle, das Adminmenue in intern.admlinks.php,
   benutzt jetzt .link-list wie alle anderen Linklisten. */

/* main.satzung.php: <table width="95%"> ohne eigenes align -- zentriert
   trotzdem als direktes Block-Kind von .main-panel__content (Phase 7.5).
   margin-inline seit Phase 8.3: die Zentrierung kam vorher aus
   text-align:-webkit-center am Container -- der nicht standardisierte Wert
   zentriert auch block-level Kinder, sein Ersatz "center" tut das nicht. */
.satzung-panel {
  max-width: var(--measure);
  margin-inline: auto;
  text-align: left;
}

/* Phase 8.5: die 17 <dl> der Satzung enthielten ausschliesslich <dd>, kein
   einziges <dt> (Nebenbefund 11) -- die Absatznummern "(1)", "(2)", ... standen
   im Fliesstext des <dd>. Jetzt echte Paare: die Nummer ist das <dt>, der Text
   das <dd>. Das Raster stellt sie nebeneinander statt sie einzurücken. */
.satzung-panel dl {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--space-3);
  row-gap: var(--space-2);
  margin: 0 0 var(--space-6);
}

.satzung-panel dt {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.satzung-panel dd {
  margin: 0;
}

/* main.history.php (Detailansicht): schmale, blockzentrierte Spalte, wie
   vorher die <table width="80%">. Der Blocksatz (text-align:justify) ist mit
   8.5 entfallen -- ohne Silbentrennung reisst er in schmalen Spalten Loecher,
   und genau schmal wird die Spalte am Handy. */
.history-detail {
  max-width: var(--measure);
  margin-inline: auto;
  text-align: left;
}

/* --- Login -------------------------------------------------------------- */

/* Vorher .login-panel: padding-left:148px auf dem Container, padding-top:94px
   auf der Formularspalte -- beides Rueckrechnung aus einem <img null.gif
   height="70"> plus einem Zeilenumbruch im Original von 2003 (Herleitung in
   FRONTEND.md Phase 7.5). Die 148px waren der Grund, warum "login" als einzige
   oeffentliche Route bei 375px noch horizontal ueberlief. Jetzt eine echte
   Karte in Inhaltsbreite. */
.login-card {
  max-width: 22rem;
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  text-align: left;
}

.login-card__title {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-lg);
}

.login-card__field {
  display: grid;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
}

.login-card__field input {
  width: 100%;
}

.login-card__submit input {
  width: 100%;
}

/* --- Icon-Knopf --------------------------------------------------------- */

/* Loeschen/Bearbeiten-Knoepfe, die nur aus einem GIF bestehen. Sie stehen seit
   Phase 5 (CSRF-Schutz) als <button> in einem <form>, trugen aber ein
   style="border:none;background:none;padding:0;cursor:pointer" im Markup, um wie
   der frueher dort stehende Link auszusehen -- und wuerden ohne das seit 8.4 wie
   ein gruener 40px-Knopf aussehen. Vier weitere Fundstellen (intern.chgmember,
   intern.proto, zweimal intern.gallery) folgen in 8.6/8.7. */
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  padding: var(--space-1);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: inherit;
  cursor: pointer;
}

.icon-button:hover {
  background: var(--danger-50);
  border-color: var(--danger-600);
}

/* --- Funstuff ----------------------------------------------------------- */

/* main.stuff.php?mode=add: Upload-Formular. */
.upload-panel {
  max-width: 30rem;
  margin-inline: auto;
  text-align: left;
}

.upload-panel__field {
  display: grid;
  gap: var(--space-1);
  margin-top: var(--space-4);
}

.upload-panel__field input[type="text"] {
  width: 100%;
}

.upload-panel__submit {
  margin-top: var(--space-6);
}

/* main.stuff.php (Default-Modus): Downloadliste. Vorher .funstuff-item als
   Flexzeile aus 80px-Icon + fester 300px-Textspalte + Loeschknopf; die Summe
   lief bei 375px ueber (390px Inhaltsbreite in der 8.4-Shot-Matrix). Jetzt
   umbrechend, Icon kleiner, Textspalte elastisch. */
.funstuff-panel {
  text-align: left;
}

.funstuff-panel__title {
  margin: 0 0 var(--space-3);
}

.funstuff-panel__admin {
  margin: 0 0 var(--space-4);
}

.funstuff-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.funstuff-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.funstuff-item__icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
}

.funstuff-item__icon img {
  max-height: 100%;
  width: auto;
}

.funstuff-item__descr {
  flex: 1 1 12rem;
  min-width: 0;
}

.funstuff-item__delete {
  flex-shrink: 0;
  margin-left: auto;
  display: inline;
}

/* --- Breakpoint --------------------------------------------------------- */

/* Unter 40rem stapeln Inhalt und Bild. Der Notausgang aus 8.3 (flex-wrap fuer
   die fuenf alten *-row-Klassen) ist damit entfallen -- .page-split braucht
   nur noch seine Spaltendefinition zurueckzunehmen. */
@media (max-width: 39.999rem) {
  .page-split {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }

  .page-figure {
    text-align: center;
  }

  .page-figure img {
    margin-inline: auto;
    max-height: 14rem;
  }
}

/* --- Steckbrief --------------------------------------------------------- */

/* Der Steckbrief (details.php), seit der Datenschutz-Aenderung 2026-08 nur noch
   als eigenstaendige Seite im Popup-Fenster und nur fuer Angemeldete. Die Regeln
   des Overlays (.profile-dialog, ::backdrop, __loading -- in Phase 8.8 vom
   absolut positionierten <div> auf <dialog> umgebaut) sind damit entfallen:
   die oeffentliche Mitgliederliste verlinkt keinen Steckbrief mehr. */
.profile-card {
  text-align: left;
}

/* Vorher eine <td> mit background-color:#016D00 -- ein Gruen, das in keinem
   Marken-Ton vorkam. */
.profile-card__title {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--brand-800);
  color: var(--color-on-brand);
  font-size: var(--fs-lg);
}

.profile-card__body {
  display: grid;
  grid-template-columns: 13rem minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4);
}

.profile-card__photo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.profile-card__nophoto {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 8rem;
  margin: 0;
  background: var(--grey-50);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  text-align: center;
}

.profile-card__fields {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--space-4);
  row-gap: var(--space-1);
  margin: 0;
  min-width: 0;
}

.profile-card__fields dt {
  color: var(--color-text-muted);
}

.profile-card__fields dd {
  margin: 0;
  font-weight: 700;
}

.profile-card__actions {
  margin: 0;
  padding: 0 var(--space-4) var(--space-4);
  text-align: right;
}

@media (max-width: 39.999rem) {
  .profile-card__body {
    grid-template-columns: minmax(0, 1fr);
  }

  .profile-card__fields {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0;
  }

  .profile-card__fields dd {
    margin-bottom: var(--space-2);
  }
}

/**
 * Phase 7.7 (FRONTEND.md): "einfache" interne Fragmente ohne echte
 * Datentabellen (Formulare, Listen, Verwaltungsmenue). Gleiches
 * -webkit-center-Prinzip wie Phase 7.5/7.6: die Komponenten sind
 * inline-level (inline-grid/inline-block) und werden dadurch von
 * .main-panel__content automatisch zentriert, ohne eigenes margin:auto.
 */

/* intern.profile.php/intern.admprofile.php/intern.addmember.php: identisches
   Steckbrief-Formular (Adresse/Kontakt/Messenger/sonstige Angaben/
   Zugangsdaten, optional Rechteverwaltung). Vorher <table align="center">
   mit einer rechtsbuendigen Label- und einer linksbuendigen Eingabespalte
   (Spaltenbreite je durchs Tabellen-Auto-Layout auf die breiteste Zelle
   aufgeblasen) plus 10px-Spacer-Zelle dazwischen. CSS Grid mit
   max-content-Spalten bildet dieselbe Auto-Breite nach, ohne sie hart zu
   verdrahten. row-gap:2px entspricht dem Tabellen-Default-cellspacing (per
   getBoundingClientRect() an der Baseline verifiziert: 22px Zeilenhoehe +
   2px Abstand, s. FRONTEND.md Phase 7.7); die "height=30"-Spacer-Zeilen vor
   jeder neuen Sektion rendern real 32px hoch (Zelle + 1px Default-Padding
   oben/unten), hier als fester Sektions-Abstand statt einer eigenen
   Leerzeile. */
/* Phase 8.1: dieselbe Rezeptur stand dreimal im File -- .profile-form hier,
   .field-form (Admin-Formulare) und .kv-list (Bankverbindung in
   intern.strafen.php). Zusammengefasst als Gruppenselektor, nicht als neue
   gemeinsame Klasse: das haette Markup in sechs Fragmenten geaendert, und 8.1
   fasst kein PHP an. Die drei behalten ihre eigenen Namen und ihre eigenen
   Zusatzregeln weiter unten. */
/* Phase 8.6: zwei Aenderungen an dieser Rezeptur.
   1. Die Wertspalte ist "minmax(0, 1fr)" statt "max-content" und das Gitter ein
      block-level grid mit Obergrenze statt eines inline-grid. Zwei
      max-content-Spalten koennen nicht schrumpfen: das Steckbrief-Formular war
      779px breit und lief damit noch bei 768px ueber (zwei der letzten drei
      Ueberlauf-Faelle ausserhalb von Forum und Galerie).
   2. .kv-list ist aus der gemeinsamen Regel heraus -- sie traegt fuenf kurze
      Zeilen Bankverbindung, eine gestreckte Wertspalte wuerde Bezeichnung und
      Wert quer ueber die Seite auseinanderziehen. Sie behaelt zwei
      max-content-Spalten, jetzt aber linksbuendig statt per inline-grid in der
      Seitenmitte. */
.profile-form,
.field-form {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 12px;
  row-gap: 2px;
  width: 100%;
  max-width: 44rem;
  margin-inline: auto;
  text-align: left;
}

.kv-list {
  display: grid;
  grid-template-columns: max-content max-content;
  justify-content: start;
  column-gap: 12px;
  row-gap: 2px;
  text-align: left;
}

/* Phase 8.2: aus dem <div class="profile-form__section"><b>Adresse</b></div>
   ist ein echtes <h2> geworden -- Groesse und Gewicht kommen jetzt aus der
   Ueberschriften-Skala in base.css (--fs-2xl entspricht mit 1,75x genau dem
   Verhaeltnis, das die alten 16pt auf 9pt Inhalt hatten), die Klasse traegt
   nur noch Rasterposition, Abstand und Trennlinie. */
.profile-form__section {
  grid-column: 1 / -1;
  margin: 32px 0 0;
  padding-bottom: 4px;
  border-bottom: 1px dashed var(--color-border-strong);
}

.profile-form__section:first-child {
  margin-top: 0;
}

.profile-form__label {
  grid-column: 1;
  align-self: center;
  text-align: right;
}

.profile-form__value {
  grid-column: 2;
  align-self: center;
  text-align: left;
}

.profile-form__row--full {
  grid-column: 1 / -1;
  text-align: center;
}

.profile-form__actions {
  grid-column: 1 / -1;
  margin-top: 32px;
  text-align: center;
}

.profile-form__hint {
  grid-column: 1 / -1;
  margin-top: var(--space-6);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

/* Phase 8.6: der Block bestand aus <br>-getrennten Zeilen, deren Einrueckung
   aus Ketten von &nbsp; kam (neun Stueck fuer die Fortsetzungszeilen). Jetzt
   Absaetze und eine echte <ol>. */
.profile-form__hint p {
  margin: 0 0 var(--space-2);
}

.profile-form__hint ol {
  margin: 0;
  padding-left: var(--space-6);
}

/* intern.admprofile.php: eigenes zweites Formular (Mitgliedsbild-Upload)
   unterhalb des Steckbrief-Formulars, im Original eine eigene verschachtelte
   <table> in derselben Zelle. */
.profile-form__subform {
  grid-column: 1 / -1;
  margin-top: 32px;
}

/* intern.addproto.php/intern.addtermin.php: kurze Admin-Formulare (ein
   Titel + wenige Label/Feld-Zeilen + zentrierter Senden-Button), vorher
   <table> ohne (addtermin, schrumpft auf Inhaltsbreite) bzw. mit
   width="70%" (addproto, linksbuendiger Inhalt in einer 70%-breiten Box) --
   beides schon vorher durch denselben -webkit-center-Mechanismus zentriert
   wie .satzung-panel/.history-detail (s. FRONTEND.md Phase 7.6), hier
   uebernommen. Das Grid selbst kommt aus der gemeinsamen Regel weiter oben
   (bei .profile-form); die dritte, implizite Spalte fuer die Hinweislinks des
   Forum-Formulars ist hier mit eingezogen -- sie stand vorher als zweite,
   getrennte .field-form-Regel ganz unten im File (Phase 7.9), was wie eine
   Doppeldefinition aussah. grid-auto-columns: max-content laesst diese
   implizite Spalte auf ihren Inhalt schrumpfen statt sich zu strecken; auf die
   Formulare ohne dritte Spalte hat die Deklaration keine Wirkung. */
.field-form {
  grid-auto-columns: max-content;
}

/* intern.addproto.php: die urspruengliche Tabelle hatte eine eigene erste
   Spacer-Spalte (<img null.gif width="50"> in der Titelzeile, width="20" in
   den Datenzeilen) -- durchs Tabellen-Auto-Layout auf die breiteste Zelle
   (50px) vereinheitlicht, s. FRONTEND.md Phase 7.7. Da die Spalte in jeder
   Zeile leer ist, entspricht das schlicht einem linken Einzug der ganzen
   Box. */
/* Phase 8.6: die 70% Breite und der 50px-Einzug (die leere erste Spalte der
   Originaltabelle) sind entfallen -- ein Formular braucht keine Sonderbreite,
   nur eine Obergrenze. */
.field-form--wide {
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
}

/* Phase 8.2: die fuenf Fundstellen sind von <div> (teils mit <b class="big">
   darin) auf <h2> gewechselt -- die Klasse traegt nur noch Rasterposition und
   Abstand. */
.field-form__title {
  grid-column: 1 / -1;
  margin: 0 0 var(--space-3);
}

.field-form__label {
  grid-column: 1;
  align-self: center;
  text-align: right;
}

.field-form__value {
  grid-column: 2;
  align-self: center;
  text-align: left;
}

.field-form__actions {
  grid-column: 1 / -1;
  margin-top: 4px;
  text-align: center;
}

.field-form__row--full {
  grid-column: 1 / -1;
}

/* intern.home.php: Textspalte links, Geburtstage rechts (beide oben
   ausgerichtet -- kein vertical-align:middle-Sonderfall wie main.home.php,
   s. FRONTEND.md Phase 7.5, weil das alte height="100%" hier ohne
   Wirkung blieb: .main-panel__content hat selbst keine explizite Hoehe,
   ein prozentualer Hoehenwert ohne definierten Elternbezug wird von
   Browsern ignoriert). Darunter Besucherzaehler + Countdown als eigene
   Fusszeile (vorher eine verschachtelte width="100%"-Tabelle mit
   align="right" auf der zweiten Zelle). */
.intern-home {
  display: flex;
  text-align: left;
}

.intern-home__col {
  padding-top: 4px;
}

.intern-home__col--main {
  flex: 0 0 400px;
}

.intern-home__col--birthdays {
  flex: 0 0 140px;
  margin-left: 15px;
}

.intern-home__footer {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
}

/* includes/intern.admlinks.php: einspaltiges Admin-Linkmenue, vorher eine
   reine Layout-<table width="100%" height="100%"> mit einer 20px-Spacer-
   Zelle vor dem Inhalt. */
.admlinks-panel {
  padding-left: 20px;
  text-align: left;
}

.admlinks-panel__list {
  margin: 8px 0 0;
  padding-left: 16px;
}

/* Original: <hr width="250" align="left"> zwischen den Rechte-Gruppen. */
.admlinks-panel hr {
  width: 250px;
  margin: 4px 0;
  margin-left: 0;
}

/* .chgmember-grid (fuenfspaltiges Raster aus zwei Name+Symbole-Paaren und einer
   22px-Spacer-Spalte, Phase 7.7) ist mit 8.6 entfallen -- s. .admin-member-list
   weiter unten. */

/**
 * Phase 7.8 (FRONTEND.md): echte Datentabellen (Mitgliederliste, Termine,
 * Strafen/Beitraege, Protokolle, News-/Geschichten-Verwaltung, Forum-Threads).
 * Bleiben laut "Datentabellen vs. Layout-Tabellen"-Leitplanke (s. oben) eine
 * <table>, bekommen aber <th scope="col"> statt <td><b> und CSS-Klassen statt
 * bgcolor/align. .data-table setzt th auf font-weight:normal zurueck (Browser-
 * Default ist bold+center) -- einzelne Spalten waren im Original NICHT fett
 * (z.B. intern.proto.php/intern.newsadm.php/intern.hisadm.php: reiner Text
 * ohne <b>), das wird jetzt wieder ueber ein eigenes <b> *innerhalb* des th
 * nachgebildet statt global zu vererben, damit jede Tabelle ihr Original
 * 1:1 abbildet statt einer geschaetzten Einheitsoptik. */
/* Phase 8.6: .data-table ist standardmaessig so breit wie ihre Spalte.
   Bis 8.5 galt das Gegenteil -- die Tabellen schrumpften auf ihren Inhalt und
   wurden per margin-inline:auto zentriert, weil Phase 7.8 den Zustand von 2003
   nachbildete (nur intern.list.php hatte ein width="100%", alle anderen keins).
   In einem 68rem-Inhaltsband sieht eine auf 50% geschrumpfte, mittig stehende
   Datentabelle unter einem linksbuendigen Seitentitel aus wie ein Fehler; dazu
   brauchen die Karten-Stapelung und der .table-scroll-Umschlag eine Tabelle, die
   ihre Spalte kennt. Der Modifier .data-table--full-width ist damit
   gegenstandslos und entfallen (einzige Fundstelle: intern.list.php). */
.data-table {
  border-collapse: collapse;
  width: 100%;
  /* Linksbuendig, weil .page bis 8.8 noch ein text-align:center traegt
     (Uebergangsregel aus 8.3, Nebenbefund 16) -- ohne diese Zeile erben alle
     Datenzellen die Zentrierung, und eine zentrierte Datentabelle unter einer
     linksbuendigen Ueberschrift liest sich wie ein Fehler. Als vererbter Wert
     verliert er gegen jedes td.text-right/td.text-center, unabhaengig von der
     Regelreihenfolge im File. */
  text-align: left;
}

.data-table th {
  text-align: left;
  font-weight: normal;
}

/* list.php/forum-Tabellen: Kopfzeilenband + eine Stufe groesser als der
   Tabelleninhalt (Original: explizites style="font-size: 11pt" gegen 9pt
   Tabellenschrift = 1,22x; hier --fs-lg gegen --fs-base = 1,125x). Der
   Absolutwert 11pt waere nach dem Wegfall des 9pt-Patches KLEINER als der
   Tabelleninhalt gewesen und haette die Hierarchie umgedreht.
   Phase 8.4: #E0E0E0 -> --brand-100, dazu eine kraeftige Unterkante als
   Abschluss des Bandes. */
.data-table th {
  background: var(--brand-100);
  border-bottom: 2px solid var(--brand-600);
}

.data-table--header-strong th {
  font-size: var(--fs-lg);
}

/* .data-table--header-grey (Kopfzeile grau, aber ohne die Vergroesserung) ist
   mit dem gemeinsamen Kopfband ueber .data-table th gegenstandslos geworden
   und samt seiner beiden Fundstellen im Markup (intern.termine.php,
   intern.proto.php) entfallen. */

/* Zebra. Bis 8.6 gab es dafuer zwei Mechanismen: diese Regel und eine explizite
   Klasse .data-table__row--even, die forum.threads.php/forumpage.php per $a&1
   selbst setzten. Grund war eine bedingte "neues Thema anlegen"-Zeile *vor* der
   ersten Datenzeile -- nth-child(even) haette dort je nach Bedingung eine andere
   Phase gehabt. Mit 8.7 steht diese Zeile ueber der Tabelle statt darin, beide
   Forum-Tabellen haben ein echtes <tbody>, und die Klasse ist samt ihrer
   $a&1-Zaehlung entfallen. */
.data-table--zebra tbody tr:nth-child(even) {
  background: var(--grey-50);
}

/* Zeilen-Hover (Phase 8.4). Nicht auf der Strafentabelle: deren Zeilenfarbe
   ist die Information selbst, ein Hover-Wisch darueber wuerde sie ueberdecken. */
.data-table:not(.strafen-table) tbody tr:hover {
  background: var(--brand-50);
}

/* Einfache Key-Value-Liste ohne <form> (intern.strafen.php: Bankverbindung),
   gleiches Grid-Prinzip wie .field-form (Phase 7.7), aber ohne Formularbezug --
   das Grid kommt seit 8.1 aus der gemeinsamen Regel bei .profile-form. */
.kv-list dt {
  grid-column: 1;
  text-align: right;
}

.kv-list dd {
  grid-column: 2;
  margin: 0;
  text-align: left;
}

/* intern.list.php: Namen je nach Rang eingefaerbt (vorher <font color>),
   gleiche Farben auch fuer die Farblegende darueber.
   Phase 8.4: alle vier auf --rang-*-Tokens (Werte und gemessene Kontraste s.
   tokens.css). Die Altwerte #00AA00 (3,1:1) und #00AAAA (2,9:1) verfehlten AA
   deutlich. Wie in 8.1 angekuendigt laufen .rang-oberleutnant und
   .text-danger hier auseinander: bis 8.3 waren sie wertgleich (#CC0000) und
   teilten sich eine Regel, jetzt liest der Rang sein eigenes Token und der
   Warnhinweis --danger-600. */
.rang-oberleutnant { color: var(--rang-oberleutnant); }
.rang-leutnant     { color: var(--rang-leutnant); }
.rang-feldwebel    { color: var(--rang-feldwebel); }
.rang-passiv       { color: var(--rang-passiv); }

.text-danger { color: var(--danger-600); }

/* .list-table__na (10px Vorsprung vor "n/a" bei fehlender Handynummer, der
   Ersatz fuer ein <img null.gif width="10">) ist mit 8.6 entfallen -- ein
   Einzug ohne Grund, der in der Kartenansicht wie eine zweite Spalte aussah. */

/* intern.list.php: Farblegende ueber der Adressliste, vorher ein
   style="font-size: 12pt" direkt im Markup (die letzte pt-Angabe ausserhalb
   der CSS-Dateien neben intern.proto.php, s.u.). Gleiche Umrechnung wie bei
   .notice-box: eine Stufe ueber dem Inhalt statt eines Absolutwerts, der nach
   dem Wegfall des 9pt-Patches keine Hervorhebung mehr waere. */
.list-legend {
  font-size: var(--fs-lg);
}

/* intern.proto.php: Jahres-Trennzeile in der Protokollliste, vorher ein
   style="font-size: 20px; font-weight: bold" direkt im Markup. */
.proto-table__year {
  font-size: var(--fs-lg);
  font-weight: bold;
}

/* .data-table__corner -- die erste, leere Spalte der Terminliste, deren
   bgcolor="var(--color-on-brand)" die graue Kopfzeilenfarbe fuer genau diese Zelle
   ueberschrieb -- ist mit 8.6 entfallen: die Spalte selbst enthielt nie mehr als
   ein 5x5-Spacer-GIF. */

/* intern.termine.php: gestrichelte Trennlinie beim Wechsel zwischen
   "kommenden 7 Tagen" (fett) und "spaeter"/"vergangen" (kursiv) --
   vorher ein dynamisch gebautes style="border-top:1px dashed #000" pro
   Zeile, hier als Klasse statt Inline-Style. */
.data-table__transition td {
  border-top: 1px dashed var(--color-border-strong);
}

/**
 * intern.strafen.php: die "Ampel" des Beitrags-/Strafenkontos.
 *
 * Bis Phase 8.4 waren das zwoelf Stufen mit zwoelf gesaettigten Rot-Toenen
 * (#FD0000 #F00000 #DA1E10 #C0291E #EA581B #EA6015 #D00505 #C02010 #BD2020
 * #B03030 #A05050 #99F099), im Original als bgcolor pro Zeile gebaut. Die
 * Reihe war nicht monoton -- Stufe 5/6 (>80/>70) waren HELLER als Stufe 4
 * (>100), die Stufen 1/2/7 und 8/9/10 praktisch nicht unterscheidbar. Zwoelf
 * Abstufungen ueber Hintergrundfarbe allein kann niemand ablesen; die Ampel
 * informierte also nicht, sie faerbte nur.
 *
 * Jetzt vier semantische Baender mit hellem Hintergrund und farbiger
 * Akzentkante links. Die Kante traegt die Stufe auch dann, wenn die Flaeche
 * zu hell ist, um sie zu unterscheiden -- und der schwarze Text bleibt auf
 * allen vier Flaechen lesbar (auf dem alten #FD0000 lag er bei 5,3:1, auf
 * #A05050 bei 5,9:1, auf #99F099 bei 15:1 -- also drei voellig verschiedene
 * Lesbarkeiten fuer dieselbe Tabelle).
 *
 * Schwellen: 0 / bis 50 / bis 150 / darueber. Die zwoelf Originalschwellen
 * (200/180/150/100/80/70/50/30/20/10/0) sind darin aufgegangen; die
 * Zuordnung steht in includes/intern.strafen.php.
 */
.strafen-row--ok       { background: var(--ok-50); }
.strafen-row--warn     { background: var(--warn-50); }
.strafen-row--danger   { background: var(--danger-50); }
.strafen-row--critical { background: color-mix(in srgb, var(--danger-600) 18%, var(--color-surface)); }

.strafen-row--ok td:first-child       { border-left: 4px solid var(--ok-600); }
.strafen-row--warn td:first-child     { border-left: 4px solid var(--warn-600); }
.strafen-row--danger td:first-child   { border-left: 4px solid var(--danger-600); }
.strafen-row--critical td:first-child { border-left: 4px solid var(--danger-600); }

/* Die kritische Stufe bekommt zusaetzlich Gewicht auf der Summe -- eine
   Farbstufe mehr waere wieder nur Farbe. */
.strafen-row--critical td:last-child {
  font-weight: 700;
}

.strafen-table td {
  border-bottom: 1px solid var(--color-surface);
}

/**
 * Phase 7.9 (FRONTEND.md): Forum-Beitraege (includes/forum.posts.php) +
 * Popup-Fenster. Die Beitragsliste ist eine Kartenliste (Autor-Sidebar +
 * Nachricht), keine echte Datentabelle im Sinne von Phase 7.8 (keine
 * Spaltenkoepfe) -- deshalb CSS Grid/Flexbox statt <table>, analog zu den
 * Layout-Tabellen aus Phase 7.5/7.6.
 */
/* Phase 8.3: fest 735px (die Breite des alten Forum-Rahmens) -> fluid. Die Box
   sass bis dahin in einer 735px-Chrome und war darauf verdrahtet; im neuen
   Shell fuellt sie die Inhaltsspalte. */
.forum-posts {
  width: 100%;
  margin: 0 auto;
  padding: var(--space-3);
  background: var(--grey-100);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.forum-posts__toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  min-height: 40px;
  margin-bottom: var(--space-3);
}

.forum-posts__toolbar-side {
  flex: 1 1 0;
}

.forum-posts__toolbar-count {
  flex: 1 1 0;
  text-align: center;
  font-size: var(--fs-lg);
}

/* Phase 8.7: Karten-Layout statt eines 23%/77%-Splits mit min-height:132px.
   Die feste Mindesthoehe stammt aus dem Tabellenlayout von 2003 (die
   Autorenspalte hatte dort immer fuenf Zeilen) und liess kurze Beitraege als
   halbleere Kaesten stehen; die Prozentspalten machten die Autorenspalte am
   Handy 86px breit. Jetzt eine feste, aber schrumpfbare Autorenspalte, die unter
   40rem ueber den Beitrag klappt. */
.forum-post {
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  /* Linksbuendig gegen die Uebergangs-Zentrierung von .page (Nebenbefund 16):
     der Beitragstext war vorher text-align:justify und damit gegen sie
     immunisiert -- Blocksatz ohne Silbentrennung reisst in einer schmalen Spalte
     aber Loecher, und schmal wird sie am Handy. */
  text-align: left;
  gap: var(--space-4);
  width: auto;
  margin: 0 0 var(--space-3);
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
}

.forum-post--alt {
  background: var(--grey-50);
}

.forum-post__sidebar {
  min-width: 0;
  padding-right: var(--space-3);
  border-right: 1px solid var(--color-border);
  font-size: var(--fs-sm);
  overflow-wrap: break-word;
}

.forum-post__message {
  min-width: 0;
  overflow-wrap: break-word;
}

.forum-posts__pagination {
  padding: 4px;
}

/* Formular "neuen Beitrag anlegen": wie .field-form (Phase 7.7), aber mit
   einer dritten Spalte fuer die Hinweislinks (HTML/Smilies/BBCode
   an-/ausgeschaltet). Die zugehoerige grid-auto-columns-Deklaration stand hier
   als zweite .field-form-Regel und ist seit 8.1 oben bei der Klasse selbst. */
.field-form__aside {
  grid-column: 3;
  align-self: center;
  text-align: right;
}

/**
 * Phase 7.10 (FRONTEND.md): Galerie (includes/intern.gallery.php). Reine
 * Layout-Tabellen (Galerie-/Bilderlisten, Bildergitter, Formulare) --
 * CSS Grid/Flexbox statt <table>, analog zu Phase 7.5/7.6/7.9. Die zwei
 * lightUP()/lightBACK()-Aufrufstellen (setdescr-Galeriebeschreibung)
 * werden durch :hover ersetzt -- letzte Konsumenten dieser Funktionen,
 * js/common.js kann danach auf reines wop() reduziert werden (s.
 * FRONTEND.md Phase 7.2-Nebenbefund "lightUP-Handoff").
 */
.gallery-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 30px;
}

/* Phase 8.2: der Titel links in der Kopfzeile war ein <b class="big">, jetzt
   ein <h2>. Als Flex-Kind darf es seine Ueberschriften-Abstaende nicht
   mitbringen, sonst kippt die Zeile aus der Mitte. */
.gallery-header > h2 {
  margin: 0;
}

/* Phase 8.7: Galerie-Karten (Uebersicht + setdescr) und Bildraster fluid.
   Vorher drei feste Werte -- Thumbnail 120px, Textspalte 350px, in der Variante
   .gallery-card__text--narrow 400px. Die Variante war damit *breiter* als die
   Basisklasse, also falsch benannt (Nebenbefund 5); sie ist entfallen, die
   Textspalte nimmt jetzt den Rest der Zeile. Ein Grid statt Flex, damit die
   Textspalte schrumpfen darf (minmax(0,1fr)); unter 40rem stapelt die Karte. */
.gallery-card {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-align: left;
  transition: background-color var(--transition), box-shadow var(--transition);
}

.gallery-card:hover {
  background: var(--brand-50);
  box-shadow: var(--shadow-sm);
}

.gallery-card__thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 90px;
  background: var(--grey-50);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.gallery-card__text {
  min-width: 0;
}

.gallery-card__meta {
  margin-top: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

/* thumbs-Modus: Bildgitter. Vorher repeat(4, max-content) -- vier Spalten,
   egal wie breit das Fenster ist; bei 375px lief das Gitter ueber (515px
   Inhaltsbreite in der 8.6-Matrix). Jetzt so viele Spalten, wie hineinpassen. */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-3);
  margin: var(--space-4) 0;
}

.gallery-thumb {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

/* Phase 8.7: die beiden Sonderzustaende standen als border=2/border=1 plus
   style="border-color: #FFAAAA|#990000" im Markup (Nebenbefund 17) -- die
   letzten hartcodierten Farben ausserhalb von tokens.css im Galeriebereich. */
/* Phase 8.8, Kontrast-Durchgang: die Markierung stand zuerst in --accent-gold.
   Gold misst auf Weiss nur 2,42:1 und verfehlt damit die 3:1, die WCAG 1.4.11
   fuer eine bedeutungstragende Umrandung verlangt (auf der dunkelgruenen
   Kopfleiste ist Gold mit 4,69:1 dagegen richtig -- es ist kein schlechtes
   Token, nur das falsche auf weissem Grund). --warn-600 liefert 4,24:1 und
   bleibt derselbe warme Ton. */
.gallery-thumb--highlight {
  border-color: var(--warn-600);
  border-width: 2px;
  box-shadow: var(--shadow-sm);
}

.gallery-thumb--hidden {
  border-color: var(--danger-600);
}

.gallery-thumb__img {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  background: var(--grey-50);
}

.gallery-thumb__img img {
  max-height: 100%;
  width: auto;
}

.gallery-thumb__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  min-height: 32px;
  border-top: 1px solid var(--color-border);
}

/* full-Modus: Detailansicht mit vor-/zurueck-Navigation, oben und unten
   wiederholt (wie im Original). Die beiden null.gif-Platzhalter, die den Platz
   eines fehlenden "zurueck"/"weiter" hielten, sind mit 8.7 entfallen --
   justify-content erledigt das. */
.gallery-full__nav {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 1.5rem;
}

.gallery-full__image {
  padding: var(--space-4) 0;
  text-align: center;
}

.gallery-full__count {
  margin: 0 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  text-align: center;
}

/* addgallery/addpics Schritt 1: Optionszeile (Beschreibung links,
   "Do it this way!"-Link rechts). */
.gallery-step__option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  margin-top: 12px;
}

.gallery-step__option-text {
  flex: 1 1 auto;
}

.gallery-step__link {
  flex-shrink: 0;
}

/* addpics Schritt 2: nummerierte Datei-Auswahlliste. */
.gallery-upload-list {
  margin-top: 10px;
}

.gallery-upload-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}

.gallery-upload-row__num {
  flex: 0 0 15px;
  text-align: right;
}

/**
 * Phase 7.11 (FRONTEND.md): forum/latest.php, forum/search.php,
 * forum/stats.php, forum/new_forum.php -- vier ueber forum.php?action=...
 * erreichbare Fragmente, die beim Phasenplan (7.4 Forum-Chrome, 7.9
 * Forum-Beitraege) uebersehen wurden und bis hierhin unkonvertiert
 * blieben (s. FRONTEND.md Phase 7.11 Ausgangslage). Anders als die
 * Haupt-Site-Fragmente haengen diese vier NICHT unter
 * .main-panel__content -- forum.php's Body hat kein eigenes
 * text-align:-webkit-center, deshalb hier explizites .text-center statt
 * impliziter Vererbung fuer alles, was im Original align="center" trug.
 */
/* Phase 8.3: wie .forum-posts von fest 735px auf fluid. */
.forum-box {
  width: 100%;
  margin: 0 auto;
  text-align: left;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
}

/* latest.php: Radio-Auswahl (letzte 10 / neue seit Login). */
.forum-latest__method {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 8px;
}

/* stats.php: zwei Spalten (User/Beitraege) mit Bulletlisten, 85%-breite
   Box wie im Original. */
/* Phase 8.7: aus zwei festen Spalten in 85% Breite ein Raster, das unter 40rem
   stapelt -- "forum-stats" war bei 375px 440px breit. */
.forum-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-6);
  text-align: left;
}

.forum-stats__col {
  flex: 1 1 auto;
}

/**
 * Phase 8.1 (REDESIGN.md): die letzten sechs Regeln aus css/main.css. Die
 * Datei war seit Phase 7.3 der Sammelplatz fuer noch nicht migrierte
 * Legacy-Regeln und enthielt am Ende nur noch diese; sie ist damit aufgeloest
 * (Datei und beide <link>-Tags entfernt, in includes/all.htmlhead.php und in
 * news_details.php, das sein Stylesheet separat einbindet).
 *
 * Die pt-Groessen sind mit Phase 8.2 auf die Typo-Skala gegangen, die beiden
 * #559955 gehen in 8.4 auf --brand-700 (heute 3,5:1, verfehlt AA).
 */

/* includes/forum.posts.php: die aktuelle Seitenzahl in der Blaetter-Leiste. */
a.activepage {
  color: var(--color-text);
  text-decoration: underline;
}

/* a.footer (drei Zustaende, alle nur font-size) stand hier bis Phase 8.3. Der
   Footer der Forum-Popups war die einzige Fundstelle; er teilt sich seit 8.3
   den .site-footer aus layout.css mit dem Rest der Seite und bringt seine
   Groesse von dort mit. */

/* includes/main.satzung.php: Satzungs-Ueberschrift (jetzt <h1>) und
   Paragraphen-Marken (jetzt <h3>, vorher <span> mitten im <dl>). Groesse und
   Gewicht kommen seit 8.2 aus der Ueberschriften-Skala; hier bleibt nur die
   Farbe -- die geht in 8.4 auf --brand-700, #559955 misst 3,5:1 und verfehlt
   AA. .satzpara hatte vorher exakt die Inhaltsgroesse (9pt) und war damit
   ueberhaupt keine sichtbare Hierarchiestufe, nur fett und gruen. */
.satzheader,
.satzpara {
  color: var(--brand-700);
}

/* .big (font-size: 16pt) stand hier bis Phase 8.2 als Ad-hoc-
   Ueberschriftenstil fuer includes/intern.gallery.php und main.stuff.php.
   Ersatzlos entfallen -- die fuenf Fundstellen sind jetzt echte <h2>. */


/**
 * Phase 8.6 (REDESIGN.md): Mitgliederbereich + responsive Datendarstellung.
 *
 * Ausgangslage nach 8.5: alle 24 verbliebenen Aufnahmen mit horizontalem
 * Ueberlauf in der Shot-Matrix waren interne Routen, Forum oder Galerie. Der
 * Grund ist in allen Faellen derselbe -- Inhalte, die ihre Breite selbst
 * bestimmen (Datentabellen mit vier bis sechs Spalten, Formulargitter aus
 * max-content-Spalten) in einem Rahmen, der schmaler sein kann als sie.
 *
 * Zwei Mechanismen, je nach Inhalt:
 *
 *   .table-scroll      Umschlag mit overflow-x:auto. Fuer Tabellen, deren
 *                      Zeilen als Zeile gelesen werden (Termine, Protokolle,
 *                      News-/Geschichtenverwaltung) -- Querscrollen innerhalb
 *                      der Tabelle statt der ganzen Seite.
 *   .data-table--cards Zeilen stapeln unter 40rem zu Karten, jede Zelle mit
 *                      ihrer Spaltenbeschriftung aus data-label. Fuer die zwei
 *                      Tabellen, bei denen der einzelne Datensatz zaehlt
 *                      (Adressliste, Beitrags-/Strafenkonto).
 *
 * Dazu klappen die Formulargitter unter 40rem einspaltig (Label ueber dem Feld).
 */

/* Nur fuer Screenreader. Ersetzt die Spacer-GIFs in Kopfzellen, die im
   Altbestand die Stelle einer Beschriftung einnahmen ("<th><img null.gif>"). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.table-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* position:relative ist hier kein Deko-Detail: die .sr-only-Beschriftungen in
     den Kopfzellen sind position:absolute und haetten ohne positionierten
     Vorfahren das *Dokument* als Bezug -- an ihrer statischen Position, also
     ausserhalb des Viewports. Ergebnis waere ein horizontaler Ueberlauf der
     ganzen Seite (bei "termine" 539px statt 375px), obwohl die Tabelle selbst
     brav im Umschlag scrollt. Gemessen, nicht vermutet: document.scrollWidth war
     539 bei body.scrollWidth 360. */
  position: relative;
}

/* Gruppenzeile innerhalb einer Datentabelle: Monatsband in der Terminliste,
   Jahreszeile in der Protokollliste. Beide waren vorher eine Datenzeile mit
   fetter roter Schrift (Monat) bzw. 20px-Inline-Style (Jahr). */
.data-table__group td {
  padding-top: var(--space-4);
  background: var(--brand-50);
  border-bottom: 1px solid var(--brand-600);
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--brand-800);
}

.data-table td,
.data-table th {
  padding: var(--space-2) var(--space-3);
  vertical-align: top;
}

/* Aktionsspalten (aendern/loeschen) sollen nicht mitwachsen. */
.data-table__actions {
  width: 1%;
  white-space: nowrap;
}

/* Zeile ueber einer Tabelle mit den Aktionen dazu ("neuen Termin hinzufuegen",
   CSV-Export). Ersetzt <br>-Ketten und <div align="left">. */
.page-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
  text-align: left;
}

.page-actions--end {
  justify-content: flex-end;
}

/* Aktionslinks mit Symbol (CSV-Export) -- Symbol und Text auf einer Grundlinie. */
.page-actions a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* Fehlermeldung ueber einem Formular. Die drei Meldungen der Steckbrief-
   Formulare (fehlende Angaben, Passwort, Username vergeben) waren fette rote
   Zeilen, optisch nicht von einem Feldlabel zu unterscheiden. */
.form-error {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--danger-50);
  border: 1px solid var(--danger-600);
  border-left-width: 4px;
  border-radius: var(--radius);
  color: var(--danger-600);
  font-weight: 700;
  text-align: left;
}

/* Fussnote unter einem Formular (Dateigroesse beim Protokoll-Upload,
   Datumsformat beim Termin). Vorher <br> + <b>*)</b> bzw. <div align="left">. */
.field-form__footnote {
  max-width: var(--measure);
  margin: var(--space-4) auto 0;
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  text-align: left;
}

/* Spaltenbreiten, die vorher als style="width: ..." in der Kopfzelle standen. */
.strafen-table__name { width: 40%; }
.termin-table__date  { width: 11rem; }
.termin-table__event { width: 40%; }

/* Phase 8.8: der Hinweistext eines Termins. Er lag bis dahin in einem Tooltip,
   das nie etwas anzeigte (Nebenbefund 1) -- jetzt eine zweite, gedaempfte Zeile
   in der Spalte "Veranstaltung". */
.termin-hint {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  font-style: normal;
  font-weight: normal;
}

/* Legende ueber Termin- und Adressliste. Vorher vier Zeilen, die je mit einem
   10px-Spacer-GIF und "-> " begannen. */
.legend {
  margin: 0 0 var(--space-6);
  padding: var(--space-3) var(--space-4);
  background: var(--grey-50);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  text-align: left;
}

.legend ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-6);
}

.legend li + li {
  margin-top: var(--space-1);
}

/* Mitgliederverwaltung (intern.chgmember.php). Ersetzt .chgmember-grid, ein
   fuenfspaltiges Raster aus zwei Name+Icons-Paaren und einer 22px-Spacer-Spalte
   dazwischen -- die Nachbildung einer Tabelle von 2003, die am Handy zwangslaeufig
   ueberlief. Jetzt ein Kartenraster, das seine Spaltenzahl aus der Breite
   ableitet. */
.admin-member-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.admin-member-list li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.admin-member-list__name {
  flex: 1 1 auto;
  min-width: 0;
}

.admin-member-list__actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

/* Startseite des internen Bereichs. Vorher .intern-home mit zwei festen Spalten
   (400px Text + 140px Geburtstage) -- zusammen mehr als ein 375px-Viewport. */
.intern-home {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 15rem;
  gap: var(--space-8);
  align-items: start;
  text-align: left;
}

.intern-home__col {
  min-width: 0;
}

/* Seitenspalte (wer hat Geburtstag) als abgesetzte Flaeche statt einer nackten
   zweiten Textspalte. */
.side-panel {
  padding: var(--space-4);
  background: var(--grey-50);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.side-panel__title {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-lg);
}

.side-panel__subtitle {
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--color-text-muted);
}

.side-panel__subtitle:first-of-type {
  margin-top: 0;
}

/* --- Breakpoints -------------------------------------------------------- */

/* Unter 40rem: Datentabellen als Karten bzw. querscrollend, Formulargitter
   einspaltig, Zweispalter gestapelt. */
@media (max-width: 39.999rem) {
  .intern-home {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }

  /* Karten statt Tabellenzeilen. thead wird nicht ausgeblendet, sondern
     screenreader-only verschoben -- die Spaltenbeschriftung steht sichtbar an
     jeder Zelle (::before aus data-label), fuer die Vorlesereihenfolge bleibt
     der Kopf aber erhalten. */
  .data-table--cards thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .data-table--cards,
  .data-table--cards tbody,
  .data-table--cards tfoot,
  .data-table--cards tr,
  .data-table--cards td {
    display: block;
    width: auto;
  }

  .data-table--cards tr {
    margin-bottom: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
  }

  .data-table--cards td {
    padding: var(--space-1) 0;
    border: none;
  }

  /* Beschriftung ueber dem Wert, nicht daneben: ein Grid aus Label- und
     Wertspalte macht jedes Kind der Zelle zu einem Grid-Item -- die
     Adressliste hat Zellen mit zwei Zeilen ("Tel<br>Handy"), deren zweite
     dann in der Labelspalte der naechsten Rasterzeile landete. */
  .data-table--cards td[data-label]::before {
    content: attr(data-label);
    display: block;
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
  }

  /* Die Akzentkante der Strafen-Ampel sass auf der ersten Zelle -- als Karte
     traegt sie die ganze Zeile. */
  .data-table--cards .strafen-row--ok       { border-left: 4px solid var(--ok-600); }
  .data-table--cards .strafen-row--warn     { border-left: 4px solid var(--warn-600); }
  .data-table--cards .strafen-row--danger   { border-left: 4px solid var(--danger-600); }
  .data-table--cards .strafen-row--critical { border-left: 4px solid var(--danger-600); }

  .data-table--cards .strafen-row--ok td:first-child,
  .data-table--cards .strafen-row--warn td:first-child,
  .data-table--cards .strafen-row--danger td:first-child,
  .data-table--cards .strafen-row--critical td:first-child {
    border-left: none;
  }

  /* Formulargitter: Label ueber dem Feld statt rechtsbuendig davor. Die
     max-content-Spalten stammen aus der Nachbildung der Tabellen von 2003
     (FRONTEND.md Phase 7.7) und sind genau so breit wie ihr laengstes Label. */
  .profile-form,
  .field-form,
  .kv-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-1);
  }

  .profile-form__label,
  .field-form__label,
  .kv-list dt {
    text-align: left;
    margin-top: var(--space-2);
  }

  .profile-form__value,
  .field-form__value,
  .field-form__aside,
  .kv-list dd {
    grid-column: 1;
    text-align: left;
  }

  .profile-form__value input[type="text"],
  .profile-form__value input[type="password"],
  .field-form__value input[type="text"],
  .field-form__value textarea {
    width: 100%;
  }

  .field-form--wide {
    width: 100%;
    padding-left: 0;
  }
}

/**
 * Phase 8.7 (REDESIGN.md): Galerie und Forum -- die letzten acht Aufnahmen mit
 * horizontalem Ueberlauf aus der 8.6-Matrix. Breakpoint wie ueberall 40rem.
 */
@media (max-width: 39.999rem) {
  /* Galerie-Karte: Bild ueber Text statt daneben. */
  .gallery-card {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
  }

  .gallery-card__thumb {
    height: auto;
    aspect-ratio: 4 / 3;
  }

  /* Forum-Beitrag: Autorenspalte klappt ueber den Beitrag, die Trennlinie
     wandert von rechts nach unten. */
  .forum-post {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
  }

  .forum-post__sidebar {
    padding: 0 0 var(--space-2);
    border-right: none;
    border-bottom: 1px solid var(--color-border);
  }

  /* Die Brotkrumenzeile des Forums bricht statt zu ueberlaufen. */
  .forum-breadcrumb {
    font-size: var(--fs-xs);
  }
}
