/* PSH Tools — Oberfläche auf Grundlage der PSH UI Foundation.
 *
 * ABSCHNITT 1 ist unverändert aus dem Designsystem übernommen
 * (psh-design-system/PSH UI Foundation.dc.html) und wird hier NICHT
 * bearbeitet. Ändert sich das Corporate Design, wird dieser Block ersetzt,
 * nicht angepasst.
 *
 * Komponenten greifen ausschließlich auf die semantische Ebene zu
 * (--color-*), nie direkt auf die Primitives.
 *
 * Die Regeln des Systems, die das Erscheinungsbild prägen:
 *   1. Bedienelemente sind randlos und liegen auf einer weichen Fläche
 *      (--color-action) statt in einer Kontur.
 *   2. Radien sind großzügig: 10px Eingaben, 12px Schaltflächen, 16px Karten.
 *   3. Höhen sind fest (32/38/46px), nicht aus Innenabständen gerechnet.
 *   4. Der Fokus wird über einen Schattenring gezeigt, nicht über outline.
 *   5. Farbverhältnis grob 70/22/8: helle Flächen dominieren, Ink trägt Text,
 *      Türkis bleibt Akzent. Großflächiges Türkis verliert seine Wirkung.
 *   6. Türkis als Fläche, Türkis-Deep als Schrift. Türkis als Text auf Weiß
 *      erreicht 1.9:1 und ist ausdrücklich verboten.
 */

/* ═══════════════════════════════════════════════════════════════════
   1 · TOKENS — wörtlich aus dem Designsystem, nicht bearbeiten
   ═══════════════════════════════════════════════════════════════════ */
:root{
/* 1 · PRIMITIVES — Corporate Design PharmaScienceHub V01/2024 */
  --psh-ink:#1A1C39;            /* Dark Blue · CMYK 100/93/42/56 */
  --psh-turquoise:#83C6A9;      /* Turquoise · CMYK 53/0/42/0 */
  --psh-bright-bg:#D3E8D4;      /* Bright BG · CMYK 22/0/22/0 */
  --psh-bright:#EFF7F0;         /* Bright · CMYK 8/0/8/0 */
  --psh-white:#FFFFFF;
  /* abgeleitete Stufen (nicht im Print-Manual, für Bildschirm zwingend) */
  --psh-turquoise-deep:#2C7A5F; /* Türkis als TEXT/Link — AA auf Hell */
  --psh-turquoise-dark:#1F5F49; /* Hover der Deep-Stufe */
  --psh-ink-2:#3A3D5E;          /* Fließtext, weicher als Ink */
  --psh-slate:#5E617A;          /* Sekundärtext */
  --psh-line:#DCE7E0;           /* Haarlinie hell */
  --psh-grey-field:#EDEFF2;     /* Eingabefläche ruhend — neutral, nicht getönt */
  --psh-grey-field-hover:#E4E7EC;
  /* Neutrals Dunkel */
  --psh-dark-page:#14162E; --psh-dark-surface:#1E2140; --psh-dark-surface-2:#282C4E;
  --psh-dark-line:#383D63; --psh-dark-text:#EFF7F0; --psh-dark-slate:#9BA3BE;
  /* 6 Akzente — gleiche Helligkeit/Sättigung, nur Farbton variiert */
  --accent-mint:#83C6A9;   --accent-mint-deep:#017555;
  --accent-sky:#7BC0DC;    --accent-sky-deep:#006E90;
  --accent-indigo:#B0AEE7; --accent-indigo-deep:#5E599C;
  --accent-plum:#DBA1C1;   --accent-plum-deep:#8C4970;
  --accent-coral:#E1A68B;  --accent-coral-deep:#934E2C;
  --accent-sand:#BCB97C;   --accent-sand-deep:#6C6606;
  /* Status */
  --status-todo:#E39A93;    --status-todo-deep:#96453E;
  --status-doing:#BCB97C;   --status-doing-deep:#6C6606;
  --status-done:#83C6A9;    --status-done-deep:#2C7A5F;
  --status-archive:#9AA0B5; --status-archive-deep:#5A6079;

  /* 2 · SEMANTIK — nur diese Ebene in Komponenten verwenden */
  --color-bg-page:var(--psh-bright);
  --color-bg-surface:var(--psh-white);
  --color-bg-subtle:var(--psh-bright-bg);
  --color-bg-inverse:var(--psh-ink);
  --color-fg-primary:var(--psh-ink);
  --color-fg-body:var(--psh-ink-2);
  --color-fg-secondary:var(--psh-slate);
  --color-fg-inverse:var(--psh-bright);
  --color-fg-on-accent:var(--psh-ink);
  --color-border:var(--psh-line);
  --color-accent:var(--psh-turquoise);
  --color-accent-text:var(--psh-turquoise-deep);
  --color-accent-hover:var(--psh-turquoise-dark);
  --color-accent-soft:var(--psh-bright-bg);
  --color-action:var(--psh-bright-bg);   /* Fläche sekundärer Aktionen — im Dunkelmodus Petrol */
  /* Eingabefelder ruhen auf neutralem Grau, nicht auf Bright BG. Türkis bleibt
     damit dem gewählten Zustand vorbehalten: Ein Formular, in dem jedes Feld
     grün leuchtet, zeigt keine Auswahl mehr an. */
  --color-bg-field:var(--psh-grey-field);
  --color-bg-field-hover:var(--psh-grey-field-hover);
  --color-bg-field-selected:var(--psh-bright-bg);
  --color-link:var(--psh-turquoise-deep);
  --color-link-hover:var(--psh-turquoise-dark);
  --focus-ring:0 0 0 2px var(--color-bg-surface), 0 0 0 4px var(--psh-turquoise-deep);

  /* Typografie — Hausschrift Open Sans */
  --font-sans:'Open Sans','Segoe UI',-apple-system,sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,Menlo,monospace;
  --text-display:96px; --text-h1:56px; --text-h2:34px; --text-h3:21px;
  --text-body-l:18px; --text-body:16px; --text-body-s:14px; --text-caption:13px; --text-eyebrow:11px;
  --leading-body:1.30;   /* CD-Regel: Zeilenabstand = Schriftgrad + 30 % */
  --leading-tight:1.12;
  --tracking-eyebrow:0.18em;

  /* Spacing · Radien · Schatten · Motion */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:24px;
  --space-6:32px; --space-7:48px; --space-8:64px; --space-9:96px; --space-10:128px;
  --radius-input:10px; --radius-button:12px; --radius-card:16px; --radius-pill:999px;
  --shadow-sm:0 1px 2px rgba(26,28,57,0.06);
  --shadow-md:0 1px 2px rgba(26,28,57,0.06), 0 8px 32px rgba(26,28,57,0.08);
  --shadow-lg:0 4px 12px rgba(26,28,57,0.08), 0 24px 56px rgba(26,28,57,0.14);
  --control-h-sm:32px; --control-h-md:38px; --control-h-lg:46px;
  --ease-out:cubic-bezier(0.22,1,0.36,1);
  --duration-fast:120ms; --duration-base:200ms; --duration-slow:400ms;

  /* Ergänzung für dieses Werkzeug, kein Teil des Systems: Die Schaugrößen
     (H1 56px) gehören auf Website-Seiten, nicht in eine Arbeitsansicht mit
     Tabellen und Formularen. */
  --text-page-title:26px;
  --text-section:19px;
  /* Polsterung der Marken. Das System gibt sie mit 3px/11px an — bewusst
     zwischen den Stufen der Spacing-Skala, weil eine Marke enger sitzt als
     ein Bedienelement. Als Token, damit sie nicht als freier Wert gilt. */
  --pill-pad-y:3px;
  --pill-pad-x:11px;
  /* Kästchen und Schalter. Das System zeigt sie mit 22px Kantenlänge und
     6px Radius; der Haken darin ist 14px. Als Token, damit sie nicht als
     freie Werte gelten. */
  --check-size:22px;
  --radius-check:6px;
  --text-check:14px;
  /* Zeilenabstand für dichte Oberflächen. Das System nennt für Body 16 in
     Interfaces 1.50, weil UI-Text häufiger umbricht als Fließtext. */
  --leading-ui:1.50;
}

*{box-sizing:border-box}
body{margin:0;background:var(--color-bg-page);color:var(--color-fg-primary);font-family:var(--font-sans);font-size:var(--text-body);line-height:var(--leading-body);-webkit-font-smoothing:antialiased;text-wrap:pretty}
h1,h2,h3,p{margin:0}
a{color:var(--color-link);text-decoration:none;border-bottom:1px solid rgba(44,122,95,0.35)}
a:hover{color:var(--color-link-hover);border-bottom-color:currentColor}
@keyframes psh-spin{to{transform:rotate(360deg)}}
@keyframes psh-pulse{0%,100%{opacity:0.25}50%{opacity:1}}
@keyframes psh-shimmer{0%{background-position:-320px 0}100%{background-position:320px 0}}
@keyframes psh-wedge{0%,100%{opacity:0.18}30%{opacity:1}}
@keyframes psh-dock{0%{transform:translate(-16%,16%);opacity:0}12%{opacity:1}42%{transform:translate(0,0);opacity:1}88%{transform:translate(0,0);opacity:1}100%{transform:translate(-16%,16%);opacity:0}}
@keyframes psh-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* ═══════════════════════════════════════════════════════════════════
   2 · KOMPONENTEN dieser Anwendung
   ═══════════════════════════════════════════════════════════════════ */

