/* ============================================================
   PrepP — Listen (js/listen.js, 15.08.2026)
   Kontextmenue, Mehrfachauswahl, Gruppen, Favoriten und Ablagemarken
   fuer alle Portal-Listen. Laedt direkt hinter prepp.css und ergaenzt
   dessen .pp-list/.pp-actions/.pp-set-head-Regeln; nur --pp-Tokens
   (Fallstrick 11), hell und dunkel von selbst. Seit dem 18.09.2026 steht
   hier auch die Gestalt der beiden ANDEREN Menueknoten (Arbeitsflaeche,
   Schaltlabor) — eine Gestalt fuer alle drei, siehe gleich darunter.
   ============================================================ */

/* ============================================================
   Die EINE Menuegestalt (18.09.2026, docs/RECHTSKLICK-2026-09-18.md)
   ============================================================
   Jonas: „ohne Symbol · kleinere Schrift · enger beieinander ·
   uebersichtlicher · einheitlich". Es gibt drei Menue-KNOTEN in PrepP
   (#pp-ctx der Listen, #sb-ctx der Arbeitsflaeche, #lab-ctx des
   Schaltlabors) — und ab hier genau EINE Gestalt fuer alle drei.

   Warum die Selektorliste und nicht je Stylesheet dieselben Werte:
   css/lab.css (24) und css/sandbox.css (25) laden NACH css/listen.css
   (21). Stuenden die Werte dort noch einmal, gewaennen sie bei gleicher
   Spezifitaet — und liefen beim naechsten Nachjustieren auseinander.
   Beide Dateien setzen deshalb keine Flaeche, Schrift, Polsterung oder
   Hoverfarbe ihrer Menues mehr; dort steht nur noch die LAGE
   (position/z-index/max-height). verify-rechtsklick-2026-09-18.js
   haelt das fest.

   KEINE Symbolspalte: js/listen.js zeichnet sie nicht mehr, und
   .sb-ctx/.lab-ctx hatten nie eine. Einzige Marke ist ein ✓ vor einem
   gesetzten Umschaltpunkt. */
.pp-ctx, .pp-ctx-unter, .sb-ctx, .sb-ctx-unter .sb-ctx-menu, .lab-ctx {
  min-width: 180px; max-width: min(280px, calc(100vw - 8px));
  max-height: calc(100vh - 8px); overflow-y: auto;
  padding: 4px; border-radius: 8px;
  /* Nicht --pp-bg-2: das ist in beiden Themes byteweise --pp-surface, also
     die Farbe der Karte darunter (CLAUDE.md, „--pp-bg-2 ist KEIN zweiter
     Flaechenton"). --pp-surface-2 setzt sich davon ab, der Rand traegt
     den Rest. */
  background: var(--pp-surface-2); border: 1px solid var(--pp-line-2);
  box-shadow: var(--pp-lift);
  display: flex; flex-direction: column; gap: 0;
  font-family: var(--pp-sans);
}
/* Eine Menuezeile — ueberall dieselbe. Die drei Menues bauen ihr Markup
   verschieden (Klasse bzw. blankes <button>), die Gestalt ist eine. */
.pp-ctx-it,
.sb-ctx-body > button, .sb-ctx-menu > button, .sb-ctx-unter > button,
.lab-ctx-body button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 4px 10px; border: 0; border-radius: 5px; background: none;
  font-family: var(--pp-sans); font-weight: 400;
  font-size: var(--pp-fs-klein); line-height: var(--pp-lh-knapp);
  color: var(--pp-text);
  text-align: left; cursor: pointer; white-space: nowrap;
}
/* Hover/Fokus in Akzent-Ton (wie Palette): --pp-bg-2 ist in beiden Themes
   gleich der Menueflaeche — ein Fokus darauf war unsichtbar
   (Review 15.08.2026, WebKit gemessen). */
.pp-ctx-it:hover, .pp-ctx-it:focus-visible,
.sb-ctx-body > button:hover:not([disabled]), .sb-ctx-menu > button:hover:not([disabled]),
.lab-ctx-body button:hover:not([disabled]) {
  background: var(--pp-accent-tint); color: var(--pp-accent-2); outline: none;
}
.pp-ctx-it:focus-visible { box-shadow: inset 0 0 0 2px var(--pp-accent); }
/* Ausgegraut, aber lesbar: EINE Dimmung (text-3), keine Opazitaet obendrauf —
   der gesperrte Punkt im Untermenue ist die Antwort auf „wo bin ich?". */
.pp-ctx-it[disabled],
.sb-ctx-body > button[disabled], .sb-ctx-menu > button[disabled],
.lab-ctx-body button[disabled] { color: var(--pp-text-3); cursor: default; opacity: 1; }
.pp-ctx-it[disabled]:hover { background: none; }
/* Gefaehrliches: rote SCHRIFT, sonst nichts (Jonas). Der rote Balken im
   Hover war der lauteste Ton der ganzen Oberflaeche — an einem Punkt, den
   man ueberfliegt, nicht drueckt. Er steht ohnehin zuletzt. */
.pp-ctx-it.gefahr,
.sb-ctx-body > button.gefahr, .lab-ctx-body button.gefahr { color: var(--pp-err); }
.pp-ctx-it.gefahr:hover, .pp-ctx-it.gefahr:focus-visible,
.sb-ctx-body > button.gefahr:hover:not([disabled]),
.lab-ctx-body button.gefahr:hover:not([disabled]) { background: var(--pp-accent-tint); color: var(--pp-err); }
/* Die Gefahr-Zeile bekommt ihre Hover-Rueckmeldung als RING, nicht als
   Flaeche (19.09.2026, in WebKit gemessen). Grund: Im dunklen Theme ist
   --pp-err eine HELLE Schrift, und jede Aufhellung der Flaeche senkt den
   Kontrast — auf --pp-accent-tint faellt er von 4,72 auf 3,97 : 1, also
   unter AA. Nachgerechnet gilt das fuer jede Toenung, auch fuer
   --pp-err-tint (4,09), das Problem ist die Aufhellung selbst und nicht
   die Farbe. Die volle rote Flaeche waere der Weg, den Jonas am
   18.09.2026 ausdruecklich gestrichen hat („der lauteste Ton der ganzen
   Oberflaeche"). Der Ring ist dasselbe Bauteil wie der Fokusring zwei
   Regeln hoeher, liegt als box-shadow AUSSERHALB des Layouts (verschiebt
   nichts) und traegt selbst 4,72 : 1 gegen die Flaeche — ueber den 3 : 1
   der WCAG 1.4.11. Der Fokusring gewinnt, wenn die Tastatur da ist. */
