/* ===========================================================================
   basis.css — Bruchfestigkeit und Typo-Feinschliff
   Teil des Haus-Bausatzes. Wird VOR app.css geladen, NACH tokens.css.

   Warum es diese Datei gibt (Befund 16.09.2026):
   Das bisherige Fundament (40 KB app.css) war haptisch richtig — Radien,
   Schatten, Zustaende stimmten. Es hatte aber keine einzige Regel fuer den
   Fall, dass echte deutsche Daten hineinlaufen: 10 Stellen verboten den
   Umbruch, 0 Stellen erlaubten ihn. Ergebnis beim Kunden: Text schiebt sich
   aus der Karte, Tabellenspalten quetschen sich, die Seite scrollt seitwaerts.
   Mit Testdaten wie "Mueller GmbH" faellt das nie auf.

   Quellen: Adrian Roselli "Techniques to Break Words" (2024),
   MDN overflow-wrap / CSS Text Wrapping, CSS-Tricks "Handling Long Words".
   =========================================================================== */

/* --- 1. Bruchfestigkeit -----------------------------------------------------
   Voraussetzung: <html lang="de">. Ohne lang-Angabe trennt hyphens:auto nicht,
   weil der Browser nicht weiss, welches Woerterbuch er nehmen soll. Das ist
   der haeufigste Grund, warum "es funktioniert nicht". */

html { overflow-wrap: break-word; }

/* Fliesstext, Zellen, Karten: lange Woerter duerfen umbrechen und werden dabei
   sauber getrennt. word-break:break-all waere falsch — das trennt mitten im
   Wort ohne Ruecksicht auf Silben und ist fuer Lesende mit Legasthenie hart. */

/* .pill steht bewusst NICHT in der Liste oben: Statuskuerzel bleiben einzeilig
   (white-space:nowrap in app.css) und werden notfalls mit Auslassungspunkten
   gekuerzt. Ein umgebrochenes Status-Etikett zerreisst die Tabellenzeile.
   Wer hier .pill ergaenzt, macht die Zeilenhoehen wieder unruhig. */
p, li, dd, td, th,
.karte, .kachel, .meldung, .leer,
.feld label, .feld .hinweis, .kommentar .text {
  overflow-wrap: break-word;
  word-break: normal;
  hyphens: auto;
}

/* Zahlen, Betraege und Kennzahlen NIE trennen — eine umgebrochene IBAN oder
   ein zerrissener Betrag ist schlimmer als ein bisschen Ueberhang, und
   Screenreader lesen getrennte Zahlen falsch vor. */
.zahl, .mono, .betrag, .kpi .zahl, td.rechts, td.mono {
  hyphens: none;
  overflow-wrap: normal;
  white-space: nowrap;      /* siehe Fund unten */
  font-variant-numeric: tabular-nums;
}
/* white-space:nowrap ist hier PFLICHT, nicht Geschmack.
   overflow-wrap:normal allein reicht nicht: Browser brechen deutsche Betraege
   am Tausenderpunkt um. Gemessen am 16.09.2026 auf 375 px Breite wurde aus
   "1.284.550,00 EUR" drei Zeilen: "1.284." / "550,00" / "EUR". Ein zerrissener
   Betrag ist nicht nur haesslich, er wird auch falsch gelesen und von
   Screenreadern falsch vorgelesen. Lieber laesst die Spalte scrollen. */

/* Adressen, Mails, Dateinamen, Links: duerfen ueberall brechen, aber ohne
   Trennstrich — ein eingefuegter Bindestrich waere Teil der Adresse, wenn
   jemand abtippt. Fuer gezielte Stellen im Markup <wbr> setzen. */
.technisch, .mail, .datei, a[href^="mailto:"], a[href^="http"] {
  overflow-wrap: anywhere;
  hyphens: none;
}

/* DIE wichtigste Regel der Datei.
   Ein Kind in einem Flex- oder Grid-Behaelter hat von Haus aus min-width:auto.
   Das heisst: es schrumpft NICHT unter die Breite seines laengsten Wortes.
   Ein einziges "Waermepumpen-Installationsprotokoll" in einer Kachel drueckt
   damit das gesamte Raster auseinander und die Seite scrollt seitwaerts.
   Genau das war die Ursache der Umbruch-Probleme bei Scheruebel. */
.kacheln > *, .kpi > *, .zeile > *, .raster-2 > *,
.kommentar > *, .protokoll-zeile > *, .leiste-fuss > *,
main.inhalt, .karte > *, .kopf > * {
  min-width: 0;
}

/* Bilder und Medien halten sich an ihren Behaelter. */
img, svg, video, canvas, iframe { max-width: 100%; }
img, video { height: auto; }

/* --- 2. Tabellen -----------------------------------------------------------
   Zwei Sorten, bewusst getrennt.

   Standard (.tabelle): Spalten richten sich nach dem Inhalt, der Behaelter
   .tabelle-wrap scrollt waagrecht. Richtig, solange die Tabelle breit sein
   darf — auf dem Handy wischt man.

   Fest (.tabelle.fest): feste Spaltenbreiten, Inhalt bricht um. Noetig, sobald
   die Tabelle NICHT scrollen darf oder eine Spalte erfahrungsgemaess lange
   Bezeichnungen enthaelt. overflow-wrap greift in Zellen nur mit
   table-layout:fixed — ohne das passiert schlicht nichts. */