/* ═══ Typografie & Abstände ════════════════════════════════════════
   Die Schaugrößen des Systems bleiben den Website-Seiten vorbehalten; hier
   gelten die Größen einer Arbeitsansicht. Der Zeilenabstand folgt der Regel
   für dichte Oberflächen (1.50 bei Body 16).

   Der Systemblock setzt h1/h2/h3/p auf margin:0 — sinnvoll als Ausgangspunkt,
   aber dann muss jeder Folgeabstand hier gesetzt werden. Ohne das klebt eine
   Überschrift am nächsten Element. Die Abstände kommen aus der Spacing-Skala,
   nie aus freien Werten. */
h1{font-size:var(--text-page-title); font-weight:700; line-height:var(--leading-tight); letter-spacing:-0.01em}
h2{font-size:var(--text-section); font-weight:700; line-height:var(--leading-tight)}
h3{font-size:var(--text-body); font-weight:700; line-height:var(--leading-tight)}
p{line-height:var(--leading-ui)}

/* Folgeabstände: Eine Überschrift bekommt Luft nach unten, sobald etwas
   folgt. Der Nachbar-Selektor greift nur dann, sodass eine Überschrift am
   Ende eines Blocks keinen überflüssigen Abstand erzeugt. */
h1 + *{margin-top:var(--space-5)}
h2 + *{margin-top:var(--space-4)}
h3 + *{margin-top:var(--space-3)}
p + p{margin-top:var(--space-3)}
/* Ausnahmen, wo der Abstand bereits durch die Komponente gesetzt ist. */
.page-head h1 + p{margin-top:var(--space-1)}
.card-head + *{margin-top:0}
.label + *{margin-top:var(--space-2)}

code,kbd,.mono{font-family:var(--font-mono); font-size:var(--text-caption)}

/* Eyebrow: die Beschriftungsform des Systems — klein, gesperrt, in Versalien. */
.label{
  font-size:var(--text-eyebrow);
  font-weight:600;
  letter-spacing:var(--tracking-eyebrow);
  text-transform:uppercase;
  color:var(--color-fg-secondary);
  line-height:var(--leading-tight);
}

/* ═══ Gerüst ═══════════════════════════════════════════════════════
   Die Kopfzeile liegt vollständig auf Ink. Damit trägt sie den dunklen Anteil
   des Verhältnisses 70/22/8: helle Flächen dominieren die Seite, Ink hält sie
   oben zusammen. Auf dunklem Grund gelten die Regeln des Systems für Dunkel —
   Türkis wird zur Schriftfarbe für Akzente, die Deep-Stufen entfallen dort. */
.masthead{
  background:var(--color-bg-inverse);
  color:var(--color-fg-inverse);
  position:sticky; top:0; z-index:20;
}
.masthead-inner{
  max-width:1240px; margin:0 auto; padding:0 var(--space-5);
  display:flex; align-items:center; gap:var(--space-5); min-height:64px;
}

/* Marke: das HUB-Signet, laut Regelwerk sein Platz als App-Icon. Auf Ink in
   der Negativfassung — die Positivversion auf dunklem Grund ist untersagt. */
.brand{
  display:flex; align-items:center; gap:var(--space-3); flex:none;
  color:var(--color-fg-inverse); border-bottom:0;
}
.brand:hover{color:var(--color-fg-inverse)}
.brand-signet{height:32px; width:auto; display:block; flex:none}
.brand-suffix{
  font-weight:700; font-size:var(--text-body-s);
  letter-spacing:var(--tracking-eyebrow); text-transform:uppercase;
  color:var(--psh-turquoise);
  align-self:center; line-height:var(--leading-tight);
}

/* Navigation auf Ink. Der aktive Zustand wird durch Fläche markiert, nicht
   durch Farbe allein; inaktive Einträge stehen halbtransparent, wie es das
   System für Dunkel beschreibt. */
.nav{display:flex; gap:var(--space-1); margin-left:auto; align-items:center}
.nav a{
  padding:0 var(--space-3); height:var(--control-h-md);
  display:inline-flex; align-items:center; gap:var(--space-2);
  border-radius:var(--radius-button); border-bottom:0;
  color:rgba(239,247,240,0.72); font-size:var(--text-body-s); font-weight:600;
  white-space:nowrap;
  transition:background var(--duration-fast) var(--ease-out),
             color var(--duration-fast) var(--ease-out);
}
.nav a:hover{background:rgba(239,247,240,0.10); color:var(--psh-turquoise)}
.nav a[aria-current="page"]{background:var(--color-accent); color:var(--psh-ink)}
.nav-icon{color:currentColor}

/* Umschalter für schmale Bildschirme. Zustand über ein Kontrollkästchen,
   damit die Navigation ohne JavaScript auf- und zuklappt. */
.nav-burger{display:none; margin:0; cursor:pointer; align-self:center; color:var(--color-fg-inverse)}
.nav-toggle:checked ~ .nav{display:flex}

/* ═══ Profil ═══════════════════════════════════════════════════════
   Klappmenü über <details>: öffnet ohne JavaScript und bleibt mit der
   Tastatur bedienbar. Das Schließen beim Klick daneben ergänzt ui.js. */