/* Mitgezogen werden die beiden ANDEREN Knoten — „eine Gestalt fuer alle
   drei" (18.09.2026) heisst auch: Diese Reparatur laeuft nicht an ihnen
   vorbei, sonst stehen morgen zwei Gefahr-Zeilen mit verschiedenem
   Hover nebeneinander. Die Regel steht hier, in css/listen.css, wie die
   ganze uebrige Gestalt; sandbox.js und circuit.js sind unberuehrt. */
.pp-ctx-it.gefahr:hover:not(:focus-visible),
.sb-ctx-body > button.gefahr:hover:not([disabled]):not(:focus-visible),
.lab-ctx-body button.gefahr:hover:not([disabled]):not(:focus-visible) {
  background: none; box-shadow: inset 0 0 0 1px var(--pp-err);
}
/* Der Haken-Einzug entsteht NUR, wenn ein Punkt dieser Ebene ihn braucht
   (js/listen.js `mitHaken`) — sonst waere er die Symbolspalte unter
   anderem Namen. */
.pp-ctx-haken { flex: none; width: 13px; text-align: center; color: var(--pp-accent-2); }
.pp-ctx-it.gefahr .pp-ctx-haken { color: inherit; }
.pp-ctx-lbl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* sim1016 A7-08 (iPhone, Menü 280 px: „Skript-Seiten noch nicht …" endete
   im „…", das Verb „eintragen" fehlte): Am Telefon bricht ein langer Punkt
   um, statt sein Ende zu verlieren — das Kürzel bleibt rechts daneben. */
@media (max-width: 480px) {
  #pp-ctx .pp-ctx-lbl { white-space: normal; overflow-wrap: anywhere; text-overflow: clip; }
}
/* fx1020-vorbereitung (Befund 10): Ein reiner HINWEIS im Menü (gedämpfter
   Satz, kein Befehl — „Gemeinsam in der Lerngruppe — Zeit ändern und
   Entfernen gelten für alle") bricht um, statt mitten im Satz im „…" zu
   enden („Zeit ände…"). Befehle bleiben einzeilig. */
#pp-ctx .pp-ctx-lbl:has(> .pp-dim:only-child) { white-space: normal; overflow-wrap: break-word; text-overflow: clip; }
/* Kuerzel: rechtsbuendig und gedaempft, OHNE Rahmen — ein Kasten um jedes
   Kuerzel war der zweite Blickfang je Zeile. */
.pp-ctx-kbd,
.sb-ctx-body > button kbd, .sb-ctx-menu > button kbd, .lab-ctx-body button kbd {
  margin-left: auto; flex: none; font-family: var(--pp-mono); font-size: var(--pp-fs-mini);
  color: var(--pp-text-3); border: 0; border-radius: 0; padding: 0; background: none;
}
.pp-ctx-it.gefahr:hover .pp-ctx-kbd { color: inherit; }
.pp-ctx-pfeil, .sb-ctx-pfeil {
  margin-left: auto; flex: none; color: var(--pp-text-3);
  font-size: var(--pp-fs-klein); line-height: var(--pp-lh-eng);
}
/* Unter der Maus erben Kuerzel und Pfeil die AKZENTFARBE der Zeile.
   Gemessen am 19.09.2026 in WebKit, helles Theme: Auf --pp-accent-tint
   faellt --pp-text-3 von 4,63 auf 4,49 : 1 — also unter AA, und zwar
   genau in dem Moment, in dem man hinsieht. `currentColor` bringt beide
   auf den Wert der Beschriftung daneben (5,44 : 1 hell, 6,05 dunkel) und
   haengt NICHT am Token; die Gefahr-Zeile macht es eine Regel hoeher
   seit jeher genauso. In Ruhe bleibt alles wie vorher. */
.pp-ctx-it:hover .pp-ctx-kbd, .pp-ctx-it:focus-visible .pp-ctx-kbd,
.pp-ctx-it:hover .pp-ctx-pfeil, .pp-ctx-it:focus-visible .pp-ctx-pfeil,
.pp-ctx-it.hat-unter[aria-expanded="true"] .pp-ctx-pfeil,
.sb-ctx-body > button:hover:not([disabled]) .sb-ctx-pfeil,
.sb-ctx-menu > button:hover:not([disabled]) .sb-ctx-pfeil { color: inherit; }

/* ---------- Drill-Down: die Kaskade auf dem Finger (19.09.2026) --------
   docs/RECHTSKLICK-2026-09-18.md, „Nachtrag 19.09.". Auf einem Gerät ohne
   Ueberfahren ERSETZT ein Untermenue den Inhalt desselben Knotens, statt
   sich daneben zu legen — bei 390 px passen 180 + 180 + 280 px nicht
   nebeneinander, und gemessen lagen dort 13 von 27 Zeilen unter einer
   anderen Ebene (also sichtbar, aber fuer einen Finger unerreichbar).
   Die Zurueck-Zeile ist die erste Zeile der Ebene; sie ist eine
   .pp-ctx-it und erbt damit Gestalt, Hoverfarbe und die 44 px. Eigen ist
   nur die gedaempfte Ortsangabe rechts. */
.pp-ctx-zurueck .pp-ctx-lbl { flex: 0 1 auto; font-weight: 500; }
/* Wo bin ich? Der Name der Ebene an der Stelle des Kuerzels — dieselbe
   Spalte, dieselbe Daempfung, damit die Zeile EINE Zeile bleibt. */
.pp-ctx-wo {
  margin-left: auto; flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--pp-fs-mini); color: var(--pp-text-3);
}
.pp-ctx-zurueck:hover .pp-ctx-wo, .pp-ctx-zurueck:focus-visible .pp-ctx-wo { color: inherit; }
.pp-ctx-trenner, .sb-ctx-body .sep, .lab-ctx-body .sep {
  height: 1px; margin: 4px 8px; background: var(--pp-line); flex: none;
}
/* Die Gegenregel: display:flex schluege sonst das Browser-[hidden]
   (Befund „+ Karte"-Menue der Sandbox, verify-auth-formulare.js 7). */
