/* Farben von BauZeuge.de, Zeichen fuer Zeichen aus Base.astro uebernommen,
   damit App und Seite dieselbe Marke tragen.
   Systemschrift statt Webfont: spart Platz im APK und startet ohne Nachladen. */
:root {
  --papier: #f5f7f6;
  --karte: #ffffff;
  --tinte: #1f2a30;
  --tinte-leise: #54626a;
  --akzent: #0e6e72;
  --akzent-dunkel: #0a5155;
  /* Der Akzent fuer dunkle Flaechen. Petrol selbst waere dort zu dunkel. */
  --akzent-hell: #5fbabd;
  --linie: #d3dcd9;
  --band: #e9efec;
  --gut: #2e7d4f;
  --warn: #b3261e;
  /* Zustandsfarbe, keine Markenfarbe: "laeuft" braucht einen Ton, der weder
     mit dem Gruen von "fertig" noch mit dem Petrol der Marke verwechselbar
     ist. Kein Gold und kein Bernstein -- die Toene sollen nirgends mehr
     vorkommen. */
  --arbeit: #6a4fa3;
  --offen: #969eaa;

  /* Flaechen und Schrift der Plaketten und Kaesten. Frueher standen die
     Pastelltoene fest im Regelwerk; im dunklen Design waere daraus ein
     hellrosa Kasten mit dunkelrotem Text geworden. */
  --warn-flaeche: #fdecea;  --warn-schrift: #7f1d1a;
  --gut-flaeche: #e6f4ec;   --gut-schrift: #1e5c39;
  --info-flaeche: #e6eefc;  --info-schrift: #1e429f;
  --arbeit-flaeche: #efe9fa; --arbeit-schrift: #4a327d;
  /* Wetterlagen. Die Farbe sagt, ob draussen gearbeitet werden kann: klar
     und bewoelkt ruhig, Regen und Schnee kuehl, Sturm und Frost warnen. */
  --w-klar-flaeche: #dff0f2;   --w-klar-schrift: #0a5155;
  --w-grau-flaeche: #e7ebed;   --w-grau-schrift: #46545c;
  --w-nass-flaeche: #e2ecfb;   --w-nass-schrift: #1e429f;
  --w-kalt-flaeche: #e5eef7;   --w-kalt-schrift: #245b8c;
  --offen-flaeche: #fdecea; --offen-schrift: #9b2c22;
  /* Schrift auf einer Akzentflaeche. Im dunklen Design bleibt sie dunkel,
     weil der Akzent dort das helle Petrol ist. */
  --auf-akzent: #ffffff;
  --schleier: rgba(20, 22, 26, .55);
  --kopf-hoehe: 56px;
  /* Der Kopf mitsamt dem freigehaltenen Streifen der Statusleiste. Alles,
     was unter dem Kopf ansetzt -- die Seitenleiste, ihr Schatten --, rechnet
     mit dieser Zahl und nicht mit der reinen Kopfhoehe. Sonst rutscht es
     beim Ausfahren unter die Uhr. */
  --kopf-gesamt: calc(var(--kopf-hoehe) + env(safe-area-inset-top));
  --schrift: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Muss vor allem anderen stehen und !important tragen: die Regeln fuer
   #kopf .zurueck setzen display, und eine ID schlaegt das browsereigene
   [hidden] { display: none } jedes Mal. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  background: var(--papier); color: var(--tinte);
  font-family: var(--schrift); font-size: 16px; line-height: 1.5;
  overscroll-behavior-y: none;
}

/* Die Statusleiste des Telefons -- Uhr, Akku, bei neueren Geraeten die
   Kamera -- gehoert dem System und muss frei bleiben.
 *
 * Das stand vorher am body, und das war falsch: #kopf klebt mit
 * "position: sticky; top: 0" am oberen Rand des Sichtfensters, nicht am
 * Innenrand des body. Beim Scrollen wanderte er unter die Statusleiste und
 * verdeckte sie.
 *
 * Seit Android 15 faellt das auf, weil das System die App zwingt, bis unter
 * die Systemleisten zu zeichnen. Bis targetSdk 35 liess sich das abschalten,
 * ab 36 nicht mehr -- und 36 verlangt der Play Store. Also einruecken statt
 * ausweichen: Der Streifen bekommt die Farbe des Kopfes und bleibt leer. */
#kopf {
  padding-top: env(safe-area-inset-top);
  height: var(--kopf-gesamt);
}

/* Laufweite haengt an der Groesse: Je groesser die Schrift, desto weiter
   stehen die Buchstaben von selbst, und desto enger muessen sie gesetzt
   werden. Bei h2 (18px) und h3 (15px) waere das falsch -- kleine Schrift
   braucht eher mehr Luft, nicht weniger. Darum steht es nur an h1. */
h1 { font-size: 24px; line-height: 1.2; margin: 0 0 4px; font-weight: 700; letter-spacing: -.01em; }
h2 { font-size: 18px; margin: 0 0 10px; font-weight: 700; }
h3 { font-size: 15px; margin: 0 0 6px; font-weight: 600; }
p { margin: 0 0 12px; }
a { color: var(--akzent-dunkel); }

/* --------------------------------------------------------------- Grundgeruest */

#kopf {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 4px;
  /* Hoehe und oberer Rand stehen oben bei der Statusleiste; hier nur die
     Seiten, sonst faellt das Einruecken wieder heraus. */
  padding-left: 8px; padding-right: 8px;
  /* Durchscheinend statt deckend: Der Kopf klebt oben und der Inhalt laeuft
     darunter durch. Als undurchsichtiger Streifen schneidet er die Seite in
     zwei Teile; als Material sieht man, dass darunter etwas weiterlaeuft,
     und weiss, dass man noch mittendrin ist. */
  background: color-mix(in srgb, var(--karte) 82%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
}

/* Die Kante erscheint erst, wenn wirklich Inhalt darunter liegt.
   Eine 1px-Linie, die immer da ist, behauptet eine Trennung auch oben am
   Anfang der Seite, wo nichts zu trennen ist. Und sie ist hart: ein
   weicher Verlauf zeigt, dass der Inhalt verschwindet, statt dass dort
   etwas endet. gescrollt setzt app.js. */
#kopf::after {
  content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 14px;
  pointer-events: none; opacity: 0;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--tinte) 12%, transparent), transparent);
  transition: opacity 200ms ease;
}
body.gescrollt #kopf::after { opacity: 1; }

/* Wer weniger Transparenz will, bekommt Material statt Glas: deckend, ohne
   Unschaerfe. Eine milchige Flaeche ohne Unschaerfe waere das Schlechteste
   von beidem. */
@media (prefers-reduced-transparency: reduce) {
  #kopf {
    background: var(--karte);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
}

/* Wer mehr Kontrast will, bekommt die klare Kante zurueck. Ein Verlauf als
   einzige Abgrenzung verschwindet genau fuer die, die ihn am noetigsten
   braeuchten. */
@media (prefers-contrast: more) {
  #kopf {
    background: var(--karte);
    backdrop-filter: none; -webkit-backdrop-filter: none;
    border-bottom: 2px solid var(--tinte);
  }
  #kopf::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  #kopf::after { transition: none; }
}
/* Der Zurueckpfeil ist der meistbenutzte Knopf der App und sass bei 26 Pixeln
   als duenner Winkel im Kopf. Jetzt 34 und eine groessere Flaeche darunter:
   Auf der Baustelle wird mit Handschuhen getippt, und das Zeichen selbst ist
   schmal -- ein "‹" hat kaum Flaeche, es braucht Groesse, um als Pfeil
   gelesen zu werden. */
#kopf .zurueck {
  width: 48px; height: 48px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: none; background: none; color: var(--tinte);
  font-size: 34px; line-height: 1; cursor: pointer; border-radius: 10px;
  /* Der Winkel steht optisch zu tief, weil unter ihm die Unterlaenge fehlt. */
  padding-bottom: 3px;
}
#kopf .zurueck:active { background: var(--band); }
/* Die Marke ist ein Weg zur Uebersicht, kein Schmuck. Sie soll aber auch
   nicht wie ein Verweis aussehen. */
#kopf a.titel { text-decoration: none; color: inherit; }
#kopf .titel {
  font-weight: 700; font-size: 17px; flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#kopf .kopf-aktion {
  min-width: 44px; height: 44px; padding: 0 12px; flex: none;
  border: none; background: none; color: var(--akzent-dunkel);
  font: inherit; font-weight: 600; cursor: pointer; border-radius: 8px;
}

#inhalt {
  /* Als Flex-Element neben der Seitenleiste: Ohne flex-grow bliebe es auf
     Inhaltsbreite stehen, statt den Platz daneben zu nehmen. min-width: 0
     erlaubt es, schmaler als sein Inhalt zu werden; sonst sprengen breite
     Tabellen das Raster. */
  flex: 1 1 auto; min-width: 0;
  padding: 16px;
  padding-bottom: calc(32px + env(safe-area-inset-bottom));
  /* Frueher 720 Pixel, die Lesebreite eines Fliesstextes. Das war fuer eine
     App die falsche Vorgabe: Es ist der Deckel, unter dem keine zweite Spalte
     entstehen kann, egal wie breit der Bildschirm ist. Kacheln, Listen und
     Tabellen wollen die Breite; der Fliesstext bekommt sie unten einzeln
     wieder abgenommen. */
  max-width: 1440px; margin: 0 auto;
}

/* Lange Saetze bleiben lesbar: Ueber etwa siebzig Zeichen je Zeile verliert
   das Auge beim Ruecksprung die naechste Zeile. Das betrifft nur den
   Fliesstext, nicht die Zahlen daneben. */
.wizard-text, .seitenkopf .unterzeile, .leer p { max-width: 68ch; }

