# UI beruhigen und Bootstrap idiomatischer nutzen

Ziel: weniger visuelles Rauschen, mehr Konsistenz — **ohne** die Architektur zu
ändern. Der Grundaufbau bleibt: frameworklos, eine `.php` pro URL, Bootstrap 4,
das bestehende `header.php`-Include-Muster. Es geht um Bereinigung im Bestand.

> **Umsetzungsstand** (siehe `CHANGELOG.md`): Die strukturellen Schritte sind
> weitgehend erledigt. **Erledigt:** der gemeinsame **`partials/head.php`** löst die
> ~10 einkopierten Heads ab; FontAwesome ist auf **eine** Version vereinheitlicht
> (5.15.4, nicht wie unten skizziert 5.9.0); die neun `style.css` sind zu **einer**
> `css/app.css` konsolidiert (seiten-gescopt per `page-*`-Body-Klasse), totes CSS
> ist entfernt. **Bewusst abweichend:** ein `partials/navbar.php` wurde **nicht**
> extrahiert — die Navbars bleiben absichtlich pro Seite (Titel/Zurück-Button sind
> seitenspezifisch). **Noch offen:** die Inline-Styles → Utilities/Token (Schritt 6,
> 36 Stellen) und der Komponenten-Angleich (Schritt 7). Details zur CSS-Namens-
> und Token-Strategie in [css-strategie.md](css-strategie.md).

## Ausgangslage

- Der `<head>` samt Bootstrap-/jQuery-Einbindung ist in **10 Dateien** wortgleich
  einkopiert (`index.php`, `detail/index.php`, `detail/erstellen.php`,
  `dokumente/index.php`, `settings/index.php`, `search/index.php`,
  `search/index_example.php`, `news/index.php`, `login/index.php`,
  `maintenance.php`).
- Die **Navbar** steckt zusätzlich als Copy-Paste in ~8 Dateien.
- **FontAwesome dreifach parallel**: v5.7.1, v5.8.1, v5.9.0 — je nach Seite lädt
  eine andere Icon-Version.
- **Verstreute Stylesheets**: Root-`style.css`, `css/custom-colors.css` und je
  eine `style.css` in `settings/`, `search/`, `dokumente/`, `detail/`,
  `detail/comment/`, `news/`, `login/`.
- **Inline-Styles** in den `echo`-Ausgaben, teils dutzendfach, plus hartkodierte
  Farben (`#4578A5`), obwohl `custom-colors.css` bereits `--primary` definiert.

**Namensklärung:** `header.php` ist **kein** HTML-Head-Partial, sondern der
Session-/Auth-/Bootstrap-Include (er endet vor `<!DOCTYPE>`). Die `<head>`-Kopie
beginnt in jeder Seite *danach*.

## 1. Größter Hebel: gemeinsames Layout-Partial für Head + Navbar

Reduziert 10 potenzielle Abweichungen auf eine Quelle. Die Struktur existiert
schon: jede Seite ruft oben `require_once ".../header.php"`.

- **`header.php` bleibt unverändert** (Session/Auth/Konstanten/DB) — nicht
  anfassen, das ist Backend-Logik.
- Neu **`partials/head.php`**: `<!DOCTYPE>`, `<head>` mit Meta, Bootstrap-CSS,
  **einer** FontAwesome-Version, `custom-colors.css`, der zentralen App-CSS,
  jQuery/Popper/Bootstrap-JS und `<body>`. Titel über eine Variable
  (`$pageTitle`).
- Neu **`partials/navbar.php`**: der Navbar-Block aus `index.php`.
- Seiten-spezifische Assets (bootstrap-select nur in `detail/`,
  dropzone/pdf.js nur in `dokumente/`) über eine Konvention: `$extraHead`-Array
  vor dem Include.

Nutzung pro Seite: `header.php` (Auth) → `$pageTitle` setzen →
`include 'partials/head.php'` → `include 'partials/navbar.php'` → Inhalt →
Footer-Partial. Aus ~40 Zeilen kopiertem Head werden zwei Include-Zeilen.

**Stolperstelle:** Die kopierten Heads nutzen teils relative Asset-Pfade
(`href="style.css"`), teils absolute. Im zentralen Partial müssen alle Pfade
**absolut über `$BASE_URL`** laufen, sonst brechen Unterordner-Seiten.

## 2. Inline-Styles durch Utility-Klassen ersetzen; Rest in Token-CSS

Direkte 1:1-Ersetzungen mit Bootstrap-4-Utilities (kein optischer Unterschied):

- `style='display:none;visibility:hidden'` → Klasse `d-none`. **Achtung:** das JS
  `setVisibility()` in `script.js` toggelt `style.display` — beim Umstieg auf
  `classList.toggle('d-none')` umstellen, zusammen ändern.
