/* PMG Publishing App - modernes Design, Lila nur als Akzent, Light & Dark, Sheet-Tabellen */
:root{
  color-scheme:light;
  --bg:#f6f6f7; --panel:#ffffff; --sidebar:#fbfbfc;
  --ink:#1c1c1e; --muted:#6b6b72; --faint:#75757e;
  --border:#e7e7ea; --line:#efeff1; --head:#f4f4f6;
  --row-alt:#fafafb; --row-hover:#f4f2fb;
  --chip:#f0f0f2; --chip-border:#e4e4e8;
  --accent:#6b3fd4; --accent-2:#5a30bd; --accent-soft:#ece5fb; --accent-ink:#4a279f;
  --ok:#3f7a4e; --ok-soft:#e6f0e6; --warn:#8a5a12; --warn-soft:#f5edd8; --err:#a12727;
  /* Schrift, die AUF einer gefuellten Warnfarbe steht. Im hellen Theme ist die
     Flaeche dunkelrot, also weiss darauf. Siehe --on-err im dunklen Theme. */
  --on-err:#ffffff;
  --info:#1e4fd6; --info-soft:#e7f0ff; --info-border:#bcd3ff;
  --err-soft:#fbe9e9;
  /* --brand-spotify und --brand-apple sind am 11.08.2026 entfallen (Paket
     13/1.8): die beiden Logo-Knoepfe tragen jetzt --accent, und danach las die
     Tokens niemand mehr. Ein Farbwert, den nichts benutzt, sieht beim naechsten
     Lesen aus wie eine Farbe, die man verwenden darf. */
  --radius:12px; --shadow:0 1px 2px rgba(40,25,70,.06);
  --serif:Georgia,"Iowan Old Style","Times New Roman",serif;
  --sans:-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;

  /* ---- Masse (Paket D2, 09.08.2026) -------------------------------------
     Vorher standen im Stylesheet neunzehn verschiedene Abstandswerte, sechzehn
     Schriftgroessen (darunter vier mit halbem Pixel, die je Browser anders
     runden) und zwoelf Radien - alle als nackte Zahl. Zwei Karten nebeneinander
     hatten dadurch verschiedene Innenabstaende, ohne dass es jemand wollte.
     Ab hier gilt: kein nackter Pixelwert mehr fuer Abstand, Groesse, Radius,
     Ebene oder Dauer. Wer eine Stufe dazwischen braucht, braucht sie nicht. */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:24px; --sp-7:32px; --sp-8:48px;
  --fs-xs:11px; --fs-sm:12.5px; --fs-md:13.5px; --fs-base:15px;
  --fs-lg:17px; --fs-xl:22px;   --fs-2xl:30px;
  --r-sm:6px; --r-md:9px; --r-lg:12px; --r-xl:16px; --r-pill:999px;
  /* Ebenen als Leiter statt als Zufall: vorher lagen .fd2modal und .pmgmodal
     beide auf 70 und ueberdeckten sich je nach Reihenfolge im Quelltext. */
  --z-menu:20; --z-selbar:45; --z-backdrop:50; --z-drawer:60;
  --z-modal:70; --z-cmdk:80; --z-toast:90;
  --dur-fast:.15s; --dur-base:.24s; --ease-out:cubic-bezier(.2,.9,.3,1);
  /* Schalter und Haekchen: eigene Werte, weil --chip fuer eine 25 px hohe
     Bahn zu blass ist - ausgeschaltet muss man sie als Flaeche erkennen. */
  --sw-off:#d6d6dc; --sw-off-b:#c4c4cd; --sw-off-h:#c9c9d2;
  --cb-bg:#ffffff; --cb-border:#c2c2cc;
  /* Rollbalken. Bewusst NICHT --chip-border: der ist als Trennlinie gedacht
     und im dunklen Theme so leise, dass ein Balken daraus schlicht unsichtbar
     ist. Ein Rollbalken muss man SEHEN - er ist die einzige Auskunft darueber,
     dass rechts oder unten noch etwas kommt. */
  --sb-thumb:#c4c4ce; --sb-thumb-h:#a2a2ae; --sb-thumb-a:#8a8a97;
  --sb-track:rgba(20,10,40,.05);

  /* ---- Eingabefelder (07.09.2026) --------------------------------------
     Felder hatten `background:var(--panel)` - dieselbe Farbe wie die Karte,
     in der sie stehen. Im hellen Theme traegt der Rahmen die Erkennbarkeit
     noch; im dunklen ist --panel #1c1c1f und --border #2b2b30, und damit war
     nicht zu sehen, WO man etwas eingibt. Gemeldet von Johannes.

     Ein Feld braucht eine eigene Flaeche, nicht nur eine Linie. Hell bleibt
     es weiss (die Karte ist ebenfalls weiss, hier traegt der Rahmen), dunkel
     wird es TIEFER als die Karte - ein Feld ist eine Mulde, in die man
     schreibt, und dunkler heisst in einem dunklen Theme "tiefer". */
  --field:#ffffff; --field-border:#d9d9e0;
}
[data-theme="dark"]{
  /* Sagt dem Browser, dass hier ein dunkles Theme laeuft. Ohne diese eine
     Zeile zeichnet er Haekchen, Auswahlfelder, Rollbalken und Kalenderblaetter
     weiterhin hell - weisse Kaestchen auf dunklem Grund. */
  color-scheme:dark;
  --bg:#141416; --panel:#1c1c1f; --sidebar:#171719;
  --ink:#ececee; --muted:#a2a2aa; --faint:#8b8b95;
  --border:#2b2b30; --line:#242428; --head:#212125;
  --row-alt:#1f1f22; --row-hover:#272430;
  --chip:#26262b; --chip-border:#34343b;
  --accent:#9575f2; --accent-2:#a488f5; --accent-soft:#2a2340; --accent-ink:#c9b6ff;
  --ok:#82c07d; --ok-soft:#20301f; --warn:#d3a24c; --warn-soft:#332913; --err:#e88886;
  /* FIX 09.08.2026: --err ist im dunklen Theme absichtlich HELL - als Schriftfarbe
     auf dunklem Grund ist das richtig (rund 7:1). Als FLAECHE mit weisser Schrift
     war es dagegen unlesbar (rund 2:1), und genau das machte .btn.danger:hover.
     Deshalb steht die Schriftfarbe jetzt in einer eigenen Variablen: auf der
     hellen Flaeche des dunklen Themes gehoert dunkle Schrift. */
  --on-err:#1a1012;
  --info:#8fb4ff; --info-soft:#16294d; --info-border:#2c4a86;
  --err-soft:#33191a;
  /* Die Markenfarben bleiben, was sie sind - sie gehoeren Spotify und Apple und
     duerfen sich nicht mit dem Theme aendern. Sie stehen trotzdem als Variable
     da, damit sie nicht mitten in einer Regel als Hex-Wert auftauchen. */
  --shadow:0 1px 2px rgba(0,0,0,.3);
  /* Dunkel: die AUS-Bahn ist ein tiefes Grau, deutlich dunkler als die Karte,
     damit sie als Vertiefung liest. Das leere Haekchen ebenso - vorher war es
     das weisse Systemkaestchen. */
  --sw-off:#3a3a44; --sw-off-b:#4a4a56; --sw-off-h:#454552;
  --cb-bg:#212127; --cb-border:#4a4a56;
  /* Dunkel deutlich heller als die Flaeche darunter (#1c1c1f), sonst
     verschwindet der Balken im Panel. */
  --sb-thumb:#55555f; --sb-thumb-h:#71717e; --sb-thumb-a:#8d8d9a;
  --sb-track:rgba(255,255,255,.045);

  /* Das Feld liegt TIEFER als die Karte (#1c1c1f) und hat einen Rahmen, der
     deutlich heller ist als eine normale Trennlinie (--border #2b2b30). Beides
     zusammen macht aus einer Linie eine Mulde - man sieht auf einen Blick, wo
     etwas eingegeben wird. Siehe die Begruendung bei --field im hellen Theme. */
  --field:#101013; --field-border:#3e3e48;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{background:var(--bg);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.5}
a{color:var(--accent-ink);text-decoration:none}
h1,h2,h3{font-family:var(--serif);font-weight:600;color:var(--ink);margin:0}
.layout{display:flex;min-height:100vh}
/* ---- Breite der Seitenleiste als Variable (26.08.2026) -------------------
   Eine Zahl an einer Stelle: die Leiste, ihr Flex-Anteil und der Griff daneben
   rechnen alle damit. Eingeklappt geht sie auf 0 - nicht auf eine schmale
   Icon-Leiste. Gewuenscht war "die Seite wird mehr oder weniger fullscreen",
   und eine halb da stehende Leiste ist von beidem das Schlechtere. */
:root{--side-w:236px; --side-ms:280ms; --side-ease:cubic-bezier(.4,0,.2,1)}
.sidebar{width:var(--side-w);flex:0 0 var(--side-w);background:var(--sidebar);border-right:1px solid var(--border);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;
  transition:width var(--side-ms) var(--side-ease),flex-basis var(--side-ms) var(--side-ease)}
/* Der Inhalt darf beim Schrumpfen nicht umbrechen - sonst zappelt die Schrift
   waehrend der Bewegung. Er wird abgeschnitten, die Leiste ist ja im Gehen. */
.sidebar > *{min-width:0}
.side-off .sidebar{width:0;flex-basis:0;border-right-color:transparent}
.side-off .sidebar .logo,
.side-off .sidebar .navwrap,
.side-off .sidebar .sideuser{opacity:0;pointer-events:none;
  transition:opacity 140ms linear}
.sidebar .logo,.sidebar .navwrap,.sidebar .sideuser{opacity:1;transition:opacity 200ms linear 80ms}
/* ---- Der Griff -----------------------------------------------------------
   Mittig am rechten Rand der Leiste, halb darueber hinaus. Er gehoert zur
   Leiste und wandert deshalb mit ihr - eingeklappt steht er am linken
   Bildschirmrand und ist der einzige Weg zurueck. Deshalb bleibt er sichtbar
   und wird nicht mit ausgeblendet. */
/* Schmaler und hoeher (26.08.2026, zweiter Anlauf): 18 x 76 statt 26 x 52 -
   ein Griff, kein Knopf. Und die linke Kante ist jetzt DA, statt zu fehlen:
   vorher lief `border-left:none` gegen den Rand der Leiste, und beim Zeigen
   faerbte sich die Umrandung ein - nur eben dreiseitig. Ein Rahmen, der an
   einer Seite aufhoert, sieht abgeschnitten aus, weil er es ist.

   Jetzt umschliesst der Rahmen den Griff vollstaendig, und die Kante zur
   Leiste hin uebernimmt deren Farbe. Eingeklappt steht er frei am
   Bildschirmrand und ist dann ohnehin rundum sichtbar. */
.sidegrip{position:absolute;top:50%;right:-10px;transform:translateY(-50%);z-index:40;
  width:18px;height:76px;border-radius:var(--r-pill);
  background:var(--panel);border:1px solid var(--border);
  color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center;
  padding:0;box-shadow:var(--shadow)}
.sidegrip:hover{background:var(--accent-soft);color:var(--accent-ink);border-color:var(--accent)}
.sidegrip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.sidegrip .chev{display:flex;transition:transform var(--side-ms) var(--side-ease)}
.side-off .sidegrip .chev{transform:rotate(180deg)}
/* Eingeklappt ist die Leiste 0 breit - der Griff haenge sonst zur Haelfte
   ausserhalb des Bildschirms und waere genau dann schlecht zu treffen, wenn er
   der einzige Weg zurueck ist. Er rueckt deshalb um seine ganze Breite nach
   rechts und steht vollstaendig am Rand. */
.side-off .sidegrip{right:-24px}
.sidegrip{transition:right var(--side-ms) var(--side-ease),background 140ms ease,
  color 140ms ease,border-color 140ms ease}
/* Der Pfeil ist bei 18 px Breite das groesste Element im Griff - er darf nicht
   ueberstehen. */
.sidegrip .chev svg{width:13px;height:13px}
/* ---- Das Logo in der Kopfleiste -----------------------------------------
   Es steht immer im Markup, damit die Animation seine Zielposition messen
   kann, bevor es jemand sieht. Ausgeklappt belegt es keinen Platz. */
.topbrand{display:none;align-items:center;flex:none}
.topbrand img{height:24px;width:auto;display:block}
[data-theme="dark"] .topbrand img{filter:invert(1) brightness(1.7)}
.side-off .topbrand{display:flex}
@media (prefers-reduced-motion:reduce){
  .sidebar,.sidegrip .chev,.sidebar .logo,.sidebar .navwrap,.sidebar .sideuser{transition:none}
}
/* Kopf und Fuss der Seitenleiste bewusst knapp gehalten: jeder Pixel hier ist
   ein Pixel, den die Navigation nicht zum Scrollen braucht. Mit 14 Menuepunkten
   plus fuenf Gruppen lief die Master-Navigation sonst schon bei 900 px
   Fensterhoehe ueber. */
.logo{padding:var(--sp-4) var(--sp-5) var(--sp-3)}
.logo img{height:27px;width:auto;display:block}
[data-theme="dark"] .logo img{filter:invert(1) brightness(1.7)}
/* navwrap ist der Rahmen, .nav der scrollende Teil. Getrennt, damit die weiche
   Kante unten stehen bleibt, statt mit dem Inhalt wegzuscrollen. min-height:0
   ist noetig, sonst weigert sich ein Flex-Kind, kleiner als sein Inhalt zu
   werden, und die Leiste waechst aus dem Fenster heraus statt zu scrollen. */
.navwrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}
.navwrap::after{content:"";position:absolute;left:0;right:0;bottom:0;height:26px;pointer-events:none;
  background:linear-gradient(to bottom,transparent,var(--sidebar));opacity:0;transition:opacity .18s ease}
.navwrap.has-more::after{opacity:1}
.nav{padding:var(--sp-1) var(--sp-3) var(--sp-2);flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}
/* line-height ausdruecklich gesetzt: die geerbten 1.5 aus body machten jede
   Zeile 4 px hoeher, ueber 14 Punkte summiert sich das. 30 px Zeilenhoehe
   bleiben mit der Maus bequem treffbar. */
/* Kein Abstand zwischen den Punkten (07.09.2026, Wunsch Johannes). Vorher
   standen 4 px (--sp-1) zwischen den Zeilen; damit schwebten die Hover-Flaechen
   einzeln in der Leiste, statt eine zusammenhaengende Liste zu bilden - und
   ueber vierzehn Punkte summierten sich 56 px, die in einer Leiste fehlen, die
   auf kleinen Bildschirmen ohnehin scrollt. Die Flaechen schliessen jetzt
   aneinander an; die Trennung leistet der Wechsel der Hintergrundfarbe beim
   Zeigen, nicht der Zwischenraum. Die Handy-Ansicht (Paket 7) machte das schon
   so - der Unterschied war ein Versehen, kein Entwurf. */
.nav a{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2) var(--sp-3);border-radius:var(--r-sm);color:var(--muted);font-size:14px;line-height:1.3;margin-bottom:0}
.nav a:hover{background:var(--row-hover);color:var(--ink)}
.nav a.active{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.nav a .ic{width:17px;text-align:center;opacity:.85;flex:0 0 auto}
.nav .badge{margin-left:auto;background:var(--accent);color:#fff;border-radius:20px;font-size:11px;padding:1px 7px;font-weight:600;flex:0 0 auto}
/* Bleibt die Leiste doch einmal zu lang - kleiner Bildschirm, weitere
   Menuepunkte -, soll der Balken nicht der graue Systembalken sein, sondern
   schmal, rund und in den Farben der App. Er erscheint erst beim Zeigen auf die
   Leiste, damit er im Ruhezustand nicht stoert, und ist mit 8 px breit genug,
   um ihn auch mit der Maus zu greifen. */
/* Die Seitenleiste hatte hier einen EIGENEN Rollbalken-Block mit anderen
   Farben und anderer Breite. Er ist entfallen - die globalen Regeln im
   Abschnitt "Rollbalken" weiter unten gelten jetzt auch hier, mit einer
   einzigen Ausnahme (schmaler, ohne Rinne), die dort direkt danebensteht.
   ACHTUNG, gilt weiterhin: sobald scrollbar-color gesetzt ist, ignoriert
   Chromium saemtliche ::-webkit-scrollbar-Regeln und zeichnet einen
   Ueberlagerungsbalken, der keine Breite belegt und nur waehrend des Scrollens
   aufblitzt. Die Standard-Eigenschaft steht deshalb NUR im @supports-Zweig
   fuer Firefox, wo es die Pseudo-Elemente nicht gibt. */
.sideuser{border-top:1px solid var(--border);padding:var(--sp-3) var(--sp-4);display:flex;align-items:center;gap:var(--sp-3)}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--accent-soft);color:var(--accent-ink);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:13px}
.sideuser .nm{font-size:13px;font-weight:600}
.sideuser .rl{font-size:11px;color:var(--faint)}
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{background:var(--panel);border-bottom:1px solid var(--border);padding:var(--sp-4) var(--sp-7);display:flex;align-items:center;gap:var(--sp-4)}
.topbar h1{font-size:22px}
.topbar .sub{color:var(--muted);font-size:14px;font-family:var(--sans)}
.topbar .spacer{flex:1}
.chip{display:flex;align-items:center;gap:var(--sp-2);font-size:14px}
.themebtn{border:1px solid var(--border);background:var(--panel);color:var(--muted);border-radius:9px;width:36px;height:36px;cursor:pointer;font-size:16px}
.themebtn:hover{color:var(--ink);border-color:var(--accent)}
.content{padding:var(--sp-7) var(--sp-7) var(--sp-8)}
.flash{background:var(--accent-soft);border:1px solid var(--chip-border);color:var(--accent-ink);padding:var(--sp-3) var(--sp-4);border-radius:var(--r-md);margin-bottom:var(--sp-4);font-size:14px}
.grid{display:grid;gap:var(--sp-4)}
.cols-4{grid-template-columns:repeat(4,1fr)}
.cols-3{grid-template-columns:repeat(3,1fr)}
.cols-2{grid-template-columns:2fr 1fr}
.card{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:var(--sp-5) var(--sp-6);box-shadow:var(--shadow)}
.card h2{font-size:var(--fs-lg);margin-bottom:var(--sp-1)}
/* ---- Karte an Karte: EIN Abstand (26.08.2026) ---------------------------
   Vorher trug jede Vorlage ihn selbst - mal mb-5, mal mb-4, mal mt-5, mal gar
   nichts. Vier Werte fuer dieselbe Fuge, und die Seiten sahen dadurch
   unterschiedlich luftig aus, ohne dass es jemand entschieden hatte.

   Die Regel greift nur zwischen Geschwistern und nur im normalen Fluss - im
   .grid zaehlt dessen gap. Wo eine Vorlage zusaetzlich mb-4 setzt, fallen
   beide Werte zusammen (Margin-Collapsing), es entsteht also kein doppelter
   Abstand. */
.card + .card,.card + .foldcard,.foldcard + .card,.foldcard + .foldcard,
.card + .sheetwrap,.sheetwrap + .card{margin-top:var(--sp-4)}
/* ---- ... aber nicht im Raster (07.09.2026) ------------------------------
   Gefunden beim dritten Anlauf an "die Works-Kachel ist hoeher als die
   anderen". Es war nie die Kachel, es war diese Regel eine Zeile darueber:
   die vier Kacheln der Portal-Uebersicht sind aufeinanderfolgende .card, also
   bekamen die Kacheln 2, 3 und 4 je 16 px margin-top. In einem Raster wandert
   ein Element damit in seiner Zelle nach unten, waehrend die Zeilenhoehe
   gleich bleibt - die erste Kachel fuellt die ganze Hoehe, die drei anderen
   sitzen tiefer und sehen 16 px kuerzer aus. Genau das war zu sehen.

   Die Regel gehoert dem gestapelten Fluss: dort steht eine Karte UNTER der
   anderen und braucht Abstand. Im Raster macht das der `gap` - eine zweite
   Quelle fuer denselben Abstand ist immer eine zu viel. Gilt fuer jedes
   .grid der App, nicht nur fuer diese vier. */
