{# Eine Mangelkarte (Epic 11, Block 11.9, U10b), seit U30 der Inhalt der eigenen Seite des Mangels (`baumangel_seite.html`). **Die Liste ist seit U30 eine Tabelle** (Produktentscheid 21.10.2026); was nicht in eine Zeile passt (Beschreibung, Fotos, Verlauf), steht hier. Darum ist der Titel die Überschrift der Seite (`h1`) und der Verlauf ein Abschnitt darunter (`h2`). **Was hier stehen darf, entscheidet die API** (Positivliste, Schnittstelle `portal-baumaengel.md`). Die Karte filtert nichts nach und erfindet nichts dazu: Was fehlt, fehlt — leere Zeilen verschwinden, und ausdrücklich steht dort kein «unbekannt» (dieselbe Regel wie beim Kontrollbuch). `zustand_text` kommt fertig aus der API («Behoben, nicht abgenommen») und wird wörtlich gezeigt; nur die Farbe wählt das Portal (`BAUMAENGEL_TON`). **Der Satz «wer am Zug ist» kommt aus `BAUMAENGEL_ZUG`** (U10c, Produktentscheide 15.10.2026, Punkt 1): Die Tabelle steht neben `BAUMAENGEL_TON` in `main.py`, die Karte zeigt `zug` wörtlich. Nur drei Zustände tragen einen; fehlt er, steht hier nichts. **Der Verlauf steht in der Reihenfolge der Erfassung und wird NICHT umsortiert.** Eine nachgetragene Abnahme kann ein früheres Datum tragen als «behoben» davor (eingegebenes Datum, Schnittstelle) — das ist der Bestand, nicht ein Fehler, und Umsortieren wäre eine zweite Wahrheit. **HEIC-Fotos zeigt der Browser nicht.** Sie sind trotzdem Beweisfotos und gehen als Verweis zum Herunterladen hinaus; ein `` darauf wäre eine leere Fläche. Die Kennung geht durch `|pfadteil`: Autoescape hält den Wert im Attribut, ist aber keine URL-Kodierung (siehe `pfadteil` in `vorlage.py`). #} {% import "bausteine/bausatz.html" as b %}

{{ m.get('titel', '') }}

{{ b.kapsel(m.get('zustand_text', ''), m.get('ton', 'neutral')) }}{% if m.get('nummer') %} {{ m.get('nummer') }}{% endif %}

{{ m.get('liegenschaft', '') }}{% if m.get('anlage') %} · {{ m.get('anlage') }}{% endif %}

{#- Der Satz, wer am Zug ist, direkt unter dem Kopf der Karte. Er ist die Antwort auf die Frage, die der Zustand aufwirft, und steht darum in normaler Schrift vor der Beschreibung — nicht als leise Kopfzeile. -#} {%- if m.get('zug') %}

{{ m.get('zug') }}

{% endif %} {%- if m.get('beschreibung') %}

{{ m.get('beschreibung') }}

{% endif %} {#- Die drei Daten als Eckwerte, jeder nur wenn er da ist. «Gerügt» und «Behoben» fehlen bei jungen Mängeln; eine Zeile mit leerem Wert wäre ein Versprechen ohne Inhalt. -#} {%- if m.get('entdeckt_am') or m.get('geruegt_am') or m.get('behoben_am') %}
{%- if m.get('entdeckt_am') %}
Entdeckt
{{ datum_kurz(m.get('entdeckt_am', '')) }}
{% endif %} {%- if m.get('geruegt_am') %}
Gerügt
{{ datum_kurz(m.get('geruegt_am', '')) }}
{% endif %} {%- if m.get('behoben_am') %}
Behoben
{{ datum_kurz(m.get('behoben_am', '')) }}
{% endif %}
{%- endif %} {%- if m.get('fotos') %}
{%- for f in m.get('fotos') %} {%- set fid = f.get('id', '') %} {%- if fid %} {%- if f.get('inhaltstyp') in ('image/jpeg', 'image/png', 'image/webp') %} {{ f.get('dateiname', '') }} {%- else %} {{ f.get('dateiname', '') or 'Foto' }} herunterladen {%- endif %} {%- endif %} {%- endfor %}
{%- endif %} {%- if m.get('verlauf') %}

Verlauf

    {%- for s in m.get('verlauf') %}
  1. {{ s.get('text', '') }}{% if s.get('datum') %}{{ datum_kurz(s.get('datum', '')) }}{% endif %}
  2. {%- endfor %}
{%- endif %}