.profile{position:relative; flex:none; align-self:center}
.profile-trigger{
  display:flex; align-items:center; gap:var(--space-2);
  height:var(--control-h-md); padding:0 var(--space-3) 0 var(--space-1);
  border-radius:var(--radius-pill); cursor:pointer; list-style:none;
  color:rgba(239,247,240,0.85); font-size:var(--text-body-s); font-weight:600;
  transition:background var(--duration-fast) var(--ease-out);
}
.profile-trigger::-webkit-details-marker{display:none}
.profile-trigger:hover{background:rgba(239,247,240,0.10)}
/* Der Avatar folgt dem Rezept des Systems: Türkis als Fläche, Ink als Zeichen. */
.profile-avatar{
  width:32px; height:32px; border-radius:var(--radius-pill);
  background:var(--color-accent); color:var(--psh-ink);
  padding:var(--space-1); flex:none;
}
.profile-name{max-width:12ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.profile-caret{color:rgba(239,247,240,0.55); transition:transform var(--duration-fast) var(--ease-out)}
.profile[open] .profile-trigger{background:rgba(239,247,240,0.10)}
.profile[open] .profile-caret{transform:rotate(180deg)}

/* Das Klappmenü selbst steht wieder auf Hell: Es gehört zum Seiteninhalt,
   nicht zur Ankerfläche. */
.profile-menu{
  position:absolute; right:0; top:calc(100% + var(--space-2)); z-index:30;
  min-width:270px; max-width:320px; padding:var(--space-2);
  background:var(--color-bg-surface); border-radius:var(--radius-card);
  box-shadow:var(--shadow-lg);
  display:flex; flex-direction:column; gap:0;
  color:var(--color-fg-body);
}
.profile-head{
  padding:var(--space-3);
  border-bottom:1px solid var(--color-border); margin-bottom:var(--space-1);
  line-height:var(--leading-tight);
}
.profile-head strong{display:block; font-size:var(--text-body-s); color:var(--color-fg-primary)}
/* Die Adresse bricht nicht um: Ein mitten im Wort getrennter Adressteil ist
   unlesbar. Bei Überlänge Auslassungspunkte, der volle Wert steht im title. */
.profile-head .hint{
  margin-top:var(--space-1);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.profile-menu a,
.profile-menu button{
  display:flex; align-items:center; gap:var(--space-3);
  padding:0 var(--space-3); height:var(--control-h-md);
  border:0; border-radius:var(--radius-button); background:none;
  color:var(--color-fg-body); font:inherit; font-size:var(--text-body-s);
  font-weight:600; text-align:left; cursor:pointer; width:100%;
  border-bottom:0;
  transition:background var(--duration-fast) var(--ease-out);
}
.profile-menu a:hover,
.profile-menu button:hover{background:var(--color-action); color:var(--color-fg-primary)}
.profile-menu a .icon,
.profile-menu button .icon{color:var(--color-fg-secondary)}
.profile-menu a:hover .icon,
.profile-menu button:hover .icon{color:var(--color-accent-text)}
.profile-menu form{margin:0}

main{max-width:1240px; margin:0 auto; padding:var(--space-6) var(--space-5) var(--space-9)}

/* Seitenkopf: Eyebrow, Überschrift, Erläuterung, Handlungen. Die Abstände
   stehen hier vollständig, damit sie nicht aus dem Zusammenspiel von
   Vererbung und Folgeabständen entstehen — das ergab zuvor Werte zwischen den
   Stufen der Skala. */
.page-head{
  display:flex; align-items:flex-start; gap:var(--space-4); flex-wrap:wrap;
  margin-bottom:var(--space-5); padding-bottom:var(--space-4);
  border-bottom:1px solid var(--color-border);
}
.page-head > div{min-width:0}
.page-head .label{margin:0 0 var(--space-1)}
.page-head h1{margin:0}
.page-head h1 + p{margin-top:var(--space-2)}
.page-head .spacer{margin-left:auto}
.page-head p{color:var(--color-fg-body)}
/* Die Handlungen rechts stehen rechtsbündig und brechen von rechts nach
   links um, nicht von links: Sonst hängt eine einzelne Schaltfläche in der
   zweiten Zeile linksbündig unter den übrigen und sieht verrutscht aus. */
.page-head .btn-row{margin-top:0; justify-content:flex-end}

/* Wird der Platz knapp, weichen die Beschriftungen und die Symbole bleiben:
   Vier Schaltflächen nebeneinander sind lesbarer als zwei Zeilen, und das
   Symbol trägt die Bedeutung schon. Der Name bleibt als Titel erhalten,
   damit er beim Zeigen erscheint. */
@media (max-width:1100px){
  .page-head .btn-row .btn-label{
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap;
  }
  .page-head .btn-row .btn{padding:0 var(--space-3)}
  .page-head .btn-row .btn .icon-btn{margin:0}
}
.breadcrumb{font-size:var(--text-caption); color:var(--color-fg-secondary); margin-bottom:var(--space-1)}
.breadcrumb a{color:var(--color-fg-secondary); border-bottom:0}
.breadcrumb a:hover{color:var(--color-accent-text)}

/* ═══ Karten ═══════════════════════════════════════════════════════
   Randlos auf weißer Fläche mit weichem Schatten. Der Zustand wird über
   einen farbigen Streifen am oberen Rand gezeigt, nicht über eine Kontur:
   Das System kennt keine Konturen. */
.card{
  background:var(--color-bg-surface);
  border-radius:var(--radius-card);
  box-shadow:var(--shadow-sm);
  padding:var(--space-5);
}
.card + .card{margin-top:var(--space-3)}
.card-head{display:flex; align-items:baseline; gap:var(--space-3); margin-bottom:var(--space-3)}
.card-head .spacer{margin-left:auto}

/* Abstände innerhalb einer Karte. Der allgemeine Folgeabstand (h3 + *) greift
   hier nicht zuverlässig, weil zwischen Überschrift und Inhalt bedingte Blöcke
   stehen können. Deshalb stehen die Werte hier vollständig. */
.card > h2,
.card > h3{margin-bottom:var(--space-3)}
.card > h2:only-child,
.card > h3:only-child{margin-bottom:0}
.card > p{margin-bottom:var(--space-4)}
.card > p:last-child{margin-bottom:0}
.card > .hint{margin-top:0; margin-bottom:var(--space-4)}
.card > .hint:last-child{margin-bottom:0}
.card > .btn-row,
.card > form,
.card > .table-wrap{margin-top:var(--space-4)}
.card > .btn-row:first-child,
.card > form:first-child{margin-top:0}
/* Eine einzelne Schaltfläche direkt unter einem Text braucht denselben
   Abstand wie eine Reihe davon. */
.card > .btn{margin-top:var(--space-4)}


.grid{display:grid; gap:var(--space-4); align-items:stretch}
.grid-tools{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.grid-2{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}
.grid > .card{height:100%; margin-top:0}
.grid > div > .card + .card{margin-top:var(--space-3)}
/* Karten in einer Reihe füllen dieselbe Höhe; die Schlusszeile sitzt an der
   Unterkante, statt in der Mitte zu hängen. Ohne das stünde die Schaltfläche
   der kürzeren Karte auf halber Höhe der längeren. */
.card.s-fill{display:flex; flex-direction:column}
.card.s-fill > .s-foot{margin-top:auto; margin-bottom:0}
/* Zwischen einem Block und der nächsten Feldgruppe eine Stufe mehr als
   innerhalb der Gruppe. */
.card.s-fill > pre + .field{margin-top:var(--space-4)}
/* Spalten, deren Inhalt unterschiedlich lang ist und nicht gestreckt werden
   soll — etwa ein Formular neben einer kurzen Hinweisspalte. */
.grid-top{align-items:start}
.grid-top > .card{height:auto}
/* Arbeitsfläche neben Eigenschaften: Das Eigentliche bekommt die Breite, die
   Einstellungen daneben nur so viel, wie sie brauchen. Zwei Drittel zu einem
   Drittel, unter 900px untereinander. */
.grid-main{grid-template-columns:2fr 1fr}
@media (max-width:900px){.grid-main{grid-template-columns:1fr}}

/* --- Mitgliederkommunikation ---------------------------------------------
   Links wer, rechts was besprochen wurde. Man sucht eine Person und liest
   ihren Verlauf, ohne die Liste zu verlieren. */
.comm{display:grid; grid-template-columns:340px 1fr; gap:var(--space-4);
  align-items:start}
@media (max-width:900px){.comm{grid-template-columns:1fr}}
/* Beim Echtversand rahmt die Oberfläche sich ein: Der Unterschied zwischen
   Test und Ernstfall muss ins Auge fallen. */
/* Der rote Rahmen um die ganze Arbeitsfläche ist entfallen: Der Modusbalken
   darüber sagt dasselbe, und zwar in Worten. Zwei Zeichen für eine Auskunft
   heben sich gegenseitig auf — man liest keins davon mehr. */

.comm-list{padding:var(--space-3)}

/* Eingabegruppe: ein Bedienelement aus zwei Teilen. Links das Zeichen, das
   sagt, worum es geht, rechts das Feld — kein Spalt dazwischen, weil sie
   zusammengehören.
   Das vorangestellte Teil ist ruhig getönt, keine Handlung: Es beschriftet,
   es tut nichts. Ausgelöst wird über die Eingabetaste. */
.input-group{
  display:flex; margin-bottom:var(--space-2);
  border-radius:var(--radius-input); overflow:hidden;
}
.input-group-text{
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  height:var(--control-h-lg); min-width:var(--control-h-lg);
  padding:0 var(--space-3);
  background:var(--color-bg-field-hover); color:var(--color-fg-secondary);
}
.input-group-text .icon{margin:0}
/* Die allgemeine Feldregel steht später im Stylesheet und trüge sonst ihren
   eigenen Radius in das zusammengesetzte Element hinein. Die Höhe muss hier
   genannt werden: Beide Teile stehen nebeneinander, und ein Unterschied von
   acht Pixeln fiele sofort als Stufe auf. */
.input-group input[type="search"],
.input-group input[type="text"]{
  flex:1; min-width:0; margin:0; border-radius:0;
  height:var(--control-h-lg);
}
/* Der Fokusring gehört um das ganze Element, nicht um den Eingabeteil —
   sonst säße er mitten im Bedienelement. Das vorangestellte Zeichen bleibt
   dabei grau: Getönt wird das Feld, in dem geschrieben wird. */
.input-group:focus-within{box-shadow:var(--focus-ring)}
.input-group input:focus-visible{box-shadow:none}

/* Die Filter stecken in einem Ausklappfeld: Sie werden seltener angefasst als
   die Suche und nähmen sonst die halbe Spalte ein. Zugeklappt steht da, was
   gerade gilt.

   Keine eigene Fläche und kein Rahmen: Das Feld sitzt bereits in einer Karte,
   und eine Karte in der Karte ist im System ausdrücklich unerwünscht. Getrennt
   wird über eine Linie, wie in der Kartenkopfzeile auch. Getönte Flächen sind
   der Auswahl vorbehalten, nicht einem geöffneten Behälter. */
/* Die Trennlinie läuft bis an den Kartenrand, wie die zwischen den Zeilen
   darunter auch — sonst lägen zwei Linien verschieden weit innen. Der Inhalt
   rückt danach wieder auf die Kante der Suche zurück. */
.comm-filterbox{
  border-top:1px solid var(--color-border);
  margin:var(--space-3) calc(-1 * var(--space-3)) 0;
  padding:0 var(--space-3);
}
/* Der Auslöser ist eine Schaltfläche, keine Fläche: Er reicht über die volle
   Breite, damit die Kanten links mit der Suche und dem Kästchen darunter
   fluchten. */
.comm-filterbox > summary{
  display:flex; align-items:center; gap:var(--space-2);
  min-height:var(--control-h-lg);
  cursor:pointer; list-style:none;
  font-size:var(--text-body-s); font-weight:600;
  color:var(--color-fg-primary);
}
.comm-filterbox > summary:hover{color:var(--color-accent-deep)}
.comm-filterbox > summary::-webkit-details-marker{display:none}
/* Alles in der Zeile auf einer Linie: gleiche Schriftgröße, gleiche
   Zeilenhöhe, keine eigenen Außenabstände. `align-items:center` richtet nur
   die Kästen aus — sitzt in einem davon ein kleinerer Text mit eigenem
   Abstand nach oben, steht seine Schrift trotzdem tiefer als die daneben. */
.comm-filterbox > summary > *{
  margin:0; font-size:var(--text-body-s); line-height:var(--leading-ui);
}
/* Ein Winkel statt des voreingestellten Dreiecks, damit es zum übrigen
   Erscheinungsbild passt. */
/* Der Winkel ist ein Schriftzeichen: Seine Fläche sitzt höher als die Mitte
   der Zeile, weil unter ihm die Unterlänge mitgerechnet wird. Als Zeichnung
   statt als Zeichen hat er keine solche Schlagseite und liegt wirklich mittig. */
.comm-filterbox > summary::after{
  content:""; margin-left:auto;
  width:var(--space-2); height:var(--space-2);
  border-right:2px solid var(--color-fg-secondary);
  border-bottom:2px solid var(--color-fg-secondary);
  transform:rotate(-45deg);
  transition:transform var(--duration-fast) var(--ease-out);
}
.comm-filterbox[open] > summary::after{transform:rotate(45deg)}
.comm-filterbox > summary:focus-visible{
  outline:none; box-shadow:var(--focus-ring); border-radius:var(--radius-input);
}
.comm-filterbody{padding-bottom:var(--space-3)}
/* Nur eine Gruppierung, keine Fläche: Die allgemeine Fieldset-Regel trägt
   eine Kartenfarbe, und die ergäbe hier die zweite Karte in der ersten.
   Zwischen den Gruppen eine Stufe mehr Abstand als innerhalb. */
.comm-filtergroup{
  border:0; background:none; padding:0;
  margin:0 0 var(--space-4);
}
.comm-filtergroup:last-of-type{margin-bottom:var(--space-3)}
.comm-filtergroup > .label{margin-bottom:var(--space-2)}
.comm-filterbody .check{margin-bottom:var(--space-2)}
.comm-filterbody .check:last-child{margin-bottom:0}

.comm-bulk{
  display:flex; align-items:center; gap:var(--space-2);
  padding:var(--space-2) var(--space-3); margin-bottom:var(--space-2);
  border-radius:var(--radius-card); background:var(--color-action);
  font-size:var(--text-body-s);
}
/* `display` schlägt das voreingestellte [hidden]{display:none} des Browsers.
   Ohne diese Zeile stünde die Sammelleiste immer da, auch bei null
   Ausgewählten. Gilt für jedes Element, dem eine Anzeigeart gesetzt wird. */
[hidden]{display:none !important}

/* Eine Liste, keine gestapelten Karten: durchgehende Trennlinien statt
   Rahmen je Zeile. Die Zeilen tragen keine eigene Kontur, sonst entsteht
   der Eindruck versetzter Kästchen. */
.comm-rows{max-height:60vh; overflow-y:auto; margin:0 calc(-1 * var(--space-3))}
.comm-row{
  display:flex; align-items:baseline; gap:var(--space-3);
  padding:var(--space-3);
  border-top:1px solid var(--color-border);
}
.comm-row:first-child{border-top:0}
.comm-row.is-current{
  background:var(--color-bg-page);
  /* Der gewählte Eintrag bekommt eine Marke an der Kante, keine Umrandung:
     Das hebt ihn heraus, ohne die Liste zu zerlegen. */
  box-shadow:inset 3px 0 0 var(--color-accent);
}
.comm-row a{display:block; flex:1; min-width:0; border-bottom:0; color:inherit}
.comm-row input[type=checkbox]{flex:none; margin:0}
.comm-name{
  display:block; font-weight:600; font-size:var(--text-body-s);
  line-height:var(--leading-ui);
}
.comm-meta{
  display:block; font-size:var(--text-caption); line-height:var(--leading-ui);
  color:var(--color-fg-secondary);
}

/* „Alle auswählen" sitzt über der Liste, abgesetzt durch dieselbe Linie,
   die auch die Zeilen trennt. */
.comm-pickall{
  display:flex; align-items:center; gap:var(--space-2);
  padding:var(--space-2) 0;
  font-size:var(--text-body-s);
}
.comm-pickall .check{margin:0}
.comm-pages{display:flex; align-items:center; gap:var(--space-2);
  margin-top:var(--space-3)}

.comm-timeline{max-height:52vh; overflow-y:auto; padding-right:var(--space-2)}
.comm-msg{
  margin-bottom:var(--space-3); padding:var(--space-3);
  border-radius:var(--radius-card); background:var(--color-bg-page);
}
/* Ausgehendes eingerückt, Eingehendes bündig: Wer zuletzt gesprochen hat,
   ist damit ohne Lesen erkennbar. */
.comm-out{margin-left:var(--space-6); background:var(--color-bg-subtle)}
.comm-in{margin-right:var(--space-6)}
.comm-note{
  margin:0 var(--space-5) var(--space-3);
  background:rgba(212,177,106,0.14);
  border:1px dashed var(--color-border);
}
.comm-msg.is-test{box-shadow:inset 3px 0 0 var(--status-todo)}
.comm-msg.is-failed{box-shadow:inset 3px 0 0 var(--status-todo)}
.comm-msg-head{font-size:var(--text-caption); color:var(--color-fg-secondary);
  margin:0 0 var(--space-1)}
.comm-msg-subject{font-weight:600; margin:0 0 var(--space-2)}

/* Ein Platzhalter ohne Wert wird rot: Er darf nicht unbemerkt in einer
   echten Mail landen. */
input.is-missing{box-shadow:inset 0 0 0 2px var(--status-todo)}

/* Eine Zahl auf einer Schaltfläche ist keine Statusmarke: Sie zählt, was
   dahinter liegt. Sie übernimmt deshalb die Schriftfarbe der Schaltfläche und
   setzt sich nur über die Fläche ab — eine eigene Farbe wäre auf dunklem Grund
   entweder unlesbar oder eine zweite Aussage, die es nicht gibt. */
.btn-count{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:1.5em; padding:0 var(--space-1);
  border-radius:var(--radius-pill);
  background:rgba(255,255,255,0.22); color:inherit;
  font-size:var(--text-caption); font-weight:600;
  font-variant-numeric:tabular-nums;
}
/* Auf heller Fläche kehrt sich das um. */
.btn:not(.btn-primary):not(.btn-send) .btn-count{background:rgba(26,28,57,0.10)}

.btn-test-on{background:var(--status-doing); color:var(--color-fg-body)}
.btn-live{background:var(--status-todo); color:var(--color-fg-inverse)}

/* Der Modusbalken: die eine Stelle, an der steht, wohin eine Mail geht.
   Vorher stand dieselbe Auskunft dreimal auf der Seite — als Meldung oben,
   als Marke in der Kopfzeile und noch einmal als Meldung darunter. Wer etwas
   dreimal liest, liest es beim vierten Mal nicht mehr.
   Der Umschalter sitzt darin, weil man den Zustand dort liest. */
.modebar{
  display:flex; align-items:center; gap:var(--space-3);
  min-height:var(--control-h-lg);
  padding:0 var(--space-4); margin-bottom:var(--space-4);
  border-radius:var(--radius-card);
  font-size:var(--text-body-s); line-height:var(--leading-ui);
}
.modebar-test{background:rgba(131,198,169,0.30)}
.modebar-live{background:rgba(227,154,147,0.30)}
.modebar .icon{flex:none; margin:0}
.modebar-test .icon{color:var(--color-accent-deep)}
.modebar-live .icon{color:var(--status-todo-deep)}
/* Das Wort, auf das es ankommt, in Versalien wie die Beschriftungen sonst. */
.modebar-state{
  font-weight:700; letter-spacing:var(--tracking-eyebrow);
  text-transform:uppercase;
}
.modebar-note{color:var(--color-fg-secondary)}
/* Der Umschalter steht rechts, mit Abstand zum Text: Er ist die Handlung,
   nicht die Auskunft. Auf der getönten Fläche braucht er eine eigene, helle
   Fläche — die übliche Schaltflächenfarbe liegt zu nah am Balken und ließe
   ihn wie beschrifteten Text aussehen. */
.modebar form{margin-left:auto}
.modebar .btn{
  margin:0; background:var(--psh-white); color:var(--color-fg-primary);
}
.modebar .btn:hover{background:var(--color-accent); color:var(--color-fg-on-accent)}

/* Der gesammelte Posteingang. Eine Liste, die eine Frage beantwortet:
   worauf muss ich noch reagieren? */
.inbox-row{
  display:flex; align-items:flex-start; gap:var(--space-4);
  padding:var(--space-4) 0; border-top:1px solid var(--color-border);
}
.inbox-row:first-child{border-top:0; padding-top:0}
.inbox-main{flex:1; min-width:0}
.inbox-actions{flex:none; display:flex; gap:var(--space-2)}
/* Ungelesenes trägt eine Marke an der Kante, kein farbiges Feld: Es soll
   auffallen, ohne die Liste einzufärben. */
.inbox-row.is-unread{
  box-shadow:inset 3px 0 0 var(--status-todo);
  padding-left:var(--space-3);
}
.inbox-head{margin:0 0 var(--space-1); font-size:var(--text-body-s)}
.inbox-head a{border-bottom:0; color:inherit}
.inbox-subject{margin:0 0 var(--space-1); font-weight:600}
.inbox-preview{
  margin:0; font-size:var(--text-body-s); color:var(--color-fg-secondary);
  line-height:var(--leading-ui);
}

/* Fortschritt eines Rundschreibens. */
.progress{
  height:var(--space-2); border-radius:var(--radius-pill);
  background:var(--color-bg-field); overflow:hidden;
}
.progress-bar{
  height:100%; background:var(--color-accent);
  transition:width var(--duration-base) var(--ease-out);
}

/* Schrittanzeige eines Assistenten. Zeigt, wo man ist und wie viel noch
   kommt — sonst bliebe bei Schritt 3 unklar, ob noch zwei oder zehn folgen. */
.wizard-steps{
  display:flex; flex-wrap:wrap; gap:var(--space-2);
  list-style:none; margin:0 0 var(--space-5); padding:0;
}
.wizard-steps li{
  display:inline-flex; align-items:center; gap:var(--space-2);
  padding:var(--pill-pad-y) var(--pill-pad-x);
  border-radius:var(--radius-pill);
  font-size:var(--text-caption); font-weight:600;
  background:rgba(94,97,122,0.10); color:var(--color-fg-secondary);
}
.wizard-steps .wizard-num{
  display:inline-flex; align-items:center; justify-content:center;
  width:1.25rem; height:1.25rem; border-radius:var(--radius-pill);
  background:rgba(94,97,122,0.18); font-variant-numeric:tabular-nums;
}
.wizard-steps li.is-done{
  background:rgba(131,198,169,0.22); color:var(--accent-mint-deep);
}
.wizard-steps li.is-done .wizard-num{background:rgba(131,198,169,0.35)}
.wizard-steps li.is-current{
  background:var(--color-action); color:var(--color-fg-inverse);
}
.wizard-steps li.is-current .wizard-num{background:rgba(255,255,255,0.22)}

.tool-card{
  display:flex; flex-direction:column; height:100%;
  border-bottom:0; color:inherit; padding:var(--space-5);
  transition:box-shadow var(--duration-base) var(--ease-out),
             transform var(--duration-base) var(--ease-out);
}
.tool-card:hover{box-shadow:var(--shadow-md); transform:translateY(-2px); color:inherit}
.tool-card h3{color:var(--color-fg-primary)}
.tool-card p{margin-top:var(--space-2); color:var(--color-fg-secondary)}

/* Ikonografie — Phosphor Regular, das verbindliche Hausset.
   Größen nach Regelwerk: 16 in dichten Listen, 20 in Schaltflächen,
   24 im Standard, 32 in leeren Zuständen. */
/* fill hier und nicht am Sprite: Über <use> wird das Attribut des versteckten
   Quell-Elements nicht vererbt, die Symbole blieben sonst schwarz. */
.icon{width:24px; height:24px; display:block; flex:none; fill:currentColor}
.icon-sm{width:16px; height:16px}
.icon-btn{width:20px; height:20px}
.icon-lg{width:32px; height:32px}

/* Kategorie-Kachel: Tönung des Akzents als Fläche, Deep-Stufe als Icon.
   Hover verdichtet die Tönung, das Icon behält seine Farbe. So beschreibt es
   das Regelwerk für Übersichten — nie zur Dekoration, nie mehr als sechs. */
.tool-icon{
  width:52px; height:52px; display:grid; place-items:center;
  border-radius:var(--radius-button); background:var(--color-bg-subtle);
  color:var(--color-accent-text); margin-bottom:var(--space-4);
  transition:background var(--duration-base) var(--ease-out);
}
.tool-card:hover .tool-icon{background:var(--color-accent); color:var(--psh-ink)}

/* ═══ Kennzahlen ═══════════════════════════════════════════════════ */
.stats{display:flex; gap:var(--space-6); flex-wrap:wrap}
.stat .num{
  font-family:var(--font-mono); font-size:var(--text-h3); font-weight:500;
  display:block; line-height:var(--leading-tight); color:var(--color-fg-primary);
}
.stat .num.warn{color:var(--status-todo-deep)}
.stat .num.done{color:var(--status-done-deep)}

/* ═══ Tabellen ═════════════════════════════════════════════════════ */
.table-wrap{
  overflow-x:auto; background:var(--color-bg-surface);
  border-radius:var(--radius-card); box-shadow:var(--shadow-sm);
}
table{width:100%; border-collapse:collapse; font-size:var(--text-body-s); line-height:var(--leading-ui)}
/* Mittig statt oben ausgerichtet: In einer Zeile stehen Text, Marken und
   Schaltflächen nebeneinander, und die sind unterschiedlich hoch. An der
   Oberkante ausgerichtet sitzt dann jedes auf einer anderen Linie. */
th,td{padding:var(--space-3) var(--space-4); text-align:left; vertical-align:middle}
/* Eine Zelle, deren Inhalt selbst mehrzeilig ist (Name über Beschreibung),
   bleibt oben — sonst rutschte die ganze Zeile auseinander. */
td.top{vertical-align:top}
thead th{
  background:var(--color-bg-surface);
  border-bottom:1px solid var(--color-border);
  font-size:var(--text-eyebrow); font-weight:700;
  letter-spacing:var(--tracking-eyebrow); text-transform:uppercase;
  color:var(--color-fg-secondary); white-space:nowrap;
}
tbody tr{border-bottom:1px solid var(--color-border)}
tbody tr:last-child{border-bottom:0}
tbody tr:hover{background:var(--color-bg-page)}
td.mono,th.mono{font-family:var(--font-mono); font-size:var(--text-caption)}
td.num{text-align:right; font-family:var(--font-mono)}
/* Handlungen am Zeilenende stehen rechts und rühren sich nicht: Ohne
   `nowrap` bricht eine Schaltfläche um, sobald der Titel daneben länger
   wird, und die Spalte franst über die Zeilen hinweg aus. */
td:last-child .btn-row{justify-content:flex-end; flex-wrap:nowrap}
th:last-child:empty,td:last-child:has(.btn-row){white-space:nowrap; width:1%}

/* Klebender Kopf nur, wenn die Tabelle selbst scrollt — sonst wäre der
   Bezugspunkt die Seite, und der Kopf legte sich über die erste Zeile. */
.table-scroll{max-height:70vh; overflow-y:auto}
.table-scroll thead th{position:sticky; top:0; z-index:1; box-shadow:0 1px 0 var(--color-border)}

/* Zustandsstreifen in Zeilen, dieselbe Sprache wie bei den Karten. */
tbody tr[class*="s-"] > td:first-child{
  box-shadow:inset 3px 0 0 var(--status-archive); padding-left:var(--space-4);
}
tbody tr.s-accent > td:first-child{box-shadow:inset 3px 0 0 var(--color-accent)}
tbody tr.s-warn   > td:first-child{box-shadow:inset 3px 0 0 var(--status-todo)}
tbody tr.s-done   > td:first-child{box-shadow:inset 3px 0 0 var(--status-done)}
tbody tr.s-idle   > td:first-child{box-shadow:inset 3px 0 0 var(--color-border)}

/* ═══ Marken (Pills) ═══════════════════════════════════════════════
   Genau nach den Werten des Systems: 3px oben/unten, 11px links/rechts,
   Caption-Größe, halbfett. Die Fläche ist eine Tönung des Akzents, die
   Schrift dessen Deep-Stufe — dasselbe Rezept wie bei den Kategoriekacheln.
   Eine volle Akzentfläche wäre zu laut für eine Marke, die nur einordnet. */
.tag{
  display:inline-flex; align-items:center;
  border-radius:var(--radius-pill); padding:var(--pill-pad-y) var(--pill-pad-x);
  font-size:var(--text-caption); font-weight:600;
  background:rgba(94,97,122,0.14); color:var(--color-fg-secondary);
  white-space:nowrap; flex:none;
}
.tag-accent{background:rgba(131,198,169,0.22); color:var(--accent-mint-deep)}
.tag-done{background:rgba(131,198,169,0.22); color:var(--status-done-deep)}
.tag-warn{background:rgba(227,154,147,0.26); color:var(--status-todo-deep)}
/* Status einer Umfrage in der Farbe des Zustands, nicht alle gleich grau:
   Entwurf ist in Arbeit, offen laeuft, geschlossen ist vorbei. Die drei
   Farben stammen aus der Statusreihe des Designsystems. */
.tag-draft{background:rgba(188,185,124,0.26); color:var(--status-doing-deep)}
.tag-open{background:rgba(131,198,169,0.26); color:var(--status-done-deep)}
.tag-closed{background:rgba(94,97,122,0.14); color:var(--color-fg-secondary)}
/* Belegzustaende. Dieselbe Reihe: was laeuft ist gelblich, was gut ausging
   gruen, was erledigt oder verworfen ist grau, und Storno traegt die
   Warnfarbe — es ist der einzige Zustand, bei dem etwas schiefging. */
.tag-sent{background:rgba(188,185,124,0.26); color:var(--status-doing-deep)}
.tag-accepted{background:rgba(131,198,169,0.26); color:var(--status-done-deep)}
.tag-paid{background:rgba(131,198,169,0.26); color:var(--status-done-deep)}
.tag-cancelled{background:rgba(227,154,147,0.26); color:var(--status-todo-deep)}
/* Summenblock unter der Positionstabelle. Rechtsbuendig wie die Betraege
   darueber, damit die Ziffern in einer Spalte stehen. */
.sumbox{
  display:flex; flex-direction:column; gap:var(--space-2);
  margin-top:var(--space-4); padding:var(--space-4);
  border-radius:var(--radius-card); background:var(--color-bg-page);
  font-size:var(--text-body-s);
}
.sumline{display:flex; align-items:baseline; gap:var(--space-4)}
.sumline > span:first-child{flex:1}
.sumline > span:last-child{font-family:var(--font-mono); text-align:right}
/* Betragsspalten brechen nicht um: „437,63" und das Waehrungszeichen
   gehoeren zusammen, und umgebrochen sieht es aus wie zwei Zahlen. */
td.num,th.num{white-space:nowrap}
.sumline-total{
  padding-top:var(--space-2); border-top:1px solid var(--color-border);
  font-weight:700; font-size:var(--text-body);
}
/* Eine Marke, die nur eine Zahl trägt, wird rund statt länglich: Sie zählt
   etwas, sie beschriftet nichts. */
.tag-count{
  min-width:1.5em; padding:var(--pill-pad-y) var(--space-1);
  justify-content:center; font-variant-numeric:tabular-nums;
}
.tag-unread{background:var(--status-todo); color:var(--status-todo-deep)}

/* Mehrere Marken nebeneinander brauchen Abstand — als Reihe, nicht durch
   Leerzeichen im Markup. */
.tag-row{display:flex; flex-wrap:wrap; gap:var(--space-2)}

/* ═══ Bedienelemente ═══════════════════════════════════════════════
   Randlos, auf weicher Fläche, feste Höhe. Das ist die auffälligste Regel
   des Systems: keine Konturen um Schaltflächen und Eingabefelder. */
.btn{
  height:var(--control-h-md); padding:0 var(--space-4);
  border:0; border-radius:var(--radius-button);
  background:var(--color-action); color:var(--psh-ink);
  font-family:var(--font-sans); font-size:var(--text-body-s); font-weight:600;
  cursor:pointer; display:inline-flex; align-items:center; gap:var(--space-2);
  white-space:nowrap; border-bottom:0;
  transition:background var(--duration-fast) var(--ease-out),
             transform var(--duration-fast) var(--ease-out);
}
.btn:hover{background:var(--color-accent); color:var(--color-fg-on-accent)}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--color-accent-text); color:var(--psh-white)}
.btn-primary:hover{background:var(--color-accent-hover); color:var(--psh-white)}
/* Echtversand: die Handlung, die sich nicht zurücknehmen lässt. */
.btn-send{background:var(--status-todo-deep); color:var(--psh-white)}
.btn-send:hover{background:#7d3934; color:var(--psh-white)}
.btn-small{height:var(--control-h-sm); padding:0 var(--space-3); font-size:var(--text-caption)}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.45; cursor:not-allowed}
/* Schaltflächen einer Reihe stehen auf gleicher Höhe und auf einer Linie.
   `stretch` statt `center`: Steht eine davon in einem Formular, ist dieses
   Formular das Reihenkind und die Schaltfläche darin würde sonst in ihrer
   eigenen Höhe schweben. */
.btn-row{display:flex; gap:var(--space-2); flex-wrap:wrap; align-items:stretch}
.btn-row > form{display:flex}
/* Fällt eine aus der Reihe, liegt es fast immer daran, dass sie eine andere
   Größenklasse trägt. Die Reihe gleicht das nicht aus — sie macht es
   sichtbar, indem alle dieselbe Höhe bekommen wie die erste. */
.btn-row > .btn,
.btn-row > form > .btn{align-self:stretch}

label{display:block; margin-bottom:var(--space-4)}
/* Die Beschriftung sitzt über dem Feld, mit Luft dazwischen. Ohne diesen
   Abstand kleben Eyebrow und Eingabe aneinander. */
label > .label{display:block; margin-bottom:var(--space-2)}
label > .hint{margin-top:var(--space-2)}
label:last-child{margin-bottom:0}

/* Feldgruppe nach dem Vorbild von psh-ui: Beschriftung und Eingabe gehören
   zusammen, zwischen ihnen ein Schritt, zur nächsten Gruppe zwei.

   Ohne die Gruppe steht die Beschriftung als Geschwister vor dem Feld, und
   dann greift der Abstand *unter* der Beschriftung: Zwischen Beschriftung
   und Feld lagen 16px, zwischen Feld und Schaltfläche keine — also genau
   verkehrt herum. */
.field{display:block; margin-bottom:var(--space-4)}
.field:last-child{margin-bottom:0}
.field > label{margin-bottom:var(--space-2)}
.field > .label{display:block; margin-bottom:var(--space-2)}
.field > .hint{margin-top:var(--space-2); margin-bottom:0}
/* Innerhalb der Gruppe trägt das Feld selbst keinen eigenen Außenabstand:
   Er käme zu dem der Gruppe hinzu. */
.field > input,.field > select,.field > textarea{margin-bottom:0}

input[type="text"],input[type="email"],input[type="password"],input[type="number"],
input[type="date"],input[type="datetime-local"],input[type="search"],input[type="file"],select{
  width:100%; height:var(--control-h-lg);
  border:0; border-radius:var(--radius-input);
  background:var(--color-bg-field); padding:0 var(--space-4);
  font-family:var(--font-sans); font-size:var(--text-body); color:var(--psh-ink);
  transition:background var(--duration-fast) var(--ease-out);
}
input[type="text"]:hover,input[type="email"]:hover,input[type="password"]:hover,
input[type="number"]:hover,input[type="date"]:hover,input[type="datetime-local"]:hover,
input[type="search"]:hover,select:hover,textarea:hover{background:var(--color-bg-field-hover)}
/* Türkis erst, wenn der Nutzer das Feld angesteuert hat. */
input:focus-visible,select:focus-visible,textarea:focus-visible{background:var(--color-bg-field-selected)}
select{appearance:none; padding-right:var(--space-6);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%236B7093' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right var(--space-4) center; background-size:16px;
}
select[multiple]{height:auto; padding:var(--space-3) var(--space-4); background-image:none}
/* Auch das Dateifeld hat die Höhe eines Bedienelements: Es steht neben
   Schaltflächen, und `height:auto` ließe es dort niedriger sitzen.
   Ausgerichtet wird über die Zeilenhöhe, nicht über flex: Der Browser setzt
   in dieses Feld eine eigene Schaltfläche und den Dateinamen: Als
   Flex-Container gerieten beide zu eigenständigen Elementen, und der Name
   rutschte aus dem Feld heraus über den Text darüber. */
input[type="file"]{
  height:var(--control-h-lg); padding:0 var(--space-3);
  line-height:var(--control-h-lg);
}
/* Die Schaltfläche darin in der Form des Systems, statt in der des Browsers. */
input[type="file"]::file-selector-button{
  height:var(--control-h-sm); margin-right:var(--space-3); padding:0 var(--space-3);
  border:0; border-radius:var(--radius-button);
  background:var(--color-action); color:var(--color-fg-primary);
  font-family:var(--font-sans); font-size:var(--text-body-s); font-weight:600;
  cursor:pointer;
}
input[type="file"]::file-selector-button:hover{
  background:var(--color-accent); color:var(--color-fg-on-accent);
}
textarea{
  width:100%; border:0; border-radius:var(--radius-input);
  background:var(--color-bg-field); padding:var(--space-3) var(--space-4);
  transition:background var(--duration-fast) var(--ease-out);
  font-family:var(--font-mono); font-size:var(--text-caption);
  line-height:var(--leading-ui); color:var(--psh-ink); min-height:10rem; resize:vertical;
}
input:focus-visible,select:focus-visible,textarea:focus-visible,
.btn:focus-visible,a:focus-visible{outline:none; box-shadow:var(--focus-ring)}

.field-error{color:var(--status-todo-deep); font-size:var(--text-caption); margin-top:var(--space-1)}
input[aria-invalid="true"],textarea[aria-invalid="true"]{
  background:rgba(227,154,147,0.14); box-shadow:0 0 0 2px var(--status-todo-deep);
}
.hint{color:var(--color-fg-secondary); font-size:var(--text-caption); margin-top:var(--space-1)}
/* Steht ein Hinweis über einem Formular, braucht er Luft nach unten: Sonst
   klebt die Beschriftung des ersten Feldes daran. Innerhalb eines Feldes
   gilt das nicht — dort gehört der Hinweis dicht an das Feld. */
.hint + form,.hint + .btn,.hint + .btn-row{margin-top:var(--space-4)}

/* Kästchen in der Form des Designsystems: 22px, Radius 6, gewählt in Türkis
   mit Ink-Haken. Der Systementwurf zeigt sie ausdrücklich so — die Vorgabe
   des Browsers über `accent-color` trifft weder Größe noch Radius.

   Die Regel gilt für jedes Kästchen, nicht nur für die in einem `.check`:
   In der Mitgliederliste steht eines blank in der Tabellenzelle, und das
   erschien dort in der Browserform, neben den gestalteten sichtbar anders. */
.check{display:flex; align-items:center; gap:10px; margin-bottom:var(--space-2)}
input[type="checkbox"],
input[type="radio"]{
  appearance:none; -webkit-appearance:none;
  flex:none; width:var(--check-size); height:var(--check-size); margin:0;
  border:0; border-radius:var(--radius-check); background:var(--color-bg-field);
  cursor:pointer; display:grid; place-items:center;
  transition:background var(--duration-fast) var(--ease-out);
}
input[type="radio"]{border-radius:var(--radius-pill)}
input[type="checkbox"]:hover,
input[type="radio"]:hover{background:var(--color-bg-field-hover)}
input[type="checkbox"]:checked,
input[type="radio"]:checked{background:var(--color-accent)}
/* Der Haken als Zeichen, nicht als Bild: Er skaliert mit und braucht keine
   zweite Datei. Ink auf Türkis erreicht 8.4:1. */
input[type="checkbox"]:checked::after{
  content:"✓"; color:var(--psh-ink);
  font-size:var(--text-check); font-weight:700; line-height:var(--leading-tight);
}
input[type="radio"]:checked::after{
  content:""; width:var(--space-2); height:var(--space-2);
  border-radius:var(--radius-pill);
  background:var(--psh-ink);
}
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible{box-shadow:var(--focus-ring)}
.check span{font-size:var(--text-body-s)}
.check label{margin-bottom:0}

fieldset{
  border:0; border-radius:var(--radius-card); background:var(--color-bg-page);
  padding:var(--space-4); margin:0 0 var(--space-4);
}
legend{padding:0; margin-bottom:var(--space-2)}

/* Testmodus-Schalter: das eine Bedienelement, das nicht übersehen werden darf. */
/* Testmodus in der Farbe für „in Arbeit“, nicht in der für Warnungen: Er ist
   ein laufender Zustand und kein Fehler. Dadurch bleibt er zugleich vom roten
   Echtversand unterscheidbar. */
.testmode{
  display:flex; align-items:flex-start; gap:var(--space-3);
  padding:var(--space-4); border-radius:var(--radius-card);
  background:rgba(188,185,124,0.22);
}
.testmode input{width:auto; height:auto; align-self:center; accent-color:var(--status-doing-deep)}
.testmode strong{display:block; font-size:var(--text-body-s)}
.testmode small{color:var(--color-fg-body); font-size:var(--text-caption)}
.testmode label{margin-bottom:0}

/* ═══ Meldungen ════════════════════════════════════════════════════ */
/* Meldungen tragen ein Symbol, damit ihre Art ohne Lesen erkennbar ist. */
.flash{
  display:flex; align-items:flex-start; gap:var(--space-3);
  padding:var(--space-3) var(--space-4); border-radius:var(--radius-card);
  margin-bottom:var(--space-3); font-size:var(--text-body-s);
  line-height:var(--leading-ui);
  background:var(--color-accent-soft); color:var(--color-fg-primary);
}
.flash-icon{flex:none; align-self:center}
.flash-success .flash-icon{color:var(--status-done-deep)}
.flash-warning .flash-icon,
.flash-error .flash-icon{color:var(--status-todo-deep)}
.flash-success{background:rgba(131,198,169,0.30)}
.flash-warning{background:rgba(227,154,147,0.30)}
.flash-error{background:rgba(227,154,147,0.28)}

.empty{
  padding:var(--space-8) var(--space-5); text-align:center; color:var(--color-fg-secondary);
  border-radius:var(--radius-card); background:var(--color-bg-surface); box-shadow:var(--shadow-sm);
}
.empty h3{color:var(--color-fg-primary)}
.empty p{margin:var(--space-2) 0 var(--space-4)}

/* ═══ Verlauf ══════════════════════════════════════════════════════ */
.thread{display:flex; flex-direction:column; gap:var(--space-3)}
.msg{
  border-radius:var(--radius-card); padding:var(--space-4);
  background:var(--color-bg-surface); box-shadow:var(--shadow-sm);
  position:relative; overflow:hidden;
}
.msg::before{content:""; position:absolute; inset:0 auto 0 0; width:3px; background:var(--color-border)}
.msg-out::before{background:var(--color-accent)}
.msg-in::before{background:var(--status-done)}
.msg-note::before{background:var(--status-archive)}
.msg-head{
  display:flex; gap:var(--space-3); align-items:baseline;
  font-size:var(--text-caption); color:var(--color-fg-secondary); margin-bottom:var(--space-2);
}
.msg-head .subject{color:var(--color-fg-primary); font-weight:700; font-size:var(--text-body-s)}
.msg-body{
  white-space:pre-wrap; font-family:var(--font-mono); font-size:var(--text-caption);
  line-height:var(--leading-ui); margin:0; color:var(--color-fg-body);
}

/* ═══ Umfragen ═════════════════════════════════════════════════════ */
.question{border-bottom:1px solid var(--color-border); padding:var(--space-4) 0}
.question:last-of-type{border-bottom:0}
.question > .q-text{font-weight:600; margin-bottom:var(--space-1); color:var(--color-fg-primary)}
.required-mark{color:var(--status-todo-deep); margin-left:var(--space-1)}

.scale{display:flex; gap:var(--space-2); flex-wrap:wrap; margin-top:var(--space-2)}
.scale label{
  margin:0; cursor:pointer; border-radius:var(--radius-button);
  height:var(--control-h-md); padding:0 var(--space-4);
  display:inline-flex; align-items:center;
  font-family:var(--font-mono); font-size:var(--text-body-s);
  background:var(--color-action); color:var(--psh-ink);
  transition:background var(--duration-fast) var(--ease-out);
}
.scale input{position:absolute; opacity:0; width:0}
.scale label:has(input:checked){background:var(--color-accent-text); color:var(--psh-white)}
.scale label:has(input:focus-visible){box-shadow:var(--focus-ring)}

.bar{height:6px; background:var(--color-action); border-radius:var(--radius-pill); overflow:hidden; min-width:60px}
.bar > span{display:block; height:100%; background:var(--color-accent); border-radius:var(--radius-pill)}

.dots{display:flex; gap:var(--space-1); flex-wrap:wrap}
.dots a{
  width:26px; height:26px; display:grid; place-items:center;
  border-radius:var(--radius-button); border-bottom:0;
  background:var(--color-action); color:var(--color-fg-secondary);
  font-size:var(--text-eyebrow); font-family:var(--font-mono);
}
.dots a.done{background:var(--status-done); color:var(--status-done-deep)}
.dots a.current{background:var(--color-accent-text); color:var(--psh-white)}

/* ═══ Filterleisten ════════════════════════════════════════════════
   Suchfeld und Auswahllisten in einer Zeile. Alle Felder wachsen gleich
   mit, damit keins schmaler bleibt als das daneben; auf schmalen
   Bildschirmen steht jedes über die volle Breite. */
.filter-bar{display:flex; gap:var(--space-3); flex-wrap:wrap; align-items:flex-end}
.filter-field{flex:1 1 220px; margin:0; min-width:0}
.filter-check{margin-bottom:var(--space-3); flex:0 0 auto}
.filter-bar .btn{margin-bottom:0}

/* Filterzeile für Notion-Quellen */
.filter-row{display:flex; gap:var(--space-2); align-items:center; margin-bottom:var(--space-2); flex-wrap:wrap}
.filter-row select,.filter-row input[type="text"]{width:auto; flex:1 1 170px; min-width:130px}
.filter-row .btn{flex:0 0 auto}

/* ═══ Öffentliche Seiten ═══════════════════════════════════════════ */
.public{max-width:720px; margin:var(--space-8) auto; padding:0 var(--space-5)}
.public-card{
  background:var(--color-bg-surface); border-radius:var(--radius-card);
  padding:var(--space-7); box-shadow:var(--shadow-md);
}
.public h1{font-size:var(--text-h2); line-height:var(--leading-tight)}
.public .intro{color:var(--color-fg-body); margin-bottom:var(--space-5); font-size:var(--text-body)}
/* Die Anmeldung sitzt in derselben Karte wie die übrigen öffentlichen Seiten.
   Die Karte selbst wird deshalb schmal, nicht ein Kind darin: Sonst bliebe
   die Karte 720px breit und der Inhalt klebte linksbündig darin. */
.public-login{max-width:420px; margin-top:14vh}
.login{max-width:none; margin:0}
/* Die Überschrift braucht Luft zum Formular. Der allgemeine Folgeabstand
   greift hier nicht, weil zwischen beiden ein bedingter Block stehen kann. */
.login h1{margin-bottom:var(--space-5)}
.login form{margin-top:0}
/* Der Abstand unter dem Logo hält den Schutzraum ein: Freiraum rundum in der
   Breite des „H“ der Wortmarke, in den nichts hineinragt. */
.login-logo{height:53px; width:auto; display:block; margin-bottom:var(--space-6)}

/* ═══ Schmale Bildschirme ══════════════════════════════════════════
   Ab hier klappt die Navigation zusammen. Die Kopfzeile bleibt einzeilig:
   Logo, Umschalter, Profil — die Abschnitte liegen darunter im Klappmenü. */
@media (max-width:860px){
  .masthead-inner{gap:var(--space-3); padding:0 var(--space-4)}
  /* Der Umschalter sitzt auf Ink, also gelten die Farben für dunklen Grund.
     Die Fließtextfarbe für helle Flächen erreichte hier 1.6:1 und war damit
     praktisch unsichtbar; Bright kommt auf 15.2:1. */
  .nav-burger{
    display:grid; place-items:center; margin-left:auto;
    width:var(--control-h-md); height:var(--control-h-md);
    border-radius:var(--radius-button); color:var(--color-fg-inverse);
  }
  .nav-burger:hover{background:rgba(239,247,240,0.10); color:var(--psh-turquoise)}
  .nav-burger .icon-close{display:none}
  .nav-toggle:checked ~ .nav-burger .icon-open{display:none}
  .nav-toggle:checked ~ .nav-burger .icon-close{display:block}

  /* Die Abschnitte liegen als Liste unter der Kopfzeile. */
  .nav{
    display:none; position:absolute; left:0; right:0; top:100%;
    flex-direction:column; align-items:stretch; gap:0; margin:0;
    padding:var(--space-2) var(--space-4) var(--space-4);
    background:var(--color-bg-inverse);
    box-shadow:var(--shadow-md);
  }
  .nav a{height:var(--control-h-lg); font-size:var(--text-body)}
  /* Die Liste liegt auf Ink; das Symbol erbt die Textfarbe des Eintrags,
     statt die Sekundärfarbe für helle Flächen zu verwenden. */
  .nav-icon{display:block; color:currentColor}
  .masthead{position:sticky}
  .masthead-inner{position:relative}

  .profile-name{display:none}
  .profile-caret{display:none}
  .profile-trigger{padding:0; width:var(--control-h-md); justify-content:center}

  /* Formularfelder stehen auf schmalen Bildschirmen über die volle Breite:
     Nebeneinander bliebe für keins genug Platz, und unterschiedlich breite
     Felder wirken wie ein Fehler. */
  .filter-bar{flex-direction:column; align-items:stretch}
  .filter-field, .filter-check, .filter-bar .btn{width:100%; flex:none}
  .filter-bar .btn{justify-content:center}
  .filter-row{flex-direction:column; align-items:stretch}
  .filter-row select, .filter-row input[type="text"]{width:100%; flex:none}
  .grid-2{grid-template-columns:1fr}

  main{padding:var(--space-5) var(--space-4) var(--space-8)}
  h1{font-size:var(--text-h3)}
  .page-head{gap:var(--space-3)}
  /* Schaltflächen am linken Rand, nicht mittig: Die Kopfzeile einer Ansicht
     liest sich von links, die Handlungen gehören in dieselbe Spalte. */
  .page-head{gap:var(--space-4)}
  .page-head .spacer{display:none}
  .page-head > div{width:100%}
  .page-head .btn-row{width:100%; margin-top:0}
  .public{margin:var(--space-5) auto}
  .public-card{padding:var(--space-5)}
}

@media (max-width:420px){
  .brand{padding:0 var(--space-4); gap:var(--space-3)}
  .brand-signet{height:30px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important; transition-duration:.01ms !important}
}

@media print{
  .masthead,.btn-row,.nav{display:none}
  .card,.table-wrap,.empty{box-shadow:none}
  body{background:var(--psh-white)}
}

/* ═══ Kategorienfarben ═════════════════════════════════════════════
   Die sechs Akzente des Systems, in fester Reihenfolge vergeben — nicht nach
   Geschmack. Fläche immer die Tönung, Schrift immer die Deep-Stufe. Sie
   unterscheiden Bereiche in Übersichten; zur Dekoration werden sie nicht
   verwendet. */
.cat-1{--cat:var(--accent-mint);   --cat-deep:var(--accent-mint-deep)}
.cat-2{--cat:var(--accent-sky);    --cat-deep:var(--accent-sky-deep)}
.cat-3{--cat:var(--accent-indigo); --cat-deep:var(--accent-indigo-deep)}
.cat-4{--cat:var(--accent-plum);   --cat-deep:var(--accent-plum-deep)}
.cat-5{--cat:var(--accent-coral);  --cat-deep:var(--accent-coral-deep)}
.cat-6{--cat:var(--accent-sand);   --cat-deep:var(--accent-sand-deep)}

/* Kategorie-Kachel: Tönung als Fläche, Deep-Stufe als Icon. Hover verdichtet
   die Tönung, das Icon behält seine Kategoriefarbe. */
.tool-card[class*="cat-"] .tool-icon{background:var(--cat); color:var(--cat-deep)}
.tool-card[class*="cat-"]:hover .tool-icon{background:var(--cat-deep); color:var(--psh-white)}

/* Eine abgeschickte Schaltfläche zeigt, dass etwas läuft. Der Schutz vor dem
   doppelten Versand liegt im Server; hier geht es nur um die Rückmeldung. */
.btn[data-busy]{opacity:.6; pointer-events:none}

/* Zeile in einer Aufzählung mit Aktion am Ende — etwa eine Verteilerliste
   mit ihrer Mitgliederzahl und einer Schaltfläche zum Entfernen. */
.list-row{
  display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-2) 0; border-bottom:1px solid var(--color-border);
}
.list-row:last-child{border-bottom:0}
.list-row .spacer{margin-left:auto}
.list-row .hint{margin-top:0}
.list-row form{margin:0}

