/* ==========================================================================
   Telefon und Touch — alles, was die App fuer den Finger und 390 px tut

   Gesammelt in EINER Datei und nach `app.css` geladen: bei gleicher
   Spezifitaet gewinnt damit immer die Regel hier, und niemand muss im
   5000-Zeilen-Bestand suchen, ob eine Telefonregel vor oder hinter ihrer
   Grundregel steht (genau daran ist #12851 gescheitert). Farben stehen hier
   keine — nur Variablen, das Dunkel und das Glas ziehen also mit.

   Gemessen wurde vorher auf einem nachgebildeten iPhone (390x844, Touch) ueber
   alle Seiten aus `e2e_layout.SEITEN`:

   * 29 Tabellen scrollten seitwaerts, in jeder davon lag die Aktionsspalte
     rechts ausserhalb des Bildes (Kunden: „Bearbeiten" nur durch Wischen).
   * Rund 450 Bedienelemente waren niedriger als 36 px — vor allem
     `.btn--sm` mit 27 px, die Zeilenaktionen jeder Liste.
   * Das Monatsgitter zeigte Termine als „M…" in 42 px breiten Zellen.
   * Kennzahl-Kacheln standen einzeln untereinander — die Projektakte war
     8600 px lang, ein Drittel davon sechs Zahlen.

   Die Grenzen folgen dem Bestand: 860 px (Seitenleiste wird Overlay),
   700 px (`.col-sm` entfaellt — ab dort ist eine Tabelle zu schmal) und
   `pointer: coarse` fuer alles, was am FINGER haengt statt an der Breite
   (ein Tablet quer ist breit und trotzdem ein Finger).
   ========================================================================== */

/* Kein Doppeltipp-Zoom auf Bedienelementen — er verzoegert auf manchen
   Geraeten jeden Tipp um 300 ms, und auf einem Knopf will niemand zoomen. */
a,
button,
input,
select,
textarea,
label,
summary {
    touch-action: manipulation;
}

/* --------------------------------------------------------------------------
   Fingergerechte Ziele
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
    /* Die Zeilenaktion jeder Liste. 27 px trifft man nur mit Zielen; 40 px
       ist die Untergrenze, die neben dem Text noch ruhig aussieht. */
    .btn--sm {
        min-height: 40px;
        padding-left: 14px;
        padding-right: 14px;
    }

    .iconbtn {
        width: 40px;
        height: 40px;
    }

    .iconbtn--sm {
        width: 36px;
        height: 36px;
    }

    /* Textlinks als Knopf („Anlage eintragen", „Öffnen →"): die Flaeche
       waechst, die Zeile nicht — Polsterung und Gegen-Aussenabstand heben
       sich in der Hoehe auf. */
    .linkbtn,
    .dash__link {
        display: inline-block;
        padding-top: 9px;
        padding-bottom: 9px;
        margin-top: -9px;
        margin-bottom: -9px;
    }

    .group__toggle,
    .legende__kopf,
    .woche__kopf {
        padding-top: 9px;
        padding-bottom: 9px;
    }

    /* Links in einer Listenkarte (Name, Telefonnummer) — dieselbe Rechnung
       wie oben. Nur in der gestapelten Tabelle: dort steht der Link allein
       in seiner Zeile, im Fliesstext wuerde er die Nachbarzeilen ueberdecken. */
    .table--stapel td > a:not(.btn),
    .table--stapel td > p > a:not(.btn) {
        display: inline-block;
        padding-top: 8px;
        padding-bottom: 8px;
        margin-top: -8px;
        margin-bottom: -8px;
    }

    /* Native Haken messen 13 px. */
    input[type="checkbox"],
    input[type="radio"] {
        width: 20px;
        height: 20px;
    }
}

/* --------------------------------------------------------------------------
   Huelle: Kopfzeile, Inhalt, Hintergrund
   -------------------------------------------------------------------------- */