.grid > .card + .card,.grid > .card + .foldcard,
.grid > .foldcard + .card,.grid > .foldcard + .foldcard{margin-top:0}
/* ---- .hint: der eine Erklaertext ----------------------------------------
   Erklaerungen unter einer Ueberschrift standen bisher in vier verschiedenen
   Groessen nebeneinander: 11.5, 12, 12.5 und 13 px, dazu Absaetze ganz ohne
   Angabe, die die 15 px des Fliesstexts erbten und dadurch fast so gross waren
   wie die Ueberschrift darueber. Ab jetzt gibt es genau eine Groesse. Die Regel
   ist bewusst NICHT mehr auf .card beschraenkt - sie galt sonst nur in Karten,
   und ausserhalb fiel derselbe Absatz auf Fliesstextgroesse zurueck.
   Wer hier eine Ausnahme braucht, braucht in Wahrheit keinen Hinweis. */
.hint{color:var(--muted);font-size:var(--fs-sm);line-height:1.45;margin:var(--sp-1) 0 0}
p.hint{margin:var(--sp-1) 0 0}
.hint a{color:var(--accent-ink)}
.stat{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:var(--sp-5)}
.stat .lab{color:var(--muted);font-size:13px}
.stat .num{font-family:var(--serif);font-size:var(--fs-2xl);font-weight:600;margin-top:var(--sp-2)}
.stat .dl{font-size:var(--fs-sm);margin-top:var(--sp-1);color:var(--ok)}
.stat.warn{background:var(--warn-soft);border-color:var(--warn)}
.stat.warn .num,.stat.warn .dl{color:var(--warn)}
/* ---- .foldcard: eine Karte, die sich zuklappen laesst (26.08.2026) -------
   Gebaut auf <details>/<summary> und nicht auf JavaScript: das Aufklappen ist
   dann eine Browserfunktion - sie funktioniert ohne Skript, der Browser findet
   Text auch in zugeklappten Abschnitten (Strg+F), und die Tastaturbedienung
   ist geschenkt.

   Der Kopf traegt rechts einen Platz fuer den Zustand (.foldstate). Genau das
   ist der Sinn des Ganzen: zugeklappt muss man sehen, ob etwas fehlt, ohne
   aufzuklappen. Eine Klappe, die ihren Inhalt vollstaendig verbirgt, macht aus
   drei Blicken vier Klicks. */
.foldcard{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow);margin-bottom:var(--sp-4);overflow:hidden}
.foldcard > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-5) var(--sp-6);min-height:38px;user-select:none}
.foldcard > summary::-webkit-details-marker{display:none}
.foldcard > summary:hover{background:var(--row-hover)}
.foldcard > summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.foldcard > summary h2{font-size:17px;margin:0;display:flex;align-items:center;gap:var(--sp-2)}
.foldcard .foldsub{color:var(--muted);font-size:var(--fs-sm)}
.foldcard .foldstate{margin-left:auto;display:flex;align-items:center;gap:var(--sp-2)}
/* Der Pfeil dreht sich, statt zu springen - dieselbe Kurve wie der Griff an
   der Seitenleiste, damit sich die App an allen Klappen gleich anfuehlt. */
.foldcard .foldx{display:flex;color:var(--muted);transition:transform 220ms var(--side-ease,ease)}
.foldcard[open] > summary .foldx{transform:rotate(180deg)}
.foldbody{padding:0 var(--sp-6) var(--sp-5)}
.foldcard[open] > summary{border-bottom:1px solid var(--border);margin-bottom:var(--sp-5)}
@media (prefers-reduced-motion:reduce){.foldcard .foldx{transition:none}}
@media (max-width:860px){.foldcard > summary{padding:var(--sp-4)}.foldbody{padding:0 var(--sp-4) var(--sp-4)}}

/* ---- Symbole in Knoepfen: eine Zeile, keine Schraeglage ------------------
   `.icon` traegt global ein `vertical-align:-.125em` - richtig im Fliesstext,
   wo das Symbol auf der Schriftlinie sitzt. In einem Flex-Knopf ist
   vertical-align wirkungslos, aber `align-self` gilt: ohne diese Zeile
   entscheidet der Browser anhand der Zeilenhoehe, und bei ungeraden Groessen
   landet das Symbol einen halben Pixel zu tief. Genau daran sieht ein Plus in
   einem Knopf "verrutscht" aus. */
.btn > .icon,.btn > svg{align-self:center;vertical-align:0;flex:0 0 auto}
.btn{line-height:1.25}

/* ---- .pick: eine Entscheidung je Zeile (Import-Vorschau, 26.08.2026) -----
   Kaestchen und Beschriftung sind EIN Klickziel, und die Zeilenhoehe haelt die
   38 px der uebrigen Klickflaechen ein - in einer Tabelle mit dreissig Zeilen
   ist ein 13-px-Kaestchen sonst ein Treffspiel. */
.pick{display:flex;align-items:center;gap:var(--sp-2);min-height:38px;
  font-size:var(--fs-md);cursor:pointer;white-space:nowrap}
.pick input{flex:none;margin:0}
.pick.accent{color:var(--accent)}

/* ---- .warnline: eine Zeile, die nur bei einem Problem erscheint ----------
   BAK-01 (26.08.2026). Bewusst KEINE Kachel: eine Anzeige, die immer gruen
   danebensteht, wird nach der zweiten Woche nicht mehr gelesen - und dann
   auch nicht, wenn sie rot ist. Dieselben Tokens wie .stat.warn, damit
   "Achtung" in der ganzen App eine Farbe hat und nicht drei. */
.warnline{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  background:var(--warn-soft);border:1px solid var(--warn);color:var(--warn);
  border-radius:var(--radius);padding:10px 14px;margin-bottom:var(--sp-4)}
.warnline a{color:var(--warn);text-decoration:underline}
.warnline svg{flex:none}
.btn{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--border);background:var(--panel);color:var(--ink);padding:8px 15px;border-radius:9px;font-size:14px;cursor:pointer;font-family:var(--sans)}
.btn:hover{border-color:var(--accent);background:var(--row-hover)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn.primary:hover{background:var(--accent-2)}
/* Ein gesperrter Knopf muss auch gesperrt AUSSEHEN. Ohne diese Regel sah der
   Absendeknopf bei erreichter Schreibgrenze normal aus und liess sich nur nicht
   druecken - das wirkt wie ein Fehler statt wie eine Absicht. */
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed}
.btn:disabled:hover,.btn[disabled]:hover{border-color:var(--border);background:var(--panel)}
.btn.primary:disabled:hover,.btn.primary[disabled]:hover{background:var(--accent)}
.btn.ghost{background:transparent}
.btn.sm{padding:5px 11px;font-size:13px}
.toolbar{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-4);flex-wrap:wrap}
.search{position:relative;flex:1;min-width:240px;max-width:420px}
/* 07.09.2026: Die Suche trug die Feldgroesse von 14 px. In einer Filterzeile
   neben Auswahlfeldern und Datumsangaben ist sie damit das lauteste Element -
   und sie ist das Feld, in dem am wenigsten steht. --fs-md ist die Groesse,
   in der auch die Tabellen darunter schreiben. */
.search input{width:100%;font-size:var(--fs-md)}
/* Datumsfelder gehoeren hier ausdruecklich dazu. Fehlten sie, fiel input[type=date]
   auf den nackten Browser-Stil zurueck: andere Hoehe als die Nachbarfelder, grauer
   Systemrahmen, und im dunklen Theme dunkle Schrift auf dunklem Grund. Genau das
   sah in der Filterzeile des Audit Logs falsch aus. */
input[type=text],input[type=email],input[type=password],input[type=search],input[type=date],input[type=datetime-local],input[type=number],select{width:100%;padding:9px 12px;border:1px solid var(--field-border);border-radius:9px;background:var(--field);font-size:14px;font-family:var(--sans);color:var(--ink)}
/* Der Fokus traegt jetzt beides: den farbigen Rahmen UND einen Ring. Vorher
   war der Ring im dunklen Theme (--accent-soft #2a2340) gegen eine Karte in
   #1c1c1f kaum zu sehen - der einzige Hinweis auf das aktive Feld war ein
   Rahmen in Lila, und der verschwand bei schmalen Feldern. */
input:focus,select:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft),0 0 0 1px var(--accent)}
input:hover:not(:focus),select:hover:not(:focus),textarea:hover:not(:focus){border-color:var(--muted)}
input::placeholder,textarea::placeholder{color:var(--faint)}

/* Paket 13, 2.5: Auswahlfelder sahen als einzige Bedienelemente noch aus, wie
   der Browser sie gerade zeichnet - je nach System unterschiedlich hoch, mit
   fremdem Pfeil und in Chrome mit einem grauen Hintergrund, der neben den
   weissen Textfeldern daneben auffiel.

   appearance:none nimmt die Systemzeichnung weg, der Pfeil kommt als Inline-SVG
   im Hintergrund. `currentColor` geht in einer data-URL nicht - deshalb steht
   die Farbe zweimal da, hell und dunkel; sie ist bewusst --muted, damit der
   Pfeil den Wert nicht ueberstimmt.

   Gilt global fuer jedes select, nicht nur fuer das eine im Portal: ein Feld,
   das anders aussieht als die zwoelf daneben, ist genau der Bruch, den 2.5
   beheben soll. */
select{
  appearance:none;-webkit-appearance:none;-moz-appearance:none;
  min-height:38px;                       /* wie .btn und die Textfelder */
  padding-right:34px;                    /* Platz fuer den Pfeil */
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236f6f78' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 11px center;
  cursor:pointer;
}
[data-theme="dark"] select{
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b8b95' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
/* Kein eigenes color-scheme noetig: es steht in :root und in [data-theme=dark]
   und wird vererbt. Die aufklappende Liste zeichnet damit das Betriebssystem
   im richtigen Theme. */
select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
select:disabled{opacity:.6;cursor:default;background-image:none}
/* select ist eine Ausnahme von der Breitenregel oben: in Werkzeugleisten steht
   es neben Knoepfen und soll dort nicht die ganze Zeile nehmen. */
.toolbar select,.hstack select{width:auto}
/* Gleiche Hoehe wie die Textfelder daneben. color-scheme sorgt dafuer, dass das
   aufklappende Kalenderblatt im dunklen Theme ebenfalls dunkel ist - sonst
   springt ein grellweisser Kasten auf. */
input[type=date],input[type=datetime-local]{min-height:38px;line-height:1.2;color-scheme:light}
[data-theme="dark"] input[type=date],[data-theme="dark"] input[type=datetime-local]{color-scheme:dark}
input[type=date]::-webkit-calendar-picker-indicator,
input[type=datetime-local]::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.5;padding:2px;border-radius:5px;transition:opacity .15s ease,background .15s ease}
input[type=date]:hover::-webkit-calendar-picker-indicator,
input[type=datetime-local]:hover::-webkit-calendar-picker-indicator{opacity:.9}
input[type=date]::-webkit-calendar-picker-indicator:hover,
input[type=datetime-local]::-webkit-calendar-picker-indicator:hover{opacity:1;background:var(--accent-soft)}
/* Kein filter:invert im dunklen Theme - color-scheme:dark laesst den Browser das
   Kalendersymbol bereits hell zeichnen. Eine zusaetzliche Umkehrung drehte es
   wieder auf dunkel und machte es auf dunklem Grund praktisch unsichtbar. */
/* Ein leeres Datumsfeld zeigt sonst ein blasses tt.mm.jjjj, das wie ein Fehler wirkt. */
input[type=date]::-webkit-datetime-edit{color:var(--ink)}
input[type=date]:invalid::-webkit-datetime-edit{color:var(--faint)}
/* ---- Popup-Muster ----
   Gemeinsam fuer Foundry und Inbox, damit es das nicht zweimal als seitenlokales
   CSS gibt. Wichtig ist die Reihenfolge: OHNE die Klasse "js" am <html> bleibt
   ein .pmgmodal eine ganz normale Karte im Seitenfluss. Das Formular steht immer
   im Quelltext und wird nur per JavaScript versteckt - faellt das Skript aus,
   erscheint es als Karte statt gar nicht. Bei einem Meldeweg fuer Probleme darf
   ein Skriptfehler nicht den einzigen Kanal zusperren. */
.pmgmodal{position:fixed;inset:0;z-index:70;background:rgba(0,0,0,.38);align-items:center;justify-content:center;padding:20px}
.pmgbox{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:20px;width:440px;max-width:92vw;max-height:88vh;overflow:auto;box-shadow:0 18px 50px rgba(20,10,40,.28)}
.pmgbox h3{margin:0 0 12px;font-size:16px}
.pmgbox .field{margin-bottom:10px}
.pmgbox label{display:block;font-size:12px;color:var(--muted);margin-bottom:3px}
.pmgbox input,.pmgbox select,.pmgbox textarea{width:100%;padding:8px 10px;border:1px solid var(--border);border-radius:8px;background:var(--bg);color:var(--ink);font-size:14px;font-family:var(--sans)}
.pmgbox input:disabled{opacity:.55}
.pmgbox.wide{width:620px}
.pmghead{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.pmghead h3{flex:1;margin:0}
.pmgx{background:none;border:none;font-size:20px;line-height:1;color:var(--muted);cursor:pointer;padding:0 4px;border-radius:6px}
.pmgx:hover{color:var(--ink);background:var(--row-hover)}
html.js .pmgmodal{display:none}
html.js .pmgmodal.open{display:flex}
/* Ohne JavaScript: normale Karte, kein Overlay, kein Schliessknopf. */
html:not(.js) .pmgmodal{position:static;background:none;padding:0;display:block}
html:not(.js) .pmgbox{width:auto;max-width:none;max-height:none;box-shadow:var(--shadow);margin-bottom:16px}
html:not(.js) .pmgx,html:not(.js) [data-modal-open],html:not(.js) [data-modal-close]{display:none}

.menu{position:relative;display:inline-block}
.menu-body{display:none;position:absolute;right:0;top:calc(100% + 6px);background:var(--panel);border:1px solid var(--border);border-radius:10px;box-shadow:0 8px 24px rgba(20,10,40,.18);padding:8px;min-width:230px;z-index:20}
.menu.open .menu-body{display:block}
.menu-body .row{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;font-size:14px}
.menu-body .row:hover{background:var(--row-hover)}
.menu-body button.link{background:none;border:none;color:var(--ink);font-size:14px;cursor:pointer;width:100%;text-align:left;padding:8px;border-radius:7px;font-family:var(--sans)}
.menu-body button.link:hover{background:var(--row-hover)}
.menu-body input[type=text]{margin:4px 0}
.sheetwrap{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);overflow:auto;box-shadow:var(--shadow)}
table.sheet{width:100%;border-collapse:collapse;font-size:13.5px}
table.sheet thead th{position:sticky;top:0;background:var(--head);text-align:left;font-family:var(--sans);font-weight:600;color:var(--muted);font-size:12px;letter-spacing:.03em;padding:11px 14px;border-bottom:1px solid var(--border);border-right:1px solid var(--line);white-space:nowrap}
table.sheet thead th:last-child{border-right:none}
table.sheet thead th.drag{cursor:grab}
table.sheet thead th.dragover{background:var(--accent-soft);color:var(--accent-ink)}
table.sheet tbody td{padding:10px 14px;border-bottom:1px solid var(--line);border-right:1px solid var(--line);vertical-align:top;color:var(--ink)}
table.sheet tbody td:last-child{border-right:none}
table.sheet tbody tr:nth-child(even){background:var(--row-alt)}
table.sheet tbody tr:hover{background:var(--row-hover)}
/* ---- Prozentfelder (07.09.2026) ----------------------------------------
   Der Split und der PMG-Satz im Split Manager standen mit einem
   `style="width:56px"` im Formular. Ein Textfeld traegt links und rechts je
   12 px Innenabstand und 1 px Rahmen - von den 56 px bleiben also 30 px fuer
   den Inhalt. "100,00" braucht bei 14 px Schrift rund 45. Die letzte Stelle
   war damit abgeschnitten, und zwar genau bei den zwei Werten, die am
   haeufigsten vorkommen: 100,00 und 33,33.

   Die Breite steht deshalb in ch (Zeichenbreiten) plus dem Rahmenwerk, nicht
   als nackte Pixelzahl: sie waechst mit der Schriftgroesse mit, statt beim
   naechsten Schrifttausch wieder zu klemmen. Rechts ausgerichtet und mit
   tabellarischen Ziffern, damit in einer Spalte die Kommas untereinander
   stehen. */
/* ---- Pflicht-Stern und Fragezeichen am Feldlabel (07.09.2026) ----------
   Der Stern ist der Akzent des Hauses, nicht Rot: ein Pflichtfeld ist keine
   Fehlermeldung. --accent-ink liest sich in beiden Themes als "Lila", ohne im
   Dunkelmodus zu leuchten.

   Das Fragezeichen ist absichtlich leise (--faint) und wird beim Zeigen
   deutlich. Es traegt einen `title` - der Browser-Tooltip erscheint nach einer
   knappen Sekunde und ist damit die richtige Geschwindigkeit fuer einen
   Hinweis, den man nur beim ersten Mal braucht. */
.req{color:var(--accent-ink);font-weight:600}
/* Das Feldraster der Nachmeldung. Stand als drei Angaben in einem
   style-Attribut; der Abstand kommt jetzt aus der Skala (--sp-4) statt aus
   einer nackten 16. */
/* "Track hinzufuegen" unter der Tabelle (07.09.2026). Ueber die ganze Breite
   und gestrichelt: der Knopf sieht damit aus wie die Leerzeile, die er
   anlegt, und nicht wie ein zweiter Absendeknopf neben dem echten. */
/* Die vier Kacheln der Portal-Uebersicht. Gleiche Hoehe, gleicher Aufbau -
   vorher standen Groesse, Schrift und Farbe als Inline-Stile an drei Stellen,
   und eine Kachel sah dadurch schnell anders aus als ihre Nachbarn. */
/* Eine Ueberschrift in Fliesstextgroesse - stand als style="font-size:..." an
   der Vorschau-Ueberschrift der Nachmeldung. */
.fs-md{font-size:var(--fs-md)}
/* Gefunden am 07.09.2026, nachdem "der Kasten mit Works ist groesser" ein
   zweites Mal kam: `repeat(4,1fr)` ist `repeat(4,minmax(auto,1fr))`, und
   `auto` heisst "mindestens so breit wie der Inhalt". Die Zahl steht in
   --fs-2xl (30 px) Serif; bei einem Writer mit 377 oder 1697 Werken ist sie
   breiter als das Label "Open" daneben, und genau diese Spalte waechst. Die
   Kachel war also nicht falsch gebaut - das Raster gab ihr recht.

   `minmax(0,1fr)` nimmt der Spalte das Recht, wegen ihres Inhalts zu wachsen.
   Bewusst nur hier und nicht an .cols-4 allgemein: andere Seiten benutzen die
   Klasse fuer Karten, die sehr wohl mitwachsen sollen. */