.tabelle.fest { table-layout: fixed; }
.tabelle.fest th, .tabelle.fest td { overflow-wrap: break-word; hyphens: auto; }

/* Feste Spaltenbreiten kippen auf schmalen Geraeten ins Unlesbare: Bei 375 px
   bleiben von 45 % noch 168 px, und "Grundstuecksentwaesserungsgenehmigung"
   wird daraus mit einer Silbe je Zeile. Gemessen am 16.09.2026.
   Darum unter 700 px: zurueck auf inhaltsabhaengige Breiten und den Rahmen
   waagrecht scrollen lassen. Am Handy wischt man ohnehin.
   VORAUSSETZUNG: Auch eine .tabelle.fest gehoert in einen .tabelle-wrap. */
@media (max-width: 700px) {
  .tabelle.fest { table-layout: auto; min-width: 560px; }
  .tabelle.fest th[style*="width"], .tabelle.fest td { width: auto !important; }
}

/* Kopfzeilen duerfen umbrechen statt die Spalte aufzublasen.
   (Das geerbte Blatt hatte hier white-space:nowrap — eine lange Ueberschrift
   wie "Letzte Aenderung durch" zwang damit die ganze Spalte breit.) */
.tabelle th { white-space: normal; }

/* Kuerzen mit Auslassungspunkten — die sichere Vorgabe fuer einzelne lange
   Werte. PFLICHT dazu im Markup: title="voller Wert", sonst ist der Inhalt
   fuer Maus UND Tastatur verloren. Nie fuer eine ganze Tabelle verwenden,
   nur fuer einzelne Spalten. */
.kurz {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Erste Spalte stehen lassen, wenn waagrecht gescrollt wird. */
.tabelle.haft-erste th:first-child,
.tabelle.haft-erste td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--karte);
}

/* --- 3. Typo-Feinschliff ---------------------------------------------------
   Drei Kleinigkeiten, die den Unterschied zwischen "selbstgebaut" und
   "gekauft" ausmachen. Alle drei kosten nichts. */

/* a) Grosse Ueberschriften brauchen eine engere Zeile und minimal negative
      Laufweite. Eine 28-px-Zeile mit Zeilenhoehe 1.5 und Standardlaufweite
      ist das deutlichste Amateur-Signal, das es gibt. */
h1, h2, h3, .kpi .zahl, .kachel h2 {
  line-height: 1.2;
  letter-spacing: -0.011em;
  text-wrap: balance;      /* keine einzelne Hurenkind-Zeile */
}
h1, .kpi .zahl { letter-spacing: -0.018em; }

/* b) Fliesstext haelt Lesebreite. Ueber rund 75 Zeichen verliert das Auge
      beim Ruecksprung die Zeile. Gilt fuer Prosa, NICHT fuer Tabellen. */
.fliess, p.sub, .leer p, .karte > p { max-width: 68ch; }

/* c) Absaetze lassen keine Einzelworte auf der letzten Zeile stehen. */
p, li { text-wrap: pretty; }

/* --- 4. Verschachtelte Radien ----------------------------------------------
   Sitzt eine Flaeche IN einer anderen, muss der innere Radius kleiner sein:
   innen = aussen minus Innenabstand. Gleich grosse Radien ineinander sind
   der zweithaeufigste Grund, warum eine Oberflaeche "irgendwie falsch"
   aussieht, ohne dass man sagen kann warum. */
.karte > .tabelle-wrap,
.karte > .karte,
.karte > .flaeche-innen { border-radius: var(--radius-knopf); }

/* --- 5. Zustaende, die gern vergessen werden -------------------------------
   Eine Oberflaeche wirkt hochwertig, wenn sie in JEDEM Zustand fertig
   aussieht — nicht, wenn der Ruhezustand schoen ist. */

/* Sichtbarer Fokus auch auf Zeilen und Kacheln, nicht nur auf Knoepfen. */
.tabelle tr.zeile-link:focus-visible,
a.karte:focus-visible,
.karte.anfassbar:focus-visible {
  outline: 2px solid var(--marke);
  outline-offset: 2px;
}

/* Wartezustand: Zeiger und Halbtransparenz, damit ein laufender Vorgang
   sichtbar ist, ohne dass die Seite springt. */
[aria-busy="true"] { cursor: progress; opacity: .6; }

/* Deaktiviert ist nicht dasselbe wie unsichtbar. */
[disabled], .aus { cursor: not-allowed; }

/* Auswahl in Markenfarbe statt Browser-Blau. */
::selection { background: var(--marke-bg); color: var(--tinte); }

/* --- 6. Bewegung -----------------------------------------------------------
   Steht auch in tokens.css. Hier bewusst noch einmal, weil basis.css auch
   ohne die Marken-Datei ein vollstaendiges Fundament sein muss. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