@media (max-width: 860px) {
    /* Der Menueknopf bleibt oben stehen. Die Projektakte ist mehrere
       Bildschirme lang — wer unten ist, kam ohne das nur durch Zurueckwischen
       ans Menue. Unter dem Dialog (60), der Leiste (65/70) und dem
       Feedback-Knopf (50). */
    .mobilebar {
        position: sticky;
        top: 0;
        z-index: 45;
    }

    /* Der Feedback-Knopf schwebt unten rechts ueber dem Inhalt. Ohne diesen
       Platz deckt er am Seitenende genau die letzte Zeilenaktion ab. */
    .content {
        padding-bottom: 80px;
    }

    /* Am Ende einer scrollenden Leiste bzw. eines Dialogs scrollt nicht die
       Seite dahinter weiter. */
    .sidebar,
    .modal__pad,
    .modal__body {
        overscroll-behavior: contain;
    }

    /* Der Farbverlauf des Glas-Themas als feste Ebene statt
       `background-attachment: fixed`: das ignoriert iOS (der Verlauf zog sich
       dort ueber die ganze Seitenlaenge und lief nach einem Bildschirm in
       Grau aus), und Android zeichnet es bei jedem Scrollschritt neu. Die
       Ebene liegt hinter allem und faengt keinen Tipp. */
    html[data-thema="glass"] body {
        background-image: none;
    }

    html[data-thema="glass"] body::before {
        content: "";
        position: fixed;
        inset: 0;
        z-index: -1;
        background-image: var(--flaeche);
        background-repeat: no-repeat;
        pointer-events: none;
    }

    /* A dialog may take almost the whole screen — 24 px margin at the top
       and bottom were a tenth of the height on a phone. */
    .modal {
        padding: 12px 8px;
    }

    /* Button rows: 2 px spacing is enough for the mouse, not for the
       finger — and a wrapped row stands left-aligned instead of as a
       right-aligned staircase (survey: three rows, each a different length). */
    .rowactions {
        gap: 8px;
    }

    /* The gap of `.rowactions` above would otherwise also overwrite the
       12 px of the head row (amount next to button, app.css). */
    .rowactions--head {
        justify-content: flex-start;
        gap: 12px;
    }

    /* If title and buttons don't fit on one line, the buttons slip below —
       and stand there left-aligned side by side instead of right-aligned
       on top of each other (calendar: two buttons, two lines). */
    .pagehead .rowactions {
        justify-content: flex-start;
        gap: 8px;
        margin-bottom: 0;
    }

    /* Code field in the wiki (13 px): iOS zooms into every field under 16 px. */
    .field__input--code {
        font-size: 16px;
    }
}

/* --------------------------------------------------------------------------
   Tabellen werden Karten (`js/app/tabellenstapel.js` beschriftet die Zellen)
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
    .table--stapel thead {
        display: none;
    }

    .table--stapel,
    .table--stapel tbody,
    .table--stapel tfoot {
        display: block;
    }

    /* Jede Zeile eine Karte in zwei Spalten: links und rechts je ein Wert
       unter seiner Beschriftung. Die erste Zelle (Name, Titel) und die
       Aktionen gehen ueber die volle Breite. */
    .table--stapel tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 10px 16px;
        padding: 14px var(--card-inset);
    }

    .table--stapel tbody tr + tr {
        border-top: 1px solid var(--border);
    }

    /* `:nth-child(n)` hebt die Regel ueber die Polsterung der ersten und
       letzten Spalte in `.card--flush` — die gilt fuer ein Raster, nicht fuer
       eine Karte. */
    .table.table--stapel tbody td:nth-child(n) {
        display: block;
        min-width: 0;
        padding: 0;
        border-top: 0;
        background: none;
        overflow-wrap: anywhere;
    }

    /* A button label breaks between words, never inside one: "anywhere"
       above turned "Ansprechpartner" into "Ansprechpart/ner" (390px). */
    .table.table--stapel tbody td .btn {
        overflow-wrap: normal;
    }

    .table.table--stapel tbody td:first-child,
    .table.table--stapel tbody td[colspan],
    .table.table--stapel tbody td:has(> .rowactions),
    .table.table--stapel tbody td:has(> .checkliste, > .table__photos) {
        grid-column: 1 / -1;
    }

    /* Ohne Kopf keine Beschriftung — ein Wert ohne Namen in einer halben
       Spalte waere ein Raetsel. Er steht dann einfach unter dem vorigen. */
    .table.table--stapel:not(:has(thead)) tbody td {
        grid-column: 1 / -1;
    }

    .table--stapel td[data-label]:not(:first-child)::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 1px;
        color: var(--text-dim);
        font-size: 12px;
        font-weight: 500;
        line-height: 16px;
    }

    .table--stapel tbody td:first-child {
        font-size: 15px;
    }

    /* Leere Zellen (keine Notiz, keine Aktion fuer diesen Nutzer) nehmen
       keinen Platz. `:empty` allein reicht nicht — Jinja laesst in einer
       Zelle mit unerfuelltem `{% if %}` Leerzeichen stehen; `data-leer`
       setzt das Skript. */
    .table.table--stapel tbody td:empty,
    .table.table--stapel tbody td[data-leer] {
        display: none;
    }

    /* `.col-sm` entfaellt weiter — `display: block` oben ist spezifischer
       als die Grundregel und holte die Spalte sonst zurueck. */
    .table.table--stapel tbody td.col-sm,
    .table.table--stapel tbody td.col-md {
        display: none;
    }

    /* „23.10. 08:00–16:00" darf in der halben Karte umbrechen — als
       Tabellenspalte hielt `nowrap` ihn zusammen, hier ragte er heraus. */
    .table--stapel .table__nowrap {
        white-space: normal;
    }

    /* Die Aktionen stehen unten links unter den Werten, nicht am rechten
       Rand einer Spalte, die es nicht mehr gibt. */
    .table--stapel .rowactions {
        justify-content: flex-start;
        gap: 8px;
    }

    /* Hervorgehobene Zeilen faerben die Karte, nicht die einzelnen Zellen —
       im Raster stuenden sonst getoente Inseln mit hellen Fugen. */
    .table--stapel tbody tr.is-low,
    .table--stapel tbody tr.is-overdue {
        background: rgba(232, 133, 10, 0.06);
    }

    .table--stapel tbody tr.is-accepted {
        background: rgba(47, 143, 87, 0.08);
    }

    .table--stapel tbody tr.is-selected {
        box-shadow: inset 3px 0 0 var(--accent);
    }

    .table.table--stapel tbody tr.is-selected td:first-child {
        box-shadow: none;
    }

    /* Summen (Rechnung, Angebot): Bezeichnung links, Betrag rechts. */
    .table--stapel tfoot tr {
        display: flex;
        justify-content: space-between;
        gap: 16px;
        padding: 6px var(--card-inset);
    }

    .table.table--stapel tfoot td:nth-child(n) {
        padding: 0;
        border: 0;
    }

    .table--stapel tfoot td:empty {
        display: none;
    }

    .table--stapel tfoot tr:first-child {
        border-top: 1px solid var(--border);
        padding-top: 12px;
    }

    /* Waehrend des Ziehens (Sortieren) bleibt die angehobene Karte eine
       Karte. */
    .table--stapel tbody tr.is-ziehend {
        display: grid;
    }
}