.kpis{margin-bottom:var(--sp-5);grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:860px){ .kpis{grid-template-columns:repeat(2,minmax(0,1fr))} }
/* Und die Zahl darf nicht ausbrechen, wenn die Kachel schmal wird. */
.kpi-num{overflow:hidden;text-overflow:ellipsis}
.kpi{display:flex;flex-direction:column;justify-content:space-between;
  min-height:96px;color:inherit}
.kpi-lab{color:var(--muted);font-size:var(--fs-sm)}
.kpi-num{font-size:var(--fs-2xl);font-family:var(--serif);line-height:1.1;
  margin-top:var(--sp-1)}
.pmadd{width:100%;justify-content:center;margin-top:var(--sp-2);
  border-style:dashed;color:var(--muted)}
.pmadd:hover{border-style:solid;color:var(--accent-ink);border-color:var(--accent);
  background:var(--accent-soft)}
/* Die Seitengroesse als eigenes Menue statt als `select` (07.09.2026, zweiter
   Anlauf). Ein aufgeklapptes `select` zeichnet das Betriebssystem - weisse
   Liste, Systemschrift, im Dunkelmodus ein heller Kasten in einer dunklen
   Seite. Mit CSS nicht erreichbar, deshalb das Menue des Hauses.

   Schmaler als die Spaltenwahl (230 px waeren fuer vier Zahlen absurd) und
   die Zahlen rechtsbuendig, damit 25 und 200 untereinander stehen. */
.perpage .menu-body{min-width:0;width:6.5rem}
.perpage .menu-body .row{justify-content:flex-end;font-variant-numeric:tabular-nums;
  color:var(--ink);cursor:pointer}
.perpage .menu-body .row.on{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.msgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:var(--sp-4)}
/* Die Anteilsspalte braucht Platz fuer "100,00" plus Stern und Fragezeichen. */
.pmshare{width:150px}
.qmark{display:inline-flex;vertical-align:-2px;color:var(--faint);cursor:help}
.qmark:hover,.qmark:focus-visible{color:var(--accent-ink)}
.qmark:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm)}
.pctfield{width:calc(7ch + 26px);text-align:right;font-variant-numeric:tabular-nums}
/* Ein NUR-LESE-Wert, der in einer Spalte neben Eingabefeldern steht (PMG netto
   im Split Manager). Dieselbe Breite und derselbe Innenabstand wie ein Feld,
   nur ohne Rahmen und Flaeche - dadurch stehen die Ziffern auf derselben
   Linie. Ein rechtsbuendiger Text allein reicht dafuer nicht: die Eingabe
   traegt zusaetzlich 1 px Rahmen und 7 px Innenabstand, ihre letzte Ziffer
   sitzt also 8 px weiter innen. */
.pctval{display:inline-block;width:calc(7ch + 26px);padding:3px 7px;
  border:1px solid transparent;text-align:right;
  font-family:var(--mono);font-size:var(--fs-sm);font-variant-numeric:tabular-nums}
/* Zahlenspalten: Kopf und Zelle rechtsbuendig. */
table.sheet th.num,table.sheet td.num{text-align:right}
/* Eingaben in den Album-Tabellen des Split Managers auf Zeilenhoehe - dieselbe
   Regel, die `table.sheet.tight` mitbringt. Diese Tabellen tragen `tight`
   nicht, weil sie ihre Spaltenbreiten nicht fest vergeben. */
table.sheet.smsheet tbody td input[type=text],
table.sheet.smsheet tbody td select{padding:3px 7px;
  min-height:0;height:28px;font-size:var(--fs-sm)}
table.sheet.smsheet tbody tr{height:38px}
/* Und der Grund, warum Titel und Version "nicht in line" standen: die
   Grundregel setzt `vertical-align:top` an jede Zellen (richtig fuer Zellen
   mit mehreren Zeilen). In einer Zeile mit 28 px hohen Eingaben klebt der Text
   damit oben, waehrend die Felder mittig sitzen - zwei Grundlinien in einer
   Zeile. `middle` gilt hier fuer ALLE Zellen dieser Tabelle, sonst verschiebt
   man das Problem nur von einer Spalte in die naechste. */
table.sheet.smsheet tbody td{vertical-align:middle}
.mono{font-family:"SF Mono",ui-monospace,"Cascadia Code",Consolas,monospace;font-size:12.5px;color:var(--muted)}
.title-cell{font-weight:600;color:var(--ink)}
/* Der Name in der ersten Spalte ist seit dem 11.08.2026 der Weg ins Profil
   (Songwriter-Liste, Paket 13/1.1). Er erbt die Farbe der Zelle statt der
   Linkfarbe: eine ganze Spalte in Lila zoege den Blick von den Statusmarken
   weg, die daneben etwas bedeuten. .title-cell.owner behaelt so auch als Link
   sein --accent-ink. Erkennbar wird der Link beim Zeigen - unterstrichen, und
   der Zeiger wechselt ohnehin.
   Bewusst auf .swtab und die Kartenliste EINGEGRENZT und nicht auf
   .title-cell a allgemein: im Posteingang ist der Betreff derselbe Bau, aber
   dort ist der Link die Hauptsache der Zeile und traegt zu Recht die
   Linkfarbe. */
.swtab .title-cell a{color:inherit;text-decoration:none}
.swtab .title-cell a:hover{text-decoration:underline}
.cardlist .cardrow .ct a{color:inherit;text-decoration:none}
.cardlist .cardrow .ct a:hover{text-decoration:underline}
.owner{font-weight:600;color:var(--accent-ink)}
.muted{color:var(--muted)}
.tagcell input{border:1px solid transparent;background:transparent;padding:4px 6px;border-radius:6px;font-size:13px}
.tagcell input:hover{border-color:var(--border)}
.tagcell input:focus{background:var(--field)}
.splits{display:flex;flex-wrap:wrap;gap:6px}
.split{background:var(--chip);border:1px solid var(--chip-border);border-radius:20px;padding:2px 9px;font-size:12px;color:var(--muted)}
.split.client{background:var(--accent-soft);border-color:var(--chip-border);color:var(--accent-ink);font-weight:600}
.split .pc{font-weight:600}
.split.open{background:transparent;border-style:dashed;color:var(--faint)}
.tag{display:inline-block;font-size:11.5px;padding:2px 9px;border-radius:20px;white-space:nowrap}
.tag.ok{background:var(--ok-soft);color:var(--ok)}
.tag.open{background:var(--warn-soft);color:var(--warn)}
.bars{display:flex;align-items:flex-end;gap:8px;height:150px;margin-top:14px}
.bars .bar{flex:1;background:var(--accent-soft);border-radius:5px 5px 0 0;min-width:8px}
.bars .bar.hl{background:var(--accent)}
.barlab{display:flex;gap:8px;margin-top:6px}
.barlab span{flex:1;text-align:center;font-size:10.5px;color:var(--faint)}
.hbar{height:9px;border-radius:5px;background:var(--line);overflow:hidden}
.hbar>i{display:block;height:100%;background:var(--accent)}
/* 08.09.2026: `flex-direction:column` dazu. `.login` war eine Flex-ZEILE mit
   einem einzigen Kind, der Karte - solange nichts daneben stand, sah man den
   Unterschied nicht. Seit die Sprachwahl als Geschwister der Karte darunter
   steht, machte die Zeile sie zur Nachbarin: die Flaggen landeten NEBEN dem
   Anmeldefeld. Gemeldet von Johannes.

   `align-items:center` zentriert in einer Spalte waagerecht, `justify-content`
   senkrecht - beide behalten damit ihre Wirkung, nur um 90 Grad gedreht. */
.login{min-height:100vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;background:var(--bg)}
.login .box{background:var(--panel);border:1px solid var(--border);border-radius:16px;padding:38px 34px;width:360px;box-shadow:0 10px 40px rgba(30,15,60,.12)}
.login img{height:34px;margin-bottom:22px}
[data-theme="dark"] .login img{filter:invert(1) brightness(1.7)}
.login label{display:block;font-size:13px;color:var(--muted);margin:12px 0 5px}
.login .btn{width:100%;justify-content:center;margin-top:20px}

.empty{text-align:center;padding:var(--sp-8) var(--sp-5);color:var(--muted)}
.empty .big{font-family:var(--serif);font-size:var(--fs-xl);color:var(--ink);margin-bottom:var(--sp-2)}
/* Auch im Leerzustand steht der Erklaertext in der Hinweisgroesse - vorher erbte
   er die 15 px des Fliesstexts und stand fast so gross da wie die Zeile darueber. */
.empty p{font-size:12.5px;line-height:1.45;margin:0}
.check{width:56px;height:56px;border-radius:50%;background:var(--ok-soft);color:var(--ok);display:flex;align-items:center;justify-content:center;font-size:26px;margin:0 auto 16px}

.sec-title{display:flex;align-items:center;gap:var(--sp-3);margin:var(--sp-6) 0 var(--sp-3)}
.sec-title h2{font-size:18px}
/* UI-12: hier stand display:inline - und ausgerechnet ui.postbtn, die Fassung,
   die auf ueber vierzig Seiten gerendert wird, ueberschrieb das im
   style-Attribut mit inline-block. Zwei Regeln fuer denselben Zweck, die
   zweite unsichtbar im Markup. Es gilt inline-block fuer alle acht Stellen:
   ein Knopf hat eine Hoehe, und display:inline ignoriert sie. */
form.inline{display:inline-block}
.fieldrow{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);margin-bottom:var(--sp-4)}
.field label{display:block;font-size:var(--fs-md);color:var(--muted);margin-bottom:var(--sp-2)}
.hide{display:none !important}

.flag{width:26px;height:18px;border-radius:3px;overflow:hidden;border:1px solid var(--border);opacity:.5;display:inline-block;line-height:0}
.flag svg{width:100%;height:100%;display:block}
.flag.on{opacity:1;box-shadow:0 0 0 2px var(--accent)}
.flag:hover{opacity:.85}
.impbar{background:var(--accent-soft);border-bottom:1px solid var(--chip-border);color:var(--accent-ink);padding:8px 32px;display:flex;align-items:center;gap:12px;font-size:13px}
.impbar .btn{padding:4px 12px;font-size:13px}
th.sortable{cursor:pointer;user-select:none}
th .caret{opacity:.4;font-size:10px;margin-left:3px}
th.sorted .caret{opacity:1;color:var(--accent-ink)}
/* 08.09.2026: Das Klappmenue sitzt oben rechts IM Kasten. Absolut, damit es
   das Logo nicht nach unten schiebt; der Kasten hat dafuer position:relative.
   Vorher stand es als erstes Element im Fluss und war damit das Erste, was man
   auf der Seite sah - vor dem Logo.

   Zwischenzeitlich stand hier eine Reihe Flaggen unter der Karte. Sie ist
   wieder weg, Johannes wollte den Umschalter zurueck. Warum er auf diesen
   Seiten einen eigenen Zuhoerer braucht, steht in _langbar.html. */
.login .box{position:relative}
.login .langmenu{position:absolute;top:12px;right:12px;margin:0}
/* Das Menue klappt in einem 360 px breiten Kasten auf - rechts ausgerichtet,
   damit es nicht ueber den Rand haengt. */
.login .langmenu .menu-body{right:0;min-width:160px;text-align:left}

/* ---- Passwort zeigen: Symbol IM Feld -----------------------------------
   Dieselbe Bauform wie der Kalenderknopf im Datumsfeld (.datef): der Knopf
   sitzt absolut im Feld, und das Feld haelt rechts Platz frei. Vorher stand
   der Umschalter als Textlink UNTER dem Feld und schob den Anmeldeknopf eine
   Zeile tiefer. */
.pwfield{position:relative;display:block}
.pwfield input{padding-right:38px}
.pwbtn{position:absolute;right:4px;top:50%;transform:translateY(-50%);
  display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border:0;background:none;color:var(--muted);
  cursor:pointer;border-radius:var(--r-sm)}
.pwbtn:hover{color:var(--ink);background:var(--row-hover)}
.pwbtn[aria-pressed="true"]{color:var(--accent-ink)}
.pwbtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.login img{margin-top:4px}
.login .box{text-align:center}
.login .box form,.login label{text-align:left}

.flagbtn{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);background:var(--panel);border-radius:9px;padding:5px 8px;cursor:pointer;color:var(--muted)}
.flagbtn:hover{border-color:var(--accent)}
.flagbtn .flag{opacity:1;border:none;width:24px;height:16px}
.langmenu .menu-body{min-width:150px}
.langmenu .menu-body .row{color:var(--ink)}
.langmenu .menu-body .row.active{background:var(--accent-soft);color:var(--accent-ink)}
.langmenu .menu-body .flag{opacity:1;width:24px;height:16px}

/* CSV-Import Hilfe */
.qmark{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;
  border:1px solid var(--border);background:transparent;color:var(--muted);font-size:12px;cursor:pointer;vertical-align:middle;margin-left:6px}
.qmark:hover{border-color:var(--accent);color:var(--accent-ink)}
.helpbox{display:none;margin-top:10px;padding:10px 12px;border:1px solid var(--border);border-radius:8px;background:var(--panel)}
.helpbox.show{display:block}

/* Hier standen bis zum 11.08.2026 sieben Klassen der Spotify-Top-Songs-Ansicht
   (.toplist .toprow .toprank .topmain .topname .popbar .toppop). Die Karte
   "Spotify Insights" im Songwriter-Profil war ihre einzige Stelle und ist mit
   Paket 13/1.7 entfallen - die Regeln sind mitgegangen.

   Falls wieder ein Fortschrittsbalken gebraucht wird: `.hbar` weiter unten tut
   dasselbe und wird benutzt. Ein zweiter Balken daneben waere genau die Art
   Doppelung, die dieses Aufraeumen beseitigt hat. */


/* Mini-Chips (Aliasse, IDs) */
.chips{display:flex;flex-wrap:wrap;gap:4px;max-width:220px}
.mchip{display:inline-block;padding:2px 8px;border-radius:20px;background:var(--accent-soft);color:var(--accent-ink);font-size:11.5px;line-height:1.6;white-space:nowrap}
.mchip.mono{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10.5px}

/* Streaming-Profil-Buttons */
.iconbtn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:1px solid var(--border);color:var(--ink);transition:.15s}
/* Auch beim Zeigen die Akzentfarbe statt Spotify-Gruen und Apple-Rot
   (11.08.2026, Paket 13/1.8). Die Ruhefarbe steht weiter unten bei .iconbtn.sp
   - dort steht auch die Begruendung. */