- `style='color: white; margin:auto'` → `text-white m-auto`.
- `style='text-align: right'` → `text-right`; `center` → `text-center`.
- `style='margin-bottom:10px'` → Spacing-Utilities `mb-2` etc.
- `display:flex; flex-wrap:nowrap; justify-content:space-between` →
  `d-flex flex-nowrap justify-content-between`.
- Navbar-Suchicon (absolut positioniert) → Bootstrap **Input-Group** mit
  `input-group-text` + FA-Icon.
- Burger-Button-Höhenfix (`calc(...)`) → benannte Klasse in der zentralen CSS.

**Echte Custom-Styles zentralisieren mit Tokens:** `custom-colors.css` zur
einzigen Token-Quelle ausbauen (neben `--primary` auch die Grautöne, Radius,
Sidebar-Offset). Die 9 verstreuten `style.css` in **eine** App-CSS (`css/app.css`)
zusammenführen, die die Tokens konsumiert. Wo `!important` nur Bootstrap
überschreibt, durch Bootstrap-Kontextklassen ersetzen.

Faustregel: **Erst Utility-Klasse, dann Token-Variable, und nur wenn beides
fehlt** eine benannte Regel — nie wieder Inline-Style.

## 3. Bootstrap-Komponenten konsistent; FontAwesome vereinheitlichen

- **Tabellen:** aufklappbare Zeilen in `bpTable.php` (Unicode-Pfeile + `onclick`
  - `display:none`) idiomatischer über Bootstrap-`collapse` oder zumindest
  `d-none`. Die `thead-dark`-Tabellen in `news/`, `dokumente/`, `settings/`,
  `search/` auf dieselben Utility-Sets bringen.
- **Cards:** die handgebaute Termin-Sidebar (`.termine-item` …) ließe sich als
  `card` + `list-group` mit weniger Custom-CSS abbilden.
- **Modals/Forms:** auf einheitliches Bootstrap-Markup normalisieren.
- **FontAwesome auf eine Version** (v5.9.0, bereits im Einsatz, abwärtskompatibel
  zu v5.7/5.8) — zentral im Head-Partial. Damit verschwinden die drei parallelen
  Ladepfade.

## 4. Risikoarme Reihenfolge, abgesichert per Golden-Master

Der Golden-Master (`tests/goldenmaster.sh`) vergleicht die gerenderte
HTML-Ausgabe gegen eine Baseline. **Reine Refactorings mit identischem Output**
(Head/Navbar in Includes, byte-identisch) müssen einen leeren Diff ergeben.
**Markup-ändernde, aber optisch neutrale Schritte** (Inline-Style → Utility)
ändern Bytes: Diff bewusst prüfen, im Browser sichten, dann `capture` neu
ausführen (Baseline nachziehen).

1. **Baseline sichern** (`capture`).
2. **Head-Partial extrahieren, byte-identisch** — zuerst nur `index.php`, prüfen,
   dann die übrigen. Leerer `check`-Diff als Ziel.
3. **Navbar-Partial extrahieren**, Seite für Seite.
4. **FontAwesome auf v5.9.0 vereinheitlichen** (nur im Partial), Baseline
   nachziehen.
5. **CSS konsolidieren** (Ordner-`style.css` → `css/app.css`, Tokens in
   `custom-colors.css`), Sichttest pro Seitentyp.
6. **Inline-Styles → Utilities**, gebündelt pro Muster (inkl. `script.js`-
   Anpassung bei `d-none`). Nach jedem Bündel `check`, Baseline nachziehen.
7. **Komponenten-Angleich** (Tabellen/Cards/Modals) zuletzt und optional.

Prinzip: **erst Struktur (Includes) — dort schützt der leere Diff maximal —,
dann Kosmetik**, wo bewusst re-baselined wird.

## 5. Was hier bewusst NICHT passiert

Kein Upgrade Bootstrap 4 → 5, kein Wechsel auf Composer/npm-Assets, kein
Framework, keine Backend-Umstellung, keine neue Seiten-Architektur.

**Warum diese Bereinigung eine spätere Modernisierung erleichtert:** Sobald
`<head>` und Asset-Liste an einer Stelle stehen, wird ein späteres Bootstrap-5-
Upgrade oder die Umstellung auf lokale Assets eine Ein-Datei-Änderung statt 10
Kopien. Sind Farben/Abstände als CSS-Variablen zentralisiert, ist ein
Dark-Mode-Ausbau (der Code hat bereits `$_SESSION['darkMode']` und
`library/darkBootstrap.min.css`, aber unverdrahtet) nur ein Umschalten der
Token-Werte. Utility-Klassen überstehen einen Bootstrap-5-Wechsel meist per
Suchen-Ersetzen (`ml-*`→`ms-*`, `text-right`→`text-end`).

Siehe auch [Frontend-Abhängigkeiten](frontend-abhaengigkeiten.md) (Composer/npm,
Versions-Upgrades) und [Code-Strategie](code-strategie.md).