.seitenkopf { margin-bottom: 16px; }
.unterzeile { color: var(--tinte-leise); font-size: 14px; margin: 0; }

.karte {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: 12px; padding: 16px; margin-bottom: 14px;
}

/* ------------------------------------------------------------------ Startseite */

.kachelgitter { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 340px) { .kachelgitter { grid-template-columns: 1fr; } }

.kachel {
  display: flex; flex-direction: column; gap: 4px;
  min-height: 104px; padding: 14px;
  background: var(--karte); border: 1px solid var(--linie); border-radius: 12px;
  text-align: left; text-decoration: none; color: var(--tinte);
  font: inherit; cursor: pointer;
}
.kachel:active { background: var(--band); }
.kachel .kachel-zeichen { font-size: 22px; line-height: 1; }
.kachel .kachel-titel { font-weight: 700; font-size: 15px; }
.kachel .kachel-text { font-size: 12.5px; color: var(--tinte-leise); line-height: 1.35; }

/* ------------------------------------------------------------------ Formulare */

.feld { display: block; margin-bottom: 14px; }
.feld-name { display: block; font-size: 13px; font-weight: 600; color: var(--tinte-leise); margin-bottom: 5px; }
.feld-hinweis { display: block; font-size: 12px; color: var(--tinte-leise); margin-top: 4px; }

/* Umgekehrt aufgezaehlt: Nicht die erlaubten Arten nennen, sondern die
   Ausnahmen. Sonst faellt bei jeder neuen Feldart eine durch -- so sah das
   Passwortfeld lange schmaler aus als die E-Mail daneben. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="color"]),
select, textarea {
  width: 100%; font: inherit; font-size: 16px;
  min-height: 48px; padding: 11px 12px;
  border: 1px solid var(--linie); border-radius: 8px;
  background: var(--karte); color: var(--tinte);
}
/* Drei Zeilen statt fuenf. Ein Mangel wird in einem Satz beschrieben --
   "Riss neben der Terrassentuer, etwa 40 cm" --, und ein Kasten, der auf
   einen Aufsatz wartet, draengt das Formular auf dem Telefon nach unten.
   Wer mehr schreibt, zieht ihn auf: resize bleibt. */
textarea { min-height: 62px; resize: vertical; line-height: 1.45; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--akzent); outline-offset: -1px; }

input[type="range"] { width: 100%; height: 44px; accent-color: var(--akzent); }
input[type="checkbox"] { width: 22px; height: 22px; min-height: 0; accent-color: var(--akzent); }

.knopf, .knopf-haupt, .knopf-leise, .knopf-warn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 48px; padding: 12px 18px; width: 100%;
  font: inherit; font-weight: 700; font-size: 15px;
  border-radius: 8px; border: 1px solid var(--linie);
  background: var(--karte); color: var(--tinte); cursor: pointer;
}
.knopf-haupt { background: var(--akzent); border-color: var(--akzent); color: var(--auf-akzent); }
.knopf-haupt:active { background: var(--akzent-dunkel); border-color: var(--akzent-dunkel); }
.knopf-leise { background: none; border-color: transparent; color: var(--akzent-dunkel); font-weight: 600; }
.knopf-warn { color: var(--warn); border-color: var(--linie); }
.knopf:active, .knopf-warn:active { background: var(--band); }

/* Nachgeben beim Druecken, nicht erst beim Loslassen. Zwei Zeiten mit
   Absicht: 90 ms hinein, 180 ms zurueck. Die Antwort auf den Finger muss
   sofort da sein; das Zurueckfedern ist keine Antwort mehr und darf
   Zeit lassen. Dieselben Werte wie auf bauzeuge.de. */
@media (prefers-reduced-motion: no-preference) {
  .knopf, .knopf-haupt, .knopf-leise, .knopf-warn, .kachel, .zustandstaste {
    transition: background-color 150ms ease, transform 180ms cubic-bezier(.23, 1, .32, 1);
  }
  .knopf:active, .knopf-haupt:active, .knopf-leise:active, .knopf-warn:active,
  .kachel:active, .zustandstaste:active {
    transform: scale(.97);
    transition: transform 90ms ease-out;
  }
}

/* Einzeln untereinander stehende Knoepfe brauchen Luft; in einer Reihe
   uebernimmt das gap den Abstand, dort stoert der Rand. */
.knopf, .knopf-haupt, .knopf-leise, .knopf-warn { margin-bottom: 10px; }
/* Zwei oder drei Knoepfe nebeneinander, solange sie nebeneinander passen.
   Sonst untereinander.

   Vorher stand hier "flex: 1" ohne Umbruch. Flex-Kinder haben von sich aus
   "min-width: auto" und schrumpfen deshalb nie unter ihre Textbreite -- drei
   Knoepfe mit je 126 Pixeln standen in einer 254 Pixel breiten Karte und
   schoben die Seite nach rechts. Aufgefallen erst mit gefuellten Daten bei
   320 Pixeln, also dort, wo niemand hinschaut.

   "flex: 1 1 140px": Jeder Knopf will 140 Pixel; reicht es nicht fuer zwei,
   bricht die Reihe um. min-width: 0 erlaubt zusaetzlich, dass ein langer
   Text den Knopf nicht aufblaeht. */
.knopf-reihe { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.knopf-reihe > * { flex: 1 1 140px; min-width: 0; margin-bottom: 0; }
.karte > .knopf:last-child, .karte > .knopf-haupt:last-child,
.karte > .knopf-leise:last-child, .karte > .knopf-warn:last-child { margin-bottom: 0; }
.knopf-schmal { width: auto; }
/* Nebensaechliche Knoepfe unter der Ueberschrift: Sie sollen nicht die
   ganze Breite nehmen, sonst lesen sie sich wie Abschnitte. */
.kopfaktionen { justify-content: flex-start; margin: -4px 0 16px; }
.kopfaktionen > * { flex: 0 0 auto; width: auto; }

/* -------------------------------------------------------------------- Listen */

.liste { list-style: none; margin: 0; padding: 0; }
.listenzeile {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--linie);
  text-align: left; width: 100%; background: none;
  border-left: 0; border-right: 0; border-top: 0;
  font: inherit; color: var(--tinte); cursor: pointer; min-height: 56px;
}
.listenzeile:last-child { border-bottom: none; }

/* Baunebenkosten: Bezeichnung, Betrag, Umbenennen und Entfernen. Auf dem
   Telefon rutschen Betrag und Knoepfe unter den Namen, statt ihn auf drei
   Zeichen zusammenzuquetschen. */
.nebenzeile {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 12px 0; border-bottom: 1px solid var(--linie);
}
.nebenliste > .nebenzeile:last-child { border-bottom: none; }
.nebenzeile .zeilen-text { flex: 1 1 200px; min-width: 0; }
/* Betrag und Knoepfe bilden eine Einheit und rutschen gemeinsam in die
   zweite Zeile, wenn der Name den Platz braucht. */
.nebenwerte {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  flex: 1 1 auto; justify-content: flex-end;
}
.nebenwerte > input { flex: 0 0 96px; width: 96px; text-align: right; }
.nebenknoepfe { display: flex; gap: 6px; flex: 0 0 auto; }
/* Enger als ein gewoehnlicher Knopf: Zwei davon neben einem Betragsfeld
   passen sonst auf keinem Telefon in eine Zeile. Die Hoehe bleibt, damit
   sie mit dem Finger zu treffen sind. */
.nebenknoepfe .knopf { width: auto; padding: 10px 11px; font-size: 14px; }
.listenzeile .zeilen-text { flex: 1; min-width: 0; }
.zeilen-titel { font-weight: 600; display: block; }
.zeilen-unter { font-size: 13px; color: var(--tinte-leise); display: block; }
.listenzeile .zeilen-wert { font-weight: 700; white-space: nowrap; }
.listenzeile .vorschau {
  width: 48px; height: 48px; flex: none; border-radius: 8px;
  object-fit: cover; background: var(--band);
}

.wertzeile {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--linie); font-size: 15px;
}
.wertzeile:last-child { border-bottom: none; }
.wertzeile.stark { font-size: 17px; padding-top: 12px; }
.wertzeile.stark strong { color: var(--akzent-dunkel); }

/* -------------------------------------------------------------------- Kaesten */

.kasten { border-radius: 8px; padding: 12px 14px; font-size: 14px; margin: 0 0 14px; }
.kasten-info { background: var(--band); }
.kasten-warn { background: var(--warn-flaeche); color: var(--warn-schrift); }
.kasten-gut { background: var(--gut-flaeche); color: var(--gut-schrift); }

.leer { text-align: center; padding: 28px 12px; color: var(--tinte-leise); }
.leer h2 { color: var(--tinte); }

.marke {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 700; background: var(--band); color: var(--tinte-leise);
}
.marke-offen { background: var(--offen-flaeche); color: var(--offen-schrift); }
.marke-geplant { background: var(--band); color: var(--tinte-leise); }
.marke-beauftragt { background: var(--info-flaeche); color: var(--info-schrift); }

/* Abweichungen: ueber dem Geplanten rot, darunter gruen. Das ist die
   Information, um die es in einer Kostenaufstellung ueberhaupt geht. */
.leise { color: var(--tinte-leise); }
.mehr { color: var(--warn); font-weight: 700; }
.weniger { color: var(--gut); font-weight: 700; }
.marke-arbeit { background: var(--arbeit-flaeche); color: var(--arbeit-schrift); }
.marke-fertig { background: var(--gut-flaeche); color: var(--gut-schrift); }

/* -------------------------------------------------------------------- Tabelle */