.iconbtn.sp:hover,.iconbtn.ap:hover{background:var(--accent);color:#fff;border-color:var(--accent)}



/* Unlink-x in Chips */
.linkx{border:none;background:transparent;color:var(--muted);cursor:pointer;font-size:14px;line-height:1;padding:0 2px}
.linkx:hover{color:var(--err)}

/* ---------- Toasts ---------- */
.toasts{position:fixed;right:20px;bottom:20px;z-index:90;display:flex;flex-direction:column;gap:10px;max-width:min(420px,calc(100vw - 40px))}
.toast{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;font-size:14px;
  /* FIX 09.08.2026: hier stand var(--card,#fff) - die Variable --card gibt es in
     KEINER der beiden Paletten, der Rueckfallwert griff also immer. Im dunklen
     Theme war damit jede Meldung ein weisser Kasten, auf dem der geerbte helle
     Text (--ink:#ececee) praktisch unsichtbar war. --panel ist die Variable,
     die ueberall sonst fuer erhabene Flaechen steht. */
  background:var(--panel);border:1px solid var(--border);box-shadow:0 8px 28px rgba(0,0,0,.13);
  animation:toast-in .28s cubic-bezier(.2,.9,.3,1) both}
.toast-ic{flex:0 0 auto;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:700;color:#fff;margin-top:1px}
.toast-tx{flex:1;line-height:1.45;overflow-wrap:anywhere}
.toast-x{flex:0 0 auto;background:none;border:none;cursor:pointer;font-size:17px;line-height:1;color:var(--muted,#8a8a95);padding:0 2px;font-family:inherit}
.toast-x:hover{color:var(--ink)}
.toast-ok .toast-ic{background:var(--ok)}
.toast-warn .toast-ic{background:var(--warn)}
.toast-err .toast-ic{background:var(--err)}
.toast-ok{border-left:3px solid var(--ok)}
.toast-warn{border-left:3px solid var(--warn)}
.toast-err{border-left:3px solid var(--err)}
.toast-out{animation:toast-out .38s ease forwards}
@keyframes toast-in{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateX(24px)}}
@media (max-width:640px){.toasts{left:12px;right:12px;bottom:12px;max-width:none}}
@media (prefers-reduced-motion:reduce){.toast,.toast-out{animation:none}}

/* ===== Handy-Tauglichkeit (Paket 7) ======================================
   Die App wurde bis dahin nur in Desktop-Breiten geprueft. Songwriter tragen
   Splits aber am Telefon ein - unter 861 px wird die Seitenleiste deshalb zur
   einblendbaren Schublade (Knopf oben links), und Abstaende, Tabellen und
   Popups ruecken enger zusammen. Tabellen scrollen seitlich im .sheetwrap,
   statt die Seite zu sprengen. */
.navbtn{display:none}
.navbackdrop{display:none}
@media (max-width:860px){
  .navbtn{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;
    border:1px solid var(--border);border-radius:9px;background:var(--panel);color:var(--ink);
    font-size:18px;cursor:pointer;flex:0 0 auto;padding:0}
  .sidebar{position:fixed;left:0;top:0;bottom:0;z-index:60;height:100vh;height:100dvh;
    transform:translateX(-104%);transition:transform .22s ease;box-shadow:0 0 44px rgba(0,0,0,.28)}
  body.nav-open .sidebar{transform:none}
  /* Der Griff hat hier nichts zu suchen: die Leiste ist eine Schublade, und
     die Schublade hat schon einen Knopf (das Burger-Zeichen). Zwei Wege fuer
     dieselbe Sache waeren einer zu viel - und ein Griff, der am Bildrand einer
     unsichtbaren Leiste klebt, ist auf dem Telefon ein Fehlklick. Auch die
     Breitenregeln muessen hier weg, sonst bliebe die Schublade eingeklappt. */
  .sidegrip{display:none}
  .side-off .sidebar{width:var(--side-w);flex-basis:var(--side-w);border-right-color:var(--border)}
  .side-off .sidebar .logo,.side-off .sidebar .navwrap,.side-off .sidebar .sideuser{opacity:1;pointer-events:auto}
  .side-off .topbrand{display:none}
  body.nav-open .navbackdrop{display:block;position:fixed;inset:0;background:rgba(15,10,25,.45);z-index:50}
  body.nav-open{overflow:hidden}

  .topbar{padding:var(--sp-3) var(--sp-3);gap:var(--sp-2)}
  .topbar h1{font-size:18px}
  .content{padding:var(--sp-4) var(--sp-3) var(--sp-8)}
  .impbar{padding:var(--sp-2) var(--sp-3)}

  /* 16px in Eingabefeldern ist Absicht: darunter zoomt iOS beim Fokussieren
     die ganze Seite heran, und man findet sich nach dem Tippen woanders wieder. */
  input,select,textarea{font-size:16px}
  .pmgbox input,.pmgbox select,.pmgbox textarea{font-size:16px}

  .pmgbox.wide{width:440px}
  /* Kachel-Raster stapeln statt quetschen: 4 Spalten auf 360 px hiessen
     abgeschnittene Karten und Seitwaertsscrollen der ganzen Seite. */
  .cols-4{grid-template-columns:repeat(2,1fr)}
  .cols-3{grid-template-columns:1fr}
  .cols-2{grid-template-columns:1fr}
  table.sheet{font-size:12.5px}
  table.sheet thead th{padding:9px 10px}
  table.sheet td{padding:8px 10px}
}
@media (max-width:560px){
  /* Name im Kopf ausblenden - er steht ohnehin in der Seitenleiste. Das
     Avatar-Kuerzel bleibt als Anker. */
  .topbar .chip{font-size:0;gap:0}
  .topbar .sub{display:none}
  .search{min-width:150px}
}
@media (prefers-reduced-motion:reduce){.sidebar{transition:none}}

/* Aktionsleiste der Mehrfachauswahl im Split Manager (Paket U1). Schwebt
   unten mittig, erscheint erst, wenn etwas angehakt ist. */
.smbar{display:none;position:fixed;left:50%;transform:translateX(-50%);bottom:18px;z-index:45;
  background:var(--panel);border:1px solid var(--border);border-radius:14px;
  box-shadow:0 14px 40px rgba(20,10,40,.22);padding:10px 14px;gap:10px;align-items:center;
  max-width:calc(100vw - 24px);flex-wrap:wrap;justify-content:center}
.smbar.show{display:flex}

/* Split Manager: kompakte Listen-Ansicht (Nachtrag Paket U1). Jedes Album ist
   ein <details>; die summary-Zeile ist die Kompaktdarstellung, der Inhalt die
   bisherige Karte. Checkboxen app-weit in der Akzentfarbe statt Browser-Blau. */
/* accent-color stand hier - es faerbt nur den ANGEHAKTEN Zustand.
   Der leere Kasten blieb weiss. Die vollstaendige Zeichnung steht
   weiter unten im Abschnitt Paket D2. */
input[type=checkbox]{accent-color:var(--accent)}
.smitem{padding:0}
.smitem summary{list-style:none}
.smitem summary::-webkit-details-marker{display:none}
.smrow{display:flex;align-items:center;gap:9px;flex-wrap:wrap;cursor:pointer;
  padding:11px 16px;user-select:none;-webkit-user-select:none;border-radius:var(--radius)}
.smrow:hover{background:var(--row-hover)}
.smitem[open] .smrow{border-bottom:1px solid var(--line);border-radius:var(--radius) var(--radius) 0 0}
.smrow-x{font-size:11px;color:var(--muted);transition:transform .15s ease;flex:0 0 auto}
.smitem[open] .smrow-x{transform:rotate(90deg)}
.smrow-title{font-family:var(--serif);font-size:15.5px}
.smbody{padding:14px 16px 16px}
.smpick{width:17px;height:17px;flex:0 0 auto;cursor:pointer}

/* ---------------------------------------------------------------------------
   Kompakt vs. Karten (Nachtrag nach Paket 8)
   Vorher waren beide Ansichten dieselbe Karte, nur auf- oder zugeklappt - der
   Unterschied war praktisch nicht sichtbar. Jetzt ist "kompakt" eine echte
   Liste: eine Zeile je Release, nicht umbrechend, und aufgeklappt zeigt sie
   NUR die ISRC-Tabelle. Die Karten bleiben wie gehabt.
--------------------------------------------------------------------------- */
.mode-compact .smitem{margin-bottom:0 !important;border-radius:0;border-top:0}
.mode-compact .smitem:first-of-type{border-radius:var(--radius) var(--radius) 0 0;border-top:1px solid var(--border)}
.mode-compact .smitem:last-of-type{border-radius:0 0 var(--radius) var(--radius)}
.mode-compact .smrow{flex-wrap:nowrap;padding:6px 12px;gap:8px;font-size:13px;min-height:34px}
/* 07.09.2026: `max-width:38vw` schnitt den Titel ab, obwohl rechts daneben
   Platz war - der Deckel sass fest an der Fensterbreite und nicht an dem, was
   die Zeile tatsaechlich noch frei hat. Jetzt nimmt der Titel den freien Raum
   (flex:1) und kuerzt erst, wenn er wirklich nicht mehr passt. `min-width:0`
   ist dabei die Bedingung, ohne die ein Flex-Kind gar nicht schrumpfen kann -
   sonst schiebt es die Chips rechts aus der Zeile. */
/* 07.09.2026, Nachtrag: `flex:1 1 auto` liess den Titel ALLEN freien Platz
   nehmen - der Chip "5 Fassungen" wurde damit vom Titel weggeschoben und stand
   mitten in der Zeile. Gemeint war nur, den harten Deckel von 38vw
   loszuwerden.

   `flex:0 1 auto` ist der Unterschied: der Titel nimmt, was er braucht, und
   schrumpft erst, wenn es eng wird. Der Chip steht damit wieder direkt neben
   ihm, und den Rest der Zeile schiebt der .spacer nach rechts. */
.mode-compact .smrow-title{font-family:var(--sans);font-size:13.5px;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  flex:0 1 auto;min-width:0;max-width:none}
.mode-compact .smrow .tag,.mode-compact .smrow .mchip{font-size:10.5px;padding:1px 7px}
.mode-compact .smrow .smmeta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mode-compact .smbody{padding:6px 12px 12px}
/* Kompakt zeigt ausschliesslich die ISRC-Ebene. */
.mode-compact .smb-fields,.mode-compact .smb-actions,.mode-compact .smb-meta{display:none}
.mode-compact .smb-isrc>summary{display:none}
.mode-compact .sheet th,.mode-compact .sheet td{padding:5px 8px;font-size:12.5px}
/* Die album-weiten Felder stehen breiter als ein Prozentwert braucht, aber
   nicht ueber die ganze Karte - der Wert stand vorher zweimal als
   style="max-width:440px" an denselben zwei Feldern (UI-12). */
.smb-fields .field{max-width:440px}
.mode-cards .smb-isrc>summary{display:list-item}
/* In den Karten gibt es keine Ziehen-Auswahl - dort wird gearbeitet, nicht
   selektiert. Die Checkbox bleibt trotzdem klickbar. */
.mode-cards .smrow{cursor:default}

/* ---------------------------------------------------------------------------
   Auswahl-Zustand, app-weit (Paket D, 10.08.2026)

   Vorher bekam im Split Manager das GANZE <details> den getoenten Hintergrund.
   Weil .smitem gerundete Ecken hat, sah eine ausgewaehlte Zeile aus wie ein
   eigener, herausgehobener Block - ein zweiter Rahmen mitten in der Liste.
   Bei zwoelf ausgewaehlten Zeilen zerfaellt die Liste dadurch optisch.

   Jetzt traegt nur die ZEILE den Zustand: Haekchen vorne plus Akzentbalken.
   Das reicht - das Haekchen ist ohnehin die verlaessliche Auskunft, und wer
   mit der Tastatur arbeitet, braucht den Fokusring davon unterscheidbar.

   .is-selected ist der app-weite Name. Tabellenzeilen in Works, Foundry und
   Suggestions benutzen ihn direkt; der Split Manager setzt weiter .sel auf
   das <details>, deshalb steht sein Selektor hier daneben.
--------------------------------------------------------------------------- */
.is-selected,.smitem.sel>.smrow{
  background:var(--accent-soft);box-shadow:inset 3px 0 0 var(--accent)}
tr.is-selected>td{background:var(--accent-soft)}
tr.is-selected>td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
.smitem.sel .smrow-title,.is-selected .smrow-title{color:var(--accent-ink)}
.smrow.dragover{outline:2px solid var(--accent);outline-offset:-2px}
.mode-compact .smpick{width:15px;height:15px}
/* Beim Ziehen soll der Text nicht blau markiert werden. */
body.smdragging{user-select:none;-webkit-user-select:none;cursor:cell}

/* Ansicht-Umschalter als Segment statt zwei loser Knoepfe. */
.viewseg{display:inline-flex;border:1px solid var(--border);border-radius:10px;overflow:hidden}
.viewseg button{border:0;background:transparent;color:var(--muted);font:inherit;font-size:13px;
  padding:7px 12px;cursor:pointer}
.viewseg button+button{border-left:1px solid var(--border)}
.viewseg button.on{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}

/* Datei-Auswahl. Das nackte <input type=file> war der haesslichste Knopf der
   App - jetzt ein Label im Stil der uebrigen Knoepfe, der Dateiname steht
   daneben. Das Eingabefeld selbst bleibt im DOM (Formular unveraendert). */
.filepick{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}
.filepick input[type=file]{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}
.filepick label{display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  border:1px dashed var(--border);background:var(--panel);color:var(--ink);
  padding:9px 14px;border-radius:10px;font-size:13.5px;transition:.15s}
.filepick label:hover{border-color:var(--accent);background:var(--row-hover);color:var(--accent-ink)}
.filepick label:focus-within{outline:2px solid var(--accent);outline-offset:2px}
.filepick .fname{font-size:12.5px;color:var(--muted);max-width:220px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.filepick.has label{border-style:solid;border-color:var(--accent);color:var(--accent-ink)}
.filepick.has .fname{color:var(--ink)}

/* Zuordnungs-Feld in den Vorschlaegen: der Vorschlag steht vorbelegt drin und
   ist als solcher markiert. */
.assignwrap{display:inline-flex;align-items:center;gap:6px}
.assignwrap select{min-width:150px;font-size:12.5px;padding:5px 8px}
.assignwrap .sugg{font-size:10.5px;color:var(--accent-ink);background:var(--accent-soft);
  border-radius:6px;padding:1px 6px;white-space:nowrap}

/* ===========================================================================
   Hilfe-Seite (09.08.2026)
   Reiter und die Ablauf-Grafik "Weg eines Werks". Die Grafik ist bewusst reines
   HTML und CSS - kein Bild, keine Bibliothek: sie muss in beiden Themes stimmen,
   in sechs Sprachen unterschiedlich lange Beschriftungen vertragen und sich am
   Telefon von der Reihe zur Spalte umlegen lassen. Ein PNG koennte das nicht.
   =========================================================================== */
.helptabs{display:flex;gap:6px;overflow-x:auto;padding-bottom:10px;margin-bottom:18px;
  border-bottom:1px solid var(--border);scrollbar-width:none}
.helptabs::-webkit-scrollbar{display:none}
.helptabs a{flex:0 0 auto;padding:8px 14px;border-radius:9px;font-size:13.5px;
  color:var(--muted);border:1px solid transparent;white-space:nowrap}
.helptabs a:hover{background:var(--row-hover);color:var(--ink)}
.helptabs a.on{background:var(--accent-soft);color:var(--accent-ink);font-weight:600;
  border-color:var(--chip-border)}

/* ---- Ablauf-Grafik ---- */
.wf{margin:18px 0 6px}
.wf-lab{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);
  font-weight:600;margin:0 0 8px}
.wf-sources{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.wf-card{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  padding:14px 16px;box-shadow:var(--shadow)}
.wf-card .wf-ic{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;
  border-radius:9px;background:var(--accent-soft);color:var(--accent-ink);font-size:15px;margin-bottom:8px}
.wf-card b{display:block;font-size:14px;margin-bottom:2px}
/* Der Pfeil ist eine Linie mit Spitze, keine Schriftzeichen-Pyramide: so bleibt
   er in jeder Sprache und bei jedem Zoom gleich dick. */
.wf-flow{display:flex;flex-direction:column;align-items:center;gap:0;margin:10px 0}
.wf-down{width:2px;height:26px;background:var(--accent);opacity:.35}
.wf-tip{width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;
  border-top:9px solid var(--accent);opacity:.35;margin-bottom:2px}
.wf-gate{background:var(--accent-soft);border:1px solid var(--chip-border);border-radius:var(--radius);
  padding:14px 18px;color:var(--accent-ink)}
.wf-gate b{display:block;font-size:14px;margin-bottom:2px}
.wf-gate .hint{color:var(--accent-ink);opacity:.85}

/* Die drei Stufen. Der farbige Streifen oben nimmt genau die Farben der
   Status-Marken aus der App auf - wer die Grafik gelesen hat, erkennt die Marke
   in der Werkliste wieder. */
.wf-rail{display:grid;grid-template-columns:1fr auto 1fr auto 1fr;align-items:stretch;gap:0}
.wf-stage{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  padding:0 0 14px;box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column}
.wf-stage .wf-bar{height:4px}
/* UI-14: hier standen drei Hex-Werte, als einzige Farbangaben der Datei
   ausserhalb des Token-Satzes. Der Kommentar darueber behauptete schon, sie
   naehmen "genau die Farben der Status-Marken" auf - taten sie aber nur im
   hellen Theme, und im dunklen leuchteten sie als drei fremde Flecken.
   Offen/eingereicht/registriert heissen --info/--warn/--ok. */
.wf-stage.s1 .wf-bar{background:var(--info)}
.wf-stage.s2 .wf-bar{background:var(--warn)}
.wf-stage.s3 .wf-bar{background:var(--ok)}
.wf-stage .wf-head{display:flex;align-items:center;gap:9px;padding:13px 16px 0}
.wf-num{font-family:var(--serif);font-size:24px;line-height:1;color:var(--faint)}
.wf-stage h3{font-size:15px;padding:8px 16px 0}
.wf-stage .hint{padding:0 16px}
/* margin-top:auto schiebt die Zeile an den unteren Rand. Ohne das saessen die
   drei Fusszeilen auf verschiedenen Hoehen, weil die Beschreibungen ueber ihnen
   unterschiedlich lang sind - und in sechs Sprachen sind sie das immer. */
.wf-who{margin:12px 16px 0;padding-top:9px;border-top:1px dashed var(--border);
  font-size:11.5px;color:var(--muted);margin-top:auto}
.wf-who b{color:var(--ink);font-weight:600}
.wf-chev{display:flex;align-items:center;justify-content:center;width:46px;
  color:var(--accent);opacity:.45;font-size:22px;line-height:1}
.wf-return{display:flex;align-items:center;gap:9px;margin-top:12px;padding:10px 14px;
  border:1px dashed var(--border);border-radius:var(--radius);font-size:12.5px;color:var(--muted)}
.wf-always{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;padding:12px 16px;
  border-radius:var(--radius);background:var(--head);border:1px solid var(--border);font-size:12.5px}
.wf-always .mchip{font-size:12px}
@media (max-width:860px){
  /* Am Telefon wird aus der Reihe eine Spalte, und die Pfeile drehen sich mit. */
  .wf-sources{grid-template-columns:1fr}
  .wf-rail{grid-template-columns:1fr}
  .wf-chev{width:auto;height:34px;transform:rotate(90deg)}
  /* Nebeneinander bricht die Zeile unschoen um: die Erklaerung landete rechts
     NEBEN den Marken statt darunter. Untereinander liest sie sich richtig. */
  .wf-always{flex-direction:column;align-items:flex-start;gap:8px}
  .wf-always .hint{min-width:0}
}
@media (prefers-reduced-motion:reduce){.helptabs{scroll-behavior:auto}}

/* ---------------------------------------------------------------------------
   Schalter (.switch) - 09.08.2026
   Ein Haekchen und ein Schalter sind nicht dasselbe. Ein Haekchen heisst
   "dieses Element ist ausgewaehlt" und gehoert in Listen, aus denen man mehreres
   herausgreift. Ein Schalter heisst "diese Faehigkeit ist an oder aus" und
   gehoert dorthin, wo genau ein Zustand geschaltet wird - Rechtevergabe zum
   Beispiel. Vorher sahen beide Faelle gleich aus.

   Die echte Checkbox bleibt im Markup und traegt weiterhin name und value; sie
   liegt nur unsichtbar ueber der Bahn. Damit aendert sich am Formular und an
   der Tastaturbedienung nichts, und ohne CSS bleibt eine ganz normale Checkbox
   uebrig. Reihenfolge im Markup: input, dann .track, dann .knob - die
   Geschwister-Selektoren unten setzen das voraus.
--------------------------------------------------------------------------- */
.switch{position:relative;display:inline-flex;align-items:center;flex:0 0 auto;
  width:44px;height:25px;vertical-align:middle}
.switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;
  cursor:pointer;z-index:2}
/* AUS ist ein sattes Grau, nicht ein helles: ein Schalter, der ausgeschaltet
   fast so hell ist wie die Karte darunter, sieht aus wie ein Ladefehler.
   AN sind ZWEI Lila uebereinander - der Verlauf gibt der Bahn Tiefe und macht
   den Unterschied auch dann sichtbar, wenn jemand Farben schlecht trennt. */
.switch .track{position:absolute;inset:0;border-radius:var(--r-pill);
  background:var(--sw-off);border:1px solid var(--sw-off-b);
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.12)}
.switch .knob{position:absolute;top:3px;left:3px;width:19px;height:19px;border-radius:50%;
  background:#fff;box-shadow:0 1px 2px rgba(20,10,40,.35),0 0 0 .5px rgba(20,10,40,.08);
  transition:transform var(--dur-fast) var(--ease-out);pointer-events:none}
.switch input:checked ~ .track{
  background:linear-gradient(180deg,var(--accent-2) 0%,var(--accent) 100%);
  border-color:var(--accent);box-shadow:inset 0 1px 2px rgba(255,255,255,.18)}
.switch input:checked ~ .knob{transform:translateX(19px)}
.switch input:disabled{cursor:not-allowed}
.switch input:disabled ~ .track{opacity:.45}
.switch input:disabled ~ .knob{opacity:.65}
.switch input:focus-visible ~ .track{outline:2px solid var(--accent);outline-offset:2px}
.switch:hover .track{border-color:var(--accent)}
.switch:hover input:not(:checked) ~ .track{background:var(--sw-off-h)}
@media (prefers-reduced-motion:reduce){.switch .track,.switch .knob{transition:none}}
@media (max-width:900px){
  .switch{width:50px;height:29px}
  .switch .knob{width:23px;height:23px}
  .switch input:checked ~ .knob{transform:translateX(21px)}
}

/* ---- Haekchen ------------------------------------------------------------
   Das Systemhaekchen sah im dunklen Theme aus wie ein weisser Klebezettel:
   heller Kasten, heller Rahmen, mitten in einer dunklen Zeile. accent-color
   faerbt nur den ANGEHAKTEN Zustand - der leere Kasten blieb weiss. Deshalb
   zeichnen wir ihn selbst; Groesse, Rahmen und Haken folgen dem Rest der App. */
input[type=checkbox]{appearance:none;-webkit-appearance:none;
  width:18px;height:18px;flex:0 0 auto;margin:0;border-radius:5px;cursor:pointer;
  border:1.5px solid var(--cb-border);background:var(--cb-bg);
  display:inline-grid;place-content:center;vertical-align:-3px;
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
input[type=checkbox]:hover{border-color:var(--accent)}
input[type=checkbox]::before{content:"";width:11px;height:11px;transform:scale(0);
  transition:transform var(--dur-fast) var(--ease-out);background:#fff;
  clip-path:polygon(14% 47%,0 62%,40% 100%,100% 20%,85% 6%,38% 70%)}
input[type=checkbox]:checked{background:var(--accent);border-color:var(--accent)}
input[type=checkbox]:checked::before{transform:scale(1)}
/* Zwischenzustand der Kopf-Checkbox: ein Strich, kein Haken. */
input[type=checkbox]:indeterminate{background:var(--accent);border-color:var(--accent)}
input[type=checkbox]:indeterminate::before{transform:scale(1);height:2.5px;width:10px;
  border-radius:2px;clip-path:none}
input[type=checkbox]:disabled{opacity:.5;cursor:not-allowed}
/* Groessere Trefferflaeche am Telefon, ohne den Kasten aufzublasen. */
@media (max-width:900px){input[type=checkbox]{width:22px;height:22px}
  input[type=checkbox]::before{width:13px;height:13px}}
/* Waehrend des Ziehens soll nichts blau markiert werden. */
body.pmgdrag{user-select:none;-webkit-user-select:none;cursor:cell}
body.pmgdrag *{cursor:cell !important}

/* ---------------------------------------------------------------------------
   Aufraeumen 08.08.2026
--------------------------------------------------------------------------- */
/* Loesch-Knoepfe: acht Stellen trugen dieselbe hartkodierte Farbe #e5484d, die
   in KEINER Palette steht - im Dunkelmodus stach sie heraus. Jetzt eine Klasse
   auf Basis der Variablen. */
.btn.danger{border-color:var(--err);color:var(--err)}
.btn.danger:hover{border-color:var(--err);background:var(--err);color:var(--on-err)}
/* Mehrzeilige Eingabefelder sahen an vier Stellen nur deshalb richtig aus, weil
   dort dasselbe lange style-Attribut stand - und an einer fuenften eben nicht. */
textarea{width:100%;padding:9px 12px;border:1px solid var(--field-border);border-radius:9px;
  background:var(--field);color:var(--ink);font-family:var(--sans);font-size:14px}
textarea:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft),0 0 0 1px var(--accent)}
/* Leerzeile in Tabellen - stand neunmal als Inline-Stil da. */
.cell-empty{text-align:center;padding:26px;color:var(--muted)}
@media (max-width:900px){
  /* Klickflaechen: .btn.sm war 31 px hoch, die Auswahl-Checkbox 15 px. */
  .btn.sm{padding:8px 13px}
  .smpick{width:22px;height:22px}
  .mode-compact .smpick{width:20px;height:20px}
}

/* ===========================================================================
   PAKET D2 · 09.08.2026
   Fokus, Bewegung, und die Bausteine, die es vorher nur seitenlokal oder
   gar nicht gab. Alles hier ist global - wer eine dieser Klassen braucht,
   schreibt kein eigenes <style> mehr in sein Template.
   =========================================================================== */

/* ---- Fokus ---------------------------------------------------------------
   Bis heute kam :focus-visible in der gesamten Datei KEIN EINZIGES MAL vor.
   Die einzige Outline-Regel hing an .filepick. Damit waren Knoepfe, Reiter,
   Menueeintraege, Schliesskreuze und saemtliche Links per Tastatur zwar
   erreichbar, aber unsichtbar - man tabbte blind durch die App.
   :focus-visible statt :focus ist Absicht: der Ring erscheint bei Tastatur,
   nicht beim Mausklick. */
:where(a,button,summary,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-sm)}
:where(a,button,summary):focus:not(:focus-visible){outline:none}
/* Der Ring an Formularfeldern war ein 3-px-Schatten in --accent-soft: auf Weiss
   sind das 1,15:1, also praktisch unsichtbar (WCAG 1.4.11 verlangt 3:1).
   Getragen hat allein die Rahmenfarbe. Jetzt echter Ring plus Schatten. */
