/* kata – Entwurf „Raster". Nur Systemschriften, keine externen Dateien.
   Alle Farben und Masse als Variablen: die Einstellungen (Stufe 2) sollen später nur Werte
   ändern, nicht CSS. Herleitung der Palette: ARCHITEKTUR.md → 6.
   Bewusst NUR dunkel – das ist die gewünschte Optik; ein zweiter Farbsatz für hell wäre
   doppelte Arbeit an einer Entwurfsseite. */

:root {
  --grund: #17181a;
  --karte: #212327;
  --linie: #35383d;
  --text: #eceded;
  --leise: #9b9ea3;
  --akzent: #b4682f;
  --akzent-hell: #cd7f45;
  --akzent-dunkel: #7d4620;

  /* ---- Breitenregel (ARCHITEKTUR.md → 3) ----
     Diese Zahl ist die EINE Quelle der Spaltenbreite. JS baut daraus `--spalten`; der
     Zieh-Griff am Desktop ändert nichts anderes als sie. */
  --breit: 9.5rem;      /* alle sieben Tage gleich – seit Job 118 kein schmales Wochenende mehr */
  --zeit: 3.4rem;       /* Uhrzeit-Spalte links, dehnt sich nie */
  --halb: 1.25rem;      /* Höhe einer halben Stunde → Stunde = 2 × --halb */

  /* ---- Spaltenflächen (ab v0.0.9.0) ----
     Die Wochenfarben (sechs Töne im Umlauf) sind RAUS, Jogi 13.8.: Farbe kann nur EINE Sache
     bedeuten, und sie wird für den Kalender gebraucht (ARCHITEKTUR.md → 4). Die Woche zeigt
     jetzt ein Trenner an, die Fläche gehört der Tagesart.
     Werktag hell, Wochenende dunkler – genau Jogis Formulierung. */
  --werktag: #3c4147;         /* Grundfläche einer Spalte – deutlich heller (Jogi, 13.8.) */
  --trenner: var(--akzent);   /* senkrechter Strich vor der ersten sichtbaren Spalte der Woche */

  /* ⚠️ Eigene Linienfarbe fürs Raster. `--linie` ist auf den DUNKLEN Flächen (Kopfzeile,
     Leiste, Karten) gedacht; auf der jetzt hellen Spaltenfläche wäre sie fast unsichtbar –
     Stundenlinien und Spaltengrenzen verschwänden. Deshalb zwei Werte statt einem. */
  --gitter: #565b62;

  /* ⚠️ Rot ist die erste Farbe ausserhalb der Palette und bedeutet GENAU eine Sache: „jetzt"
     (Job 130, Jogi 16.8.). Orange war schon dreifach vergeben – Wochen-Trenner, „heute" im
     Spaltenkopf, Termine –, eine vierte Bedeutung im selben Ton wäre Matsch geworden. */
  /* ⚠️ Farbe ALLER Schliessen-X, an EINER Stelle (Jogi, 17.8.: „ich möchte später für alle
     Schliessen-X eine gemeinsame Farbe (dunkelrot) definieren"). Vorerst so leise wie die
     übrigen Nebenzeichen – wird daraus Dunkelrot, ändert sich genau diese Zeile.
     ⚠️ NICHT `--jetzt` mitbenutzen: das Rot des Jetzt-Zeigers bedeutet genau eine Sache. */
  --schliessen: var(--leise);
  --schliessen-hell: var(--text);

  --jetzt: #e0483c;
  /* Die Höhenmarke über FREMDE Tage (Job 138, Jogi 17.8.) sagt „so weit ist der Tag", nicht
     „jetzt" – nur das durchgezogene Rot in der Spalte „heute" behauptet den Zeitpunkt. Ohne diese
     Trennung stünde eine „jetzt"-Linie mitten im 25. August.
     ⚠️ Sie ist **orange**, nicht blassrot (Jogi, 17.8.): damit gehört Rot in kata ausschliesslich
     dem „jetzt", und die Marke steht in der Palette, in der alles andere steht. Verwechselbar ist
     sie nicht – Termine sind Flächen, der Wochen-Trenner steht senkrecht, diese Linie liegt
     waagrecht und gestrichelt über allem. */
  --jetzt-marke: rgba(205, 127, 69, .5);

  --kal-h: 26rem;   /* Höhe des Stundenbereichs – der Teiler schreibt hier hinein */

  /* Arbeitszeit dunkler, Randstunden heller (ARCHITEKTUR.md → 6).
     Beide Schleier deutlich aufgehellt (Jogi, 13.8.): der schwarze Schleier über der Arbeitszeit
     zog die ganze Fläche wieder nach unten, die eben erst heller geworden war. */
  --arbeit: rgba(0, 0, 0, .08);
  --frei: rgba(255, 255, 255, .08);

  --navi-breit: 15rem;
  --navi-streifen: 2.9rem;
  --kopf-h: 3rem;
  --fuss-h: 1.6rem;   /* Fuß-Statuszeile – geht in die Höhe der Bühne ein */
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--grund); color: var(--text);
  overflow-x: hidden;      /* waagrecht scrollt der Wagen, nie die Seite */
}
button { font: inherit; color: inherit; cursor: pointer; }

/* ---------- Kopfzeile (wie duundi: Burger · Name · Nummer · Platz · Nutzer) ---------- */
/* ⚠️ `center`, nicht `baseline`: mit Grundlinien-Ausrichtung sass der Burger (ein Knopf mit
   Innenabstand) tiefer als der Schriftzug – der stand dann sichtbar ÜBER ihm (Jogi, 13.8.). */
#kopf {
  display: flex; align-items: center; gap: .6rem;
  height: var(--kopf-h);
  padding: 0 calc(.7rem + env(safe-area-inset-right, 0px))
           0 calc(.7rem + env(safe-area-inset-left, 0px));
  background: var(--karte); border-bottom: 1px solid var(--linie);
  position: sticky; top: 0; z-index: 20;
}
/* Das Symbol nur so hoch wie der Schriftzug – es soll die Kopfleiste nicht auseinanderdrücken
   (Jogi, 13.8.: „nicht zu hoch, sondern passend"). Die abgerundete Ecke bringt die Datei mit.
   Seit Job 116 ist es eine Schaltfläche (Navileiste umschalten) – daher der Knopf-Rückbau. */