.pp-ctx[hidden], .sb-ctx[hidden] { display: none; }
/* Die LAGE bleibt je Menue eigen — sie ist das einzige, was sich wirklich
   unterscheidet: #pp-ctx schwebt am body, #sb-ctx und #lab-ctx liegen in
   ihrer Flaeche (css/sandbox.css, css/lab.css).
   z 140: ueber der klebenden Kopfzeile (20), unter Dialogen (150). */
.pp-ctx { position: fixed; z-index: 140; }
/* a1014-P5: Ein Menü aus einem Dialog heraus (Anker in .pp-modal-bg, z 150)
   steht ÜBER ihm — sonst öffnete „Erstellen ▾" im Vor-/Nachbereiten-Fenster
   unsichtbar dahinter. Gesetzt in js/listen.js (menueOeffnen). */
.pp-ctx.pp-ctx-ueber-dialog { z-index: 155; }
.pp-ctx.pp-ctx-ueber-dialog .pp-ctx-unter { z-index: 156; }
/* Untermenue: position:fixed, weil der Kasten selbst scrollt und ein
   absolutes Kind an seiner Kante abgeschnitten wuerde (Sandbox-Befund B2). */
.pp-ctx-unter { position: fixed; z-index: 141; }
.pp-ctx-unter[hidden] { display: none; }
/* Auf dem Finger bleibt jede Menuezeile mindestens 44 px hoch (R3) — in
   allen drei Menues, an EINER Stelle. */
@media (hover: none) {
  .pp-ctx-it,
  .sb-ctx-body > button, .sb-ctx-menu > button, .sb-ctx-unter > button,
  .lab-ctx-body button { min-height: 44px; padding-top: 6px; padding-bottom: 6px; }
  /* Die REITERZEILE des Laborsmenues gehoert dazu (19.09.2026): Sie ist das
     einzige Menue mit Reitern, und „Bauteile" ist auf dem Telefon der Weg
     zur Bauteilauswahl. Gemessen waren die zwei Knoepfe 88,8 x 31 px —
     also breit genug und zu flach. Sie steht HIER und nicht in css/lab.css,
     weil dort seit dem 18.09. nur noch die LAGE der Menues wohnt. */
  .lab-ctx-tabs button { min-height: 44px; }
}
.pp-ctx-it.hat-unter[aria-expanded="true"] { background: var(--pp-accent-tint); color: var(--pp-accent-2); }
/* Der Ausloeser (⋯) bleibt markiert, solange sein Menue steht. */
.pp-ctx-anker { background: var(--pp-accent-tint) !important; color: var(--pp-accent-2) !important; border-color: var(--pp-accent-line) !important; }
/* Die Zeile bleibt „angefasst", solange ihr Menue offen ist — sonst blendete
   .pp-actions beim Wegziehen der Maus aus, und das Menue hinge an einem Knopf,
   den es nicht mehr gibt. Sie gilt seit dem 18.09.2026 auch fuer die
   Gespraechsliste: .prof-row traegt .pp-ctx-offen wie jede andere Zeile. */
.pp-pick.pp-ctx-offen .pp-actions { opacity: 1; pointer-events: auto; }
.pp-list .pp-pick.pp-ctx-offen { background: var(--pp-surface-2); z-index: 2; }
/* Dasselbe fuer die Antwortzeile einer Aufgabe (Punkt 34): Solange das Menue
   steht, ist UMRAHMT, worauf es sich bezieht. Eine Aufgabe hat mehrere
   Antwortzeilen, und „Loesung anzeigen" meint genau eine — ohne den Rahmen
   sieht man dem Menue nicht an, welche.
   outline statt border: Die .answer-row traegt eine eigene border-top, und ein
   zweiter Rahmen im Kastenmodell verschoebe die ganze Zeile um 2 px, also
   genau in dem Moment, in dem man hinsieht. outline-offset:-2px haelt ihn
   INNEN — sonst ueberlappte er die Nachbarzeile darueber.
   Gilt in beiden Welten: Die Zeile steht so im Training wie in der Einsicht,
   und --pp-accent liegt auf body (nicht auf .pp-root). */
.answer-row.pp-ctx-offen {
  outline: 2px solid var(--pp-accent);
  outline-offset: -2px;
  border-radius: 6px;
}
@media (prefers-reduced-motion: reduce) { .pp-ctx, .pp-ctx-it { transition: none; } }

/* ---------- Freie Flaeche der Liste (Rechtsklick NEBEN einem Eintrag) ---------- */
/* Gemessen in WebKit am 15.08.2026 (1440x900, #course/gget2/exercises):
   Zwischen der letzten Zeile und der Unterkante des Kastens lag genau 1 px.
   Der Rechtsklick „unter der letzten Zeile" traf deshalb immer noch eine
   Zeile — das Listenmenue war praktisch nicht erreichbar, obwohl es den
   Zweig seit dem 15.08.2026 gibt. Der Streifen ist die Flaeche, die es
   erreichbar macht; er liegt IM Kasten (also in der Wurzel, an der der
   contextmenu-Hoerer haengt) und traegt keine eigene Zeile im DOM — ein
   zusaetzliches Kind haette verify-kurs-sets.js und die Grundriss-Probe in
   verify-listen.js gebrochen, die die Kinder der Liste aufzaehlen.
   Nur an Listen, die am Kern haengen: `data-lraum` setzt binden(). */
.pp-list[data-lraum] { padding-bottom: 16px; }
/* Eine leere Liste traegt ihren Leertext — dort waere der Streifen doppelt. */
.pp-list[data-lraum]:has(> .pp-empty) { padding-bottom: 0; }

/* Dasselbe fuer die Kursuebersicht (16.08.2026): Ihre Kacheln liegen in
   einem Raster mit `1fr`-Spalten — die letzte Reihe wird gestreckt, unter
   ihr liegt NICHTS. Der Rechtsklick „daneben" traf ohne diesen Streifen
   immer eine Kachel, und das Menue mit „Neuen Kurs erstellen" waere nur
   ueber die 20-px-Luecken zwischen den Kacheln erreichbar gewesen. Kein
   zusaetzliches Kind im DOM, aus demselben Grund wie oben.
   Der Streifen bleibt auch mit der Plus-Kachel (K2, 20.08.2026): Sie
   fuellt die letzte Reihe oft ganz aus, dann ist der Streifen wieder die
   einzige freie Flaeche — und seit T3 erreicht ihn auch ein Long-Press. */