input:focus-visible,select:focus-visible,textarea:focus-visible{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.skiplink{position:absolute;left:var(--sp-2);top:-60px;z-index:calc(var(--z-toast) + 1);
  background:var(--panel);border:1px solid var(--accent);color:var(--accent-ink);
  padding:var(--sp-2) var(--sp-4);border-radius:var(--r-md);font-size:var(--fs-md);
  transition:top var(--dur-fast) var(--ease-out)}
.skiplink:focus{top:var(--sp-2)}

/* ---- Bewegung ------------------------------------------------------------
   Vorher deckte prefers-reduced-motion nur die Toasts und die Schublade ab;
   Rotationen, Auf- und Zublenden und der Spinner liefen weiter. Ein Block
   ersetzt beide Einzelfaelle und erwischt auch alles Kuenftige. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
}

/* ---- Symbole -------------------------------------------------------------
   Inline-SVG aus _icons.html. Es erbt die Schriftfarbe, deshalb genuegt es,
   den Container einzufaerben - kein eigenes Farbattribut je Symbol. */
.icon{display:inline-block;vertical-align:-.125em;flex:0 0 auto}
.iclab{display:inline-flex;align-items:center;gap:var(--sp-2)}
.btn .icon{margin-right:calc(var(--sp-1) * -1)}

/* ---- Knoepfe: die fehlenden Stufen ---------------------------------------
   Vorher gab es primary, normal, ghost, sm, danger - und weil dazwischen
   nichts stand, wurde alles Wichtige primary. Auf einem Split-Manager-Bild
   waren zehn Flaechen in Akzentfarbe; wenn alles primaer ist, ist nichts
   primaer. .subtle ist die Stufe darunter, .btnsplit fasst eine Hauptaktion
   mit ihren Varianten zusammen. */
.btn.subtle{border-color:transparent;background:transparent;color:var(--muted)}
.btn.subtle:hover{background:var(--row-hover);color:var(--ink);border-color:transparent}
.btn.danger.solid{background:var(--err);border-color:var(--err);color:var(--on-err)}
.btnsplit{display:inline-flex;align-items:stretch}
.btnsplit>.btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0}
.btnsplit>.menu>.btn{border-top-left-radius:0;border-bottom-left-radius:0;margin-left:-1px;padding-left:var(--sp-2);padding-right:var(--sp-2)}
/* Klickflaechen: .btn.sm war 29 px hoch, gefordert sind 40 (Telefon 44). Die
   Korrektur galt vorher erst ab 900 px Fensterbreite - also ausgerechnet dort
   nicht, wo mit dem Finger geklickt wird. */
.btn{min-height:38px}
.btn.sm{min-height:34px;padding:6px 12px}
@media (max-width:900px){.btn{min-height:44px}.btn.sm{min-height:40px}}
.iconbtn{min-width:36px;min-height:36px}
.pmgx,.toast-x,.linkx{min-width:32px;min-height:32px;display:inline-flex;
  align-items:center;justify-content:center}

/* ---- Segment-Umschalter (.seg) -------------------------------------------
   Eine Ansicht aus mehreren, exklusiv. .viewseg war dasselbe und bleibt als
   Aliasname bestehen, damit alte Templates weiterlaufen. Wichtig ist der
   Unterschied zu .fchip weiter unten: exklusiv und kombinierbar duerfen nie
   gleich aussehen, sonst lernt man eine Regel, die eine Seite weiter nicht
   mehr gilt - genau das war zwischen Werke und Split Manager der Fall. */
.seg,.viewseg{display:inline-flex;border:1px solid var(--border);border-radius:var(--r-md);
  overflow:hidden;background:var(--panel);flex:0 0 auto}
.seg button,.seg a,.viewseg button{border:0;background:transparent;color:var(--muted);
  font:inherit;font-size:var(--fs-md);padding:8px var(--sp-3);cursor:pointer;
  display:inline-flex;align-items:center;gap:var(--sp-2);min-height:38px;white-space:nowrap}
.seg button+button,.seg a+a,.viewseg button+button{border-left:1px solid var(--border)}
.seg button:hover,.seg a:hover,.viewseg button:hover{background:var(--row-hover);color:var(--ink)}
.seg [aria-pressed="true"],.seg .on,.viewseg button.on{
  background:var(--accent-soft);color:var(--accent-ink);font-weight:600}

/* ---- Seitenreiter (.tabs) ------------------------------------------------
   Der Zustand steht in der ADRESSE, nicht im Skript: verlinkbar, der
   Zurueck-Knopf tut das Erwartete, ohne JavaScript unveraendert bedienbar.
   Vorher gab es dafuer vier verschiedene Darstellungen in der App. */
.tabs,.helptabs{display:flex;gap:var(--sp-1);overflow-x:auto;padding-bottom:var(--sp-3);
  margin-bottom:var(--sp-5);border-bottom:1px solid var(--border);scrollbar-width:none}
.tabs::-webkit-scrollbar,.helptabs::-webkit-scrollbar{display:none}
.tabs a,.tabs button,.helptabs a{flex:0 0 auto;padding:8px var(--sp-4);border-radius:var(--r-md);
  font-size:var(--fs-md);color:var(--muted);border:1px solid transparent;white-space:nowrap;
  background:none;font-family:inherit;cursor:pointer;display:inline-flex;align-items:center;
  gap:var(--sp-2);min-height:38px}
.tabs a:hover,.tabs button:hover,.helptabs a:hover{background:var(--row-hover);color:var(--ink)}
.tabs a.on,.tabs button.on,.tabs [aria-current="page"],.helptabs a.on{
  background:var(--accent-soft);color:var(--accent-ink);font-weight:600;border-color:var(--chip-border)}
.tabs .cnt{font-size:var(--fs-xs);opacity:.75}

/* ---- Filter-Chips (.fchip) ----------------------------------------------
   Fuer KOMBINIERBARE Filter. Man sieht auf einen Blick, was gerade filtert,
   und wird jeden einzeln wieder los - vorher musste man dafuer einen
   Formularblock aufklappen und raten. */
.fbar{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-bottom:var(--sp-3)}
.fbar .lab{font-size:var(--fs-xs);letter-spacing:.06em;text-transform:uppercase;color:var(--faint);font-weight:600}
.fchip{display:inline-flex;align-items:center;gap:var(--sp-2);background:var(--accent-soft);
  color:var(--accent-ink);border:1px solid var(--chip-border);border-radius:var(--r-pill);
  padding:5px var(--sp-2) 5px var(--sp-3);font-size:var(--fs-sm);max-width:280px}
.fchip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fchip-x{border:none;background:none;color:inherit;cursor:pointer;font-size:var(--fs-md);
  line-height:1;padding:0;opacity:.7;display:inline-flex;align-items:center}
.fchip-x:hover{opacity:1}
.fchip.off{background:transparent;color:var(--muted)}

/* ---- Auswahlleiste (.selbar) --------------------------------------------
   Verallgemeinerung der Split-Manager-Leiste: schwebt unten, erscheint mit
   der ersten Auswahl, nennt IMMER die Zahl. "12 von 340 ausgewaehlt" ist die
   Information, die vorher fehlte - man musste sie zaehlen. */
.selbar,.smbar{display:none;position:fixed;left:50%;transform:translateX(-50%);bottom:var(--sp-5);
  z-index:var(--z-selbar);background:var(--panel);border:1px solid var(--border);
  border-radius:var(--r-xl);box-shadow:0 14px 40px rgba(20,10,40,.22);
  padding:var(--sp-3) var(--sp-4);gap:var(--sp-3);align-items:center;
  max-width:calc(100vw - var(--sp-6));flex-wrap:wrap;justify-content:center}
.selbar.show,.smbar.show{display:flex}
.selbar .cnt{font-size:var(--fs-md);font-weight:600;white-space:nowrap}
@media (max-width:640px){.selbar,.smbar{left:var(--sp-2);right:var(--sp-2);transform:none;max-width:none}}

/* ---- Tabellen ------------------------------------------------------------ */
/* Die Kopfzeile war als position:sticky gesetzt, klebte aber nie: .sheetwrap
   hatte overflow:auto OHNE Hoehenbegrenzung, wuchs also mit dem Inhalt mit.
   Erst eine Deckelung macht aus dem Container einen Scrollbereich. */
.sheet-scroll{max-height:min(70vh,720px)}
.sheetwrap:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
th.sortable button{background:none;border:0;font:inherit;color:inherit;cursor:pointer;
  padding:0;display:inline-flex;align-items:center;gap:var(--sp-1);width:100%}
th[aria-sort] .caret{opacity:1;color:var(--accent-ink)}
/* Kartenliste statt Querscrollen. Zehn Spalten auf 360 px hiessen drei
   Bildschirmbreiten seitwaerts, ohne jeden Hinweis darauf. */
.cardlist{display:none;flex-direction:column;gap:var(--sp-3)}
.cardrow{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--sp-3) var(--sp-4);box-shadow:var(--shadow)}
.cardrow .ct{font-weight:600;font-size:var(--fs-md);margin-bottom:var(--sp-1)}
.cardrow dl{display:grid;grid-template-columns:auto 1fr;gap:2px var(--sp-3);margin:var(--sp-2) 0 0;font-size:var(--fs-sm)}
.cardrow dt{color:var(--muted)}
.cardrow dd{margin:0;text-align:right;overflow-wrap:anywhere}
@media (max-width:860px){
  .cardlist{display:flex}
  /* .mobile-hide gilt fuer alles, nicht nur fuer Tabellen: neben der
     ersetzten Tabelle verschwinden auch die Hinweise, die sich auf sie
     beziehen - "Spaltenkoepfe ziehen zum Umsortieren" ist auf einer
     Kartenliste sinnlos. */
  .cardlist + .sheetwrap,.mobile-hide{display:none !important}
}

/* ---- Meldungen: Rueckgaengig --------------------------------------------
   Ein Undo-Knopf nach der Tat ist mehr wert als eine Rueckfrage davor: er
   unterbricht nicht und rettet trotzdem. Deshalb hat die Meldung jetzt einen
   Platz fuer genau eine Aktion. */
.toast-act{flex:0 0 auto;border:1px solid currentColor;background:none;color:inherit;
  font:inherit;font-size:var(--fs-sm);padding:3px var(--sp-2);border-radius:var(--r-sm);
  cursor:pointer;opacity:.9;min-height:28px}
.toast-act:hover{opacity:1;background:var(--row-hover)}

/* ---- Gespeichert-Blitz --------------------------------------------------
   pmgSave meldete bisher nur Fehler. Wer einen Wert tippte und wegklickte,
   erfuhr nie, ob er angekommen ist - das Feld zeigte ihn ja weiter an. */
@keyframes pmgsaved{
  0%{box-shadow:0 0 0 3px var(--ok-soft);border-color:var(--ok)}
  70%{box-shadow:0 0 0 3px var(--ok-soft);border-color:var(--ok)}
  100%{box-shadow:none}
}
.saveflash{animation:pmgsaved 1.1s var(--ease-out)}

/* ---- Ladezustand --------------------------------------------------------- */
@keyframes pmgshim{100%{background-position:200% 0}}
.skeleton{background:linear-gradient(90deg,var(--line) 25%,var(--row-alt) 37%,var(--line) 63%);
  background-size:200% 100%;animation:pmgshim 1.3s linear infinite;border-radius:var(--r-sm);
  color:transparent !important;pointer-events:none}
[aria-busy="true"]{opacity:.6}

/* ---- Popup: Dialog-Verhalten und Bottom-Sheet ---------------------------
   Der Hintergrund scrollte bisher weiter, waehrend das Popup offen war - auf
   iOS rutscht einem die Seite dabei weg. Unter 560 px faehrt der Kasten von
   unten ein statt in der Mitte zu schweben: am Telefon ist der untere
   Bildschirmrand die Stelle, die der Daumen erreicht. */
body.modal-open{overflow:hidden}
.pmgbox{display:flex;flex-direction:column}
@media (max-width:560px){
  .pmgmodal{align-items:flex-end;padding:0}
  .pmgbox{width:100%;max-width:none;max-height:90dvh;border-radius:var(--r-xl) var(--r-xl) 0 0;
    animation:pmgsheet .26s var(--ease-out)}
  @keyframes pmgsheet{from{transform:translateY(100%)}to{transform:none}}
}

/* ---- Command Palette ----------------------------------------------------
   Strg/Cmd + K. Bei vierzehn Menuepunkten plus Werken, Songwritern und
   Foundry-Dateien war der einzige globale Tastaturbefehl der App bisher
   Escape. Eine seitenuebergreifende Suche gab es ueberhaupt nicht - jedes
   Suchfeld war seitenlokal. */
.cmdk{position:fixed;inset:0;z-index:var(--z-cmdk);background:rgba(10,5,25,.42);
  display:none;align-items:flex-start;justify-content:center;padding:10vh var(--sp-4) var(--sp-4)}
.cmdk.open{display:flex}
.cmdkbox{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-xl);
  width:600px;max-width:100%;max-height:70vh;display:flex;flex-direction:column;
  overflow:hidden;box-shadow:0 24px 70px rgba(20,10,40,.34)}
.cmdkhead{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--border);color:var(--muted)}
.cmdkhead input{border:0;background:none;font-size:var(--fs-lg);padding:var(--sp-2) 0;
  font-family:inherit;color:var(--ink);width:100%}
/* Das Feld hat bewusst keinen eigenen Rahmen - der Kopf des Kastens ist der
   Rahmen. Der globale Ring war hier aber ERSATZLOS abgeraeumt (UI-13): mit der
   Maus geoeffnet und dann getabbt, sah man nicht mehr, wo man steht. Also
   Schatten und Rahmen weiterhin weg, den Ring bei Tastaturfokus zurueck. */
.cmdkhead input:focus{outline:none;box-shadow:none;border:0}
.cmdkhead input:focus-visible{outline:2px solid var(--accent);outline-offset:2px;
  box-shadow:none;border:0;border-radius:var(--r-sm)}
.cmdklist{overflow:auto;padding:var(--sp-2);flex:1;min-height:60px}
.cmdkgrp{font-size:var(--fs-xs);letter-spacing:.07em;text-transform:uppercase;
  color:var(--faint);font-weight:600;padding:var(--sp-3) var(--sp-3) var(--sp-1)}
.cmdkit{display:flex;align-items:center;gap:var(--sp-3);padding:9px var(--sp-3);
  border-radius:var(--r-md);cursor:pointer;color:var(--ink);font-size:var(--fs-md);width:100%;
  border:0;background:none;font-family:inherit;text-align:left}
.cmdkit .sub{color:var(--muted);font-size:var(--fs-sm);margin-left:auto;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45%}
.cmdkit.sel,.cmdkit:hover{background:var(--accent-soft);color:var(--accent-ink)}
.cmdkfoot{border-top:1px solid var(--border);padding:var(--sp-2) var(--sp-4);
  font-size:var(--fs-xs);color:var(--faint)}
kbd{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:var(--fs-xs);
  border:1px solid var(--border);border-bottom-width:2px;border-radius:var(--r-sm);
  padding:1px 5px;background:var(--bg);color:var(--muted)}

/* ---- Brotkrumen ---------------------------------------------------------
   Unterseiten wie ein Songwriter-Profil oder ein Vorgang hatten bisher keinen
   Rueckweg ausser dem Zurueck-Knopf des Browsers. */
.crumbs{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-sm);
  color:var(--muted);margin-bottom:var(--sp-3);flex-wrap:wrap}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--accent-ink)}

/* ---- Assistent (Schritt 1 von 3) ---------------------------------------- */
.wizard{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-5);flex-wrap:wrap}
.wz{display:flex;align-items:center;gap:var(--sp-2);padding:6px var(--sp-3);border-radius:var(--r-pill);
  font-size:var(--fs-sm);color:var(--muted);background:var(--chip);border:1px solid var(--chip-border)}
.wz .n{width:20px;height:20px;border-radius:50%;background:var(--panel);color:var(--muted);
  display:inline-flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:700}