/* Feld-Zuordnung: Beschriftung und Auswahl in einer Zeile, damit die Liste
   der Zielfelder auf einen Blick lesbar bleibt. */
.mapping{display:grid; gap:var(--space-3)}
.mapping-row{display:grid; grid-template-columns:200px 1fr; align-items:center;
             gap:var(--space-4); margin:0}
.mapping-row > .label{margin:0}
@media (max-width:640px){
  .mapping-row{grid-template-columns:1fr; gap:var(--space-1)}
}

/* Formularseiten mit wenigen Feldern. Begrenzt, weil ein Eingabefeld über die
   volle Breite eines großen Bildschirms unangenehm zu lesen ist — aber
   großzügiger als zuvor, sonst wirkt die Seite halbleer. Der Wert entspricht
   der Lesebreite, die das System für Fließtext nennt (rund 68 Zeichen). */
.form-narrow{max-width:56rem}
.form-narrow .card{width:100%}

/* Nummerierte Schritte in einer Anleitung. Die Ziffer steht als Marke davor,
   damit die Reihenfolge sichtbar ist, ohne sie zu lesen. */
.steps{list-style:none; margin:0; padding:0; counter-reset:schritt}
.steps > li{
  counter-increment:schritt; position:relative;
  padding-left:var(--space-7); padding-bottom:var(--space-5);
}
.steps > li:last-child{padding-bottom:0}
.steps > li::before{
  content:counter(schritt);
  position:absolute; left:0; top:0;
  width:26px; height:26px; border-radius:var(--radius-pill);
  background:var(--color-accent); color:var(--psh-ink);
  display:grid; place-items:center;
  font-size:var(--text-caption); font-weight:700;
}
.steps > li > strong{display:block; margin-bottom:var(--space-1)}
.steps > li > .hint{margin-bottom:var(--space-3)}
.steps form{margin-top:var(--space-3)}