.pp-courses { padding-bottom: 28px; }

/* ---------- Auswahl ---------- */
/* Ohne user-select markiert ein Shift-Klick Text quer ueber die halbe Liste,
   statt einen Bereich zu waehlen (uebernommen von .pp-own-row). */
.pp-list [data-lid] { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

/* ---------- Auswahlleiste: EIN Grundriss, zwei Zustaende ---------- */
/* Sie steht immer da (js/listen.js, auswahlLeisteHtml). Damit das Auswaehlen
   die Liste nicht verschiebt, darf sich zwischen „leer" und „voll" NUR Text
   aendern — nie die Zahl oder die Groesse der Flex-Kinder:
   - der Zaehler wird per [hidden] weggenommen (er ist inline, sein Wegfall
     kostet Breite, keine Hoehe),
   - „Auswahl aufheben" wird UNSICHTBAR, nicht ausgeblendet: display:none
     naehme seine Hoehe mit, und die bestimmt die Hoehe der Leiste,
   - der Hinweis bleibt einzeilig (nowrap + Ellipse), sonst haette ein
     laengerer Text im einen Zustand eine zweite Zeile.
   Gemessen: 50 px in beiden Zustaenden, Versatz 0 px (docs/LISTEN.md 6). */
.pp-sel-bar [hidden] { display: none; }   /* Gegenregel: sonst schlaegt eine
   spaetere display-Regel das Browser-[hidden] (Befund „+ Karte"-Menue der
   Sandbox, verify-auth-formulare.js 7). */
.pp-sel-bar .pp-sel-hint { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pp-sel-bar[data-stand="leer"] { color: var(--pp-text-2); background: none; border-color: var(--pp-line); }
.pp-sel-bar[data-stand="leer"] #sel-clear,
.pp-sel-bar[data-stand="leer"] [data-lsel-clear] { visibility: hidden; }
.pp-list .pp-row.sel {
  background: var(--pp-accent-tint);
  box-shadow: inset 2px 0 0 0 var(--pp-accent);   /* innen: die Zeile behaelt ihre Hoehe */
}
.pp-list .pp-row.sel:hover { background: var(--pp-accent-tint); }

/* ---------- Favoriten ---------- */
/* Der Stern steht IM Titel (::before), nicht als eigene Spalte: Das
   Mobil-Raster von .pp-exam-row adressiert direkte Kinder, und ein
   zusaetzliches Kind landete in einer neuen Rasterzeile (prepp.css:673). */
.pp-list .pp-row.fav > .grow > :first-child::before {
  content: "★ " / ""; color: var(--pp-accent-2); font-size: .92em;   /* Alternativtext leer: nicht vorlesen */
}
.pp-actions .pp-lfav.on { color: var(--pp-accent-2); border-color: var(--pp-accent-line); }
.pp-actions .pp-lfav, .pp-actions .pp-lmore { padding-left: 9px; padding-right: 9px; min-width: 32px; }
.pp-actions .pp-lmore { letter-spacing: 1px; font-weight: 700; }
/* Favoriten-Chip der Kursseite und Zeilen der Startseiten-Karte tragen den Stern in Akzent. */
.pp-chip .pp-fav-stern, .pp-favs-row .pp-fav-stern { color: var(--pp-accent-2); margin-right: 4px; }

/* ---------- Gruppen ---------- */
/* Vor dem Gruppennamen steht KEIN Symbol (24.08.2026, Jonas' Befund).
   Bis dahin trug eine EIGENE Gruppe hier ein ▣ (U+25A3) als ::before —
   „die Nadel sagt, dass man sie selbst angelegt hat". Zwei Gruende, es
   wegzunehmen: Es beantwortete eine Frage, die an dieser Stelle niemand
   stellt (ob eine Gruppe aus den Daten oder von Hand kommt, merkt man beim
   Umbenennen und Aufloesen, und das ⋯-Menue unterscheidet die beiden
   weiterhin mit ▤/▣). Und es war das einzige Zeichen im Kopf: Neben dem
   gezeichneten Chevron stand ein Schriftglyph aus einer fremden Familie,
   fett gefaerbt im Akzent — auffaelliger als der Name daneben.
   Die Klasse `.eigen` bleibt am Markup: Sie sagt, worauf sich das
   Kontextmenue bezieht, und ist der Anknuepfungspunkt, falls die
   Unterscheidung je wieder sichtbar werden soll. */
.pp-set-head { position: relative; }
.pp-set-head .pp-set-more {
  margin-left: 8px; flex: none;
  border: 1px solid transparent; border-radius: 5px; background: none;
  font: inherit; font-size: var(--pp-fs-klein); font-weight: 700; letter-spacing: 1px; line-height: var(--pp-lh-eng);
  padding: 3px 7px; color: var(--pp-text-3); cursor: pointer;
  opacity: 0; transition: opacity .13s ease;
}
.pp-set-head:hover .pp-set-more, .pp-set-head:focus-within .pp-set-more, .pp-set-head.pp-ctx-offen .pp-set-more { opacity: 1; }
.pp-set-head .pp-set-more:hover, .pp-set-head .pp-set-more:focus-visible { color: var(--pp-accent-2); border-color: var(--pp-accent-line); background: var(--pp-accent-tint); }
@media (hover: none) { .pp-set-head .pp-set-more { opacity: 1; } }
/* K3 (wa-3, 27.09.2026, WebKit-Abnahme Stufe 2): Die 44-px-Regeln für das
   ⋯ am Gruppenkopf und für ☆/⋯ an der Zeile standen nur im Telefon-Block
   (max-width: 640px) — auf dem iPad quer (1180 px, grober Zeiger) maßen
   sie 29 × 21 bzw. 33 px Breite. Dieselben Werte deshalb für JEDEN groben
   Zeiger; mit Maus bleibt alles pixelgleich. Hier wächst der KASTEN, nicht
   ein Vorsatz: Ein ::before um das ⋯ des Kopfes reichte in der 43 px hohen
   Kopfzeile nicht bis 44 und ragte sonst in die erste Zeile darunter, und
   ☆/⋯ stehen 8 px auseinander — zwei 44er Vorsätze um 33er Kästen
   überlappten sich (der spätere gewönne). Echte 44 px sind hier der
   überlappungsfreie Weg; im Telefon-Block ist es seit C56 dieselbe Wahl. */
@media (pointer: coarse) {
  .pp-set-head .pp-set-more { padding: 12px 12px; min-width: 44px; min-height: 44px; }
  .pp-actions .pp-lfav, .pp-actions .pp-lmore { min-width: 44px; }
}

/* ---------- Die Luecke zwischen den Bloecken (23.08.2026, Jonas' Befund 9) ----------
   Gemessen in WebKit (1440x950, #course/hm2/exams mit einer eigenen Gruppe
   „Test" und ungruppiertem Rest): JEDES Kind des Kastens meldete
   `margin-top: 0px`, die Zeilen lagen luecklos aneinander (t = 343/385/463/
   541/619). Getrennt haben die Bloecke damit nur zwei Haarlinien, die man
   nicht auseinanderhalten kann: die gewoehnliche `--pp-line`-Unterkante
   (Kontrast zur Flaeche 1,41:1) und die 2-px-Marke `.ohne-start` darunter
   (1,83:1). Ein Gruppenkopf hatte obendrein NULL Flaechenkontrast gegen
   seine eigenen Zeilen, also trug die Trennung allein die Linie — zu wenig.
   NACHTRAG 23.08.2026 (Jonas' Wahl „Kopf bekommt eigene Flaeche"): Der
   Kopf steht seitdem auf `--pp-surface-2` statt `--pp-bg-2` und hat 1,09
   (dunkel) bzw. 1,11 (hell) Flaechenkontrast — Begruendung samt der
   zwingend mitgezogenen Hover-Regel in css/prepp.css bei `.pp-set-head`.
   Die Luecke hier bleibt trotzdem: Sie trennt BLOECKE, nicht Zeilen, und
   1,1 zwischen zwei angrenzenden Flaechen ist eine Kante, kein Abstand.

   Das Mass 16px ist nicht gewaehlt, sondern uebernommen: Es ist der Streifen
   freier Listenflaeche von `.pp-list[data-lraum]` weiter oben. Eine Luecke
   zwischen zwei Bloecken ist dieselbe Sache wie der Rand unter dem letzten
   Block, und so misst der Kasten oben, unten und dazwischen gleich.

   Drei Dinge, die man nicht anders machen darf:
   - `:not(:first-child)` ist Pflicht. `.pp-list` traegt `overflow: hidden`
     und ist damit ein BFC; das Margin eines ERSTEN Kindes kollabiert nicht
     heraus und stuende als leerer Streifen unter der abgerundeten Oberkante.
   - Nur `margin-top` am folgenden Element, nie zusaetzlich `margin-bottom`
     am vorangehenden — sonst 32 px. Angrenzende Geschwistermargins
     kollabieren (`.pp-set-leer` mit 8 px unten neben einem Kopf mit 16 px
     oben ergibt 16, nicht 24 — genau so gewollt).
   - KEIN zusaetzliches Kind im DOM: verify-kurs-sets.js und verify-listen.js
     zaehlen die Kinder der Liste auf (dieselbe Begruendung wie beim
     Streifen der freien Flaeche).

   Zwei gemessene Nebenwirkungen, beide gewollt: Die Luecke IST freie
   Listenflaeche — ein Rechtsklick darin oeffnet das Listenmenue, nicht das
   Gruppenmenue (der Kopf selbst antwortet unveraendert). Und beim Ziehen
   liegt in ihr kein Ablageziel (`zielVon` findet nichts, `dragover` ruft
   kein preventDefault) — die Einfuegekante verschwindet auf 16 px, Zeile und
   Kopf daneben bleiben Ziele. */
.pp-list > .pp-set-head:not(:first-child) { margin-top: 16px; }
.pp-list > .pp-row.ohne-start             { margin-top: 16px; }

/* ---------- Ein Block ist eine Karte (24.08.2026, Jonas' Befund) ----------
   Die Luecke von oben trennte, aber sie RUNDETE nicht: Ein Block endete an
   einer geraden Schnittkante, und weil die Luecke dieselbe Farbe hatte wie
   die Zeilen darueber (`.pp-list` traegt `--pp-surface`, die Zeilen sind
   durchsichtig), sah man von der Trennung nur zwei Haarlinien. Gemessen in
   WebKit bei 1440x950 auf #course/hm2/exams mit einer eigenen Gruppe:
   JEDES Kind meldete `border-radius: 0px`, und Luecke wie Zeile lagen auf
   rgb(22,27,34).

   Zwei Zutaten, und beide braucht es — eine allein zeigt nichts:

   1. RUNDUNG an den Blockkanten. Wo ein Block anfaengt (ein Gruppenkopf,
      der nicht der erste ist; die erste ungruppierte Zeile) oben, wo einer
      endet (das Element unmittelbar VOR so einem Anfang, und das letzte
      Kind) unten. Ausgedrueckt ueber `:has(+ …)` statt ueber eine Klasse:
      js/listen.js schiebt Kopf und Zeilen als flache Geschwister in den
      Kasten, es gibt kein Element je Block — und ein zusaetzliches Kind
      ist ausgeschlossen (verify-listen.js und verify-kurs-sets.js zaehlen
      die Kinder auf). `:has()` steht in dieser Datei schon einmal
      (`[data-lraum]:has(> .pp-empty)`), es kommt also nichts Neues dazu.
   2. GRUND in der Luecke. Ohne sie waere die Rundung unsichtbar: Sie
      klemmt nur die Ecken eines durchsichtigen Kastens, der auf derselben
      Flaeche liegt wie das, was ihn umgibt. Gemalt wird sie als ::before
      des BLOCKANFANGS in die eigene 16-px-Marge hinein — kein Kind im DOM,
      keine Layoutaenderung, und `pointer-events: none`, damit die Luecke
      freie Listenflaeche BLEIBT (Rechtsklick oeffnet weiter das
      Listenmenue, siehe oben).

   Warum `--pp-bg` und nicht `--pp-surface-2`: Die Luecke soll nicht „eine
   andere Flaeche" sein, sondern KEINE — der Blick soll durch den Kasten
   auf die Seite fallen. Genau so entstehen aus einer Liste mehrere Karten.

   Die 8 px sind die des Kastens (`.pp-list`, prepp.css) — dieselbe Sprache
   wie aussen, kein zweites Mass.

   Zwei Dinge, die man nicht anders machen darf:
   - Die untere Kante wird nur DURCHSICHTIG gefaerbt, nicht entfernt: Ein
     `border-bottom: none` naehme der Zeile 1 px Hoehe und schoebe alles
     darunter — die gemessenen Zeilenhoehen (78 px) sollen sich nicht
     aendern.
   - `overflow: hidden` an `.pp-list` bleibt, wie es ist. Es klemmt die
     AUSSENecken und macht den Kasten zum BFC; ohne den kollabierte das
     Margin des ersten Kindes heraus (siehe der Absatz darueber). Die
     Innenecken kommen deshalb von den Kindern selbst. */
.pp-list > .pp-set-head:not(:first-child),
.pp-list > .pp-row.ohne-start {
  border-top-left-radius: 8px; border-top-right-radius: 8px;
}
.pp-list > *:has(+ .pp-set-head),
.pp-list > *:has(+ .pp-row.ohne-start),
.pp-list > *:last-child {
  border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;
  border-bottom-color: transparent;
}
.pp-list > .pp-set-head:not(:first-child)::before,
.pp-list > .pp-row.ohne-start::before {
  content: ""; position: absolute; left: 0; right: 0; top: -16px; height: 16px;
  background: var(--pp-bg); pointer-events: none;
}
/* Der Streifen unter dem letzten Block (`[data-lraum]`) ist dieselbe
   Luecke, nur ohne Nachfolger — er bekommt deshalb denselben Grund. Ohne
   das saehe die Liste unten anders aus als in der Mitte. Nur bei Listen
   MIT Gruppen: ohne sie gibt es keine Bloecke, und der Kasten bleibt die
   eine Karte, die er immer war. */
.pp-list[data-lraum]:has(> .pp-set-head) { position: relative; }
.pp-list[data-lraum]:has(> .pp-set-head)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 16px;
  background: var(--pp-bg); pointer-events: none;
}

/* Wo das Ungruppierte anfaengt (23.08.2026, Jonas' Wunsch „Gruppen oben,
   Ungruppiertes darunter"). Seitdem liegen diese Zeilen UNTER einem
   Gruppenkopf und laesen sich sonst als dessen Inhalt — der Kopf sagt
   „1 Uebung", darunter staenden zwei Zeilen. Eine kraeftigere Linie statt
   einer erfundenen Ueberschrift „Ohne Gruppe": Die Vorlage zeigt keine, und
   in einer Liste ganz ohne Gruppen (der Normalfall) stuende sie ueber allem.
   js/listen.js vergibt die Marke deshalb nur, wenn wirklich eine Gruppe
   darueber steht.
   Gezeichnet als ::after, nicht als border-top und nicht als inset-Schatten.
   Ein Rand schoebe genau diese eine Zeile um 2 px und damit alles darunter;
   ein Schatten teilte sich die EINE box-shadow-Eigenschaft mit .pp-row.sel
   (Auswahlbalken links) und .ins-above (Ablagekante beim Ziehen) — von den
   dreien saehe man je nach Spezifitaet und Quellreihenfolge immer nur eine,
   und ausgerechnet die Ablagekante waere beim Zug auf eine gewaehlte Zeile
   verschwunden. Das Pseudoelement kollidiert mit keinem von beiden.
   .pp-list .pp-pick traegt position:relative bereits (prepp.css). */
.pp-list .pp-row.ohne-start::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--pp-line-2); pointer-events: none;
  /* Seit der Blockrundung (24.08.2026) sitzt die Marke auf einer runden
     Oberkante — ohne denselben Radius stiesse sie an beiden Enden ueber
     die Ecke hinaus. */
  border-top-left-radius: 8px; border-top-right-radius: 8px;
}

