/* ---------------------------------------------------------------
   Instandhaltung - Oberflaeche
   Ausgelegt auf Bedienung am Handy und Tablet vor Ort: grosse
   Trefferflaechen, hoher Kontrast, keine Feinmotorik noetig.
   --------------------------------------------------------------- */

:root {
    --blau:        #1f4e79;
    --blau-hell:   #2f6ea5;
    --blau-zart:   #eaf1f8;
    --gruen:       #1f7a44;
    --gruen-zart:  #e6f4ec;
    --rot:         #b3261e;
    --rot-zart:    #fbeae9;
    --gelb:        #8a6100;
    --gelb-zart:   #fdf3dc;
    --text:        #1a1d21;
    --text-leise:  #5c6470;
    --linie:       #d8dde4;
    --flaeche:     #ffffff;
    --grund:       #f4f6f9;
    --radius:      10px;
    --schatten:    0 1px 3px rgba(16, 24, 40, .08),
                   0 1px 2px rgba(16, 24, 40, .04);
}

* { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    /* Der graue Blitz beim Antippen laesst die App langsam wirken -
       Rueckmeldung geben die Knoepfe selbst (:active). */
    -webkit-tap-highlight-color: rgba(31, 78, 121, .12);
    /* Spruenge zu Ankern (Sprungleiste am Tag, Monatsanker im
       Jahresplan) gleiten, statt zu springen - sonst weiss man nicht,
       ob man gerade nach oben oder unten versetzt wurde. */
    scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* Sprungziele nicht unter der klebenden Kopfzeile (und ggf. der
   Sprungleiste) verstecken. Die Hoehe misst app.js und legt sie in
   --haft-hoehe ab; ohne Javascript bleibt der alte Zustand. */
[id] { scroll-margin-top: calc(var(--haft-hoehe, 0px) + .75rem); }

body {
    margin: 0;
    background: var(--grund);
    color: var(--text);
    font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

a { color: var(--blau); }

h1 { font-size: 1.5rem; margin: 0 0 .25rem; }
h2 { font-size: 1.15rem; margin: 1.75rem 0 .75rem; }
h3 { font-size: 1rem;    margin: 1.25rem 0 .5rem; }

/* --- Rahmen ---------------------------------------------------- */

.huelle        { max-width: 1180px; margin: 0 auto; padding: 1.25rem 1rem 4rem; }
.huelle-schmal { max-width: 430px;  margin: 0 auto; padding: 2.5rem 1rem 4rem; }

/* Nur in der Testumgebung (config 'umgebung' => 'test'). Absichtlich in
   einer Farbe, die sonst nirgends vorkommt — der Balken soll aus dem
   Augenwinkel auffallen, nicht huebsch sein. */
.testbanner {
    background: #b3261e;
    color: #fff;
    text-align: center;
    font-weight: 600;
    font-size: .85rem;
    letter-spacing: .04em;
    padding: .4rem 1rem;
    padding-top: calc(.4rem + env(safe-area-inset-top));
}

.kopf {
    background: var(--blau);
    color: #fff;
    position: sticky;
    top: 0;
    z-index: 20;
    padding-top: env(safe-area-inset-top);
}
.kopf-innen {
    max-width: 1180px;
    margin: 0 auto;
    padding: .6rem 1rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}
.marke { display: flex; align-items: center; gap: .6rem;
         color: #fff; text-decoration: none; }
.marke-zeichen {
    width: 34px; height: 34px; flex: none;
    display: grid; place-items: center;
    background: rgba(255,255,255,.16);
    border-radius: 8px;
    font-weight: 700; font-size: .8rem; letter-spacing: .04em;
}
.marke-text strong { display: block; font-size: .95rem; line-height: 1.2; }
.marke-text small  { display: block; font-size: .75rem; opacity: .75; }

/* Klappschalter fuer das Menue am Handy. Bewusst ein Kontrollkaestchen
   und kein Javascript-Knopf: das Menue muss auch dann aufgehen, wenn
   app.js nicht geladen hat - sonst kaeme man auf dem Handy nirgendwo
   mehr hin. Sichtbar wird es erst unterhalb von 860px (siehe unten). */
.navschalter {
    display: none;                      /* am Rechner gar nicht erst da:
                                           unsichtbar, aber anklickbar
                                           haette es "Abmelden" verdeckt */
    opacity: 0; margin: 0;
    width: 44px; height: 44px; z-index: 1;
}
.navknopf {
    display: none;                      /* am Rechner nicht vorhanden */
    width: 44px; height: 44px; flex: none;
    margin-inline-start: auto;
    place-items: center; border-radius: 8px;
    cursor: pointer;
}
.navknopf i {
    display: block; position: relative;
    width: 22px; height: 2px; border-radius: 2px;
    background: #fff;
}
.navknopf i::before, .navknopf i::after {
    content: ''; position: absolute; left: 0;
    width: 22px; height: 2px; border-radius: 2px;
    background: #fff;
}
.navknopf i::before { top: -7px; }
.navknopf i::after  { top:  7px; }
/* Offen: aus den drei Strichen wird ein Kreuz. */
.navschalter:checked ~ .navknopf i           { background: transparent; }
.navschalter:checked ~ .navknopf i::before   { top: 0; transform: rotate(45deg); }
.navschalter:checked ~ .navknopf i::after    { top: 0; transform: rotate(-45deg); }
.navschalter:focus-visible ~ .navknopf { outline: 2px solid #fff; outline-offset: 2px; }

/* Am Rechner loest sich die Huelle auf - Menue und Benutzerbereich
   liegen dann wieder unmittelbar in der Kopfzeile, wie zuvor. */
.kopf-menue { display: contents; }

.hauptnav { display: flex; gap: .25rem; flex-wrap: wrap;
            margin-inline-start: auto; }
.hauptnav a {
    color: rgba(255,255,255,.85);
    text-decoration: none;
    padding: .5rem .7rem;
    border-radius: 7px;
    font-size: .92rem;
    white-space: nowrap;
}
.hauptnav a:hover { background: rgba(255,255,255,.12); color: #fff; }
.hauptnav a.aktiv { background: rgba(255,255,255,.2); color: #fff; font-weight: 600; }

.kopf-benutzer { display: flex; align-items: center; gap: .6rem; }
.benutzername  { font-size: .88rem; opacity: .9; }

.fuss {
    max-width: 1180px; margin: 0 auto;
    padding: 1.5rem 1rem 2.5rem;
    color: var(--text-leise); font-size: .85rem;
    display: flex; gap: 1rem; flex-wrap: wrap;
}

/* --- Flaechen -------------------------------------------------- */

.karte {
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    box-shadow: var(--schatten);
    padding: 1.1rem;
    margin-bottom: 1rem;
}
.karte > :first-child { margin-top: 0; }
.karte > :last-child  { margin-bottom: 0; }

.kopfzeile {
    display: flex; align-items: flex-start; gap: 1rem;
    flex-wrap: wrap; margin-bottom: 1.25rem;
}
.kopfzeile .rechts { margin-inline-start: auto; display: flex;
                     gap: .5rem; flex-wrap: wrap; }
.unterzeile { color: var(--text-leise); font-size: .92rem; }

/* --- Kennzahlen ------------------------------------------------ */

.kennzahlen {
    display: grid; gap: .75rem; margin-bottom: 1.5rem;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.kennzahl {
    background: var(--flaeche); border: 1px solid var(--linie);
    border-radius: var(--radius); padding: .9rem 1rem;
}
.kennzahl .wert  { font-size: 1.75rem; font-weight: 700; line-height: 1.1; }
.kennzahl .titel { color: var(--text-leise); font-size: .85rem; margin-top: .15rem; }
.kennzahl.gut    .wert { color: var(--gruen); }
.kennzahl.warn   .wert { color: var(--gelb); }
.kennzahl.schlecht .wert { color: var(--rot); }

/* --- Knoepfe --------------------------------------------------- */

.knopf {
    display: inline-flex; align-items: center; justify-content: center;
    gap: .4rem;
    min-height: 44px;
    padding: .6rem 1.1rem;
    background: var(--blau); color: #fff;
    border: 1px solid transparent; border-radius: 8px;
    font: inherit; font-weight: 600;
    text-decoration: none; cursor: pointer;
    transition: background .12s;
}
.knopf:hover  { background: var(--blau-hell); }
.knopf:active { transform: translateY(1px); }
.knopf[disabled], .knopf.laedt { opacity: .55; pointer-events: none; }

.knopf.stumm  { background: var(--flaeche); color: var(--text);
                border-color: var(--linie); }
.knopf.stumm:hover { background: var(--grund); }
.knopf.still  { background: rgba(255,255,255,.14); color: #fff; }
.knopf.still:hover { background: rgba(255,255,255,.24); }
.knopf.gruen  { background: var(--gruen); }
.knopf.rot    { background: var(--rot); }
.knopf.klein  { min-height: 34px; padding: .35rem .7rem; font-size: .85rem; }
.knopf.breit  { width: 100%; }

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

.feld { margin-bottom: 1rem; }
.feld > label {
    display: block; margin-bottom: .3rem;
    font-weight: 600; font-size: .9rem;
}
.feld .hilfe { color: var(--text-leise); font-size: .85rem; margin-top: .3rem; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=time], input[type=number], input[type=search], select, textarea {
    width: 100%;
    min-height: 44px;
    padding: .55rem .7rem;
    border: 1px solid var(--linie); border-radius: 8px;
    background: var(--flaeche); color: var(--text);
    font: inherit;
}
textarea { min-height: 96px; resize: vertical; }
input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--blau-hell); outline-offset: 1px;
    border-color: var(--blau-hell);
}
.feldreihe { display: flex; gap: .75rem; flex-wrap: wrap; }
.feldreihe > .feld { flex: 1 1 180px; }

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

.hinweis {
    padding: .8rem 1rem; border-radius: 8px;
    margin-bottom: 1rem; border: 1px solid;
    font-size: .95rem;
}
.hinweis.erfolg { background: var(--gruen-zart); border-color: #bfe0cd; color: #14532d; }
.hinweis.fehler { background: var(--rot-zart);   border-color: #f0c3c0; color: #7f1d1d; }
.hinweis.info   { background: var(--blau-zart);  border-color: #c4d8ec; color: #17395c; }
.hinweis.warn   { background: var(--gelb-zart);  border-color: #ecd9a6; color: #713f12; }

/* --- Marken (Status) ------------------------------------------- */

.marke-status {
    display: inline-block; padding: .18rem .55rem;
    border-radius: 999px; font-size: .78rem; font-weight: 600;
    white-space: nowrap;
}
.st-offen      { background: #eceff3; color: #454c56; }
.st-geplant    { background: var(--blau-zart); color: #17395c; }
.st-laeuft     { background: var(--gelb-zart); color: var(--gelb); }
.st-erledigt   { background: var(--gruen-zart); color: var(--gruen); }
.st-ueberfaellig,
.st-dringend   { background: var(--rot-zart); color: var(--rot); }
.st-verschoben { background: #f2ecfa; color: #5b21b6; }

/* Faelligkeit nach Quartal: frueheres Quartal offen = rot,
   laufendes = gelb, spaeteres = gruen. */
.faellig-alt     { background: var(--rot-zart);   color: var(--rot); }
.faellig-jetzt   { background: var(--gelb-zart);  color: var(--gelb); }
.faellig-spaeter { background: var(--gruen-zart); color: var(--gruen); }
.st-entfallen  { background: #eceff3; color: #8a919c; text-decoration: line-through; }

/* --- Tabellen -------------------------------------------------- */

.tabellenrahmen { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.liste { width: 100%; border-collapse: collapse; font-size: .93rem; }
table.liste th, table.liste td {
    padding: .6rem .7rem; text-align: left;
    border-bottom: 1px solid var(--linie);
    vertical-align: top;
}
table.liste th {
    font-size: .8rem; text-transform: uppercase; letter-spacing: .03em;
    color: var(--text-leise); font-weight: 600;
    background: var(--grund); white-space: nowrap;
    position: sticky; top: 0;
}
table.liste tbody tr:hover { background: var(--blau-zart); }
/* .reihe (display:flex) gehoert NIE direkt an ein <td>: die Zelle ist
   dann keine Zelle mehr, waechst nicht auf Zeilenhoehe mit, und ihre
   Trennlinie sitzt hoeher als die der Nachbarn - die Linie hat einen
   Absatz. Aufgefallen am 2026-08-08 in /admin/erinnerungen, es traf
   sechs Ansichten. Der Inhalt gehoert in ein <div class="reihe"> IN der
   Zelle. Diese Regel faengt den Rueckfall ab: die Knoepfe stehen dann
   untereinander, aber die Zeile bleibt heil. */
table.liste td.reihe { display: table-cell; }
table.liste td.zahl { text-align: right; font-variant-numeric: tabular-nums; }
.ref { font-variant-numeric: tabular-nums; color: var(--text-leise);
       font-size: .85rem; white-space: nowrap; }

/* Huelle um den Zellinhalt, von app.js gesetzt. Sie wird erst am
   schmalen Schirm gebraucht (Tabelle als Karten, siehe unten); hier
   loest display:contents sie auf, die Zelle bleibt wie sie war. */
.stapel-wert { display: contents; }

/* --- Jahresplan-Raster ----------------------------------------- */

/* Monatskopf ueber den zwoelf Kaestchen - ohne ihn muesste man
   abzaehlen, in welchem Monat etwas geplant ist. */
table.liste th.monatskopf {
    text-align: center;
    padding: .3rem .1rem;
    font-size: .66rem;
    letter-spacing: 0;
    min-width: 24px;
    cursor: pointer;
}
table.liste th.monatskopf.aktuell {
    background: var(--blau);
    color: #fff;
    border-radius: 4px 4px 0 0;
}
/* Anklickbare Spaltenhervorhebung - bleibt beim Scrollen sichtbar,
   da sie auf jeder einzelnen Zelle sitzt statt nur im Kopf. */
table.liste td.spalte-hervor,
table.liste th.monatskopf.spalte-hervor {
    background: #cfe0f2;
}
table.liste th.monatskopf.aktuell.spalte-hervor {
    background: var(--blau);
}

.monatsraster { display: flex; gap: 2px; }
.monatsraster span {
    width: 20px; height: 20px; border-radius: 4px;
    background: #eceff3; display: grid; place-items: center;
    font-size: .62rem; color: #98a0ac;
}
/* Geplant = ausgefuelltes Kaestchen ohne Zeichen, wie in der Vorlage */
.monatsraster span.geplant  { background: #365f91; }
.monatsraster span.erledigt { background: var(--gruen); color: #fff; font-weight: 700; }
.monatsraster span.offen    { background: var(--gelb-zart); color: var(--gelb); font-weight: 700; }
.monatsraster span.faellig  { background: var(--rot); color: #fff; font-weight: 700; }

/* --- Checkliste ------------------------------------------------ */

.schrittgruppe {
    margin: 1.5rem 0 .5rem; font-size: .82rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em;
    color: var(--blau); padding-bottom: .35rem;
    border-bottom: 2px solid var(--blau-zart);
}

.schritt {
    display: flex; gap: .85rem; align-items: flex-start;
    background: var(--flaeche); border: 1px solid var(--linie);
    border-radius: var(--radius); padding: .85rem;
    margin-bottom: .6rem;
    transition: border-color .12s, background .12s;
}
.schritt.erledigt   { background: var(--gruen-zart); border-color: #bfe0cd; }
.schritt.nicht-ok   { background: var(--rot-zart);   border-color: #f0c3c0; }
.schritt.entfaellt  { opacity: .6; }
.schritt.gespeichert { animation: aufblitzen .8s ease-out; }
@keyframes aufblitzen {
    from { box-shadow: 0 0 0 3px rgba(31,122,68,.35); }
    to   { box-shadow: 0 0 0 0 rgba(31,122,68,0); }
}

/* Grosse Trefferflaeche - bedienbar auch mit Arbeitshandschuhen */
.haken {
    flex: none; width: 30px; height: 30px; margin: 0;
    accent-color: var(--gruen); cursor: pointer;
}
.schritt-text  { flex: 1; min-width: 0; }
.schritt-hinweis {
    margin-top: .5rem; padding: .5rem .7rem;
    background: var(--gelb-zart); border-left: 3px solid #e0b955;
    border-radius: 0 6px 6px 0; font-size: .88rem; color: #6b4d0f;
}
/* Unterlagen, die zu genau diesem Arbeitsschritt gehoeren */
.schritt-unterlagen {
    display: flex; gap: .4rem; align-items: center; flex-wrap: wrap;
    margin-top: .55rem; padding: .5rem .6rem;
    background: var(--blau-zart); border-radius: 8px;
}
.schritt-unterlagen .knopf { background: var(--flaeche); }

.schritt-fuss {
    display: flex; gap: .5rem; align-items: center;
    margin-top: .55rem; flex-wrap: wrap;
    font-size: .82rem; color: var(--text-leise);
}
.schritt.typ-hinweis {
    background: var(--gelb-zart); border-color: #ecd9a6;
    color: #6b4d0f; font-size: .92rem;
}
.schritt.typ-sicherheit { background: var(--blau-zart); border-color: #c4d8ec; }

.fortschritt {
    height: 10px; background: #e3e7ed; border-radius: 999px;
    overflow: hidden; margin: .6rem 0;
}
.fortschritt > i {
    display: block; height: 100%; background: var(--gruen);
    border-radius: 999px; transition: width .3s ease;
}

/* Am unteren Rand angeheftete Aktionsleiste auf dem Handy */
.aktionsleiste {
    position: sticky; bottom: 0;
    background: var(--flaeche); border-top: 1px solid var(--linie);
    padding: .75rem 1rem calc(.75rem + env(safe-area-inset-bottom));
    margin: 1.5rem -1rem 0;
    display: flex; gap: .6rem; flex-wrap: wrap;
    box-shadow: 0 -2px 8px rgba(16,24,40,.06);
}
.aktionsleiste .knopf { flex: 1 1 160px; }

/* --- Kachelliste (Instandhaltungstag) -------------------------- */

.kacheln { display: grid; gap: .8rem;
           grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.kachel {
    background: var(--flaeche); border: 1px solid var(--linie);
    border-left: 4px solid var(--linie);
    border-radius: var(--radius); padding: 1rem;
    display: flex; flex-direction: column; gap: .5rem;
    text-decoration: none; color: inherit;
}
.kachel:hover     { border-color: var(--blau-hell); box-shadow: var(--schatten); }
.kachel.frei      { border-left-color: var(--blau); }
.kachel.meins     { border-left-color: var(--gelb); }
.kachel.fertig    { border-left-color: var(--gruen); }
.kachel.fremd     { opacity: .72; }
.kachel h3        { margin: 0; font-size: 1.02rem; }
.kachel .zeile    { display: flex; gap: .5rem; align-items: center;
                    flex-wrap: wrap; font-size: .85rem; color: var(--text-leise); }

/* --- Bilder ---------------------------------------------------- */

.bilderreihe { display: flex; gap: .5rem; flex-wrap: wrap; }
.bilderreihe img {
    width: 110px; height: 110px; object-fit: cover;
    border-radius: 8px; border: 1px solid var(--linie);
}
/* Dateifelder mit eigener Beschriftung (app.js baut sie um). Ohne
   Javascript bleibt das nackte Feld stehen - deshalb tragen beide
   Fassungen denselben gestrichelten Rahmen. */
.bildfeld input[type=file],
.bildfeld .dateiwahl {
    width: 100%; padding: .8rem; min-height: 56px;
    border: 2px dashed var(--linie); border-radius: 8px;
    background: var(--flaeche);
}
.dateiwahl {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
    cursor: pointer; position: relative;
}
.dateiwahl-stand { font-size: .88rem; color: var(--text-leise);
                   overflow-wrap: anywhere; }
/* Nicht display:none: ein verstecktes Pflichtfeld liesse sich sonst
   weder ansteuern noch bemaengeln, und der Browser koennte beim
   Absenden auf ein Feld zeigen, das niemand sieht. */
.datei-versteckt {
    position: absolute; width: 1px; height: 1px;
    opacity: 0; overflow: hidden; padding: 0; margin: 0; border: 0;
}

/* --- QR -------------------------------------------------------- */

.qr-block { text-align: center; }
.qr-block svg { max-width: 320px; width: 100%; height: auto;
                border: 1px solid var(--linie); border-radius: var(--radius); }
.qr-link {
    display: block; margin-top: .75rem; word-break: break-all;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .88rem; background: var(--grund);
    padding: .6rem; border-radius: 8px;
}

/* --- Kleinkram ------------------------------------------------- */

.leer {
    text-align: center; padding: 3rem 1rem;
    color: var(--text-leise);
}
.leise { color: var(--text-leise); }
.klein { font-size: .85rem; }
.trenner { height: 1px; background: var(--linie); margin: 1.25rem 0; }
.reihe { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
/* Erscheint erst am schmalen Schirm - siehe Umbrueche am Dateiende. */
.nur-handy { display: none; }

/* Sprungleiste (Instandhaltungstag): Chips zu den Abschnitten der
   Seite. Am Rechner stehen die Spalten nebeneinander, da braucht es
   sie nicht - sichtbar erst, wenn die Seite einspaltig wird. */
.springer { display: none; }
.abstand-oben { margin-top: 1.25rem; }

/* Nur-Lese-Ansicht: Angaben als Paare statt als Formular. Fuer Rollen
   ohne Aenderungsrecht (Trainer, Mitarbeiter, Helfer IHK) - die sollen
   die Daten sehen, aber kein Formular mit totem Speichern-Knopf. */
.angaben {
    display: grid; grid-template-columns: max-content 1fr;
    gap: .5rem 1rem; margin: 0;
}
.angaben dt { color: var(--text-leise); font-size: .85rem; }
.angaben dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 480px) {
    .angaben    { grid-template-columns: 1fr; gap: .15rem; }
    .angaben dd { margin-bottom: .6rem; }
}

/* Sprachwahl - oben rechts, wo es keine Kopfzeile gibt (Login, Einwahl) */
.sprachwahl {
    position: absolute; top: .6rem; right: .75rem; z-index: 30;
    padding-top: env(safe-area-inset-top);
}
.sprachwahl select {
    min-height: 34px; padding: .2rem .5rem;
    font-size: .82rem; border-radius: 7px;
    background: rgba(255,255,255,.92); border: 1px solid var(--linie);
    box-shadow: var(--schatten);
}
body.schlicht .sprachwahl { position: fixed; }

/* Im angemeldeten Portal sitzt sie in der Kopfzeile und laeuft im
   normalen Fluss mit. Schwebend hat sie sich bei schmalem Fenster ueber
   "Abmelden" gelegt - der Kopf bricht dort um, die Sprachwahl nicht. */
.sprachwahl.im-kopf { position: static; padding-top: 0; }
.sprachwahl.im-kopf select {
    background: rgba(255,255,255,.14); color: #fff;
    border-color: rgba(255,255,255,.28); box-shadow: none;
    min-height: 30px;
}
/* Das Klappmenue selbst zeichnet das Betriebssystem - weisse Schrift auf
   hellem Grund waere dort unlesbar. */
.sprachwahl.im-kopf option { color: var(--text); background: #fff; }

/* Im Testsystem sitzt der rote Balken ganz oben — die Sprachwahl muss
   darunter, sonst deckt sie ihn zur Haelfte ab. Der Sicherheitsabstand
   fuers Notch wandert dabei zum Balken. */
body.testumgebung .sprachwahl {
    top: calc(.6rem + 1.9rem);
    padding-top: 0;
}

/* Rueckfrage vor heiklen Aktionen - ersetzt das confirm() des Browsers.
   Erscheint bei der Maus statt oben am Fensterrand, im Stil der
   Anwendung statt in dem des Browsers. */
dialog.frage {
    border: 1px solid var(--linie); border-radius: 12px;
    box-shadow: 0 12px 34px rgba(0,0,0,.22);
    padding: 1.1rem 1.2rem; max-width: min(30rem, calc(100vw - 1.5rem));
    background: #fff; color: var(--text);
}
dialog.frage::backdrop { background: rgba(15,23,42,.28); }
dialog.frage p { margin: 0 0 1rem; line-height: 1.45; }
.frage-knoepfe {
    display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap;
}
@media (max-width: 480px) {
    .frage-knoepfe .knopf { flex: 1 1 auto; justify-content: center; }
}

.live-punkt {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    background: var(--gruen); margin-right: .35rem;
    animation: pulsieren 2s ease-in-out infinite;
}
@keyframes pulsieren { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

/* =================================================================
   Handy und Tablet

   Drei Stufen, jede mit einem eigenen Grund:

     860px  Das Menue hat bis zu elf Punkte. Nebeneinander passen sie
            hier nicht mehr; frueher rutschten sie in eine waagerechte
            Rolle, in der die hinteren Punkte unsichtbar blieben. Ab
            hier klappt das Menue auf Knopfdruck auf.
     700px  Tabellen mit vielen Spalten werden zu Karten: jede Zeile
            ein Block, jede Zelle mit ihrer Spaltenueberschrift davor.
            Waagerechtes Schieben faellt damit weg - das war am Handy
            der groesste Stolperstein, weil die entscheidende Spalte
            (Status, Knopf) immer rechts ausserhalb lag.
     640px  Kleinkram: engere Abstaende, Knoepfe ueber die volle
            Breite, Kacheln einspaltig.
   ================================================================= */

@media (max-width: 860px) {
    .kopf-innen { padding: .5rem .75rem; position: relative; }
    .navschalter { display: block; position: absolute;
                   top: .5rem; inset-inline-end: .75rem; }
    .navknopf   { display: grid; }

    /* Lange Objektnamen duerfen den Knopf nicht wegdruecken. */
    .marke { min-width: 0; }
    .marke-text { min-width: 0; }
    .marke-text strong, .marke-text small {
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    .kopf-menue {
        display: none;
        order: 3; width: 100%;
        margin: .5rem -.75rem -.5rem;
        padding: .25rem .75rem .5rem;
        padding-bottom: calc(.5rem + env(safe-area-inset-bottom));
        border-top: 1px solid rgba(255,255,255,.18);
        /* Bei elf Punkten auf einem kleinen Bildschirm reicht die Hoehe
           sonst nicht - und die Kopfzeile klebt oben fest. */
        max-height: calc(100vh - 7rem);
        overflow-y: auto;
    }
    .navschalter:checked ~ .kopf-menue { display: block; }

    .hauptnav { flex-direction: column; gap: 0; margin: 0; }
    .hauptnav a {
        display: flex; align-items: center; gap: .5rem;
        padding: .8rem .55rem; font-size: 1rem;
        border-radius: 7px;
        border-bottom: 1px solid rgba(255,255,255,.1);
        white-space: normal;
    }

    .kopf-benutzer { padding: .8rem .55rem 0; gap: .75rem; }
    .benutzername  { flex: 1; min-width: 0; font-size: .95rem;
                     overflow: hidden; text-overflow: ellipsis;
                     white-space: nowrap; }
    .kopf-benutzer .knopf { min-height: 40px; }
    .sprachwahl.im-kopf select { min-height: 40px; }

    /* --- Detailseiten mit fester Infospalte -------------------
       Termin, Mangel, Tag, Pruefprotokoll & Co. stellen eine schmale
       Infospalte neben den Inhalt; die Breiten stehen als Inline-Stil
       an der Seite. Am Handy quetschte dieses Raster den Inhalt auf
       Restbreite - hier wird eine Spalte daraus. !important, weil der
       Inline-Stil sonst vorgeht. */
    .spaltig { grid-template-columns: 1fr !important; }

    /* Instandhaltungstag: die Arbeit (Aufgaben, Zuweisung) nach oben,
       QR und Rahmendaten darunter. Nur die Darstellung dreht sich
       (order) - die DOM-Reihenfolge bleibt stehen, denn an ihr haengt
       die Zuordnung der data-erneuern-Bereiche in app.js. */
    .tag-spalten > div:first-child { order: 2; }

    /* Die Sprungleiste dazu: eine Reihe Chips, seitlich rollbar,
       haftet unter der Kopfzeile (Hoehe misst app.js; ohne Javascript
       fehlt --kopf-hoehe, top wird 0 und die Leiste verschwindet beim
       Rollen hinter der Kopfzeile - gleiches Verhalten wie nicht
       haftend, nur ohne die Spruenge geht es dann eben vom Seitenkopf
       aus). Negative Raender fuehren sie randlos ueber die volle
       Breite, damit beim Haften nichts seitlich hervorlugt. */
    .springer {
        display: flex; gap: .4rem;
        overflow-x: auto; -webkit-overflow-scrolling: touch;
        position: sticky; top: var(--kopf-hoehe, 0px); z-index: 15;
        background: var(--grund);
        margin: 0 -1rem .9rem; padding: .5rem 1rem;
        border-bottom: 1px solid var(--linie);
    }
    .springer a {
        flex: none;
        padding: .35rem .75rem; border-radius: 999px;
        border: 1px solid var(--linie); background: var(--flaeche);
        color: var(--text); text-decoration: none;
        font-size: .85rem; white-space: nowrap;
    }
    .springer a:active { background: var(--blau-zart); }
}

@media (max-width: 700px) {
    .nur-handy { display: block; }

    /* --- Tabelle als Karten ------------------------------------
       Die Klasse setzt app.js, und nur dort, wo es sich lohnt:
       eine einzeilige Ueberschrift mit mindestens vier Spalten.
       Schmale Tabellen bleiben Tabellen, das Raster des Jahresplans
       ebenfalls (dort steht die Ueberschrift zweizeilig). Ohne
       Javascript bleibt alles wie bisher - dann wird geschoben. */
    table.liste.gestapelt,
    table.liste.gestapelt tbody,
    table.liste.gestapelt tr,
    table.liste.gestapelt td { display: block; width: auto; }
    table.liste.gestapelt thead { display: none; }

    table.liste.gestapelt tr {
        border: 1px solid var(--linie); border-radius: var(--radius);
        background: var(--flaeche);
        padding: .55rem .7rem; margin-bottom: .6rem;
    }
    table.liste.gestapelt tr:last-child  { margin-bottom: 0; }
    table.liste.gestapelt tbody tr:hover { background: var(--flaeche); }

    table.liste.gestapelt td {
        border: 0; padding: .22rem 0;
        display: grid; grid-template-columns: minmax(5.5rem, 34%) 1fr;
        gap: .1rem .75rem; align-items: baseline;
        overflow-wrap: anywhere;
    }
    /* Genau zwei Felder im Raster: die Ueberschrift und die Huelle um
       den Inhalt. Ohne die Huelle wuerde jedes Kind der Zelle ein
       eigenes Rasterfeld belegen. */
    table.liste.gestapelt td[data-spalte] > .stapel-wert {
        display: block; min-width: 0;
    }
    table.liste.gestapelt td::before {
        content: attr(data-spalte);
        color: var(--text-leise); font-size: .74rem; font-weight: 600;
        text-transform: uppercase; letter-spacing: .03em;
        line-height: 1.35;
    }
    table.liste.gestapelt td.zahl { text-align: start; }

    /* Spalten ohne Ueberschrift sind in dieser Anwendung immer die
       Knopfspalten. Sie gehoeren ans Ende der Karte, ueber die volle
       Breite - so trifft man sie auch mit Handschuhen. */
    table.liste.gestapelt td.stapel-aktion {
        display: flex; gap: .5rem; flex-wrap: wrap;
        margin-top: .5rem; padding-top: .55rem;
        border-top: 1px solid var(--linie);
    }
    table.liste.gestapelt td.stapel-aktion::before { content: none; }
    table.liste.gestapelt td.stapel-aktion > .knopf,
    table.liste.gestapelt td.stapel-aktion .reihe { flex: 1 1 auto; }
    table.liste.gestapelt td.stapel-aktion .knopf { min-height: 40px; }

    /* Leere Zellen wuerden als Ueberschrift ohne Angabe dastehen, eine
       leere Knopfspalte als leerer Kasten mit Trennlinie. Muss nach
       .stapel-aktion stehen - gleiche Staerke, spaeter gewinnt. */
    table.liste.gestapelt td.stapel-leer { display: none; }

    /* Zwischenueberschriften (Zeilen mit einer Zelle ueber alle
       Spalten) bleiben Ueberschriften und werden keine Karte. */
    table.liste.gestapelt tr.stapel-gruppe {
        border: 0; background: none; border-radius: 0;
        padding: .9rem 0 .2rem; margin: 0;
    }
    table.liste.gestapelt tr.stapel-gruppe td { display: block; padding: 0; }
    table.liste.gestapelt tr.stapel-gruppe td::before { content: none; }

    /* Bedienelemente in den Karten: volle Breite und gross genug
       fuer den Daumen. !important, weil die Views hier mit
       Inline-Stilen arbeiten (width:auto, min-height:34px) - die
       gelten weiter fuer die Tabellenform am Rechner. Schriftgroesse
       mindestens 16px, sonst springt iOS beim Antippen in den Zoom. */
    table.liste.gestapelt td[data-spalte] select {
        width: 100% !important;
        min-height: 44px !important;
        font-size: 1rem !important;
    }
    table.liste.gestapelt input[type=checkbox],
    table.liste.gestapelt input[type=radio] {
        width: 26px !important; height: 26px !important;
    }

    /* Spalte ohne Ueberschrift am ANFANG der Zeile ist keine
       Knopfleiste, sondern das Auswahlkaestchen (Aufgaben
       hinzufuegen, Einladungen): ohne Trennlinie und Abstand. */
    table.liste.gestapelt td.stapel-aktion:first-child {
        margin-top: 0; padding-top: 0; border-top: 0;
    }

    /* Die Tabelle ist jetzt schmal - der Schiebekasten darf sich
       weder als Fangrahmen fuer senkrechtes Wischen anbieten noch
       seine Inline-Hoehenbegrenzung behalten (max-height:420px war
       fuer die Tabellenform gedacht; die Karten scrollen mit der
       Seite). */
    .tabellenrahmen.gestapelt-rahmen {
        overflow: visible;
        max-height: none !important;
    }
}

@media (max-width: 640px) {
    .huelle { padding: 1rem .75rem 4rem; }
    .karte  { padding: .9rem; }
    h1      { font-size: 1.3rem; }
    h2      { font-size: 1.08rem; }

    /* Die Knopfleiste einer Ueberschrift bekommt eine eigene Zeile
       und teilt sie unter sich auf, statt rechts zu zerfransen. */
    .kopfzeile { gap: .6rem; margin-bottom: 1rem; }
    .kopfzeile .rechts { width: 100%; margin-inline-start: 0; }
    .kopfzeile .rechts > .knopf,
    .kopfzeile .rechts > form   { flex: 1 1 auto; }
    .kopfzeile .rechts > form > .knopf { width: 100%; }

    .kennzahlen { gap: .5rem;
                  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
    .kennzahl        { padding: .7rem .8rem; }
    .kennzahl .wert  { font-size: 1.5rem; }
    .kennzahl .titel { font-size: .8rem; }

    .kacheln { grid-template-columns: 1fr; }

    /* Vier statt drei nebeneinander waeren Briefmarken. */
    .bilderreihe img { width: calc(33.333% - .34rem); height: auto;
                       aspect-ratio: 1; }

    /* Muss zum Rand von .huelle passen (dort .75rem), sonst steht die
       Leiste ueber und die ganze Seite laesst sich seitlich schieben. */
    .aktionsleiste { margin: 1.5rem -.75rem 0; padding: .75rem .75rem
                     calc(.75rem + env(safe-area-inset-bottom)); }
    .springer      { margin-inline: -.75rem; padding-inline: .75rem; }
    .aktionsleiste .knopf { flex: 1 1 100%; }

    /* Am Zeigefinger statt an der Maus: die Rueckfrage sitzt unten,
       wo der Daumen ist, und nicht dort, wo getippt wurde. */
    dialog.frage {
        position: fixed; inset: auto 0 0 0; margin: 0;
        max-width: none; width: 100%;
        border-radius: 14px 14px 0 0; border-bottom: 0;
        padding-bottom: calc(1.1rem + env(safe-area-inset-bottom));
    }
    .frage-knoepfe .knopf { flex: 1 1 auto; justify-content: center; }
}

@media print {
    .kopf, .fuss, .aktionsleiste, .knopf { display: none !important; }
    body { background: #fff; }
    .karte { border: none; box-shadow: none; padding: 0; }
}