/* --------------------------------------------------------------------------
   Kennzahl-Kacheln zu zweit
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
    /* Zwei je Reihe statt einer: sechs Kacheln sind dann drei statt sechs
       Bildschirmhoehen-Achtel. Eine ungerade letzte Kachel nimmt die ganze
       Reihe, damit keine allein in der Ecke steht. */
    .statgrid,
    .statgrid:has(> :nth-child(4):last-child),
    .statgrid:has(> :nth-child(6):last-child) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
    }

    .statgrid > :last-child:nth-child(odd) {
        grid-column: 1 / -1;
    }

    .statgrid > .card {
        padding: 14px;
    }

    /* 18 px: „101.500,00 €" passt damit in eine halbe Kachel, bei 20 px
       brach das Euro-Zeichen in die naechste Zeile. */
    .stat__value {
        font-size: 18px;
        line-height: 1.25;
        overflow-wrap: anywhere;
    }
}

@media (max-width: 340px) {
    .statgrid,
    .statgrid:has(> :nth-child(4):last-child),
    .statgrid:has(> :nth-child(6):last-child) {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* --------------------------------------------------------------------------
   Monatsgitter: Punkte statt Text
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
    /* In 50 px breiten Zellen ist kein Titel lesbar („M…"). Ein Termin wird
       zum farbigen Strich in seiner Terminfarbe; lesen tut man ihn in der
       Tages- bzw. Wochenansicht, und dorthin fuehrt jetzt die GANZE Zelle,
       nicht nur die 8 px breite Tageszahl. */
    .cal__weekday {
        padding: 8px 4px;
        text-align: center;
        font-size: 12px;
    }

    .cal__day {
        position: relative;
        min-height: 64px;
        padding: 4px 3px;
        gap: 3px;
    }

    .cal__daynum {
        justify-content: center;
        font-size: 13px;
    }

    /* Month sheet only: the week view (`.woche`) has room for who is absent
       and which holiday it is — on the phone that is what fitters read. */
    .cal .cal__holiday,
    .cal .cal__absent {
        display: none;
    }

    .cal__daylink::after {
        content: "";
        position: absolute;
        inset: 0;
    }

    .cal .cal__event {
        height: 6px;
        padding: 0;
        border-left: 0;
        border-radius: 3px;
        font-size: 0;
        background: var(--accent);
    }

    .cal .cal__event > * {
        display: none;
    }

    .cal .cal__event--wartung { background: var(--signal-orange); }
    .cal .cal__event--termin { background: var(--signal-green); }
    .cal .cal__event--sonstiges { background: var(--border-strong); }
    .cal .cal__event--angebot { background: var(--signal-green); }
    .cal .cal__event--besprechung { background: var(--text-dim); }
    .cal .cal__event--kundendienst { background: var(--signal-blue); }
    .cal .cal__event--notdienst { background: var(--signal-red); }
    .cal .cal__event--reklamation { background: var(--signal-orange); }
    .cal .cal__event.cal__event--aufgabe { background: var(--text-dim); }
    .cal .cal__event--erledigt { opacity: 0.45; }

    /* Wo die Zelle zum Tag fuehrt, gehoert der Tipp ihr — ein 6-px-Strich
       ist kein Ziel. Im Projektkalender gibt es keinen Tageslink, dort
       bleibt der Strich der Link in die Akte. */
    .cal__day:has(.cal__daylink) .cal__event,
    .cal__day:has(.cal__daylink) .cal__more {
        pointer-events: none;
    }

    .cal__more {
        font-size: 11px;
        line-height: 1;
        text-align: center;
    }
}