/* Der Platzhalter einer noch leeren Fuss-Gruppe (js/listen.js `fuss`,
   wa-5, 27.09.2026): Er steht dort, wo die Gruppe entstuende, und ist ein
   Block wie eine Gruppe — dieselbe Luecke davor, dieselbe Rundung, derselbe
   Seitengrund in der Luecke wie bei Kopf und `ohne-start` oben. Als eigene
   Regeln, damit die Selektorlisten oben unveraendert bleiben (sie werden
   als Text geprueft). Wieder kein zusaetzliches Kind: Der Fuss IST das
   Kind, das der Adapter bestellt hat. */
.pp-list > .pp-lfuss.ohne-kopf:has(> .pp-lfuss-kopf):not(:first-child) {
  margin-top: 16px; border-top-left-radius: 8px; border-top-right-radius: 8px;
}
.pp-list > .pp-lfuss.ohne-kopf:has(> .pp-lfuss-kopf):not(:first-child)::before {
  content: ""; position: absolute; left: 0; right: 0; top: -16px; height: 16px;
  background: var(--pp-bg); pointer-events: none;
}
.pp-list > *:has(+ .pp-lfuss.ohne-kopf > .pp-lfuss-kopf) {
  border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;
  border-bottom-color: transparent;
}

/* ---------- Jeder Block ist sein EIGENER Kasten (UI-Politur, 02.10.2026) ----------
   Jonas' Befund (Bild vom 02.10.): Zwischen zwei Gruppen lief der seitliche
   Rahmen des LISTENKASTENS durch die 16-px-Luecke — die Bloecke sahen aus
   wie Karten IN einem Kasten statt wie Karten nebeneinander. Uebermalen
   ging nicht: Der Rand gehoert `.pp-list`, und deren `overflow: hidden`
   klemmt jedes Kind an der Innenkante; ein ::before kommt an den Rand nie
   heran.

   Deshalb zeichnet in einer Liste MIT Bloecken (eine Gruppe, oder der
   Platzhalter-Fuss mit eigenem Kopf) nicht mehr der Kasten den Rahmen,
   sondern jedes Kind seine Seiten, der Blockanfang seine Oberkante und das
   Blockende seine Unterkante — jeweils mit der Rundung von oben. Der
   Kasten selbst wird rahmen-, schatten- und grundlos; seine 1-px-Raender
   fallen weg (`border: 0`), damit Anfang und Ende der Liste genau dort
   liegen, wo vorher der Kastenrand lag. In der Luecke steht damit nur noch
   der Seitengrund.

   Was gleich bleibt (die Regeln von oben gelten weiter): die Luecke ist
   freie Listenflaeche (Rechtsklick → Listenmenue), kein Kind im DOM,
   `:not(:first-child)` an den Margen, `overflow: hidden` am Kasten. Eine
   Liste OHNE Bloecke ist unveraendert die eine Karte.

   Der Grund der Zeilen kommt jetzt von den Zeilen (ueber `:where`, also
   ohne Spezifitaet — jede Hover-, Auswahl- und Ablagefarbe gewinnt). */
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) {
  border: 0; background: transparent; box-shadow: none;
}
:where(.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf))) > * {
  background-color: var(--pp-surface);
}
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > * {
  border-left: 1px solid var(--pp-line); border-right: 1px solid var(--pp-line);
}
/* Blockanfang: Oberkante und Rundung oben. */
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > :first-child,
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-set-head,
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-row.ohne-start,
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-lfuss.ohne-kopf:has(> .pp-lfuss-kopf) {
  border-top: 1px solid var(--pp-line);
  border-top-left-radius: 8px; border-top-right-radius: 8px;
}
/* Blockende: Unterkante SICHTBAR (oben wurde sie durchsichtig, weil der
   Kastenrand sie trug) und Rundung unten. */
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > *:has(+ .pp-set-head),
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > *:has(+ .pp-row.ohne-start),
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > *:has(+ .pp-lfuss.ohne-kopf > .pp-lfuss-kopf),
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > *:last-child {
  border-bottom: 1px solid var(--pp-line);
  border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;
}
/* Die 2-px-Marke ueber dem Ungruppierten (oben) war die Trennung, solange
   alles in EINEM Kasten stand. Als eigener Kasten traegt der Block seine
   Oberkante selbst — die Marke darunter waere eine zweite Linie. */
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-row.ohne-start::after { display: none; }
/* Die leere eigene Gruppe traegt ihre gestrichelte Flaeche mit Rand nach
   aussen (margin 8px 20px) — in einem Block ohne Kastenrand riss das die
   Seitenlinien des Blocks auf. Hier wird der Abstand Innenabstand und die
   gestrichelte Flaeche ein ::before (kein Kind im DOM). */
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-set-leer {
  position: relative; isolation: isolate; margin: 0; padding: 20px 36px;
  border-top: 0; border-top-left-radius: 0; border-top-right-radius: 0;
  border-left: 1px solid var(--pp-line); border-right: 1px solid var(--pp-line);
  border-bottom-style: solid; border-bottom-color: var(--pp-line);
}
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-set-leer::before {
  content: ""; position: absolute; inset: 8px 20px; pointer-events: none; z-index: -1;
  border: 1px dashed var(--pp-line-2); border-radius: 6px;
}
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-set-leer.drop {
  background: var(--pp-surface);
}
.pp-list:is(:has(> .pp-set-head), :has(> .pp-lfuss.ohne-kopf > .pp-lfuss-kopf)) > .pp-set-leer.drop::before {
  border-color: var(--pp-accent); background: var(--pp-accent-tint);
}