.wz.on{background:var(--accent-soft);border-color:var(--chip-border);color:var(--accent-ink);font-weight:600}
.wz.on .n{background:var(--accent);color:#fff}
.wz.done .n{background:var(--ok);color:#fff}
.wz-line{flex:1;height:1px;background:var(--border);min-width:12px}
@media (max-width:640px){.wz .lab{display:none}.wz{padding:6px}}

/* ---- Dichte -------------------------------------------------------------
   War bisher eine seitenlokale Eigenheit des Split Managers. Als Einstellung
   am <html> gilt sie ueberall, ohne dass eine Seite davon wissen muss. */
[data-density="compact"] table.sheet thead th{padding:7px var(--sp-3)}
[data-density="compact"] table.sheet tbody td{padding:5px var(--sp-3);font-size:var(--fs-sm)}
[data-density="compact"] .card{padding:var(--sp-3) var(--sp-4)}
[data-density="compact"] .content{padding:var(--sp-4) var(--sp-6) var(--sp-8)}
[data-density="compact"] .stat{padding:var(--sp-3) var(--sp-4)}
[data-density="compact"] .stat .num{font-size:var(--fs-xl)}

/* ---- Status-Marken ------------------------------------------------------
   Standen als acht Hex-Werte in base.html, inklusive handgeschriebener
   Dunkelvariante. Das war der Beleg, dass eine Info-Farbe im Token-Satz
   fehlte. Jetzt gibt es --info und die Marken folgen dem Theme von selbst. */
/* Die drei Zustandschips tragen die Grossschreibung im STIL, nicht im Text
   (07.09.2026, gemeldet von Johannes: "der OPEN chip ist nicht alles gross wie
   die anderen"). Die Uebersetzungen von SUBMITTED und REGISTERED stehen als
   Grossbuchstaben in i18n; `st_open` konnte das nicht, weil derselbe
   Schluessel auf dem Dashboard und in der Portal-Uebersicht als normale
   Beschriftung dient - dort waere "OFFEN" geschrien. Also macht es die
   Darstellung. */
.tag.st-open,.tag.st-submitted,.tag.st-registered{text-transform:uppercase;letter-spacing:.04em}
.tag.st-open{background:var(--info-soft);color:var(--info);border:1px solid var(--info-border)}
.tag.st-submitted{background:var(--warn-soft);color:var(--warn);border:1px solid var(--warn)}
.tag.st-registered{background:var(--ok-soft);color:var(--ok);border:1px solid var(--ok)}

/* ---- Leerzustand mit Ausweg --------------------------------------------- */
.empty .act{margin-top:var(--sp-5);display:flex;gap:var(--sp-2);justify-content:center;flex-wrap:wrap}
/* 07.09.2026: `.empty .icon` traf JEDES Symbol im Leerzustand - auch das im
   Knopf darunter, denn `ic()` gibt seinem SVG die Klasse `icon`. Der Plus im
   Knopf "Neue Meldung" bekam damit 12 px margin-bottom und die Farbe --faint:
   er sass zu hoch und war blasser als seine Beschriftung. Gemeldet von
   Johannes ("das + bei inbox bei new report ist verzogen - nicht das oben
   sondern das unten").

   Gemeint war immer nur das grosse Symbol oben, und das ist ein direktes Kind.
   Ein `>` statt eines Leerzeichens - der Fehler traf jeden Leerzustand mit
   Knopf, nicht nur den Posteingang. */
.empty > .icon{color:var(--faint);margin-bottom:var(--sp-3)}

/* ---- Kartenkopf ---------------------------------------------------------
   Dieselbe Flex-Zeile stand allein in sync.html dreimal woertlich kopiert. */
.cardhead{display:flex;align-items:flex-start;gap:var(--sp-4);flex-wrap:wrap}
.cardhead .txt{flex:1;min-width:240px}
.cardhead .act{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;justify-content:flex-end}

/* ---- Kopfleiste: Suchknopf, Aktionsplatz, Theme -------------------------- */
.pageact{display:flex;align-items:center;gap:var(--sp-2)}
.pageact:empty{display:none}
.cmdkbtn{display:inline-flex;align-items:center;gap:var(--sp-2);border:1px solid var(--border);
  background:var(--panel);color:var(--muted);border-radius:var(--r-md);padding:0 var(--sp-3);
  height:36px;cursor:pointer;font:inherit;font-size:var(--fs-md)}
.cmdkbtn:hover{border-color:var(--accent);color:var(--ink)}
.cmdkbtn .lab{max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.themebtn{display:inline-flex;align-items:center;justify-content:center}
.themebtn .th-d{display:none}
[data-theme="dark"] .themebtn .th-l{display:none}
[data-theme="dark"] .themebtn .th-d{display:inline-flex}
/* Ein Link, der nicht navigiert, war frueher <a href="#" onclick>. Jetzt ein
   echter Knopf, der nur aussieht wie ein Link. */
.linkbtn{background:none;border:0;padding:0;font:inherit;font-size:inherit;
  color:var(--accent-ink);cursor:pointer;text-decoration:none}
.linkbtn:hover{text-decoration:underline}
/* Nur fuer Screenreader - etwa der Knopfname waehrend des Ladens. */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
@media (max-width:1100px){.cmdkbtn .lab,.cmdkbtn kbd{display:none}.cmdkbtn{width:36px;padding:0;justify-content:center}}
@media (max-width:860px){.pageact .btn span:not(.icon){display:none}}

/* ---- Nachtrag aus dem Integrationsdurchgang -----------------------------
   Regeln, die beim Umbau der Seiten als fehlend auffielen. Sie stehen hier
   und nicht im jeweiligen Template, weil jede von ihnen an mehr als einer
   Stelle gebraucht wird - genau daran krankte die Datei vorher. */

/* Kachel als Link. Stand achtmal als identischer Inline-Stil im Dashboard. */
a.stat{display:block;color:inherit}
a.stat:hover{border-color:var(--accent);background:var(--row-hover)}

/* Schalterliste mit Gruppentiteln. War ein seitenlokaler <style>-Block in
   organization.html, wird aber inzwischen auch fuer die Inbox-Zuweisungen
   gebraucht - also kein Sonderfall einer Seite mehr. */
.permgrid{padding:var(--sp-3) var(--sp-4)}
.permhead{padding-bottom:var(--sp-2);border-bottom:1px solid var(--border);margin-bottom:var(--sp-1)}
.permgroup{margin-bottom:var(--sp-2)}
.permgrouptitle{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-xs);
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;
  margin:var(--sp-3) 0 2px}
.permrow{display:flex;align-items:center;gap:11px;padding:5px 6px;font-size:var(--fs-md);
  cursor:pointer;border-radius:var(--r-sm)}
.permrow:hover{background:var(--row-hover)}
/* Gesperrt wird nur durch gedaempfte Schrift angezeigt - der ausgeschaltete
   Schalter ist deutlich genug, ein zusaetzlicher Durchstrich war Laerm. */
.permrow.locked .permname{color:var(--muted)}
.permname{flex:1;min-width:0}
.pn-h{display:block;font-size:var(--fs-xs);font-weight:400;line-height:1.35;margin-top:1px}
.permspecial{border-top:1px dashed var(--border);margin-top:var(--sp-3);padding-top:2px}

/* Nachrichtenverlauf. Vorher unterschied ein 3-px-Farbstrich links die eigenen
   von den fremden Beitraegen - das liest sich nicht als Gespraech. */
.thread{display:flex;flex-direction:column;gap:var(--sp-3)}
.tsep{text-align:center;font-size:var(--fs-xs);color:var(--faint);margin:var(--sp-2) 0}
.tmsg{display:flex;flex-direction:column;max-width:min(78%,560px)}
.tmsg.mine{align-self:flex-end;align-items:flex-end}
.tbub{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--sp-3) var(--sp-4);box-shadow:var(--shadow)}
.tmsg.mine .tbub{background:var(--accent-soft);border-color:var(--chip-border);color:var(--accent-ink)}
.tmeta{font-size:var(--fs-xs);color:var(--faint);margin-bottom:3px}
.tbody{white-space:pre-wrap;overflow-wrap:anywhere;font-size:var(--fs-md)}
.tatt{margin-top:var(--sp-2)}
.tatt img{max-width:100%;border-radius:var(--r-md);display:block}

/* Ungelesene Zeile: Farbe war die einzige Information. Der Punkt traegt jetzt
   zusaetzlich Text fuer Screenreader (.sr), die Zeile bleibt getoent. */
tr.unread{background:var(--accent-soft)}
tr.unread:hover{background:var(--accent-soft)}
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent);flex:0 0 auto}

/* Ein Menue in einer scrollenden Tabelle: .sheetwrap hat overflow:auto, das
   aufgeklappte Kebab der letzten Zeile erzeugte dort einen Rollbalken statt
   frei darueber zu liegen. position:fixed loest das, ohne den Container
   anzufassen - die Lage setzt das Skript in base.html. */
.sheetwrap .menu.open .menu-body{position:fixed;z-index:var(--z-modal)}

/* Nur fuer Screenreader sichtbar. Wird jetzt an mehreren Stellen gebraucht. */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* Chrome zeichnet in input[type=search] ein eigenes Loeschkreuz. In der
   Command Palette stand es direkt neben unserem Schliessknopf - zwei Kreuze
   nebeneinander, die Verschiedenes tun. */
.cmdkhead input::-webkit-search-cancel-button{appearance:none;-webkit-appearance:none}

/* ---- Seitenleiste: Gruppenkoepfe, Zahnrad, Ladeknopf --------------------
   Stand als <style>-Block in base.html, mit Rueckfallwerten wie
   var(--border,#e2e2e6) - die greifen nie, weil die Variable immer gesetzt
   ist, und taeuschen eine zweite Wahrheit vor. Ein hartkodiertes #12a150
   war ausserdem die einzige gruene Farbe der App, die in keiner Palette
   stand. */
.navtools{display:flex;gap:var(--sp-2);padding:0 var(--sp-3) var(--sp-2)}
.navtools button{flex:1;font-size:10px;line-height:1.2;background:none;border:1px solid var(--border);color:var(--muted);border-radius:6px;padding:3px 6px;cursor:pointer;font-family:inherit}
.navtools button:hover{color:var(--ink);border-color:var(--border)}
/* Gruppenueberschriften sind reine Beschriftungen - 28 px fuer eine 10.5-px-Zeile
   waren zu grosszuegig, wenn darunter 14 Punkte um Platz kaempfen. */
.navgroup .navsec{display:flex;align-items:center;justify-content:space-between;width:100%;text-align:left;background:none;border:none;cursor:pointer;font-size:10.5px;line-height:1.2;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:9px 11px 3px;font-weight:600;font-family:inherit;transition:color .15s ease}
.navgroup .navsec:hover{color:var(--ink)}
.navgroup .navsec:hover .navsec-x{color:var(--accent-ink);transform:translateY(1px)}
.navgroup.collapsed .navsec:hover .navsec-x{transform:rotate(-90deg) translateX(-1px)}
.navsec-x{font-size:9px;transition:transform .15s ease,color .15s ease}
.navgroup.collapsed .navsec-x{transform:rotate(-90deg)}
.navgroup.collapsed .navsec-items{display:none}
/* Kompakter Modus fuer flache Fenster (typisch 1366x768, das gibt rund 650 px
   sichtbare Hoehe). Statt die Leiste ueberall zu quetschen, wird nur dort
   enger, wo der Platz wirklich fehlt: zuerst an Logo, Kopf- und Fusszeile,
   dann erst an den Menuepunkten selbst. Unterhalb davon greift der schmale
   Rollbalken - irgendwann ist eine Liste eben laenger als der Bildschirm. */
@media (max-height:780px){
  .logo{padding:var(--sp-3) var(--sp-5) var(--sp-2)}
  .logo img{height:24px}
  .navtools{padding:0 var(--sp-3) var(--sp-1)}
  .navtools button{padding:2px var(--sp-2)}
  .navgroup .navsec{padding:var(--sp-2) var(--sp-3) 2px}
  .nav a{padding:var(--sp-1) var(--sp-3);margin-bottom:0}
  .sideuser{padding:var(--sp-2) var(--sp-4)}
  .sideuser .avatar{width:28px;height:28px;font-size:12px}
}
.settingsgear{font-size:16px;text-decoration:none;opacity:.65;padding:4px 7px;border-radius:8px;color:var(--ink)}
.settingsgear:hover,.settingsgear.active{opacity:1;background:var(--accent-soft)}
.btnspin{display:inline-block;width:13px;height:13px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:pmgrot .6s linear infinite;vertical-align:-2px}
@keyframes pmgrot{to{transform:rotate(360deg)}}
.is-loading{opacity:.7;pointer-events:none;cursor:progress}
.logo{text-align:center}.logo img{margin-left:auto;margin-right:auto}
.flash-ok{display:inline-block;color:var(--ok);font-weight:800;margin-right:6px;animation:pmgpop .4s ease}
@keyframes pmgpop{0%{transform:scale(0);opacity:0}55%{transform:scale(1.35)}100%{transform:scale(1);opacity:1}}
.sumok{color:var(--ok)}
.sumoff{color:var(--err);font-weight:700}
.tag.sumoff{background:var(--warn-soft);color:var(--err);border:1px solid var(--err);font-weight:700}
[data-theme="dark"] [data-theme="dark"]

/* ---- Rollbalken ----------------------------------------------------------
   Der graue Systembalken ist in einer App mit dunklem Theme ein Fremdkoerper -
   er ist breit, eckig und im Dunkelmodus je nach Betriebssystem hellgrau.
   Bisher war nur die Seitenleiste versorgt; Tabellen, Menues, Textfelder und
   die Seite selbst zeigten den nackten Systembalken.

   ACHTUNG Reihenfolge (gilt hier wie schon bei .nav): sobald scrollbar-color
   gesetzt ist, ignoriert Chromium saemtliche ::-webkit-scrollbar-Regeln und
   zeichnet einen Ueberlagerungsbalken, der nur waehrend des Scrollens
   aufblitzt. Die Standard-Eigenschaft steht deshalb NUR im @supports-Zweig
   fuer Firefox, wo es die Pseudo-Elemente nicht gibt. */
/* ---------------- Grundform: gilt fuer JEDEN Rollbereich ----------------- */
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-corner{background:transparent}
::-webkit-scrollbar-thumb{background:var(--sb-thumb);border-radius:var(--r-pill);
  border:3px solid transparent;background-clip:content-box;min-height:40px;min-width:40px}
::-webkit-scrollbar-thumb:hover{background:var(--sb-thumb-h);background-clip:content-box}
::-webkit-scrollbar-thumb:active{background:var(--accent);background-clip:content-box}
@supports not selector(::-webkit-scrollbar){
  *{scrollbar-width:thin;scrollbar-color:var(--sb-thumb) transparent}
  *:hover{scrollbar-color:var(--sb-thumb-h) transparent}
}

/* ---------------- Rinne: nur in umrandeten Behaeltern --------------------
   Ein Balken OHNE Rinne sieht bei kurzem Inhalt aus wie ein Fleck; mit Rinne
   sieht man sofort, wie weit man ist und wie viel noch kommt. Am Fensterrand
   waere dieselbe Rinne dagegen nur ein grauer Streifen neben dem Inhalt -
   deshalb bekommen sie ausdruecklich die KAESTEN, nicht die Seite.
   Die Rinne ist eingerueckt (margin), damit sie nicht in die abgerundete Ecke
   des Kastens laeuft. */
.sheetwrap,.cmdklist,.menu-body,.pmgbox,textarea,pre,.smlist,.fd2wrap{
  scrollbar-gutter:auto}
.sheetwrap::-webkit-scrollbar,.cmdklist::-webkit-scrollbar,.menu-body::-webkit-scrollbar,
.pmgbox::-webkit-scrollbar,textarea::-webkit-scrollbar,pre::-webkit-scrollbar,
.fd2wrap::-webkit-scrollbar{width:14px;height:14px}
.sheetwrap::-webkit-scrollbar-track,.cmdklist::-webkit-scrollbar-track,
.menu-body::-webkit-scrollbar-track,.pmgbox::-webkit-scrollbar-track,
textarea::-webkit-scrollbar-track,pre::-webkit-scrollbar-track,
.fd2wrap::-webkit-scrollbar-track{background:var(--sb-track);border-radius:var(--r-pill);
  margin:var(--sp-1)}
.sheetwrap::-webkit-scrollbar-thumb,.cmdklist::-webkit-scrollbar-thumb,
.menu-body::-webkit-scrollbar-thumb,.pmgbox::-webkit-scrollbar-thumb,
textarea::-webkit-scrollbar-thumb,pre::-webkit-scrollbar-thumb,
.fd2wrap::-webkit-scrollbar-thumb{border-width:4px;min-height:44px;min-width:44px}
/* Beim Zeigen auf den KASTEN wird der Balken deutlicher, beim Zeigen auf ihn
   selbst am deutlichsten. So bleibt er im Ruhezustand leise, ohne unsichtbar
   zu sein. */
.sheetwrap:hover::-webkit-scrollbar-thumb,.cmdklist:hover::-webkit-scrollbar-thumb,
.menu-body:hover::-webkit-scrollbar-thumb,.pmgbox:hover::-webkit-scrollbar-thumb,
textarea:hover::-webkit-scrollbar-thumb,.fd2wrap:hover::-webkit-scrollbar-thumb{
  background:var(--sb-thumb-h);background-clip:content-box}
@supports not selector(::-webkit-scrollbar){
  .sheetwrap,.cmdklist,.menu-body,.pmgbox,textarea,pre,.fd2wrap{
    scrollbar-color:var(--sb-thumb) var(--sb-track)}
}

/* ---------------- Ausnahme: die Seitenleiste ----------------------------
   Schmal und ohne Rinne. Sie ist 236 px breit und traegt vierzehn Punkte -
   dort zaehlt jeder Pixel, und eine Rinne neben den Menuenamen waere eine
   zweite senkrechte Linie direkt neben der Trennlinie zum Inhalt. */
.nav::-webkit-scrollbar{width:10px}
.nav::-webkit-scrollbar-track{background:transparent;margin:0}
.nav::-webkit-scrollbar-thumb{border-width:3px;min-height:36px}
@supports not selector(::-webkit-scrollbar){
  .nav{scrollbar-color:var(--sb-thumb) transparent}
}

/* Reiterleisten scrollen waagerecht, sollen aber keinen Balken zeigen: sie
   sind kurz, und der Balken saesse direkt auf der Trennlinie darunter. */
.tabs,.helptabs{scrollbar-width:none}
.tabs::-webkit-scrollbar,.helptabs::-webkit-scrollbar{display:none}

/* Die klebende Kopfzeile deckt sonst die obere Ecke des senkrechten Balkens ab. */
.sheet-scroll table.sheet thead th{z-index:1}


/* ---- Zeigefinger ---------------------------------------------------------
   Ein Element, das auf einen Klick reagiert, muss das auch am Mauszeiger
   zeigen. Durch den Umbau auf echte <button> haben etliche Stellen den
   Zeigefinger verloren, den sie als <a> automatisch hatten. */
button:not(:disabled),summary,label.permrow,label.switch,
.seg button,.seg a,.tabs a,.tabs button,.fchip-x,.cmdkit,
[role="button"],[data-menu],[data-modal-open],[data-modal-close]{cursor:pointer}
button:disabled,.btn[disabled]{cursor:not-allowed}
input[type=checkbox],input[type=radio],.switch input{cursor:pointer}

/* ---- Aktionsleiste ueber einer Liste (.smactions) -----------------------
   Loest die schwebende Auswahl-Pille ab. Zwei Gruende: die Pille erschien erst
   MIT der Auswahl - vorher wusste niemand, dass es diese Aktionen gibt -, und
   sie lag an einer anderen Stelle als alles andere auf der Seite.
   Klebend, damit sie auch nach hundert Zeilen noch da ist. Der z-index liegt
   unter dem Menue, damit ein aufgeklapptes Kebab darueber liegt. */
.smactions{position:sticky;top:0;z-index:calc(var(--z-menu) - 1);
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  padding:var(--sp-2) var(--sp-3);margin:0 0 var(--sp-3);
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--shadow)}
.smactions .selall{display:inline-flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-md);color:var(--muted);cursor:pointer;white-space:nowrap}
.smactions .cnt{white-space:nowrap;font-weight:600;color:var(--accent-ink)}
/* Ein stumpfer Knopf muss stumpf AUSSEHEN und trotzdem lesbar bleiben - bei
   .45 Deckkraft war die Schrift auf hellem Grund nicht mehr zu entziffern. */