/* Die Vorschau der Umfrage in der Ansicht davor. Ein eigener Rahmen ist
   nötig: Die Seite bringt ihre eigenen Stile mit, und ohne Abgrenzung liefen
   sie mit denen der Werkstatt zusammen. */
.survey-preview{
  width:100%; height:32rem;
  border:0; border-radius:var(--radius-input);
  background:var(--color-bg-surface);
}

/* Ablagefeld für Dateien. Die Beschriftung deckt die ganze Fläche ab, damit
   ein Klick überall darin den Dialog öffnet — nicht nur auf der kleinen
   Schaltfläche, die der Browser selbst zeichnet und deren Verhalten sich
   nicht sicher beeinflussen lässt. */
.dropzone{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--space-2);
  min-height:var(--control-h-lg); padding:var(--space-5) var(--space-4);
  border-radius:var(--radius-input);
  background:var(--color-bg-field);
  cursor:pointer; text-align:center;
  transition:background var(--duration-fast) var(--ease-out);
}
.dropzone:hover{background:var(--color-bg-field-hover)}
/* Beim Überfahren mit einer Datei und beim Ansteuern über die Tastatur. */
.dropzone.is-over,
.dropzone:focus-within{background:var(--color-bg-field-selected)}
.dropzone .icon{color:var(--color-fg-secondary); margin:0}
.dropzone-text{font-size:var(--text-body-s); font-weight:600}
.dropzone-names:empty{display:none}
/* Das Feld bleibt im Formular, nur unsichtbar: Ohne JavaScript funktioniert
   die Seite dadurch weiterhin. `display:none` ginge nicht — ein so verstecktes
   Feld lässt sich über die Beschriftung nicht mehr ansteuern. */
.dropzone-input{
  position:absolute; padding:0; margin:0;
  opacity:0; pointer-events:none;
}