/* Leere eigene Gruppe: eine gestrichelte Ablageflaeche statt nichts —
   sonst waere die Gruppe unerreichbar. */
.pp-set-leer {
  margin: 8px 20px; padding: 12px 14px;
  border: 1px dashed var(--pp-line-2); border-radius: 6px;
  color: var(--pp-text-2); font-size: var(--pp-fs-klein); text-align: center;   /* Anleitung, nicht Zierde: AA */
}
.pp-set-leer.drop { border-color: var(--pp-accent); background: var(--pp-accent-tint); color: var(--pp-accent-2); }

/* ---------- Drag & Drop (Muster Lernplan: prepp.css .lp-unit.ins-above) ---------- */
.pp-list [data-lid][draggable="true"] { cursor: pointer; }
.pp-list [data-lid].dragging { opacity: .45; }
.pp-list [data-lid].ins-above { box-shadow: inset 0 2px 0 0 var(--pp-accent); }
.pp-list [data-lid].ins-below { box-shadow: inset 0 -2px 0 0 var(--pp-accent); }
.pp-set-head.drop { background: var(--pp-accent-tint); box-shadow: inset 0 0 0 1px var(--pp-accent); }
.pp-set-head.drop .name, .pp-set-head.drop .chev { color: var(--pp-accent-2); }