.marke {
  flex: none; display: block; margin-right: -.15rem;
  background: none; border: 0; padding: 0; line-height: 0; cursor: pointer;
  border-radius: .35rem;
}
.marke img { height: 1.5rem; width: 1.5rem; display: block; }
.marke:hover { background: #ffffff12; }
/* Nur DIESES Päckchen richtet an der Grundlinie aus – die Nummer sitzt damit auf der
   Bodenlinie von „kata", während der Burger daneben mittig bleibt. */
.wortmarke { display: flex; align-items: baseline; gap: .45rem; }
#kopf h1 { font-size: 1.15rem; margin: 0; letter-spacing: .02em; }
#kopf h1::first-letter { color: var(--akzent-hell); }
.burger {
  background: none; border: 0; font-size: 1.2rem; padding: .2rem .35rem;
  border-radius: .3rem; line-height: 1;
}
.burger:hover { background: #ffffff12; }
.build { color: var(--leise); font-size: .78rem; }
.fuell { flex: 1; }
.wer { color: var(--leise); font-size: .85rem; }

/* ---------- Fuß-Statuszeile ----------
   Klebt unten und ist immer da – sie ist der Ort, an dem in Stufe 3 der Abgleich-Zustand steht.
   Eine Zeile, nichts umbricht: bei wenig Platz wird abgeschnitten, nicht umgebrochen, sonst
   wüchse die Zeile und die Rechnung oben (`--fuss-h`) stimmte nicht mehr. */
/* ⚠️ Sicherheitsabstand unten (Job 115): als INSTALLIERTE App reicht die Seite bis an den
   Bildschirmrand, und am iPhone liegt dort der Home-Balken über allem. Ohne den Zuschlag läge
   die Fußzeile darunter. Der Zuschlag muss an beiden Stellen stehen – hier und in der Rechnung
   für `#buehne` –, sonst stimmt die Höhe wieder nicht. Ausserhalb einer installierten App ist
   `env(...)` schlicht 0. */
/* ---------- Fuß-Statuszeile ----------
   ⚠️ Seit v0.1.12.1 waagrecht WISCHBAR statt abgeschnitten (Jogis Versuch, 15.8.).
   Vorher stand hier `overflow: hidden` und dazu eine Regel, die das rechte Feld am schmalen
   Schirm ganz ausblendete („für die dritte Auskunft ist kein Platz"). Das stammte aus der Zeit,
   als dort nur „nur auf diesem Gerät" stand – seit Job 124 steht dort der Zustand des
   Abgleichs, und der ist ausgerechnet am Handy der wichtigste.
   Gemessen bei einer Woche im 390-px-Rahmen: links 201 px, Mitte 242 px, rechts 134 px –
   zusammen 577 von 390. Es passt also nicht, und zwar deutlich. */
.fuss {
  display: flex; align-items: center; gap: .4rem;
  height: calc(var(--fuss-h) + env(safe-area-inset-bottom, 0px));
  /* ⚠️ RECHTS kein Polster mehr am Behälter – ein rechtes Padding wird beim waagrechten
     Rollen am Ende verschluckt (der Inhalt hört bündig an der Kante auf). Es sitzt statt
     dessen am letzten Kind, dann gilt es in beiden Fällen. */
  padding: 0 0
           env(safe-area-inset-bottom, 0px)
           calc(.7rem + env(safe-area-inset-left, 0px));
  background: var(--karte); border-top: 1px solid var(--linie);
  font-size: .7rem; color: var(--text);
  white-space: nowrap;
  overflow-x: auto; overflow-y: hidden;
  /* Keine Rollleiste: die Zeile ist rund 20 px hoch, eine Leiste darin verdeckte den Text. */
  scrollbar-width: none;
}
.fuss::-webkit-scrollbar { display: none; }
/* ⚠️ Nichts darf schrumpfen. Ohne das quetscht Flex die Felder auf die Behälterbreite zusammen
   und schneidet ihren Text ab – dann gäbe es gar nichts zu wischen. */
.fuss > * { flex: 0 0 auto; }
.fuss .leise { color: var(--leise); }
/* Der Abgleich-Zustand ist seit v0.1.28.0 ein KNOPF (Jogi, 17.8.: „wenn man draufklickt, soll es
   abgleichen"). Er soll dabei aussehen wie vorher der Text – kein Rahmen, keine Fläche –, nur
   Zeiger und Aufhellen verraten, dass man ihn drücken kann. Am Handy gibt es kein Überfahren;
   dort verrät es erst der Tipper, und das ist unvermeidlich. */
.fuss-knopf {
  background: none; border: 0; font: inherit; padding: 0;
  text-align: right; cursor: pointer;
}
.fuss-knopf:hover { color: var(--text); text-decoration: underline; }
.fuss .fuell { flex: 1 1 auto; min-width: 0; }
#fuss-daten { padding-right: calc(.7rem + env(safe-area-inset-right, 0px)); }

/* ---------- Offline-Hinweis (Job 150) ----------
   Links unten, in dem Feld, das seit Job 137 bewusst leer stand („Platz für Späteres", Regel 18).
   Er sagt, warum sich am anderen Gerät gerade nichts tut – sonst hielte man den stehengebliebenen
   Abgleich für einen Fehler. Zurückhaltend in `--leise`: eine Feststellung, keine Warnung. */
#fuss-links:empty { display: none; }
.netz-weg { color: var(--leise); }
.netz-weg::before {
  content: ""; display: inline-block; vertical-align: middle;
  width: .45rem; height: .45rem; margin-right: .35rem;
  border-radius: 50%; background: var(--leise);
}

/* ---------- Ladehinweis (Job 150) ----------
   Steht fest im HTML (siehe dort) und deckt die Fläche, bis der Kalender gezeichnet ist. Er ist
   vor allem im ZÄHEN Netz zu sehen: ohne Netz greift die Kopie sofort, dann blitzt er nur auf.
   ⚠️ `.laden[hidden]` gehört mit in die `display: none`-Zeile der Regel 16 – eine eigene
   `display`-Regel sticht das eingebaute `hidden` sonst aus, und der Hinweis bliebe für immer
   über der App liegen. */
.laden {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  background: var(--grund); color: var(--leise); font-size: .85rem;
}
.laden[hidden] { display: none; }
/* Der Ring ist gezeichnet, keine Datei und kein Emoji – wie Glocke, Pin und der Gross-Schalter
   (auf s01 fehlt die Schrift für Sonderzeichen). */
.laden-ring {
  width: 1.1rem; height: 1.1rem; border-radius: 50%;
  border: 2px solid var(--linie); border-top-color: var(--akzent);
  animation: laden-dreh .8s linear infinite;
}
@keyframes laden-dreh { to { transform: rotate(360deg); } }
/* Wer Bewegung im System abgestellt hat, bekommt einen ruhenden Ring statt eines Karussells. */
@media (prefers-reduced-motion: reduce) { .laden-ring { animation: none; } }

/* ---------- Bühne: Leiste + Tafel nebeneinander ---------- */
/* ⚠️ Die Fußzeile MUSS hier abgezogen werden. Steht sie nicht in der Rechnung, schiebt sie das
   untere Ende der Bühne aus dem Bild – am Handy verschwindet dann die letzte Aufgabenzeile
   hinter dem Fenster­rand, ohne dass irgendetwas scrollt. */
#buehne {
  display: flex; align-items: stretch;
  height: calc(100dvh - var(--kopf-h) - var(--fuss-h) - env(safe-area-inset-bottom, 0px));
}

/* ---------- Navileiste, drei Zustände ----------
   angepinnt  → im Fluss, nimmt festen Platz, Breite ziehbar
   Streifen   → im Fluss, schmal, nur Symbole
   weg        → gar nicht da
   Nicht angepinnt legt sie sich beim Öffnen ÜBER die Kalenderansicht (`.navi--ueber`),
   damit das Raster darunter seine Breite behält. */
.navi {
  background: var(--karte); border-right: 1px solid var(--linie);
  display: flex; flex-direction: column; min-height: 0;
  position: relative; flex: none;
}
/* Angeheftet: die Leiste nimmt eigenen Platz, der erste Tag steht RECHTS daneben statt
   hinter ihr (Jogi, 13.8.). `min(…, 55vw)` ist die einzige Rücksicht auf schmale Schirme –
   kein zweiter Zustand, nur eine Obergrenze. */
.navi--pin { width: min(var(--navi-breit), 55vw); }
.navi--pin .streifen { display: none; }

.navi--streifen { width: var(--navi-streifen); }
.navi--streifen .navi-inhalt { display: none; }

.navi--weg { display: none; }

/* Überliegende Fassung: volle Leiste, schwebend, ohne dem Raster Platz zu nehmen –
   der erste Tag steckt dann hinter ihr. */
.navi--ueber {
  display: flex; width: min(var(--navi-breit), 80vw);
  position: fixed; top: var(--kopf-h); bottom: 0; left: 0; z-index: 15;
  box-shadow: 0 0 24px rgba(0, 0, 0, .55);
}
.navi--ueber .streifen { display: none; }
.navi--ueber .navi-inhalt { display: block; }

.schleier {
  display: none; position: fixed; inset: var(--kopf-h) 0 0 0; z-index: 14;
  background: rgba(0, 0, 0, .45);
}
.schleier--an { display: block; }

.streifen { display: flex; flex-direction: column; align-items: center; gap: .3rem; padding: .5rem 0; }
.sym {
  width: 2rem; height: 2rem; border: 0; border-radius: .35rem;
  background: none; color: var(--leise); font-size: 1rem;
}
.sym:hover { background: #ffffff12; color: var(--text); }

.navi-inhalt { padding: .6rem .7rem; overflow-y: auto; }
/* `.navi-kopf` und `.navi-titel` („TAGE") sind mit v0.1.25.0 entfallen (Jogi, 17.8.): die Leiste
   zeigt einen Monatskalender, das sagt sie selbst, und Pin und « sitzen jetzt in der
   „heute"-Zeile. Damit beginnt die Leiste gleich mit dem, was man bedient. */
.klein { background: none; border: 1px solid var(--linie); border-radius: .3rem; padding: .1rem .4rem; color: var(--leise); }
.klein:hover { border-color: var(--akzent); color: var(--text); }

.schnellwahl { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; margin-bottom: .7rem; }
/* Zwei Zeilen seit Job 137 – die erste („heute" + Hilfe-Symbol) rückt eng an die zweite. */
.schnellwahl.erste { margin-bottom: .35rem; }
.gruppe-titel { color: var(--leise); font-size: .75rem; }
/* ⚠️ Auch hier nur die Wahl-Knöpfe: Pin und « stehen seit v0.1.25.0 in derselben Zeile und
   bekämen sonst deren Fläche und Mindestbreite (dieselbe Falle wie beim Klick in app.js). */
.schnellwahl button[data-wahl] {
  background: #ffffff0d; border: 1px solid var(--linie); border-radius: .3rem;
  padding: .22rem .5rem; font-size: .8rem; min-width: 1.9rem;
}
.schnellwahl button[data-wahl]:hover { border-color: var(--akzent); }

.monat-kopf { display: flex; align-items: center; justify-content: space-between; margin-bottom: .3rem; }
.monat-kopf button { background: none; border: 0; padding: .1rem .5rem; font-size: 1.1rem; color: var(--leise); border-radius: .3rem; }
.monat-kopf button:hover { background: #ffffff12; color: var(--text); }
#monat-name { font-size: .9rem; }

/* Monatsgitter: 1 schmale Spalte für den Wochen-Knopf, dann 7 Tage.
   `touch-action: none`, damit der Finger einen Bereich ziehen kann, statt die Leiste zu rollen. */
.monat-gitter { display: grid; grid-template-columns: 1.1rem repeat(7, 1fr); gap: 1px;
                touch-action: none; user-select: none; }
.monat-gitter .wtag { text-align: center; font-size: .68rem; color: var(--leise); padding: .15rem 0; }
.monat-gitter .woche-knopf {
  background: none; border: 0; color: #ffffff35; font-size: .7rem; padding: 0;
}
.monat-gitter .woche-knopf:hover { color: var(--akzent-hell); }
.monat-gitter .tag {
  border: 0; background: none; border-radius: .25rem;
  padding: .25rem 0; font-size: .8rem; color: var(--text); text-align: center;
}
.monat-gitter .tag:hover { background: #ffffff14; }
.monat-gitter .tag.fremd { color: #ffffff30; }        /* Nachbarmonat */
.monat-gitter .tag.heute { outline: 1px solid var(--akzent); }
.monat-gitter .tag.gewaehlt { background: var(--akzent-dunkel); color: #fff; }
/* Vorschau während des Zugs – noch nicht gesetzt, nur angezeigt. */
.monat-gitter .tag.vorschau { background: var(--akzent); color: #fff; }

/* `.navi-fuss` ist mit Job 137 entfallen – darin stand nur die Zeile „8 von höchstens 32 Tagen",
   und die ist auf Jogis Wunsch in die Hilfe gewandert (`hilfe.html#tage`). */
.zahl { font-size: .8rem; color: var(--leise); display: block; }
.zahl input {
  width: 3.2rem; background: var(--grund); color: var(--text);
  border: 1px solid var(--linie); border-radius: .3rem; padding: .15rem .3rem; font: inherit; font-size: .8rem;
}
.hinweis { color: var(--leise); font-size: .72rem; margin: .4rem 0 0; }
.leise { color: #ffffff45; }
.schalter { display: flex; align-items: center; gap: .35rem; font-size: .8rem;
            color: var(--leise); margin-top: .4rem; cursor: pointer; }
.schalter input { accent-color: var(--akzent); }
/* Der Pin-Knopf zeigt, ob die Leiste hängt oder schwebt. */
/* Der Pin (ab v0.1.29.1 eine gezeichnete Nadel, Jogi 17.8.: „dezenter, das Rot braucht es
   nicht", und gleich hoch wie das „?"). Angeheftet: gerade und orange. Schwebend: schräg und
   in derselben Farbe wie „?" und « – also unauffällig, bis er wirklich hält.
   ⚠️ Gedreht wird das ZEICHEN, nicht der Knopf: sonst stünde der Rahmen schief. */
#pin, #schmal {
  /* Dieselbe Höhe wie `.hilfe-knopf` – die drei stehen nebeneinander und sollen eine Linie
     bilden (Jogi, 17.8.: „zu niedrig"). */
  height: 1.35rem; padding: 0 .3rem;
  display: inline-flex; align-items: center; justify-content: center;
}
#pin { width: 1.35rem; padding: 0; }
#pin .pin-zeichen {
  display: block;
  transition: transform .12s ease;
}
#pin[aria-pressed="true"] { color: var(--akzent-hell); border-color: var(--linie); }
#pin[aria-pressed="false"] { color: var(--leise); }
#pin[aria-pressed="false"] .pin-zeichen { transform: rotate(38deg); }

/* Zieh-Griff der Leistenbreite – nur am Desktop (feiner Zeiger). */
.navi-griff { display: none; }
@media (pointer: fine) {
  .navi--pin .navi-griff {
    display: block; position: absolute; top: 0; right: -3px; bottom: 0; width: 6px;
    cursor: col-resize; z-index: 2;
  }
  .navi--pin .navi-griff:hover { background: var(--akzent); opacity: .6; }
}

/* ---------- Tafel: Stunden oben, Aufgaben unten, ziehbarer Teiler dazwischen ---------- */
#tafel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }

/* ⚠️ `scrollbar-gutter: stable` an BEIDEN Fenstern: sonst hat das eine eine senkrechte
   Rollleiste und das andere nicht – dann sind die Fenster verschieden breit, und im
   Dehn-Fall (Breitenregel) fielen die Aufgabenspalten um genau diese Leistenbreite
   neben die Kalenderspalten. */
.rollfenster { overflow: auto; scrollbar-gutter: stable; }
#kal-fenster { height: var(--kal-h); flex: none; }
#auf-fenster { flex: 1; min-height: 0; }

/* Aufgaben zugeklappt → die Stunden bekommen den ganzen Platz. */
#tafel.ohne-aufgaben #auf-fenster { display: none; }
#tafel.ohne-aufgaben #kal-fenster { height: auto; flex: 1; }

.teiler {
  flex: none; display: flex; align-items: center; gap: .5rem;
  padding: .15rem .5rem; background: var(--karte);
  border-top: 1px solid var(--linie); border-bottom: 1px solid var(--linie);
  cursor: row-resize;
  touch-action: none;   /* am Handy zieht der Finger den Teiler, statt die Seite zu rollen */
}
.teiler button {
  background: none; border: 0; color: var(--leise); font-size: .8rem;
  text-transform: uppercase; letter-spacing: .07em; padding: .15rem .3rem; border-radius: .3rem;
  cursor: pointer;
}
.teiler button:hover { color: var(--text); background: #ffffff12; }
.teiler .pfeil { display: inline-block; transition: transform .12s; }
#tafel.ohne-aufgaben .pfeil { transform: rotate(-90deg); }
.teiler .hinweis { margin: 0; }
.teiler-griff { color: #ffffff40; letter-spacing: .2em; font-size: 1rem; line-height: 1; }
.teiler:hover .teiler-griff { color: var(--akzent-hell); }
body.zieht-hoehe { cursor: row-resize; user-select: none; }

/* min-content = Summe der festen Spaltenbreiten.
   ⚠️ Das ist die ganze Breitenregel: passt die Summe NICHT ins Fenster, wächst der Wagen auf
   min-content und der Scroller scrollt waagrecht; passt sie hinein, bleibt der Wagen bei
   100 % und die fr-Anteile in `--spalten` dehnen die Spalten PROPORTIONAL zu ihrer festen
   Breite (Werktag 9.5 → 9.5fr, Wochenende 4.6 → 4.6fr). Ein Layout-Pfad für Handy, Browser
   und Desktop – kein zweiter Modus. */
.wagen { min-width: var(--mindest, 150px); }

/* Zeilenzahl und Lage der Arbeitszeit rechnet `setzeStundenraster()` aus – hier stehen nur
   Rückfallwerte für den Fall, dass das Skript noch nicht gelaufen ist. */
/* Drei Bänder: Kopfzeile (Datum), Ganztages-Streifen, dann die Halbstunden.
   ⚠️ Der Streifen ist `auto` hoch – ohne ganztägige Termine legt JS dort gar keine Zellen an,
   die Zeile ist dann 0 hoch und niemand sieht sie (Job 120). */
.kalender {
  display: grid;
  grid-template-columns: var(--spalten);
  grid-template-rows: auto auto repeat(var(--zeilen, 48), var(--halb));
}

/* Uhrzeit-Spalte bleibt beim Waagrecht-Scrollen stehen (am Handy ist das der Normalfall),
   die Tages-Kopfzeile beim Senkrecht-Scrollen. Die Ecke klebt in beide Richtungen und liegt
   deshalb am höchsten. */
.eck, .uhr, .auf-kopf, .auf-schild {
  position: sticky; left: 0; z-index: 3; background: var(--grund);
}
.eck, .auf-kopf { top: 0; z-index: 6; }
.eck { grid-column: 1; grid-row: 1; border-bottom: 1px solid var(--gitter); }
.uhr {
  grid-column: 1; font-size: .7rem; color: var(--leise);
  padding-right: .4rem; text-align: right;
  border-top: 1px solid var(--gitter);
  display: flex; align-items: flex-start; justify-content: flex-end;
}
/* ⚠️ Die Zahl sitzt MITTIG AUF ihrer Linie (`v0.1.31.4`, Jogis Fund vom 17.8.). Vorher begann sie
   an der Linie und hing 16 px nach unten weg – ihre Mitte lag damit 9 px unter der Linie, also
   umgerechnet 14 Minuten. Beim Vergleichen nimmt das Auge die Mitte der Zahl, und deshalb sah der
   Jetzt-Zeiger (der auf die Minute richtig steht) rund eine Viertelstunde zu früh aus. Nicht die
   Uhr war falsch, sondern ihr Massstab. So macht es auch der Google-Kalender.
   ⚠️ `.uhr-erste` ist ausgenommen – die oberste Zahl ragte sonst über den Rasteranfang hinaus. */
.uhr .hh, .uhr .mm { transform: translateY(-50%); background: var(--grund); }
.uhr.uhr-erste .hh, .uhr.uhr-erste .mm { transform: none; }
/* ⚠️ Der eigene Hintergrund ist Pflicht, kein Feinschliff: die Rasterlinie ist der `border-top`
   DIESER Zelle und liefe sonst mitten durch die Ziffern – das sah aus wie durchgestrichen. So
   bleibt links davon ein kurzer Strich stehen (die Marke) und die Zahl selbst bleibt frei. */
.uhr .hh { padding-left: .18rem; }

/* ---- Schmaler Schirm: nur die Stunde (ab v0.1.3.0, Jogi 14.8.) ----
   Am iPhone im Hochformat passt eine ganze Woche ins Bild – dort zählt jeder Pixel Spaltenbreite.
   „:00" sagt dann nichts, was die Zeile nicht schon sagt, und kostet gut 24 px.
   ⚠️ An der FENSTERBREITE festgemacht, nicht am Hochformat: ein iPad im Hochformat hat reichlich
   Platz, ein schmales Fenster am Rechner dagegen dasselbe Problem. Dieselbe Grenze wie bei der
   Fußzeile (dort verschwindet „nur auf diesem Gerät").
   ⚠️ Der volle Text steht weiter im HTML – nur die Anzeige entscheidet hier. Beim Drehen des
   Geräts passt sich das damit von selbst an, ohne dass das Raster neu gezeichnet werden muss. */
@media (max-width: 30rem) {
  :root { --zeit: 1.9rem; }
  .uhr { padding-right: .25rem; }
  .uhr .mm { display: none; }
}

/* ⚠️ Innenabstand knapp halten: Polsterung + Rahmen sind die HARTE Untergrenze eines
   Gitter-Kindes. Mit .4rem je Seite konnte der Kopf nicht unter ~16 px – bei schmalen Spalten
   ragte er heraus, und das Fenster bekam eine Rollleiste, obwohl die Spalten längst passten
   (Jogi, 13.8.: „ab dem Zeitpunkt, wo sie schmal werden sollten, kommt der Scrollbalken"). */
.tagkopf {
  grid-row: 1; padding: .3rem .25rem .35rem; border-bottom: 1px solid var(--gitter);
  border-left: 1px solid var(--gitter); background: var(--tf, var(--werktag)); overflow: hidden;
  position: sticky; top: 0; z-index: 2;
  box-shadow: var(--s-trenner, 0 0 #0000);
}
.tagkopf .wtag { font-size: .72rem; color: var(--leise); }
.tagkopf .dat { font-size: .95rem; white-space: nowrap; overflow: hidden; }
/* ---------- Randzeiger im Spaltenkopf (Job 121) ----------
   „↑2" / „↓1": so viele Termine liegen ganz über bzw. unter dem sichtbaren Ausschnitt.
   ⚠️ Beide Knöpfe sind `hidden`, solange nichts draussen liegt – der Kopf bleibt dann genau so
   hoch wie vorher. Die Zeile darf NICHT umbrechen, sonst wüchse die Kopfzeile beim Rollen und
   das ganze Raster ruckte. */
.tagkopf .zeiger {
  display: flex; justify-content: space-between; gap: .15rem;
  height: 1rem; overflow: hidden; white-space: nowrap;
}
/* ⚠️ Die Knöpfe tragen Polsterung, obwohl die Zahl winzig ist: ohne sie ist die Trefffläche
   rund 12 × 13 px und am Handy mit dem Daumen nicht zu erwischen. */
.tagkopf .zeiger button {
  background: none; border: 0; padding: 0 .25rem; cursor: pointer;
  font: inherit; font-size: .64rem; line-height: 1rem;
  color: var(--akzent-hell); opacity: .85;
}
.tagkopf .zeiger button:hover { opacity: 1; text-decoration: underline; }
.tagkopf .zeiger button[hidden] { display: none; }
.tagkopf.heute .zeiger button { color: #fff; }

.tagkopf.heute { background: var(--akzent-dunkel); }
.tagkopf.heute .wtag, .tagkopf.heute .dat { color: #fff; }

/* Die Spalte selbst: EIN Element je Tag über alle Stunden – Stundenlinien und die
   Arbeitszeit-Schattierung kommen aus Farbverläufen. 32 Spalten × 10 Stunden wären sonst
   320 Zellen; so sind es 32 Elemente (ARCHITEKTUR.md → 3). */
.spalte {
  grid-row: 3 / -1; border-left: 1px solid var(--gitter);   /* ab Zeile 3: über ihr der Ganztages-Streifen */
  background-color: var(--tf, var(--werktag));
  background-image:
    repeating-linear-gradient(to bottom,
      transparent 0, transparent calc(2 * var(--halb) - 1px),
      var(--gitter) calc(2 * var(--halb) - 1px), var(--gitter) calc(2 * var(--halb))),
    linear-gradient(to bottom,
      var(--frei) 0,
      var(--frei) calc(var(--arbeit-ab, 16) * var(--halb)),
      var(--arbeit) calc(var(--arbeit-ab, 16) * var(--halb)),
      var(--arbeit) calc(var(--arbeit-bis, 34) * var(--halb)),
      var(--frei) calc(var(--arbeit-bis, 34) * var(--halb)));
}
/* ---- Wochen-Trenner (ab v0.0.9.0) ----
   ⚠️ Als AUFLAGE gezeichnet (inset box-shadow), NICHT als Rahmen: Rahmen und Polsterung sind die
   harte Untergrenze eines Gitter-Kindes (die 150-px-Lehre aus v0.0.6.0, ARCHITEKTUR.md → 8).
   Ein 2-px-Rahmen verschöbe die Untergrenze bei jeder Wochengrenze; der Schatten kostet nichts.
   Weil „heute" ebenfalls einen inneren Schatten trägt, laufen beide über EINE Erklärung mit
   zwei Variablen – sonst überschriebe die eine Regel die andere. */
.spalte, .auf-zelle {
  box-shadow: var(--s-heute, 0 0 #0000), var(--s-trenner, 0 0 #0000);
}
.wo-trenner { --s-trenner: inset 2px 0 0 0 var(--trenner); }
.spalte.heute, .auf-zelle.heute { --s-heute: inset 0 2px 0 0 var(--akzent); }

/* Als `button`, nicht als `div`: ein Termin lässt sich antippen (ändern) und muss deshalb auch
   mit der Tastatur erreichbar sein. Die Knopf-Voreinstellungen werden dafür zurückgenommen. */
.termin {
  margin: 1px; padding: .1rem .2rem; border-radius: .25rem; overflow: hidden;
  background: var(--akzent-dunkel); border: 0; border-left: 3px solid var(--akzent-hell);
  font-size: .75rem; line-height: 1.15; z-index: 1; min-width: 0;
  text-align: left; display: block; width: calc(100% - 2px);
  /* `relative` allein für die Glocke (Job 129) – ohne `top`/`left` verschiebt es nichts, es
     schafft nur den Bezugsrahmen, damit sie in der Ecke der KACHEL sitzt und nicht in der
     Ecke der Spalte. */
  position: relative;
}
/* ⚠️ Die Uhrzeit ist KLEIN und SCHMAL gesetzt (ab `v0.1.32.6`), und zwar mit Mitteln, die das
   Layout kennt: kleinere Schrift spart Höhe (→ 38), ein Hauch negativer Zeichenabstand Breite.
   `font-stretch: condensed` steht bewusst NICHT da – kata setzt `system-ui`, also je Gerät eine
   andere Schrift: Windows hätte einen schmalen Schnitt, Apple keinen, Android vielleicht. Die
   Uhrzeit wäre auf jedem Gerät anders breit, genau in der Kachel, die knapp passen muss.
   `tabular-nums` macht nicht schmäler, aber alle Ziffern gleich breit – damit stehen die Zeiten
   über die Spalten hinweg ruhig, statt bei jeder „1" zu zappeln. */
.termin .zeit {
  color: #ffffffb0; font-size: .62rem;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}

/* ---------- Termine im Stundenraster (Job 134) ----------
   Höhe, Versatz und Breite stehen INLINE am Element (`setzeTerminLage()`): sie hängen an der
   Minute und an der Zahl der Spuren, das kann kein Stylesheet wissen.
   ⚠️ Der linke Rand ist hier KEIN `border` mehr, sondern das Kind `.dauer` – nur so kann er
   kürzer sein als die Kachel und damit die wahre Länge eines kurzen Termins zeigen.
   ⚠️ Enge Zeilen und knappes Polster sind der Unterschied zwischen „Titelanfang lesbar" und
   „abgeschnittener Buchstabenrest": die flachste Kachel ist eine halbe Stunde, also rund 20 px. */
.termin.raster {
  border-left: 0; padding: .05rem .2rem; line-height: 1.05; margin: 0 1px;
}
/* ⚠️ `line-height: .9` ist KEIN Feinschliff, sondern der halbe Zwischenraum aus `v0.1.34.1`:
   die Zeilenbox des Titels schrumpft von 12,1 auf 10,4 px und gibt die Differenz an die Uhrzeit
   darunter ab. Der Titel steht IMMER einzeilig (`white-space: nowrap`, → unten), es kann also
   nichts kollidieren; die Buchstaben werden nicht kleiner, nur ihre Zeile enger. */
.termin.raster .titel { font-size: .72rem; line-height: .9; }

/* ---------- Der Titel läuft in die zweite Zeile weiter (Job 148, `v0.1.37.0`, Jogi 19.8.) ----
   Die zweite Zeile der Kachel hat seither DREI mögliche Belegungen (Einstellung „Zweite Zeile in
   der Termin-Kachel"): `mit-zeit` schreibt die Uhrzeit hinein, `titel-2z` gibt sie dem Titel,
   und ohne beide bleibt sie leer – das ist die Vorgabe und das Verhalten bis `v0.1.35.1`.
   ⚠️ POSITIVE Klasse, keine Verneinung: der Versuch aus `v0.1.36.0` hing an `:not(.mit-zeit)`
   und beschrieb damit einen von drei Zuständen über das Fehlen eines anderen. Mit drei
   Zuständen wäre das eine Falle – „leer" und „Titel" sind beide „nicht Uhrzeit".
   ⚠️ An Schrift, Größe, Zeilenhöhe und Polster ist NICHTS geändert (Jogi, 19.8.): derselbe Text
   in denselben Zeilen, nur ohne das Umbruch-Verbot aus `.termin .titel`.
   ⚠️ Zwei Zeilen, nicht „so viele wie passen": es geht um genau das eine Feld, das sonst die
   Uhrzeit belegt. Das Ganztags-Band trägt die Klasse nie. */
.termin.raster.titel-2z .titel {
  white-space: normal;
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2;
}

/* ---------- Uhrzeit in der Kachel: UNTER dem Titel, eng gesetzt (`v0.1.32.7`, Jogi 17.8.) ----
   ⚠️ Titel und Uhrzeit stehen UNTEREINANDER. Sie standen in `v0.1.32.6` kurz nebeneinander, weil
   zwei Zeilen rechnerisch nicht in eine 30-Minuten-Kachel passen (~23 px auf ~18 px). Jogi hat
   das verworfen, und zwar zu Recht: nebeneinander nahm die Uhrzeit dem Titel die BREITE – „Auto
   zu Toyota Mittelberger" wurde zu „Aut…", während „12:30–13:15" vollständig dastand. Von beidem
   ist der Titel das Wichtigere. Seine Ansage: „dann ist mir lieber, dass die Uhrzeit darunter ist
   und abgeschnitten ist."
   Darum wird hier nur noch geholt, was ohne Breitenverlust zu holen ist – rund 5 px:
     · kleinere Schrift (.68 → .62 rem)   ≈ 1 px
     · Zeilenhöhe 1.05 → 1                ≈ 0.5 px
     · Polster oben/unten weg             ≈ 1.6 px
   ⚠️ ZWISCHENRAUM statt Anschnitt (`v0.1.34.1`, Jogi 18.8.): die Uhrzeit war 2 px NACH OBEN
   gerückt und klebte damit am Titel. Nachgemessen lag der freie Platz nicht in der Mitte,
   sondern an den Rändern – 1,54 px über dem Titel, 1,46 px unter der Uhrzeit, 0,00 px dazwischen.
   Jetzt wird beides eingesammelt (Titel-Zeilenhöhe .9, Uhrzeit +1 px statt −2 px) und als
   **2,1 px Luft** zwischen Titel und Uhrzeit ausgegeben; die Kachel bleibt 19 px.
   ⚠️ Gemessen wird die TINTE, nicht die Textzeile: die Zeilenbox der Uhrzeit ragt weiter 2 px
   unten hinaus, die Ziffern selbst bleiben drin (0,18 px Reserve) – Ziffern haben keine
   Unterlängen. Wer hier `scrollHeight` prüft, misst das Falsche.
   ⚠️ Die Uhrzeit NICHT zusätzlich verkleinern, um Luft zu gewinnen: kleinere Ziffern sitzen
   mittig in ihrer kleineren Zeile, der Gewinn verteilt sich auf beide Ränder statt in die Lücke
   zu gehen (nachgemessen 18.8.: .56 rem bringt 0 px mehr Zwischenraum).
   ⚠️ Die Klasse steht nur bei gesetztem Haken (`mitZeit` in `macheTermin()`) – ohne Uhrzeit
   bleibt die Kachel unverändert. */
.termin.raster.mit-zeit { padding-top: 0; padding-bottom: 0; }
.termin.raster.mit-zeit .zeit { display: block; line-height: 1; margin-top: 1px; }
.termin.raster .dauer {
  position: absolute; left: 0; top: 0; width: 3px; min-height: 2px;
  background: var(--akzent-hell); border-radius: .25rem 0 0 .25rem; pointer-events: none;
}
/* ⚠️ Zweite Farbe ausserhalb der Palette – nach dem Rot des Jetzt-Zeigers (→ 21) das Blau für
   „kürzer als eine Viertelstunde" (Jogi, 17.8.). Sie steht nur am Balken, nie an der Kachel:
   Orange bleibt die Farbe der Termine. Hell genug, damit drei Pixel auf der braunen Kachel
   auffallen. */
.termin.raster .dauer.kurz { background: #5aa9e6; }

/* ---------- Ganztägige Termine (Job 120) ----------
   Eigenes Band zwischen Datum und Stundenraster. ⚠️ Es klebt beim Senkrecht-Rollen mit unter
   der Kopfzeile (`top: var(--kopf-h)`, von JS gesetzt) – sonst wäre der ganztägige Termin weg,
   sobald man zum Nachmittag rollt (Jogi, 14.8.). */
.ganztags-zelle {
  grid-row: 2; border-left: 1px solid var(--gitter);
  background: var(--tf, var(--werktag));
  position: sticky; top: var(--kopf-h, 3rem); z-index: 2;
  display: flex; flex-direction: column; gap: 1px;
  padding: 1px 0; min-width: 0;
  box-shadow: var(--s-trenner, 0 0 #0000);
  border-bottom: 1px solid var(--gitter);
}
.ganztags-eck {
  grid-column: 1; grid-row: 2;
  position: sticky; left: 0; top: var(--kopf-h, 3rem); z-index: 5;
  background: var(--grund); border-bottom: 1px solid var(--gitter);
}
/* Die Balken stapeln sich – bei drei ganztägigen Terminen wird das Band drei Zeilen hoch
   (Jogi, 14.8.: lieber wachsen als ein „+2 weitere" zum Aufklappen). */
/* ⚠️ `relative`, nicht `static` (Job 129): sonst hinge die Glocke am nächsten positionierten
   Vorfahren – das ist die klebende Band-Zelle – und säße bei drei gestapelten Terminen dreimal
   an derselben Stelle. Ohne `top`/`left` ändert `relative` am Stapel nichts. */
.termin.ganztags { position: relative; width: calc(100% - 2px); margin: 0 1px; }
.termin .titel { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Aufgaben ---------- */
.aufgaben { display: grid; grid-template-columns: var(--spalten); }
.auf-kopf { grid-column: 1; grid-row: 1; }
.auf-schild { grid-column: 1; grid-row: 2; font-size: .7rem; color: var(--leise); padding: .2rem .4rem; }
/* Die Datumszeile klebt oben: der Aufgabenbereich rollt jetzt für sich, und eine
   Aufgabenspalte ohne Datum ist wertlos. */
.auf-datum {
  grid-row: 1; font-size: .68rem; color: var(--leise);
  padding: .1rem .25rem; border-left: 1px solid var(--gitter);
  background: var(--tf, var(--werktag));
  overflow: hidden; white-space: nowrap;
  position: sticky; top: 0; z-index: 2;
  box-shadow: var(--s-trenner, 0 0 #0000);
}
.auf-datum.heute { color: var(--akzent-hell); }
/* ⚠️ `min-width: 0` hebt das automatische Mindestmass von Gitter-Kindern auf: sonst hielte
   das längste Wort einer Aufgabe die Spalte auf, und „alle Tage ins Fenster" bliebe genau in
   der Aufgabenzeile wirkungslos (die Stunden schrumpften, die Aufgaben nicht). */
.auf-zelle {
  grid-row: 2; min-width: 0; border-left: 1px solid var(--gitter);
  background: var(--tf, var(--werktag));
  padding: .15rem; min-height: 3.5rem; display: flex; flex-direction: column; gap: .15rem;
  overflow: hidden;   /* nichts darf seitlich aus der Spalte ragen */
  /* `relative` allein für den Einfüge-Strich beim Ziehen (Job 133) – ohne `top`/`left`
     verschiebt es nichts, es schafft nur den Bezugsrahmen. */
  position: relative;
}

/* `flex-wrap` + Mindestbreite für den Namen: in schmalen Spalten rutscht der „seit N T"-Merker
   in die nächste Zeile, statt den Namen auf null zu drücken (gesehen im Versuch „alle Tage ins
   Fenster": dort stand in der Spalte heute nur noch „seit 14 T"). */
.auf {
  display: flex; align-items: baseline; gap: .3rem; flex-wrap: wrap;
  background: #ffffff0d; border: 1px solid var(--gitter); border-radius: .25rem;
  padding: .15rem .25rem; font-size: .76rem; line-height: 1.2; text-align: left;
  width: 100%; min-width: 0;
}
.auf:hover { border-color: var(--akzent); }
.auf .name { flex: 1 1 4rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.auf.fertig { opacity: .55; }
.auf.fertig .name { text-decoration: line-through; }
/* „Seit N Tagen" ist der ganze Grund, warum Aufgaben NICHT physisch umdatiert werden
   (ARCHITEKTUR.md → 1) – der Merker muss auffallen. */
.auf.ueberfaellig { border-color: var(--akzent); background: #b4682f22; }
/* Die immer sichtbare leere Zeile am Ende jeder Aufgabenspalte (Job 136). Sie ist der sichtbare
   Teil der Klickfläche, die es vorher nur gab, solange die Spalte nicht voll war.
   ⚠️ `flex-shrink: 0`: in einer vollen Spalte drückte die Flex-Rechnung sie sonst auf null – genau
   dort, wo sie gebraucht wird. Und `min-height` statt `height`, damit sie mit der Schriftgrösse
   mitwächst. */
.auf-neu {
  flex: 0 0 auto; min-height: 1.15rem; border: 1px dashed var(--gitter); border-radius: .25rem;
  color: var(--leise); font-size: .7rem; line-height: 1.15; text-align: center; opacity: .55;
}
.auf-zelle:hover .auf-neu, .auf-zelle.markiert .auf-neu { opacity: 1; border-color: var(--akzent); }

/* ---------- Spaltenbreite ziehen – nur am Desktop (ARCHITEKTUR.md → 3) ---------- */
.breit-griff { display: none; }
@media (pointer: fine) {
  .breit-griff {
    display: block; position: absolute; top: 0; right: -3px; bottom: 0; width: 6px;
    cursor: col-resize; z-index: 4;
  }
  .breit-griff:hover { background: var(--akzent); opacity: .6; }
}
body.zieht { cursor: col-resize; user-select: none; }

/* Die Untergrenze hängt am GANZEN Raster, nicht an der einzelnen Spalte: die Spalten haben
   keine eigene Mindestbreite (`minmax(0, Xfr)`), der Wagen eine feste. Fenster breiter →
   alles teilt sich die Fensterbreite, nichts rollt. Fenster schmaler → der Wagen bleibt auf
   `--mindest` stehen und rollt, statt weiter zu quetschen. */

/* ---------- Dialog: anlegen · ändern · löschen (Job 112) ----------
   ⚠️ Handy zuerst (harte Regel 4): der Dialog dockt UNTEN an und nimmt die volle Breite – dort
   ist der Daumen. Am breiten Schirm wird er zu einer mittigen Karte. Ein Zustandsbild, kein
   zweiter Dialog: `dialog` bringt Hintergrund-Sperre und Esc von Haus aus mit, nachgebaut
   wäre das mehr Code und schlechter bedienbar. */
.dlg {
  border: 0; padding: 0; color: var(--text); background: var(--karte);
  width: 100%; max-width: 100%; margin: auto auto 0;
  border-radius: .8rem .8rem 0 0; box-shadow: 0 -8px 30px rgba(0, 0, 0, .6);
}
.dlg::backdrop { background: rgba(0, 0, 0, .55); }
.dlg form { display: flex; flex-direction: column; gap: .6rem; padding: .9rem 1rem 1rem; }
.dlg h2 { margin: 0 0 .2rem; font-size: 1rem; font-weight: 600; }
.dlg h2::first-letter { color: var(--akzent-hell); }

/* Kopfzeile eines Dialogs: Titel links, Schliessen-X rechts (Jogi, 17.8.).
   ⚠️ Der Titel behält seinen eigenen Abstand nach unten – die Zeile ändert nur die ANORDNUNG,
   nicht das Aussehen der Überschrift. */
.dlg-kopf { display: flex; align-items: flex-start; gap: .6rem; }
.dlg-kopf h2 { flex: 1 1 auto; }
/* ⚠️ EIN Bauteil für alle Schliessen-X (Jogi, 17.8.: „später für alle eine gemeinsame Farbe,
   dunkelrot"). Die Farbe steht deshalb in `--schliessen` ganz oben – dann ist es EINE Zeile,
   nicht ein Rundgang durch jeden Dialog. Bis dahin ist sie so leise wie die übrigen Nebenzeichen.
   ⚠️ Grosszügige Fläche (Regel 4, Handy zuerst): das Zeichen ist klein, die Trefferfläche nicht. */
/* ⚠️ EIN Bauteil für alle Schliessen-✕ (Dialog und Wecker-Karte, ab `v0.1.33.0`) – damit Jogis
   „irgendwann bekommen alle ✕ dieselbe Farbe (vermutlich dunkelrot)" wirklich EINE Zeile bleibt:
   `--schliessen` ganz oben. Neues ✕ irgendwo? Dann hier den Selektor erweitern, nicht kopieren. */
.dlg-x, .weck-x, .feld-x {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem; margin: -.25rem -.35rem 0 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: .4rem; background: none; cursor: pointer;
  font-size: 1.25rem; line-height: 1; color: var(--schliessen);
}
.dlg-x:hover, .weck-x:hover, .feld-x:hover { background: #ffffff12; color: var(--schliessen-hell); }
/* Das kleine × IM FELD, rechts hinter der Uhrzeit (Job 188, Jogi 3.9.: „rechts oben hinter der
   Uhrzeit. Aber klein. Platz genug ist ja da."). Es erbt Farbe und Verhalten vom Block darüber
   und ändert nur Grösse und Lage.
   ⚠️ **Am Aufbau des Feldes wird NICHTS geändert** – der `<input>` steht genau dort im `.feld`,
   wo er vor Job 188 stand, und das × liegt als absolut gesetztes Geschwister darüber. Zwei
   Anläufe sind daran gescheitert, dem Feld etwas mitzugeben: erst `padding-right` (`v0.1.40.1`),
   dann ein eigener Kasten um den `<input>` (`v0.1.40.2`) – beides am Rechner ohne jede Wirkung,
   am iPhone jedes Mal eine Zeile, die über den Schirm hinausragte (Jogis Funde vom 3.9.).
   **Lehre: an einem Datums- oder Zeitfeld bestimmt iOS die Breite, nicht das Stylesheet.** Wer
   dort etwas anbauen will, legt es DARÜBER und rührt das Feld selbst nicht an.
   ⚠️ Ausgerichtet wird an der UNTERKANTE (`bottom`), nicht über die Mitte: das `.feld` enthält
   auch die Beschriftung darüber, seine Mitte liegt also nicht in der Mitte des Eingabefeldes.
   Der Wert `.4rem` ist die halbe Differenz aus Feldhöhe (~2,4 rem) und × (1,6 rem).
   ⚠️ Kein Polster rechts: das × liegt in dem freien Raum, den ein Zeitwert im rund 190 px breiten
   Feld ohnehin lässt – genau Jogis „Platz genug ist ja da". */
.feld { position: relative; }
.feld-x {
  position: absolute; right: .15rem; bottom: .4rem;
  width: 1.6rem; height: 1.6rem; margin: 0; font-size: .95rem;
}
.feld .feld-x[hidden] { display: none; }
/* ⚠️ Riegel gegen Überlauf: ein Flex-Kind schrumpft von Haus aus NICHT unter die Eigenbreite
   seines Inhalts (`min-width: auto`). Ein Feld, das intern zu breit wird, schiebt sonst die ganze
   Zeile über den Schirm hinaus, statt selbst nachzugeben. */
.zeilen .feld { min-width: 0; }
/* ---- Zwei Felder, die sich die Zeile HART hälftig teilen (Job 188, `v0.1.40.5`) -------------
   ⚠️ Für „von / bis" und „fällig / Uhrzeit" reicht Flexbox NICHT. Ein natives Datums- oder
   Zeitfeld bringt am iPhone eine Eigenbreite mit, und in einer Flex-Zeile teilen sich zwei
   solche Felder den Platz nach ihren Eigenbreiten – das grössere nimmt sich mehr, das kleinere
   bekommt weniger. Vier Fassungen lang war das die Ursache, einmal in die eine Richtung
   („Uhrzeit zu breit"), nach `appearance: none` in die andere („Uhrzeit halb so gross").
   **Grid mit zwei `1fr`-Spalten teilt dagegen die ZEILE, nicht den Inhalt** – die Spalten sind
   gleich breit, ganz gleich, was in ihnen steht. `minmax(0, …)` nimmt ihnen zusätzlich die
   Untergrenze „so breit wie mein Inhalt", `overflow: hidden` hält ein trotzig breiteres
   Bedienelement in seiner Spalte. Damit KANN keine der beiden Fehlerrichtungen wiederkommen.
   ⚠️ Nur für Zeilen mit genau ZWEI gleichrangigen Feldern – „Tag + ganztägig" und
   „erledigt am + heute" haben ungleiche Glieder und bleiben bei Flex. */
.zeilen--halb {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start;
}
.zeilen--halb .feld { overflow: hidden; }
/* ⚠️ Chromes eigenes Uhr-Symbol sitzt genau dort, wo jetzt das × steht – zwei Zeichen
   übereinander. Es wird deshalb ausgeblendet; das Auswahlfenster geht weiterhin über einen
   Tipper ins Feld auf (und am Handy gab es das Symbol ohnehin nie). */
.dlg input[type="time"]::-webkit-calendar-picker-indicator { display: none; }

@media (min-width: 34rem) {
  .dlg { max-width: 26rem; margin: auto; border-radius: .8rem; }
}

.feld { display: flex; flex-direction: column; gap: .2rem; font-size: .78rem; color: var(--leise); }
/* Beschriftung mit „?" daneben (ab v0.1.28.0): das Fragezeichen soll neben dem Wort stehen und
   nicht über der ganzen Feldbreite mittig oder unten kleben. */
.feld-kopf { display: flex; align-items: center; gap: .35rem; }
.feld.waagrecht { flex-direction: row; align-items: center; gap: .45rem; }
.zeilen { display: flex; gap: .6rem; }
.zeilen .feld { flex: 1; }
/* ⚠️ Pflicht, kein Feinschliff (Job 140, Jogis Fund vom 17.8.): `display: flex` steht in einer
   EIGENEN Regel und sticht damit das eingebaute `[hidden] { display: none }` des Browsers aus.
   Ohne diese Zeile blieb „erledigt am" an jeder offenen Aufgabe sichtbar, obwohl `app.js` es
   längst verbarg – das sah aus wie ein Fehler in der Logik und war einer im Aussehen. */
.feld[hidden], .zeilen[hidden] { display: none; }
/* Drei sich ausschliessende Möglichkeiten stehen UNTEREINANDER offen da – kein Auswahlrad, das
   sich erst öffnen muss (Regel 4: Handy zuerst), und kein zweiter Haken, der die unsinnige
   Kombination „Uhrzeit UND Titel" erlaubte. Die Zeilen rücken ein, damit sie als Gruppe unter
   ihrer Überschrift lesbar sind. */
.feld.wahlgruppe > .feld.waagrecht { padding-left: .6rem; }
/* Knopf neben einem Feld („heute"): unten bündig mit dem Eingabefeld, nicht über dessen ganze
   Höhe gedehnt – die Beschriftung darüber macht das Feld höher als den Knopf. */
.zeilen--knopf { align-items: flex-end; }
.zeilen--knopf .klein { flex: 0 0 auto; padding: .45rem .6rem; }
/* Ein Kästchen mit Beschriftung („ganztägig") nimmt sich nur, was es braucht – gedehnt stünde es
   mitten im Nichts, weit weg von dem Feld, zu dem es gehört. Der kleine Abstand nach unten hebt
   es auf die Höhe des Eingabefeldes daneben (das Feld trägt seine Beschriftung darüber). */
.zeilen--knopf .feld.waagrecht { flex: 0 0 auto; padding-bottom: .55rem; }
/* Auskunft, kein Eingabefeld: das Anlegedatum lässt sich nicht ändern (Job 125). */
.feld-notiz { margin: 0; font-size: .72rem; color: var(--leise); opacity: .8; }
/* Vorgeschlagene Werte stehen blasser da als eingetippte (Jogi, 18.8.) – „fällig heute" oder
   „9:00–10:00" sähen sonst aus wie eine bewusste Eingabe. `app.js` setzt die Klasse und nimmt
   sie beim ersten Anfassen des Feldes wieder weg.
   ⚠️ Nur die Schriftfarbe, KEINE `opacity`: die legte sich auch über den Rahmen des Feldes, und
   ein halb sichtbarer Rahmen liest sich als Fehler, nicht als Vorschlag. */
input.vorgabe, select.vorgabe { color: var(--leise); }
/* Ein gesperrter Dialog-Teil (ab `v0.1.35.0`): der Erinnerungs-Bereich steht auch ohne Uhrzeit
   da, nur blass und unbedienbar. Versteckt fiel gar nicht auf, DASS es ihn gibt – der Grund
   steht jetzt in seiner Überschrift (Jogi, 18.8.). Das `disabled` an den Bedienelementen setzt
   `app.js`; hier steht nur das Aussehen. */
/* ⚠️ Deutlich blasser als die .5 bis `v0.1.39.3` (Job 188, Jogi 3.9.: „manchmal meint man, da
   stünde eine echte Uhrzeit drinnen"). Der GRUND muss trotzdem lesbar bleiben – `opacity` lässt
   sich von innen nicht zurückholen, darum bekommt die Überschrift die kräftigere Schriftfarbe. */
.teil.gesperrt { opacity: .3; }
.teil.gesperrt #f-erinn-kopf { color: var(--text); }
/* ⚠️ `font-size: 1rem` ist Pflicht, kein Geschmack: unter 16 px zoomt iOS beim Antippen eines
   Feldes in die Seite hinein und kommt nicht von selbst wieder heraus. */
.dlg input[type="text"], .dlg input[type="date"], .dlg input[type="time"],
.dlg select, .dlg textarea {
  font: inherit; font-size: 1rem; color: var(--text);
  background: var(--grund); border: 1px solid var(--gitter); border-radius: .35rem;
  padding: .4rem .5rem; width: 100%; min-width: 0;
}
/* ⚠️ DIE Zeile gegen „das Uhrzeit-Feld ist breiter als das Datumsfeld" (Jogi, 3.9., dritter
   Anlauf). Ein `input[type="date"|"time"]` ist am iPhone ein NATIVES Bedienelement und bringt
   eine eigene Mindestbreite mit – die richtet sich nach dem, was das Gerät hineinzeichnet
   („07:30" gegen „20.08.2026", je nach Sprache mit AM/PM), und sie lässt sich weder von
   `width: 100%` noch von `min-width: 0` drücken. Zwei solche Felder in einer `.zeilen`-Zeile
   werden dadurch UNGLEICH breit, obwohl beide `flex: 1` tragen, und die Zeile ragt hinaus.
   `appearance: none` nimmt ihnen dieses native Kleid – erst dann greifen unsere Breiten.
   ⚠️ Am Aussehen ändert das nichts: Hintergrund, Rahmen, Polster und Schrift kommen ohnehin aus
   der Regel darüber. Das Auswahlrad des Geräts geht weiter auf wie bisher.
   ⚠️ In Chrome war das nie zu sehen – dort haben die Felder diese Eigenbreite nicht. Drei
   Fassungen lang habe ich deshalb am Falschen gedreht (→ ARCHITEKTUR.md → 45). */
/* ⚠️ Die MINDESTHÖHE gehört zwingend zu `appearance: none` dazu (Jogis Fund vom 3.9., `v0.1.40.6`).
   Ein natives Zeitfeld ist auch LEER so hoch wie ein volles – der Browser hält seine Ziffernzeile
   frei. Ohne das native Kleid hat ein leeres Feld dagegen buchstäblich keinen Inhalt: keine
   Ziffern, keine Textzeile, also auch keine Zeilenhöhe. Übrig bleiben Polster und Rahmen, und das
   Feld fällt auf gut die halbe Höhe zusammen – sichtbar, seit Job 188 das × zum Leeren gebracht
   hat. Betrifft „von", „bis" und „Uhrzeit (Erinnerung)".
   ⚠️ Die 2.4 rem sind NICHT geraten, aber auch nicht ausgerechnet: die volle Feldhöhe ist
   Zeilenhöhe + Polster + Rahmen, und die Zeilenhöhe ist hier `normal` – die legt der Browser aus
   der Schrift fest, sie lässt sich in CSS nicht benennen. Nachgemessen sind es im Testbrowser
   39,97 px; 2.4 rem = 38,4 px liegt knapp DARUNTER. Genau so soll es sein: in Chrome ändert die
   Zeile damit gar nichts (die Ist-Höhe gewinnt), und dort, wo das Feld zusammenfällt, fängt sie
   es auf Feldhöhe ab. Dieselbe Zahl steht schon im ×-Block darüber.
   ⚠️ KEINE `line-height` dazu, so naheliegend es aussieht: Chromes innerer Ziffernteil
   (`::-webkit-datetime-edit`) rechnet sie ZUSÄTZLICH auf seine eigene Höhe – nachgemessen wurde
   das Feld damit 2 px höher als bisher, in jedem Browser, nur um einen Fehler zu beheben, den
   Chrome gar nicht hat.
   ⚠️ Und `appearance: none` NICHT einfach wieder herausnehmen (die Ursache): es hält am iPhone
   die Eigenbreite des Feldes in Schach – siehe die Regel darüber und `v0.1.40.4`. */
.dlg input[type="date"], .dlg input[type="time"] {
  -webkit-appearance: none; appearance: none;
  min-height: 2.4rem;
}
.dlg textarea { resize: vertical; }
/* Ein Knopf, der nur ein Zeichen trägt: das Polster von `.klein` passt für Text, nicht für eine
   Zeichnung. Aufgeklappt färbt er sich orange – derselbe Weg wie beim Pin (allein `aria-pressed`). */
.knopf-symbol { display: inline-flex; align-items: center; padding: .15rem .3rem; }
.symbol-gross { width: .9rem; height: .9rem; display: block; }
.knopf-symbol[aria-pressed="true"] { color: var(--akzent); border-color: var(--akzent); }

/* ---- Notiz gross (Job 141, 17.8.) ----------------------------------------------------------
   ⚠️ Auf `resize: vertical` allein ist kein Verlass: die Ecke zum Ziehen zeichnet Chrome hier
   gar nicht (am 17.8. bei dreifacher Vergrösserung nachgesehen, auch an nackten Vergleichs-
   feldern ohne unser CSS), und mit dem Finger wäre sie ohnehin nicht zu treffen. Darum ein
   Schalter: entweder zwei Zeilen oder der ganze Schirm – nichts dazwischen (Jogis Ansage).
   Alles ausser Überschrift, Notiz und Knopfzeile geht dabei weg; das Feld nimmt den Rest. */
.dlg.notiz-gross { height: 100%; max-height: 100%; border-radius: 0; }
.dlg.notiz-gross form { height: 100%; }
.dlg.notiz-gross form > *:not(h2):not(.feld-gross):not(.dlg-knoepfe) { display: none; }
.dlg.notiz-gross .feld-gross { flex: 1; min-height: 0; }
/* ⚠️ `min-height: 0` an beiden: ein Flex-Kind schrumpft sonst nicht unter seine Inhaltshöhe und
   das Feld schöbe die Knopfzeile aus dem Bild. `resize: none`, solange der Schalter regiert. */
.dlg.notiz-gross .feld-gross textarea { flex: 1; min-height: 0; height: auto; resize: none; }
@media (min-width: 34rem) {
  .dlg.notiz-gross { max-width: 40rem; border-radius: .8rem; }
}
.dlg input[type="checkbox"] { width: 1.1rem; height: 1.1rem; accent-color: var(--akzent); }
.dlg input:focus-visible, .dlg select:focus-visible, .dlg textarea:focus-visible {
  outline: 2px solid var(--akzent); outline-offset: 1px;
}
/* Der jeweils nicht gebrauchte Block ist WEG, nicht nur blass: leere Felder eines fremden
   Typs würden sonst mit abgeschickt und ergäben halbe Datensätze. */
.teil[hidden] { display: none; }

.dlg-knoepfe { display: flex; align-items: center; gap: .5rem; margin-top: .3rem; }
.dlg-knoepfe button {
  background: none; border: 1px solid var(--gitter); border-radius: .4rem;
  padding: .45rem .8rem; font-size: .85rem;
}
.dlg-knoepfe .haupt { background: var(--akzent); border-color: var(--akzent); color: #fff; }
.dlg-knoepfe .gefahr { color: #e08a8a; border-color: #6a3b3b; }
/* Beim Anlegen gibt es nichts zu löschen – der Knopf verschwindet, statt untätig dazustehen. */
.dlg-knoepfe .gefahr[hidden] { display: none; }
.dlg-knoepfe button:disabled { opacity: .4; cursor: default; }

/* ---------- Export und Import (Job 215) ----------
   Das Feld ist zum Wiedererkennen da, nicht zum Lesen: klein, nicht umbrechend, fest hoch.
   ⚠️ Die Schriftgrösse bleibt bei 1rem (Regel über `.dlg textarea`) – darunter zoomt iOS beim
   Antippen hinein. Die Zahlen-Zeile ist das, was Jogi wirklich liest. */
.dlg-daten {
  font-family: ui-monospace, Menlo, Consolas, monospace; white-space: pre;
  height: 7.5rem; overflow: auto;
}
.dlg-zahlen { margin: 0; font-size: .82rem; color: var(--text); }
.dlg-zahlen.falsch { color: #e08a8a; }

/* ---------- Einstellungen (Job 124) ----------
   Zwischenüberschrift und Erklärzeile. Der Abgleich ist die erste Einstellung überhaupt, und
   er braucht mehr Erklärung als ein Schalter – deshalb steht hier ein ganzer Satz, nicht bloss
   eine Beschriftung. */
.dlg-gruppe {
  margin: .4rem 0 0; font-size: .78rem; font-weight: 600; letter-spacing: .02em;
  color: var(--akzent-hell);
}
.dlg-hinweis { margin: 0; font-size: .74rem; line-height: 1.35; }
/* Zugeklappter Bereich für das, was man fast nie braucht (ab v0.1.29.0: die Adresse des
   Dienstes). Sieht aus wie eine leise Zeile, nicht wie ein Knopf. */
.dlg-mehr { margin-top: .8rem; }
.dlg-mehr > summary {
  cursor: pointer; font-size: .74rem; color: var(--leise);
  padding: .2rem 0; list-style-position: inside;
}
.dlg-mehr > summary:hover { color: var(--text); }
.dlg-mehr[open] > summary { margin-bottom: .4rem; }
/* Der Titel nimmt beim Öffnen den Fokus (siehe index.html) – ohne sichtbaren Rahmen darum. */
#ein-titel:focus, #exp-titel:focus, #imp-titel:focus { outline: none; }
/* Das Kennwort-Feld erbt die Feldform nicht von selbst – `input[type=password]` steht in der
   Aufzählung oben (bewusst) nicht drin, sonst wüchse sie mit jedem neuen Feldtyp. */
.dlg input[type="password"] {
  font: inherit; font-size: 1rem; color: var(--text);
  background: var(--grund); border: 1px solid var(--gitter); border-radius: .35rem;
  padding: .4rem .5rem; width: 100%; min-width: 0;
}
/* Der Zustand des Abgleichs in der Fußzeile. Farbe sagt nur „stimmt etwas nicht" – kata vergibt
   Farbe sonst ausschliesslich an Kategorien (ARCHITEKTUR.md → 6), deshalb bleibt „gut" grau. */
.fuss .sync-fehler { color: #e08a8a; }
.fuss .sync-wartet { color: var(--akzent-hell); }

/* ---------- Markierung: erst tippen, dann öffnen (ab v0.1.1.0) ----------
   ⚠️ Als `outline` gezeichnet, NICHT als Rahmen: ein Rahmen verschöbe die harte Untergrenze
   jedes Gitter-Kindes (die 150-px-Lehre, ARCHITEKTUR.md → 8) und liesse beim Markieren die
   ganze Spalte springen. Zwei Handschriften, damit man sieht, was der zweite Tipper tut:
     durchgezogen = ein vorhandener Eintrag ist gemeint (öffnet ihn)
     gestrichelt  = eine freie Stelle ist gemeint (legt dort etwas Neues an)                */
.termin.markiert, .auf.markiert {
  outline: 2px solid var(--akzent-hell); outline-offset: -1px;
}
.auf-zelle.markiert { outline: 2px dashed var(--akzent-hell); outline-offset: -2px; }
.zell-marke {
  margin: 1px; border-radius: .25rem; z-index: 1;
  background: #b4682f33; outline: 2px dashed var(--akzent-hell); outline-offset: -2px;
  pointer-events: none;   /* ⚠️ sonst schluckt die Marke genau den Tipper, auf den sie wartet */
}

/* Langes Drücken darf am Handy nicht die Textauswahl bzw. die iOS-Sprechblase aufziehen –
   sonst liegt über dem Kontextmenü noch „Kopieren / Nachschlagen". */
.termin, .auf { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

/* ---------- Verschieben: die Kachel selbst ist der Anfasser (Job 203, Jogi 20.9.) ----------
   Der Griff in der oberen rechten Ecke (Job 125, Nachtrag 16.8.) ist entfallen. Am Finger hängt
   die Kachel, nachdem er `HALT_ZIEH` lang gelegen hat; diese Anhebung ist die einzige
   Rückmeldung dafür – vibrieren kann das iPhone nicht.
   ⚠️ **Kein `transform`** für die Anhebung: bei einem Termin trägt `transform` seine LAGE im
   Raster (harte Regel 15, minutengenau inline gesetzt) – ein `scale()` hier schöbe ihn beim
   Anfassen auf eine andere Uhrzeit. Deshalb Schatten und etwas mehr Licht.
   ⚠️ **Kein Ring** (Job 205, Jogi 21.9.): die markierte Kachel trägt ihren `outline` schon aus
   der Vorstufe – ein zweiter an derselben Kante sagte nichts Neues. Jede Rückmeldung genau
   einmal; Schatten und Helligkeit allein tragen das „hängt jetzt".
   ⚠️ Kein `touch-action: none` an der Kachel. Stünde es hier (so war der erste Bau vom 15.8.),
   liesse sich die Ansicht am Handy nicht mehr rollen, sobald der Finger auf einem Termin
   aufsetzt – bei sieben vollen Spalten also fast immer. Das Rollen hält `app.js` erst an, wenn
   wirklich gezogen wird. */
.termin.markiert, .auf.markiert { position: relative; overflow: visible; }
.termin.wird-geschoben, .auf.wird-geschoben { opacity: .35; }
.termin.zieh-bereit, .auf.zieh-bereit {
  box-shadow: 0 6px 18px #000a;
  filter: brightness(1.15);
  z-index: 5;
  cursor: grabbing;
}
/* Während des Zuges soll der Zeiger überall gleich aussehen und nichts blau unterlegt werden. */
body.schiebt { cursor: grabbing; user-select: none; -webkit-user-select: none; }

.schieb-geist {
  position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none;
  max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: .2rem .45rem; border-radius: .3rem; font-size: .72rem;
  background: var(--akzent); color: #fff; box-shadow: 0 .3rem .8rem #0007;
}

/* Vorschau im Stundenraster: dieselbe Sprache wie die Zell-Marke (gestrichelt = hier entsteht
   gleich etwas), nur satter – und mit der Zeit, auf der der Termin einrastet. */
.schieb-ziel {
  margin: 1px; border-radius: .25rem; z-index: 2; pointer-events: none;
  background: #b4682f4d; outline: 2px solid var(--akzent-hell); outline-offset: -2px;
  font-size: .66rem; color: #fff; padding: .1rem .25rem; overflow: hidden;
}
/* Ganze Zelle als Ziel im Ganztages-Band – dort gibt es weder Uhrzeit noch Einfügestelle,
   also muss die Zelle selbst das Ziel zeigen.
   ⚠️ Die AUFGABENSPALTE steht hier bewusst NICHT mehr dabei (Job 205, Jogi 21.9.): dort liegt
   der Einfüge-Strich ohnehin schon in der Zielspalte und sagt zugleich, an welcher Stelle die
   Aufgabe landet. Ring und Tönung darüber hinaus waren dieselbe Aussage ein zweites und drittes
   Mal. Die Klasse wird weiterhin gesetzt (`zeigeSchiebZiel`), sie zeichnet dort nur nichts. */
.ganztags-zelle.schieb-ueber {
  outline: 2px solid var(--akzent-hell); outline-offset: -2px; background: #b4682f2b;
}

/* Der Einfüge-Strich beim senkrechten Ziehen einer Aufgabe (Job 133).
   ⚠️ `position: absolute` gegen die Spalte (die dafür `relative` ist): eingehängt zwischen die
   Kacheln schöbe er sie beim Ziehen weiter und änderte damit das Ziel unter dem eigenen Finger.
   ⚠️ `pointer-events: none` wie bei jeder Vorschau – sonst fände `elementFromPoint` nur ihn.
   ⚠️ Seit Job 205 ist er die EINZIGE Rückmeldung über dem Ziel (Ring und Tönung der Spalte sind
   weg) – deshalb 3 px statt 2 und ein etwas weiterer Schein. Nicht wieder dünner machen, ohne
   der Spalte etwas zurückzugeben. */
.schieb-linie {
  position: absolute; left: .15rem; right: .15rem; height: 3px; z-index: 3;
  pointer-events: none; border-radius: 2px;
  background: var(--akzent-hell); box-shadow: 0 0 .4rem var(--akzent);
}

/* Die Ablegefläche im Band entsteht erst, wenn ein Termin markiert ist (`bandAblage()`), und
   ist absichtlich flach: sie soll den Blick aufs Raster nicht verstellen. */
.ganztags-zelle.ablage { min-height: 1.2rem; opacity: .75; }

/* ---------- Kontextmenü (lang drücken · rechte Maustaste) ---------- */
.menue {
  position: fixed; z-index: 40; min-width: 9.5rem;
  display: flex; flex-direction: column; padding: .25rem;
  background: var(--karte); border: 1px solid var(--gitter); border-radius: .5rem;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .6);
}
.menue[hidden] { display: none; }
.menue button {
  background: none; border: 0; text-align: left; white-space: nowrap;
  padding: .5rem .7rem; border-radius: .35rem; font-size: .88rem;
}
.menue button:hover { background: #ffffff12; }
/* ---- Hauptmenü am Burger (Job 116) ----
   Die Gruppe „Daten" steht als Überschrift da und ihre Punkte rücken ein. Untermenüs, die beim
   Überfahren aufgehen, gibt es bewusst NICHT – am Handy sind sie unbedienbar (harte Regel 4). */
.menue-gruppe {
  padding: .45rem .7rem .2rem;
  font-size: .72rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--leise);
}
.menue-gruppe + button { margin-top: 0; }
.menue button.tief { padding-left: 1.4rem; }
.menue--unten button.tief { padding-left: 1.6rem; }
/* Noch nicht gebaut (Einstellungen, Stufe 2): sichtbar, damit der Platz vergeben ist, aber
   ohne Wirkung – ein Punkt, der still nichts tut, wäre schlimmer als ein blasser. */
.menue button.aus { color: var(--leise); cursor: default; }
.menue button.aus:hover { background: none; }
/* Bereichs-Wahl im Hauptmenü (Job 201): jeder Punkt hält links Platz für den Haken, der
   gewählte zeigt ihn – so rückt der Text beim Umschalten nicht hin und her. Orange + fett ist
   dieselbe Sprache wie in den Listen-Menüs (`.ckl-menue .gewaehlt`). */
.menue button.wahl { display: flex; align-items: center; gap: .45rem; }
.menue button.wahl.gewaehlt { color: var(--akzent-hell); font-weight: 600; }
/* Punkte NEBEN der Bereichs-Wahl: gleich weit eingerückt wie deren Text (Polster + Haken + Lücke),
   damit eine Spalte entsteht. ⚠️ Die drei Werte sind dieselben wie oben – ändert sich einer,
   ändert sich diese Zeile mit. */
.menue button.neben-wahl { padding-left: calc(.7rem + .9rem + .45rem); }
.menue-haken {
  width: .9rem; height: .9rem; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  visibility: hidden;
}
.menue button.gewaehlt .menue-haken { visibility: visible; }

/* Rot warnt, aber ohne die abgesetzte Bodenkante von `.gefahr`: seit der Umstellung vom 19.9.
   steht „DB löschen" zwar als letzter Punkt da, die Überschrift „Daten" setzt die Gruppe aber
   schon sichtbar ab – eine zweite Kante darüber wäre doppelt. */
.menue button.rot { color: #e08a8a; }

/* Löschen sitzt unten und abgesetzt – nicht dort, wo der Daumen beim Aufgehen ohnehin steht. */
.menue button.gefahr {
  color: #e08a8a; margin-top: .2rem; border-top: 1px solid var(--linie); border-radius: 0 0 .35rem .35rem;
}
/* Am schmalen Schirm unten angedockt (harte Regel 4): dort ist der Daumen, und das Menü
   verdeckt nicht die Spalte, um die es geht. Die Punkte werden dafür grösser. */
.menue--unten {
  left: .5rem; right: .5rem; bottom: .5rem; top: auto;
  padding: .35rem;
}
.menue--unten button { padding: .75rem .8rem; font-size: 1rem; }

/* ---------- Erinnerungen (Job 129) ------------------------------------------------------
   Drei Orte: die Glocke in der Kachel, der Bereich im Dialog und der Wecker in der Mitte.
   Herleitung und Datenmodell: ARCHITEKTUR.md → 20. */

/* Die Glocke sagt nur „hier steht noch etwas aus". Sie darf NIE Platz vom Titel nehmen: am
   Handy ist eine Tagesspalte rund 23 px breit (gemessen zu Job 125), da zählt jedes Pixel.
   Deshalb `flex: 0 0 auto` und eine Grösse unter der Zeilenhöhe. */
/* ⚠️ Eine selbst gezeichnete SVG, kein Emoji – auf s01 fehlt die Emoji-Schrift und „🔔" kam als
   leeres Kästchen heraus (dieselbe Schrift-Falle wie bei der Fußzeile, ARCHITEKTUR.md → 16).
   `currentColor` nimmt die Textfarbe der Kachel an, die Grösse hängt an der Schrift.
   Nicht kleiner als .75 rem: darunter ist die Kontur nur noch ein Fleck. */
.termin .glocke, .auf .glocke {
  flex: 0 0 auto; width: .75rem; height: .75rem; opacity: .85; color: inherit;
}
.termin .glocke { position: absolute; right: .1rem; bottom: .05rem; }
.auf .glocke { margin-left: .15rem; align-self: flex-start; }

/* ---- Der Bereich im Dialog ---- */
.erinn-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.erinn-liste li {
  display: flex; align-items: center; gap: .3rem;
  background: var(--grund); border: 1px solid var(--gitter); border-radius: 999px;
  padding: .15rem .2rem .15rem .6rem; font-size: .78rem;
}
/* Job 187 (Jogi, 3.9.): eine abgeschlossene Erinnerung steht grau und durchgestrichen da –
   dieselbe Bildsprache wie die erledigte Aufgabe (`.auf.fertig .name`). Der Zusatz
   „· geschlossen" ist dafür entfallen; ein Zustand, den man sieht, muss nicht auch dastehen. */
.erinn-wert.zu { color: var(--leise); text-decoration: line-through; }
.erinn-weg {
  background: none; border: 0; color: var(--leise); font-size: 1rem; line-height: 1;
  /* 1.6 rem Trefferfläche: das Kreuz selbst ist klein, aber der Daumen ist es nicht. */
  width: 1.6rem; height: 1.6rem; border-radius: 999px;
}
.erinn-weg:hover { color: #e08a8a; background: #ffffff12; }
.erinn-neu { display: flex; align-items: center; gap: .4rem; }
.erinn-neu select { flex: 1 1 auto; min-width: 0; }
/* ⚠️ Solange „eigene …" offen ist, tritt die Auswahl in der Breite ZURÜCK (Jogi, 18.8.): sie
   zeigt dann ohnehin nur „eigene …", während Zahl und Einheit den Platz brauchen. Ohne diese
   Zeile drückt sie das Zahlenfeld auf wenige Pixel – dieselbe Falle wie am Schlummer-Feld. */
.erinn-neu.eigen select#f-erinn-wahl { flex: 0 1 7rem; }
/* Der Knopf ist ein oranges „+" statt des Wortes „dazu" (Jogi, 18.8.) – er kostete in der Zeile
   mehr Breite als das Feld, um das es geht. Quadratisch und fingertauglich (harte Regel 4). */
.erinn-neu button {
  flex: 0 0 auto; background: none; border: 1px solid var(--gitter); border-radius: .4rem;
  color: var(--akzent-hell); padding: 0; font-size: 1.25rem; line-height: 1;
  width: 2.2rem; height: 2.2rem;
}
.erinn-neu button:hover { border-color: var(--akzent-hell); background: #ffffff10; }
/* „eigene …": Zahl und Einheit stehen nebeneinander und teilen sich die Breite der Auswahl. */
.erinn-eigen { display: flex; gap: .3rem; flex: 1 1 auto; min-width: 0; }
.erinn-eigen[hidden] { display: none; }
/* ⚠️ FESTE Breite, kein `flex: 1 1 3rem` (Jogi, 18.8.): ein Zahlenfeld ist kein Dehnglied – in
   einer Zeile aus dehnbaren Gliedern gibt es als erstes nach, bis von der Ziffer nichts mehr zu
   sehen ist. Dieselbe Lehre wie an der Weck-Karte (`v0.1.34.2`, → 40): drei Ziffern plus Polster,
   Rahmen und die Pfeilchen, die Chrome anhängt. */
.erinn-eigen input { flex: 0 0 4.5rem; min-width: 0; }
.erinn-eigen select { flex: 0 0 4.6rem; }
/* `type=number` steht bewusst nicht in der grossen Feld-Aufzählung oben – die wüchse sonst mit
   jedem neuen Feldtyp. Hier gilt dieselbe Form, inklusive der 16-px-Regel für iOS. */
.dlg input[type="number"] {
  font: inherit; font-size: 1rem; color: var(--text);
  background: var(--grund); border: 1px solid var(--gitter); border-radius: .35rem;
  padding: .4rem .5rem; width: 100%; min-width: 0;
}

/* ---- Der Wecker ----
   Mittig und gestapelt (Jogi, 16.8.). Bewusst KEIN `dialog`: der sperrt den Kalender dahinter
   und kann immer nur EINE Meldung obenauf haben.
   ⚠️ `max-height` + eigenes Rollen: bei zehn verpassten Erinnerungen ragte der Stapel sonst
   oben und unten aus dem Bild, und der unterste Knopf wäre nicht mehr zu treffen. */
/* ⚠️ 27rem, nicht 22 (ab `v0.1.34.2`, Jogis Fund): in der Knopfzeile stehen „Beenden", das
   Schlummer-Feld und „Erneut erinnern" nebeneinander – zusammen rund 400 px. In 22 rem (352 px,
   innen 328) blieb für das Zahlenfeld als einziges schrumpfendes Glied **14,8 px** übrig, davon
   0,2 px Inhalt: von der „1" war die linke Hälfte zu sehen. Die Karte ist so breit, weil das Feld
   dreistellig sein soll, nicht umgekehrt. */
.wecker {
  position: fixed; z-index: 60; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(27rem, calc(100vw - 1.5rem)); max-height: min(70vh, 34rem);
  overflow-y: auto; display: flex; flex-direction: column; gap: .5rem;
}
.wecker[hidden] { display: none; }
.weck-karte {
  background: var(--karte); border: 1px solid var(--akzent); border-radius: .6rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .6);
  padding: .6rem .7rem; display: flex; flex-direction: column; gap: .35rem;
}
/* Titel und ✕ in einer Zeile. `min-width: 0` am Titel, sonst schöbe ein langer Titel das ✕
   aus der Karte hinaus, statt selbst umzubrechen. */
.weck-kopf { display: flex; align-items: flex-start; gap: .4rem; }
.weck-titel { font-size: .95rem; font-weight: 600; cursor: pointer; flex: 1 1 auto; min-width: 0; }
.weck-wann { font-size: .78rem; color: var(--akzent-hell); }
.weck-spaet { font-size: .72rem; color: var(--leise); }
/* ⚠️ Pflichtzeile wie bei `.feld[hidden]` (harte Regel 16): ohne sie stünde die leere Zeile als
   Lücke im Karten-Abstand, weil `hidden` von jeder eigenen `display`-Regel ausgestochen wird. */
.weck-spaet[hidden] { display: none; }
/* ⚠️ `flex-wrap: wrap` ist die Rückfallebene fürs Handy: dort deckelt `100vw - 1.5rem` die Karte
   auf ~366 px, und ohne Umbruch würde wieder das Zahlenfeld zerdrückt – als einziges Glied, das
   nachgeben kann. Lieber zwei Zeilen als ein unlesbares Feld. */
.weck-knoepfe { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-top: .15rem; }
.weck-knoepfe button {
  background: none; border: 1px solid var(--gitter); border-radius: .4rem; color: var(--text);
  padding: .45rem .7rem; font-size: .85rem; flex: 0 0 auto;
}
.weck-knoepfe .haupt { background: var(--akzent); border-color: var(--akzent); color: #fff; }
/* „Beenden" steht bewusst UNAUFFÄLLIG neben dem hervorgehobenen „Erneut erinnern" (Jogis Wahl,
   18.8.): es ist der endgültige Weg, und endgültige Wege gehören nicht unter den Daumen. */
.weck-beenden { flex: 0 0 auto; }
.weck-knoepfe .erinn-eigen { flex: 1 1 auto; min-width: 9.5rem; }
.weck-knoepfe input[type="number"], .weck-knoepfe select {
  font: inherit; font-size: 1rem; color: var(--text); width: 100%; min-width: 0;
  background: var(--grund); border: 1px solid var(--gitter); border-radius: .35rem;
  padding: .35rem .4rem;
}
/* ⚠️ Feste Breite statt `flex: 1 1 3rem`: drei Ziffern (~27 px) plus Polster, Rahmen und die
   Pfeilchen, die Chrome an ein Zahlenfeld hängt (~14 px). Mit `min-width: 0` und einer flexiblen
   Basis war genau dieses Feld das erste, das die Zeile beim Platzmangel opferte. */
.weck-knoepfe input[type="number"] { flex: 0 0 4.5rem; width: 4.5rem; }

/* ---- Die Liste im Burger-Menü ---- */
.erinn-zeile {
  display: flex; align-items: center; gap: .5rem;
  border-top: 1px solid var(--linie); padding: .45rem 0;
}
.erinn-was { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.erinn-was .erinn-titel { font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.erinn-was .erinn-wann { font-size: .72rem; color: var(--leise); }
.erinn-knoepfe { flex: 0 0 auto; display: flex; gap: .3rem; }
.erinn-knoepfe button {
  background: none; border: 1px solid var(--gitter); border-radius: .4rem; color: var(--text);
  padding: .35rem .5rem; font-size: .75rem;
}
#erinn-inhalt { max-height: 60vh; overflow-y: auto; }

/* Der Knopf „Systemmeldungen erlauben" steht mitten im Hinweissatz der Erinnerungs-Liste –
   deshalb inline und in Textgrösse, nicht als Blockknopf (Job 129, `v0.1.16.0`). */
#erinn-inhalt .dlg-hinweis button {
  background: none; border: 1px solid var(--gitter); border-radius: .35rem; color: var(--text);
  padding: .2rem .45rem; font: inherit; font-size: .74rem; margin-left: .2rem;
}
#erinn-inhalt .dlg-hinweis button:hover { border-color: var(--akzent); }

/* ---------- Jetzt-Zeiger (Job 130) ------------------------------------------------------
   Dreieck am rechten Rand der Uhrzeit-Spalte, Linie quer durch die Spalte „heute" – beide auf
   derselben Höhe, beide von JS über `grid-row` + `transform` gesetzt.
   ⚠️ `pointer-events: none` an beiden: sie liegen über der Spaltenfläche, und ohne die Zeile
   verschluckten sie genau dort den Tipper, der eine neue halbe Stunde markiert. */
.jetzt-linie {
  align-self: start; height: 0; border-top: 2px solid var(--jetzt);
  /* über den Terminen (die haben z-index 1) – sonst verschwände sie hinter jeder Kachel */
  z-index: 3; pointer-events: none;
}
/* Die Höhenmarke über alle Spalten (Job 138): gestrichelt und blass, damit sie sichtbar etwas
   ANDERES ist als das durchgezogene Rot in „heute". Sie liegt eine Stufe tiefer, damit die rote
   Linie in ihrer Spalte oben bleibt. */
.jetzt-linie.jetzt-marke { border-top: 1px dashed var(--jetzt-marke); z-index: 2; }
/* Die Uhrzeit am Zeiger (`v0.1.31.5`): sie steht in der Uhrzeit-Spalte auf derselben Höhe wie
   Dreieck und Linie und sagt in Zahlen, was der Zeiger meint.
   ⚠️ Eigener Hintergrund und `z-index` über den Stundenzahlen – sie liegt oft direkt neben einer
   und muss die gewinnen. Die halbe Texthöhe nach oben (`margin-top`), damit ihre MITTE auf der
   Linie sitzt: derselbe Grund wie bei den Stundenzahlen (→ 36). Der Höhen-Versatz innerhalb der
   halben Stunde läuft weiter über `transform` und darf davon nicht angefasst werden. */
.jetzt-zeit {
  grid-column: 1; align-self: start; justify-self: end;
  /* ⚠️ `z-index` unter dem Dreieck (7) und ein `margin-right` statt Polster: mit Polster deckte
     der eigene Hintergrund das Dreieck am Spaltenrand zu. */
  position: sticky; left: 0; z-index: 6; pointer-events: none;
  margin-top: -.55rem; margin-right: .55rem; padding: 0 .1rem 0 .18rem;
  font-size: .7rem; line-height: 1.1; color: var(--jetzt); background: var(--grund);
}
@media (max-width: 30rem) { .jetzt-zeit { font-size: .62rem; margin-right: .4rem; } }

.jetzt-pfeil {
  grid-column: 1; align-self: start; justify-self: end;
  /* ⚠️ Klebt links wie die Uhrzeiten selbst, sonst wanderte es beim Waagrecht-Rollen aus dem
     Bild. Deshalb darf der Höhen-Versatz NICHT über `top` laufen – das ist hier die Klebekante. */
  position: sticky; left: 0; z-index: 7;
  /* Bündig an der Spaltengrenze: mit Abstand nach rechts schob es sich über die
     Uhrzeit-Beschriftung („21:0▶" statt „21:00"). */
  width: 0; height: 0; margin-top: -5px;
  border-top: 5px solid transparent; border-bottom: 5px solid transparent;
  border-left: 8px solid var(--jetzt);
  pointer-events: none;
}

/* ================================================================ Hilfeseite (Job 137)
   `hilfe.html` benutzt DIESE Datei mit – Farben, Schrift und Kopfzeile sollen an einem Ort
   stehen. Hier steht nur, was die Seite darüber hinaus braucht.
   ⚠️ `height: auto`: `html, body { height: 100% }` oben ist für die App gedacht, die ihre eigene
   Bühne rollt. Auf einer Lese-Seite verhinderte das genau das Rollen. */
body.hilfe-seite { height: auto; min-height: 100%; }

.hilfe {
  /* Lesebreite, nicht Fensterbreite – am 27-Zöller wären das sonst 200 Zeichen je Zeile. */
  max-width: 44rem;
  margin: 0 auto;
  padding: 1.2rem calc(1rem + env(safe-area-inset-right, 0px))
           3rem calc(1rem + env(safe-area-inset-left, 0px));
}
.hilfe h2 { font-size: 1.4rem; margin: .2rem 0 1.2rem; }
.hilfe h3 { font-size: 1.05rem; margin: 0 0 .5rem; color: var(--akzent-hell); }
.hilfe p  { margin: 0 0 .7rem; }
.hilfe ul { margin: 0 0 .7rem; padding-left: 1.2rem; }
.hilfe li { margin-bottom: .3rem; }
.hilfe section {
  background: var(--karte); border: 1px solid var(--linie); border-radius: .5rem;
  padding: .9rem 1rem; margin-bottom: 1rem;
  /* Angesprungene Abschnitte dürfen nicht unter der klebenden Kopfzeile landen. */
  scroll-margin-top: calc(var(--kopf-h) + .6rem);
}
.hilfe-inhalt { display: flex; flex-wrap: wrap; gap: .3rem .9rem; margin-bottom: 1.2rem; }
.hilfe-inhalt a { color: var(--leise); font-size: .85rem; }
.hilfe-inhalt a:hover { color: var(--akzent-hell); }
.hilfe a { color: var(--akzent-hell); }
/* ⚠️ Die Hilfeseite hat KEINEN Weg zurück in die App (Jogi, 17.8.) – sie geht neben kata auf
   und wird geschlossen wie jedes Fenster. Das Symbol oben links ist deshalb kein Link. */
.hilfe-seite .marke { cursor: default; }

/* Was noch nicht endgültig ist, sagt es selbst (Jogi, 17.8.: „markier das als #ToDo") – kata
   ist in der Testphase, und ein Leser soll das an der Stelle sehen, nicht raten müssen. */
.todo {
  font-size: .7rem; color: var(--jetzt); border: 1px solid var(--jetzt);
  border-radius: .3rem; padding: .05rem .3rem; vertical-align: .1em; margin-left: .3rem;
}
.todo-notiz {
  border-left: 3px solid var(--jetzt); padding-left: .6rem;
  color: var(--leise); font-size: .85rem;
}

/* ---------- Übergabe an den Kalender des Geräts (Job 154) ----------
   Sitzt unter den Erinnerungen im Dialog, nicht bei „Sichern": es geht ums Wecken. Bewusst KEIN
   Hauptknopf (`--akzent` gefüllt) – der gehört dem Sichern; dies hier ist ein Weg neben dem
   üblichen, und er kostet einen Handgriff am Gerät. */
.kal-zeile { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; }
.kal-knopf {
  background: transparent; border: 1px solid var(--akzent); color: var(--akzent-hell);
  border-radius: .4rem; padding: .35rem .7rem; font: inherit; font-size: .85rem; cursor: pointer;
}
.kal-knopf:hover { background: var(--akzent-dunkel); color: var(--text); }
/* ⚠️ Pflichtzeile, kein Feinschliff: eine eigene `display`-Regel sticht das eingebaute `hidden`
   aus – genau daran blieb „erledigt am" bis v0.1.29.1 an jeder offenen Aufgabe stehen (Regel 16).
   Jede neue Klasse mit `display`, die `hidden` tragen kann, gehört dazu. */
.kal-zeile[hidden], .kal-knopf[hidden] { display: none; }

/* ---------- Das Hilfe-Symbol („?") ----------
   Ein BAUTEIL für viele Stellen (Jogi, 17.8.): jeder Bereich bekommt mit der Zeit sein eigenes
   „?" mit eigenem Anker, `hilfe.html#…`. Deshalb ein schlichtes `<a>` und kein Knopf mit
   JS – ein Link braucht nichts, kann in einem neuen Reiter geöffnet und als Lesezeichen
   gespeichert werden. Dezent: gleicher Ton wie die anderen leisen Beschriftungen, erst beim
   Überfahren tritt es hervor. */
.hilfe-knopf {
  flex: none; width: 1.35rem; height: 1.35rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--linie); color: var(--leise);
  font-size: .72rem; line-height: 1; text-decoration: none;
}
.hilfe-knopf:hover { border-color: var(--akzent); color: var(--text); }

/* ---------- Listen und Tafeln (Job 198) ----------
   Offen verschwinden Bühne und Fußzeile, und die SEITE rollt – `checkliste.js` rollt das Fenster,
   nicht einen Kasten (so wie auf der Testseite). Der kata-Kopf klebt oben, der Kopf der
   Checkliste klebt darunter statt dahinter. Bei offener Tafel rollen nur ihre Spalten. */
body.listen-offen { height: auto; min-height: 100%; }
body.listen-offen #buehne, body.listen-offen #fuss { display: none; }
body.listen-offen.tafel-offen { overflow: hidden; }
body.listen-offen .ckl-kopf { top: var(--kopf-h); }
/* Der Zeitplan (Job 212) füllt den Rest unter dem kata-Kopf; es rollt nur seine Zeitachse. */
#zp { height: calc(100vh - var(--kopf-h)); height: calc(100dvh - var(--kopf-h)); }
#zp .ckl-kopf { top: 0; }
.zum-kalender {
  background: none; border: 1px solid var(--linie); border-radius: .35rem;
  padding: .25rem .6rem; font-size: .85rem; color: var(--text);
}
.zum-kalender:hover { border-color: var(--akzent); }
.zum-kalender[hidden] { display: none; }
