* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    line-height: 1.6;
    color: #333;
    background: #f5f5f5;
}

a {
    color: #2563eb;
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* Header */
header {
    background: #1e3a5f;
    color: white;
    padding: 1rem 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

header h1 {
    font-size: 1.5rem;
}

header h1 a {
    color: white;
}

header h1 a:hover {
    text-decoration: none;
}

header nav a {
    color: #93c5fd;
    margin-left: 1.5rem;
}

header nav a:hover {
    color: white;
}

/* Main */
main {
    max-width: 1200px;
    margin: 2rem auto;
    padding: 0 1rem;
}

/* Buttons */
button, .btn {
    background: #2563eb;
    color: white;
    border: none;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    display: inline-block;
}

button:hover, .btn:hover {
    background: #1d4ed8;
    text-decoration: none;
}

.btn-secondary {
    background: #6b7280;
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    display: inline-block;
}

.btn-secondary:hover {
    background: #4b5563;
    text-decoration: none;
}

/* Löschen-Einstieg unten in der Bearbeiten-Maske (Schritt 3 aus docs/PLAN.md, .form-actions
   in edit.html): gleiche Größe wie Speichern/Abbrechen daneben, aber rot wie .btn-delete —
   die gefährliche Handlung soll sich von den beiden übrigen abheben. Eigene Klasse statt
   .btn-delete, weil dieses hier ein Link ist, kein <button>, und deutlich größer als die
   kleinen Löschen-Schaltflächen an Kacheln und Kostenzeilen sein soll. */
.btn-delete-link {
    background: #dc2626;
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    display: inline-block;
}

.btn-delete-link:hover {
    background: #b91c1c;
    text-decoration: none;
}

/* Forms */
.form-group {
    margin-bottom: 1rem;
}

.form-group label {
    display: block;
    margin-bottom: 0.25rem;
    font-weight: 500;
}

/* Bauphase und Folgetermin teilen sich eine Zeile: beide Werte sind kurz
   (ein Phasenkürzel, ein Datum) und kosteten je eine volle Formularzeile.
   Der Abstand nach unten kommt weiter aus .form-group, deshalb nur ein
   Spalten-Gap. */
.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 1rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
textarea,
select {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid #d1d5db;
    border-radius: 4px;
    font-size: 1rem;
}

textarea {
    resize: vertical;
}

.checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-weight: normal;
}

.form-actions {
    margin-top: 1.5rem;
    display: flex;
    gap: 1rem;
}

/* Login */
.login-page {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #1e3a5f;
}

.login-container {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    width: 100%;
    max-width: 400px;
}

.login-container h1 {
    text-align: center;
    margin-bottom: 1.5rem;
    color: #1e3a5f;
}

.error {
    background: #fee2e2;
    color: #991b1b;
    padding: 0.75rem;
    border-radius: 4px;
    margin-bottom: 1rem;
}

/* Filters */
.filters {
    background: white;
    padding: 1rem;
    border-radius: 8px;
    margin-bottom: 1rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.filter-form {
    display: flex;
    gap: 1rem;
    align-items: center;
    flex-wrap: wrap;
}

.filter-form input[type="text"] {
    width: auto;
    min-width: 200px;
}

.filter-form select {
    width: auto;
}

/* Table */
table {
    width: 100%;
    background: white;
    border-collapse: collapse;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

th, td {
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid #e5e7eb;
}

th {
    background: #f9fafb;
    font-weight: 600;
}

tr:hover {
    background: #f9fafb;
}

.datum {
    width: 120px;
    white-space: nowrap;
}

/* Aktionsspalte der Übersichtstabelle. Die Detailansicht benutzt diese Klasse seit
   docs/archive/PLAN-2026-09-ansicht.md, Schritt 1, NICHT mehr: Dort erzwang die feste Breite
   den Umbruch zwischen »Zurück« und »Bearbeiten«, siehe .arbeit-aktionen. */
.actions {
    width: 180px;
}

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

/* Übersicht: Bauteil, Phase und Kategorien. Datum (120 px) und Aktionen (180 px) sind
   gesetzt, Bauteil und Phase bekommen je eine schmale feste Breite, den Rest teilen
   sich Titel und Kategorien. */
.bauteil-zelle,
.projektphase-zelle {
    width: 110px;
}

.kategorien-zelle .kategorie {
    margin-bottom: 0.25rem;
}

.no-results {
    background: white;
    padding: 2rem;
    text-align: center;
    border-radius: 8px;
}

/* Detail View */
.arbeit-detail {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.arbeit-header {
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid #e5e7eb;
}

.arbeit-header h2 {
    margin-bottom: 0.5rem;
}

/* Schaltflächenzeile der Detailansicht (docs/archive/PLAN-2026-09-ansicht.md, Schritt 1): steht
   unter dem Text, nicht mehr im Kopf, und hält »Zurück« und »Bearbeiten« nebeneinander.
   Bewusst nicht .actions — deren feste Breite von 180 px gilt der Spalte der
   Übersichtstabelle und brach die beiden Schaltflächen hier um. */
.arbeit-aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 1.5rem 0 2rem;
}

.meta {
    color: #6b7280;
    margin-bottom: 1rem;
}

.meta span {
    margin-right: 1.5rem;
}

.folgetermin {
    color: #b45309;
}

/* Schritt 3: Eintrag gehört nicht zum aktuell aktiven Objekt */
.objekt-kennzeichnung {
    display: inline-block;
    background: #fef3c7;
    color: #92400e;
    padding: 0.15rem 0.6rem;
    border-radius: 9999px;
    font-weight: 600;
}

.objekt-umschalter {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.kategorien {
    margin-bottom: 1.5rem;
}

.kategorie {
    display: inline-block;
    background: #dbeafe;
    color: #1e40af;
    padding: 0.25rem 0.75rem;
    border-radius: 9999px;
    font-size: 0.875rem;
    margin-right: 0.5rem;
}

/* Kürzel mit hinterlegter Beschreibung (docs/archive/PLAN-2026-09-ansicht.md, Schritt 3): Dass
   im Mouseover etwas steht, ist sonst nicht zu erraten. Der Ausschluss von title=""
   ist nötig, weil die Templates das Attribut immer setzen — auch dort, wo im Vokabular
   keine Beschreibung gepflegt ist. */
.kategorie[title]:not([title=""]),
.bauteil[title]:not([title=""]),
.projektphase[title]:not([title=""]),
.plan-marke[title]:not([title=""]) {
    cursor: help;
}

.beschreibung {
    white-space: pre-wrap;
    margin-bottom: 2rem;
}

/* sql/012_kostenplaene.sql, Schritt 1e/6: Bauteil (ersetzt den früheren Bauabschnitt —
   die Leistungsphase LPH1-9 sitzt seither in der Kostenstelle der Kosten-Position). */
.bauteil {
    display: inline-block;
    background: #ede9fe;
    color: #5b21b6;
    padding: 0.15rem 0.6rem;
    border-radius: 9999px;
    font-weight: 600;
}

/* Projektphase an der Arbeit (sql/012_kostenplaene.sql, Schritt 1f/6): eigene, gedämpftere
   Farbe als Bauteil — beide Pillen stehen nebeneinander in derselben Zeile/Zelle. */
.projektphase {
    display: inline-block;
    background: #e0f2fe;
    color: #075985;
    padding: 0.15rem 0.6rem;
    border-radius: 9999px;
    font-weight: 600;
}

/* Plan-Pille an der Anhangskachel (sql/013_plaene.sql, docs/archive/PLAN-2026-09-planlisten.md,
   Schritt 3): eigene Farbe, damit sie nicht mit .bauteil verwechselt wird — beide können
   an derselben Kachel bzw. Zeile nebeneinander stehen. */
.plan-marke {
    display: inline-block;
    background: #dcfce7;
    color: #166534;
    padding: 0.15rem 0.6rem;
    border-radius: 9999px;
    font-weight: 600;
    margin: 0.35rem 0;
}

/* Behälter mit mehr als einer Datei (docs/PLAN-2026-09-anhang-container.md,
   Entscheidung 10): sichtbar ohne Aufklappen, nach dem Muster von .plan-marke, aber
   gedämpfter — die zweite Datei ist eine Eigenschaft des Anhangs, keine eigene Rolle
   wie »Plan«. Bei genau einer Datei (353 von 357) erscheint gar nichts. */
.dateien-marke {
    display: inline-block;
    background: #e5e7eb;
    color: #374151;
    padding: 0.15rem 0.6rem;
    border-radius: 9999px;
    font-size: 0.8125rem;
    font-weight: 600;
    margin: 0.35rem 0;
}

.dateien-marke[title]:not([title=""]) {
    cursor: help;
}

.anhang-dateien > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    color: #4b5563;
}

.anhang-dateien-liste {
    list-style: none;
    margin: 0.35rem 0 0;
    padding: 0;
    font-size: 0.8125rem;
}

.anhang-dateien-liste li {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    padding: 0.15rem 0;
}

/* Die Knöpfe je Datei stehen in eigenen Formularen und würden sonst untereinander
   brechen. */
.anhang-datei-aktionen {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
}

.anhang-datei-aktionen form {
    margin: 0;
}

/* Zweite Endung in der Spalte »Datei« auf /plaene ("plan.pdf + dwg") und der passende
   Dateiname in der Trefferliste der Anhangssuche — beide gedämpft: Sie ergänzen die
   Angabe daneben, sie ersetzen sie nicht. */
.weitere-datei,
.anhang-treffer-datei {
    color: #6b7280;
    font-size: 0.8125rem;
}

/* Feldbeschreibung unter einem Formularfeld — kleiner, gedämpfter Fließtext, anders als
   .hinweis (Warnfarbe für "ohne Nachweis"/"abgelaufen"). Bislang nur an Bauteil
   (sql/012_kostenplaene.sql, Schritt 1e/6), um die Faustregel gegen die Kategorie
   unterzubringen. */
.feld-hinweis {
    color: #6b7280;
    font-size: 0.8125rem;
    margin-top: 0.25rem;
}

/* Kosten (Schritt 9) */
.kosten {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.kosten h3 {
    margin-bottom: 1rem;
}

.kosten-erfassen {
    margin-top: 1.5rem;
}

.kosten-erfassen summary {
    cursor: pointer;
    font-weight: 600;
    margin-bottom: 1rem;
}

.kosten-tabelle {
    width: 100%;
    background: white;
    border-collapse: collapse;
    margin-bottom: 1rem;
}

.kosten-tabelle th, .kosten-tabelle td {
    padding: 0.5rem 0.75rem;
    text-align: left;
    border-bottom: 1px solid #e5e7eb;
}

.kosten-tabelle tfoot td {
    font-weight: 600;
    border-top: 2px solid #d1d5db;
    border-bottom: none;
}

/* Aktionszeile der Kostentabelle (Schritt 2 aus docs/PLAN.md), dieselbe Bauform wie
   .anhang-aktionen an der Anhangskachel: Bearbeiten und Löschen liegen nebeneinander in
   einer eigenen Zeile unter dem Kosteneintrag. Der Löschen-Knopf stand zunächst in einer
   sechsten Tabellenspalte rechts, während Bearbeiten darunter saß — zwei Schaltflächen
   zu einem Eintrag an zwei Orten. Die Zelle trägt nicht die Polsterung der Datenzeilen
   darüber, sonst wirkte sie wie eine weitere, leere Kostenzeile. */
.kosten-bearbeiten td {
    padding: 0 0.75rem 0.5rem;
    border-bottom: 1px solid #e5e7eb;
}

/* flex-wrap zusammen mit der [open]-Regel unten gibt dem aufgeklappten Formular die
   volle Zeilenbreite; Löschen rückt dann darunter — wie an der Anhangskachel. */
.kosten-aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
}

/* .delete-form bringt für den Einsatz außerhalb dieser Zeile einen eigenen Abstand mit,
   der hier die beiden Schaltflächen gegeneinander versetzen würde. */
.kosten-aktionen .delete-form {
    margin-top: 0;
}

.kosten-bearbeiten-formular {
    flex: 0 0 auto;
}

.kosten-bearbeiten-formular[open] {
    flex: 1 0 100%;
    padding-bottom: 0.5rem;
}

.kosten-bearbeiten-formular[open] .btn-edit {
    margin-bottom: 0.75rem;
}

.betrag {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Drilldown-Links auf /kosten (docs/PLAN-2026-09-kosten-drilldown.md, Schritt 4): dieselbe
   Linkfarbe wie überall im Projekt, kein eigener Zierrat -- .erklaert ist an denselben
   Zeilen bereits vergeben (Mouseover-Erklärung der Phasen), eine zweite Markierung
   erklärte nichts mehr. white-space: nowrap kommt schon von .betrag; der Link darf den
   Umbruch nicht einführen. */
.kosten-tabelle td.betrag a,
.kosten-gesamt a {
    color: #2563eb;
}

.hinweis {
    color: #92400e;
    font-size: 0.875rem;
}

/* Eine Stelle, an der eine Mouseover-Erklärung (title) zu holen ist. Phasencodes wie
   "2c" sind ohne Erklärung nicht lesbar, ein title-Attribut allein aber unsichtbar --
   die gepunktete Unterstreichung und der Hilfe-Zeiger sagen, dass hier etwas steht.
   Bewusst nur an den Phasen (Abschnitt, Tabellenköpfe, Zellen) und nicht an jedem title
   im Projekt: Eine Markierung, die überall steht, zeigt nichts mehr an. Auswahlfelder
   und Pillen bleiben ebenfalls unmarkiert -- die laden von sich aus zum Draufgehen ein. */
.erklaert {
    text-decoration: underline dotted #9ca3af;
    text-underline-offset: 0.2em;
    cursor: help;
}

/* Eine leere Phasenzelle hat keinen Text, den man unterstreichen könnte -- der
   Hilfe-Zeiger bleibt, die Erklärung dazu steht im Spaltenkopf. */
td.erklaert:empty {
    cursor: default;
}

/* Eine wirksame Projektphase, die aus der Kostenstelle abgeleitet ist (kostengliederung.pph
   statt kosten.pph, siehe Kosten.IstPPHAbgeleitet) — gedämpft, damit sie nicht wie ein
   gepflegter Wert aussieht (docs/archive/PLAN-2026-09-kostenplaene.md, Schritt 5e). */
.abgeleitet {
    color: #9ca3af;
    font-style: italic;
}

.kosten-summen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.kosten-gesamt, .kosten-gruppe {
    background: white;
    padding: 1rem;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.kosten-gesamt {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-bottom: 1.5rem;
}

.kosten-gesamt strong {
    font-size: 1.5rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Die drei Gliederungen auf /kosten (docs/archive/PLAN-2026-09-kostenplaene.md, Schritt 5):
   ÖNORM B 1801-1, Projektphasen, Schätzung Kuen. Eigene Karte je Abschnitt, dieselbe
   Bauform wie .kosten-gesamt/.kosten-gruppe darin. */
.kosten-abschnitt {
    background: white;
    padding: 1rem 1.5rem 1.5rem;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    margin-bottom: 1.5rem;
}

.kosten-abschnitt .kosten-summen {
    margin-bottom: 0;
}

.kosten-abschnitt .kosten-gruppe {
    box-shadow: none;
    padding: 0;
}

.kosten-abschnitt h4 {
    margin-bottom: 0.25rem;
}

/* Grobelement-Zeilen unter ihrem Kostenbereich einrücken (Schritt 5a): '2' bleibt
   flach, '2B' eine Stufe, eine Elementzeile ('7C.LPH3') zwei Stufen tiefer. */
.kostengruppe-ebene-2 td:first-child {
    padding-left: 1.5rem;
}

.kostengruppe-ebene-3 td:first-child {
    padding-left: 3rem;
}

/* Kennzahlen BWK/BAK/ERK/GEK (Schritt 5a): gerechnet, nicht gespeichert — siehe
   kostenKostenbereich in handlers/kosten.go. */
.kennzahlen {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid #e5e7eb;
}

.kennzahlen > div {
    display: flex;
    flex-direction: column;
}

.kennzahlen dt {
    font-size: 0.75rem;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.kennzahlen dd {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* Die Kuen-Spalte der flachen Liste auf /kosten (Schritt 5e) bekommt bewusst KEIN
   display:none unter 640px, anders als seinerzeit die Bauabschnitt-Spalte der
   Arbeitenliste: .kosten-tabelle ist inzwischen ihr eigener horizontaler
   Scroll-Container (siehe @media weiter unten), acht Spalten laufen dort nebeneinander
   weiter statt eine zu verlieren. */
.kuen-zelle {
    white-space: nowrap;
}

.kosten-ohne-nachweis {
    margin-bottom: 1.5rem;
}

/* Beleg-Kopfdaten (docs/PLAN-2026-09-belege.md, Schritt 3): einfache Definitionsliste,
   zwei Spalten je Zeile ab genug Platz, darunter (Mobilansicht) einspaltig gestapelt. */
.beleg-daten {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.5rem 1.5rem;
    margin-bottom: 1rem;
}

.beleg-daten div {
    display: flex;
    gap: 0.5rem;
}

.beleg-daten dt {
    color: #6b7280;
    min-width: 8rem;
}

.beleg-daten dd {
    font-weight: 500;
}

/* Probe auf /beleg/{id}: Summe der Positionen gegen die Belegsumme. */
.beleg-probe {
    background: white;
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin: 1rem 0;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.beleg-probe-abweichung {
    background: #fef2f2;
    color: #b91c1c;
}

/* Belegliste /belege (docs/PLAN-2026-09-belegliste.md, Schritt 4). Zwei Ebenen in einer
   Tabelle: je Beleg ein <tbody> mit der Belegzeile und darunter seinen Positionen. Die
   Abgrenzung läuft deshalb über die Gruppe (obere Linie je tbody) statt über
   Zebrastreifen je Zeile — die würden hier quer zur Gliederung laufen. */
.belegliste {
    margin-top: 1.5rem;
    /* Der Scroll-Container ist der umgebende div, NICHT die Tabelle: Eine Tabelle, die
       per min-width breiter als ihr Kasten ist, scrollt sich nicht selbst — sie schiebt
       stattdessen die ganze Seite seitlich weg. Beides steht hier und nicht in der
       Media-Query, weil fünf Spalten auch zwischen 640 px und 800 px nicht in die
       Breite passen und dort sonst niemand zuständig wäre. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* table-layout: fixed macht die colgroup-Breiten verbindlich statt zu einem Vorschlag,
   den der längste Zelleninhalt überstimmt. Die Mindestbreite ist die Gegenprobe dazu:
   Unter ~800 px ergeben fünf feste Spalten nur noch Wortsalat — ein Rechnungsdatum
   bricht dann mitten entzwei. overflow-wrap fängt ab, was trotzdem nicht in seine
   Spalte passt (lange Dateinamen sind über kuerzeDateiname ohnehin begrenzt). */
.belegliste .kosten-tabelle {
    table-layout: fixed;
    min-width: 800px;
}

.belegliste .kosten-tabelle td,
.belegliste .kosten-tabelle th {
    overflow-wrap: anywhere;
}

.belegliste tbody.beleg {
    border-top: 2px solid #e5e7eb;
}

/* Gruppenkopf mit dem Aussteller und seiner Zwischensumme. Er ist der Grund für die
   ganze Ansicht: Die Belege eines Ausstellers untereinander zeigen eine Lücke, die in
   der chronologischen Liste zwischen fremden Zeilen untergeht. */
.belegliste tbody.aussteller-kopf th,
.belegliste tbody.aussteller-kopf td {
    background: #f3f4f6;
    border-top: 2px solid #d1d5db;
    border-bottom: none;
    font-weight: 600;
    padding-top: 0.75rem;
}

/* Die Einrückung sitzt am ersten td, nicht am tr: Ein <tr> nimmt weder padding noch
   text-indent an. */
.belegliste tr.position td {
    font-size: 0.875rem;
    color: #4b5563;
    border-bottom: none;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}

.belegliste tr.position td:first-child {
    padding-left: 2rem;
}

/* Die Kostenstelle steht vor dem Arbeitstitel in derselben Zelle. Betrag, Belegsumme,
   Zwischensumme und Gesamtsumme teilen sich dafür EINE Spalte — die Probe »Positionen
   ergeben die Belegsumme« liest sich sonst nicht ab. Die frühere zusätzliche
   Bauabschnitt-Pille (Bauteil der Arbeit) ist mit Kosten.Bauabschnitt entfallen
   (sql/012_kostenplaene.sql, Schritt 6) — die Kostenstelle der Position selbst steht
   jetzt allein hier. */
.belegliste tr.position .kostenstelle {
    display: inline-block;
    min-width: 3.5rem;
    color: #6b7280;
    font-weight: 600;
}

/* Planliste /plaene (docs/archive/PLAN-2026-09-planlisten.md, Schritt 5): eigener
   Scroll-Container wie .belegliste (siehe dort für die Begründung), acht schmale
   Spalten statt fünf, daher die größere Mindestbreite. */
.planeliste {
    margin-top: 1.5rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.planeliste .kosten-tabelle {
    table-layout: fixed;
    min-width: 1000px;
}

.planeliste .kosten-tabelle td,
.planeliste .kosten-tabelle th {
    overflow-wrap: anywhere;
}

.planeliste tbody.plantyp-kopf th {
    background: #f3f4f6;
    border-top: 2px solid #d1d5db;
    font-weight: 600;
}

.planeliste-anzahl {
    color: #6b7280;
    margin-top: 0.75rem;
}

/* Verweis von /kosten auf die Belegliste, an der Stelle der früheren Probenliste. */
.belege-verweis {
    background: white;
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 1.5rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

/* Umschalter für die Ordnung, neben dem Filterformular. */
.sortierung-form {
    align-items: center;
}

.sortierung-form label {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

/* Rückwärts-Referenzen (Schritt 4) */
.verweise {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.verweise h3 {
    margin-bottom: 1rem;
}

/* Anhänge */
.anhaenge {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.anhaenge h3 {
    margin-bottom: 1rem;
}

.anhaenge-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1rem;
}

.anhang img {
    width: 100%;
    height: 150px;
    object-fit: cover;
    border-radius: 4px;
}

/* PDF-Kachel (docs/archive/PLAN-2026-09-ansicht.md, Schritt 2): dasselbe Raster wie beim Foto,
   aber die Seite wird eingepasst statt beschnitten — bei "cover" bliebe von einer
   Rechnung nur der mittlere Streifen übrig. Der weiße Grund hinter dem eingepassten
   Bild lässt die Seite als Blatt erscheinen. */
.anhang-pdf img {
    object-fit: contain;
    background: white;
    border: 1px solid #e5e7eb;
}

.anhang-bezeichnung {
    font-size: 0.875rem;
    font-weight: 600;
    margin-top: 0.5rem;
    word-break: break-word;
}

.anhang-beschreibung {
    font-size: 0.875rem;
    color: #6b7280;
    margin-top: 0.5rem;
}

.file-link {
    display: block;
    padding: 1rem;
    background: #f3f4f6;
    border-radius: 4px;
    text-align: center;
}

.delete-form {
    margin-top: 0.5rem;
}

.btn-delete {
    background: #dc2626;
    color: white;
    border: none;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.75rem;
}

.btn-delete:hover {
    background: #b91c1c;
}

.upload-section {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.upload-section h3 {
    margin-bottom: 1rem;
}

/* Löschen-Bestätigungsseite (Schritt 3 aus docs/PLAN.md, templates/loeschen.html): macht
   sichtbar, was am Eintrag hängt, bevor er verschwindet — die Seite selbst ist die
   Bestätigung, kein confirm()-Dialog. */
.loeschen-meta {
    color: #6b7280;
    margin-bottom: 1.5rem;
}

.loeschen-uebersicht {
    list-style: disc;
    padding-left: 1.25rem;
    margin: 0 0 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.loeschen-anhaenge {
    margin: 0.5rem 0 0 1.25rem;
    padding: 0;
    font-size: 0.875rem;
    color: #6b7280;
}

.loeschen-bleibt {
    color: #15803d;
}

.loeschen-mitgeloescht {
    color: #b91c1c;
}

.loeschen-sperre {
    color: #92400e;
    font-weight: 600;
}

/* Edit Form */
.arbeit-edit {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.arbeit-edit h2 {
    margin-bottom: 1.5rem;
}

.upload-section summary,
.anhang-verknuepfen summary {
    cursor: pointer;
    font-weight: 600;
    margin-bottom: 1rem;
}

/* Dezent wie die Beschreibung — der Dateiname ist eine Nebenangabe, keine
   Überschrift der Kachel. Genau eine Zeile: Zu lange Namen enden auf … , der
   vollständige steht im title-Attribut. */
.anhang-dateiname {
    font-size: 0.875rem;
    color: #6b7280;
    margin-top: 0.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Aktionen der Kachel: Bearbeiten und Löschen nebeneinander in einer Zeile.
   flex-wrap zusammen mit der [open]-Regel unten gibt dem aufgeklappten Formular
   die volle Kachelbreite; Löschen rückt dann darunter. */
.anhang-aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* .delete-form bringt für den Einsatz außerhalb dieser Zeile einen eigenen
   Abstand mit, der hier die beiden Schaltflächen gegeneinander versetzen würde. */
.anhang-aktionen .delete-form {
    margin-top: 0;
}

/* In der Trefferliste steht der Dateiname hinter der Bezeichnung statt in einer
   eigenen Flex-Spalte — inline-block, damit die Kürzung dort überhaupt greift. */
.anhang-treffer .anhang-dateiname {
    display: inline-block;
    max-width: 100%;
    vertical-align: bottom;
    margin: 0 0 0 0.4rem;
}

.anhang-dateiname-leer {
    color: #9ca3af;
}

.anhang-bearbeiten {
    flex: 0 0 auto;
}

/* Die Zusammenfassung ist die Schaltfläche »Bearbeiten«: blau, in Größe und Form
   wie das rote Löschen daneben (.btn-delete). */
.btn-edit {
    background: #2563eb;
    color: white;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    font-size: 0.75rem;
    cursor: pointer;
    /* Das Dreieck der details-Zusammenfassung weg — in einer Schaltfläche stünde
       sonst zweierlei Bedienung nebeneinander. display für Safari und ältere
       WebKit-Versionen (dort greift list-style auf summary nicht), list-style für
       Firefox, ::marker und ::-webkit-details-marker als dritter Weg für
       Safari-Versionen, die den Marker trotz display: flex zeichnen. */
    display: inline-flex;
    list-style: none;
    align-items: center;
    gap: 0.3rem;
}

.btn-edit::marker,
.btn-edit::-webkit-details-marker {
    content: "";
    display: none;
}

.btn-edit svg {
    width: 0.95em;
    height: 0.95em;
}

.btn-edit:hover {
    background: #1d4ed8;
}

.anhang-bearbeiten[open] {
    flex: 1 0 100%;
}

.anhang-bearbeiten[open] .btn-edit {
    margin-bottom: 0.75rem;
}

/* Dritte Schaltfläche der Anhangskachel, gleiche Bauform wie .anhang-bearbeiten. */
.anhang-freigeben {
    flex: 0 0 auto;
}

.anhang-freigeben[open] {
    flex: 1 0 100%;
}

.anhang-freigeben[open] .btn-edit {
    margin-bottom: 0.75rem;
}

/* Vierte Schaltfläche der Anhangskachel (docs/archive/PLAN-2026-09-planlisten.md, Schritt 3),
   gleiche Bauform wie .anhang-bearbeiten/.anhang-freigeben. */
.anhang-plan {
    flex: 0 0 auto;
}

.anhang-plan[open] {
    flex: 1 0 100%;
}

.anhang-plan[open] .btn-edit {
    margin-bottom: 0.75rem;
}

/* Freigabe-Links (docs/PLAN.md, Schritt 4) im Block #freigaben der Detailansicht,
   gleiche Grundform wie .kosten bzw. .anhaenge (Abstand zum Block darüber). */
.freigaben {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.freigaben h3 {
    margin-bottom: 1rem;
}

.freigabe-erstellen-formular {
    margin-bottom: 1rem;
}

.freigaben-liste {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.freigabe-eintrag {
    background: white;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 0.75rem 1rem;
}

/* Abgelaufen, aber bewusst nicht ausgeblendet — die Zeile bleibt sichtbar, damit klar
   ist, dass es diese Freigabe gab und dass sie nicht mehr funktioniert. */
.freigabe-abgelaufen {
    color: #9ca3af;
}

.freigabe-zeile {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

/* Markierbares, aber unveränderliches Eingabefeld: die ganze URL soll sich mit einem
   Klick markieren und kopieren lassen (siehe onclick="this.select()"), monospace macht
   den Token darin besser lesbar. */
.freigabe-url {
    flex: 1;
    min-width: 12rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.8rem;
    background: #f9fafb;
}

/* Freigegebener Anhang: Die Schaltfläche »Freigeben« an der Kachel wird grün, sobald
   eine gültige Freigabe besteht — an der Kachel selbst ist sonst nicht zu sehen, dass
   diese Datei außer Haus ist. Abgelaufene Freigaben färben nicht mehr, sie geben nichts
   mehr preis. */
.btn-freigegeben {
    background: #15803d;
}

.btn-freigegeben:hover {
    background: #166534;
}

/* Kopierknopf daneben: legt den Freigabe-Link in die Zwischenablage. Gleiche Größe wie
   die übrigen Kachel-Schaltflächen, aber zurückhaltend gefärbt — er ist eine Beigabe zur
   grünen Schaltfläche, keine eigene Handlung an den Daten. */
.btn-kopieren {
    background: #4b5563;
    color: white;
    border: none;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.75rem;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.btn-kopieren:hover {
    background: #374151;
}

.btn-kopieren svg {
    width: 0.95em;
    height: 0.95em;
}

/* Kurze Rückmeldung nach dem Kopieren — ohne sie bleibt offen, ob der Klick gewirkt hat. */
.btn-kopieren-fertig {
    background: #15803d;
}

/* Freigaben einer Kachel stehen im aufgeklappten Freigeben-Bereich unter dem Formular. */
.anhang-freigaben-liste {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
}

.freigabe-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.5rem;
    font-size: 0.875rem;
    color: #6b7280;
}

.freigaben-aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.freigaben-aktionen .delete-form {
    margin-top: 0;
}

.freigabe-verlaengern-formular {
    flex: 0 0 auto;
}

.freigabe-verlaengern-formular[open] {
    flex: 1 0 100%;
    padding-bottom: 0.5rem;
}

.freigabe-verlaengern-formular[open] .btn-edit {
    margin-bottom: 0.75rem;
}

/* Übersicht /freigaben (FreigabenListe): dieselbe Tabelle wie bei den Kosten. */
.freigaben-tabelle .freigabe-url {
    width: 100%;
    min-width: 10rem;
}

/* Freigabeseite (templates/freigabe.html): eigenes, schlankes Grundgerüst ohne das
   dunkle Kopfband der angemeldeten Seiten — der Empfänger hat kein Konto, ein Kopf mit
   Objekt-Umschalter und Navigation liefe für ihn ohnehin nur auf /login. */
.freigabe-header {
    background: #1e3a5f;
    color: white;
    padding: 1rem 2rem;
}

.freigabe-header h1 {
    font-size: 1.25rem;
}

.freigabe-inhalt {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.freigabe-footer {
    max-width: 1200px;
    margin: 0 auto 2rem;
    padding: 0 1rem;
    color: #6b7280;
    font-size: 0.875rem;
}

/* Kosten in einer Freigabe (docs/PLAN-2026-09-freigabe-kosten.md).

   Die Marke steht an zwei Stellen, an denen sonst nur Freundliches steht: in der
   Freigabenliste am Eintrag und in der Spalte "Kosten" auf /freigaben. Sie ist deshalb
   bewusst auffällig gesetzt und nicht grau wie die übrige Meta-Zeile — wer über seine
   Freigaben schaut, soll die mit Beträgen ohne Suchen finden. Dieselben Farben wie
   .hinweis, nur als gefüllte Marke. */
.freigabe-kosten-marke {
    display: inline-block;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    background: #fef3c7;
    color: #92400e;
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
}

/* Das Ankreuzfeld im Erstellen-Formular: Kästchen und Text in einer Zeile, der
   Erklärsatz darunter. .form-group label ist block und fett — für ein Kontrollkästchen
   beides falsch. */
.form-group-kontrollkaestchen label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 400;
}

.form-group-kontrollkaestchen input[type="checkbox"] {
    width: auto;
    margin: 0;
}

.feldhinweis {
    margin: 0.25rem 0 0 1.6rem;
    color: #6b7280;
    font-size: 0.8125rem;
}

.freigabe-kosten-fussnote {
    margin-top: 0.5rem;
    color: #6b7280;
    font-size: 0.875rem;
}

/* ==========================================================================
   Mobiltauglichkeit (Schritt 6) — Telefone bis 640px Breite.
   Lesepfad (Liste -> Detail -> Bild) hat Vorrang, die Edit-Maske muss hier
   nur benutzbar sein, nicht schön. Alles unterhalb wirkt ausschließlich in
   diesem Bereich, die Desktop-Darstellung bleibt unverändert.
   ========================================================================== */
@media (max-width: 640px) {

    main {
        margin: 1rem auto;
        padding: 0 0.75rem;
    }

    .arbeit-detail,
    .arbeit-edit {
        padding: 1rem;
    }

    /* Kopfzeile: Objektauswahl und Navigation umbrechen statt abzuschneiden */
    header {
        flex-wrap: wrap;
        gap: 0.5rem;
        padding: 0.75rem 1rem;
    }

    header h1 {
        width: 100%;
        font-size: 1.15rem;
    }

    .objekt-umschalter {
        width: 100%;
        flex-wrap: wrap;
    }

    .objekt-umschalter select {
        flex: 1;
        min-width: 0;
    }

    header nav {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }

    header nav a {
        margin-left: 0;
        padding: 0.5rem 0;
    }

    /* .arbeit-aktionen ist schon in der Grundregel ein flex-Container (siehe dort);
       am Handy bleibt nur der engere Abstand. */
    .arbeit-aktionen {
        gap: 0.5rem;
    }

    /* Schaltflächen mind. 44px hoch — gilt fürs ganze Formular, nicht nur den Kopf.
       .btn-delete-link (Schritt 3 aus docs/PLAN.md) ist ein Link wie .btn-secondary und
       braucht die Regel deshalb ausdrücklich, anders als .btn-delete: das sind immer
       <button>-Elemente und damit über den Selektor "button" bereits erfasst. */
    button, .btn, .btn-secondary, .btn-delete-link {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Einträgeliste: Tabelle -> gestapelte Karten, Aktionen-Spalte entfällt,
       die Karte selbst führt zum Eintrag */
    .arbeiten-liste table,
    .arbeiten-liste thead,
    .arbeiten-liste tbody,
    .arbeiten-liste tr,
    .arbeiten-liste th,
    .arbeiten-liste td {
        display: block;
        width: auto;
    }

    .arbeiten-liste thead {
        display: none;
    }

    .arbeiten-liste tr {
        position: relative;
        background: white;
        border-radius: 8px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        padding: 0.75rem 1rem;
        margin-bottom: 0.75rem;
    }

    .arbeiten-liste td {
        border-bottom: none;
        padding: 0.15rem 0;
    }

    .arbeiten-liste td.datum {
        color: #6b7280;
        font-size: 0.875rem;
    }

    .arbeiten-liste td.actions {
        display: none;
    }

    .arbeiten-liste td.bauteil-zelle,
    .arbeiten-liste td.projektphase-zelle,
    .arbeiten-liste td.kategorien-zelle {
        display: inline-block;
        width: auto;
        vertical-align: middle;
    }

    .arbeiten-liste td.bauteil-zelle,
    .arbeiten-liste td.projektphase-zelle {
        margin-right: 0.5rem;
    }

    /* Klickfläche über die ganze Karte legen — ein <tr> selbst als <a> wäre
       ungültiges HTML, stattdessen streckt sich der Titel-Link per ::after */
    .arbeiten-liste .karte-link::after {
        content: "";
        position: absolute;
        inset: 0;
    }

    /* Filter- und sonstige Formulare: volle Breite statt fester Mindestbreiten */
    .filter-form {
        flex-direction: column;
        align-items: stretch;
    }

    .filter-form input[type="text"],
    .filter-form select {
        width: 100%;
        min-width: 0;
    }

    .filter-form label {
        width: 100%;
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }

    .filter-form label input {
        flex: 1;
        min-width: 0;
    }

    /* Ausnahme von der Regel darüber: Die beiden Radioschalter der Belegliste sind keine
       Eingabefelder, die volle Breite brauchen — gestreckt schöben sie ihre Beschriftung
       aus dem Bild. Sie bleiben nebeneinander. */
    .sortierung-form label {
        width: auto;
        display: inline-flex;
    }

    .sortierung-form label input {
        flex: 0 0 auto;
    }

    .form-row {
        grid-template-columns: 1fr;
    }

    .form-actions {
        flex-direction: column;
        align-items: stretch;
    }

    /* 16px verhindert das Auto-Zoom beim Fokussieren in iOS-Safari */
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="date"],
    textarea,
    select {
        font-size: 16px;
    }

    /* Anhang-Raster: feste Mindestbreite weicht ein/zwei Spalten */
    .anhaenge-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }

    .anhang img {
        width: 100%;
        height: auto;
    }

    /* Wie die übrigen Schaltflächen (button, .btn) mit dem Finger treffbar —
       die Zusammenfassung ist kein <button> und fällt sonst durch die Regel oben. */
    .btn-edit {
        min-height: 44px;
        justify-content: center;
    }

    /* Breite Kosten-Tabellen (view.html-Kostenblock, kosten.html): eigener
       Scroll-Container statt Seiten-Scroll. Zeilen/Zellen behalten ihr
       Tabellen-Layout, nur die <table> selbst wird zum Block und darf
       innerhalb ihrer eigenen Breite scrollen. */
    .kosten-tabelle {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Zurück auf display: table — die Regel darüber macht jede .kosten-tabelle zu ihrem
       eigenen Scroll-Container, die Belegliste hat dafür aber ihren äußeren div. */
    .belegliste .kosten-tabelle {
        display: table;
    }

    /* Dieselbe Rückausnahme für die Planliste (docs/archive/PLAN-2026-09-planlisten.md, Schritt 5) —
       .planeliste ist ebenfalls schon ihr eigener äußerer Scroll-Container. */
    .planeliste .kosten-tabelle {
        display: table;
    }
}

@media (max-width: 420px) {
    /* Sehr schmale Geräte: eine Spalte statt zwei im Anhang-Raster */
    .anhaenge-grid {
        grid-template-columns: 1fr;
    }
}