/* ---------- Rueckfrage und Eingabe (ppModal-Inhalt) ---------- */
/* .pp-modal-body bringt bewusst keinen seitlichen Innenabstand mit (der
   Teilen-Dialog traegt ihn selbst) — also auch hier. Gemessen in WebKit:
   ohne Polster klebte der Text an der Dialogkante. */
.pp-frage { display: flex; flex-direction: column; gap: 14px; padding: 16px 20px 20px; }
.pp-frage-text { font-size: var(--pp-fs-text); line-height: var(--pp-lh-text); color: var(--pp-text); }
.pp-frage-liste { margin: 8px 0 0 var(--pp-sp-4); padding: 0; font-size: var(--pp-fs-klein); color: var(--pp-text-2); }
.pp-frage-liste li { margin: 2px 0; }
/* Erst-Upload (Stufe 2, 10-C — js/erst-upload.js): die Aufzählung in der
   Rückfrage „Arbeit von diesem Gerät ins Konto übernehmen?". Steht hier,
   weil sie IN .pp-frage-text lebt; keine eigene Fläche, nur Liste und
   zwei leise Zeilen. */
.pp-eu-liste { margin: 0 0 8px var(--pp-sp-4); padding: 0; }
.pp-eu-liste li { margin: 2px 0; }
.pp-eu-groesse, .pp-eu-hinweis { font-size: var(--pp-fs-klein); color: var(--pp-text-2); }
.pp-eu-hinweis { margin-top: 8px; }
.pp-frage-input {
  width: 100%; box-sizing: border-box; padding: 9px 11px; font: inherit; font-size: var(--pp-fs-text);
  color: var(--pp-text); background: var(--pp-bg); border: 1px solid var(--pp-line-feld); border-radius: 6px;
}
.pp-frage-input:focus { border-color: var(--pp-accent); box-shadow: 0 0 0 3px var(--pp-accent-tint); }
/* Das mehrzeilige Feld (nur mit `mehrzeilig: true`, heute der Titel-Dialog
   des Editors). `display: block` gegen die Grundlinienluecke, die ein
   inline gesetztes <textarea> unter sich laesst; `anywhere` bricht auch
   ein einzelnes langes Wort um (ein Klausurname traegt Bindestriche und
   Punkte, aber nicht immer eine Leerstelle an der richtigen Stelle);
   `resize: vertical` ist der Griff fuer alles ueber sechs Zeilen —
   waagerecht waere er sinnlos, der Dialog hat eine feste Breite. */