.smactions .btn[disabled]{opacity:.55}
.smactions .btn.primary[disabled]{background:var(--chip);border-color:var(--chip-border);color:var(--muted)}
@media (max-width:860px){
  .smactions{gap:var(--sp-1);padding:var(--sp-2)}
  .smactions .selall span{display:none}
  .smactions .btn span:not(.icon){display:none}
}

/* ---- Kompakte Zeilen ----------------------------------------------------
   Die Werkliste hat vierzehn Spalten. Faellt auch nur EINE davon in die zweite
   Zeile - "Exclusive Deal" tut das zuverlaessig -, wird die ganze Zeile doppelt
   so hoch, und aus zwanzig sichtbaren Werken werden zehn. Deshalb: eine Zeile
   je Werk, Ueberlaufendes mit Auslassungspunkten, der volle Text im title.
   Wer alles sehen will, schaltet oben auf die Karten- bzw. Interaktiv-Ansicht
   oder faehrt mit der Maus darueber. */
table.sheet.tight tbody td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:220px;vertical-align:middle;padding:6px var(--sp-3)}
table.sheet.tight thead th{padding:8px var(--sp-3)}
/* Die Songwriter-Marke ist der letzte Hoehentreiber: sie bringt eigene
   Innenabstaende mit und schob die Zeile auf 49 px. */
table.sheet.tight .mchip{padding:1px 7px;line-height:1.5}
table.sheet.tight tbody td.wide{max-width:320px}
table.sheet.tight tbody th{vertical-align:middle}
table.sheet.tight tbody tr{height:38px}
/* Eingabefelder in der Zeile duerfen die Hoehe nicht wieder aufblaehen. */
table.sheet.tight tbody td input[type=text],
table.sheet.tight tbody td select{padding:3px 7px;min-height:0;height:28px;font-size:var(--fs-sm)}
table.sheet.tight .splits{flex-wrap:nowrap;overflow:hidden}
[data-density="compact"] table.sheet.tight tbody tr{height:32px}

/* Zaehler am Spalten-Knopf: sagt, dass nicht alle Spalten zu sehen sind.
   Ohne ihn waere die Voreinstellung ein stilles Verstecken von Daten. */
.btn .cnt{font-size:var(--fs-xs);color:var(--muted);font-variant-numeric:tabular-nums}
.btn.primary .cnt{color:rgba(255,255,255,.75)}

/* ---- Werkliste: passt sich der Breite an, statt sie zu sprengen ----------
   table-layout:fixed ist der Unterschied zwischen "die Tabelle ist so breit
   wie ihr laengster Inhalt" und "die Tabelle ist so breit wie das Fenster".
   Ohne das entscheidet ein einziger langer Kuenstlername ueber die Gesamt-
   breite - und damit darueber, ob ein waagerechter Rollbalken erscheint.

   Die festen Breiten unten sind keine Willkuer: sie ergeben sich aus dem
   Inhalt, der dort stehen KANN. Ein ISRC hat immer 12 Zeichen, ein Datum
   immer 10, "Exclusive Deal" ist der laengste Deal-Name. Was uebrig bleibt,
   teilen sich Titel, Kuenstler und Album - die Felder, bei denen ein
   Auslassungspunkt niemandem weh tut, weil der volle Text im title steht. */
table.sheet.tight{table-layout:fixed;width:100%}
table.sheet.tight th[data-key="_sel"]{width:44px}
/* Die Auswahlzelle enthaelt nur ein Haekchen - sie darf nichts abschneiden,
   sonst haengen Auslassungspunkte neben dem Kasten. */
table.sheet.tight td[data-key="_sel"]{overflow:visible;text-overflow:clip}
/* Datum und ISRC bekommen so viel Platz, wie ihr Inhalt IMMER braucht: ein
   Datum hat zehn Zeichen, ein ISRC zwoelf. Bei diesen beiden waere ein
   Auslassungspunkt kein Schoenheitsfehler, sondern ein Datenverlust - ein
   halber ISRC ist zu nichts zu gebrauchen. */
table.sheet.tight th[data-key="release_date"]{width:110px}
table.sheet.tight th[data-key="isrc"]{width:126px}
table.sheet.tight th[data-key="upc"]{width:132px}
table.sheet.tight th[data-key="split"]{width:76px}
table.sheet.tight th[data-key="pmg_net"],
table.sheet.tight th[data-key="pmg"]{width:80px}
table.sheet.tight th[data-key="work_type"]{width:84px}
/* Breit genug fuer "Exclusive Deal" in einer Zeile - genau daran ist die
   Zeilenhoehe vorher aufgelaufen. */
table.sheet.tight th[data-key="deal_type"]{width:106px}
table.sheet.tight th[data-key="status"]{width:112px}
/* Songwriter, Titel und Kuenstler bekommen ABSICHTLICH keine feste Breite:
   sie teilen sich, was uebrig bleibt. Genau deshalb passt die Tabelle sich der
   Fensterbreite an, statt sie vorzugeben. */
/* Bei fester Tabellenbreite ist max-width an der Zelle gegenstandslos - die
   Spaltenbreite entscheidet. Die Abschneidung bleibt. */
table.sheet.tight tbody td{max-width:none}

/* Kennungen nie kuerzen. */
table.sheet.tight tbody td[data-key="isrc"],
table.sheet.tight tbody td[data-key="upc"],
table.sheet.tight tbody td[data-key="release_date"]{text-overflow:clip}

/* ===========================================================================
   Paket D (10.08.2026) - Erklaer-Box, Datumsfeld, Auswahl
   =========================================================================== */

/* ---- Erklaer-Box am Seitentitel ------------------------------------------
   Der Knopf sitzt im .topbar direkt hinter dem h1. Er ist bewusst klein und
   leise: er soll auffindbar sein, nicht um Aufmerksamkeit bitten. */
.phelp{position:relative;display:inline-flex;align-items:center;flex:0 0 auto}
.phelp-btn{width:20px;height:20px;padding:0;border-radius:var(--r-pill);
  border:1px solid var(--border);background:transparent;color:var(--muted);
  font:600 12px/1 var(--sans);cursor:pointer;display:inline-flex;
  align-items:center;justify-content:center;
  transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
.phelp-btn:hover{background:var(--chip);color:var(--ink)}
.phelp-btn[aria-expanded="true"]{background:var(--accent-soft);color:var(--accent-ink);
  border-color:var(--accent)}

.phelp-box{position:absolute;top:calc(100% + 8px);left:-8px;z-index:var(--z-modal);
  display:flex;flex-direction:column;width:min(420px,calc(100vw - 32px));
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:0 8px 28px rgba(30,20,60,.18);overflow:hidden;
  animation:phelpIn var(--dur-base) var(--ease-out)}
.phelp-box[hidden]{display:none}
@keyframes phelpIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.phelp-head{display:flex;align-items:center;gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--line);
  background:var(--head);font-size:var(--fs-md)}
.phelp-head strong{flex:1;font-family:var(--sans)}
.phelp-x{border:0;background:transparent;color:var(--muted);font-size:19px;
  line-height:1;cursor:pointer;padding:0 2px}
.phelp-x:hover{color:var(--ink)}
.phelp-body{display:block;padding:var(--sp-4);max-height:52vh;overflow:auto}
.phelp-p{display:block;font-size:var(--fs-md);line-height:1.55;color:var(--ink)}
.phelp-p + .phelp-p{margin-top:var(--sp-3)}
.phelp-foot{display:block;padding:var(--sp-3) var(--sp-4);
  border-top:1px solid var(--line);background:var(--head);font-size:var(--fs-sm)}
.phelp-foot a{color:var(--accent-ink);text-decoration:none}
.phelp-foot a:hover{text-decoration:underline}

/* Auf dem Telefon ist ein 420-px-Popover an einem 20-px-Knopf unbedienbar.
   Dort faehrt die Box als Blatt von unten ein - dasselbe Muster, das der
   Design-Audit fuer alle Modale unter 560 px vorschlaegt. */
@media (max-width:560px){
  .phelp-box{position:fixed;left:0;right:0;bottom:0;top:auto;width:auto;
    max-height:85dvh;border-radius:var(--r-xl) var(--r-xl) 0 0;border-bottom:0;
    animation:phelpUp var(--dur-base) var(--ease-out)}
  .phelp-body{max-height:60dvh}
  @keyframes phelpUp{from{transform:translateY(100%)}to{transform:none}}
}

/* ---- Datumsfeld mit Kalender --------------------------------------------- */
.datef{position:relative;display:inline-flex;align-items:center;gap:var(--sp-2)}
.datef-btn{position:absolute;right:4px;top:50%;transform:translateY(-50%);
  border:0;background:transparent;color:var(--muted);cursor:pointer;
  padding:3px;display:inline-flex;border-radius:var(--r-sm)}
.datef-btn:hover{color:var(--accent);background:var(--chip)}

.cal{position:absolute;top:calc(100% + 6px);right:0;z-index:var(--z-modal);
  width:252px;padding:var(--sp-3);background:var(--panel);
  border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:0 8px 28px rgba(30,20,60,.18)}
.cal-head{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-2)}
.cal-head strong{flex:1;text-align:center;font:600 var(--fs-md)/1 var(--sans)}
.cal-nav{border:1px solid var(--border);background:transparent;color:var(--muted);
  width:26px;height:26px;border-radius:var(--r-sm);cursor:pointer;font-size:13px;line-height:1}
.cal-nav:hover{background:var(--chip);color:var(--ink)}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal-dow{font-size:var(--fs-xs);color:var(--faint);text-align:center;padding:3px 0}
.cal-d{border:0;background:transparent;color:var(--ink);font:inherit;
  font-size:var(--fs-sm);padding:5px 0;border-radius:var(--r-sm);cursor:pointer}
.cal-d:hover{background:var(--chip)}
.cal-d.out{color:var(--faint)}
.cal-d.today{box-shadow:inset 0 0 0 1px var(--accent)}
.cal-d.on{background:var(--accent);color:#fff}
.cal-foot{display:flex;gap:var(--sp-2);margin-top:var(--sp-2);
  padding-top:var(--sp-2);border-top:1px solid var(--line)}
.cal-foot button{flex:1;font-size:var(--fs-sm)}

/* ---- Paket D: Foundry-Auswahlspalte --------------------------------------
   Schmal und ruhig. Die Spalte traegt keinen Sortierknopf: nach einer
   Checkbox sortiert niemand, und ein Klickziel dort haette nur die Auswahl
   aufgehoben. */
table.sheet th.fd2-selth,table.sheet td.fd2-selc{width:34px;padding-left:10px;padding-right:4px}
table.sheet td.fd2-selc input,table.sheet th.fd2-selth input{width:16px;height:16px;cursor:pointer}
#fd2-selcount{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-ink);font-variant-numeric:tabular-nums}
#fd2-selcount:hover{background:var(--accent);color:#fff}
@media (max-width:860px){
  table.sheet th.fd2-selth,table.sheet td.fd2-selc{width:40px}
  table.sheet td.fd2-selc input,table.sheet th.fd2-selth input{width:20px;height:20px}
}

/* ---- Paket D, M3: Filterleiste auf EINE Linie ----------------------------
   Die Werkzeugleiste stand auf align-items:center. Solange alles gleich hoch
   ist, faellt das nicht auf. Sobald aber ein .field dabei ist - Beschriftung
   OBEN, Eingabefeld darunter -, ist dieses Feld hoeher als ein nackter Knopf.
   Zentriert bedeutet dann: der Knopf sitzt auf halber Hoehe des Feldes, also
   genau ZWISCHEN Beschriftung und Eingabe. Er wirkt verrutscht, weil er es ist.

   Ende statt Mitte: alle Bedienelemente stehen auf der Unterkante, die
   Beschriftungen darueber. Damit liegen Eingabefeld, Knopf und Umschalter auf
   einer Linie - unabhaengig davon, wie viele Felder eine Beschriftung tragen.

   :has() statt einer neuen Klasse, damit die Regel nur dort greift, wo es
   ueberhaupt beschriftete Felder gibt - Leisten ohne Beschriftung bleiben
   zentriert, wie sie es sollen. */
.toolbar:has(.field){align-items:flex-end}
.toolbar:has(.field) > .btn,
.toolbar:has(.field) > button,
.toolbar:has(.field) > .seg,
.toolbar:has(.field) > .btnsplit,
.toolbar:has(.field) > .menu{margin-bottom:0}
/* Das Feld selbst darf unten keinen Rest tragen, sonst steht die Linie zwar
   parallel, aber zwei Pixel zu tief. */
.toolbar .field{margin-bottom:0}

/* ---- Datumsfeld: Label darueber, Feld so breit wie sein Inhalt ----------
   Das Label kommt aus dem Makro jetzt VOR dem .datef und verhaelt sich damit
   wie jedes andere Feldlabel - das umgebende .field setzt es als Block
   darueber. Frueher stand es INNERHALB des inline-flex und damit daneben: das
   Feld wurde doppelt so breit und schob in einer Filterzeile die Nachbarn
   hinaus.

   .datef selbst traegt weiter position:relative, weil der Kalenderknopf und
   das Popup darin haengen - aber es umfasst nur noch Eingabe und Knopf. */
.datef-lab{display:block;font-size:13px;color:var(--muted);margin-bottom:5px}
.field .datef{display:inline-flex;width:auto}
.datef-in{width:12ch;min-width:0;padding-right:30px}

/* Das umwickelnde .field darf keine zweite Beschriftungsspur aufziehen. */

/* Ein INLINE-Style schlaegt jede Regel aus dieser Datei. Auf der Sync-Seite
   stehen zwei Werkzeugleisten mit `style="...align-items:center..."` - deshalb
   sass der Speichern-Knopf dort weiter auf halber Feldhoehe, obwohl M3
   behoben war. !important ist hier kein Faulheitszeichen, sondern die einzige
   Moeglichkeit, ohne fremde Vorlagen zu aendern. */
.toolbar:has(.field){align-items:flex-end !important}

/* ---- Paket 11: Combine Writers als EIN Punkt ----------------------------
   Vorher ein Schalter mit Beschriftung daneben - das breiteste Element der
   Zeile, und es liess die Leiste umbrechen. Jetzt ein Knopf wie seine
   Nachbarn, der Zustand haengt an aria-pressed.

   Die Leiste selbst bleibt dauerhaft stehen (Wunsch Johannes): das Ein- und
   Ausklappen aus dem ersten Anlauf ist wieder heraus. Ein Werkzeug, das man
   erst hervorholen muss, ist eines, das man nicht benutzt. */
#fd2-combine[aria-pressed="true"]{background:var(--accent-soft);
  border-color:var(--accent);color:var(--accent-ink)}

/* Zugeklappt fallen die Vorbereitungs-Werkzeuge weg: Dateimenue, Statuschip,
   die ganze Filterzone, Export und Statement. Was beim ARBEITEN gebraucht
   wird, bleibt. */


/* ---- Paket 11: zwei Foundry-Leisten, jede einzeilig --------------------
   Vorher eine Leiste mit flex-wrap. Bei zu wenig Platz rutschte ein
   beliebiges Element in die naechste Zeile - meist die Suche, und die stand
   dann ueber einem Knopf, zu dem sie nicht gehoert. Was umbricht, entschied
   die Fensterbreite, nicht die Bedeutung.

   Jetzt zwei Zeilen mit nowrap: oben, was die ANSICHT bestimmt, unten, was
   man mit dem Inhalt TUT. Wird es eng, scrollt die Zeile seitwaerts statt zu
   springen - so behaelt sie ihre Hoehe und die Tabelle darunter ihren Platz. */
.fd2row{flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;
  margin-bottom:var(--sp-2);padding-bottom:2px}
.fd2row > div{flex-wrap:nowrap !important}
/* Die Suche gibt als erste nach: sie hat eine Mindestbreite, aber keinen
   Anspruch auf ihre Wunschbreite. Ohne min-width:0 weigert sich ein
   Flex-Kind zu schrumpfen und schiebt stattdessen die Nachbarn hinaus. */
.fd2row .search{min-width:120px;flex:0 1 220px}
.fd2row .search input{width:100%;min-width:0}
.fd2row-act{margin-bottom:var(--sp-3)}
/* Ein Menue in einer seitwaerts scrollenden Leiste wuerde am Rand
   abgeschnitten - dieselbe Loesung wie in .sheetwrap: beim Oeffnen fixiert. */
.fd2row .menu.open .menu-body{position:fixed;z-index:var(--z-modal)}
@media (max-width:860px){
  .fd2row{gap:var(--sp-2)}
  .fd2row .search{flex:0 1 140px}
}

/* ---- Paket 11: Verbindungszustand als nicht klickbarer Knopf -------------
   Ein Knopf, der verschwindet, sobald er erledigt ist, laesst einen raten, ob
   es geklappt hat. Deshalb bleibt er stehen - gruen, mit Haken, und ohne
   Klickziel. .plok sieht wie ein Knopf aus und ist keiner: kein Zeiger, kein
   Hover, aria-disabled fuer die Ansage. */
/* ---- Der "erledigt"-Knopf, EINE Fassung fuer Sync und Foundry -----------
   Er sah nach nichts aus, weil `.btn:disabled{opacity:.45}` weiter oben in
   derselben Datei steht und bei gleicher Spezifitaet die spaetere Regel
   gewinnt - meine kam vorher. Rahmen und Schrift waren gesetzt, aber auf
   45 Prozent Deckkraft: aus Gruen wurde Blassgrau.

   Deshalb hier ausdruecklich !important auf opacity und Farbe. Das ist an
   dieser Stelle kein Faulheitszeichen: die Ausgrauung ist gewollt fuer
   "geht nicht" und falsch fuer "ist erledigt". Zwei Aussagen, zwei
   Darstellungen.

   .plok gilt fuer beide Stellen - den Verbunden-Knopf im Sync und die
   Speicheranzeige in der Foundry-Leiste. Vorher waren das zwei Bauweisen fuer
   dieselbe Aussage. */
/* Dieselbe Farbgebung wie .tag.ok - die gruene Marke, die es in der App
   ueberall gibt: helle Flaeche, dunklere Schrift. Ein dunkelgruener Rahmen um
   eine weisse Flaeche war ein vierter gruener Ton neben den drei vorhandenen
   und sah wie ein Fremdkoerper aus. */
.plok,.plok[disabled],.plok:disabled{
  background:var(--ok-soft) !important;
  border:1px solid var(--ok-soft) !important;
  color:var(--ok) !important;
  opacity:1 !important;
  cursor:default}
.plok:hover,.plok[disabled]:hover{background:var(--ok-soft) !important;
  border-color:var(--ok) !important}
.plok svg{color:var(--ok)}
/* Als reine Anzeige (kein Knopf) in der Foundry-Leiste: gleiche Hoehe und
   gleicher Rahmen wie die Knoepfe daneben, damit die Zeile nicht springt. */
span.plok{display:inline-flex;align-items:center;gap:6px;
  padding:5px 10px;border-radius:var(--r-sm);font-size:var(--fs-sm)}
/* Waehrend gespeichert wird und wenn es schiefging: dieselbe Form, andere
   Farbe. Ein Zustand, der die Form wechselt, laesst die Zeile zappeln. */
span.plok.busy{border-color:var(--border) !important;color:var(--muted) !important}
span.plok.bad{border-color:var(--err) !important;color:var(--err) !important}

/* ---- Konto-Zeichen in der Songwriter-Liste ------------------------------
   Ein Haken oder ein Kreuz, beide in derselben runden Form: so behaelt die
   Spalte eine Linie, egal welcher Zustand gilt. Vorher stand dort bei fehlendem
   Konto ein Halbsatz und bei vorhandenem ein Name - zwei verschiedene Hoehen
   und zwei verschiedene Leserichtungen. */