.tabellenrahmen { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { border-collapse: collapse; width: 100%; font-size: 14px; }
th, td { padding: 8px 10px; text-align: right; border-bottom: 1px solid var(--linie); white-space: nowrap; }
th:first-child, td:first-child { text-align: left; }
th { font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tinte-leise); }
tr.bindung td { background: var(--band); font-weight: 700; }

/* ---------------------------------------------------------------- Anschlussplan */

.planflaeche {
  position: relative; width: 100%; overflow: hidden;
  border: 1px solid var(--linie); border-radius: 10px; background: var(--band);
  touch-action: none;
}
.planflaeche img { display: block; width: 100%; user-select: none; -webkit-user-drag: none; }
.pin {
  position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px;
  border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  border: 2px solid var(--karte); box-shadow: 0 1px 4px rgba(0,0,0,.4);
  display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
}
.pin span { transform: rotate(45deg); font-size: 14px; line-height: 1; }
.pin.gewaehlt { outline: 3px solid var(--akzent); outline-offset: 2px; }

/* Raumnamen liegen flach auf dem Plan und verdecken ihn so wenig wie
   moeglich: Der Grundriss ist die Auskunft, die Marke nur die Beschriftung.
   Deshalb halbdurchsichtig und ohne Nadel. */
.raummarke {
  position: absolute; transform: translate(-50%, -50%);
  max-width: 46%; padding: 4px 9px; border-radius: 999px;
  /* Erst die einfache Farbe, dann die gemischte: color-mix kennt erst
     Chrome 111. Aeltere WebViews ueberspringen die zweite Zeile und behalten
     die erste -- ohne Rueckfall stuende hier gar keine Farbe. */
  background: var(--karte);
  background: color-mix(in srgb, var(--karte) 88%, transparent);
  border: 1.5px solid var(--akzent); color: var(--akzent-dunkel);
  font: inherit; font-size: 12.5px; font-weight: 700; line-height: 1.2;
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.raummarke:hover { background: var(--akzent); color: var(--auf-akzent); }
/* Waehrend gesetzt wird, sagt der Zeiger, dass der Plan jetzt zuhoert. */
.planflaeche.setzt { cursor: crosshair; }
.planflaeche.setzt img { opacity: .85; }

.geschossleiste { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 12px; }
.geschossleiste button {
  flex: none; min-height: 40px; padding: 8px 14px;
  font: inherit; font-weight: 600; font-size: 14px;
  border: 1px solid var(--linie); border-radius: 999px;
  background: var(--karte); color: var(--tinte); cursor: pointer;
}
.geschossleiste button.aktiv { background: var(--akzent); border-color: var(--akzent); color: var(--auf-akzent); }

/* ---------------------------------------------------------------------- Fotos */

.fotoreihe { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.fotoreihe figure { position: relative; margin: 0; }
.fotoreihe img { width: 84px; height: 84px; object-fit: cover; border-radius: 8px; border: 1px solid var(--linie); }
/* Ein Eintrag der Baudokumentation: Zeile plus Bilderstreifen. */
.doku-eintrag { padding: 8px 0; border-top: 1px solid var(--linie); }
.doku-eintrag:first-of-type { border-top: 0; }
.doku-eintrag .fotoreihe { margin: 6px 0 0; }
.doku-eintrag .fotoreihe img {
  width: 84px; height: 84px; object-fit: cover; border-radius: 8px;
  border: 1px solid var(--linie);
}

/* Helferzeile im Tageseintrag: Name, Stunden, Unterschrift. */
.helferzeile { display: flex; gap: 8px; align-items: center; min-height: 48px; }
.helferzeile .helfername {
  flex: 1; min-width: 0; display: flex; gap: 10px; align-items: center;
}
.helferzeile .helfername span { overflow-wrap: anywhere; }
.helferzeile .knopf-schmal { flex: none; }

/* Unterschriftenfeld: weisses Blatt mit Linie, so breit wie das Blatt. */
.unterschriftsfeld {
  width: 100%; height: auto; aspect-ratio: 3 / 1; touch-action: none;
  background: #fff; border: 1px solid var(--linie); border-radius: 8px;
  margin-bottom: 6px; cursor: crosshair;
}

.dateikachel {
  width: 84px; height: 84px; border-radius: 8px; border: 1px solid var(--linie);
  background: var(--band); display: flex; flex-direction: column; gap: 4px;
  align-items: center; justify-content: center; padding: 6px;
  text-decoration: none; color: var(--tinte); overflow: hidden;
}
.dateizeichen { font-weight: 700; font-size: 13px; color: var(--akzent-dunkel); }
.dateiname {
  font-size: 10.5px; line-height: 1.2; text-align: center; color: var(--tinte-leise);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
}

.fotoreihe .weg {
  position: absolute; top: -6px; right: -6px; width: 26px; height: 26px;
  border-radius: 50%; border: 1px solid var(--linie); background: var(--karte);
  font-size: 15px; line-height: 1; cursor: pointer; padding: 0;
}
.grossbild { width: 100%; border-radius: 10px; border: 1px solid var(--linie); display: block; margin-bottom: 12px; }

/* Der Dateiwaehler haengt an einem Knopf, das Feld selbst bleibt unsichtbar. */
.versteckt { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* ------------------------------------------------------------------- Diagramm */

.balkenblock { display: flex; align-items: flex-end; gap: 2px; height: 120px; margin: 12px 0 6px; }
.balkenblock .saeule { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; }
.balkenblock .anteil-zins { background: var(--akzent); }
.balkenblock .anteil-tilg { background: var(--akzent-dunkel); }
.legende { display: flex; gap: 16px; font-size: 12.5px; color: var(--tinte-leise); }
.legende i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; }

.fortschrittsbalken { height: 10px; border-radius: 5px; background: var(--band); overflow: hidden; margin: 8px 0; }
.fortschrittsbalken div { height: 100%; background: var(--akzent); }

/* Betrag, Balken, Erlaeuterung: der Baustein aller Statistiken. */
.balkenzeile { margin-bottom: 14px; }
.balkenzeile .fortschrittsbalken { margin: 6px 0 4px; }
.balkenzeile .unterzeile { margin: 0; }

/* Die Kostenaufstellung hat acht Spalten. Auf dem Telefon passt das nicht,
   also rollt die Tabelle in sich statt die ganze Seite breit zu machen. */
.tabelle-rolle { overflow-x: auto; margin: 0 -14px; padding: 0 14px; }
.sortknopf {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  text-transform: inherit; letter-spacing: inherit; cursor: pointer;
}
.sortknopf:hover { color: var(--akzent); }
tbody tr:hover td { background: var(--band); }
/* Die Bauweise ist eine Entscheidung, keine Auswahl aus einer Liste. Also
   ganze Felder mit Erklaerung statt Reiter, die nur ein Wort tragen. */
.bauweisewahl { display: grid; gap: 8px; margin-bottom: 12px; }
@media (min-width: 760px) {
  .bauweisewahl { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
}
button.bauweise {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 11px 13px; border-radius: 10px;
  border: 1px solid var(--linie); background: var(--karte); color: var(--tinte);
  font: inherit;
}
button.bauweise:hover { border-color: var(--akzent-hell); }
button.bauweise.aktiv {
  border-color: var(--akzent); background: var(--akzent); color: var(--auf-akzent);
}
.bauweise-name { display: block; font-weight: 700; font-size: 15px; }
.bauweise-klammer {
  display: block; font-size: 12.5px; line-height: 1.35; margin-top: 2px;
  color: var(--tinte-leise);
}
button.bauweise.aktiv .bauweise-klammer { color: var(--auf-akzent); opacity: .85; }

/* Eigenleistungen: viele kurze Haken, in Spalten statt in einer langen
   Schlange. */
.gewerkewahl {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 2px 12px; margin: 8px 0 12px;
}
.gewerkewahl label {
  display: flex; align-items: center; gap: 9px; min-height: 40px; cursor: pointer;
}
h3.unterabschnitt { font-size: 15px; margin: 16px 0 4px; }

.filterleiste { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }

/* Die Leistungsliste steht in der Angebotskarte und teilt sich das
   Aufklappen mit den Phasen des Leitfadens. */
.leistungsblock { margin-top: 12px; border-top: 1px solid var(--linie); padding-top: 12px; }
.leistungsblock td, .leistungsblock th { text-align: center; }
.leistungsblock td:first-child, .leistungsblock th:first-child {
  text-align: left; white-space: normal; min-width: 150px;
}
.leistungsblock .filterleiste { margin: 12px 0 0; }
.filterleiste input, .filterleiste select { flex: 1 1 160px; }
/* Zins und Tilgung im Kreditvergleich: schmales Feld mit Aufschrift davor.

   Es darf schrumpfen. Mit "flex: 0 0 auto" und einem Eingabefeld von festen
   74 Pixeln standen die beiden Felder auf einem 320 Punkte breiten Telefon
   fuenf Punkte ueber dem Rand -- die Zeile bricht zwar um, aber ein Feld,
   das nicht schmaler werden darf, bricht nicht in sich zusammen. "min-width:
   0" muss dazu: Ein Flex-Kind ist sonst mindestens so breit wie sein Inhalt
   und schrumpft trotz Schrumpffaktor nicht. */
.satzfeld { display: flex; align-items: center; gap: 6px; flex: 1 1 130px; min-width: 0; }
.satzfeld span { font-size: 12px; color: var(--tinte-leise); white-space: nowrap; }
.satzfeld input { flex: 1 1 auto; width: auto; min-width: 0; max-width: 94px; text-align: right; }
.filterleiste button { flex: 0 0 auto; width: auto; margin: 0; }

/* ------------------------------------------------------------------- Meldungen */

.meldung {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
  background: var(--tinte); color: var(--karte); padding: 11px 18px; border-radius: 999px;
  font-size: 14px; z-index: 60; max-width: 90vw; text-align: center;
  transition: opacity 350ms ease;
}
.meldung.weg { opacity: 0; }

/* --------------------------------------------------------------------- Dialog */

/* Der Schleier folgt dem Blatt: --blatt-anteil ist 1, wenn das Blatt ganz
   offen ist, und 0, wenn es unten angekommen ist. Gesetzt wird er Bild fuer
   Bild von blattziehen.js. So sieht man schon waehrend des Ziehens, dass
   man gerade schliesst, statt es erst am Ende zu erfahren. */
.ueberlagerung {
  position: fixed; inset: 0; z-index: 50;
  background: var(--schleier);
  opacity: var(--blatt-anteil, 1);
  display: flex; align-items: flex-end; justify-content: center;
}
.blatt {
  background: var(--papier); width: 100%; max-width: 720px;
  max-height: 92vh; overflow-y: auto;
  border-radius: 16px 16px 0 0;
  padding: 8px 16px calc(20px + env(safe-area-inset-bottom));
  will-change: transform;
}

/* Der Griff. Er sagt, dass sich das Blatt ziehen laesst, und er ist die
   Flaeche, an der gezogen wird -- am Rumpf ginge es nicht, der scrollt.
   touch-action: none, weil der Browser die senkrechte Geste sonst als
   Scrollen fuer sich behaelt und pointermove nicht mehr kommt.
   Die Flaeche ist hoeher als der sichtbare Strich: 44 px sind das Mass,
   unter dem ein Ziel mit dem Daumen schwer zu treffen ist. */
.blatt-griff {
  display: block; width: 100%; height: 28px; margin: 0 0 4px;
  touch-action: none; cursor: grab; position: relative;
}
.blatt-griff:active { cursor: grabbing; }
.blatt-griff::before {
  content: ''; position: absolute; left: 50%; top: 10px;
  width: 40px; height: 4px; margin-left: -20px;
  border-radius: 2px; background: var(--linie);
}
.blatt h2 { margin-top: 0; }
.blatt h2 { margin-bottom: 14px; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------------------------------------------------------------- Balkenplan */

/* Ein Bauplan laeuft ueber Monate. Statt alles auf Bildschirmbreite zu
   quetschen, wo ein Viertagesbalken zum Strich wird, ist die Achse breit und
   die Flaeche wird seitlich geschoben. */
.balken-flaeche { overflow-x: auto; overflow-y: hidden; margin: 4px -4px 10px; padding: 0 4px; }
.balken-innen { position: relative; }

.balken-kopf { height: 20px; }
.balken-monate { position: relative; height: 20px; }
.balken-monat {
  position: absolute; top: 0; font-size: 11.5px; font-weight: 600;
  color: var(--tinte-leise); white-space: nowrap; overflow: hidden;
  padding-left: 3px; border-left: 1px solid var(--linie);
}

/* Liegt hinter den Zeilen, damit Monatsstriche und Heute-Linie durchlaufen. */
.balken-raster { position: absolute; top: 20px; bottom: 0; pointer-events: none; }
.balken-strich { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--linie); }
.balken-heute { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--warn); opacity: .55; }

.balken-zeilen { position: relative; }
.balken-zeile {
  display: flex; align-items: center; width: 100%; min-height: 40px;
  padding: 4px 0; border: 0; background: none; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
.balken-zeile + .balken-zeile { border-top: 1px solid var(--band); }
.balken-titel {
  flex: none; width: 132px; padding-right: 10px; overflow: hidden;
  display: flex; flex-direction: column; line-height: 1.25;
}
.balken-titel strong { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.balken-titel .zeilen-unter { font-size: 11.5px; }

.balken-bahn { position: relative; flex: none; height: 20px; }
.balken { position: absolute; top: 4px; height: 12px; border-radius: 3px; }
.balken-offen  { background: var(--offen); }
.balken-laeuft { background: var(--arbeit); }
.balken-fertig { background: var(--gut); }

.legende i.balken-offen  { background: var(--offen); }
.legende i.balken-laeuft { background: var(--arbeit); }
.legende i.balken-fertig { background: var(--gut); }

/* ------------------------------------------------------------ Dunkles Design

   Drei Zustaende. Von Haus aus folgt die App der Geraeteeinstellung; wer
   umschaltet, setzt data-thema auf dem <html>-Element, und das gilt dann.

   Die Reihenfolge ist Bedingung: Die Medienabfrage darf nicht greifen, wenn
   jemand von Hand auf hell gestellt hat, deshalb das :not(). Die feste Wahl
   "dunkel" steht danach und schlaegt beides.

   Der Akzent wird im Dunkeln das helle Petrol. Das dunkle Petrol der Marke
   waere auf schwarzem Grund kaum vom Hintergrund zu unterscheiden. Aus
   demselben Grund steht auf einer Akzentflaeche dort dunkle Schrift. */

html[data-thema="dunkel"],
html:not([data-thema="hell"]) {
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  html:not([data-thema="hell"]) {
    color-scheme: dark;
    --papier: #10171a;
    --karte: #182226;
    --tinte: #e6ecec;
    --tinte-leise: #9bacae;
    --akzent: #5fbabd;
    --akzent-dunkel: #8ed6d8;
    --akzent-hell: #5fbabd;
    --linie: #2a383c;
    --band: #1f2c30;
    --gut: #5fc98a;
    --warn: #ff8b80;
    --arbeit: #b9a4e6;
    --offen: #7d8a95;
    --w-klar-flaeche: #16323a;   --w-klar-schrift: #7fd3d6;
    --w-grau-flaeche: #232c31;   --w-grau-schrift: #aab6bd;
    --w-nass-flaeche: #1b2740;   --w-nass-schrift: #9dc0f5;
    --w-kalt-flaeche: #1d2b39;   --w-kalt-schrift: #96bde3;

    --warn-flaeche: #3a1f1d;  --warn-schrift: #ffb3aa;
    --gut-flaeche: #17301f;   --gut-schrift: #86ddaa;
    --info-flaeche: #1b2740;  --info-schrift: #9dc0f5;
    --arbeit-flaeche: #251f38; --arbeit-schrift: #cdbcf2;
    --offen-flaeche: #3a1f1d; --offen-schrift: #ffb3aa;
    --auf-akzent: #0c1416;
    --schleier: rgba(0, 0, 0, .62);
  }
}

html[data-thema="dunkel"] {
  color-scheme: dark;
  --papier: #10171a;
  --karte: #182226;
  --tinte: #e6ecec;
  --tinte-leise: #9bacae;
  --akzent: #5fbabd;
  --akzent-dunkel: #8ed6d8;
  --akzent-hell: #5fbabd;
  --linie: #2a383c;
  --band: #1f2c30;
  --gut: #5fc98a;
  --warn: #ff8b80;
  --arbeit: #b9a4e6;
  --offen: #7d8a95;
  --w-klar-flaeche: #16323a;   --w-klar-schrift: #7fd3d6;
  --w-grau-flaeche: #232c31;   --w-grau-schrift: #aab6bd;
  --w-nass-flaeche: #1b2740;   --w-nass-schrift: #9dc0f5;
  --w-kalt-flaeche: #1d2b39;   --w-kalt-schrift: #96bde3;

  --warn-flaeche: #3a1f1d;  --warn-schrift: #ffb3aa;
  --gut-flaeche: #17301f;   --gut-schrift: #86ddaa;
  --info-flaeche: #1b2740;  --info-schrift: #9dc0f5;
  --arbeit-flaeche: #251f38; --arbeit-schrift: #cdbcf2;
  --offen-flaeche: #3a1f1d; --offen-schrift: #ffb3aa;
  --auf-akzent: #0c1416;
  --schleier: rgba(0, 0, 0, .62);
}

/* ----------------------------------------------------------- Themenschalter

   Aufbau und Masse wie der Schalter auf karten.360welt.de: eine Pille mit
   einer weissen Kugel, die von links nach rechts wandert und Sonne oder Mond
   traegt. Die Spur ist im Dunkeln anthrazit, im Hellen gruen. */

/* Drei Stellungen nebeneinander: Geraet, hell, dunkel. Die gewaehlte
   bekommt eine eigene Flaeche, die beiden anderen bleiben ruhig -- so
   steht da, was gilt, und daneben, was es sonst gibt. */
.thema-schalter {
  flex: none; display: inline-flex; align-items: center; gap: 2px;
  margin: 0 2px; padding: 2px;
  border-radius: 999px; background: var(--band);
  border: 1px solid var(--linie);
}
.thema-taste {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 26px; padding: 0;
  border: none; border-radius: 999px; cursor: pointer;
  background: none; color: var(--tinte-leise);
  transition: background 0.15s, color 0.15s;
}
.thema-taste:hover { color: var(--tinte); }
.thema-taste.aktiv {
  background: var(--karte); color: var(--akzent-dunkel);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
/* Dieselbe Pille mit Beschriftung statt Zeichen -- fuer Wahlmoeglichkeiten,
   die sich nicht in ein Sinnbild fassen lassen ("30 Tage"). Ein zweiter
   Schaltertyp daneben saehe aus wie ein zweites Bedienkonzept. */
.thema-schalter.mit-text .thema-taste {
  width: auto; padding: 0 13px; font: inherit; font-size: 13px; font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .thema-taste { transition: none; }
}

/* ------------------------------------------------------------ Anmeldung

   Eine Sache auf dem Bildschirm, in der Mitte, mit Luft ringsum. Wer sich
   anmeldet, will nichts anderes -- alles Erklaerende steht darunter und
   nicht daneben. */
.anmeldung { display: flex; justify-content: center; }
.anmeldekarte { width: 100%; max-width: 430px; padding: 26px 24px 22px; }
.anmeldung-titel { margin: 0 0 6px; font-size: 30px; line-height: 1.12; letter-spacing: -.018em; }
.anmeldung-unter {
  margin: 0 0 20px; font-size: 15px; line-height: 1.5; color: var(--tinte-leise);
}
.anmeldekarte .knopf-gross { margin-top: 6px; }
.anmeldung-meldung {
  margin: 8px 0 0; font-size: 14px; line-height: 1.45; color: var(--warn);
  min-height: 1.2em;
}
/* "oder": eine Linie mit einem Wort darin. Zwei Wege, kein Nebeneinander --
   der zweite steht unter dem ersten und nicht daneben. */
.anmeldung-oder {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0 12px; font-size: 13px; color: var(--tinte-leise);
}
.anmeldung-oder::before, .anmeldung-oder::after {
  content: ''; flex: 1; height: 1px; background: var(--linie);
}

/* Sechs Ziffern, gross und weit: Man tippt sie von einem zweiten Bildschirm
   ab und will beim Blick zurueck sofort sehen, wo man war. */
.codefeld {
  font-size: 24px; font-weight: 700; letter-spacing: 0.35em;
  text-align: center; font-variant-numeric: tabular-nums;
}

.anmeldung-fuss {
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--linie);
  font-size: 14px; text-align: center; color: var(--tinte-leise);
}

/* Das Auge sitzt im Feld, nicht daneben: Sonst waere das Passwortfeld
   schmaler als das darueber, und genau das faellt auf. */
.passwortfeld { display: block; position: relative; }
.passwortfeld > input { width: 100%; padding-right: 46px; }
.augenknopf {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; margin: 0;
  border: none; border-radius: 8px; background: none;
  color: var(--tinte-leise); cursor: pointer;
}
.augenknopf:hover { color: var(--tinte); background: var(--band); }

/* Ein Verweis, der wie ein Verweis aussieht und trotzdem ein Knopf ist. */
.textknopf {
  border: none; background: none; padding: 0; margin: 0;
  font: inherit; font-weight: 700; color: var(--akzent-dunkel);
  cursor: pointer; text-decoration: underline;
}
.textknopf:hover { color: var(--akzent); }

/* ------------------------------------------------------------- Wortmarke

   Wie im Kopf der Website: Hauszeichen, "Bau" in Tinte, "Zeuge" im Akzent.
   Sie steht nur auf der Startseite; in einem Bereich zeigt der Kopf dessen
   Namen. */
.wortmarke { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.wortmarke svg { width: 28px; height: 28px; flex: none; border-radius: 6px; }
.wm-text {
  font-weight: 900; font-size: 20px; letter-spacing: -0.2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wm-akzent { font-weight: 500; color: var(--akzent-dunkel); }
.wm-de { font-size: 12px; font-weight: 500; letter-spacing: 0; color: var(--tinte-leise); }
/* Schmale Telefone mit Zurueckpfeil: Menue, Pfeil, Marke und Themaschalter
   passen bei 320 Punkten nicht nebeneinander, die Marke wurde abgeschnitten.
   Der Pfeil fuehrt ohnehin zurueck, dort darf das Hauszeichen weichen, und
   Schalter und Schrift ruecken eine Stufe kleiner. */
@media (max-width: 380px) {
  .wm-text { font-size: 18px; }
  .thema-taste { width: 24px; }
}
@media (max-width: 359px) {
  #kopf:has(.zurueck:not([hidden])) .wortmarke svg { display: none; }
}

/* ---------------------------------------------------------- Seitenleiste

   Auf dem Rechner steht sie fest links, auf dem Telefon faehrt sie als
   Schublade herein. Der Inhalt bekommt deshalb keinen festen Rand, sondern
   die Leiste ist Teil eines Rasters; sonst muesste jede Breite einzeln
   nachgerechnet werden. */

#rumpf { display: flex; align-items: flex-start; }

/* Fusszeile: Kontakt und Rechtliches, wie auf der Website.
   Leise gehalten -- sie ist eine Pflichtangabe und kein Angebot, und auf
   einem Telefon darf sie den Daumen nicht vom Inhalt wegziehen. */
#fusszeile {
  border-top: 1px solid var(--linie); background: var(--karte);
  padding: 18px 16px calc(18px + env(safe-area-inset-bottom));
  font-size: 13.5px; color: var(--tinte-leise);
}
.fuss-marke { margin: 0 0 8px; }
.fuss-wege { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.fuss-wege a { color: var(--tinte-leise); text-decoration: underline; min-height: 32px; display: inline-flex; align-items: center; }
.fuss-wege a:hover { color: var(--akzent); }

#seitenleiste {
  flex: none; width: 236px; align-self: stretch;
  position: sticky; top: var(--kopf-gesamt);
  max-height: calc(100vh - var(--kopf-gesamt));
  overflow-y: auto; overscroll-behavior: contain;
  padding: 10px 8px calc(24px + env(safe-area-inset-bottom));
  background: var(--karte); border-right: 1px solid var(--linie);
}

/* Die Projektwahl steht ueber allem anderen in der Leiste. */

.leiste-gruppe { margin-bottom: 2px; }
.leiste-gruppe > summary {
  display: flex; align-items: center; gap: 9px;
  min-height: 44px; padding: 6px 10px; border-radius: 8px;
  font-weight: 700; font-size: 14.5px; cursor: pointer;
  list-style: none; user-select: none;
}
.leiste-gruppe > summary::-webkit-details-marker { display: none; }
.leiste-gruppe > summary::after {
  content: '\203A'; margin-left: auto; font-size: 18px; color: var(--tinte-leise);
  transform: rotate(90deg); transition: transform 0.2s;
}
.leiste-gruppe[open] > summary::after { transform: rotate(-90deg); }
.leiste-gruppe > summary:hover { background: var(--band); }

.leiste-zeichen { font-size: 16px; line-height: 1; }

.leiste-punkt {
  display: flex; align-items: center; gap: 9px;
  min-height: 42px; padding: 6px 10px 6px 34px; margin-bottom: 1px;
  border-radius: 8px; font-size: 14.5px; color: var(--tinte);
  text-decoration: none;
}
.leiste-allein { padding-left: 10px; font-weight: 700; }
.leiste-punkt:hover { background: var(--band); }
.leiste-punkt.aktiv { background: var(--akzent); color: var(--auf-akzent); font-weight: 700; }
.leiste-punkt.aktiv .leiste-zeichen { filter: grayscale(1) brightness(3); }

/* Der Hamburger gehoert dem Telefon; auf dem Rechner steht die Leiste ohnehin. */
#kopf .menue-knopf {
  display: none; width: 44px; height: 44px; flex: none;
  flex-direction: column; justify-content: center; align-items: center; gap: 5px;
  border: none; background: none; cursor: pointer; border-radius: 8px;
}
#kopf .menue-knopf span {
  display: block; width: 22px; height: 2.5px; border-radius: 2px;
  background: var(--tinte); transition: transform 0.25s, opacity 0.2s;
}
body.leiste-offen #kopf .menue-knopf span:nth-child(1) { transform: translateY(7.5px) rotate(-45deg); }
body.leiste-offen #kopf .menue-knopf span:nth-child(2) { opacity: 0; }
body.leiste-offen #kopf .menue-knopf span:nth-child(3) { transform: translateY(-7.5px) rotate(45deg); }

#leistenschatten { display: none; }

@media (max-width: 899px) {
  #kopf .menue-knopf { display: flex; }
  #seitenleiste {
    position: fixed; top: var(--kopf-gesamt); left: 0; bottom: 0; z-index: 40;
    width: min(280px, 84vw); max-height: none;
    transform: translateX(-102%); transition: transform 0.28s ease;
    box-shadow: 2px 0 16px rgba(0, 0, 0, .18);
  }
  body.leiste-offen #seitenleiste { transform: translateX(0); }
  /* Waehrend des Ziehens fuehrt der Finger, nicht die Uhr. Die Transition
     laeuft auf ein festes Ziel in fester Zeit und zoege dagegen. */
  #seitenleiste.leiste-zieht { transition: none; }
  body.leiste-offen #leistenschatten {
    display: block; position: fixed; inset: var(--kopf-gesamt) 0 0 0; z-index: 39;
    background: var(--schleier);
  }
  body.leiste-offen { overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
  #seitenleiste, #kopf .menue-knopf span { transition: none; }
}

/* --------------------------------------------------------- Projektuebersicht */

/* --------------------------------------------------------- Kacheln

   Eine Zahl je Kachel, nebeneinander statt untereinander. Untereinander
   liest man sie als Liste und vergleicht sie nicht; nebeneinander sieht man
   auf einen Blick, welche aus der Reihe faellt. */

.kachelreihe {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px; margin-bottom: 14px; align-items: start;
}
.kachelreihe > .karte { margin-bottom: 0; }
.kachelkopf {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.kachelname { font-weight: 700; font-size: 15px; flex: 1; min-width: 0; }
.kachelwert { display: block; font-size: 24px; font-weight: 700; line-height: 1.15; letter-spacing: -.01em; }
.kachelfuss {
  display: block; margin-top: 8px; font-size: 12.5px; color: var(--tinte-leise);
}

/* Die eine Zahl, um die es geht: gross, allein und mittig. */
.grosszahl { text-align: center; padding: 6px 0 14px; }
.grosszahl-name { display: block; font-size: 15px; font-weight: 700; margin-bottom: 4px; }
.grosszahl-wert { display: block; font-size: 32px; line-height: 1.1; }
.zahlenpaar {
  display: flex; border-top: 1px solid var(--linie); padding-top: 12px; text-align: center;
}
.zahlenpaar > div { flex: 1; }
.zahlenpaar > div + div { border-left: 1px solid var(--linie); }
.paar-name { display: block; font-size: 13px; color: var(--tinte-leise); margin-bottom: 4px; }
.paar-wert { font-size: 17px; font-weight: 700; }
.paar-einheit { font-size: 13px; color: var(--tinte-leise); margin-left: 4px; }
.zahlenpaar input { display: inline-block; margin: 0; }

/* Ueberschrift ueber einer Kachelreihe, also ausserhalb einer Karte. */
h2.abschnitt { font-size: 17px; margin: 18px 0 8px; }
h2.abschnitt + .unterzeile { margin-top: -4px; margin-bottom: 10px; }

/* Ein Abschnitt, der noch keine Zahlen hat: Der Rahmen steht schon, damit
   man sieht, was spaeter dort steht. */
.leer-hinweis { margin: 0; }

/* Datenschutz und Impressum am Fuss der Einstellungen. Nebeneinander,
   wenn Platz ist, sonst untereinander -- drei Links in einer 320 Pixel
   breiten Zeile werden sonst zu drei halben Woertern. */
.rechtsverweise {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin: 14px 0 0; font-size: 14px;
}

/* Der Zettel, wenn die App nicht startet. Eigene Farben statt Variablen:
   Wenn das Stylesheet nur halb ankommt, soll wenigstens das hier lesbar
   sein. */
.startfehler {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; background: #f5f7f6;
  font: 16px/1.5 -apple-system, "Segoe UI", Roboto, sans-serif; color: #1f2a30;
}
.startfehler-karte {
  max-width: 34em; background: #fff; border: 1px solid #d3dcd9;
  border-radius: 12px; padding: 22px 24px;
}
.startfehler-karte h1 { margin: 0 0 12px; font-size: 22px; }
.startfehler-karte p { margin: 0 0 12px; }
.startfehler-karte a { color: #0a5155; }
.startfehler-grund:empty { display: none; }
.startfehler-grund {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12.5px;
  color: #54626a; word-break: break-word;
}

/* Telefonnummer und E-Mail-Adresse in einer Wertzeile: als Verweis kenntlich,
   aber ohne die Zeile zu zerreissen. Umbrechen darf eine lange Adresse
   trotzdem -- sonst schiebt sie auf dem Telefon die Seite nach rechts. */
.erreichbar {
  color: var(--akzent-dunkel); text-decoration: underline;
  text-underline-offset: 3px; overflow-wrap: anywhere;
}

/* Die Marken am rechten Rand einer Kontaktzeile. Sie duerfen umbrechen:
   "Anrufen" und "E-Mail schreiben" nebeneinander passen neben einem langen
   Firmennamen auf 360 Pixeln nicht in eine Zeile. */
.zeilen-marken {
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: 5px; flex: none; max-width: 45%;
}

/* Zustand zum Antippen. Verwandt mit dem Hell-Dunkel-Schalter, aber ueber
   die volle Breite eines Formularfeldes: Hier ist die Wahl der Inhalt und
   nicht eine Kleinigkeit am Rand.

   Die gewaehlte Taste traegt den Akzent, nicht nur eine hellere Flaeche --
   auf einem Telefon im Sonnenlicht ist ein Grauton neben einem anderen
   Grauton keine Antwort auf "was gilt gerade?". */
.zustandswahl {
  display: flex; gap: 2px; padding: 3px;
  border: 1px solid var(--linie); border-radius: 10px; background: var(--band);
}
.zustandstaste {
  flex: 1 1 0; min-width: 0; min-height: 42px; padding: 8px 6px;
  border: none; border-radius: 8px; background: none; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 600; color: var(--tinte-leise);
  transition: background .15s, color .15s;
}
.zustandstaste:active { background: var(--karte); }
.zustandstaste.aktiv {
  background: var(--akzent); color: var(--auf-akzent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
@media (prefers-reduced-motion: reduce) {
  .zustandstaste { transition: none; }
}

/* Die Karte, die oben steht: ein Schritt, nicht zehn.
   Die Marke darueber ist klein und in der Akzentfarbe -- sie sagt, wozu
   die Karte da ist, ohne der Ueberschrift die Groesse wegzunehmen. */
.karte.alsnaechstes { border-color: var(--akzent); }
.alsnaechstes-marke {
  margin: 0; font-size: 11.5px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase; color: var(--akzent);
}
.alsnaechstes-titel { margin: 6px 0 0; font-size: 19px; line-height: 1.25; }

/* Zwei Zahlen nebeneinander statt vier Kacheln untereinander. */
.geldzahlen { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; }
.geldzahlen .rechts { text-align: right; }
.geldname { display: block; font-size: 13px; color: var(--tinte-leise); }
.geldwert { display: block; font-size: 26px; font-weight: 700; line-height: 1.15; letter-spacing: -.4px; }
.fortschrittsbalken.schmal { height: 6px; border-radius: 3px; margin: 14px 0 8px; }

.kennzahlen { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.kennzahl { background: var(--karte); border: 1px solid var(--linie); border-radius: 12px; padding: 12px 14px; }
.kennzahl .wert { font-size: 21px; font-weight: 700; display: block; line-height: 1.2; }
.kennzahl .name { font-size: 13px; color: var(--tinte-leise); display: block; }
/* Dritte Zeile: die Einordnung zur Zahl ("2 neu in 30 Tagen"). Eigene
   Zeile und leiser als der Name -- ohne display:block klebte sie an ihm
   ("Konten2 neu in 30 Tagen"). */
.kennzahl .zusatz {
  display: block; margin-top: 2px;
  font-size: 12px; line-height: 1.35; color: var(--tinte-leise); opacity: .8;
}

/* Wo nichts steht, steht der Weg dorthin: Die Kachel wird ein Knopf,
   bleibt aber ruhig -- vier laute Aufforderungen nebeneinander waeren
   schlimmer als vier Nullen. */
.kennzahl-leer {
  text-align: left; font: inherit; cursor: pointer;
  border-style: dashed; background: none;
}
.kennzahl-leer:hover { border-color: var(--akzent); border-style: solid; }
.kennzahl-leer .wert-leer {
  display: block; font-size: 15px; font-weight: 600; line-height: 1.25;
  color: var(--tinte-leise);
}
.kennzahl-aktion {
  display: block; margin-top: 6px; font-size: 12.5px; font-weight: 700;
  color: var(--akzent-dunkel);
}

/* ---------------------------------------------------- Willkommen und Kopf */

/* Der erste Bildschirm hat genau eine Handlung. Sie muss so aussehen. */
.willkommenskarte { border-top: 5px solid var(--akzent); }
/* Kein Versalsatz: Er wuerde aus BauZeuge BAUZEUGE machen, und das grosse
   Z in der Mitte ist die Marke. */
.willkommen-marke {
  margin: 0 0 2px; font-size: 13px; font-weight: 700; letter-spacing: .02em;
  color: var(--akzent-dunkel);
}
.willkommen-titel { margin: 0 0 6px; font-size: 24px; line-height: 1.2; }
.willkommen-text { margin: 0 0 14px; font-size: 15.5px; line-height: 1.55; color: var(--tinte-leise); }
.knopf-gross { font-size: 17px; min-height: 56px; }
.einstiege {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px; margin-bottom: 12px;
}
.einstieg {
  display: block; text-align: left; font: inherit; cursor: pointer;
  background: var(--karte); color: var(--tinte);
  border: 1px solid var(--linie); border-radius: 12px; padding: 14px 16px;
}
.einstieg:hover { border-color: var(--akzent); }
.einstieg-titel { display: block; font-weight: 700; margin-bottom: 4px; }
.einstieg-text { display: block; font-size: 13px; line-height: 1.45; color: var(--tinte-leise); }

/* Der Projektkopf: Bauweise, Phase, Fortschritt. Eine Zeile, kein Kasten --
   er gehoert zur Ueberschrift und nicht zum Inhalt. */
.projektkopf {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px;
  margin: -6px 0 12px;
}
.projektzeichen {
  flex: none; width: 46px; height: 46px; border-radius: 12px;
  background: var(--band); color: var(--akzent-dunkel);
  display: inline-flex; align-items: center; justify-content: center;
}
.projektkopf-text { flex: 1 1 240px; min-width: 0; }
.projektkopf-zeile { display: block; font-weight: 700; font-size: 15px; }
.projektkopf-unter { display: block; font-size: 13px; color: var(--tinte-leise); }
.projektkopf-stand { font-size: 12.5px; color: var(--tinte-leise); white-space: nowrap; }

/* Die Phasen des Leitfadens als Band. Kein Prozentbalken: Die Phasen sind
   verschieden gross, und "60 Prozent" saehe genauer aus, als es ist. */
.phasenband {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: 6px; margin: 10px 0;
}
.phasenstueck {
  border-radius: 8px; padding: 7px 9px; border: 1px solid var(--linie);
  background: var(--karte); min-width: 0;
}
.phasenname {
  display: block; font-size: 11.5px; font-weight: 600; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.phasenzahl { display: block; font-size: 11px; color: var(--tinte-leise); }
.phase-fertig { background: var(--gut-flaeche); border-color: transparent; }
.phase-fertig .phasenname { color: var(--gut-schrift); }
.phase-laufend { border-color: var(--akzent); border-width: 2px; }
.phase-laufend .phasenname { color: var(--akzent-dunkel); }

/* Was jetzt zu tun ist, steht an der Aufgabe -- nicht nur, warum sie
   wichtig ist. */
.zeilen-tun {
  display: block; font-size: 13px; font-weight: 600; color: var(--akzent-dunkel);
}

/* --------------------------------------------------------- Bauleitfaden */

/* Die Aufgabe links, die Phasenliste rechts. Auf dem Telefon untereinander,
   dort ist fuer zwei Spalten kein Platz. */
.wizard { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
@media (min-width: 860px) {
  .wizard { grid-template-columns: minmax(0, 2fr) minmax(230px, 1fr); align-items: start; }
}
.wizard > .karte { margin-bottom: 0; }
.wizard-kopf { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.wizard-kopf select { flex: 1 1 220px; }
.wizard-titel { margin: 16px 0 6px; }
.wizard-text { white-space: pre-line; margin-bottom: 14px; }
.wizard-fuss {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  border-top: 1px solid var(--linie); padding-top: 12px; margin-top: 4px;
}
.wizard-fuss .knopf, .wizard-fuss .knopf-haupt { flex: 1 1 125px; width: auto; margin: 0; }
.wizard-fuss .knopf-haupt { flex-basis: 165px; }
.wizard-fuss button[disabled] { opacity: .45; cursor: default; }

/* Die Phasenliste: Nummer, Name, Stand. Die laufende Phase ist hervorgehoben. */
.phasenliste .listenzeile { gap: 10px; }
.phasenliste .listenzeile.aktiv { background: var(--band); }
.phasen-zeichen {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--linie); display: inline-flex;
  align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: var(--tinte-leise);
}
.phasen-zeichen.fertig {
  background: var(--gut-flaeche); color: var(--gut-schrift); border-color: var(--gut-flaeche);
}

.phasenblock > summary {
  display: flex; align-items: center; gap: 12px;
  cursor: pointer; list-style: none; margin-bottom: 8px;
}
.phasenblock > summary::-webkit-details-marker { display: none; }
.phasen-titel { font-size: 17px; font-weight: 700; flex: 1; }
.phasen-zahl {
  font-size: 13px; font-weight: 700; color: var(--tinte-leise);
  font-variant-numeric: tabular-nums;
}
.phasenblock > summary::after {
  content: '\203A'; font-size: 20px; color: var(--tinte-leise);
  transform: rotate(90deg); transition: transform 0.2s;
}
.phasenblock[open] > summary::after { transform: rotate(-90deg); }

.leitfaden-zeile {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 9px 0; min-height: 44px;
  /* Umbrechen statt quetschen: Zwei Knoepfe neben einem langen Namen lassen
     auf dem Telefon sonst eine Spalte von drei Zeichen Breite uebrig. */
  flex-wrap: wrap;
}
.leitfaden-zeile .knopf-schmal { white-space: nowrap; }
/* Drei Knoepfe in einer Zeile (Oeffnen, Umbenennen, Loeschen) passen auf ein
   schmales Telefon nicht nebeneinander. Sie duerfen umbrechen und bleiben
   dabei rechts. */
.zeilen-aktionen {
  display: flex; gap: 8px; flex: 0 1 auto; margin-left: auto;
  flex-wrap: wrap; justify-content: flex-end;
}

/* Checklistenpunkte: Zwei ausgewachsene Knoepfe je Zeile machen aus neun
   Punkten eine Bildschirmhoehe. Hier stehen sie klein und ruhig unter dem
   Text -- sie sollen erreichbar sein, nicht wichtig aussehen. Der Punkt
   ist das Abhaken. */
.punktzeile { padding: 6px 0; }
.punktknoepfe { gap: 4px; margin-top: -2px; }
.punktknopf {
  min-height: 30px; padding: 3px 9px; width: auto; margin: 0;
  font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap;
  border: 1px solid var(--linie); border-radius: 8px;
  background: none; color: var(--tinte-leise); cursor: pointer;
}
.punktknopf:hover { border-color: var(--akzent); color: var(--akzent-dunkel); }

/* ------------------------------------------------ Kaesten statt Kolonnen

   Auf dem Telefon steht alles untereinander, das ist dort richtig. Auf einem
   Bildschirm daneben ist es Platzverschwendung: Sechs Eingabefelder in einer
   Kolonne zwingen zum Rollen, obwohl rechts die halbe Karte leer bleibt.

   Statt in jedem Modul eine eigene Anordnung zu bauen, ordnet sich hier alles
   selbst: Die Karte wird zum umbrechenden Flusskasten, alles darin nimmt
   standardmaessig die ganze Breite -- Ueberschriften, Balken, Tabellen,
   Knoepfe -- und nur die Dinge, die nebeneinander Sinn ergeben, bekommen eine
   Grundbreite. Reicht die Zeile nicht, brechen sie von allein um. */

@media (min-width: 760px) {
  .karte, .blatt {
    display: flex; flex-wrap: wrap; align-items: flex-start; column-gap: 16px;
  }
  .karte > *, .blatt > * { flex: 1 1 100%; min-width: 0; }

  /* Eingabefelder: zwei bis drei je Zeile, je nach Platz. */
  .karte > .feld, .blatt > .feld, .felderblock > .feld { flex: 1 1 250px; }

  /* Zahlenzeilen und Balken der Statistiken, ebenfalls nebeneinander. */
  .karte > .balkenzeile { flex: 1 1 300px; }
  .karte > .wertzeile { flex: 1 1 280px; }

  /* Listen: Raeume, Maengel, Kontakte, Dokumente, Aufgaben. Sie richten sich
     nach ihrem Behaelter, nicht nach dem Fenster -- eine Liste in einer
     schmalen Spalte bleibt einspaltig, dieselbe Liste in einer breiten Karte
     bekommt zwei. Deshalb "auto-fit" und keine feste Spaltenzahl: Wer das
     Fenster schmaler zieht, sieht sie von allein zusammenrutschen. */
  .liste {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    column-gap: 20px; align-items: start;
  }

  /* Aufgaben und Checklistenpunkte nicht: Sie tragen Haken, Begruendung,
     naechsten Schritt und zwei Knoepfe, und drei Spalten davon sind eine
     Wand statt einer Liste. */
  .liste-punkte { grid-template-columns: 1fr; }

  /* Gleichrangige Karten nebeneinander statt untereinander: Phasen des
     Leitfadens, Raeume je Geschoss, Maengel je Raum, Angebote je Position,
     Dokumente je Art, Checklisten. */
  .kartengitter {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 12px; align-items: start;
  }
  .kartengitter > .karte { margin-bottom: 0; }
}

/* ------------------------------------------------------------- Wetterkarte

   Farbe bekommt hier eine Bedeutung, statt nur huebsch zu sein: Sie sagt,
   ob draussen gearbeitet werden kann. Klar und bewoelkt sind ruhig, Regen
   und Schnee kuehl, Sturm und Frost warnen. Wer im Vorbeigehen hinsieht,
   weiss es, bevor er gelesen hat.

   Kein Gelb fuer die Sonne: Die Form aus Kreis und Strahlen ist eindeutig
   genug, und ein Goldton passt weder zur Marke noch zum Rest. */

/* Abweichung als Balken von der Mitte: rechts drueber, links drunter. Ein
   Balken, der immer von links waechst, kann kein Vorzeichen zeigen -- und
   genau darum geht es bei Mehrkosten. */
.mehrkostenbild { margin-top: 14px; }
.mittelbalken {
  position: relative; height: 10px; border-radius: 5px;
  background: var(--band); margin: 4px 0 2px;
}
.mittelbalken::before {
  content: ''; position: absolute; left: 50%; top: -2px; bottom: -2px;
  width: 1px; background: var(--linie);
}
.mittelbalken-strich { position: absolute; top: 0; bottom: 0; border-radius: 5px; }
.mittelbalken-strich.nach-rechts { background: var(--warn); }
.mittelbalken-strich.nach-links { background: var(--gut-schrift); }

.wetterkarte { border-left: 5px solid var(--wetterfarbe, var(--linie)); }
.wetterkopf {
  display: flex; align-items: center; gap: 16px; margin-bottom: 12px;
  background: var(--wetterflaeche, var(--band)); color: var(--wetterfarbe, var(--tinte));
  border-radius: 12px; padding: 14px 16px;
}
.wetterzeichen { flex: none; color: var(--wetterfarbe, var(--akzent-dunkel)); }
.wettergrad {
  display: block; font-size: 34px; font-weight: 700; line-height: 1.05;
  color: var(--tinte);
}
.wetterlage {
  display: block; font-size: 15px; font-weight: 700;
  color: var(--wetterfarbe, var(--tinte-leise));
}

/* Die kleine Fassung: eine Zeile. Solange geplant wird, ist das Wetter
   eine Randnotiz -- erst auf der offenen Baustelle entscheidet es den Tag. */
.wetterkarte-klein h2 { font-size: 15px; }
.wetterzeile {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  background: var(--wetterflaeche, var(--band)); border-radius: 12px;
  padding: 10px 14px;
}
.wettergrad-klein { font-size: 22px; font-weight: 700; color: var(--tinte); }
.wetterlage-klein {
  flex: 1 1 auto; font-size: 14px; font-weight: 600;
  color: var(--wetterfarbe, var(--tinte-leise));
}
.wetterzeile .knopf { flex: 0 0 auto; width: auto; margin-bottom: 0; }

.wetter-sonnig   { --wetterflaeche: var(--w-klar-flaeche); --wetterfarbe: var(--w-klar-schrift); }
.wetter-bewoelkt { --wetterflaeche: var(--w-grau-flaeche); --wetterfarbe: var(--w-grau-schrift); }
.wetter-regen    { --wetterflaeche: var(--w-nass-flaeche); --wetterfarbe: var(--w-nass-schrift); }
.wetter-schnee   { --wetterflaeche: var(--w-kalt-flaeche); --wetterfarbe: var(--w-kalt-schrift); }
.wetter-frost    { --wetterflaeche: var(--w-kalt-flaeche); --wetterfarbe: var(--w-kalt-schrift); }
.wetter-sturm    { --wetterflaeche: var(--warn-flaeche);   --wetterfarbe: var(--warn-schrift); }

/* Die Kennzahlen des Tages als kleine Kaesten, nicht als Satz mit Punkten. */
.wetterwerte {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px; margin-bottom: 10px;
}
.wetterwert {
  background: var(--band); border-radius: 10px; padding: 8px 10px; text-align: center;
}
.wetterwert strong { display: block; font-size: 16px; }
.wetterwert span { font-size: 11.5px; color: var(--tinte-leise); }

/* Zeichen stehen in der Schriftfarbe und tragen sie mit: In einer
   markierten Zeile wechseln sie mit, ohne eine eigene Regel zu brauchen. */
.zeichen { display: block; flex: none; }
.zeilenzeichen {
  flex: none; width: 34px; height: 34px; border-radius: 8px;
  background: var(--band); color: var(--akzent-dunkel);
  display: inline-flex; align-items: center; justify-content: center;
}
.mit-zeichen { display: inline-flex; align-items: center; gap: 7px; }
.vorschau-zeichen {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--akzent-dunkel);
}

/* Der Text einer Listenzeile ist zugleich der Knopf. Er sieht nicht danach
   aus: Ein Knopfrahmen um jede Zeile waere ein Zaun um jeden Satz. */
.zeilen-knopf {
  flex: 1 1 150px; min-width: 0; text-align: left; cursor: pointer;
  border: 0; background: none; color: inherit; font: inherit;
  padding: 2px 4px; margin: -2px -4px; border-radius: 8px;
}
.zeilen-knopf:hover { background: var(--band); }
.zeilen-knopf .zeilen-unter { white-space: normal; }

/* --------------------------------------------------------- Raum- und
   Gewerkekacheln

   Ein Raum ist ein Ding mit Bild, Flaeche und Kosten -- und Dinge stehen
   nebeneinander, nicht in einem Band, das sich ueber die ganze Breite zieht
   und in der Mitte ein Loch hat. */

.raumgitter, .gewerkegitter {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 10px;
}
.gewerkegitter { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }

.raumkachel, .gewerkekachel {
  border: 1px solid var(--linie); border-radius: 12px; background: var(--karte);
  display: flex; flex-direction: column; overflow: hidden;
}
.raumkachel-flaeche {
  flex: 1; display: block; width: 100%; text-align: left; cursor: pointer;
  border: 0; background: none; color: inherit; font: inherit; padding: 10px 12px 8px;
}
.raumkachel-flaeche:hover { background: var(--band); }
.raumbild {
  display: block; width: 100%; height: 92px; object-fit: cover;
  border-radius: 8px; background: var(--band); margin-bottom: 8px;
}
.raumbild-zeichen {
  display: flex; align-items: center; justify-content: center;
  color: var(--akzent-dunkel);
}
.raumkachel-kopf { display: flex; align-items: center; gap: 8px; }
.raumkachel-name { font-weight: 700; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.raumkachel-unter {
  display: block; font-size: 12.5px; color: var(--tinte-leise); margin-top: 2px;
}
.raumkachel-aendern { margin: 0 12px 12px; width: auto; }

.gewerkekachel { padding: 10px 12px; gap: 10px; }
.gewerkekopf { display: flex; align-items: center; gap: 10px; }
.gewerkeknoepfe { display: flex; gap: 8px; }
.gewerkeknoepfe .knopf-schmal { flex: 1; }
.zeilen-aktionen .knopf-schmal { flex: none; }
.leitfaden-zeile input[type="checkbox"] { margin-top: 3px; flex: none; }
.leitfaden-zeile .zeilen-text { flex: 1 1 150px; min-width: 0; }
.leitfaden-zeile .zeilen-unter { white-space: normal; }
/* Erledigtes bleibt lesbar, tritt aber zurueck. Durchstreichen waere hier
   falsch: Die Begruendung soll man auch spaeter noch lesen koennen. */
.leitfaden-zeile.erledigt .zeilen-titel { color: var(--tinte-leise); }
.leitfaden-zeile .knopf-schmal { flex: none; align-self: center; }

/* ------------------------------------------------------- Beispielprojekt

   Ueber jedem Bereich, solange das Beispiel offen ist. Deutlich, damit
   niemand erfundene Zahlen fuer eigene haelt, aber nicht rot: Es ist kein
   Fehler, sondern ein Rundgang. */
.beispielband {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 14px; padding: 8px 8px 8px 12px;
  background: var(--band); border: 1px solid var(--linie); border-left: 4px solid var(--akzent);
  border-radius: 10px;
}
.beispielband p { margin: 0; font-size: 13.5px; line-height: 1.4; flex: 1 1 auto; min-width: 0; }
.beispielband .knopf { flex: none; width: auto; margin: 0; min-height: 40px; padding: 6px 14px; font-size: 14px; }

/* ------------------------------------------------------ Fotoaufgaben

   Im Bauablauf, bevor ein Schritt etwas verdeckt. Hervorgehoben wie die
   Willkommenskarte: Das ist die eine Sache, die heute nicht warten kann. */
.fotoaufgabe { border-left: 4px solid var(--akzent); }
.fotoliste { margin: 8px 0 10px; padding-left: 20px; }
.fotoliste li { margin: 3px 0; line-height: 1.45; }
.haken-zeile { display: flex; align-items: center; gap: 8px; margin-top: 6px; font-weight: 600; }
.haken-zeile input { width: 20px; height: 20px; }

/* Zwischentitel im Blatt, etwa "Vertrag und Fristen" unter den Kontaktdaten. */
.blatt-zwischentitel { margin: 18px 0 4px; font-size: 15px; }

/* Installationshinweis auf der Uebersicht. Nummern statt Punkte, weil die
   Reihenfolge der Handgriffe zaehlt und man sie beim Tippen mitzaehlt. */
.install-karte { border-left: 4px solid var(--akzent); }
.install-schritte { list-style: none; margin: 10px 0 8px; padding: 0; display: grid; gap: 10px; }
.install-schritte li { display: flex; gap: 12px; align-items: flex-start; line-height: 1.45; }
.install-nr {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--band); color: var(--tinte); font-weight: 700; font-size: 14px;
}

/* Leistungsumfang im Angebotsvergleich: drei Zustaende, nicht zwei.
   Ungeklaert ist der Normalfall und soll auffallen, ohne zu warnen. */
.umfang {
  min-width: 40px; min-height: 36px; border-radius: 8px; border: 1px solid var(--linie);
  background: var(--karte); color: var(--tinte-leise); font-weight: 700; font-size: 16px; cursor: pointer;
}
.umfang-drin { background: #2e7d4f; border-color: #2e7d4f; color: #fff; }
.umfang-ohne { background: var(--band); color: var(--tinte); text-decoration: none; }
.umfang-offen { border-style: dashed; }

/* Anbietervergleich: eine Tabelle, die von links gelesen wird.
 *
 * table-layout: fixed ist hier keine Feinheit, sondern Bedingung. Mit der
 * automatischen Verteilung zieht die erste Spalte die ganze Breite an sich
 * -- die Fragen darin sind lang --, die Anbieterspalten rutschen aus dem
 * Bild, und der Text laeuft in die Auswahl hinein. Fest verteilt bekommt
 * die Position ihre 260 px, den Rest teilen sich die Anbieter.
 *
 * Die Mindestbreite setzt das Modul je nach Zahl der Anbieter. Reicht der
 * Platz nicht, rollt der Rahmen darum, nicht die Seite. */
.vergleich { border-collapse: collapse; width: 100%; table-layout: fixed; }
/* white-space normal ist hier Pflicht: Die allgemeine Tabellenregel weiter
   oben setzt th und td auf nowrap. Ohne diese Zeile laeuft die Frage in der
   ersten Spalte ueber ihren Rand hinaus quer in die Auswahl daneben. */
.vergleich th, .vergleich td {
  border-bottom: 1px solid var(--linie); padding: 8px 10px; vertical-align: top; text-align: left;
  white-space: normal; overflow-wrap: anywhere;
}
.vergleich thead th { font-size: 13px; color: var(--tinte-leise); }
.vergleich-kopf {
  position: sticky; left: 0; z-index: 2; background: var(--karte);
  width: 260px; font-weight: 400;
}
.vergleich td.zahl { text-align: right; font-variant-numeric: tabular-nums; }
.vergleich .zeilen-titel { display: block; }
.vergleich .zeilen-unter { display: block; margin-top: 2px; }
.vergleich-summe td, .vergleich-summe th { font-weight: 700; border-top: 2px solid var(--akzent); }
/* Bei nur einem Anbieter bekaeme die Spalte die ganze Breite. Ein Feld,
   das ueber einen Meter Bildschirm laeuft, liest sich schlecht. */
.vergleich-wahl { width: 100%; max-width: 420px; min-height: 44px; }
.vergleich-wahl.art-drin { border-color: #2e7d4f; }
.vergleich-wahl.art-betrag { border-color: var(--akzent); }
.vergleich input { width: 100%; max-width: 420px; margin-top: 6px; }
/* Auf dem Telefon bliebe von einer festgepinnten 260-px-Spalte nichts
   uebrig. Dort rollt die Tabelle ganz normal mit. */
@media (max-width: 700px) {
  .vergleich-kopf { position: static; width: 180px; }
}
.anbieter-neu { margin-top: 12px; }
.anbieter-neu input { flex: 1 1 160px; min-width: 0; }
.knopf-leise { margin-top: 6px; color: var(--tinte-leise); }
.schritte { margin: 0; padding-left: 20px; line-height: 1.5; }
.schritte li { margin-bottom: 8px; }