.pp-frage-mehr {
  display: block; resize: vertical; overflow-wrap: anywhere;
  line-height: var(--pp-lh-text); max-height: 40vh;
}
.pp-frage-knoepfe { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }

/* ---------- Startseite: Karte „Favoriten" ---------- */
.pp-favs-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 20px; border: 0; background: none; font: inherit; color: var(--pp-text);
  text-align: left; cursor: pointer;
}
.pp-favs-row:hover { background: var(--pp-surface-2); }
.pp-favs-row .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; font-size: var(--pp-fs-klein); }
.pp-favs-row .m { font-size: var(--pp-fs-mini); color: var(--pp-text-3); white-space: nowrap; }
.pp-favs-row .pp-go { font-size: var(--pp-fs-gross); }

/* ---------- Telefon ---------- */
@media (max-width: 640px) {
  .pp-ctx, .sb-ctx, .lab-ctx { min-width: 168px; }
  /* Vom Hinweis bliebe bei 390 px „· ⌘+V f…" übrig — eine Ellipse, die nichts
     sagt (in WebKit gemessen). Und die Tasten, die er nennt, gibt es auf dem
     Telefon ohnehin nicht. Die Hoehe der Leiste haengt an Zaehler, Wort und
     Knopf, nicht am Hinweis — der Versatz bleibt deshalb 0. */
  .pp-sel-bar .pp-sel-hint { display: none; }
  .pp-sel-bar .pp-btn { margin-left: auto; }
  /* Die Klausurzeile traegt jetzt DREI Knoepfe (Anschauen, Stern, ⋯) statt
     einem: In der zweiten Rasterspalte von prepp.css nahmen sie dem Titel
     die Breite (gemessen in WebKit bei 390 px: drei Woerter je Zeile). Wie
     bei .pp-own-row bekommen die Nebenaktionen deshalb eine EIGENE Zeile
     ueber die volle Breite — geteilt wird die Hoehe, nicht die Breite. Die
     Regel steht hier (spezifischer ueber .pp-list), damit prepp.css und
     verify-mobil-kursliste.js unangetastet bleiben. */
  .pp-list .pp-exam-row > .status { grid-column: 1 / -1; grid-row: auto; }
  .pp-list .pp-exam-row > .pp-actions { grid-column: 1 / -1; grid-row: auto; justify-content: flex-end; }
  /* grid-row auto: Zeilen ohne .status (Verlauf, Geteilt, Sandbox) bekommen
     sonst eine leere Rasterzeile samt doppelter Luecke. */
  .pp-set-head .pp-set-more { padding: 12px 12px; min-width: 44px; min-height: 44px; }
  /* Dieselbe Hausvorgabe fuer Stern und ⋯ der Zeile (Befund C56,
     06.09.2026 — R3): Die HOEHE stimmte laengst (44 px aus prepp.css),
     die BREITE blieb bei gemessenen 33 px stehen — `min-width: 32px`
     eine Zeile hoeher war der Deckel, nicht der Boden. Zwei Ikonen
     nebeneinander, 8 px auseinander, ohne Beschriftung: genau der Fall,
     fuer den die 44 px da sind. */
  .pp-actions .pp-lfav, .pp-actions .pp-lmore { min-width: 44px; }
  /* Der Kopf traegt jetzt drei Elemente hinter dem Namen (Anzahl, ⋯):
     Anzahl bleibt einzeilig, der Name darf umbrechen (Regel aus prepp.css). */
}

/* ---------- Telefonbreite bis 600 px: an der Zeile nur „⋯" ----------
   Handy-Schliff 13.10.2026 (docs/abnahme/handy-1013/BERICHT.md): Mit Üben ·
   Anschauen · ☆ · ⋯ war eine Klausurzeile bei 390 px 155–199 px hoch, die
   Knopfreihe stand als eigene Zeile über die volle Breite. Unter 600 px
   bleibt allein das ⋯ — es steht in der ersten Zeile neben dem Pfeil, und
   sein Menü trägt die ausgeblendeten Knöpfe (js/listen.js,
   zeilenKnopfPunkte). Gilt nur für Zeilen des Listenkerns (deren ⋯ heißt
   .pp-lmore); andere .pp-actions bleiben, wie sie sind. */
@media (max-width: 600px) {
  .pp-list .pp-row > .pp-actions:has(> .pp-lmore) > :not(.pp-lmore) { display: none; }
  .pp-list .pp-row:is(.pp-exam-row, .pp-own-row):has(> .pp-actions > .pp-lmore) {
    grid-template-columns: minmax(0, 1fr) auto auto; column-gap: 4px;
  }
  .pp-list .pp-row:is(.pp-exam-row, .pp-own-row) > .pp-actions:has(> .pp-lmore) {
    grid-column: 2; grid-row: 1; align-self: start; flex-wrap: nowrap;
  }
  .pp-list .pp-row:is(.pp-exam-row, .pp-own-row):has(> .pp-actions > .pp-lmore) > .pp-go { grid-column: 3; grid-row: 1; }
  .pp-list .pp-row:is(.pp-exam-row, .pp-own-row):has(> .pp-actions > .pp-lmore) > :is(.status, .pp-tag) { grid-column: 1 / -1; }
  /* Über einer leeren Liste gibt es nichts auszuwählen (js/listen.js,
     zeichneAuswahl setzt die Marke): 64 px „Nichts ausgewählt" weniger. */
  .pp-sel-bar[data-leer-liste] { display: none; }
  /* H1 (Entscheidung 13.10.2026 nachmittags): auch über einer VOLLEN Liste
     keine Leiste, solange nichts ausgewählt ist — auf 390 px kosteten
     64 px „Nichts ausgewählt" Platz für ein seltenes Werkzeug. Sie kommt,
     sobald „Auswählen" im ⋯ oder der lange Druck etwas wählt (data-stand
     „voll", js/listen.js leisteZeichnen). Der Sprung um ihre Höhe stört
     hier nicht: Gewählt wird über ein Menü, das sich dabei schließt. */
  .pp-sel-bar[data-stand="leer"] { display: none; }
}