/* 11.08.2026 (Paket 13/1.2): 17 statt 20 px, Symbol 12 statt 14. Das Zeichen
   steht jetzt unmittelbar neben dem Konto-Knopf (36 px) statt am anderen Ende
   der Zelle; in dieser Nachbarschaft war die alte Groesse ein zweiter Knopf,
   der keiner ist. vertical-align und line-height, weil ein 12-px-Symbol in
   einem 17-px-Kasten sonst zwei Pixel ueber der Grundlinie des Knopfes sitzt.
   Bewusst KEINE 38-px-Klickflaeche: .acctmark ist kein Bedienelement, es hat
   nur title und aria-label. Die Regel aus Paket D2 gilt fuer Knoepfe. */
.acctmark{display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;border-radius:var(--r-pill);flex:0 0 auto;
  vertical-align:middle;line-height:1;
  border:1px solid transparent}
.acctmark.ja{color:var(--ok);border-color:var(--ok);background:var(--ok-soft)}
.acctmark.nein{color:var(--err);border-color:var(--err);background:var(--err-soft)}

/* Beide Logos tragen seit dem 11.08.2026 das Lila der App (Paket 13/1.8) und
   nicht mehr Spotify-Gruen und Apple-Rot. Grund: die beiden Knoepfe stehen
   nebeneinander in einer Zeile, und zwei fremde Markenfarben nebeneinander
   waren die kraeftigsten Farben der ganzen Seite - kraeftiger als jede
   Statusmarke, die etwas zu sagen hat. Erkennbar bleiben sie an der Form des
   Logos, nicht an der Farbe. --accent traegt hell wie dunkel auf --panel.
   Farbe schon im Ruhezustand: ein Logo, das man erst anfassen muss, um es zu
   erkennen, erkennt man nicht. */
.iconbtn.sp,.iconbtn.ap{color:var(--accent)}

/* ---- Verifiziert-Haken neben dem Namen im Songwriter-Profil -------------
   Immer sichtbar (Entscheidung 11.08.2026), also kein Zustand, sondern Teil
   der Ueberschrift. Dieselbe Akzentfarbe wie die Logos daneben, damit auf der
   Seite ein Lila gilt und nicht zwei. -2px hebt ihn auf die Mittellinie der
   Versalien - auf der Grundlinie haengt er unter dem Namen. */
.vmark{color:var(--accent);display:inline-flex;vertical-align:-2px}

/* ---- Pflichtfeld, das leer geblieben ist (11.08.2026) --------------------
   Roter Rand am FELD, nicht bloss eine Meldung oben. Bei einer Nachmeldung mit
   zwoelf Tracks sagt "Bitte Pflichtfelder ausfuellen" nichts darueber, WELCHE
   der sechzig Zellen gemeint ist.

   Farbe UND aria-invalid: der Rand allein waere fuer jemanden, der Farben
   schlecht unterscheidet, kein Hinweis. Die Route setzt beides gemeinsam.

   !important beim Rand, weil input:focus seinen eigenen Rand setzt und der
   Fehler beim Hineinklicken nicht verschwinden darf - genau dann will man ihn
   noch sehen. Der Fokusring bleibt trotzdem sichtbar, er kommt aus box-shadow. */
input.fieldbad,select.fieldbad,.fieldbad .datef-in{
  border-color:var(--err) !important;background:var(--err-soft)}
input.fieldbad:focus,select.fieldbad:focus,.fieldbad .datef-in:focus{
  border-color:var(--err) !important;box-shadow:0 0 0 3px var(--err-soft)}

/* ---- Songwriter-Liste: zwoelf Spalten ohne Querleiste (11.08.2026) -------
   Gestaucht wird der leere Raum, nicht der Inhalt.

   Das Zellenpolster ist der groesste Posten: 14 px links und rechts sind bei
   zwoelf Spalten 336 px, die keine Information tragen. Auf 8 px gekuerzt bleibt
   die Tabelle luftig und gewinnt 144 px - mehr als jede einzelne Spalte breit
   ist.

   Der Statuschip bleibt ausdruecklich einzeilig: .tag hat dafuer jetzt
   white-space:nowrap, und die Statuszelle zusaetzlich. "No User" auf zwei
   Zeilen sah aus wie ein Fehler, nicht wie ein Zustand. */
table.sheet.swtab thead th{padding-left:8px;padding-right:8px}
table.sheet.swtab tbody td{padding-left:8px;padding-right:8px}
/* Chips brechen um, statt die Spalte aufzuziehen. */
.swtab .chips{max-width:132px}
/* Eingabefelder duerfen unter ihre Inhaltsbreite - sonst setzt der Browser
   eine Mindestbreite aus dem Platzhalter durch und die Spalte waechst wieder. */
.swtab .tagcell input{min-width:0}
/* Die Spotify-Id gekuerzt zeigen, vollstaendig im title (siehe Vorlage). */
.swtab .mchip.spid{max-width:104px;overflow:hidden;text-overflow:ellipsis;
  vertical-align:bottom}

/* ---- UI-12: Abstand und Ausrichtung als Klassen (11.08.2026) -------------
   489 style-Attribute standen in den Vorlagen, obwohl es --sp-1 bis --sp-8
   seit Paket D2 gibt. Der sichtbare Schaden war nie die Menge, sondern die
   Streuung: margin-top:8px, 10px, 12px, 14px und 18px standen auf DERSELBEN
   Seite fuer denselben Zweck nebeneinander. Drei Karten untereinander hatten
   drei verschiedene Abstaende, und niemand hatte das je entschieden.

   Ab hier gibt es fuer diesen einen Zweck Klassen, und die kennen nur die
   Stufen der Leiter. Krumme Werte rasten auf die naechste Stufe ein
   (10 -> 12, 14 -> 16, 18 -> 20); wer eine Stufe dazwischen braucht,
   braucht sie nicht.

   Bewusst NICHT aufgeloest bleiben: errechnete Werte (Balkenhoehe aus einer
   Zahl), Feldbreiten (width:56px an einem Prozentfeld) und echte Einzelfaelle.
   Eine Klasse, die genau einmal benutzt wird, ist nur ein zweiter Ort fuer
   dieselbe Angabe - und der zweite Ort ist der, den man beim naechsten Mal
   nicht findet. */
.mt-0{margin-top:0}
.mt-1{margin-top:var(--sp-1)}
.mt-2{margin-top:var(--sp-2)}
.mt-3{margin-top:var(--sp-3)}
.mt-4{margin-top:var(--sp-4)}
.mt-5{margin-top:var(--sp-5)}
.mt-6{margin-top:var(--sp-6)}
.mt-8{margin-top:var(--sp-8)}
.mb-0{margin-bottom:0}
.mb-1{margin-bottom:var(--sp-1)}
.mb-2{margin-bottom:var(--sp-2)}
.mb-3{margin-bottom:var(--sp-3)}
.mb-4{margin-bottom:var(--sp-4)}
.mb-5{margin-bottom:var(--sp-5)}
.mb-6{margin-bottom:var(--sp-6)}
.m-0{margin:0}
/* Der Fuellplatz zwischen linker und rechter Haelfte einer Leiste. Er stand
   zwoelfmal als <span class="spacer" style="flex:1"> da - die Klasse war also
   schon dran, definiert war sie nur INNERHALB der .topbar. */
.spacer{flex:1}
.grow{flex:1 1 auto;min-width:0}
.nogrow{flex:0 0 auto}
.nowrap{white-space:nowrap}
/* Lesbare Zeilenlaenge fuer Fliesstext - stand siebenmal als max-width:70ch. */
.prose{max-width:70ch}
/* Eine Reihe aus Knoepfen, Chips oder Marken. Dieselben drei bis vier
   Angaben standen ueber ein Dutzend Mal inline. */
.hstack{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.hstack.tight{gap:var(--sp-2)}
.hstack.end{justify-content:flex-end}
.hstack.top{align-items:flex-start}

/* ---- UI-09: Split Manager am Telefon (11.08.2026) ------------------------
   Werke und alle Portal-Seiten schalten unter 860 px auf .cardlist um; der
   Split Manager tat es nicht. Er ist keine Tabelle, sondern eine Liste
   aufklappbarer Alben - der Schaden sass deshalb an drei anderen Stellen:

   1. Die kompakte Zeile ist ausdruecklich flex-wrap:nowrap. Am Telefon
      standen Titel, Anzahl, Songwriter-Chips, Datum, Deal und Statusmarke
      auf EINER nicht umbrechenden Zeile - der halbe Inhalt lag ausserhalb
      des Bildschirms, ohne Hinweis darauf.
   2. Die kompakte Ansicht blendet .smb-actions komplett aus. Am Telefon war
      damit ausgerechnet "Registrieren" unerreichbar - und der Split Manager
      ist die Seite, an der von unterwegs bestaetigt wird.
   3. Die ISRC-Tabelle hat drei feste Spalten plus eine je Songwriter. Sie
      bekommt jetzt wie ueberall sonst eine .cardlist daneben.

   Punkt 1 und 2 loest die Umschaltung hier: unter 860 px gilt die
   KARTEN-Form, egal was der Umschalter oben sagt. Der Umschalter selbst
   verschwindet dort, denn er wuerde sichtbar nichts mehr tun. */
@media (max-width:860px){
  .mode-compact .smrow{flex-wrap:wrap;min-height:0;padding:var(--sp-2) var(--sp-3)}
  .mode-compact .smrow-title{max-width:none;white-space:normal;overflow:visible}
  .mode-compact .smb-fields,.mode-compact .smb-meta{display:block}
  .mode-compact .smb-actions{display:flex}
  .mode-compact .smb-isrc>summary{display:list-item}
  /* Die drei Selektoren, weil die Kompakt-Regeln oben die erste und letzte
     Karte ueber :first-of-type/:last-of-type ansprechen - dieselbe
     Spezifitaet, und ohne Nennung gewaenne dort die fruehere Regel. */
  .mode-compact .smitem,
  .mode-compact .smitem:first-of-type,
  .mode-compact .smitem:last-of-type{margin-bottom:var(--sp-3) !important;
    border:1px solid var(--border);border-radius:var(--radius)}
  /* Der Fuellplatz wuerde die Zeile in der Umbruch-Form auseinanderreissen. */
  .smrow>.spacer{display:none}
  .smview{display:none}
  .smb-fields .field{max-width:none}
}

/* ---- UI-12: Bausteine, die mehr als einmal abgetippt waren ---------------
   Kein Utility-Wildwuchs, sondern genau die Muster, die in den Vorlagen
   woertlich mehrfach standen. Jede Regel hier ersetzt mindestens drei
   style-Attribute; Einzelfaelle bleiben bewusst inline. */

/* Menue-Eintraege (ui.kebab). Die drei Angaben standen IM MAKRO als
   style-Attribut - gerendert also einmal je Menuepunkt der ganzen App. */
.menu-body form{margin:0}
.menu-sep{border-top:1px solid var(--border);margin:var(--sp-1) 0}
.menu-body button.link.danger{color:var(--err)}

/* Profilkopf: Bild oder Anfangsbuchstabe, daneben Name und Adresse.
   Stand im Songwriter-Profil als drei ineinandergeschachtelte
   style-Attribute mit zusammen elf Angaben. */
.idhead{display:flex;align-items:center;gap:var(--sp-4);margin-bottom:var(--sp-4)}
.idhead .ava{width:76px;height:76px;flex:0 0 auto;border-radius:var(--r-lg);
  object-fit:cover;border:1px solid var(--border)}
.idhead .ava.ph{display:flex;align-items:center;justify-content:center;
  background:var(--accent-soft);color:var(--accent-ink);border-color:transparent;
  font-family:var(--serif);font-size:var(--fs-2xl)}

/* Nur-Lese-Tabelle "Feld | Wert". Die Zeilenkoepfe brauchten sechsmal
   dasselbe text-align:left, weil th zentriert ausgerichtet ist. */
table.sheet.deftab{border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden}
table.sheet.deftab th[scope=row]{text-align:left;width:120px}

/* Ein Abschnitt innerhalb einer Karte, durch eine Linie abgesetzt. Stand
   zweimal mit verschiedenen Werten (14/12 und 16/14) fuer dasselbe Bild. */
.subsec{border-top:1px solid var(--border);margin-top:var(--sp-4);padding-top:var(--sp-3)}

/* Zahlenfeld in einer Filter- oder Vertragsleiste: so breit wie sein Inhalt,
   nicht so breit wie das Formular. Stand viermal als width:7ch. */
.inp-num{width:7ch}

/* Die Karte, in der etwas Unwiderrufliches steht. */
.card.danger{border-color:var(--err)}
.card.danger>h2{color:var(--err)}

/* Wert mit Beschriftung daruber - die Kennzahlenreihe unter dem Vertrag und
   dieselbe Form im Portal. */
.kpirow{display:flex;flex-wrap:wrap;gap:var(--sp-5);align-items:flex-start}
.hstack.between{justify-content:space-between}
/* Der Fliesstext einer Biografie: Zeilenumbrueche aus dem Feld bleiben
   stehen, und er liest sich in Textfarbe, nicht in Hinweisgrau. */
.bio{white-space:pre-wrap;color:var(--ink);line-height:1.6}
/* Ein Namens-Chip in einer Liste untereinander: gleiche Mindestbreite,
   damit die Knoepfe daneben eine Spalte bilden. */
.mchip.namecol{min-width:90px}
.hstack.center{justify-content:center}
/* Ein Abschnittstitel ohne den grossen Vorlauf: wenn er INNERHALB einer Karte
   steht, sind 26 px darueber eine Luecke, kein Absatz. */
.sec-title.tight{margin:0 0 var(--sp-2)}
.sec-title h3{font-size:var(--fs-md)}
/* Ein Hinweis, der eine Fehlbedienung meldet. Stand als style="color:var(--err)"
   an mehreren Warnzeilen. */
.hint.err{color:var(--err)}
/* Formulare und Absaetze mit begrenzter Lesebreite. .narrow ist die Breite
   eines Eingabeblocks, .measure die eines Satzes; beide standen mehrfach als
   max-width im style-Attribut. */
.narrow{max-width:460px}
.measure{max-width:44ch;margin-left:auto;margin-right:auto}
/* Eine Zeile in einer Liste untereinander, durch eine Linie getrennt. */
.rowline{padding:var(--sp-2) 0;border-bottom:1px solid var(--border)}
/* Ein Menue, in dem ein ganzes Formular steht statt einer Knopfreihe. */
.menu-body.wide{min-width:300px}
/* Zwei Felder nebeneinander, enger als der Standardabstand. */
.fieldrow.tight{gap:var(--sp-2)}
.block{display:block}
.accent{color:var(--accent-ink)}
/* Die Kontenzelle der Songwriter-Liste: Chips links, Knopf rechts, und die
   Zelle bleibt bei null, einem und zwei Konten gleich hoch. */
.acctcell{max-width:260px}

/* ---- UI-12: die vier ausgeloggten Seiten --------------------------------
   Anmelden, Passwort vergessen, Passwort setzen und Einladung annehmen sind
   vier Kopien derselben Karte. Sie laden base.html bewusst NICHT, und genau
   deshalb hatte jede ihr Layout im style-Attribut stehen - sechsmal dieselbe
   Ueberschrift, fuenfmal dieselbe Knopfzeile, viermal ein Knopf-Stil, den
   .login .btn seit jeher schon setzt (er war schlicht wirkungslos doppelt).
   Weil .box hier zugleich das <form> ist, greift .login .box form nicht -
   daher die zweite Zeile. */
.login h1{font-family:var(--serif);font-size:var(--fs-xl);font-weight:600;margin:0 0 var(--sp-2)}
.login form.box{text-align:center}
.ta-l{text-align:left}
.ta-c{text-align:center}
.ta-r{text-align:right}
/* Eine Reihe, in der Text verschiedener Groesse nebeneinander steht: sie
   richtet sich an der Schriftlinie aus, nicht am Kasten. */
.hstack.base{align-items:baseline}
.pt-3{padding-top:var(--sp-3)}

/* ---- Blaetterleiste (BET-07, 11.08.2026) --------------------------------
   Bis heute gab es sie genau einmal, in archive.html, und dort ohne jede
   Regel: nackte Links in einer Reihe, ohne Abstand, ohne erkennbaren
   aktuellen Zustand. Mit /works, /split-manager und den beiden Portalseiten
   sind es fuenf Stellen - also gehoert sie hierher.

   Mittig, weil sie unter der Liste steht und nicht an ihr klebt. Die aktive
   Seite bekommt die Akzentfarbe wie jeder andere ausgewaehlte Zustand der
   App (.seg .on, .tabs .on). */
.pager{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
       gap:var(--sp-2);margin:var(--sp-5) 0}
.pager a{text-decoration:none}
.pager a[aria-current="page"],.pager a.on{
  background:var(--accent);border-color:var(--accent);color:#fff}
.pager a[aria-current="page"]:hover,.pager a.on:hover{background:var(--accent-2)}
/* Die Luecke zwischen erster/letzter und dem Fenster um die aktuelle Seite.
   Reine Auszeichnung - sie traegt aria-hidden und ist nicht anklickbar. */
.pager .pgap{color:var(--muted);padding:0 var(--sp-1)}
/* "Seite 3 / 9" steht daneben, nicht statt der Zahlen: die Zahlen sind zum
   Springen da, dieser Text sagt, wie viele es ueberhaupt sind. Am Telefon
   rutscht er in eine eigene Zeile. */
.pager .pgnow{font-size:13px;margin-left:var(--sp-2)}
@media (max-width:600px){
  .pager .pgnow{flex-basis:100%;text-align:center;margin-left:0}
}

/* ---- .tag.err ------------------------------------------------------------
   Die Klasse steht seit Paket A in drei Vorlagen (Lauf-Historie, Dubletten-
   Marke in der Warteschlange) - eine Regel dazu gab es nie. Sie sah damit aus
   wie ein neutrales .tag, und "fehlgeschlagen" war von "zurueckgenommen"
   nicht zu unterscheiden. Farbgebung wie .tag.ok, nur mit --err. */
.tag.err{background:var(--err-soft);color:var(--err)}

/* Catalogue identification remains readable; optional columns may scroll. */
#worksheet{table-layout:auto;width:max-content;min-width:100%}
#worksheet [data-key]{min-width:84px}
#worksheet [data-key="_sel"]{min-width:36px}
#worksheet [data-key="songwriter"]{min-width:170px;max-width:250px;white-space:normal}
#worksheet [data-key="name"]{min-width:240px;max-width:360px;white-space:normal;overflow-wrap:anywhere}
#worksheet [data-key="all_artists"]{min-width:190px;max-width:300px;white-space:normal;overflow-wrap:anywhere}
#worksheet .mchip{max-width:none;white-space:normal}
#worksheet .work-edit{font:inherit;text-align:left;white-space:normal}

/* Separate product, tracks and preview sections in manual submission. */
#msform .ms-tracks-title, #msform .ms-preview-title { margin: 2rem 0 .75rem; }
.ms-request-history > h2 { margin: 0 0 .75rem; }

.portal-inbox-toolbar{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-5);padding-bottom:var(--sp-3);border-bottom:1px solid var(--border)}
.portal-inbox-toolbar > .tabs{flex:0 1 auto;min-width:0;margin:0;padding-bottom:0;border-bottom:0}
.portal-inbox-toolbar > .btn{flex-shrink:0;margin-left:auto;white-space:nowrap}
.inbox-mode-switch{margin-bottom:var(--sp-4)}
@media(max-width:560px){
  .portal-inbox-toolbar{gap:var(--sp-2)}
  .portal-inbox-toolbar > .tabs a{padding-inline:var(--sp-2)}
}
