/* Farbrollen des Kundenbereichs und der Verwaltung. Sie folgen der
   öffentlichen Website (app/static/css/styles.css), damit Angebot,
   Kundenbereich und Website als eine Marke auftreten.

   KEINE FESTEN FARBWERTE UNTERHALB DIESES BLOCKS. Alles, was eine Fläche,
   eine Linie oder eine Schrift einfärbt, geht über eine Rolle – sonst
   leuchtet im dunklen Modus irgendwo ein weißes Feld, und gefunden wird das
   erst von dem, der abends davorsitzt.

   Drei Zustände wie auf der Website: Ohne data-theme entscheidet das
   Betriebssystem, mit data-theme gewinnt die Wahl des Menschen. Deshalb
   steht die helle Fassung auf blankem :root und wird zweimal überschrieben –
   einmal für „System sagt dunkel", einmal für „ich will dunkel". Eine Farbe,
   die es nur im Medienblock gäbe, fehlte dem Umschalter.

   Die dunklen Flächen kommen aus dem Blaugrau der Marke und nicht aus reinem
   Schwarz: In einer Verwaltung liest man stundenlang Tabellen, und auf
   reinem Schwarz steht der Kontrast dafür zu hart. */
:root{
  --ink:#1a1a1e;--muted:#5b5b66;--brand:#6559bd;--brand-dark:#5749a8;
  --knopf-bg:#6559bd;--knopf-ink:#fff;
  --accent:#e7e5fb;--bg:#f6f6f8;--paper:#fff;--line:#e0e0e8;
  --sunk:#f7f7fa;              /* eingelassene Fläche: Codeblock, Anhang */
  --field-line:#c9c9d4;        /* Rand von Eingabefeldern – kräftiger als --line */
  --chip:#eeeef3;--chip-ink:#4c4c58;
  --ok-bg:#def3e6;--ok-ink:#17613a;
  --info-bg:#e6eff9;--info-ink:#255a88;
  --warn:#fff5da;--warn-ink:#735916;--warn-line:#ead99e;
  --danger:#fff0ed;--danger-ink:#9b3628;--danger-line:#e2c3bb;
  --ok-line:#cfe6da;
  --signal-rot:#a3341f;--signal-bernstein:#b8860b;
  --schatten-weich:rgba(26,26,30,.05);
  --schatten-tief:rgba(26,26,30,.1);
  --shadow:0 18px 44px var(--schatten-tief);
  /* Der Pfeil der Auswahlfelder. Er steckt als SVG in einem Hintergrundbild,
     und in einer Adresse lässt sich keine Farbrolle einsetzen – deshalb ist
     das ganze Bild die Rolle und wird im dunklen Modus ausgetauscht. Vorher
     stand ein festes Grau darin und verschwand dort auf dunklem Grund. */
  --feld-pfeil:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235b5b66' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme:light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --ink:#eceaf4;--muted:#a2a0b4;--brand:#a99df0;--brand-dark:#bcb2f6;
  --knopf-bg:#5e50c0;--knopf-ink:#fff;
  --accent:#2e2a47;--bg:#131219;--paper:#1c1b24;--line:#302e3d;
  --sunk:#232230;--field-line:#3d3b4d;
  --chip:#2b2a37;--chip-ink:#c2c0d2;
  --ok-bg:#17352a;--ok-ink:#7fd8ac;
  --info-bg:#152a3d;--info-ink:#8ec2ef;
  --warn:#3a3218;--warn-ink:#e8cf8a;--warn-line:#544625;
  --danger:#3a201c;--danger-ink:#f0a294;--danger-line:#5c342d;
  --ok-line:#2a5442;
  --signal-rot:#e08a76;--signal-bernstein:#e0b355;
  --schatten-weich:rgba(0,0,0,.4);
  --schatten-tief:rgba(0,0,0,.55);
  --feld-pfeil:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%23a2a0b4' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme:dark;
  }
}
:root[data-theme="dark"] {
  --ink:#eceaf4;--muted:#a2a0b4;--brand:#a99df0;--brand-dark:#bcb2f6;
  --knopf-bg:#5e50c0;--knopf-ink:#fff;
  --accent:#2e2a47;--bg:#131219;--paper:#1c1b24;--line:#302e3d;
  --sunk:#232230;--field-line:#3d3b4d;
  --chip:#2b2a37;--chip-ink:#c2c0d2;
  --ok-bg:#17352a;--ok-ink:#7fd8ac;
  --info-bg:#152a3d;--info-ink:#8ec2ef;
  --warn:#3a3218;--warn-ink:#e8cf8a;--warn-line:#544625;
  --danger:#3a201c;--danger-ink:#f0a294;--danger-line:#5c342d;
  --ok-line:#2a5442;
  --signal-rot:#e08a76;--signal-bernstein:#e0b355;
  --schatten-weich:rgba(0,0,0,.4);
  --schatten-tief:rgba(0,0,0,.55);
  --feld-pfeil:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%23a2a0b4' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  color-scheme:dark;
}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}a{color:var(--brand);font-weight:700;text-decoration:none}h1,h2,h3{line-height:1.12;letter-spacing:-.035em;margin:0 0 14px}h1{font-size:clamp(34px,4vw,56px)}h2{font-size:clamp(23px,2vw,31px)}h3{margin-top:26px;font-size:19px}p{color:var(--muted);margin:0 0 16px}.portal-header{min-height:72px;padding:10px clamp(18px,4vw,58px);background:var(--paper);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:28px;position:sticky;top:0;z-index:10}.portal-header nav{display:flex;gap:22px;margin-left:auto}.portal-header.public>a:last-child{margin-left:auto}.portal-brand{display:flex;align-items:center;gap:10px;color:var(--ink)}.portal-brand img{object-fit:contain}.portal-brand span,.portal-brand small{display:block}.portal-brand small{font-weight:500;color:var(--muted)}.portal-main{width:min(1480px,calc(100% - 36px));margin:0 auto;padding:clamp(28px,4vw,58px) 0 80px}.public-main{width:min(1260px,calc(100% - 36px))}.portal-footer{padding:24px;text-align:center;border-top:1px solid var(--line);color:var(--muted);background:var(--paper)}.page-heading{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;margin-bottom:32px}.page-heading p{font-size:17px}.overline{display:inline-block;margin-bottom:10px;color:var(--brand);font-weight:850;text-transform:uppercase;letter-spacing:.12em;font-size:12px}.portal-button,.search-form button{display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:9px;background:var(--knopf-bg);color:var(--knopf-ink);min-height:44px;padding:0 18px;font:inherit;font-weight:800;cursor:pointer}.portal-button.secondary{background:var(--paper);color:var(--brand);border:1px solid var(--line)}.portal-button:disabled{opacity:.45;cursor:not-allowed}.link-button{border:0;background:none;color:var(--brand);font:inherit;font-weight:750;cursor:pointer;padding:8px}.button-row,.form-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:24px}.metrics article,.panel,.auth-card,.offer-document{background:var(--paper);border:1px solid var(--line);border-radius:15px;box-shadow:0 8px 28px var(--schatten-weich)}.metrics article{padding:22px}.metrics strong{display:block;font-size:26px;letter-spacing:-.04em}.metrics span{color:var(--muted)}.panel{padding:clamp(20px,2.2vw,32px)}.panel-heading{display:flex;justify-content:space-between;align-items:center;gap:20px}.table-wrap{overflow:auto}table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:14px 12px;border-bottom:1px solid var(--line);vertical-align:top}th{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}small,.field-note{display:block;color:var(--muted);font-size:12px}.status{display:inline-flex;align-items:center;white-space:nowrap;padding:4px 10px;border-radius:999px;background:var(--chip);color:var(--chip-ink);font-size:12px;font-weight:800}.status.active,.status.accepted{background:var(--ok-bg);color:var(--ok-ink)}.status.sent,.status.ready{background:var(--info-bg);color:var(--info-ink)}.status.rejected,.status.ended{background:var(--danger);color:var(--danger-ink)}.search-form{display:flex;max-width:620px;margin-bottom:18px}.search-form input{flex:1;border:1px solid var(--line);border-radius:9px 0 0 9px;padding:12px}.search-form button{border-radius:0 9px 9px 0}.portal-form{display:grid;gap:16px}.portal-form label{display:grid;gap:6px;font-weight:750}.portal-form input,.portal-form textarea,.search-form input{width:100%;font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:11px 12px}.portal-form input:focus,.portal-form textarea:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}.form-grid-wide{grid-template-columns:repeat(2,minmax(0,1fr))}.span-2{grid-column:1/-1}.internal-field,.internal-note{background:var(--warn);border:1px solid var(--warn-line);border-radius:10px;padding:16px}.inline-fields{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}fieldset{border:1px solid var(--line);border-radius:10px;padding:15px}legend{font-weight:800}.auth-card{width:min(520px,100%);margin:6vh auto;padding:clamp(26px,4vw,46px)}.auth-card-wide{width:min(780px,100%)}.two-factor-setup{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:28px;align-items:center;margin:26px 0}.qr-card{display:grid;place-items:center;background:var(--paper);border:1px solid var(--line);border-radius:14px;padding:10px}.qr-card img{display:block;width:100%;height:auto;max-width:260px}.setup-copy h2{font-size:22px}.totp-secret{display:block;margin:14px 0;padding:12px;border:1px solid var(--line);border-radius:8px;background:var(--sunk);color:var(--ink);font:700 15px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;letter-spacing:.08em;overflow-wrap:anywhere;user-select:all}.auth-cancel{display:inline-block;margin-top:18px}.portal-form input[name="totp"]{font-size:20px;letter-spacing:.18em;text-align:center;font-variant-numeric:tabular-nums}

/* ══ Auswahlfelder ═══════════════════════════════════════════════════════
 *
 * EINE Regel für jedes <select> in der Verwaltung und im Kundenbereich.
 *
 * Ungestaltet bringt ein Auswahlfeld die Ecken, die Schrift und den Pfeil des
 * Betriebssystems mit. Neben den Feldern und Knöpfen des Projekts steht dann
 * ein Fremdkörper: graue Kanten, fremde Schrift, ein paar Pixel zu niedrig.
 * Die Antwort darauf stand vorher zwei Dutzend Mal in dieser Datei – jedes
 * Mal dieselben vier Zeilen, und wer eine Seite dazubaute, vergaß sie. Ein
 * Auswahlfeld ohne passende Umgebungsklasse stand deshalb nackt da.
 *
 * Was hier steht, gilt überall. Die Sonderfälle weiter unten dürfen nur in
 * Grösse und Breite abweichen, nie in Rahmen, Rundung oder Farbe.
 *
 * Senkrecht keine Polsterung, dafür die Knopfhöhe: Ein Auswahlfeld zentriert
 * seinen Text von selbst, und nur so steht es in einer Knopfreihe auf
 * derselben Linie wie die Knöpfe daneben. Rechts bleibt Platz für den
 * eigenen Pfeil, der sonst unter der längsten Beschriftung läge. */
select{appearance:none;-webkit-appearance:none;max-width:100%;font:inherit;font-weight:400;line-height:1.4;color:var(--ink);background-color:var(--paper);border:1px solid var(--field-line);border-radius:8px;padding:0 38px 0 12px;min-height:44px;cursor:pointer;background-image:var(--feld-pfeil);background-repeat:no-repeat;background-position:right 14px center;background-size:12px 8px}
select:hover{border-color:var(--brand)}
select:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}
select:disabled{opacity:.55;cursor:not-allowed}
/* Die aufgeklappte Liste zeichnet das Betriebssystem. Ohne eigene Farbe
   steht darin je nach Browser schwarze Schrift auf schwarzem Grund. */
select option{background-color:var(--paper);color:var(--ink)}
/* Volle Breite nur, wo die Felder untereinander in einem Formular stehen –
   in einer Leiste soll das Feld so breit sein wie sein Inhalt. */
.portal-form select,.inline-form select,.brief-arbeitsflaeche select,.modelltabelle select,.anschrift-raster select,.entwurf-raster select{width:100%}
/* Enge Leisten. Dort sind auch die Knöpfe niedriger, und ein Feld in voller
   Höhe stünde als einziges heraus. Nur Grösse, sonst nichts. */
.sammelleiste select,.prospect-aktionen select,.punkt-aktionen select,.nachricht-stand select,.anfrage-aktionen select{min-height:38px;font-size:14px;padding:0 32px 0 10px;background-position:right 11px center}
.sammelleiste select{min-height:36px}
.anfrage-aktionen select{min-height:40px}
/* Anschrift und Entwurf stehen in einem Raster: Dort ist ein Feld 40 hoch,
   und das Auswahlfeld hält die Flucht. */
.anschrift-raster select,.entwurf-raster select{min-height:40px}

.detail-grid,.offer-layout{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(350px,.75fr);gap:22px;align-items:start}.facts{display:grid;grid-template-columns:minmax(130px,.35fr) 1fr;margin:18px 0;gap:0}.facts dt,.facts dd{padding:10px 0;border-bottom:1px solid var(--line);margin:0}.facts dt{color:var(--muted)}.record-card,.price-line{display:flex;justify-content:space-between;align-items:center;gap:18px;padding:14px 0;border-bottom:1px solid var(--line);color:var(--ink)}.record-card small,.price-line small{margin-top:2px}.record-card span:first-child,.price-line span:first-child{min-width:0}.action-stack{display:grid;gap:16px}.clean-list{list-style:none;padding:0}.clean-list li{position:relative;padding:8px 0 8px 28px;border-bottom:1px solid var(--line)}.clean-list li:before{content:"✓";position:absolute;left:0;color:var(--brand);font-weight:900}.flash-stack{display:grid;gap:8px;margin-bottom:18px}.flash{padding:13px 15px;border-radius:9px;background:var(--info-bg);color:var(--info-ink);overflow-wrap:anywhere}.flash.success{background:var(--ok-bg);color:var(--ok-ink)}.flash.error{background:var(--danger);color:var(--danger-ink)}.flash.warning{background:var(--warn);color:var(--warn-ink)}.offer-heading{padding:34px 0}.offer-heading p{font-size:18px}.offer-document{padding:clamp(26px,4vw,52px)}.offer-document section+section{border-top:1px solid var(--line);padding-top:30px;margin-top:30px}.lead-small{font-size:18px;color:var(--ink)}.offer-decision{position:sticky;top:94px}.variant-list{display:grid;gap:10px}.variant{display:flex!important;grid-template-columns:auto 1fr!important;gap:12px!important;padding:14px;border:1px solid var(--line);border-radius:10px;cursor:pointer}.variant input{width:auto}.variant span,.variant strong,.variant b{display:block}.variant b{font-size:14px;color:var(--brand)}.check{display:flex!important;grid-template-columns:auto 1fr!important;align-items:flex-start;gap:10px!important;font-weight:500!important}.check input{width:auto;margin-top:5px}.secure-note{font-size:13px;border-left:3px solid var(--accent);padding-left:12px}.reject-form{text-align:center;margin-top:10px}.success-box,.notice-box{padding:15px;border-radius:10px;background:var(--ok-bg);color:var(--ok-ink)}.success-box p,.notice-box p{color:inherit}.notice-box{background:var(--warn);color:var(--warn-ink)}.compact{gap:10px}@media(max-width:900px){.metrics{grid-template-columns:repeat(2,1fr)}.auth-card-wide{width:min(780px,100%)}.two-factor-setup{display:grid;grid-template-columns:minmax(220px,280px) 1fr;gap:28px;align-items:center;margin:26px 0}.qr-card{display:grid;place-items:center;background:var(--paper);border:1px solid var(--line);border-radius:14px;padding:10px}.qr-card img{display:block;width:100%;height:auto;max-width:260px}.setup-copy h2{font-size:22px}.totp-secret{display:block;margin:14px 0;padding:12px;border:1px solid var(--line);border-radius:8px;background:var(--sunk);color:var(--ink);font:700 15px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;letter-spacing:.08em;overflow-wrap:anywhere;user-select:all}.auth-cancel{display:inline-block;margin-top:18px}.portal-form input[name="totp"]{font-size:20px;letter-spacing:.18em;text-align:center;font-variant-numeric:tabular-nums}
.detail-grid,.offer-layout{grid-template-columns:1fr}.offer-decision{position:static}.form-grid-wide{grid-template-columns:1fr}.span-2{grid-column:auto}.inline-fields{grid-template-columns:1fr}.page-heading{align-items:flex-start;flex-direction:column}}@media(max-width:700px){.two-factor-setup{grid-template-columns:1fr}.qr-card{width:min(300px,100%);margin:0 auto}.setup-copy{text-align:center}}@media(max-width:540px){.metrics{grid-template-columns:1fr}.portal-header{padding:10px 14px}.portal-main,.public-main{width:min(100% - 24px,1480px)}.portal-brand small{display:none}.facts{grid-template-columns:1fr}.facts dd{padding-top:0}.record-card,.price-line{align-items:flex-start;flex-direction:column}}


/* Referenzverwaltung */
.status.draft{background:var(--warn);color:var(--warn-ink)}.status.published{background:var(--ok-bg);color:var(--ok-ink)}.status.archived{background:var(--chip);color:var(--muted)}
/* Auf einem <span> in der Zelle, nicht auf dem <td> selbst: display:flex auf
   einer Tabellenzelle wirft ihr display:table-cell weg und riss dadurch die
   Trennlinie unter der Zeile ab - genau an dieser Spalte. */
.table-actions{display:inline-flex;gap:12px;flex-wrap:wrap}.reference-table-project{display:flex;align-items:center;gap:12px;min-width:260px}.reference-table-project img{width:84px;height:56px;object-fit:cover;border-radius:8px;border:1px solid var(--line)}.reference-table-project span{min-width:0}.reference-table-project strong,.reference-table-project small{overflow-wrap:anywhere}
.form-section-title{margin:18px 0 0;padding-top:24px;border-top:1px solid var(--line);font-size:24px}.reference-form>.form-section-title:first-of-type{margin-top:0;padding-top:0;border-top:0}.reference-media-columns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.reference-admin-preview{display:block;width:100%;max-height:360px;object-fit:cover;border:1px solid var(--line);border-radius:10px;margin-bottom:12px}.reference-logo-preview{display:grid;place-items:center;min-height:180px;padding:20px;border:1px solid var(--line);border-radius:10px;background:var(--sunk);margin-bottom:12px}.reference-logo-preview img{max-width:100%;max-height:130px;object-fit:contain}.reference-admin-gallery{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:18px}.reference-gallery-remove{display:block!important;border:1px solid var(--line);border-radius:10px;padding:8px!important;background:var(--paper);font-weight:650!important}.reference-gallery-remove img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;border-radius:6px;margin-bottom:8px}.reference-gallery-remove span{display:flex;align-items:center;gap:7px}.reference-gallery-remove input{width:auto}.approval-check{padding:16px;border:1px solid var(--warn-line);border-radius:10px;background:var(--warn)}.approval-check strong{color:var(--warn-ink)}
@media(max-width:900px){.reference-media-columns{grid-template-columns:1fr}.reference-admin-gallery{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.reference-admin-gallery{grid-template-columns:1fr}.reference-table-project{min-width:220px}}

/* Mailcenter */
.dashboard-metrics{grid-template-columns:repeat(5,minmax(0,1fr))}.metric-link{display:block;padding:22px;background:var(--paper);border:1px solid var(--line);border-radius:15px;box-shadow:0 8px 28px var(--schatten-weich);color:var(--ink)}.metric-link strong{display:block;font-size:26px;letter-spacing:-.04em}.metric-link span{color:var(--muted);font-weight:400}.mailcenter-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-bottom:24px}.mailcenter-card{display:grid;gap:4px;min-height:155px;padding:22px;background:var(--paper);border:1px solid var(--line);border-radius:15px;box-shadow:0 8px 28px var(--schatten-weich);color:var(--ink);transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.mailcenter-card:hover{transform:translateY(-2px);border-color:var(--brand);box-shadow:var(--shadow)}.mailcenter-card-icon{display:grid;place-items:center;width:42px;height:42px;border-radius:12px;background:var(--accent);color:var(--brand);font-size:22px;font-weight:900;margin-bottom:12px}.mailcenter-card strong{font-size:19px}.mailcenter-card small{font-size:13px;line-height:1.45}.mail-panel{padding:0;overflow:hidden}.mail-panel .panel-heading{padding:24px 26px;border-bottom:1px solid var(--line)}.mail-list{display:grid}.mail-row{display:grid;grid-template-columns:10px minmax(170px,.8fr) minmax(280px,2fr) minmax(120px,.55fr);gap:16px;align-items:center;padding:16px 24px;border-bottom:1px solid var(--line);color:var(--ink);font-weight:400}.mail-row:last-child{border-bottom:0}.mail-row:hover{background:var(--sunk)}.mail-row.unread{background:var(--accent)}.mail-row.unread strong{font-weight:850}.mail-state{width:8px;height:8px;border-radius:50%;background:var(--field-line)}.mail-row.unread .mail-state{background:var(--brand)}.mail-sender,.mail-subject,.mail-date{min-width:0}.mail-sender strong,.mail-subject strong,.mail-sender small,.mail-subject small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mail-date{text-align:right;color:var(--muted);font-size:12px}.mail-date small{margin-top:4px}.empty-state{padding:42px 24px;text-align:center;color:var(--muted)}.mail-detail{padding:0;overflow:hidden}.mail-detail-head{display:grid;grid-template-columns:auto 1fr auto;gap:16px;align-items:center;padding:24px 28px;border-bottom:1px solid var(--line)}.mail-detail-head small{font-size:13px}.mail-avatar{display:grid;place-items:center;width:48px;height:48px;border-radius:50%;background:var(--accent);color:var(--brand);font-weight:900;font-size:20px}.mail-body-text{padding:32px 34px;white-space:pre-wrap;overflow-wrap:anywhere;font:15px/1.72 Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--ink)}.mail-attachments{padding:0 34px 34px}.mail-attachments h2{font-size:20px}.attachment-list{display:flex;gap:12px;flex-wrap:wrap}.attachment-list a{display:grid;gap:3px;min-width:220px;padding:13px 15px;border:1px solid var(--line);border-radius:10px;background:var(--sunk)}.mail-compose-layout{display:grid;grid-template-columns:minmax(0,2fr) minmax(260px,.75fr);gap:20px;align-items:start}.mail-compose-form textarea{min-height:330px;resize:vertical}.mail-footer-info{position:sticky;top:94px;text-align:center}.mail-footer-info img{display:block;margin:4px auto 18px;border-radius:18px}.mail-footer-info h2{font-size:22px}.mail-preview{margin-top:24px}.email-preview-frame{margin-top:18px;padding:24px;background:var(--paper);border:1px solid var(--line);border-radius:12px;overflow:auto}.mail-settings-form{grid-template-columns:repeat(2,minmax(0,1fr))}.mail-toggle{display:flex!important;grid-template-columns:auto 1fr!important;align-items:flex-start!important;gap:12px!important;padding:16px;border:1px solid var(--line);border-radius:10px;background:var(--sunk)}.mail-toggle input{width:20px!important;height:20px!important;padding:0!important;flex:0 0 20px!important;margin:2px 0 0!important}.mail-toggle span{display:grid;gap:3px}.mail-toggle small{font-weight:400;line-height:1.45}.mail-settings-form .form-section-title{grid-column:1/-1}.notice-box{margin-bottom:24px}.notice-box strong{display:block;margin-bottom:4px}.notice-box p{margin-bottom:6px}
@media(max-width:1100px){.dashboard-metrics{grid-template-columns:repeat(3,minmax(0,1fr))}.mailcenter-cards{grid-template-columns:repeat(2,minmax(0,1fr))}.mail-compose-layout{grid-template-columns:1fr}.mail-footer-info{position:static}.mail-row{grid-template-columns:8px minmax(145px,.75fr) minmax(220px,1.5fr) 120px}}
@media(max-width:760px){.dashboard-metrics{grid-template-columns:1fr 1fr}.mail-settings-form{grid-template-columns:1fr}.mail-settings-form .span-2,.mail-settings-form .form-section-title{grid-column:auto}.mail-row{grid-template-columns:8px 1fr auto;gap:10px;padding:14px 16px}.mail-subject{grid-column:2/-1}.mail-date{grid-row:1;grid-column:3}.mail-detail-head{grid-template-columns:auto 1fr}.mail-detail-head form{grid-column:1/-1}.mail-body-text{padding:24px 20px}.mail-attachments{padding:0 20px 24px}}
@media(max-width:520px){.dashboard-metrics,.mailcenter-cards{grid-template-columns:1fr}.mail-row{grid-template-columns:8px 1fr}.mail-date{grid-row:auto;grid-column:2;text-align:left}.mail-subject{grid-column:2}.mail-detail-head{padding:20px}.email-preview-frame{padding:14px}}

/* Mailcenter-Einstellungen: Kennwortfelder */
.mail-secret-box{display:grid;gap:.75rem;padding:1rem;border:1px solid var(--line);border-radius:1rem;background:var(--paper)}
.mail-secret-label{font-weight:800;font-size:1rem;color:var(--ink)}
.mail-secret-status{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-height:3.25rem;padding:.8rem 1rem;border:1px solid var(--field-line);border-radius:.8rem;background:var(--sunk)}
.mail-secret-status span{letter-spacing:.14em;font-size:1.1rem;color:var(--ink)}
.mail-secret-status strong{font-size:.85rem;color:var(--muted)}
.mail-secret-new{display:grid;gap:.45rem}

/* Übergabe der Zugangsdaten: Werte müssen fehlerfrei abschreibbar sein. */
.credential-value{font:600 15px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;letter-spacing:.03em;background:var(--accent);border:1px solid var(--line);border-radius:6px;padding:3px 8px;display:inline-block;overflow-wrap:anywhere;user-select:all}

/* Verlauf eines Änderungswunsches */
.message-thread{display:grid;gap:14px;margin-bottom:26px}
.message{padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:var(--paper)}
.message header{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.message header time{margin-left:auto;color:var(--muted);font-size:12px}
.message p{margin:0;color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere}
.message.from-customer{background:var(--accent);border-color:var(--line)}
.message.is-internal{background:var(--warn);border-color:var(--warn-line)}
.status.open{background:var(--info-bg);color:var(--info-ink)}
.status.in_progress{background:var(--warn);color:var(--warn-ink)}
.status.done{background:var(--ok-bg);color:var(--ok-ink)}
.status.declined{background:var(--danger);color:var(--danger-ink)}

/* Änderungswünsche direkt am Angebot */
.offer-change-panel{margin-top:22px}
.offer-change-panel details>summary{cursor:pointer;font-weight:800;padding:10px 0}
.change-entry{padding:16px;margin-bottom:16px;border:1px solid var(--line);border-radius:12px}
.change-entry>header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}

/* Vorschau und Abnahme */
.preview-panel{margin-top:22px}
.preview-entry{padding:16px;margin-bottom:14px;border:1px solid var(--line);border-radius:12px}
.preview-entry>header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:12px}
.preview-entry>header small{display:block;color:var(--muted);font-weight:400;margin-top:3px}
.status.ready{background:var(--info-bg);color:var(--info-ink)}
.status.sent{background:var(--accent);color:var(--info-ink)}
.status.accepted{background:var(--ok-bg);color:var(--ok-ink)}
.status.active{background:var(--ok-bg);color:var(--ok-ink)}
.status.ended{background:var(--ok-bg);color:var(--chip-ink)}

/* Erinnerungen, Zusatzversand und Löschen im Angebot */
.inline-form{display:grid;gap:12px;max-width:520px;margin-bottom:8px}
.inline-form label{display:grid;gap:6px;font-weight:750}
/* Bewusst über :not() statt über eine Aufzählung von Typen: Ein Feld ohne
   type-Attribut ist ein Textfeld, wird von input[type=text] aber nicht
   getroffen – genau daran sind die Felder für Betrag und Grund hängen
   geblieben und standen ungestaltet da. */
.inline-form input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]),.inline-form textarea{width:100%;font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:11px 12px}
/* Auswahlfelder: siehe die gemeinsame Regel für select weiter oben. */
.inline-form input:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}
.inline-form button{justify-self:start}
.inline-form label.checkbox{display:flex;align-items:center;gap:10px;font-weight:500}
.inline-form label.checkbox input{width:auto}
/* Grundregel für freistehende Häkchen außerhalb einer .button-row oder
   eines .inline-form: Ohne diese Zeile blieb label.checkbox ein normales
   Inline-Element - Kästchen und Text hingen ohne Abstand aneinander, und
   nach einer Knopfzeile klebte das Häkchen direkt an den Knöpfen. */
label.checkbox{display:flex;align-items:flex-start;gap:10px;cursor:pointer}
label.checkbox input{margin-top:3px;flex:none}
.button-row+label.checkbox{margin-top:16px}
label.checkbox+label.checkbox{margin-top:10px}
/* Löschen ist endgültig und sitzt deshalb sichtbar abgesetzt, nicht zwischen
   den übrigen Knöpfen. */
.danger-panel{border-color:var(--danger-line)}
.danger-panel h2{color:var(--danger-ink)}
.link-button.danger{color:var(--danger-ink);font-weight:800}

/* Anmeldung und Kundenübersicht */
.access-help{margin-top:26px;padding-top:20px;border-top:1px solid var(--line)}
.access-help summary{cursor:pointer;font-weight:750;color:var(--brand);padding:6px 0}
.access-help .portal-form{margin-top:14px}
.portal-metrics{grid-template-columns:repeat(4,minmax(0,1fr))}
.portal-metrics article{padding:18px}
.portal-metrics strong{font-size:23px}
.portal-metrics span{font-size:13px;line-height:1.35;display:block}
@media(max-width:900px){.portal-metrics{grid-template-columns:repeat(2,1fr)}}
@media(max-width:540px){.portal-metrics{grid-template-columns:1fr}}

/* Bilder an Änderungswünschen */
.bild-block-huelle{margin:4px 0 8px;padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--sunk)}
.bild-block-huelle summary{cursor:pointer;font-weight:750;color:var(--brand)}
.bild-block{display:grid;gap:10px;padding:14px 0;border-top:1px solid var(--line)}
.bild-block:first-of-type{border-top:0}
.bild-block label{display:grid;gap:6px;font-weight:650;font-size:14px}
.bild-block input[type=text]{width:100%;font:inherit;border:1px solid var(--field-line);border-radius:8px;padding:10px 12px;background:var(--paper);color:var(--ink)}
.bild-block input[type=file]{font:inherit;font-size:13px}
.bild-flaeche{display:grid;gap:8px}
.bild-flaeche canvas{width:100%;height:auto;max-height:60vh;object-fit:contain;border:1px solid var(--line);border-radius:10px;background:var(--paper);touch-action:none;cursor:crosshair}
.markier-werkzeuge{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.markier-farbe{width:26px;height:26px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px var(--line);cursor:pointer;padding:0}
.markier-farbe.aktiv{box-shadow:0 0 0 2px var(--brand)}
.markier-staerke{width:110px}
.bild-galerie{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px;margin:12px 0 4px}
.bild-eintrag{margin:0;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--paper)}
.bild-eintrag img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.bild-eintrag figcaption{padding:9px 11px;font-size:13px;line-height:1.45;color:var(--ink)}
.bild-eintrag figcaption small{display:block;margin-top:3px;color:var(--muted);font-size:11px}

/* Kontaktanfragen */
.anfrage{padding:18px 0;border-bottom:1px solid var(--line)}
.anfrage:last-child{border-bottom:0}
/* UMBRUCH UND `min-width:0`: Links steht ein Name mit Firma, rechts der
   Zustand. Bei 390 Pixeln passte beides nicht nebeneinander – und weil ein
   Flex-Element von sich aus nicht schmaler wird als sein längstes Wort,
   schob der Zustandsknopf die Seite nach rechts, statt umzubrechen. */
.anfrage>header{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:10px;flex-wrap:wrap}
.anfrage>header>div{min-width:0;flex:1 1 200px}
.anfrage>header small{display:block;color:var(--muted);font-weight:400;margin-top:3px}
.anfrage-text{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--ink)}
.anfrage.nicht-zugestellt{border-left:3px solid #9b3628;padding-left:14px;background:var(--danger)}
.filterleiste{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:20px}
.anfrage-aktionen{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px}
.anfrage-aktionen input[type=text]{font:inherit;border:1px solid var(--field-line);border-radius:8px;padding:9px 11px;background:var(--paper);color:var(--ink);flex:1;min-width:200px}
.anfrage-loeschen{margin-top:10px}
.anfrage-loeschen summary{cursor:pointer;color:var(--danger-ink)}
.status.new{background:var(--info-bg);color:var(--info-ink)}
.status.in_progress{background:var(--warn);color:var(--warn-ink)}
.status.done{background:var(--ok-bg);color:var(--ok-ink)}
.status.discarded{background:var(--chip);color:var(--muted)}

/* Einzelne Punkte eines Änderungswunsches */
.punkte{margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid var(--line)}
.punkte-kopf{display:flex;justify-content:space-between;align-items:baseline;gap:16px;flex-wrap:wrap}
.punkte-kopf h3{margin:0}
.punkte-fortschritt{color:var(--muted);font-size:13px;font-weight:700}
.punkte-balken{height:6px;border-radius:999px;background:var(--chip);overflow:hidden;margin:10px 0 14px}
.punkte-balken span{display:block;height:100%;background:var(--brand);border-radius:999px;transition:width .2s ease}
.punkte-liste{list-style:none;padding:0;margin:0;display:grid;gap:2px}
.punkt{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;padding:11px 12px;border-radius:9px;background:var(--sunk)}
.punkt.done{background:var(--ok-bg)}
.punkt.done .punkt-text{color:var(--muted)}

.punkt.declined{background:var(--danger)}
.punkt-text{min-width:0;overflow-wrap:anywhere}
.punkt-text small{display:block;margin-top:3px;color:var(--muted);font-size:12px}
.punkt-link{display:inline-block;margin-left:8px;font-size:13px}
.punkt-aktionen{display:flex;align-items:center;gap:4px;flex-shrink:0}
.punkt-aktionen form{display:inline}
.punkt-aktionen .link-button{padding:4px 6px;font-size:13px}
.punkte-anlegen{margin-bottom:22px}

/* Dateiauswahl: eigener Knopf statt des Systemelements */
.datei-wahl{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.datei-eingabe{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.datei-knopf{display:inline-flex!important;align-items:center;gap:8px;padding:10px 16px;border:1px solid var(--line);border-radius:9px;background:var(--paper);color:var(--brand);font-weight:750;font-size:14px;cursor:pointer;transition:border-color .15s ease,background .15s ease}
.datei-knopf:hover{border-color:var(--brand);background:var(--accent)}
.datei-eingabe:focus-visible+.datei-knopf{outline:3px solid rgba(101,89,189,.35);outline-offset:2px}
.datei-knopf span{font-size:17px;line-height:1}
.datei-name{color:var(--muted);font-size:13px;overflow-wrap:anywhere}

/* Fortschrittsbreiten als Klassen – die CSP erlaubt keine style-Attribute. */
.punkte-balken .fortschritt-0{width:0%}.punkte-balken .fortschritt-5{width:5%}.punkte-balken .fortschritt-10{width:10%}.punkte-balken .fortschritt-15{width:15%}.punkte-balken .fortschritt-20{width:20%}.punkte-balken .fortschritt-25{width:25%}.punkte-balken .fortschritt-30{width:30%}.punkte-balken .fortschritt-35{width:35%}.punkte-balken .fortschritt-40{width:40%}.punkte-balken .fortschritt-45{width:45%}.punkte-balken .fortschritt-50{width:50%}.punkte-balken .fortschritt-55{width:55%}.punkte-balken .fortschritt-60{width:60%}.punkte-balken .fortschritt-65{width:65%}.punkte-balken .fortschritt-70{width:70%}.punkte-balken .fortschritt-75{width:75%}.punkte-balken .fortschritt-80{width:80%}.punkte-balken .fortschritt-85{width:85%}.punkte-balken .fortschritt-90{width:90%}.punkte-balken .fortschritt-95{width:95%}.punkte-balken .fortschritt-100{width:100%}

/* Formular für mehrere Änderungen */
.aenderungen{display:grid;gap:14px;margin:6px 0 14px}
.aenderung{display:grid;gap:12px;padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--sunk)}
.aenderung-kopf{display:flex;justify-content:space-between;align-items:center;gap:12px}
.aenderung-nummer{font-weight:800;font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--brand)}
.aenderung label{display:grid;gap:6px;font-weight:650;font-size:14px}
.aenderung textarea,.aenderung input[type=url],.aenderung input[type=text]{width:100%;font:inherit;border:1px solid var(--field-line);border-radius:8px;padding:10px 12px;background:var(--paper);color:var(--ink)}
.aenderung textarea:focus,.aenderung input:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}
.aenderung-bilder{display:grid;gap:12px}
.aenderung-bilder .bild-block{padding:12px;border:1px solid var(--line);border-radius:10px;background:var(--paper)}
.aenderung [data-bild-hinzu],.aenderung [data-entfernen]{justify-self:start;padding:4px 0}
/* Bilder innerhalb eines Punktes bleiben klein – sie begleiten den Text,
   statt ihn zu erschlagen. Zum Ansehen genügt ein Klick. */
.punkt .bild-galerie{grid-template-columns:repeat(auto-fill,minmax(140px,168px));gap:10px;margin:10px 0 2px}
.punkt .bild-eintrag figcaption{padding:7px 9px;font-size:12px}
.punkte-leer{margin-bottom:22px;padding:16px 18px;border:1px dashed var(--line);border-radius:12px;background:var(--sunk)}
.punkte-leer h3{margin:0 0 6px;font-size:17px}
.punkte-leer p{margin:0;font-size:14px}
.punkt-text small .status{font-size:11px;padding:2px 7px}
.punkt-ueberschrift{display:block;font-weight:750;line-height:1.4}
.punkt-beschreibung{display:block;margin-top:2px;color:var(--muted);font-size:14px;line-height:1.5}
.punkt.done .punkt-ueberschrift{text-decoration:line-through}

/* Bearbeitungsstand je Kundennachricht */
.anfragen-stand{margin-bottom:16px;padding:12px 15px;border-radius:10px;background:var(--accent)}
.anfragen-stand strong{display:block;color:var(--brand-dark)}
.anfragen-stand small{display:block;margin-top:3px;color:var(--muted)}
.message.erledigt{opacity:.72}
.message.erledigt>p{text-decoration:line-through;text-decoration-color:rgba(26,26,30,.35)}
.nachricht-stand{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--line);flex-wrap:wrap}
.nachricht-stand small{color:var(--muted);font-size:12px}
.message header .status{margin-left:8px}

/* Sonderangebot mit befristetem Einführungspreis */
/* Sonderpreis in der Variantenauswahl. Die Spezifität muss über .variant
   span liegen, sonst zwingt der Grundstil jedes Kind auf display:block –
   die Marke lief dadurch über die volle Breite. */
.variant.aktion{border-color:var(--brand);background:var(--info-bg);box-shadow:0 2px 10px rgba(101,89,189,.09)}
.variant .variant-kopf{display:flex!important;align-items:center;gap:9px;flex-wrap:wrap}
.variant .variant-kopf strong{display:inline!important}
.variant em.aktion-marke{display:inline-flex!important;align-items:center;padding:3px 10px;border-radius:999px;background:var(--brand);color:#fff;font-size:10px;font-weight:850;letter-spacing:.09em;text-transform:uppercase;font-style:normal;line-height:1.4;white-space:nowrap}
.variant b.preis-zeile{display:flex!important;align-items:baseline;gap:7px;flex-wrap:wrap;margin-top:7px;font-size:15px}
.variant .preis-neu{display:inline!important;font-size:23px;font-weight:850;letter-spacing:-.02em;color:var(--brand-dark)}
.variant .preis-einheit{display:inline!important;color:var(--muted);font-weight:650;font-size:14px}
.variant s.preis-alt{display:inline!important;margin-left:2px;color:var(--muted);font-weight:600;font-size:15px;text-decoration-thickness:2px}
.variant .aktion-ersparnis{display:block;margin-top:5px;color:var(--ok-ink);font-size:13px;font-weight:750;line-height:1.45}
.variant .aktion-hinweis{display:block;margin-top:2px;color:var(--muted);font-size:13px;line-height:1.45;font-weight:500}
.aktion-frist{margin-bottom:16px;padding:12px 15px;border-radius:10px;background:var(--warn);color:var(--warn-ink)}
.aktion-frist strong{display:block}
.aktion-frist span{font-size:13px}
.sonderangebot legend{color:var(--brand)}
.sonder-art{display:grid;gap:10px;margin:14px 0}
.sonder-art .check{align-items:flex-start!important;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--paper)}
.sonder-art .check span{display:grid;gap:3px}
.sonder-art .check small{color:var(--muted);font-weight:400;line-height:1.45}
/* Der Auswahlknopf gehört auf die Höhe der Bezeichnung, nicht in die Mitte
   des gewachsenen Blocks. */
.variant{align-items:flex-start!important}
.variant>input[type=radio]{margin-top:3px;flex:0 0 auto}

/* Auswahl der Abrechnungsvariante.
   Der Grundstil legt einen eckigen Fokusrahmen um jedes Formularfeld. Um
   einen runden Auswahlknopf wirkt das wie ein Kasten. Hier deshalb kein
   Rahmen bei Mausklick; bei Tastaturbedienung bleibt ein runder Ring
   sichtbar, sonst wäre die Seite ohne Maus nicht mehr bedienbar. */
.variant input[type=radio]{accent-color:var(--brand);width:19px;height:19px;outline:none!important}
.variant input[type=radio]:focus{outline:none!important}
.variant input[type=radio]:focus-visible{outline:3px solid rgba(101,89,189,.4)!important;outline-offset:3px;border-radius:50%}
/* Die gewählte Karte hebt sich selbst hervor – das ersetzt den Rahmen um den
   kleinen Knopf durch eine Anzeige, die man auch aus zwei Metern sieht. */
.variant:has(input[type=radio]:checked){border-color:var(--brand);box-shadow:0 0 0 2px var(--brand) inset,0 6px 18px rgba(101,89,189,.14)}
.variant:hover{border-color:var(--brand)}

/* Suchfeld und Knopf als ein zusammenhängendes Bedienelement.
   Vorher setzte eine spätere Regel border-radius:8px rundum, während der
   Knopf links eckig blieb – daher der unsaubere Übergang. Die Auswahl hier
   ist spezifischer und gewinnt. */
.search-form{display:flex;align-items:stretch;max-width:620px;margin-bottom:18px}
.search-form input[type=search]{flex:1;min-height:46px;padding:0 15px;border:1px solid var(--field-line);border-right:0;border-radius:9px 0 0 9px;font:inherit;background:var(--paper);color:var(--ink)}
.search-form input[type=search]::placeholder{color:var(--muted)}
.search-form input[type=search]:focus{outline:3px solid rgba(101,89,189,.16);outline-offset:-1px;border-color:var(--brand);position:relative;z-index:1}
.search-form button{min-height:46px;padding:0 22px;border-radius:0 9px 9px 0}
.search-form button:hover{background:var(--brand-dark)}

/* Akquise: Interessenten-Liste */
.akquise-fortschritt{margin-top:16px;padding:14px 16px;border-radius:10px;background:var(--accent)}
.akquise-fortschritt strong{display:block;color:var(--brand-dark)}
.akquise-fortschritt small{color:var(--muted)}
/* Stehengeblieben ist kein Fortschritt, sondern eine Störung – und muss auch
   so aussehen. In Markenfarbe gehalten sah man vier Tage lang zu, wie nichts
   geschah. */
.akquise-fortschritt.steht{background:var(--warn)}
.akquise-fortschritt.steht strong{color:var(--warn-ink)}
.akquise-fortschritt.steht .punkte-balken span{background:var(--signal-bernstein)}
.steht-hinweis{margin:6px 0 12px;color:var(--warn-ink)}
.akquise-fortschritt form{margin:0}
.akquise-recht{margin-top:16px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--sunk)}
.prospect{padding:20px 22px;border:1px solid var(--line);border-radius:12px;margin-bottom:14px;background:var(--paper)}
.prospect.bedarf-hoch{border-left:4px solid var(--signal-rot)}
.prospect.bedarf-mittel{border-left:4px solid #b8860b}
.prospect.bedarf-niedrig{border-left:4px solid #17613a}
.prospect-kopf{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.prospect-kopf strong{display:block;font-size:17px;line-height:1.3}
.prospect-kopf small{display:block;margin-top:2px;color:var(--muted)}
.prospect-marken{display:flex;gap:7px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.badge{display:inline-flex;padding:4px 10px;border-radius:999px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap}
.badge.bedarf-hoch{background:var(--danger);color:var(--danger-ink)}
.badge.bedarf-mittel{background:var(--warn);color:var(--warn-ink)}
.badge.bedarf-niedrig{background:var(--ok-bg);color:var(--ok-ink)}
.badge.pruefend{background:var(--info-bg);color:var(--info-ink)}
/* Die Fakten als zweispaltiges Raster: Beschriftung schmal, Wert daneben.
   Vorher lief die Beschriftung über die halbe Breite und riss die Zeilen
   unnötig auseinander. */
.prospect-fakten{display:grid;grid-template-columns:minmax(140px,190px) 1fr;gap:2px 18px;margin:0 0 14px}
.prospect-fakten dt{padding:7px 0;color:var(--muted);font-size:14px;border-bottom:1px solid var(--line)}
.prospect-fakten dd{margin:0;padding:7px 0;font-size:14px;border-bottom:1px solid var(--line);overflow-wrap:anywhere}
.prospect-fakten dd small{display:block;margin-top:2px;font-size:12px}
.prospect-fakten>:nth-last-child(-n+2){border-bottom:0}
.prospect-probleme{margin:0 0 14px;padding-left:20px;color:var(--danger-ink)}
.prospect-probleme li{margin:3px 0;font-size:14px}
/* Aktionen in einer Zeile, gleiche Höhe. Vorher stand die Auswahlliste
   über dem Knopf und die Zeile brach unschön um. */
.prospect-aktionen{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:4px;padding-top:14px;border-top:1px solid var(--line)}
.prospect-aktionen .inline-form{display:flex;gap:8px;align-items:center;margin:0}
.prospect-aktionen form{margin:0}
.prospect-aktionen .portal-button{min-height:38px;padding:0 16px;font-size:14px}
.prospect-aktionen .link-button{padding:8px 4px;font-size:14px}
.brief-text{font:inherit;white-space:pre-wrap;background:var(--paper)}
.badge.einwilligung{background:var(--ok-bg);color:var(--ok-ink)}
.badge.keine-einwilligung{background:var(--warn);color:var(--warn-ink)}
/* Beschriftungen der Aktionen nicht innerhalb des Knopfes umbrechen lassen –
   ein zweizeiliger Knopf reißt die ganze Zeile auf. */
.prospect-aktionen .link-button,.prospect-aktionen .portal-button{white-space:nowrap}

/* --- Brief-Editor der Akquise --------------------------------------------- */
/* Zwei Spalten: links gearbeitet, rechts das Ergebnis. Unter 1100 px klappt
   die Vorschau unter den Editor – nebeneinander wäre beides zu schmal. */
.brief-arbeitsflaeche{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:start}
.brief-spalte{display:flex;flex-direction:column;gap:22px;min-width:0}
.brief-spalte .panel{margin:0}
.panel.haftend{position:sticky;top:96px}
/* Die Abschnitte unterhalb der Arbeitsfläche – Kunde anlegen, Drucken, Word,
   Design-Modus – sind keine Rasterfelder mehr, sondern Geschwister im
   Textfluss. Ohne eigenen Abstand klebten sie aneinander und an der
   Arbeitsfläche darüber, während oben im Raster 22 px Luft stehen. */
.brief-arbeitsflaeche{margin-bottom:22px}
.brief-arbeitsflaeche~.panel{margin-bottom:22px}
.brief-knoepfe{display:flex;gap:10px;flex-wrap:wrap;margin-top:6px}
@media (max-width:1100px){.brief-arbeitsflaeche{grid-template-columns:minmax(0,1fr)}.panel.haftend{position:static}}

/* Vorlagenauswahl */
.vorlagen-liste{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.vorlage-karte{display:block;position:relative;padding:14px 16px;border:1px solid var(--line);border-radius:11px;background:var(--paper);cursor:pointer}
.vorlage-karte:hover{border-color:var(--brand)}
.vorlage-karte.gewaehlt{border-color:var(--brand);background:var(--accent)}
.vorlage-karte input{position:absolute;opacity:0;pointer-events:none}
.vorlage-kopf{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.vorlage-kopf strong{font-size:15px}
.vorlage-karte .passt{font-style:normal;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;background:var(--ok-bg);color:var(--ok-ink);padding:3px 7px;border-radius:999px}
.vorlage-text{display:block;color:var(--muted);font-size:13px;line-height:1.5}

/* Anschrift und Entwurf: gleiches Raster, damit die Felder eine Flucht bilden */
.anschrift-raster,.entwurf-raster{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}
.anschrift-raster label,.entwurf-raster label{display:flex;flex-direction:column;gap:5px;font-weight:700;font-size:13px;margin:0}
.anschrift-raster label.breit,.entwurf-raster label.breit{grid-column:1/-1}
.anschrift-raster input,.entwurf-raster input,.entwurf-raster textarea{font:inherit;font-weight:400;border:1px solid var(--field-line);border-radius:8px;padding:9px 11px;background:var(--paper);color:var(--ink);min-height:40px;width:100%}
.anschrift-raster input:focus,.entwurf-raster input:focus,.entwurf-raster textarea:focus{outline:2px solid var(--brand);outline-offset:1px}
.field-note.warnung{background:var(--warn);border-radius:8px;padding:10px 12px}

/* DER BRIEFBOGEN STEHT NICHT MEHR HIER. Die Vorschau auf der Briefseite
   zeigt seit der Vereinheitlichung dasselbe Blatt wie der Ausdruck – dieselbe
   Vorlage (admin/_briefblatt.html), dasselbe Stylesheet (css/brief-druck.css),
   nur verkleinert (.blatt-vorschau dort).

   An dieser Stelle stand ein Nachbau in Pixeln: rund sechzig Regeln mit
   eigenen Klassennamen (.bogen-*), die dasselbe Blatt ein zweites Mal
   beschrieben. Jede Verbesserung am Brief musste zweimal gemacht werden, und
   weil das niemand durchhält, wurde sie einmal gemacht – zuletzt setzte der
   Druck den Gruß mit wachsendem Abstand nach unten, während die Vorschau ihn
   weiter am Text kleben ließ. Wer die Vorschau glaubte, bekam einen anderen
   Brief aus dem Drucker.

   HIER GEHÖRT NICHTS ÜBER DEN BRIEF HIN. Was das Blatt angeht, gehört nach
   brief-druck.css – sonst beginnt genau dieselbe Geschichte von vorn. */

/* --- Der Brief-Editor ----------------------------------------------------
   ALLES HIER IST BEDIENUNG, NICHTS IST BRIEF. Was das Blatt angeht, steht in
   brief-druck.css – auch die Rasten. Diese Trennung ist der Grund, warum es
   den Bogen nicht mehr zweimal gibt; sie hält nur, solange niemand hier eine
   Regel über den Brief unterbringt.

   Die Bedienelemente liegen NEBEN dem Blatt, nicht darauf: Ein Knopf, der auf
   dem Papier klebt, wandert bei jedem Regler mit und steht irgendwann über
   dem Text. Der einzige Eingriff im Blatt ist der Rahmen um den Absatz, in
   dem gerade geschrieben wird. */
/* UMBRICHT AM HANDY. Ohne flex-wrap schob die Leiste die ganze Seite
   ueber den Rand hinaus – man konnte quer scrollen, und der Brief stand
   links angeschnitten. Auf einem 390 Pixel breiten Bildschirm passen
   sieben Knoepfe nicht in eine Zeile, also stehen sie in zweien. */
.editor-leiste{display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;margin:0 0 12px;padding:8px 12px;background:var(--sunk);border:1px solid var(--line);border-radius:9px}
.editor-leiste .link-button{padding:4px 8px;font-weight:750}
.editor-leiste .link-button:disabled{opacity:.35;cursor:default}
/* Die Einfuegeknoepfe stehen leiser als Zurueck/Vor: Sie werden seltener
   gebraucht, und eine Leiste, in der alles gleich laut ist, hat keine
   Rangfolge mehr. */
.editor-einfuegen{display:flex;flex-wrap:wrap;gap:2px;margin-left:14px;padding-left:14px;border-left:1px solid var(--line)}
.editor-einfuegen .link-button{font-size:12px;font-weight:650;color:var(--muted);padding:4px 7px}
.editor-einfuegen .link-button:hover:not(:disabled){color:var(--brand)}
.editor-einfuegen .link-button:disabled{opacity:.35;cursor:default}
.editor-stand{margin-left:auto;font-size:12px;color:var(--muted);min-width:0}
.editor-stand.zu-lang{color:var(--danger-ink);font-weight:750}

/* Der Absatz, in dem geschrieben wird. Ein Rahmen INNERHALB des Blattes wäre
   ein Eingriff ins Papier – deshalb ein Umriss, der nichts verdrängt:
   outline nimmt keinen Platz, der Text bleibt millimetergenau dort, wo er
   auch gedruckt wird. */
/* An .bearbeitbar und nicht an .blatt-vorschau: Diese Klasse setzt der
   Editor, sie gehoert also der Bedienung. .blatt-vorschau gehoert dem Blatt
   und steht in brief-druck.css - ein Test wacht darueber, dass sich beide
   Stylesheets keinen Klassennamen teilen. */
.bearbeitbar{cursor:text}
.bearbeitbar [contenteditable]:focus{outline:2px solid var(--brand);outline-offset:2px;border-radius:2px}
.bearbeitbar [contenteditable]:hover{outline:1px dashed var(--field-line);outline-offset:2px}

/* Die Knöpfe eines Blockes. Sie stehen links neben dem Blatt in der Spalte,
   die der Falzmarken-Rand ohnehin frei lässt – so verdecken sie keine Zeile
   und wandern nicht in den Text, wenn ein Regler die Abstände ändert. */
/* WAAGERECHT UND NUR EINMAL. Senkrecht gestapelt brauchten drei Knoepfe
   sechzig Pixel Hoehe - ein Absatz im Massstab der Vorschau hat dreissig, und
   die Saetze ueberlappten einander zu einer unlesbaren Saeule. */
.block-knoepfe{position:absolute;display:flex;gap:3px;z-index:3;padding:2px;background:var(--paper);border-radius:7px;box-shadow:0 2px 8px var(--schatten-weich)}
.block-knoepfe button{width:22px;height:20px;padding:0;border:1px solid var(--line);border-radius:5px;background:var(--paper);color:var(--muted);font-size:11px;line-height:1;cursor:pointer}
.block-knoepfe button:hover:not(:disabled){border-color:var(--brand);color:var(--brand)}
.block-knoepfe button:disabled{opacity:.3;cursor:default}

/* Die Maße. Ein Zahlenfeld je Maß, daneben die Rasten als Schnellwahl und
   ein Knopf zurück auf die Vorgabe. Gegliedert in Gruppen, weil siebenundzwanzig
   Felder in einer Reihe niemand mehr überblickt. */
.mass-feld{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.mass-kopf{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:12px}
.mass-kopf h3{margin:0;font-size:15px}
.schablone-schalter{display:inline-flex!important;align-items:center;gap:8px;margin:0!important;font-size:12px;font-weight:650;color:var(--muted);cursor:pointer}
.schablone-schalter input{width:auto;margin:0}
.mass-gruppe{border:1px solid var(--line);border-radius:10px;padding:12px 14px;margin:0 0 12px}
.mass-gruppe legend{padding:0 6px;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}
.mass{display:grid;gap:4px;margin-bottom:12px}
.mass:last-child{margin-bottom:0}
.mass label{display:flex!important;align-items:center;justify-content:space-between;gap:12px;margin:0!important}
.mass-titel{font-weight:750;font-size:13px}
.mass-eingabe{display:inline-flex;align-items:center;gap:5px;flex:none}
.mass-eingabe input{width:76px!important;text-align:right;padding:6px 8px!important;font-variant-numeric:tabular-nums}
.mass-eingabe em{font-style:normal;font-size:12px;color:var(--muted);min-width:16px}
.mass-rasten{display:flex;flex-wrap:wrap;gap:5px}
.mass-rasten button{padding:3px 9px;border:1px solid var(--line);border-radius:999px;background:var(--paper);font:inherit;font-size:11px;font-weight:700;color:var(--muted);cursor:pointer}
.mass-rasten button:hover{border-color:var(--brand);color:var(--brand)}
.mass-rasten button.vorgabe{border-style:dashed}
/* Der Fuss des Massblatts: Speichern steht dort, wo die Masse enden -
   nicht oben beim Brieftext, wo ihn nach 26 Feldern niemand mehr sucht. */
.mass-fuss{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:4px 0 10px}
.mass-stand{font-size:12px;font-weight:700;color:var(--muted)}
.mass-stand.gut{color:var(--ok,#1a7f4b)}
.mass-stand.warnung{color:var(--warn,#a3560d)}

/* --- Briefvorlagen ------------------------------------------------------- */
.vorlagen-betrieb{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;margin:0}
.vorlagen-betrieb label{flex:1 1 260px;margin:0}
.vorlagen-tafel{display:grid;gap:12px}
.vorlagen-zeile{border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.vorlagen-kopf{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.vorlagen-kopf strong{font-size:15px}
.vorlagen-kopf em{font-style:normal;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;padding:2px 8px;border-radius:999px}
/* Aus den Farbvariablen, nicht aus festen Werten: Sonst leuchtet die Marke
   im Dunkelmodus als heller Fleck auf dunklem Grund. */
.marke-urfassung{background:var(--chip);color:var(--chip-ink)}
.marke-abschrift{background:var(--warn);color:var(--warn-ink)}
.marke-eigene{background:var(--ok-bg);color:var(--ok-ink)}
.vorlagen-text{margin:6px 0 10px;color:var(--muted);font-size:13px}
.vorlagen-knoepfe{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.knopfform{display:inline}

/* Der Editor: Bloecke links, Bausteine rechts. Unter 900 px untereinander -
   am Handy ist Nebeneinander zwei zu schmale Spalten. */
/* Haelfte/Haelfte, nicht drei zu zwei: Rechts steht jetzt ein ganzes
   Briefblatt und kein Fliesstext mehr. Bei zwei Fuenfteln schrumpft es
   so weit, dass man die Zeilen zwar sieht, aber nicht mehr liest - und
   dann ist es Zierde statt Vorschau. */
/* align-items:start IST HIER NICHT KOSMETIK, SONDERN BEDINGUNG.
   Ohne das streckt das Raster beide Spalten auf die volle Zeilenhoehe.
   Die rechte ist dann so hoch wie die linke - und ein haftendes
   Element, das seinen Behaelter ganz ausfuellt, kann nicht haften: Es
   scrollt mit weg. Das Blatt war beim Verstellen der Maße nicht mehr
   zu sehen, also genau dann nicht, wenn man es braucht. */
.vorlage-spalten{display:grid;gap:16px;align-items:start;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
@media (max-width:900px){.vorlage-spalten{grid-template-columns:1fr}}
.block-liste{display:grid;gap:10px;margin:10px 0}
.block{border:1px solid var(--line);border-radius:10px;padding:10px 12px;background:var(--paper)}
.block-kopf{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.block-kopf label{margin:0;font-size:12px}
.block-art{flex:0 1 150px}
.block-bedingung{flex:1 1 220px}
.block textarea{width:100%;font:inherit;font-size:13px;line-height:1.45}
.block-knoepfe{margin-bottom:14px}
.platzhalter-liste{display:grid;gap:8px}
.platzhalter-liste.schmal{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
.platzhalter{display:block;width:100%;text-align:left;border:1px solid var(--line);border-radius:8px;background:var(--paper);padding:8px 10px;font:inherit;cursor:pointer}
.platzhalter:hover{border-color:var(--brand)}
.platzhalter:disabled{opacity:.5;cursor:default}
.platzhalter strong{display:block;font-size:13px}
.platzhalter code{font-size:11px;color:var(--brand)}
.platzhalter small{display:block;margin-top:3px;color:var(--muted);font-size:11px;line-height:1.4}
/* DIE VORSCHAU BLEIBT STEHEN, waehrend man durch die Bloecke geht.

   Sie stand unter dem Formular und zeigte den GESPEICHERTEN Stand - beim
   Schreiben genau falsch herum: Man tippt einen Satz und sieht den alten.
   Jetzt steht sie rechts, zeigt den Stand im Formular und haftet beim
   Scrollen. */
/* DIE GANZE SPALTE HAFTET, NICHT NUR DIE VORSCHAU.

   Vorher war allein .vorschau-feld sticky. Ein haftendes Element bleibt am
   oberen Rand stehen, waehrend seine Geschwister darunter weiterscrollen -
   und weil die Vorschau einen Hintergrund hat, legt sie sich ueber sie.
   Maße und Platzhalter darunter waren damit nicht mehr anklickbar: Der
   Klick landete auf dem Briefblatt. Nachgemessen mit Playwright, das den
   Griff der Maß-Schublade dreissig Sekunden lang nicht treffen konnte.

   Jetzt haftet die Spalte als Ganzes und scrollt in sich. Vorschau oben,
   darunter alles Weitere - erreichbar, weil nichts mehr uebereinander
   liegt. */
.vorlage-links{display:grid;gap:16px;align-content:start;min-width:0}
.vorlage-rechts{display:grid;gap:16px;align-content:start;min-width:0}
@media (min-width:1100px){
  /* Nur das Blatt haftet - und in seiner Spalte steht nichts darunter, das
     es zudecken koennte. */
  .vorlage-rechts{position:sticky;top:70px}
  .vorschau-feld{max-height:calc(100vh - 90px);overflow-y:auto}
}
.vorschau-kopf{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.vorschau-kopf h2{margin:0 0 10px}
.vorschau-stand{font-size:12px;font-weight:700;color:var(--muted)}
.vorschau-stand.warnung{color:var(--danger-ink)}
.zurueck{margin:0 0 12px;font-size:13px}
/* Die Felder des Vorlagen-Editors sehen aus wie ueberall sonst im Portal:
   Beschriftung ueber dem Feld, Feld ueber die volle Breite. Ohne diese
   Regel blieben label und input inline - drei winzige Kaestchen in einer
   Zeile, in die kein Betreff passt. */
.vorlage-arbeitsflaeche label{display:grid;gap:6px;font-weight:750;margin:0 0 14px}
.vorlage-arbeitsflaeche input[type=text],.vorlage-arbeitsflaeche input:not([type]),
.vorlage-arbeitsflaeche textarea{width:100%;font:inherit;font-weight:400;
  background:var(--paper);color:var(--ink);border:1px solid var(--field-line);
  border-radius:8px;padding:11px 12px}
.vorlage-arbeitsflaeche .block-kopf label{margin:0}

/* --- Blatt und Werkzeug ---------------------------------------------------
   Zuerst ist nur der Brief da. „Maße bearbeiten" klappt die Felder DANEBEN
   auf, nicht darunter: Man verstellt ein Mass, weil man sieht, wie das Blatt
   darauf reagiert – und das geht nur, wenn beides zugleich sichtbar ist.

   Umgesetzt mit :has(). Kann der Browser das nicht, stehen die Felder
   untereinander statt nebeneinander – aufklappen und speichern gehen
   trotzdem. Ein Rueckfall, der nichts kaputt macht. */
/* BEIM BEARBEITEN GEHOERT DIE BREITE DEM BRIEF.

   Die Seite hat zwei Spalten: links Vorlage, Anschrift und Text, rechts die
   Vorschau. Klappt daneben noch das Massblatt auf, bleibt vom Bogen ein
   Streifen von zwei Zentimetern uebrig – man verstellt dann Zahlen und sieht
   nicht mehr, was sie tun.

   Solange bearbeitet wird, wandert die Formularspalte deshalb nach UNTEN und
   die Vorschau bekommt die ganze Seite. Sie ist nicht weg, nur nicht mehr
   daneben – und beim Zuklappen steht alles wieder wie vorher. */
.brief-arbeitsflaeche:has([data-werkzeug][open]){grid-template-columns:minmax(0,1fr)}
.brief-arbeitsflaeche:has([data-werkzeug][open]) > .formularseite{order:2}

/* GESTELLT WIRD ".blattfeld", NICHT ".blatt-vorschau".

   ``.blatt-vorschau`` gehoert dem Druckstylesheet – es verkleinert damit das
   Blatt. Auf der Briefseite gelten beide Stylesheets gleichzeitig; eine
   Klasse, die in beiden vorkommt, ist eine Falle: Wer dort etwas aendert,
   aendert unbemerkt auch das andere. Die Stellung im Raster ist Sache der
   Portalseite und bekommt deshalb einen eigenen Namen. */
.blatt-und-werkzeug{display:grid;gap:16px;grid-template-columns:minmax(0,1fr);align-items:start}
.blatt-und-werkzeug > details{grid-column:1}
.blatt-und-werkzeug > .blattfeld{grid-column:1}
@media (min-width:1100px){
  .blatt-und-werkzeug:has(details[open]){grid-template-columns:minmax(0,1fr) minmax(300px,380px)}
  .blatt-und-werkzeug:has(details[open]) > details{grid-column:2;grid-row:1;
    max-height:calc(100vh - 90px);overflow-y:auto;position:sticky;top:70px}
  .blatt-und-werkzeug:has(details[open]) > .blattfeld{grid-column:1;grid-row:1}
}
.werkzeug{border:1px solid var(--line);border-radius:10px;background:var(--paper)}
.werkzeug[open]{padding-bottom:8px}
.werkzeug-griff{cursor:pointer;list-style:none;padding:10px 14px;font-weight:800;font-size:13px;
  color:var(--brand);display:flex;align-items:center;gap:8px}
.werkzeug-griff::-webkit-details-marker{display:none}
.werkzeug-griff::before{content:"⚙";font-size:15px}
.werkzeug .mass-feld{padding:0 14px}
.werkzeug .mass-gruppe{padding:10px 12px}

/* Speichern bleibt beim Blaettern stehen - es ist der Knopf, den man sucht. */
.mass-fuss.haftend-oben{position:sticky;top:0;z-index:2;background:var(--paper);
  margin:0 -14px 10px;padding:4px 14px 10px;border-bottom:1px solid var(--line)}
.mass small{color:var(--muted);font-size:12px;line-height:1.45}

/* DIE SCHABLONE: das Sichtfenster des Umschlags als Umriss ueber dem Blatt.
   Nur in der Vorschau und nur auf Wunsch - auf dem Papier hat sie nichts zu
   suchen, deshalb steht sie hier und nicht in brief-druck.css.

   Die Masse sind DIN 5008 Form B: Anschriftfeld 45 bis 90 mm ab Oberkante,
   85 mm breit, ab dem linken Rand. Sie stehen als feste Millimeter im Blatt,
   das der Massstab verkleinert - die Schablone wandert damit von selbst mit. */
.schablone{position:absolute;top:45mm;left:25mm;width:85mm;height:45mm;border:.4mm dashed #a3341f;background:rgba(163,52,31,.06);pointer-events:none;z-index:2}
.schablone span{position:absolute;top:100%;left:0;margin-top:1mm;font:700 3mm/1.2 Inter,sans-serif;color:#a3341f;white-space:nowrap}
/* Verborgen ist sie schon durch brief-druck.css - hier wird sie nur
   eingeblendet. ``.mit-schablone`` setzt allein der Editor, die Regel gilt
   damit nur in der Vorschau.

   OHNE ``.blatt-vorschau`` DAVOR: Diese Klasse gehoert dem Blatt und steht in
   brief-druck.css. Sie hier zu nennen hiesse, dass sich beide Stylesheets
   einen Namen teilen - und genau davor warnt der Test, der schon einmal die
   Falzmarken gerettet hat. */
.mit-schablone .schablone{display:block}

/* Ergebnis des Design-Modus */
.entwurf-fertig{margin-top:18px;padding:16px;border:1px solid var(--line);border-radius:10px;background:var(--accent)}
.entwurf-fertig p{margin:0 0 8px;color:var(--ink)}
.entwurf-fertig a{word-break:break-all}
.entwurf-fertig form{margin:6px 0 0}


/* Felder im Brief-Editor. Bisher fehlten sie: Die Beschriftungen hängen an
   .portal-form, das Editor-Formular heißt aber anders – dadurch standen Label
   und Feld nebeneinander statt untereinander. */
.brief-arbeitsflaeche label{display:grid;gap:6px;font-weight:750;margin:0 0 14px}
.brief-arbeitsflaeche input[type=text],.brief-arbeitsflaeche input:not([type]),.brief-arbeitsflaeche textarea{width:100%;font:inherit;font-weight:400;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:11px 12px}
.brief-arbeitsflaeche textarea{min-height:380px;resize:vertical;line-height:1.6}
.brief-arbeitsflaeche input:focus,.brief-arbeitsflaeche textarea:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}
.brief-arbeitsflaeche .anschrift-raster label{margin:0}

/* Die Markierung der gewählten Vorlage folgt jetzt dem Klick, nicht erst dem
   Neuladen. Ohne das wirkt die Auswahl kaputt. */
.vorlage-karte:has(input:checked){border-color:var(--brand);background:var(--accent);box-shadow:0 0 0 1px var(--brand)}
.vorlage-karte:focus-within{outline:3px solid rgba(101,89,189,.2)}

/* Das Feld für die Entwurfs-Adresse steht unter dem Anschriften-Raster und
   soll die volle Breite nehmen, nicht in eine Rasterspalte rutschen. */
.brief-arbeitsflaeche label.entwurf-feld{margin-top:14px}
.brief-arbeitsflaeche label.entwurf-feld small{font-weight:400;color:var(--muted);font-size:13px;line-height:1.5}


/* Stellvertreterdomain: eine Adresse, die nur auf einen anderen Auftritt
   zeigt. Muss auffallen – sonst schickt man einen Website-Entwurf an einen
   Betrieb, dessen echte Seite tadellos ist. */
.badge.stellvertreter{background:var(--warn);color:var(--warn-ink)}

/* Zwei Filterleisten übereinander: Handlungsbedarf und Vertriebsstand.
   Die Beschriftung davor verhindert, dass man zwei Knopfreihen für eine
   einzige Auswahl hält. */
.filterleiste{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}
.filter-titel{font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);margin-right:4px;min-width:112px}
.filterleiste .portal-button{min-height:36px;padding:0 13px;font-size:14px}
.filterleiste .portal-button em{font-style:normal;font-weight:800;opacity:.65;margin-left:6px}
.brief-stand{align-self:center;font-size:13px;color:var(--muted)}
@media (max-width:700px){.filter-titel{min-width:100%;margin-bottom:2px}}

/* --- Filtertafel der Akquise ---------------------------------------------
   Vier Reihen aus Knöpfen in voller Größe waren nicht zu überblicken: gleiche
   Farbe, gleiches Gewicht, keine Gruppierung. Hier trägt jede Zeile eine
   Beschriftung in fester Spaltenbreite, damit die Marken darunter untereinander
   stehen – das Auge findet die Zeile, nicht den Knopf. */
.filtertafel{padding:18px 22px;margin-bottom:16px}
.filtertafel-kopf{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;flex-wrap:wrap;padding-bottom:14px;margin-bottom:12px;border-bottom:1px solid var(--line)}
.filtertafel-kopf .overline{margin-bottom:4px}
.filtertafel-kopf strong{display:block;font-size:17px;letter-spacing:-.02em}
.filtertafel-kopf small{margin-top:3px}
.filtertafel-werkzeuge{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.filtertafel-werkzeuge form{margin:0}
.filtertafel-werkzeuge .link-button{padding:6px 2px;font-size:14px}

/* 152px, weil „HANDLUNGSBEDARF" in Großbuchstaben mit Sperrung so breit ist –
   ein einzelnes Wort bricht nicht um, es würde abgeschnitten. */
.filterzeile{display:grid;grid-template-columns:152px 1fr;align-items:baseline;gap:12px;padding:7px 0}
.filterzeile+.filterzeile{border-top:1px solid var(--line)}
.filterzeile .filter-titel{min-width:0;margin:0;overflow-wrap:anywhere}
.filter-marken{display:flex;flex-wrap:wrap;gap:6px}

/* Marke statt Knopf: Ein Filter ist eine Auswahl, keine Handlung. Die
   Unterscheidung ist wichtig, weil daneben echte Knöpfe stehen, die etwas
   verändern („Briefe drucken", „Entfernen"). */
.marke{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border:1px solid var(--line);border-radius:999px;background:var(--paper);color:var(--ink);font-size:14px;font-weight:650;white-space:nowrap;line-height:1.4}
a.marke:not(.aktiv):hover{border-color:var(--brand);background:var(--info-bg)}
/* Die aktive Marke braucht ein eigenes Hover. Ohne das ":not" gewann die
   allgemeine Hover-Regel den Hintergrund (sie ist um ein Element spezifischer),
   während die weiße Schrift aus ".aktiv" stehen blieb: weiß auf fast weiß,
   sobald der Zeiger darauf lag. */
a.marke.aktiv:hover{background:var(--brand-dark);border-color:var(--brand-dark);color:#fff}
.marke em{font-style:normal;font-weight:800;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.marke.aktiv{background:var(--brand);border-color:var(--brand);color:#fff}
.marke.aktiv em{color:#fff;opacity:.75}
.marke.leer{opacity:.42;cursor:default}

@media (max-width:700px){.filterzeile{grid-template-columns:1fr;gap:4px}}

/* --- Entwurfsanfragen ------------------------------------------------------ */
.anfrage-karte{border:1px solid var(--line);border-radius:12px;padding:18px;margin-bottom:16px;background:var(--paper)}
.anfrage-karte:last-child{margin-bottom:0}
.anfrage-nachricht{white-space:pre-wrap}
.anfrage-bilder{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 4px}
.anfrage-bilder figure{margin:0;width:120px}
.anfrage-bilder img{width:120px;height:90px;object-fit:cover;border:1px solid var(--line);border-radius:8px;background:var(--paper)}
.anfrage-bilder figcaption{font-size:12px;color:var(--muted);margin-top:3px}
/* Das Logo wird eingepasst statt beschnitten – bei einer Wortmarke schneidet
   ein Zuschnitt sonst die Hälfte des Namens ab. */
.anfrage-logo img{object-fit:contain;padding:6px}
.anfrage-aktionen{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.anfrage-aktionen label{display:grid;gap:5px;font-weight:750;font-size:13px;margin:0}
.anfrage-aktionen input{font:inherit;font-weight:400;border:1px solid var(--field-line);border-radius:8px;padding:9px 11px;background:var(--paper);color:var(--ink);min-height:40px}
.anfrage-aktionen input{min-width:280px}

/* --- Besucherwege ------------------------------------------------------- */
.kennzahlen{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-bottom:24px}
.kennzahlen article{background:var(--paper);border:1px solid var(--line);border-radius:15px;box-shadow:0 8px 28px var(--schatten-weich);padding:20px}
.kennzahlen strong{display:block;font-size:26px;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.kennzahlen span{color:var(--muted)}
.panel-hinweis{font-size:13px}
.analyse-paar{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:18px}
.analyse-paar .panel{margin:0}
.panel+.panel,.analyse-paar+.panel,.auftraege-block+.panel{margin-top:18px}
td.zahl{text-align:right;font-weight:800;font-variant-numeric:tabular-nums;width:1%;white-space:nowrap}

/* Ein Weg wird als Kette gelesen, nicht als Tabelle: Die Reihenfolge ist die
   eigentliche Aussage. */
.weg-kette{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.weg-schritt{display:inline-block;padding:4px 10px;border-radius:999px;background:var(--chip);border:1px solid var(--line);font:700 13px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere}
.weg-pfeil{color:var(--muted);font-weight:800}
.weg-ende{color:var(--muted);font-size:12px;font-weight:700;padding-left:4px}
.weg-liste{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.weg-liste li{display:grid;grid-template-columns:60px 1fr;gap:12px;align-items:start;padding-bottom:12px;border-bottom:1px solid var(--line)}
.weg-liste li:last-child{border-bottom:0;padding-bottom:0}
.weg-anzahl{font-weight:850;font-variant-numeric:tabular-nums}
.besuch-liste{list-style:none;margin:0;padding:0;display:grid;gap:16px}
.besuch-liste li{padding-bottom:14px;border-bottom:1px solid var(--line)}
.besuch-liste li:last-child{border-bottom:0;padding-bottom:0}
.besuch-kopf{display:flex;flex-wrap:wrap;gap:10px;align-items:baseline;margin-bottom:8px}
.besuch-kopf span{color:var(--muted);font-size:13px}

@media (max-width:1100px){
  .kennzahlen{grid-template-columns:repeat(2,1fr)}
  .analyse-paar{grid-template-columns:1fr}
}

/* --- Zugang zum Entwurf -------------------------------------------------- */
.zugang-feld{margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.zugang-feld h3{margin:0 0 6px}
.zugang-feld label{display:grid;gap:6px;margin-bottom:14px;font-weight:750}
.zugang-feld input[type=text],.zugang-feld input:not([type]){width:100%;font:inherit;font-weight:400;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:11px 12px}
.zugang-feld small{font-weight:400}
.feld-paar{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.zugang-stand{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin:0 0 14px;font-size:14px}
.zugang-stand code{padding:4px 9px;border-radius:6px;background:var(--chip);border:1px solid var(--line);font:700 14px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;user-select:all}
.zugang-loeschen{display:inline-flex!important;align-items:center;gap:7px;margin:0!important;font-weight:600;color:var(--muted)}
.zugang-loeschen input{width:auto}
/* Der Haken vor „Passwort erzeugen". Er steht bewusst UEBER dem Knopf und
   nicht daneben: Wer den Knopf sucht, liest ihn dann zwangslaeufig. */
.zugang-neu{display:flex!important;align-items:flex-start;gap:9px;margin:0 0 10px!important;font-weight:650}
.zugang-neu input{width:auto;margin-top:3px;flex:none}
.field-note.warnung{color:var(--warn-ink);font-weight:700}


@media (max-width:700px){ .feld-paar{grid-template-columns:1fr} }

/* --- Speichern-Knopf der Modell-Tabelle ----------------------------------
   Die Tabelle hat elf Zeilen; der Knopf stand bisher erst danach - wer eine
   Zeile ändert, musste sich erst durch die ganze Tabelle zurück nach unten
   scrollen. Der Knopf steht jetzt vor der Tabelle und hängt beim Scrollen
   oben fest, genau wie die Sammelleiste bei den Entwürfen. */
.modelltabelle-leiste{position:sticky;top:82px;z-index:4;margin-bottom:14px;padding:12px 16px;background:var(--paper);border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 28px var(--schatten-weich)}

/* --- Mehrfachauswahl in der Akquise -------------------------------------- */
.sammelleiste{position:sticky;top:82px;z-index:5;display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:14px;padding:12px 16px;background:var(--paper);border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 28px var(--schatten-weich)}
.sammelleiste.aktiv{border-color:var(--brand);box-shadow:0 8px 28px rgba(101,89,189,.16)}
.alle-waehlen{display:inline-flex;align-items:center;gap:8px;font-weight:750;white-space:nowrap}
.alle-waehlen input,.prospect-waehlen input{width:18px;height:18px;accent-color:var(--brand);cursor:pointer}
.sammel-anzahl{color:var(--muted);font-size:14px;white-space:nowrap}
.sammel-trenner{flex:1}
/* Beschriftung und Feld auf einer Linie, und beides schrumpft nicht: In einer
   Leiste voller Knöpfe wurde das Auswahlfeld sonst zusammengedrückt, bis von
   „10 gleichzeitig" nur noch „10 gl…" übrig war. */
.sammel-stand{display:inline-flex;align-items:center;gap:8px;font-weight:750;white-space:nowrap;flex:0 0 auto}
/* Enger gesetzt, damit die Leiste auf einem normalen Bildschirm eine Zeile
   bleibt: „Entfernen…" allein in einer zweiten Zeile sah aus wie ein zweites,
   eigenständiges Werkzeug. */
.sammelleiste{gap:9px}
.sammelleiste .portal-button{min-height:36px;padding:0 12px;font-size:14px}
.portal-button.danger{background:var(--paper);color:var(--danger-ink);border:1px solid var(--danger-line)}
.portal-button.danger:hover{background:var(--danger)}
/* Die Leiste ohne Auswahl bedienbar zu lassen, führt nur zu „Nichts
   ausgewählt" – die Knöpfe bleiben deshalb sichtbar, aber gedämpft. */
.sammelleiste:not(.aktiv) .portal-button{opacity:.55}

.prospect{position:relative}
.prospect-waehlen{position:absolute;top:16px;left:-30px;display:flex;align-items:center}

/* --- Eingeklappte Karten -------------------------------------------------
   Bei zweihundert Einträgen wird Scrollen zum Suchen. Sichtbar bleibt, wonach
   man sucht: Name, Domain und die Marken. Die Knöpfe stehen außerhalb des
   Aufklappbereichs – „Brief öffnen" darf keinen zusätzlichen Klick kosten. */
.prospect-inhalt>summary{list-style:none;cursor:pointer;border-radius:10px;padding:4px 30px 4px 6px;margin:-4px -6px}
.prospect-inhalt>summary::-webkit-details-marker{display:none}
.prospect-inhalt>summary:hover{background:var(--sunk)}
.prospect-inhalt>summary:focus-visible{outline:3px solid rgba(101,89,189,.25)}
/* Ein Dreieck, das die Richtung anzeigt – sonst sieht man der Karte nicht an,
   dass sich etwas dahinter verbirgt. */
.prospect-inhalt>summary::after{content:"";position:absolute;right:8px;top:22px;width:8px;height:8px;border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);transform:rotate(45deg);transition:transform .15s ease}
.prospect-inhalt[open]>summary::after{transform:rotate(-135deg)}
.prospect-inhalt>summary>div:first-child{min-width:0}

.versteckt{display:none}
.fertig-hinweis{margin:8px 0 0;color:var(--brand-dark)}
.akquise-fortschritt .fertig-hinweis a{margin-left:6px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

.loesch-liste{list-style:none;margin:0 0 24px;padding:0;display:grid;gap:12px}
.loesch-liste li{padding-bottom:12px;border-bottom:1px solid var(--line)}
.loesch-liste li:last-child{border-bottom:0;padding-bottom:0}

@media (max-width:900px){
  .prospect-waehlen{position:static;margin-bottom:10px}
  .sammel-trenner{display:none}
}

/* --- Herkunft der Anschrift ---------------------------------------------- */
.anschrift-herkunft{margin:0 0 18px;padding:14px 16px;border:1px solid var(--line);border-left-width:4px;border-radius:10px;background:var(--sunk)}
.anschrift-herkunft.stufe-sicher{border-left-color:var(--ok-ink);background:var(--ok-bg)}
.anschrift-herkunft.stufe-pruefen{border-left-color:var(--signal-bernstein);background:var(--warn)}
.anschrift-herkunft.stufe-unsicher{border-left-color:var(--danger-ink);background:var(--danger)}
.herkunft-kopf{margin:0;color:var(--ink);font-size:14px}
.ampel{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:5px;vertical-align:baseline}
.ampel.gut{background:#17613a}.ampel.mittel{background:var(--signal-bernstein)}.ampel.schlecht{background:var(--signal-rot)}
.herkunft-bestaetigen{margin-top:12px;min-height:38px;padding:0 14px;font-size:14px}
/* Nach der Bestätigung bleibt eine ruhige Zeile statt des roten Kastens:
   Dass geprüft wurde, wann, und ein Weg zurück. Spurlos verschwinden wäre
   bequemer und schlechter – man sähe nicht mehr, worauf die Ruhe beruht. */
/* Ein Widerspruch, den das System selbst bemerkt hat: Entwurf steht,
   Brief sagt nichts davon. Muss auffallen, sonst muss man ihn selbst
   finden – und genau das ist beim Stapeldruck schiefgegangen. */
.panel.widerspruch{border-left:4px solid #b8860b;background:var(--warn)}
.panel.widerspruch h2{font-size:20px;color:var(--warn-ink)}
.panel.widerspruch p{color:var(--warn-ink)}
.anschrift-bestaetigt{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 18px;padding:10px 14px;border:1px solid var(--ok-line);border-left:4px solid var(--ok-ink);border-radius:10px;background:var(--ok-bg);color:var(--ok-ink);font-size:14px;font-weight:650}
.anschrift-bestaetigt .link-button{margin-left:auto;padding:0;font-size:13px;font-weight:650}
.herkunft-warnungen{margin:9px 0 0;padding-left:20px;color:var(--muted);font-size:13px;display:grid;gap:5px}
.herkunft-quelle{display:inline-block;margin-top:10px;font-size:13px;overflow-wrap:anywhere}
.entwurf-vorschlag{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:-6px 0 18px;font-size:14px}
.entwurf-vorschlag code{padding:4px 9px;border-radius:6px;background:var(--chip);border:1px solid var(--line);font:700 13px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.entwurf-vorschlag small{flex-basis:100%;margin:0}
.herkunft-alternativen{margin:9px 0 0;font-size:13px;color:var(--muted)}
.herkunft-alternativen code{padding:3px 7px;border-radius:5px;background:var(--paper);border:1px solid var(--line);font:600 12px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
/* Vertriebsstand eines Interessenten. Die Farben folgen dem Weg: grau am
   Anfang, gelb solange Arbeit läuft, blau sobald der Brief raus ist, grün beim
   Auftrag. „In Bearbeitung" muss sich von „Angeschrieben" deutlich
   unterscheiden – die Verwechslung kostet einen doppelten Brief. */
.status.neu{background:var(--chip);color:var(--chip-ink)}
/* Vorgemerkt: ruhiger als „In Bearbeitung“ – es liegt ja noch nichts an,
   der Betrieb ist nur schon einmal angesehen worden. */
.status.vorgemerkt{background:var(--info-bg);color:var(--info-ink)}
.status.in_arbeit{background:var(--warn);color:var(--warn-ink)}
.status.kontaktiert{background:var(--info-bg);color:var(--info-ink)}
.status.termin{background:var(--accent);color:var(--info-ink)}
.status.kunde{background:var(--ok-bg);color:var(--ok-ink)}
.status.kein_interesse{background:var(--danger);color:var(--danger-ink)}
.badge.entwurf-steht{background:var(--ok-bg);color:var(--ok-ink)}
.badge.entwurf-fehler{background:var(--danger);color:var(--danger-ink)}
/* Schlaf ist keine Störung, also auch keine Warnfarbe. Grau wie alles, was
   nur ruht – daneben steht ohnehin die grüne Marke „Entwurf steht". */
.badge.entwurf-schlaeft{background:var(--chip);color:var(--chip-ink)}
/* Am Entwurf wird gerade gearbeitet. Gelb wie „In Bearbeitung" – dieselbe
   Aussage, derselbe Farbton. Was nur eingereiht ist oder ruht, bleibt grau:
   Sonst sähe eine Warteschlange aus wie ein Werkstattbetrieb. */
.badge.entwurf-arbeit{background:var(--chip);color:var(--chip-ink)}
.badge.entwurf-arbeit.laeuft{background:var(--warn);color:var(--warn-ink)}
.badge.entwurf-arbeit.haengt{background:var(--danger);color:var(--danger-ink)}
.filter-anhang{display:inline-flex;margin-left:auto}

/* --- Route --------------------------------------------------------------- */
.route-liste{margin:0 0 20px;padding-left:22px;display:grid;gap:14px}
.route-liste li{padding-bottom:12px;border-bottom:1px solid var(--line)}
.route-liste li:last-child{border-bottom:0}
.route-liste li.ungeprueft{background:var(--warn);border-radius:8px;padding:10px 12px}
.route-marken{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:6px;font-size:13px}
.badge.geprueft{background:var(--ok-bg);color:var(--ok-ink)}
.badge.pruefen{background:var(--warn);color:var(--warn-ink)}

/* --- Prompts ------------------------------------------------------------- */
.prompt-text{width:100%;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:var(--sunk);color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:14px;resize:vertical}
/* Zwei kurze Werte nebeneinander; sie in voller Breite zu setzen ließe sie
   nach Freitext aussehen, den man erst formulieren muss. */
/* An der Oberkante ausrichten, nicht an der Unterkante: Sonst bestimmt die
   höchste Zelle, wo die Felder sitzen, und über den kürzeren bleibt Leerraum. */
.serverzugang-form{grid-template-columns:repeat(3,minmax(0,220px));align-items:start}
.serverzugang-form input{font:600 15px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
/* Die WAF-Erklärung über die volle Breite unter der Feldzeile – im Label
   zog sie die Zeile auseinander. */
.serverzugang-form .waf-hinweis{grid-column:1/-1;margin-top:-6px;max-width:70ch}
.serverzugang-form .waf-hinweis strong{color:var(--ink)}
.serverzugang-form .button-row{grid-column:1/-1}
.serverzugang-form .button-row .field-note{flex:1;min-width:220px}
@media(max-width:900px){.serverzugang-form{grid-template-columns:repeat(2,minmax(0,220px))}}
@media(max-width:640px){.serverzugang-form{grid-template-columns:1fr}}
.farbprobe{display:inline-block;margin-right:8px;padding:3px 9px;border-radius:6px;border:1px solid var(--line);font:600 12px/1.4 ui-monospace,Menlo,Consolas,monospace}
.welten{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
.welt{padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--paper)}
.welt.gewaehlt{border-color:var(--brand);box-shadow:0 0 0 2px rgba(101,89,189,.16)}
.welt strong{display:block;margin-bottom:3px}
.welt-proben{display:flex;gap:5px;margin-bottom:10px}
.welt-proben i{width:26px;height:16px;border-radius:4px;border:1px solid rgba(0,0,0,.12)}
.welt-klassisch i:nth-child(1){background:#1f5fbf}.welt-klassisch i:nth-child(2){background:#123a73}.welt-klassisch i:nth-child(3){background:var(--info-bg)}
.welt-natur i:nth-child(1){background:#2f7d4f}.welt-natur i:nth-child(2){background:#1c5233}.welt-natur i:nth-child(3){background:var(--ok-bg)}
.welt-warm i:nth-child(1){background:#b4552d}.welt-warm i:nth-child(2){background:#7d3a1e}.welt-warm i:nth-child(3){background:var(--warn)}
.welt-schlicht i:nth-child(1){background:#1a1a1a}.welt-schlicht i:nth-child(2){background:#000}.welt-schlicht i:nth-child(3){background:var(--chip)}
.welt-dunkel i:nth-child(1){background:#7aa7ff}.welt-dunkel i:nth-child(2){background:#0e1524}.welt-dunkel i:nth-child(3){background:#1a2436}
.welt-frisch i:nth-child(1){background:#0e8f93}.welt-frisch i:nth-child(2){background:#0a5f62}.welt-frisch i:nth-child(3){background:var(--info-bg)}
.badge.nachfassen{background:var(--warn);color:var(--warn-ink)}
/* Die Preisvariante ist eine Auskunft, keine Warnung: ruhig gefaerbt, damit
   sie in einer Zeile mit "Nachfassen" und "Entwurf steht" nicht um
   Aufmerksamkeit kaempft. Nur der verwaiste Verweis ist ein Fehler - dort
   zeigt der Betrieb keinen Preis mehr. */
.badge.preisvariante{background:var(--info-bg);color:var(--info-ink)}
.badge.preisvariante.von-hand{border:1px dashed currentColor}
.badge.preisvariante-verwaist{background:var(--danger);color:var(--danger-ink)}
/* Der Preis, so wie er im Prompt steht - unveraendert, damit sichtbar ist,
   was der Betrieb wirklich liest. */
.preisvorschau{margin:8px 0;padding:10px 12px;background:var(--sunk);border:1px solid var(--line);border-radius:8px;font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap}

/* --- Angebotsstatus: eigene Farbe je Bedeutung ---------------------------
   Vorher trugen alle Zustände dasselbe Grau, und die Klasse kam aus dem
   übersetzten Text – „Abrechnung aktiv" ist kein gültiger Klassenname, also
   griff nie eine Regel. Jetzt entscheidet der gespeicherte Schlüssel. */
.status.draft{background:var(--chip);color:var(--chip-ink)}
.status.ready{background:var(--info-bg);color:var(--info-ink)}
.status.sent{background:var(--info-bg);color:var(--info-ink)}        /* unterwegs, wartet */
.status.accepted{background:var(--ok-bg);color:var(--ok-ink)}    /* Zusage */
.status.active{background:var(--ok-bg);color:var(--ok-ink);font-weight:850}  /* verdient Geld */
.status.rejected{background:var(--danger);color:var(--danger-ink)}
.status.ended{background:var(--chip);color:var(--muted)}

.abrechnung{display:inline-flex;padding:4px 9px;border-radius:999px;font-size:12px;font-weight:800;white-space:nowrap}
.abrechnung.ton-gut{background:var(--ok-bg);color:var(--ok-ink)}
.abrechnung.ton-wartet{background:var(--warn);color:var(--warn-ink)}
.abrechnung.ton-achtung{background:var(--danger);color:var(--danger-ink)}
.abrechnung.ton-beendet{background:var(--chip);color:var(--muted)}

/* Ganze Zeile als Verweis: Das Ziel füllt die Zelle aus, damit der Klick
   überall sitzt und nicht nur auf den Buchstaben. */
.zeilen-verweis tbody tr{transition:background .12s ease}
.zeilen-verweis tbody tr:hover{background:var(--info-bg)}
.zeilen-verweis td{position:relative}
.zeile-ziel{display:block;color:inherit;font-weight:inherit}
.zeile-ziel strong{display:block;color:var(--brand)}
.zeile-ziel small{display:block;color:var(--muted)}
/* Der Klickbereich reicht über die ganze Zeile, liegt aber unter den
   übrigen Zellinhalten – ein Link im Text bleibt anklickbar. */
.zeile-ziel::after{content:"";position:absolute;inset:0;z-index:0}
.zeilen-verweis td>*{position:relative;z-index:1}

/* --- Knöpfe brechen nicht mehr um ---------------------------------------
   „Formular ansehen" stand zweizeilig im Kasten, ebenso die CSV-Knöpfe. Ein
   Knopf, der umbricht, sieht nach Versehen aus.

   NICHT MEHR JEDER KNOPF, SONDERN DIE IN EINER REIHE: Es gibt Knöpfe, deren
   Beschriftung eine Mailadresse enthält – „Angebot an
   vorname@sehr-lange-domain.example.de senden". Einzeilig ist der 640 Pixel
   breit; er schob auf der Angebotsseite die ganze Seite nach rechts, bei 390
   Pixeln UND bei 1440. Ein Knopf, den man wegschieben muss, ist schlimmer
   als ein zweizeiliger. Die Fälle von oben („Formular ansehen", „Als CSV
   exportieren") stehen alle in einer Kopfzeile oder einer Knopfreihe und
   bleiben deshalb einzeilig. */
.page-heading .portal-button,.button-row .portal-button,
.form-actions .portal-button,.filterleiste .portal-button,
.filtertafel-werkzeuge .portal-button{white-space:nowrap}
.portal-button{max-width:100%;overflow-wrap:anywhere}
.page-heading .button-row{flex-wrap:wrap;justify-content:flex-end}
.page-heading>div:last-child{flex:0 0 auto}
/* EIN FLEX-ELEMENT WIRD VON SELBST NICHT SCHMALER ALS SEIN LÄNGSTES WORT.
   „Auftragsverarbeitungsvertrag" als Überschrift ist bei 390 Pixeln vier
   Pixel zu breit – und diese vier Pixel machen die ganze Seite waagerecht
   schiebbar. Mit `min-width:0` darf der Kasten schrumpfen, mit der
   Umbruchregel darunter bricht das Wort statt überzustehen.

   `max-width:100%` UND NICHT NUR `min-width:0`: Unter 900 Pixeln steht die
   Kopfzeile als Spalte mit `align-items:flex-start`. Ein Element wird darin
   so breit wie sein längstes Wort – und blieb es auch, weil
   `overflow-wrap:break-word` erst beim Umbrechen greift und die gemessene
   Mindestbreite nicht ändert. Die Deckelung zwingt es in die Spalte, und
   dann bricht das Wort. */
.page-heading>div{min-width:0;max-width:100%}
h1,h2,h3{overflow-wrap:break-word}

/* --- Entwurfsanfrage: Vorgangsseite -------------------------------------- */
.anfrage-spalten{display:grid;grid-template-columns:1.7fr 1fr;gap:18px;align-items:start}
.anfrage-spalten .panel+.panel{margin-top:18px}
.anfrage-titel{color:inherit}
.anfrage-titel:hover strong{color:var(--brand)}
.anfrage-bilder figure{margin:0}
.anfrage-bilder figcaption small{display:inline;margin-left:6px}

.mail-anlass{border:1px solid var(--line);border-radius:11px;padding:12px 14px;margin-bottom:12px;background:var(--sunk)}
.mail-anlass summary{cursor:pointer;display:flex;flex-wrap:wrap;align-items:baseline;gap:10px}
.mail-anlass summary small{color:var(--muted)}
.mail-anlass[open]{background:var(--paper);border-color:var(--brand)}
.mail-anlass .portal-form{margin-top:14px}
/* Die Vorschau zeigt wörtlich, was rausgeht – niemand verschickt gern etwas,
   das er vorher nicht gesehen hat. */
.mail-vorschau{margin:0 0 12px;padding:14px;background:var(--info-bg);border:1px solid var(--line);border-radius:9px;font:13px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre-wrap;max-height:340px;overflow:auto}

@media (max-width:1000px){ .anfrage-spalten{grid-template-columns:1fr} }

/* --- Bildansicht auf derselben Seite -------------------------------------
   Vorher öffnete jedes Bild einen neuen Reiter: ansehen, Reiter schließen,
   die Änderungsseite wiederfinden. Bei sechs Bildern sechsmal derselbe Umweg. */
.bildansicht{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;padding:clamp(12px,3vw,40px);background:rgba(20,20,26,.86);backdrop-filter:blur(3px)}
.bildansicht[hidden]{display:none}
.bildansicht-buehne{display:flex;flex-direction:column;gap:12px;max-width:min(100%,1500px);max-height:100%}
/* Das Bild wird nur zum Ansehen verkleinert – heruntergeladen wird das
   Original, nicht diese Darstellung. */
.bildansicht img{max-width:100%;max-height:calc(100vh - 150px);object-fit:contain;border-radius:10px;background:var(--paper);box-shadow:0 24px 70px rgba(0,0,0,.5)}
.bildansicht-leiste{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:14px}
.bildansicht-titel{color:#fff;font-size:14px;font-weight:700;overflow-wrap:anywhere}
.bildansicht-knoepfe{display:flex;gap:10px;flex:0 0 auto}
.bildansicht .portal-button{background:var(--paper)}
body.bildansicht-offen{overflow:hidden}

/* --- Optik-Einschätzung --------------------------------------------------- */
.badge.optik-veraltet{background:var(--danger);color:var(--danger-ink)}
/* Kaum Inhalt ist ein eigener Befund, kein Zwischending: Die Seite kann
   technisch tadellos sein und trotzdem nichts hergeben. */
.badge.optik-duenn{background:var(--warn);color:var(--warn-ink)}
.badge.optik-angestaubt{background:var(--warn);color:var(--warn-ink)}
.badge.optik-zeitgemaess{background:var(--info-bg);color:var(--info-ink)}
.optik-gruende{margin:10px 0;padding:10px 12px;border:1px solid var(--line);border-radius:9px;background:var(--sunk)}
.optik-gruende summary{cursor:pointer;font-weight:750;font-size:14px}
.optik-gruende ul{margin:10px 0 0;padding-left:20px;display:grid;gap:6px;font-size:14px;color:var(--muted)}
.badge.angesehen{background:var(--ok-bg);color:var(--ok-ink);font-weight:850}
.badge.nie-geoeffnet{background:var(--chip);color:var(--muted)}
/* Abrufe statt Ansichten: Zählt der Entwurf Maschinen mit, ist die Zahl kein
   Erfolg mehr, sondern eine Angabe. Grau, damit sie beim Überfliegen der
   Liste nicht wie eine Spur aussieht, der man nachgehen kann. */
.badge.abrufe-ungefiltert{background:var(--chip);color:var(--muted)}
/* Vor dem Brief gibt es nichts zu zählen: Der Betrieb kennt die Adresse noch
   nicht. Grau wie die Abrufe – die Marke sagt, warum hier keine Zahl steht,
   und nicht, dass es etwas zu holen gäbe. */
.badge.brief-fehlt{background:var(--chip);color:var(--muted)}
.route-einstellung{display:grid;gap:16px}
.route-einstellung fieldset{margin:0}
.route-einstellung .auswahlzeile{display:flex;align-items:flex-start;gap:10px;padding:8px 0;font-weight:750;cursor:pointer}
.route-einstellung .auswahlzeile input{margin-top:3px;flex:none}
.route-einstellung .auswahlzeile span{font-weight:750}
.route-einstellung input[type=number]{width:90px;font:inherit;border:1px solid var(--field-line);border-radius:8px;padding:9px 10px}
.route-einstellung .field-note{margin:8px 0 0}
.route-einstellung button{justify-self:start}
.panel-kopf{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;margin-bottom:6px}
.panel-kopf h2{margin:0}
.panel-kopf h2 small{display:inline;margin-left:10px;font-size:14px;font-weight:600}
.akquise-suche{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.akquise-suche input[type=search]{flex:1;min-width:220px;font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:10px 12px}
.akquise-suche input[type=search]:focus{outline:3px solid rgba(101,89,189,.16);border-color:var(--brand)}
.akquise-suche .portal-button{min-height:40px;padding:0 16px}
.suchzeile{align-items:center}
.badge.rueckmeldung{background:var(--warn);color:var(--warn-ink);font-weight:850}
.nachruesten summary{cursor:pointer;display:flex;flex-wrap:wrap;align-items:baseline;gap:12px;padding:4px 0}
.nachruesten summary strong{font-size:19px}
.nachruesten summary small{color:var(--muted)}
.nachruesten[open] summary{margin-bottom:12px}
.ki-hinweis{margin-top:12px;padding:10px 12px;border:1px solid var(--line);border-radius:9px;background:var(--sunk)}
.ki-nutzung{margin:0;padding-left:20px;display:grid;gap:12px}
.ki-nutzung strong{display:block}
.ki-nutzung span{color:var(--muted);font-size:14px}
.kontingent{display:flex;flex-wrap:wrap;gap:28px;margin:16px 0}
.kontingent dt{color:var(--muted);font-size:13px}
.kontingent dd{margin:2px 0 0;font-size:15px}
.kontingent strong{font-size:22px;letter-spacing:-.03em}
.kontingent-tabelle{max-width:520px;margin:12px 0}
.kontingent-tabelle tr.aktiv{background:var(--accent);font-weight:700}
.kontingent-tabelle code{font-size:13px}
.badge.ki-geprueft{background:var(--ok-bg);color:var(--ok-ink);font-weight:850}
.badge.ki-vollstaendig{background:var(--chip);color:var(--chip-ink)}
.badge.ki-offen{background:var(--danger);color:var(--danger-ink);font-weight:850}
/* Wo dieser Betrieb GERADE im Durchgang steht. Eine Auskunft, keine Wertung –
   deshalb dieselbe ruhige Hinweisfarbe wie bei „prüfend". Nur der
   vorgezogene hebt sich ab: Er ist die Antwort auf einen Knopfdruck von vor
   einer Sekunde, und genau die sucht man in der Liste. Für die Einzelprüfung
   gilt dasselbe – sie IST der Knopfdruck von vor einer Sekunde. */
.badge.ki-warte{background:var(--info-bg);color:var(--info-ink)}
.badge.ki-warte.vorrang,.badge.ki-warte.einzeln{font-weight:850}
/* Der Befund aus dem Durchgang. Er ist eine Auskunft und keine Warnung: Ein
   Betrieb ohne Seite ist der gesuchte Fall und kein Mangel – deshalb die
   ruhige Hinweisfarbe und nicht Rot. „Domain nicht erreichbar" bekommt die
   Warnfarbe, denn das ist der stärkste Briefanlass in dieser Liste und soll
   ins Auge fallen. Verlinkt sind alle drei: Ein Klick sammelt die gleichen
   Fälle ein. */
.badge.ki-befund{background:var(--chip);color:var(--chip-ink);font-weight:850;text-decoration:none}
.badge.ki-befund.domain_tot{background:var(--warn);color:var(--warn-ink)}
.akquise-fortschritt.ki{margin:0 0 14px}
.akquise-fortschritt.serie{margin:0 0 14px}
/* Der Briefstapel steht wie die beiden darüber in der Filtertafel und
   braucht denselben Abstand – ohne ihn klebte er am Kasten davor. */
.akquise-fortschritt.brief{margin:0 0 14px}
/* Der Zustandssatz ist die zweite Zeile des Kastens und darf nicht wie ein
   Absatz aussehen – er gehört zur Zahl darüber. */
.akquise-fortschritt .serie-zustand{margin:4px 0 0;font-weight:650}
.akquise-fortschritt .serie-schaetzung{display:block;margin-top:2px}
/* Der Satz unter der Rechnergrenze. Er steht da, weil zwei Zeilen mit
   Zahlen uebereinander gleich aussehen - der Unterschied zwischen
   "Entwuerfe" und "alle Chats des Rechners" ist aber der ganze Witz
   der unteren. Gleiche Masse wie die Schaetzung darueber. */
.akquise-fortschritt .serie-laeufer-hinweis{display:block;margin-top:2px}
.serie-knoepfe{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:10px}
/* „Anhalten" und „Fortsetzen" am Durchgang: nebeneinander, am Handy
   untereinander. Beide müssen erreichbar bleiben – der eine hält an, der
   andere nimmt es zurück, und ohne den zweiten bliebe der Schalter stehen. */
.ki-knoepfe{margin-top:10px}
.knopfgruppe{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.knopfgruppe.rechts{justify-content:flex-end;margin-bottom:12px}

/* Nebenwege: Handgriffe, die es geben muss, aber selten richtig sind.
   Zugeklappt, damit der Regelweg der offensichtliche bleibt. */
.nebenweg{margin-top:18px;padding-top:14px;border-top:1px solid var(--line)}
.nebenweg>summary{cursor:pointer;color:var(--muted);font-weight:750;font-size:13px;padding:4px 0;list-style:none}
.nebenweg>summary::-webkit-details-marker{display:none}
.nebenweg>summary:before{content:"›";display:inline-block;margin-right:8px;transition:transform .15s}
.nebenweg[open]>summary:before{transform:rotate(90deg)}
.nebenweg>summary:hover{color:var(--brand)}
.nebenweg>*+*{margin-top:12px}
.abbuchung{margin-top:6px;color:var(--ink)}

/* Angebotsseite: Karten statt einer einzigen langen Spalte.

   Vorher stand links die Kundenansicht und rechts eine schmale Spalte mit
   sechs Karten untereinander – zweitausend Pixel hoch, daneben ein halber
   Bildschirm Leere. Jetzt füllen die Karten die Breite, und was in der
   aktuellen Phase erledigt ist, steckt zugeklappt in einem Nebenweg. */
/* Spalten statt Raster: Ein Raster gibt jeder Zeile die Höhe ihrer größten
   Karte – neben der langen Kundenansicht stand dadurch ein halber Bildschirm
   Nichts. Der mehrspaltige Satz füllt die Spalten stattdessen gleichmäßig
   auf, und die Seite ist statt zweitausend nur noch tausend Pixel hoch. */
.angebot-raster{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));gap:18px;align-items:start}
.angebotsblatt{margin-bottom:18px}
.angebotsblatt .price-line{align-items:flex-start;flex-direction:column;gap:2px;padding:10px 0}
.angebotsblatt .price-line>strong{font-size:17px}
.angebot-raster .panel{padding:clamp(18px,1.8vw,26px)}
.angebot-raster .panel h2{font-size:clamp(19px,1.4vw,23px);margin-bottom:10px}
.angebot-raster .panel h3{margin-top:18px;font-size:16px}
.angebot-raster .panel>p:last-child,.angebot-raster .panel>form:last-child{margin-bottom:0}
.leistungsspalten{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:0 34px;align-items:start}
.leistungsspalten>div>h3:first-child{margin-top:14px}
ul.knapp{margin:0;padding-left:18px}
ul.knapp li{padding:3px 0;color:var(--muted)}

/* Die Zahlen, die man beim Öffnen sucht – eine Zeile statt fünf Karten. */
.statusleiste{display:flex;flex-wrap:wrap;gap:0 clamp(22px,3vw,46px);margin:0 0 18px;padding:14px clamp(16px,2vw,24px);background:var(--paper);border:1px solid var(--line);border-radius:14px;box-shadow:0 8px 28px var(--schatten-weich)}
.statusleiste>div{padding:6px 0}
.statusleiste dt{font-size:11px;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.09em}
.statusleiste dd{margin:3px 0 0;font-weight:750}
.statusleiste dd small{display:inline;color:var(--muted)}
.statusleiste .leise{color:var(--muted);font-weight:600}

.notice-box.abweichung{margin-bottom:18px}
.notice-box.abweichung ul{margin:8px 0;padding-left:20px}
.notice-box.abweichung form{margin-top:12px}
.facts.eng{margin:12px 0}
.facts.eng dt,.facts.eng dd{padding:7px 0}
/* EIN TOKEN HAT KEINE STELLE, AN DER ER VON SELBST UMBRICHT. Der Schlüssel
   für die Schnittstelle steht auf der Rechnerseite in einer Angabenliste und
   ist 43 Zeichen lang – er schob bei 390 Pixeln die ganze Seite nach rechts.
   Dasselbe gilt für Mailadressen und Domains, die hier ebenfalls stehen. */
.facts dt,.facts dd{overflow-wrap:anywhere}

@media(max-width:900px){.angebot-raster{grid-template-columns:1fr}}
.angebot-raster>.zuletzt{order:9}
/* Ein gespeicherter Name, der kein Firmenname ist. Sichtbar lassen, aber
   kenntlich: Er kommt weder auf den Brief noch in den Prompt. */
.kein-firmenname{color:var(--danger-ink);text-decoration:underline wavy var(--danger-ink);text-underline-offset:3px}
.erzwingen-haken{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--muted);font-weight:650}
.erzwingen-haken input{width:auto;margin:0}
.status.im_workchat{background:var(--info-bg);color:var(--info-ink)}
/* Die Farbwelt des Betriebs steht vor den sechs fertigen – sie entsteht erst
   im Chat, deshalb gestrichelt und ohne Farbproben. */
.welt-logo{border-style:dashed}
.status.gedruckt{background:var(--info-bg);color:var(--info-ink)}
.einwilligung-wortlaut{margin:8px 0;padding:10px 12px;border-left:3px solid var(--brand);background:var(--sunk);color:var(--ink);font-size:13px}
/* Ein Entwurf, der steht, aber niemanden antworten lässt. Der Verweis führt
   direkt zum Nachrüst-Prompt – eine Marke, die nur mahnt, hilft nicht. */
.badge.fenster-fehlt{background:var(--warn);color:var(--warn-ink);border:1px solid var(--warn-line)}
.badge.fenster-fehlt:hover{background:var(--warn)}
.push-stand{margin-top:10px;font-size:13px;color:var(--muted)}
.push-stand.gut{color:var(--ok-ink);font-weight:700}
.push-stand.warnung{color:var(--warn-ink)}

/* Liste der Servertypen im Wächter. Angehakt wird direkt in der Zeile –
   ein Auswahlmenü zwingt zum Suchen, wo eine Liste einfach dasteht. */
.servertypen{font-variant-numeric:tabular-nums}
.servertypen th:first-child,.servertypen td:first-child{width:1%;white-space:nowrap}
.servertypen td small{display:block;color:var(--muted);font-size:11px}
.servertypen tr.frei td{background:var(--ok-bg)}
.servertypen tr:hover td{background:var(--sunk)}
.servertypen tr.frei:hover td{background:var(--ok-bg)}
.servertypen .badge{white-space:nowrap}

/* Die Servertypen in Reihen nebeneinander, wie Hetzner sie selbst zeigt.
   Eine alphabetische Gesamtliste stellte CAX11 neben CCX13 und verschwieg,
   dass das zwei völlig verschiedene Dinge sind. */
.reihen{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px;align-items:start}
.reihe h3{margin:0 0 4px;font-size:15px}
.reihe .field-note{margin-bottom:8px}
.servertypen td{padding:7px 8px;vertical-align:middle}
.servertypen td.haken{width:1%;padding-right:2px}
.servertypen td.preis{text-align:right;white-space:nowrap}
.servertypen td.orte{text-align:right;width:1%}
.ort{display:inline-block;margin-left:4px;padding:2px 7px;border-radius:999px;background:var(--ok-bg);color:var(--ok-ink);font-size:11px;font-weight:800}
.ort.leer{background:var(--chip);color:var(--muted);font-weight:600}
.melde-link code{display:block;padding:8px 10px;background:var(--sunk);border:1px solid var(--line);border-radius:8px;font-size:12px;overflow-wrap:anywhere}
.push-stand{margin-top:10px;font-size:13px}
.push-stand.gut{color:var(--ok-ink)}
.push-stand.warnung{color:var(--danger-ink)}
.typenblatt{margin-bottom:18px}
.typenblatt .inline-form{margin-top:18px;align-items:flex-end}
.typenblatt .inline-form label{max-width:220px}

/* Standortwahl: angehakte Orte als Marken, damit man auf einen Blick sieht,
   wo gesucht wird. Ein Freitextfeld verlangte zu wissen, dass „hel1"
   Helsinki ist. */
.standortwahl{margin-top:20px;padding-top:16px;border-top:1px solid var(--line)}
.ortmarken{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0}
.ortmarke{display:inline-flex;align-items:center;gap:8px;padding:7px 12px;border:1px solid var(--line);border-radius:999px;background:var(--paper);cursor:pointer;font-weight:650}
.ortmarke.aktiv{border-color:var(--brand);background:var(--accent)}
.ortmarke input{width:auto;margin:0}
.ortmarke small{color:var(--muted);font-weight:600}

/* Rückmeldungen in der Akquise-Liste.

   Die Marke ist ein Verweis, kein Etikett: Vorher stand dort „Frage oder
   Nachricht", und was drinstand, war nirgends zu sehen. Die Probe daneben
   ist absichtlich leise – sie sagt „der Rückweg steht", nicht „hier hat
   jemand geschrieben". */
a.badge.rueckmeldung{text-decoration:none}
a.badge.rueckmeldung:hover{filter:brightness(.95)}
.badge.gelesen{background:var(--info-bg);color:var(--muted);text-decoration:none}
.badge.probe{background:var(--chip);color:var(--muted);font-weight:600}

/* Die Nachrichten selbst. */
.rueckmeldung{border:1px solid var(--line);border-left:4px solid var(--field-line);border-radius:8px;padding:14px 18px;margin:0 0 12px}
.rueckmeldung.dringend{border-left-color:var(--ok-ink);background:var(--ok-bg)}
.rueckmeldung-kopf{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:6px}
.rueckmeldung-kopf .leise{font-size:12.5px;color:var(--muted)}
.rueckmeldung-text{margin:0 0 10px;white-space:pre-wrap;line-height:1.55}

/* Tote Bildverweise im Entwurf. Rot, weil es der Betrieb sieht, sobald er
   die Adresse aus dem Brief eintippt. */
.badge.bilder-fehlen{background:var(--danger);color:var(--danger-ink);text-decoration:none;font-weight:700}

/* Zu wenige Fassungen im Entwurf. Warnfarbe und nicht Rot: Die Seite steht und
   ist zeigbar, es fehlt die Auswahl – ein anderer Befund als ein leerer Kasten
   dort, wo ein Bild sein sollte. */
.badge.fassungen-fehlen{background:var(--warn);color:var(--warn-ink);border:1px solid var(--warn-line);text-decoration:none}

/* Das Reichweitenfeld in der Sammelleiste. Es steht neben einem gestalteten
   Auswahlfeld und muss deshalb genauso aussehen – ein rohes Eingabefeld
   daneben liest sich wie ein Fehler in der Seite. Die Pfeilchen des
   Zahlenfelds sind weg: Sie sind winzig, und niemand stellt eine Reichweite
   in Fünferschritten ein. */
.sammel-stand input[type="number"]{
  font:inherit;font-weight:400;background:var(--paper);color:var(--ink);
  border:1px solid var(--field-line);border-radius:8px;padding:8px 10px;
}
.reichweite-feld{width:92px;text-align:right}
.reichweite-feld::-webkit-outer-spin-button,
.reichweite-feld::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.reichweite-feld{-moz-appearance:textfield;appearance:textfield}

/* Die Einheit gehört ins Feld, nicht daneben: „Reichweite … km" mit Abstand
   dazwischen liest sich wie zwei getrennte Angaben. */
.feld-mit-einheit{position:relative;display:inline-flex;align-items:center}
.feld-mit-einheit .einheit{position:absolute;right:10px;color:var(--muted);font-weight:400;pointer-events:none}
.feld-mit-einheit .reichweite-feld{padding-right:30px}

/* Widersprüchliche Anschrift: die einzige Marke, die eine Fahrt verhindert –
   und deshalb die auffälligste in der Zeile. */
.badge.anschrift-strittig{background:#8a1f1f;color:#fff;font-weight:850;text-decoration:none}
/* Der Brief ist nicht rausgegangen. Genauso auffällig: Der Betrieb steht
   wieder unter „Zum Anschreiben", und der Grund darf nicht untergehen. */
.badge.brief-zurueck{background:#8a1f1f;color:#fff;font-weight:850}
/* Der Zugang aus dem Brief wird abgewiesen. Dieselbe Auffaelligkeit wie ein
   zurueckgekommener Brief, denn es ist dieselbe Folge: Der Betrieb kann
   nichts damit anfangen - nur merkt es hier niemand, weil die Seite steht. */
.badge.zugang-kaputt{background:#8a1f1f;color:#fff;font-weight:850}
/* Filiale einer Kette: Hier wird nichts gebaut und nichts verschickt. Dieselbe
   Auffaelligkeit wie die beiden darueber, denn es ist dieselbe Sorte Auskunft
   - der Betrieb sieht in der Liste normal aus, verhaelt sich aber nicht so.
   Vorher blendete die Erkennung nur Punkte auf der Karte aus; hier stand die
   Filiale wie jeder andere, wurde mitgewaehlt, und Kontingent und Porto waren
   weg. */
.badge.kette-gesperrt{background:#8a1f1f;color:#fff;font-weight:850}
/* Von Hand freigegeben: Der Name deutet weiter auf eine Filiale, die
   Entscheidung ist getroffen. Ruhig statt alarmierend - sie soll erkennbar
   sein, aber nicht mahnen. */
.badge.kette-frei{background:var(--chip);color:var(--muted);font-weight:700;
  border:1px solid var(--line)}
.anschrift-konflikt{margin:10px 0;padding:12px 14px;border:1px solid var(--danger-line);
  border-radius:10px;background:var(--danger)}
.anschrift-konflikt > p:first-child{margin:0 0 10px}
.konflikt-wahl{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.konflikt-wahl > div{display:grid;gap:4px;align-content:start;padding:10px 12px;
  border:1px solid var(--line);border-radius:9px;background:var(--paper)}
.konflikt-wahl strong{font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.konflikt-wahl span{font-weight:750}
.konflikt-wahl small{color:var(--muted)}
.konflikt-wahl button{margin-top:6px}

/* Die Fahrtenübersicht. Karten statt Tabelle, weil sie am Handy gelesen
   wird – und dort ist eine Tabelle mit sechs Spalten unbenutzbar. */
.fahrt-karten{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.fahrt-karte{padding:14px 16px;border:1px solid var(--line);border-radius:11px;background:var(--paper)}
.fahrt-karte.erledigt{opacity:.66}
.fahrt-karte-kopf{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
.fahrt-zahlen{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:0 0 12px}
.fahrt-zahlen dt{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.fahrt-zahlen dd{margin:2px 0 0;font-weight:800;font-size:17px}

/* Die Verwaltung am Handy: seit dem Klappmenue (siehe .nav-klapp weiter
   unten) braucht der Kopf hier nur noch Kleinigkeiten. Die fruehere
   Pillen-Wischleiste stand an dieser Stelle - mit hartem #fff, das im
   Dunkelmodus als weisse Kapseln leuchtete, und einem Wischen, von dem
   niemand wusste, dass es eines gibt. */
@media (max-width: 900px) {
  .portal-brand img { width: 32px; height: 32px; }
}

/* Unter 540 px wird auch die Kopfzeile selbst knapp. */
@media (max-width: 540px) {
  .portal-header { min-height: 0; }
  .page-heading h1 { font-size: 27px; }
  .filtertafel-kopf { flex-direction: column; align-items: flex-start; gap: 10px; }
  .filtertafel-werkzeuge { flex-wrap: wrap; }
  /* Eine Tabelle mit sechs Spalten ist am Handy nicht zu lesen – sie darf
     wenigstens seitlich scrollen, statt die Seite mitzuziehen. Das ist der
     Rückfall für Tabellen, aus denen keine Karte wird (siehe unten). */
  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .button-row, .form-actions { gap: 8px; }
  .button-row .portal-button, .form-actions .portal-button { flex: 1 1 auto; }
}

/* --- AUS EINER BREITEN TABELLE WIRD AM HANDY EINE KARTE -----------------

   Seitlich schieben war die Ausrede, nicht die Lösung: Die Kopfzeile schiebt
   mit, und nach zwei Fingerbreiten weiss niemand mehr, in welcher Spalte er
   liest. Die Knöpfe der letzten Spalte findet nur, wer weiss, dass es sie
   gibt.

   `js/tabellen-karten.js` schreibt in jede Zelle die Beschriftung ihrer
   Spalte (`data-spalte`) und setzt `.karten` an den Kasten. Erst dann greift
   das hier – ohne Skript bleibt es bei der schiebbaren Tabelle von oben.

   AN DER GEMEINSAMEN KLASSE UND NICHT JE SEITE: `.table-wrap` steht in
   neunundzwanzig Vorlagen. Zwanzig Sonderregeln wären zwanzig Stellen, an
   denen es beim nächsten Mal wieder auseinander läuft. */
@media (max-width: 700px) {
  .table-wrap.karten { overflow-x: visible; }
  .table-wrap.karten > table,
  .table-wrap.karten > table > tbody,
  .table-wrap.karten > table > tbody > tr,
  .table-wrap.karten > table > tbody > tr > td,
  .table-wrap.karten > table > tbody > tr > th { display: block; width: auto; }
  .table-wrap.karten > table > thead { display: none; }
  .table-wrap.karten > table > tbody > tr {
    margin: 0 0 12px; border: 1px solid var(--line); border-radius: 11px;
    background: var(--paper); }
  .table-wrap.karten > table > tbody > tr:last-child { margin-bottom: 0; }
  .table-wrap.karten > table > tbody > tr > td,
  .table-wrap.karten > table > tbody > tr > th {
    padding: 10px 14px; border: 0; border-bottom: 1px solid var(--line);
    text-align: left; overflow-wrap: anywhere; }
  .table-wrap.karten > table > tbody > tr > td:last-child,
  .table-wrap.karten > table > tbody > tr > th:last-child {
    border-bottom: 0; }
  /* Eine leere Zelle trägt in einer Karte nur ihre Beschriftung – eine
     Zeile, die nichts sagt. In der Tabelle war sie nur eine Lücke. */
  .table-wrap.karten > table > tbody > tr > td:empty { display: none; }
  .table-wrap.karten > table > tbody > tr > td[data-spalte]::before {
    content: attr(data-spalte); display: block; margin: 0 0 3px;
    font-size: 11px; font-weight: 750; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted); }
}

/* --- LANGE WÖRTER BRECHEN, STATT ÜBERZUSTEHEN --------------------------

   Eine Mailadresse wie `vorname.nachname@sehr-langer-firmenname.example.de`,
   ein Token aus 43 Zeichen, eine Domain oder ein Wort wie
   „Entwurfsoeffnungsbestaetigungsnachweis" hat keine Stelle, an der ein
   Umbruch von selbst passiert. Solche Wörter standen an einem Dutzend
   Stellen über dem Rand ihres Kastens – in Tabellenzellen, in Karten, in
   Angabenlisten.

   AN EINER STELLE UND NICHT AN ZWÖLF: Die Angabe vererbt sich, deshalb
   genügt sie am `body`. `break-word` und NICHT `anywhere`: Es greift erst,
   wenn ein Wort sonst überstünde, und lässt die gemessene Mindestbreite
   eines Kastens in Ruhe – an der Aufteilung von Rastern, Tabellen und
   Flex-Reihen ändert sich damit nichts. Wo eine Spalte auch schmaler werden
   SOLL, steht `anywhere` eigens dabei (Kartenansicht, Angabenlisten). */
body { overflow-wrap: break-word; }

/* Vier Zahlen nebeneinander brechen bei 375 px mitten in „75.1 km". */
@media (max-width: 430px) {
  .fahrt-zahlen { grid-template-columns: repeat(2, 1fr); gap: 10px 8px; }
  .fahrt-karten { grid-template-columns: 1fr; }
}

/* --- Antworten im Mailcenter --------------------------------------------

   Die zitierte Nachricht stand bisher IM Schreibfeld: Man tippte seine
   Antwort über zwanzig Zeilen fremden Text mit „> " davor, den man ohnehin
   nie ändert. Jetzt steht sie darunter, gedämpft und unveränderlich – das
   Schreibfeld ist ein leeres Blatt. */
.zitatblock { border: 1px solid var(--line); border-radius: 11px;
  background: var(--sunk); overflow: hidden; }
.zitat-kopf { padding: 11px 14px; border-bottom: 1px solid var(--line);
  background: var(--chip); }
.zitat-kopf strong { font-size: 13px; }
.zitat-kopf .field-note { margin-top: 2px; }
.zitat-text { margin: 0; padding: 14px; max-height: 260px; overflow: auto;
  font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--muted); white-space: pre-wrap; overflow-wrap: anywhere; }

/* Der Datei-Knopf. „Dateien auswählen / Keine ausgewählt" ist die
   Voreinstellung des Browsers und sieht in jedem Browser anders aus. */
.dateiwahl input[type="file"] { border: 1px dashed var(--field-line);
  background: var(--sunk); color: var(--ink);
  padding: 10px 12px; cursor: pointer; }
.dateiwahl input[type="file"]:hover { border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 5%, var(--paper)); }
.dateiwahl input[type="file"]::file-selector-button {
  margin-right: 12px; min-height: 38px; padding: 0 15px; border: 0;
  border-radius: 8px; background: var(--brand); color: #fff;
  font: inherit; font-weight: 800; cursor: pointer;
}
.dateiwahl input[type="file"]::file-selector-button:hover { background: var(--brand-dark); }

.formathilfe { margin-top: 4px; }
.formathilfe code { padding: 1px 5px; border-radius: 4px; background: var(--chip);
  font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--chip-ink); }

/* Die Halteliste der Fahrt: Nummer, Ortsgruppe, und Marken nur, wenn sie
   etwas sagen. */
.ortsgruppe { display: flex; align-items: baseline; gap: 10px; margin: 22px 0 2px;
  font-weight: 850; font-size: 13px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--brand); }
.ortsgruppe:first-of-type { margin-top: 8px; }
.ortsgruppe span { font-weight: 600; font-size: 12px; letter-spacing: 0;
  text-transform: none; color: var(--muted); }
.halt-nr { display: inline-grid; place-items: center; min-width: 26px; height: 26px;
  margin-right: 10px; padding: 0 6px; border-radius: 8px; background: var(--chip);
  color: var(--chip-ink); font-size: 13px; font-weight: 850; vertical-align: 1px; }
.halt-zeile.ist-fertig { opacity: .55; }
.halt-zeile.ist-fertig .halt-nr { background: var(--ok-bg); color: var(--ok-ink); }

/* --- Termine ------------------------------------------------------------ */
.termin-neu { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); align-items: end; }
.termin-karten { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.termin-karte { display: grid; gap: 3px; align-content: start; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: 11px; background: var(--paper);
  color: var(--ink); font-weight: 400; }
.termin-karte:hover { border-color: var(--brand); box-shadow: var(--shadow); }
.termin-karte.erledigt { opacity: .62; }
.termin-kopf { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 4px; }
.termin-kopf strong { font-size: 16px; }
.termin-zeit { font-weight: 750; }
.leise { color: var(--muted); font-weight: 400; }

/* Das Bürobild. Der Rahmen färbt sich nach dem Stand – damit sieht man auf
   einen Blick, wo noch Fragezeichen stehen. */
.lage-block { display: grid; gap: 6px; padding: 11px 13px; margin-bottom: 10px;
  border: 1px solid var(--line); border-left: 4px solid var(--field-line);
  border-radius: 9px; background: var(--sunk); }
.lage-block.lage-steht { border-left-color: var(--ok-ink); }
.lage-block.lage-risiko { border-left-color: var(--signal-bernstein); }
.lage-block.lage-befund { border-left-color: var(--danger-ink); }
.lage-titel { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; font-weight: 800; }
.lage-titel select { width: auto; min-width: 170px; }
.lage-block input[type="text"] { width: 100%; font: inherit; padding: 9px 11px;
  border: 1px solid var(--field-line); border-radius: 8px;
  background: var(--paper); color: var(--ink); }
.zitatfeld { font: 14px/1.7 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

/* Der Streifen, der einen nicht gespeicherten Entwurf zurückholt. */
.entwurf-streifen { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 18px; padding: 12px 16px; border: 1px solid var(--warn-line);
  border-radius: 10px; background: var(--warn); color: var(--warn-ink); font-weight: 700; }
.entwurf-streifen span { flex: 1 1 240px; }

.vorschlagskasten { border-color: var(--brand); }
.vorschlagsform { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  align-items: end; }

/* Aufträge an den Läufer auf dem Mac.
   Der Knopf im Portal startet nichts – er reiht ein. Der Mac fragt nach und
   holt sich den Auftrag. Sichtbar sein muss also beides: dass etwas wartet,
   und dass etwas passiert. */
.auftrag-lauf{margin:14px 0;padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--sunk)}
.auftrag-lauf p{margin:0 0 10px;color:var(--ink)}
.auftrag-fortschritt{margin:0 0 12px;padding:12px;max-height:220px;overflow:auto;background:var(--paper);border:1px solid var(--line);border-radius:9px;font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--muted);white-space:pre-wrap;overflow-wrap:anywhere}

/* DER PULS. Er sagt das, was keine Zahl sagt: Da arbeitet gerade jemand.
   Ein Balken, der von links nach rechts wandert - kein Prozentwert, denn
   niemand weiss, wie weit ein Lauf ist. Er laeuft, solange sich der Lauf
   rueht; bleibt er stehen, steht auch der Balken. */
/* DER PRUEFSTAND. Hier ist ein echter Anteil zu haben - die Zahl der
   Kandidaten steht fest, und jeder Lauf arbeitet sie ab. Deshalb hier ein
   gefuellter Balken und kein Puls: Er sagt etwas, was stimmt. */
/* ACHTUNG, DIE FARBE: --accent ist in diesem Projekt eine FLAECHE
   (#e7e5fb hell, #2e2a47 dunkel), nicht die Marke. Wer damit einen Balken
   fuellt, faerbt ihn in der Farbe seines eigenen Hintergrunds - genau das
   war der Fehler, wegen dem der Balken bei 15 Prozent aussah wie bei 100.
   Fuer alles Sichtbare gilt --brand.

   DER GRUND HELL UND DER FORTSCHRITT DUNKEL WAERE FALSCH HERUM - und genau
   so sah es aus: var(--line) ist im dunklen Modus fast so hell wie der
   Akzent, und ein Balken, bei dem sich Fuellung und Grund nicht
   unterscheiden, ist ein Strich. Er sah bei elf Prozent aus wie bei
   hundert. */
/* OHNE INNERES ELEMENT. Vorher lag im Balken ein <span> mit einer Breite in
   Prozent - und der war beim Nutzer immer voll, egal was drinstand. Statt
   weiter zu raten, warum, faellt das Element weg: Die Fuellung ist jetzt
   ein Farbverlauf mit HARTEM Umschlag an der Stelle --anteil. Ein Verlauf
   kann nicht zu breit sein; er ist die Breite.

   --anteil kommt als Inline-Angabe von der Seite und wird beim Nachladen
   vom Skript gesetzt. Fehlt sie, steht der Balken auf 0 - leer und nicht
   voll, denn ein voller Balken ohne Daten ist eine Luege. */
.pruef-balken{--anteil:0%;height:10px;margin:0 0 8px;border-radius:5px;
  border:1px solid var(--line);
  background:linear-gradient(to right,
    var(--brand) 0 var(--anteil), var(--sunk) var(--anteil) 100%);
  transition:background .6s ease}
/* Die Lage in vier Zahlen: was gerade laeuft, wie schnell, wie lange noch.
   Ein Anteil allein beantwortet nicht die Frage, mit der man auf die Seite
   kommt - kann ich weggehen, oder ist es gleich durch? */
.pruef-lage{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px;margin:0 0 18px;padding:0}
.pruef-lage>div{padding:12px 14px;border:1px solid var(--line);border-radius:10px;
  background:var(--sunk)}
.pruef-lage dt{margin:0 0 2px;font-size:12px;color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em}
.pruef-lage dd{margin:0;font-size:21px;font-weight:800;color:var(--ink);
  font-variant-numeric:tabular-nums;line-height:1.25;
  overflow-wrap:anywhere;hyphens:auto}
.pruef-lage dd small{display:block;font-size:12px;font-weight:400;color:var(--muted);
  letter-spacing:0;text-transform:none}
.pruef-lage .pruef-rest dd{font-size:17px;color:var(--brand)}
/* KACHELN MIT AUFGABENTITELN STATT EINER ZAHL. 21 Pixel fett waren für
   „10 Aufgaben" gedacht. Ein Titel ist dafür zu lang: „Entwurfsoeffnungen"
   ist als ein Wort breiter als eine 150-Pixel-Spalte und stand über dem
   Kachelrand, und der laufende Kasten führt oft mehrere Titel hintereinander.
   Deshalb hier eine Lesegröße und eine Spalte, die breit genug für Wörter
   ist – auf 390 Pixeln bleibt dann genau eine übrig. */
.pruef-lage-titel{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.pruef-lage-titel dd{font-size:15px;font-weight:700;line-height:1.45}

.pruef-zahl{margin:0 0 14px;font-size:15px;color:var(--ink);font-variant-numeric:tabular-nums}
.pruef-zahl .leise{color:var(--muted)}

/* Die vier Befunde als Zeile, die beiden ersten hervorgehoben: Aus ihnen
   werden Briefe, die anderen beiden sind Buchhaltung. */
.pruef-befunde{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.pruef-befunde li{padding:8px 12px;border:1px solid var(--line);border-radius:9px;background:var(--sunk);font-size:13.5px;color:var(--muted)}
.pruef-befunde strong{display:block;font-size:19px;color:var(--ink);font-variant-numeric:tabular-nums}

/* WOMIT geprueft wird - abgesetzt vom Fortschritt darunter, weil es eine
   andere Frage beantwortet: nicht „wie weit", sondern „wer arbeitet daran".
   Die beiden Moeglichkeiten nebeneinander, damit der Kasten den Balken
   nicht nach unten aus dem Bild schiebt. */
.pruefweg{margin:0 0 18px;padding:14px 16px;border:1px solid var(--line);
  border-radius:11px;background:var(--sunk)}
.pruefweg-lage{margin:0 0 12px;color:var(--ink);font-size:14.5px}
.pruefweg-lage strong{color:var(--ink)}
.pruefweg .portal-form{gap:10px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.pruefweg .mail-toggle{background:var(--paper)}
/* DER AUSWAHLPUNKT IST EIN KREIS UND KEIN OVAL.
   Er sah lange aus wie ein liegendes Ei, und der Abstand zum Text sass schief
   dazu. Der Grund stand nicht hier, sondern an `.mail-toggle input` (in der
   langen Sammelzeile weiter oben): Dort stand `width:auto!important`, damit
   das Feld nicht die Breite eines Textfeldes bekommt. Was dabei blieb, war
   die Innenabstand-Angabe der Textfelder – 11 mal 12 Pixel. Mit
   `box-sizing:border-box` kann ein Kasten aber nicht schmaler werden als
   Innenabstand plus Rahmen: Aus den gewuenschten 20 Pixeln wurden 26 in der
   Breite und 24 in der Hoehe, und schon war es ein Oval.
   Deshalb steht dort jetzt eine feste Groesse OHNE Innenabstand, dazu
   `flex:0 0 20px`, damit er in der Reihe nicht mitschrumpft, und ein
   Aussenabstand von zwei Pixeln oben, der ihn auf die erste Textzeile setzt.
   WER DIE REGEL ANFASST, PRUEFT DREI SEITEN: Umgebung (Pruefweg), KI und
   Mailcenter-Einstellungen benutzen dieselbe Klasse. */
.pruefweg .button-row{grid-column:1/-1}
.pruefweg .field-note{margin:10px 0 0}
.pruef-befunde .befund-keine,.pruef-befunde .befund-fremd{border-color:var(--brand);background:var(--paper)}
.pruef-befunde .befund-keine strong,.pruef-befunde .befund-fremd strong{color:var(--brand)}

/* Feste Spalten fuer die Ortsblocks. Jede Gruppe ist eine eigene Tabelle -
   ohne feste Breiten rechnet jede ihre Spalten aus ihrem eigenen Inhalt aus,
   und beim Herunterrollen springt die Liste von Block zu Block. */
.tabelle-fest{table-layout:fixed;width:100%}
.tabelle-fest td{overflow-wrap:anywhere}
.tabelle-fest .sp-haken{width:38px}
.tabelle-fest .sp-betrieb{width:15%}
.tabelle-fest .sp-branche{width:9%}
.tabelle-fest .sp-anschrift{width:18%}
.tabelle-fest .sp-telefon{width:10%}
.tabelle-fest .sp-befund{width:16%}
/* Der zweite Befund: Gibt es den Betrieb noch? Breiter als „Befund", weil
   darunter die drei Knoepfe stehen, mit denen man ihn von Hand berichtigt. */
.tabelle-fest .sp-bestand{width:15%}
/* Der dritte Befund: Braucht der Betrieb ueberhaupt eine Seite? Er steht in
   derselben Breite wie der Bestand daneben - darunter haengen dieselben
   Handknoepfe. */
.tabelle-fest .sp-bedarf{width:15%}
.tabelle-fest .sp-akquise{width:7%}
.tabelle-fest .sp-brief{width:6%}

/* Ein geschlossener Betrieb faellt in der Liste auf, ein ungeklaerter nicht:
   Das eine ist eine Entscheidung, das andere eine offene Frage. */
.bestand-geschlossen{color:var(--danger-ink)}
.bestand-aktiv{color:var(--ok-ink)}
.bestand-hand{display:inline-flex;flex-wrap:wrap;gap:4px;margin-top:4px}

/* Dasselbe fuer den Website-Bedarf: „braucht keine" ist die Aussage, die
   einen Betrieb aus der Akquise nimmt - sie faellt auf, „lohnt sich" nicht. */
.bedarf-entbehrlich>summary,td.bedarf-entbehrlich{color:var(--danger-ink)}
.bedarf-noetig{color:var(--ok-ink)}
/* ZUGEKLAPPT, WEIL DAS FELD SONST IN JEDER DER FUENFHUNDERT ZEILEN STEHT.
   Der Satz gehoert dazu (ohne ihn zaehlt „entbehrlich" nicht), aber er wird
   selten gebraucht - und fuenfhundert Eingabefelder machen aus einer Liste
   ein Formular. */
.bedarf-entbehrlich{display:inline-block}
.bedarf-entbehrlich>summary{cursor:pointer;font-size:13px}
.bedarf-entbehrlich input{width:100%;margin-top:4px;padding:4px 6px;
  font-size:13px;border:1px solid var(--line);border-radius:6px}
/* Das Auswahlfeld der Sammelaktion schrumpft nicht mit, der Satz daneben
   schon: Von „braucht keine" darf kein Wort abgeschnitten werden, von einer
   langen Begruendung schon. */
.sammel-bedarf{display:inline-flex;align-items:center;gap:6px;
  white-space:nowrap;flex:0 0 auto}
.sammel-grund{flex:1 1 200px;min-width:140px;padding:6px 8px;
  border:1px solid var(--line);border-radius:8px}

/* Der Kasten, der die kurze Briefliste erklaert. Er steht ueber der Liste
   und nicht darunter: Wer sie leer sieht, hoert nach dem ersten Bildschirm
   auf zu lesen. */
.bestandskasten{margin:16px 0;padding:14px 16px;border-radius:10px;
  border:1px solid var(--line)}
.bestandskasten h3{margin:0 0 8px;font-size:16px}
.bestandskasten form{display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  margin-top:10px}

/* Die Handlung in einer Tabellenzeile - egal ob Link oder Formularknopf.
   EINE KLASSE FUER BEIDE, weil sonst nebeneinander zwei verschiedene
   Hoehen stehen: Ein <a> ist so hoch wie seine Schrift, ein
   .portal-button hat min-height 44px. In einer Tabelle mit
   zweihundertvierzig Zeilen faellt dieser Unterschied in jeder einzelnen
   auf - und zweihundertvierzig gefuellte Knoepfe waeren ohnehin zu laut
   fuer eine Liste, die man ueberfliegt. */
.zeilen-aktion{display:inline-block;padding:0;margin:0;border:0;
  background:none;color:var(--brand);font:inherit;font-weight:750;
  line-height:1.55;text-align:left;cursor:pointer}
.zeilen-aktion:hover,.zeilen-aktion:focus-visible{text-decoration:underline}
/* Schmaler Schirm: Die Tabelle rollt ohnehin in ihrem Kasten, aber unter
   760 Pixeln wird sie sonst unlesbar gequetscht. */
@media (max-width:760px){
  .tabelle-fest{min-width:720px}
}

/* Die Liste nach Orten: eine Ueberschrift je Ort, damit man eine Fahrt
   planen kann statt zweihundert Zeilen zu lesen. */
.ort-block{margin:0 0 22px}
.ort-block h3{margin:0 0 8px;font-size:16px}
.ort-block .ort-zahl{color:var(--muted);font-weight:400;font-size:14px}
.schon-post{color:var(--muted);font-size:12.5px}

.auftrag-puls{position:relative;height:4px;margin:0 0 12px;border-radius:2px;background:var(--line);overflow:hidden}
.auftrag-puls::after{content:"";position:absolute;inset:0;width:38%;border-radius:2px;background:var(--brand);animation:auftrag-puls 1.6s ease-in-out infinite}
/* Ruht der Lauf, ruht der Puls - und zwar SICHTBAR leer. Vorher stand er
   auf voller Breite mit 25 Prozent Deckkraft und sah damit aus wie ein
   Fortschrittsbalken, der bei hundert steht. */
.auftrag-puls[data-arbeitet="nein"]{opacity:.35}
.auftrag-puls[data-arbeitet="nein"]::after{animation:none;width:0}
@keyframes auftrag-puls{0%{transform:translateX(-100%)}100%{transform:translateX(264%)}}
@media (prefers-reduced-motion:reduce){.auftrag-puls::after{animation-duration:4s}}

/* Die juengste Meldung steht ueber dem Protokoll und in Lesegroesse: Sie
   ist die Antwort auf „was macht er gerade", und die soll man nicht aus
   vierzig Zeilen Kleinschrift heraussuchen muessen. */
.auftrag-jetzt{margin:0 0 8px;font-size:14px;color:var(--ink)}
.auftrag-jetzt .auftrag-regung{color:var(--muted)}
.auftrag-lauf details{margin:0 0 12px}
.auftrag-lauf summary{cursor:pointer;font-size:13px;color:var(--muted)}
.auftrag-befund{margin:16px 0;padding:18px;border:1px solid var(--line);border-left-width:5px;border-radius:12px;background:var(--paper)}
.auftrag-befund h3{margin:4px 0 12px}
.auftrag-befund>p{color:var(--ink)}
/* A trägt, B muss umgebaut, C von vorn – die Farbe sagt das vor dem Lesen. */
.befund-a{border-left-color:var(--ok-ink);background:var(--ok-bg)}
.befund-b{border-left-color:var(--signal-bernstein);background:var(--warn)}
.befund-c{border-left-color:var(--signal-rot);background:var(--danger)}
.seitenvergleich{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;margin:16px 0}
.seitenvergleich h4{margin:0 0 8px;font-size:13px;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.seitenvergleich ul{margin:0;padding-left:18px;color:var(--muted)}
.auftrag-befund details{margin-top:12px}
.auftrag-befund details summary{cursor:pointer;font-weight:750;color:var(--brand);padding:6px 0}
@media(max-width:640px){.seitenvergleich{grid-template-columns:1fr}}

/* Die Kritik: ein Urteil über einen fertigen Entwurf, kein A/B/C.
   Deshalb keine Ampelfarbe am Rand – die gehört der Sichtung und hieße hier
   etwas anderes. Der Kasten bleibt neutral, gelesen wird der Text. */
.kritik-befund{border-left-color:var(--brand)}
.kritik-liste{list-style:none;margin:12px 0;padding:0}
.kritik-liste>li{padding:12px 0;border-top:1px solid var(--line)}
.kritik-liste>li:first-child{border-top:0}
.kritik-liste h3{margin:2px 0 8px}
.kritik-liste pre{white-space:pre-wrap}
/* Was abgehakt ist, tritt zurück – offen bleibt, was noch jemanden braucht. */
.vorschlag-uebernommen,.vorschlag-verworfen{opacity:.62}

/* Projektordner: Verknüpfung und Handgriffe in einer Zeile. */
.ordnerform{display:flex;gap:8px;align-items:center;min-width:220px}
.ordnerform input{flex:1;min-width:0;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;border:1px solid var(--field-line);border-radius:8px;padding:9px 10px;background:var(--paper);color:var(--ink)}
.ordnerform .portal-button{min-height:38px;padding:0 12px;white-space:nowrap}
.ordnerknoepfe{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.ordnerknoepfe .portal-button{min-height:38px;padding:0 12px;white-space:nowrap}

/* --- Öffnen-Spalte der Entwürfe-Tabelle haengt rechts fest --------------
   Acht Spalten breit inklusive Live-Vorschau: Wer die Tabelle nach rechts
   scrollen musste, um "Nachrüsten" oder "Vollständig löschen" zu finden,
   verlor dabei den Rest der Zeile aus dem Blick. Die Spalte bleibt jetzt
   am rechten Rand stehen, während der Rest darunter durchscrollt - wie die
   Kopfzeile, nur seitwaerts. */
.tabelle-entwuerfe td.ordnerknoepfe,
.tabelle-entwuerfe th:last-child{
  position:sticky;right:0;z-index:2;background:var(--paper);
  box-shadow:-10px 0 16px -8px var(--schatten-weich);
}
.tabelle-entwuerfe tbody tr:hover td.ordnerknoepfe{background:var(--paper)}
/* Kompakter statt scrollen: kleinere Vorschau, engere Formularfelder und
   weniger Innenabstand je Zelle - dieselben Angaben, weniger Breite. Die
   sticky Öffnen-Spalte oben bleibt als Rückfalllösung für kleinere
   Bildschirme, wird aber auf gängigen Breiten nicht mehr gebraucht. */
.tabelle-entwuerfe th,.tabelle-entwuerfe td{padding:10px 8px;font-size:13px}
.tabelle-entwuerfe .entwurfsvorschau{width:120px;height:75px}
.tabelle-entwuerfe .entwurfsvorschau iframe{transform:scale(.09375)}
.tabelle-entwuerfe .ordnerform{min-width:0;max-width:170px}
.tabelle-entwuerfe .ordnerform input{font-size:11px;padding:7px 8px}
.tabelle-entwuerfe .ordnerknoepfe{gap:6px;max-width:150px}
.tabelle-entwuerfe .ordnerknoepfe .portal-button,.tabelle-entwuerfe .ordnerform .portal-button{min-height:32px;padding:0 9px;font-size:12px}
.tabelle-entwuerfe .entwurfsweg li{font-size:10px;padding:2px 6px 2px 5px}

/* Modell und Aufwand je Auftrag.
   Die Auswahlfelder standen hier einmal nackt da, weil die Fassung an einer
   Formularklasse hing und das hier eine Tabelle ist. Kanten, Radien und
   Farben kommen inzwischen aus der gemeinsamen Regel für select; die Tabelle
   sagt nur noch, dass die Felder die Spalte füllen. */
.modelltabelle{max-width:1080px;margin-inline:auto}
.modelltabelle table{table-layout:fixed}
.modelltabelle th:first-child,.modelltabelle td:first-child{width:38%}
.modelltabelle td{vertical-align:middle}
.modelltabelle td:first-child strong{display:block}
.modelltabelle td:first-child small{margin-top:2px}
.modelltabelle .button-row{margin-top:18px}
@media(max-width:760px){
  .modelltabelle table,.modelltabelle thead,.modelltabelle tbody,.modelltabelle tr,.modelltabelle td{display:block;width:auto}
  .modelltabelle thead{display:none}
  .modelltabelle tr{padding:14px 0;border-bottom:1px solid var(--line)}
  .modelltabelle td{border:0;padding:6px 0}
  .modelltabelle td:first-child{width:auto}
}

/* Die Kette: Design starten und den Work-Chat von selbst anhängen. */
.kettenlage{display:inline-flex;align-items:center;gap:7px;padding:5px 10px;border-radius:999px;background:var(--warn);color:var(--warn-ink);font-size:12px;font-weight:800}
.kettenlage.laeuft{background:var(--info-bg);color:var(--info-ink)}

/* Sichtungsstand in der Ordnerübersicht. Der Befund ist der Grund, warum man
   die Zeile ansieht – er bekommt eine eigene Spalte statt eines Anhängsels
   hinter der Domain. */
.sichtungsstand{min-width:200px}
.befundmarke{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:8px;font-weight:900;margin-bottom:4px}
.befundmarke.befund-a{background:var(--ok-bg);color:var(--ok-ink)}
.befundmarke.befund-b{background:var(--warn);color:var(--warn-ink)}
.befundmarke.befund-c{background:var(--danger);color:var(--danger-ink)}
.veraltet{color:var(--danger-ink);font-weight:750}


/* Moduswechsel im Kopf der Verwaltung. Dieselbe Kennung im Speicher wie auf
   der Website („itsk-theme"): Wer dort dunkel gewählt hat, sitzt hier nicht
   plötzlich vor Weiß. */
.theme-toggle{display:grid;place-items:center;width:40px;height:40px;padding:0;border:1px solid var(--line);border-radius:10px;background:var(--paper);color:var(--ink);cursor:pointer;font-size:17px;line-height:1}
.theme-toggle:hover{border-color:var(--brand);color:var(--brand)}
.theme-toggle .icon-moon{display:none}
:root[data-theme="dark"] .theme-toggle .icon-sun{display:none}
:root[data-theme="dark"] .theme-toggle .icon-moon{display:block}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-toggle .icon-sun{display:none}
  :root:not([data-theme="light"]) .theme-toggle .icon-moon{display:block}
}


/* Der Briefbogen bleibt Papier – in jedem Modus. Die Regel dazu steht nicht
 * mehr hier, sondern in brief-druck.css: Das Blatt setzt dort ausschließlich
 * feste Farbwerte und keine einzige Rolle (--ink, --muted). Im dunklen Modus
 * wurde --ink sonst zu #eceaf4 – und das Passwort im Zugangsblock stand weiß
 * auf weißem Papier; zu sehen war es nur, wenn man darüber wischte.
 *
 * Ein Blatt, das nur Papierfarben kennt, kann diesen Fehler nicht mehr haben.
 * Deshalb steht in brief-druck.css kein `var(--` außer dem Maßstab der
 * Vorschau – ein Test wacht darüber. */


/* Nächste Schritte: die Zahlen oben und der Weg als Kette. */
.schrittzahlen{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:18px 0}
.schrittzahl{display:grid;gap:2px;padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--paper);color:var(--ink);font-weight:400}
.schrittzahl strong{font-size:28px;letter-spacing:-.04em;line-height:1.1}
.schrittzahl span{color:var(--muted);font-size:13px}
.schrittzahl:hover{border-color:var(--brand)}
.schrittzahl.arbeit{border-color:var(--brand);background:var(--accent)}
.schrittzahl.arbeit strong{color:var(--brand)}
/* Eine Zeile je Schritt – nicht fünf Spalten nebeneinander.
   Nebeneinander sah nach Übersicht aus und war keine: Fünf Karten auf
   einer Fläche von tausend Pixeln sind Spalten von knapp zweihundert, und
   darin bricht „Was erlaubt ist, einmal lesen" in vier Zeilen um. Eine
   Einrichtungsliste ist ohnehin keine Galerie, sondern eine Abhakliste –
   und die liest man von oben nach unten. */
.schrittkette{display:grid;gap:8px;margin:16px 0 0;padding:0;list-style:none;counter-reset:schritt}
.schrittkette li{display:grid;grid-template-columns:24px minmax(0,1fr) auto;align-items:center;gap:8px 14px;padding:13px 16px;border:1px solid var(--line);border-radius:11px;background:var(--sunk);counter-increment:schritt}
.schrittkette li:before{content:counter(schritt);display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:var(--brand);color:#fff;font-size:12px;font-weight:800;font-variant-numeric:tabular-nums}
.schrittkette strong{display:block;font-size:15px}
/* Der Begleittext eines erledigten Schritts wird in der Vorlage weggelassen:
   Was getan ist, muss nicht mehr erklärt werden. */
.schrittkette small{display:block;color:var(--muted);margin-top:2px}
@media(max-width:620px){
  .schrittkette li{grid-template-columns:24px minmax(0,1fr)}
  .schrittkette li>:last-child{grid-column:2;justify-self:start}
}
@media(max-width:560px){.schrittzahlen{grid-template-columns:repeat(2,1fr)}}


/* Ein Befund ist eine Momentaufnahme. Ist er umgesetzt, muss das ÜBER dem
   Text stehen – sonst liest man „sieben fehlende Bauteile" und hält es für
   eine offene Liste, obwohl sie längst gebaut sind. */
.befund-erledigt{margin:10px 0 16px;padding:11px 14px;border-radius:9px;background:var(--ok-bg);color:var(--ok-ink);font-size:14px}
.befund-erledigt.veraltet{background:var(--warn);color:var(--warn-ink)}
.befund-erledigt strong{font-weight:850}


/* Entwurfsvorschau in der Ordnerübersicht.
   Der Rahmen zeigt eine Bildschirmbreite von 1280px, verkleinert auf ein
   Viertel: So sieht man das Layout, für das die Seite gebaut ist, und nicht
   die Handy-Fassung einer schmalen Zelle. */
.entwurfsvorschau{display:block;position:relative;width:200px;height:125px;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--sunk);text-decoration:none}
.entwurfsvorschau iframe{position:absolute;top:0;left:0;width:1280px;height:800px;border:0;transform:scale(.15625);transform-origin:0 0;pointer-events:none;background:#fff}
.entwurfsvorschau span{position:absolute;right:0;bottom:0;padding:3px 8px;border-radius:8px 0 0 0;background:var(--brand);color:#fff;font-size:11px;font-weight:800}
.entwurfsvorschau:hover{border-color:var(--brand)}

.entwurfsvorschau img{display:block;width:100%;height:100%;object-fit:cover;object-position:top center;background:#fff}

/* Vertriebspartner: der Fortschrittsbalken der Stufe.
   Er ist bewusst kräftig – er ist das Einzige auf der Seite, das „gleich
   geschafft" sagen kann, ohne eine Zahl zu nennen. */
/* Der Balken der Stufe.
   Die Breite kommt aus den fortschritt-*-Klassen weiter oben – NICHT aus
   einem style-Attribut: Die CSP verwirft Inline-Stile stillschweigend, und
   ein Balken ohne Breite füllt seinen Träger vollständig aus. Er sah damit
   bei null Kunden aus, als wäre alles erledigt. */
.stufenbalken{height:10px;border-radius:999px;background:var(--chip);overflow:hidden;margin:6px 0 14px}
.stufenbalken span{display:block;height:100%;border-radius:999px;background:var(--brand);transition:width .4s ease}
.stufenbalken span.fortschritt-0{background:transparent}

/* Die Kennzahlen brauchen Luft nach oben: Sie folgen unmittelbar auf einen
   Kasten, und ohne Abstand sah der Übergang aus wie ein Fehler im Raster. */
.metrics{margin-top:24px}
/* NICHT display:flex auf der Zelle selbst. Eine Tabellenzelle, die zur
   Flexbox wird, verliert ihre Zellennatur – der Rahmen darunter bricht mitten
   in der Zeile ab, und man sucht den Fehler in der Tabelle statt hier. Die
   Marken kommen deshalb in einen eigenen Kasten INNERHALB der Zelle. */
.wegeampel > span{display:inline-flex;margin:0 4px 4px 0;font-size:11px}

/* Der Kopf der Verwaltung: fünfzehn Punkte passen in keine Zeile.
   Auf breiten Schirmen bleibt die Leiste eine Zeile mit knappem Abstand.
   Wird es enger, ersetzt sie ein Hamburger-Knopf (siehe unten) - die
   fruehere Wischleiste sah aus wie abgeschnitten, und niemand wischt in
   einem Kopfbereich, von dem er nicht weiss, dass er wischbar ist. */
.portal-header nav{flex-wrap:nowrap;gap:16px}
.portal-header nav a{white-space:nowrap}
.portal-header{gap:18px}
.portal-brand small{white-space:nowrap}
@media(max-width:1400px){.portal-header nav{gap:13px;font-size:14px}}

/* Gruppen im Kopf. Aufgeklappt wird beim Darueberfahren UND beim
   Tastaturfokus: Ein Menue, das nur die Maus oeffnet, ist fuer den, der
   sich mit Tab durchhangelt, gar nicht da.

   Die Klappe haengt am Elternteil und nicht am Knopf, damit der Weg vom
   Knopf zur Liste ueber eine zusammenhaengende Flaeche fuehrt - eine
   Luecke dazwischen laesst sie beim Hinuntergehen zuklappen. */
.nav-gruppe{position:relative}
.nav-gruppenkopf{border:0;background:none;color:var(--brand);font:inherit;font-weight:700;cursor:pointer;padding:6px 2px;display:inline-flex;align-items:center;gap:7px;white-space:nowrap}
.nav-gruppenkopf::after{content:"";width:6px;height:6px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg) translate(-2px,-2px);opacity:.6}
.nav-klappe{position:absolute;top:100%;left:-14px;min-width:230px;display:none;flex-direction:column;padding:8px;background:var(--paper);border:1px solid var(--line);border-radius:12px;box-shadow:0 18px 34px var(--schatten-weich);z-index:20}
.nav-gruppe:hover .nav-klappe,.nav-gruppe:focus-within .nav-klappe{display:flex}
.nav-klappe a{padding:9px 11px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:12px}
.nav-klappe a:hover{background:var(--sunk)}

/* Wo man gerade steht.
   Der Kopf sah auf jeder Seite gleich aus - man wusste erst nach dem
   Lesen der Ueberschrift, wo man gelandet ist. Der aktive Punkt wird
   deshalb ausgezeichnet, UND die Gruppe, die ihn enthaelt: Sonst bliebe
   sie stumm, weil der Punkt darin zugeklappt ist. */
.portal-header nav>a[aria-current="page"],.nav-gruppe.hier>.nav-gruppenkopf{color:var(--ink);position:relative}
.portal-header nav>a[aria-current="page"]::after,.nav-gruppe.hier>.nav-gruppenkopf::before{content:"";position:absolute;left:0;right:0;bottom:-11px;height:3px;border-radius:3px;background:var(--brand)}
/* Der Pfeil des Gruppenkopfes ist selbst ein ::after - deshalb traegt der
   Balken dort ::before, sonst verdraengt eines das andere. */
.nav-klappe a[aria-current="page"]{background:var(--sunk);color:var(--ink)}
.nav-zahl{display:inline-flex;min-width:20px;height:20px;padding:0 6px;align-items:center;justify-content:center;border-radius:999px;background:var(--brand);color:#fff;font-size:11px;font-weight:800}

/* Das Hamburger-Menue. Der Knopf existiert im Markup immer, sichtbar wird
   er erst, wenn die Leiste nicht mehr passt. Aufgeklappt liegt die Liste
   als Feld unter dem Kopf - grosse Zeilen, eine je Punkt, mit Trennlinie:
   Daumenziele statt Wischleiste. */
.nav-klapp{display:none;margin-left:auto;border:1px solid var(--line);background:var(--paper);border-radius:9px;width:44px;height:44px;cursor:pointer;color:var(--ink);flex:none;align-items:center;justify-content:center}
.nav-klapp svg{display:block}
@media(max-width:1080px){
  .nav-klapp{display:inline-flex}
  /* Abmelden wandert optisch ins Klappmenue: Als freies Element brach es
     in eine zweite Kopfzeile und machte den Kopf doppelt hoch. */
  .portal-header > form{display:none}
  .portal-header nav .nav-abmelden{display:block}
  .portal-header nav{position:absolute;top:100%;left:0;right:0;display:none;flex-direction:column;gap:0;margin:0;padding:6px 18px 14px;background:var(--paper);border-bottom:1px solid var(--line);box-shadow:0 18px 34px var(--schatten-weich);
    /* Das Menü ist höher als der Bildschirm - ohne eigene Maximalhöhe und
       internen Scroll waren die unteren Punkte (KI, Server, Website)
       unerreichbar. 64px ist ungefähr der Kopf darüber. */
    max-height:calc(100dvh - 64px);overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
  .portal-header nav.offen{display:flex}
  .portal-header nav a{padding:13px 4px;white-space:normal}
  /* Der Trennstrich gehört an den ANFANG jeder Kategorie, nicht zwischen
     jeden einzelnen Punkt. So liest sich das Menue als Gruppen und nicht
     als eine lange Liste aus Strichen. Getrennt werden also die Gruppen
     und die freien Punkte (Übersicht, Website) - die Punkte INNERHALB
     einer Gruppe bleiben strichlos. */
  .portal-header nav > a,
  .portal-header nav > .nav-gruppe{border-top:1px solid var(--line)}
  .portal-header nav > *:first-child{border-top:0}
  /* Schmale Schirme: Die Gruppen klappen nicht, sie stehen offen
     untereinander. Ein Klappmenue im Klappmenue waere zwei Handgriffe
     fuer einen Punkt. */
  .nav-gruppe{position:static}
  .nav-gruppenkopf{width:100%;justify-content:flex-start;padding:14px 4px 6px;color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.09em;cursor:default}
  .nav-gruppenkopf::after{display:none}
  .nav-klappe{position:static;display:flex;min-width:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none}
  .nav-klappe a{padding:11px 4px 11px 14px;border-radius:0}
  .nav-gruppe.hier>.nav-gruppenkopf::before{display:none}
  .nav-gruppe.hier>.nav-gruppenkopf{color:var(--brand)}
  /* Der Farbmodus-Knopf rueckt neben den Hamburger statt hinter die Nav. */
  .portal-header .theme-toggle{margin-left:0}
}


/* Eingabefeld und Knopf: entweder verschmolzen oder getrennt – nicht halb.
   Verschmolzen waren sie nur in der Absicht: Das Feld holte sich seine
   Rundung aus der allgemeinen Formularregel und war rundum abgerundet,
   während der Knopf links eckig blieb. Der Übergang sah aus wie ein Fehler,
   und er war einer.

   Getrennt, weil das in jeder Breite hält: Zwei runde Formen nebeneinander
   brauchen keine Abstimmung, eine verschmolzene schon. */
.search-form{gap:10px}
.search-form input{border-radius:9px!important}
.search-form button{border-radius:9px}
/* Erledigtes tritt zurück, ohne zu verschwinden – nicht über opacity:
   ein halbdurchsichtiger Text auf gemustertem Grund wird grau UND unscharf.
   Zurückgenommen wird über die Farbe, dann bleibt die Schrift scharf. */
.schrittkette li.erledigt{background:none;border-color:var(--line)}
.schrittkette li.erledigt strong{font-weight:650;color:var(--muted)}
.schrittkette li.erledigt:before{background:var(--ok-ink)}
.schritt-fertig{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--ok-bg);color:var(--ok-ink);font-size:13px;font-weight:800}
.schritt-weg{font-size:13px;white-space:nowrap}

/* Wie weit der laufende Auftrag DIESER Zeile ist – auf „Nächste Schritte",
   in der Standspalte unter dem Stand.

   BALKEN UND TEXT SIND DIESELBEN wie auf der Vorhabenseite (.zeit-balken,
   .zeit-text): Es ist dieselbe Auskunft – „so weit ist das hier gediehen" –
   und zwei Bilder dafür wären zwei Begriffe von Fortschritt. Nur die
   Fassung ist eigen: keine Einrückung wie im Aufgabenkasten, und begrenzt
   auf gut zwanzig Zeichen Breite, damit der Balken in einer Tabellenspalte
   nicht über die ganze Zeile läuft und dabei aussieht wie eine Trennlinie. */
.schritt-zeit{margin:7px 0 0;max-width:22em}

/* Die Karte. Selbst gezeichnet, weil die CSP fremde Kartenserver aussperrt –
   und weil jeder Kachelabruf einem Dritten meldete, welche Betriebe hier
   angesehen werden. */
.kartenflaeche{position:relative;width:100%;max-width:900px;margin:0 auto;aspect-ratio:1;background:var(--sunk);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.kartenflaeche svg{display:block;width:100%;height:100%}
/* Ohne user-select markiert jedes Ziehen die Ortsnamen, und die Karte
   bleibt mit blau hinterlegten Wörtern zurück. touch-action:none übergibt
   Wischen und Kneifen an das Skript, statt die Seite zu scrollen. */
.kartenflaeche svg{cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none}
.kartenflaeche.zieht svg{cursor:grabbing}
/* Der Ring des Betriebssystems passt farblich nirgends hin und erschien
   nach jedem Klick. Abgeschaltet und im Hausstil ersetzt – aber nur für
   :focus-visible, sonst verliert die Tastaturbedienung ihre Anzeige. */
.kartenflaeche svg:focus{outline:none}
.kartenflaeche svg:focus-visible{outline:3px solid var(--brand);outline-offset:-3px}
/* KEIN transition auf cx/cy: Die Punkte folgen dem Zoom, und ein Übergang
   von 150 ms hinge dabei sichtbar hinterher. Nur der Radius darf federn –
   das ist eine Rückmeldung auf den Zeiger, keine Bewegung der Karte. */
.kartenpunkt{cursor:pointer}
.kartenpunkt circle{transition:r .12s ease}
.kartenpunkt:hover circle{r:9}
.kartenpunkt:focus{outline:none}
.kartenpunkt:focus-visible circle,.kartenpunkt.gewaehlt circle{r:9;stroke:var(--brand);stroke-width:3}
/* Der Name eines Betriebs. Erscheint erst nah genug – siehe karte.js. */
/* Der Name ist anklickbar wie der Punkt. Man klickt auf das, was man
   liest – nicht auf den Punkt daneben. */
.punktname{font-size:13px;font-weight:700;fill:var(--ink);paint-order:stroke;stroke:var(--paper);stroke-width:3.5px;dominant-baseline:middle;cursor:pointer}
.kartenwerkzeug{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:0 auto 12px;max-width:900px}
.kartenknoepfe{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:10px;background:var(--paper);overflow:hidden}
.kartenknopf{display:grid;place-items:center;min-width:38px;height:36px;padding:0;border:0;border-right:1px solid var(--line);background:none;color:var(--brand);font:inherit;font-weight:800;font-size:13px;cursor:pointer}
.kartenknopf.breit{padding:0 14px;min-width:0}
.kartenknopf:last-child{border-right:0}
.kartenknopf:hover{background:var(--sunk)}
.kartenknopf:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.ort-offen{fill:var(--muted)}
.ort-entwurf{fill:var(--brand)}
.ort-angeschrieben{fill:var(--info-ink)}
.ort-kunde{fill:var(--ok-ink)}
.ort-abgesagt{fill:var(--danger-ink);opacity:.45}
.kartenlegende{display:flex;flex-wrap:wrap;gap:16px;margin-top:16px;font-size:13px;color:var(--muted)}
.kartenlegende span{display:inline-flex;align-items:center;gap:6px}
.kartenlegende i{width:10px;height:10px;border-radius:50%;display:inline-block}
.kartenlegende i.ort-offen{background:var(--muted)}
.kartenlegende i.ort-entwurf{background:var(--brand)}
.kartenlegende i.ort-angeschrieben{background:var(--info-ink)}
.kartenlegende i.ort-kunde{background:var(--ok-ink)}
.kartenlegende i.ort-abgesagt{background:var(--danger-ink)}
.kartenlegende i.ort-umfeld{background:none;border:2px solid var(--muted)}
.kartenlegende i.ort-umfeld-ohne-seite{background:none;border:2px dashed var(--line)}

/* Betriebe aus dem Umfeld sind RINGE und keine Punkte.
   Der Unterschied muss ohne Legende lesbar sein: gefüllt heißt „gehört mir",
   offen heißt „steht da und wartet". Eine weitere Farbe hätte man neben den
   fünf Vertriebsständen nicht mehr auseinandergehalten. */
/* Mit .kartenflaeche davor, sonst gewinnt `.kartenflaeche circle` weiter
   unten per Spezifität und färbt den Ring papierweiß – auf hellem Grund
   also unsichtbar. Eine Klasse allein schlägt keine Klasse-plus-Element. */
.kartenflaeche circle.ort-umfeld{fill:var(--paper);stroke:var(--muted);stroke-width:2.6}
.kartenflaeche circle.ort-umfeld-ohne-seite{fill:var(--paper);stroke:var(--muted);stroke-width:2.2;stroke-dasharray:3.2 2.6;opacity:.65}

/* Das Menü am angeklickten Betrieb.

   Absolut zur Kartenfläche, Position aus dem Skript: Es soll dort stehen,
   wo geklickt wurde. Ein Menü am Kartenrand ist bei viertausend Punkten
   dasselbe wie gar keine Rückmeldung – man sieht es nicht. */
.kartenmenue{position:absolute;z-index:3;width:min(268px,calc(100% - 20px));background:var(--paper);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 36px var(--schatten-weich);overflow:hidden}
.kartenmenue-kopf{display:flex;align-items:flex-start;gap:8px;padding:12px 12px 10px;border-bottom:1px solid var(--line)}
.kartenmenue-kopf strong{display:block;font-size:15px;line-height:1.25}
.kartenmenue-kopf small{display:block;color:var(--muted);font-size:12px;margin-top:2px}
.kartenmenue-zu{margin-left:auto;flex:none;border:0;background:none;color:var(--muted);font-size:19px;line-height:1;cursor:pointer;padding:0 2px}
.kartenmenue-zu:hover{color:var(--ink)}
.kartenmenue-liste{display:flex;flex-direction:column;padding:6px}
.kartenmenue-liste form{display:contents}
/* Jede Tat ist eine Zeile mit Zeichen und Text – gleich hoch, gleich weit
   eingerückt, ob sie nun ein Link oder ein Formularknopf ist. */
.kartenmenue-tat{display:flex;align-items:center;gap:10px;width:100%;min-height:38px;padding:0 10px;border:0;border-radius:8px;background:none;color:var(--ink);font:inherit;font-weight:650;font-size:14px;text-align:left;cursor:pointer}
.kartenmenue-tat:hover{background:var(--sunk)}
.kartenmenue-tat.stark{color:var(--brand)}
.kartenmenue-zeichen{display:grid;place-items:center;width:22px;height:22px;flex:none;border-radius:6px;background:var(--sunk);color:var(--muted);font-size:13px;font-weight:800}
.kartenmenue-tat.stark .kartenmenue-zeichen{background:var(--brand);color:#fff}
.kartenmenue-hinweis{margin:6px 10px 8px;font-size:12px;color:var(--muted)}

/* Der Vertragsentwurf: als Blatt lesbar, nicht als Oberfläche. */
.vertragsblatt{max-width:78ch}
.vertragsblatt h3{margin-top:26px;font-size:16px}
.vertragsblatt p{margin-bottom:10px}
.vertragsblatt .unterschriften{margin-top:38px;line-height:2.2}

/* Zeilenlänge im Seitenkopf.
   Er lief über die volle Fensterbreite – auf einem breiten Bildschirm sind
   das weit über 150 Zeichen je Zeile. Das Auge verliert beim Rücksprung die
   Zeile, und der Absatz sieht aus, als begänne er links woanders als er
   rechts endet. 75 Zeichen sind die Spanne, in der man liest, ohne den
   Kopf zu bewegen. */
.page-heading p{max-width:75ch}
.panel > p,.panel > ul,.panel > ol{max-width:80ch}
.panel .field-note{max-width:80ch}

/* AUSSER DORT, WO ES KEIN FLIESSTEXT IST.
   Die Regel darüber gilt für Absätze, die man liest. Ein Panel kann aber
   auch Kästen enthalten – die Aufgabenliste eines Vorhabens, das Gespräch
   im Vorchat –, und die sind keine Zeilen, sondern Fläche: Bei 1630 px
   endeten sie in der Mitte des Fensters, und rechts daneben stand nichts.

   ÜBERSCHRIEBEN UND NICHT GELÖSCHT: Auf jeder anderen Admin-Seite bleibt
   die Lesebreite genau so, wie sie war. Die Selektoren hier tragen eine
   Klasse mehr und kommen deshalb ohne !important aus. */
.panel.panel-breit > p,.panel.panel-breit > ul,.panel.panel-breit > ol,
.panel.panel-breit > details,.panel.panel-breit > .field-note{max-width:none}
.panel > .vorchat-verlauf{max-width:none}
/* Der Text IN einem Aufgabenkasten – „Fertig, wenn" ist eine .field-note
   und wäre sonst als einziges Element im Kasten bei 80ch zu Ende. */
.aufgabe .field-note{max-width:none}

/* Die Karte bekommt Maßstab und Himmelsrichtung.
   Punkte allein sind ein Streudiagramm: Man sieht, DASS es Klumpen gibt, und
   nicht, welcher Kleve ist. */
/* Die Maße stehen in Einheiten der viewBox (1000 × 1000). Bei einer Fläche
   von rund 900 Pixeln ist eine Einheit knapp ein Pixel – die Zahlen lassen
   sich also lesen wie Pixel. Sie ändern sich beim Zoomen NICHT: Punkte und
   Schrift liegen ausserhalb der transformierten Gruppe. */
.gitterlinie{stroke:var(--line);stroke-width:1.4}
.kartenort{font-size:15px;font-weight:800;fill:var(--muted);letter-spacing:.06em;text-transform:uppercase;paint-order:stroke;stroke:var(--paper);stroke-width:4px;pointer-events:none}
.kartennorden path{fill:var(--muted)}
.kartennorden text{font-size:20px;font-weight:800;fill:var(--muted)}
.kartenmassstab path{stroke:var(--muted);stroke-width:2;fill:none}
.kartenmassstab text{font-size:14px;font-weight:750;fill:var(--muted)}
.karte-rand{pointer-events:none}
.kartenflaeche circle{stroke:var(--paper);stroke-width:2}

.umbruch{word-break:break-all;overflow-wrap:anywhere}

/* Kästchen und Schalter im Hausstil.
   Ohne appearance:none zeichnet sie das Betriebssystem – auf einem Mac in
   Systemblau. Das ist die einzige Farbe auf der Seite, die weder von der
   Marke noch vom Farbmodus kommt, und sie sticht genau deshalb heraus. */
input[type=checkbox],input[type=radio]{appearance:none;-webkit-appearance:none;flex:none;width:20px;height:20px;margin:0;display:inline-grid;place-items:center;border:1.5px solid var(--field-line);border-radius:6px;background:var(--paper);cursor:pointer;transition:background .12s ease,border-color .12s ease}
input[type=radio]{border-radius:50%}
input[type=checkbox]:hover,input[type=radio]:hover{border-color:var(--brand)}
input[type=checkbox]:checked,input[type=radio]:checked{background:var(--brand);border-color:var(--brand)}
/* Der Haken als zwei Kanten eines gedrehten Kastens – ein Zeichen aus einer
   Schriftart säße je nach Schnitt anders und wäre mal zu klein, mal daneben. */
input[type=checkbox]:checked:after{content:"";width:10px;height:5px;margin-top:-3px;border:solid #fff;border-width:0 0 2px 2px;transform:rotate(-45deg)}
input[type=radio]:checked:after{content:"";width:8px;height:8px;border-radius:50%;background:#fff}
input[type=checkbox]:focus-visible,input[type=radio]:focus-visible{outline:3px solid rgba(101,89,189,.28);outline-offset:1px}
input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed;border-color:var(--line);background:var(--sunk)}

/* Die Auswahlspalte einer Tabelle ist so breit wie ihr Kästchen.
   Ohne feste Breite verteilt die Tabelle die freie Breite gleichmäßig, und
   das leere Kopffeld wird so breit wie „Anschrift" – zwischen Kästchen und
   Betriebsname klafft dann eine Handbreit Nichts. */
th.wahl,td.wahl{width:34px;padding-right:0;vertical-align:middle}
/* Die ganze Zeile mittig, nicht nur die Kaestchen-Zelle: Die globale
   Tabellenregel setzt Zellen auf top, die Auswahlzelle stand auf middle -
   Kaestchen und Betriebsname lagen dadurch ein paar Pixel versetzt. */
tr:has(> td.wahl) td{vertical-align:middle}
td.wahl input[type=checkbox]{vertical-align:middle}

/* Eine Knopfreihe direkt unter einer Tabelle braucht Luft. Ohne sie klebt
   der Knopf an der letzten Trennlinie und sieht aus wie Teil der Zeile. */
.table-wrap+.button-row,.table-wrap+p+.button-row{margin-top:18px}

/* Das hidden-Attribut setzt display:none – aber nur aus der Vorlage des
   Browsers, und die verliert gegen jede Klasse hier. .portal-button hat
   display:inline-flex, .field-note display:block; beide zeigten sich
   trotz hidden weiter. Im Kartenfenster standen dadurch der Öffnen-Knopf,
   der Aufnehmen-Knopf und der Hinweis gleichzeitig da, obwohl sich alle
   drei gegenseitig ausschließen. */
[hidden]{display:none!important}

/* Gleiche Höhe in einer Knopfreihe.
   Ein Kästchen mit Beschriftung ist so hoch wie sein Text, ein Knopf
   44 Pixel. Nebeneinander sah das aus, als stünde die Zeile schief –
   zentriert waren sie zwar, gleich hoch aber nicht. */
/* white-space:nowrap: Ohne das brach der längere Text einer Pille in zwei
   Zeilen um, während die kürzere daneben einzeilig blieb - zwei Kästchen in
   derselben Reihe standen dann auf unterschiedlicher Höhe. Jetzt bleibt
   jede Pille einzeilig; zu wenig Platz lässt lieber die ganze Pille in die
   nächste Zeile des .button-row umbrechen (flex-wrap greift dort schon). */
/* height statt min-height, und das Kästchen fest auf 20px verankert: Ein
   min-height lässt jede Pille ihre eigene Inhaltshöhe behalten, und die
   weicht zwischen an- und abgehaktem Zustand über Browser hinweg leicht
   voneinander ab (bekannte Unstimmigkeit bei appearance:none-Kästchen in
   Flex-Zeilen). Eine feste Höhe plus box-sizing:border-box macht jede
   Pille exakt gleich groß, unabhängig vom Zustand. */
.button-row>label.checkbox,.button-row>.checkbox{box-sizing:border-box;display:inline-flex;align-items:center;gap:10px;height:44px;margin:0;padding:0 14px;border:1px solid var(--line);border-radius:9px;background:var(--paper);font-weight:650;white-space:nowrap;cursor:pointer}
.button-row>label.checkbox input,.button-row>.checkbox input{flex:none;align-self:center}
/* Die allgemeine Regel weiter unten schiebt freistehende Häkchen 3px nach
   unten (siehe dort) - in dieser Pille sitzt das Kästchen mittig zum Text
   und braucht diesen Versatz nicht. Ohne das stand das Häkchen der zweiten
   Pille ein paar Pixel tiefer als das der ersten. */
.button-row>label.checkbox input{margin-top:0}
.button-row>label.checkbox:hover{border-color:var(--brand)}
.button-row>label.checkbox:has(input:checked){border-color:var(--brand);background:var(--chip)}
/* Einwurf-Beleg in der Betriebsliste: das Dateifeld bleibt sichtbar (ein
   verstecktes required-Feld kann der Browser nicht fokussieren und meldet
   kryptische Fehler), aber kompakt. */
.einwurf-form{display:grid;gap:6px;min-width:170px}
.einwurf-form input[type=file]{width:170px;font-size:12px;color:var(--muted)}
.einwurf-form .link-button{padding:2px 0;text-align:left}

/* ---------------------------------------------------------------------
   Ziele-Seite: die Rechnung soll ziehen, nicht dokumentieren.
   Karten statt Tabelle, eine Flamme fuer die Serie, Balken mit Lauf-
   animation, Zahlen die hochzaehlen (ziele.js). Alles respektiert
   prefers-reduced-motion - wem Bewegung zusetzt, der bekommt Ruhe. */
/* Der Zaehler-Span in einer Metrik-Zahl erbt Groesse und Farbe der Zahl.
   Ohne diese Regel griffe ".portal-metrics span" (13px, block, gedaempft)
   und riss den Betrag vom Eurozeichen: "5,54" klein, darunter ein fettes
   Euro - gesehen auf dem Handy, geglaubt erst nach dem Screenshot. */
.metrics strong span,.metrics strong small{display:inline;font-size:inherit;color:inherit;font-weight:inherit}
.metrics strong small{font-size:15px;color:var(--muted)}
.panel-heading{flex-wrap:wrap}

.ziel-form{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap}
.ziel-form label{flex:1;min-width:230px;margin:0}
/* Knopf exakt auf Eingabehoehe (11px Polster + Zeile + 2px Rand = 47px) -
   vorher stand er 3px kuerzer daneben und wirkte verrutscht. */
.ziel-form .portal-button{min-height:47px}

.staffel-karten{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:16px;margin:20px 0 8px}
.staffel{position:relative;display:grid;gap:8px;align-content:start;padding:24px 22px;background:var(--paper);border:1px solid var(--line);border-radius:15px;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}
.staffel:hover{transform:translateY(-4px);border-color:var(--brand);box-shadow:0 14px 34px var(--schatten-weich)}
.staffel .briefe{font-size:12px;font-weight:850;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
.staffel .betrag{font-size:clamp(30px,3vw,42px);font-weight:850;letter-spacing:-.045em;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.05}
.staffel .betrag small{display:inline;font-size:15px;font-weight:750;color:var(--muted);letter-spacing:0}
.staffel .neben{font-size:13px;color:var(--muted)}
/* Die groesste Staffel traegt einen Feuerrand: Blick zuerst dorthin. */
.staffel.gross{border:2px solid transparent;background:linear-gradient(var(--paper),var(--paper)) padding-box,linear-gradient(130deg,#ff7a18,#ff3d54 45%,var(--brand)) border-box}
.staffel.gross:hover{box-shadow:0 16px 40px rgba(255,199,0,.28)}
/* "sofort sicher" als Glut-Pille - die einzige Stelle mit Feuerfarben
   NEBEN der Flamme, damit sicher und erwartet auch farblich zwei Dinge
   bleiben. */
.staffel-grund{font-size:12px;color:var(--muted);line-height:1.5;border-top:1px solid var(--line);padding-top:8px;margin-top:2px}
.sofort-pille{display:inline-flex;align-items:center;gap:5px;width:fit-content;padding:5px 11px;border-radius:999px;background:linear-gradient(100deg,#ff7a18,#ff3d54);color:#fff;font-size:12px;font-weight:850;box-shadow:0 4px 14px rgba(255,90,40,.35)}

.flammen-panel{display:flex;align-items:center;gap:20px;margin:6px 0 10px}
.flamme{font-size:58px;line-height:1;transform-origin:50% 88%;animation:flamme-flackern 1.5s ease-in-out infinite;filter:drop-shadow(0 8px 22px rgba(255,150,20,.5))}
/* Kalt heisst kalt: grau, still, und der Text daneben sagt, wie man sie
   anzuendet. Eine brennende Flamme ohne Serie waere gelogen. */
.flamme.kalt{animation:none;filter:grayscale(1) opacity(.4)}
.serien-zahl{display:block;font-size:clamp(30px,3vw,42px);font-weight:850;letter-spacing:-.04em;line-height:1.05;font-variant-numeric:tabular-nums}
.flammen-panel p{margin:4px 0 0}
@keyframes flamme-flackern{0%,100%{transform:scale(1) rotate(-2deg)}30%{transform:scale(1.07) rotate(2deg)}55%{transform:scale(.96) rotate(-1deg)}80%{transform:scale(1.04) rotate(1deg)}}

/* Balken: fuellt sich beim Laden, dann laeuft ein Lichtschein darueber.
   Das from{width:0} greift auf die width der fortschritt-N-Klasse. */
.stufenbalken span{position:relative;overflow:hidden;animation:balken-fuellen .9s cubic-bezier(.2,.7,.25,1)}
.stufenbalken span::after{content:"";position:absolute;inset:0;background:linear-gradient(100deg,transparent 32%,rgba(255,255,255,.38) 50%,transparent 68%);animation:balken-schimmer 2.4s ease-in-out infinite}
@keyframes balken-fuellen{from{width:0}}
@keyframes balken-schimmer{0%{transform:translateX(-110%)}55%,100%{transform:translateX(110%)}}

.rekord-puls{animation:rekord-pulsen 1.5s ease-in-out infinite}
@keyframes rekord-pulsen{50%{transform:scale(1.07)}}

@media(max-width:900px){.staffel-karten{grid-template-columns:1fr}}
@media (prefers-reduced-motion: reduce){
  .flamme,.stufenbalken span,.stufenbalken span::after,.rekord-puls,.staffel{animation:none!important;transition:none!important}
}

/* Der Ziel-Chip in der Kopfzeile: Serie und Zielstand immer im Blick,
   auch auf dem Handy neben dem Hamburger. Bewusst klein - er erinnert,
   er erklaert nicht; die Erklaerung wohnt auf der Zielseite dahinter. */
.ziel-chip{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border:1px solid var(--line);border-radius:999px;background:var(--sunk);color:var(--ink);font-weight:850;font-size:13px;flex:none;font-variant-numeric:tabular-nums}
.ziel-chip:hover{border-color:var(--brand)}
.chip-flamme{font-size:16px;line-height:1}
.chip-flamme.kalt{filter:grayscale(1) opacity(.45)}
.chip-serie{min-width:1ch}
.chip-balken{display:inline-block;width:52px;height:7px;border-radius:999px;background:var(--chip);overflow:hidden}
.chip-balken span{display:block;height:100%;border-radius:999px;background:var(--brand)}
.chip-prozent{color:var(--muted);font-size:12px;font-weight:800;white-space:nowrap}
/* Der Punkt zwischen Serie und Zielstand: ohne ihn liest sich "3" neben
   "0 %" wie "30 %". */
.chip-trenner{color:var(--muted);font-weight:400}
.nav-abmelden{display:none}
@media(max-width:640px){.chip-balken{display:none}.portal-brand span{display:none}}

/* Der Zielring: Prozent als Kreis, der sich beim Laden fuellt. pathLength
   100 macht dasharray zur Prozentangabe - als SVG-Attribut, nicht als
   style, wegen der Stilrichtlinie. Ab 90 Prozent pulsiert er: Die Naehe
   zum Ziel zieht staerker als jede Erinnerung. */
.ziel-schau{display:flex;gap:26px;align-items:center;margin:18px 0 6px;flex-wrap:wrap}
.zielring{width:132px;height:132px;flex:none}
.ring-grund{stroke:var(--chip)}
.ring-wert{stroke:var(--brand);animation:ring-fuellen 1.1s cubic-bezier(.2,.7,.25,1)}
.ring-zahl{font-size:26px;font-weight:850;fill:var(--ink);letter-spacing:-.03em}
.ring-wort{font-size:11px;font-weight:800;fill:var(--muted);text-transform:uppercase;letter-spacing:.09em}
.ziel-zahlen{flex:1;min-width:260px;margin:0}
@keyframes ring-fuellen{from{stroke-dasharray:0 100}}
.fast-da .zielring{animation:rekord-pulsen 1.6s ease-in-out infinite;transform-origin:center}

/* Das schwebende Ziel: unten rechts, klein, auf jeder Portalseite. */
.ziel-schwebe{position:fixed;right:16px;bottom:16px;z-index:40;background:var(--paper);border:1px solid var(--line);border-radius:14px;box-shadow:0 14px 38px var(--schatten-weich)}
.ziel-schwebe a{display:flex;align-items:center;gap:10px;padding:12px 38px 12px 14px;color:var(--ink)}
.ziel-schwebe .chip-flamme{font-size:24px}
.schwebe-text{display:grid;line-height:1.25}
.schwebe-text strong{font-size:14px}
.schwebe-text small{color:var(--muted);font-size:12px}
.schwebe-zu{position:absolute;top:4px;right:4px;width:26px;height:26px;border:0;border-radius:50%;background:none;color:var(--muted);font-size:15px;cursor:pointer;line-height:1}
.schwebe-zu:hover{background:var(--sunk);color:var(--ink)}
@media(max-width:640px){.ziel-schwebe{right:10px;bottom:10px}.ziel-schwebe a{padding:10px 34px 10px 12px}}
@media (prefers-reduced-motion: reduce){.ring-wert,.fast-da .zielring{animation:none!important}}

/* Meldungen schweben oben mittig statt im Seitenfluss: Die Seite springt
   nach dem Absenden nicht mehr nach oben, nichts schiebt den Inhalt weg.
   Herunterfahren, kurz stehen, verschwinden - Fehler bleiben, bis sie
   jemand anklickt (meldungen.js). */
.flash-stack{position:fixed;top:14px;left:50%;transform:translateX(-50%);z-index:60;display:grid;gap:8px;width:min(560px,calc(100vw - 24px));margin:0}
.flash-stack .flash{box-shadow:0 14px 38px var(--schatten-weich);cursor:pointer;animation:meldung-rein .35s cubic-bezier(.2,.7,.25,1)}
.flash-weg{opacity:0;transform:translateY(-14px);transition:opacity .3s ease,transform .3s ease}
@keyframes meldung-rein{from{opacity:0;transform:translateY(-18px)}}
@media (prefers-reduced-motion: reduce){.flash-stack .flash{animation:none}.flash-weg{transition:none}}

/* Die Live-Kamera beim Abgabe-Nachweis. Klein gehalten: Sie sitzt in einer
   Tabellenzelle und darf die Zeile nicht sprengen. */
.kamerafeld{display:grid;gap:8px;margin-top:6px}
.kamerafeld video{width:100%;max-width:260px;border-radius:10px;background:#000}

/* Das Notizfenster - geht direkt nach der Abgabe auf. Bewusst schmal und
   kurz: Es fragt eine Sache und hat einen sichtbaren Weg hinaus. */
.notizfenster{width:min(460px,calc(100vw - 32px));padding:0;border:1px solid var(--line);border-radius:16px;background:var(--paper);color:var(--ink);box-shadow:0 24px 60px var(--schatten-weich)}
.notizfenster::backdrop{background:rgba(8,10,18,.55)}
.notizfenster form{display:grid;gap:12px;padding:clamp(20px,4vw,28px)}
.notizfenster h2{margin:0;font-size:21px}
.notizfenster p{margin:0;font-size:14px}
.notizfenster textarea{width:100%;font:inherit;background:var(--sunk);color:var(--ink);border:1px solid var(--field-line);border-radius:10px;padding:10px}
.notizfenster audio{width:100%}
.notizfenster [data-memo-stand]{min-height:16px}
.notizzeile audio{width:100%;max-width:240px}
.notizzeile{padding:6px 0;border-bottom:1px solid var(--line)}
.notizzeile p{margin:2px 0;color:var(--ink);font-size:13px}
.einwurf-form input[name=grund_auswahl]{width:100%;font:inherit;background:var(--paper);color:var(--ink);border:1px solid var(--field-line);border-radius:8px;padding:7px 9px;font-size:13px}

/* --- Kopfleiste: alles auf einer Hoehe (nav-gleiche-hoehe) --------------
   Die Leiste mischt zwei Sorten Punkte: schlichte Links (<a>) und Gruppen
   mit Klappe (<div><button>). Der Knopf bringt padding:6px mit, der Link
   hatte keins - und weil nav ein Flex-Behaelter ohne align-items ist, also
   "stretch", begann der Linktext ganz oben im gestreckten Kasten und der
   Knopftext sechs Pixel darunter. Sichtbar war das als Treppe: "Uebersicht"
   stand hoeher als "Kunden".

   Zwei Dinge beheben das: die Punkte mittig ausrichten UND beiden Sorten
   dasselbe Innenmass geben. Nur das Innenmass anzugleichen reicht nicht -
   dann sitzen sie zwar gleich, aber weiterhin oben statt in der Mitte.

   Ausdruecklich nur ab 1081px: Darunter ist die Leiste ein aufklappendes
   Menue in Spaltenrichtung. Dort wuerde align-items:center die Punkte
   waagerecht zentrieren, statt sie linksbuendig zu lassen. */
@media (min-width:1081px){
  .portal-header nav{align-items:center}
  .portal-header nav>a,.portal-header nav>.nav-gruppe>.nav-gruppenkopf{
    display:inline-flex;align-items:center;padding:6px 2px;line-height:1.25}
}

/* Antrag annehmen oder verwerfen stehen in derselben Zelle. Zwei
   Formulare sind zwei Bloecke - ohne diese Regel steht "Verwerfen"
   unter dem Knopf und die Zeile wird doppelt so hoch. */
.antrag-annehmen,.antrag-verwerfen{display:inline-block;vertical-align:middle}
.antrag-verwerfen{margin-left:14px}
/* Der Statusschalter steht unter dem Einladen-Knopf, nicht daneben. */
.helfer-schalter{margin-top:8px}

/* ── Dashboard-Posteingang ──────────────────────────────────────────────
   Alles, was wartet, auf einer Fläche. Jede Zeile ist ein Link zum Ziel;
   ein schmaler Farbstreifen links und ein Art-Etikett sagen auf einen Blick,
   worum es geht und wie dringend. Farben kommen aus den vorhandenen Tokens,
   also stimmen sie hell wie dunkel. */
.metric-warn{border-color:var(--warn-line)!important;background:var(--warn)!important}
.metric-warn strong{color:var(--warn-ink)}

.posteingang{padding:0;overflow:hidden;margin-bottom:24px}
.posteingang .panel-heading{padding:20px 24px;border-bottom:1px solid var(--line)}
.pe-summe{font-size:13px;font-weight:700;color:var(--brand-dark);
  background:var(--accent);padding:4px 11px;border-radius:999px;white-space:nowrap}

.pe-liste{list-style:none;margin:0;padding:0}
.pe-zeile{border-bottom:1px solid var(--line);border-left:3px solid transparent}
.pe-zeile:last-child{border-bottom:0}
.pe-zeile.ton-hoch{border-left-color:var(--danger-ink)}
.pe-zeile.ton-mittel{border-left-color:var(--brand)}
.pe-zeile.ton-ruhig{border-left-color:var(--line)}
.pe-ziel{display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:14px;padding:13px 24px;color:var(--ink);text-decoration:none}
.pe-ziel:hover{background:var(--sunk)}

.pe-art{font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  padding:4px 9px;border-radius:7px;white-space:nowrap;min-width:92px;text-align:center;
  background:var(--sunk);color:var(--muted)}
.ton-hoch .pe-art{background:var(--danger);color:var(--danger-ink)}
.ton-mittel .pe-art{background:var(--accent);color:var(--brand-dark)}

.pe-mitte{min-width:0}
.pe-titel{display:block;font-size:15px;font-weight:600;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pe-unter{display:block;font-size:12.5px;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.pe-wann{font-size:12.5px;color:var(--muted);white-space:nowrap}
.pe-mehr{padding:12px 24px 16px;margin:0}

.pe-leer{padding:34px 24px;text-align:center}
.pe-leer strong{display:block;font-size:16px;color:var(--ink)}
.pe-leer span{display:block;margin-top:4px;color:var(--muted);font-size:14px}

/* Zwei Spalten für „Zuletzt bearbeitet" und „Neueste Kunden". */
.dashboard-spalten{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);
  gap:22px;margin-bottom:24px}
.dashboard-spalten .panel{margin:0}

/* Ein Raster dehnt seine Felder standardmäßig auf gleiche Höhe. Steht links
   „Nichts offen" und rechts eine lange Liste, wird die leere Karte genauso
   hoch wie die volle – ein Meter Leere, durch den man scrollen muss. Mit
   start ist jede Karte so hoch wie ihr Inhalt. */
.dashboard-spalten.nach_inhalt{align-items:start}

/* Ein Panel direkt vor dem Raster hatte keinen Abstand: .panel+.panel greift
   nicht, weil dazwischen ein div steht. Die Karten klebten aneinander. */
.panel+.dashboard-spalten{margin-top:18px}

/* Das Terminal der Fernsteuerung. Hoch genug, dass eine Claude-Sitzung
   hineinpasst, ohne dass man im Rahmen scrollen muss; der dunkle Grund ist
   der von ttyd, damit beim Laden nichts weiß aufblitzt. */
.fern-rahmen{margin-top:16px;border:1px solid var(--line);border-radius:11px;
  overflow:hidden;background:#1e1e1e}
.fern-rahmen iframe{display:block;width:100%;height:min(70vh,620px);border:0}
@media (max-width:700px){
  .fern-rahmen iframe{height:min(60vh,420px)}
}

/* Das Gitter der Terminals.
 *
 * ZWEI NEBENEINANDER, UND EIN EINZELNES NIMMT DIE GANZE BREITE. Der Grund
 * ist nicht Geschmack: Claude Code malt seine Oberflaeche in die Breite,
 * die es bekommt. Ein einzelnes Terminal in einer halben Spalte haette
 * neben sich eine leere Haelfte und in sich eine schmale Saeule Text.
 *
 * ":last-child:nth-child(odd)" trifft genau die letzte Kachel, wenn ihre
 * Anzahl ungerade ist - drei Kacheln heisst also zwei oben, eine breite
 * darunter.
 *
 * SCHMAL UNTEREINANDER: Zwei Terminals auf einem Telefon sind zwei
 * unbenutzbare Terminals. */
.fern-gitter{display:grid;gap:14px;margin-top:16px;
  grid-template-columns:repeat(2,minmax(0,1fr))}
.fern-gitter>.fern-kachel:last-child:nth-child(odd){grid-column:1/-1}
@media (max-width:1000px){
  .fern-gitter{grid-template-columns:minmax(0,1fr)}
}
.fern-kachel{display:flex;flex-direction:column;min-width:0;
  border:1px solid var(--line);border-radius:11px;overflow:hidden;
  background:var(--sunk)}
.fern-kachel-kopf{display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:9px 13px;border-bottom:1px solid var(--line);
  background:var(--paper)}
.fern-kachel-wer{min-width:0;font-size:13px;overflow-wrap:anywhere}
.fern-kachel-wer strong{font-size:14px;font-weight:750}
.fern-kachel-projekt{font-weight:650}
.fern-kachel-kopf form{margin:0}
/* Schliessen und beenden nebeneinander - und sie sehen bewusst nicht
   gleich aus. Das eine betrifft die Ansicht, das andere loescht Arbeit. */
.fern-kachel-taten{display:flex;align-items:center;gap:12px;flex:none}
.link-button.gefahr{color:var(--danger-ink)}
/* Die Frist verlaengern - ein Wort neben dem Zustand, kein Knopf. */
.fern-frist{margin:0}
.fern-frist .link-button{font-size:12px}
/* Die Restzeit laeuft im Sekundentakt. Tabellenziffern, weil die Anzeige
   sonst bei jeder Sekunde ein Stueck breiter und schmaler wird und alles
   daneben mitzuckt. */
[data-restzeit]{font-variant-numeric:tabular-nums}
/* UNTER ZEHN MINUTEN. Bis dahin steht die Zahl gruen da wie jeder andere
   Zustand; ab hier soll sie stoeren. Der Puls ist absichtlich langsam - er
   faellt im Augenwinkel auf, ohne beim Lesen zu flackern. */
[data-restzeit].warnt{background:var(--danger);color:var(--danger-ink);
  animation:fern-puls 2.4s ease-in-out infinite}
@keyframes fern-puls{50%{opacity:.55}}
/* Der Kasten mit dem Knopf. Er steht zwischen Kopfzeile und Gitter, also
   ueber den Rahmen und nicht darunter - weiter unten wuerde er von einem
   Terminal verdeckt, das die halbe Seite fuellt. */
.fern-warnung{margin:16px 0 0;padding:16px;border-radius:10px;
  background:var(--danger);border:1px solid var(--danger-line);
  display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.fern-warnung[hidden]{display:none}
.fern-warnung strong{font-size:17px;color:var(--danger-ink);
  font-variant-numeric:tabular-nums}
/* DER SATZ, AUF DEN ES ANKOMMT: Zu geht der Tunnel, nicht die Arbeit. Er
   nimmt die Breite zwischen Zeit und Knopf und darf ruhig umbrechen. */
.fern-warnung p{margin:0;flex:1 1 320px;color:var(--danger-ink);
  font-size:13px}
.fern-warnung form{margin:0;flex:0 0 auto}
@media(prefers-reduced-motion:reduce){
  [data-restzeit].warnt{animation:none}
}
/* Der dunkle Grund ist der von ttyd, damit beim Laden nichts weiss
   aufblitzt. Zwei nebeneinander sind schmaler als eines allein - also
   duerfen sie hoeher sein, sonst steht in jedem nur ein Briefmarkenbild. */
.fern-kachel iframe{display:block;width:100%;height:min(64vh,560px);border:0;
  background:#1e1e1e}
.fern-kachel .field-note{margin:0;padding:16px}
/* Eine Kachel, deren tmux-Sitzung erst entsteht. Sie steht schon im
   Gitter - sonst spraenge das Bild, sobald sie fertig ist. */
.fern-kachel.wird-angelegt{border-style:dashed}

/* Die Blockueberschriften in der Chatliste: Projekte, Websites, Ohne
   Projekt. Klein und leise - sie ordnen, sie kuendigen nichts an. */
.chat-gruppe{margin:18px 0 8px;font-size:12px;font-weight:750;
  color:var(--muted);text-transform:uppercase;letter-spacing:.08em}
.chat-gruppe .status{margin-left:8px;vertical-align:1px}
/* Was geschlossen wurde, steht leiser da als was laeuft. */
.verlauf-liste li{background:transparent}

/* Auswahl und Knopf. Rahmen, Rundung und Farbe des Auswahlfeldes kommen aus
   der gemeinsamen Regel für select; hier steht nur, wie breit es ist und was
   die Umgebung ihm sonst hineinvererben würde. */
.fern-start{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;
  margin:20px 0 4px}
.fern-start label{display:grid;gap:6px;font-weight:750;font-size:12px;
  color:var(--muted);text-transform:uppercase;letter-spacing:.08em}
/* Die Beschriftung darüber steht in Versalien mit Sperrung - ohne diese
   Zeile liefe beides in das Feld hinein. */
.fern-start select{min-width:220px;
  font-weight:600;letter-spacing:normal;text-transform:none}
/* Das Namensfeld fuer ein neues Projekt. Dieselbe Gestalt wie die
   Auswahl daneben - sonst stehen in einer Zeile zwei Felder, die nach
   zwei verschiedenen Formularen aussehen. */
.fern-start input[type=text]{min-width:220px;min-height:44px;font:inherit;
  font-weight:600;letter-spacing:normal;text-transform:none;
  color:var(--ink);background:var(--paper);
  border:1px solid var(--field-line);border-radius:9px;padding:0 12px}
.fern-start input[type=text]:focus{outline:3px solid rgba(101,89,189,.16);
  border-color:var(--brand)}

/* Die Erklärung als drei kurze Punkte statt als Absatzwand unter dem Knopf.
   Abgesetzt durch eine Haarlinie, damit der Knopf Luft behält. */
.fern-fakten{list-style:none;margin:22px 0 0;padding:16px 0 0;
  border-top:1px solid var(--line);display:grid;gap:10px;max-width:78ch}
.fern-fakten li{color:var(--muted);font-size:13px;line-height:1.55}
.fern-fakten strong{color:var(--ink);font-weight:750}

/* Der Abstand muss stehen, egal ob ein oder zwei Spalten. Ohne eigene
   Klasse griff bei einer Spalte keine der beiden Regeln – .panel+.panel
   nicht (ein div dazwischen), .panel+.dashboard-spalten auch nicht (die
   Klasse fehlte dann). Die Karten klebten aneinander. */
.auftraege-block{margin-top:18px}

/* Die laufenden Chats. Je Zeile: was es ist, wo es liegt, und der Weg
   hinein. Kein Tabellengerüst – es sind selten mehr als eine Handvoll. */
.chat-liste{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:8px}
.chat-liste li{display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;padding:13px 16px;background:var(--sunk);
  border:1px solid var(--line);border-radius:10px}
.chat-liste strong{font-size:14.5px;font-weight:700}
.chat-liste small{display:block;color:var(--muted);font-size:12px;
  margin-top:2px;overflow-wrap:anywhere}
.chat-liste form{margin:0}
.chat-liste .portal-button{min-height:38px;padding:0 15px}
/* Einsteigen und beenden nebeneinander – wie in der Kachel oben, damit der
   gefaehrliche der beiden ueberall gleich aussieht und gleich steht. */
.chat-taten{display:flex;align-items:center;gap:12px;flex:none}

/* ── Rueckfragen ─────────────────────────────────────────────────────────
   DIE MASSE STEHEN NICHT NACH GEFUEHL HIER, sondern sind die der uebrigen
   Tafeln: 16px Innenabstand waagerecht und 13px senkrecht wie .chat-liste
   li, 12px zwischen den Karten wie .button-row, 16px zwischen den
   Abschnitten wie ein Absatz. Vorher standen im Markup drei verschiedene
   Randmasse als style="" - und die kamen nie an: Die Content-Security-
   Policy dieses Portals erlaubt kein 'unsafe-inline' fuer Stil, der Browser
   verwarf sie stumm. Was aussah wie eine Geschmacksfrage, war eine Regel,
   die nie gegolten hat. Deshalb steht ab hier alles in dieser Datei. */

/* Die Karten sind schmaler als die Tafel - 80ch, wie jeder Fliesstext hier.
   Eine Frage im Wortlaut ueber 1400px zu ziehen liest niemand. */
.rf-liste{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:12px;
  max-width:80ch}

/* EIN RASTER STATT RAENDERN AN DEN KINDERN: So ist der Abstand zwischen
   Kopf, Frage, Balken und Fuss ueberall derselbe - egal, welche Teile eine
   Karte gerade hat. Genau daran hing die Ungleichheit vorher: Jede Zeile
   brachte ihren eigenen Rand mit. */
.rf-karte{display:grid;gap:8px;padding:13px 16px;background:var(--sunk);
  border:1px solid var(--line);border-radius:10px}
.rf-karte>*{margin:0}

/* Der Name und der Chip auf EINER Linie. Vorher hing der Chip an einem
   vertical-align von Hand - das haelt, solange niemand die Schriftgroesse
   anfasst. Eine Flex-Reihe haelt immer. */
.rf-kopf{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  min-height:27px}
.rf-kopf strong{font-size:14.5px;font-weight:700;line-height:1.3}
.rf-wann{color:var(--muted);font-size:12px;margin-left:auto}

.rf-frage{color:var(--ink);font-size:13px;line-height:1.5;
  white-space:pre-wrap;overflow-wrap:anywhere}
.rf-antwort,.rf-grund,.rf-abgehakt{color:var(--muted);font-size:12px;
  line-height:1.5;overflow-wrap:anywhere}
.rf-antwort code{font-size:11.5px}
.rf-grund{color:var(--danger-ink)}
.rf-ordner{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:11.5px;color:var(--muted);overflow-wrap:anywhere}
/* Der Knopf traegt seinen eigenen Innenabstand von 8px. Ohne das
   Zuruecknehmen auf allen Seiten stuende er 8px tiefer, 8px weiter rechts
   und 8px zu hoch ueber dem Rand als jede andere Zeile der Karte - der
   Abstand saehe doppelt so gross aus wie ueberall sonst. */
.rf-tat{margin:-8px 0 -8px -8px}

/* WARTET AUF DICH: keine Nachlese, sondern offene Arbeit - dort steht
   gerade eine Sitzung still. */
.rf-karte.wartet{border-color:var(--danger-ink);background:var(--danger)}
.rf-karte.laeuft{border-color:var(--brand)}
.rf-karte.haengt{border-color:var(--warn-line);background:var(--warn)}

/* Der Fortschritt. Drei Schritte, ein Balken, und beides sagt dasselbe -
   der Balken auf einen Blick, die Woerter fuer den zweiten. */
.rf-fortschritt{display:grid;gap:7px}
.rf-balken{position:relative;height:6px;border-radius:999px;
  background:var(--field-line);overflow:hidden}
.rf-balken>span{display:block;height:100%;border-radius:999px;
  background:var(--brand);transition:width .45s ease}
.rf-balken.schritt-1>span{width:18%}
.rf-balken.schritt-2>span{width:62%}
.rf-balken.schritt-3>span{width:100%}
/* DAS WANDERNDE LICHT IST DIE EIGENTLICHE AUSKUNFT: Es sagt „es bewegt
   sich" auch dann, wenn der Schritt eine Minute lang derselbe bleibt.
   Bleibt es stehen, haengt es - und genau das ist die Frage davor. */
.rf-balken.rennt::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.45),
    transparent);animation:rf-lauf 1.6s linear infinite}
@keyframes rf-lauf{from{transform:translateX(-100%)}
  to{transform:translateX(100%)}}
.rf-karte.haengt .rf-balken>span{background:var(--warn-ink)}

.rf-schritte{list-style:none;margin:0;padding:0;display:flex;gap:16px;
  flex-wrap:wrap;font-size:11.5px;line-height:1.4;color:var(--muted)}
.rf-schritte li::before{content:"";display:inline-block;width:6px;height:6px;
  margin-right:6px;border-radius:50%;background:var(--field-line)}
.rf-schritte li.fertig{color:var(--ink)}
.rf-schritte li.fertig::before{background:var(--brand)}
.rf-schritte li.jetzt{color:var(--brand);font-weight:800}
.rf-schritte li.jetzt::before{background:var(--brand);
  box-shadow:0 0 0 3px var(--accent)}
/* STEHENGEBLIEBEN. Derselbe Schritt, aber in der Farbe der Warnung und
   ohne den Ring: Er ist nicht der, der gerade geschieht, sondern der,
   bei dem es aufgehoert hat. Vorher stand er fett in der Hausfarbe da -
   neben einem Chip, der "ruehrt sich nicht" sagte. */
.rf-schritte li.steht{color:var(--warn-ink);font-weight:800}
.rf-schritte li.steht::before{background:var(--warn-ink)}

/* Die Ablage. Was aus den Sitzungen herauskommt - am Telefon der einzige
   Weg an eine Datei. DER NAME IST DER KNOPF: Ein zweiter Knopf "laden"
   daneben waere eine Spalte mehr auf einem Bildschirm, der ohnehin nur
   drei Zoll breit ist. */
.ablage-liste{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:0}
.ablage-zeile{display:flex;align-items:flex-start;gap:12px;
  justify-content:space-between;padding:12px 0;
  border-top:1px solid var(--line)}
.ablage-zeile:last-child{border-bottom:1px solid var(--line)}
.ablage-wer{display:flex;flex-direction:column;gap:3px;min-width:0}
.ablage-name{font-weight:750;word-break:break-word}
.ablage-wer small{color:var(--muted);font-size:12px;display:flex;
  flex-wrap:wrap;gap:6px;align-items:baseline}
.ablage-wozu{margin:2px 0 0;font-size:13px;color:var(--muted);
  max-width:70ch}
/* Die Uhrzeit traegt die Unterscheidung - deshalb steht sie nicht so
   blass da wie der Rest der Zeile, und ihre Ziffern stehen untereinander:
   Zwei Zeiten uebereinander sind so auf einen Blick zu vergleichen. */
.ablage-wann{color:var(--ink);font-variant-numeric:tabular-nums}
.ablage-weg{flex:0 0 auto}

/* Der Merker, der sagt, ob ein Chat gerade arbeitet. Er wird im Betrieb
   beschrieben statt ausgetauscht - deshalb braucht er nichts weiter als
   die Zusicherung, dass er verschwindet, wenn niemand etwas weiss. */
.chat-status[hidden]{display:none}

/* Der Verlauf. Zugeklappt eine Zeile, aufgeklappt dieselben Karten. */
.rf-verlauf{margin:0 0 16px;max-width:80ch}
.rf-verlauf>summary{display:flex;align-items:center;gap:8px;
  padding:10px 12px;border:1px solid var(--line);border-radius:10px;
  background:var(--sunk);color:var(--muted);font-size:12px;font-weight:750;
  letter-spacing:.04em;cursor:pointer;list-style:none}
.rf-verlauf>summary::-webkit-details-marker{display:none}
.rf-verlauf>summary::before{content:"▸";color:var(--brand);font-weight:900}
.rf-verlauf[open]>summary::before{content:"▾"}
.rf-verlauf[open]>summary{margin-bottom:12px}
.rf-verlauf .rf-liste{margin:0}

/* Der Fuss: Schalter und Regeln. 16px darueber wie zwischen zwei Absaetzen,
   12px zwischen Knopf und Text wie in jeder .button-row. */
.rf-fuss{display:grid;gap:12px;max-width:80ch}
.rf-fuss .field-note{margin:0}
.rf-schalter{margin:0}

.rf-warnung{max-width:80ch;margin:0 0 16px;padding:12px 14px;
  border:1px solid var(--warn-line);border-radius:10px;background:var(--warn);
  color:var(--warn-ink);font-size:13px;line-height:1.5}
.rf-warnung strong{font-weight:800}

/* ── Nichts offen: eine Zeile ────────────────────────────────────────────
   Ein leeres Panel mit Erklaertext ist Platzverschwendung. Hier steht dann
   nur noch, DASS nichts offen ist - und ein Klick holt den Rest zurueck. */
.rueckfragen.ruhig{padding:14px clamp(20px,2.2vw,32px)}
.rf-zeile{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  cursor:pointer;list-style:none}
.rf-zeile::-webkit-details-marker{display:none}
.rf-zeile h2{margin:0;font-size:19px;letter-spacing:-.02em}
.rf-ruhe{color:var(--muted);font-size:13px}
.rf-zeile-verlauf{margin-left:auto;color:var(--brand);font-size:12px;
  font-weight:750}
/* Der Pfeil braucht Luft: In content wird ein fuehrendes Leerzeichen
   zusammengefaltet, und dann klebt er am Wort. */
.rf-zeile-verlauf::after{content:"▸";margin-left:5px}
.rueckfragen.ruhig[open] .rf-zeile-verlauf::after{content:"▾"}
.rf-aufgeklappt{margin-top:16px;padding-top:16px;
  border-top:1px solid var(--line)}

/* Ein Hinweis NEBEN einem Knopf, nicht darunter. In einer Flex-Reihe wird
   jedes Kind zum Block - das alte display:inline war folgenlos. Gefehlt hat
   die Breite: ohne sie zieht der Satz sich ueber die ganze Tafel und der
   Knopf steht verloren am linken Rand. */
.button-row.abgesetzt{margin-top:14px}
.field-note.daneben{flex:1 1 320px;max-width:62ch;margin:0}

/* Bild in den Chat reichen. Eine Zeile unter dem Terminal, kein Formular
   mit eigenem Rahmen – es gehört zum Chat, nicht daneben. */
.fern-bild{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;
  margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
.fern-bild label{display:grid;gap:6px;font-weight:750;font-size:12px;
  color:var(--muted);text-transform:uppercase;letter-spacing:.08em}
.fern-bild-text{flex:1;min-width:240px}
/* In welches Terminal das Bild geht. Nur da, wenn es mehr als eines gibt -
   eine Auswahl mit einem Eintrag ist eine Frage ohne Antwortmoeglichkeit. */
.fern-bild-ziel select{min-width:170px;
  font-weight:600;letter-spacing:normal;text-transform:none}
.fern-bild input[type=text]{width:100%;min-height:44px;font:inherit;
  letter-spacing:normal;text-transform:none;color:var(--ink);
  background:var(--paper);border:1px solid var(--field-line);
  border-radius:9px;padding:0 12px}
.fern-bild input[type=file]{font:inherit;font-size:13px;letter-spacing:normal;
  text-transform:none;color:var(--ink);max-width:260px}
.fern-bild input[type=text]:focus{outline:3px solid rgba(101,89,189,.16);
  border-color:var(--brand)}

/* Wo das Terminal gerade hängt – die Zeile über dem Rahmen. */
.fern-wo{margin:16px 0 0;color:var(--muted);font-size:13px}
.fern-wo strong{color:var(--ink)}

/* Nimmt eine Kurzliste die volle Breite ein, wird sie sonst zu einer langen
   dünnen Spalte mit viel Luft rechts. Zwei Spalten füllen die Fläche. */
.kunden-kurz.zweispaltig{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:32px}
.kunden-kurz.zweispaltig li:nth-child(2){border-top:0}
@media (max-width:820px){
  .kunden-kurz.zweispaltig{grid-template-columns:1fr}
  .kunden-kurz.zweispaltig li:nth-child(2){border-top:1px solid var(--line)}
}

.kunden-kurz{list-style:none;margin:0;padding:0}
.kunden-kurz li{border-top:1px solid var(--line)}
.kunden-kurz li:first-child{border-top:0}
.kunden-kurz a{display:grid;grid-template-columns:1fr auto;align-items:baseline;
  gap:6px 12px;padding:11px 0;color:var(--ink);text-decoration:none}
.kunden-kurz a:hover strong{color:var(--brand-dark)}
.kunden-kurz strong{font-size:14.5px;font-weight:600}
.kunden-kurz small{grid-column:1;color:var(--muted);font-size:12.5px}

@media (max-width:1000px){
  .dashboard-spalten{grid-template-columns:1fr}
}
@media (max-width:560px){
  .pe-ziel{grid-template-columns:1fr auto;gap:4px 12px;padding:12px 16px}
  .pe-art{grid-row:1;grid-column:1;min-width:0;justify-self:start}
  .pe-wann{grid-row:1;grid-column:2;justify-self:end}
  .pe-mitte{grid-column:1 / -1}
}
/* Befehle zum Abtippen oder Kopieren: dunkel, feste Breite, umbruchsicher. */
.copy-block{background:var(--sunk);border:1px solid var(--line);border-radius:10px;
  padding:14px 16px;overflow-x:auto;margin:14px 0}
.copy-block code{font:400 13px/1.7 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:var(--ink);white-space:pre}

/* Ein Läufer, der hinter dem Portal zurückhängt. Deutlich, aber kein
   Alarm – es ist ein Hinweis, kein Ausfall. */
.veraltet{color:var(--warn-ink)}
.hinweis-veraltet{margin-top:18px;padding:16px 18px;background:var(--warn);
  border:1px solid var(--warn-line);border-radius:11px}
.hinweis-veraltet strong{display:block;color:var(--warn-ink);margin-bottom:6px}
.hinweis-veraltet p{color:var(--warn-ink);font-size:13px;margin-bottom:12px}
.hinweis-veraltet .copy-block{margin:0}

/* Das native Dateifeld sieht in jedem Browser anders und überall schlecht
   aus. Es bleibt bedienbar – Tastatur und Vorlesehilfen finden es weiter –,
   wird aber vom Etikett verdeckt, das wie ein Knopf aussieht. */
.fern-bild-datei{position:relative;display:inline-flex}
.fern-bild-datei input[type=file]{position:absolute;inset:0;width:100%;
  height:100%;opacity:0;cursor:pointer}
.fern-bild-datei label{pointer-events:none}
.fern-bild-datei input[type=file]:focus-visible+label{outline:3px solid
  rgba(101,89,189,.35);outline-offset:2px}

.fern-bild-name{flex-basis:100%;margin:2px 0 0;color:var(--muted);
  font-size:12.5px}
.fern-bild-name.hat-bild{color:var(--ink);font-weight:650}
.fern-bild kbd{display:inline-block;padding:1px 6px;border-radius:5px;
  border:1px solid var(--line);background:var(--sunk);font:inherit;
  font-size:11.5px;font-weight:700}
.fern-bild.zieht{border-color:var(--brand);
  box-shadow:inset 0 0 0 2px rgba(101,89,189,.25)}

/* Welcher Chat ist das? Der Name allein ist der Projektname – wer mehrere
   Chats zum selben Projekt hat, erkennt sie erst am Ordner und daran, was
   darin läuft. Trennstriche halten die Angaben auseinander. */
.chat-wer{min-width:0}
.chat-wer .status{margin-left:8px;vertical-align:2px}
.chat-trenner{color:var(--field-line);padding:0 5px}
.chat-ordner{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:11.5px}
.chat-programm{font-weight:700;color:var(--brand)}
.chat-liste li.ist-offen{border-color:var(--brand);background:var(--accent)}

/* Rechner, die kein Läufer mehr sein sollen. Klein am Fuß der Tafel: Die
   Sperre muss auffindbar bleiben (sonst sucht jemand stundenlang, warum
   ein Rechner sich nicht meldet), aber sie ist keine Nachricht, die
   jemanden beim Öffnen der Seite anspringen soll. */
.stillgelegte{margin-top:18px;padding-top:14px;border-top:1px solid var(--line)}
.stillgelegte>strong{display:block;margin-bottom:8px;color:var(--muted);
  font-size:12px;font-weight:750;letter-spacing:.08em;text-transform:uppercase}
.stillgelegte ul{list-style:none;margin:0 0 10px;padding:0;display:grid;gap:6px}
.stillgelegte li{display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap}
.stillgelegte small{display:block;color:var(--muted);font-size:12px;margin-top:2px}
.stillgelegte form{margin:0}

/* Die Tat am Zeilenende – rechtsbündig und leise, damit sie nicht mit den
   Angaben daneben um Aufmerksamkeit ringt. */
.zeilen-tat{text-align:right;white-space:nowrap}
.zeilen-tat form{margin:0}

/* ── Die Tastenreihe unter dem Terminal ──────────────────────────────────
 *
 * WOFUER: Claude Code wird mit Esc, Tab, Umschalt+Tab und den Pfeilen
 * bedient. Auf einer Bildschirmtastatur steht davon nichts. Ohne diese
 * Reihe ist das Terminal unterwegs eine Ansicht und keine Bedienung.
 *
 * VERBORGEN, BIS DAS SKRIPT DA IST: Die Knoepfe wirken nur, wenn
 * fern-tasten.js laeuft - es setzt die Klasse an der Wurzel. Geschaltet
 * wird dort und nicht an der Reihe selbst, weil das Gitter Kacheln im
 * Betrieb austauscht und eine frisch eingesetzte Reihe sonst verborgen
 * bliebe.
 *
 * EINE ZEILE, DIE SEITWAERTS SCROLLT statt umzubrechen: Zwei Reihen
 * Knoepfe unter einem Terminal sind auf einem Telefon der halbe Bildschirm.
 */
.fern-tasten{display:none}
.tasten-bereit .fern-tasten{display:flex;gap:6px;padding:7px 9px;
  border-top:1px solid var(--line);background:var(--paper);
  overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:thin}
.fern-tasten button{flex:none;min-width:42px;min-height:38px;padding:0 10px;
  border:1px solid var(--field-line);border-radius:8px;background:var(--sunk);
  color:var(--ink);font:inherit;font-size:14px;font-weight:700;cursor:pointer;
  /* Ein Knopf, der sich beim Wischen markieren laesst, wird beim Scrollen
     der Reihe zur blauen Flaeche. */
  user-select:none;-webkit-user-select:none;
  /* Ohne das legt iOS beim Antippen ein graues Rechteck darueber. */
  -webkit-tap-highlight-color:transparent}
.fern-tasten button.gefahr{color:var(--danger-ink);margin-left:auto}
/* Getroffen: ein kurzes Aufleuchten. Ohne Rueckmeldung weiss auf einem
   Telefon niemand, ob der Druck angekommen ist - der Rahmen daneben
   aendert sich bei Esc oft um kein Pixel. */
.fern-tasten button.getroffen{background:var(--brand);color:#fff;
  border-color:var(--brand)}
/* Danebengegangen: Der Rahmen hat die Taste nicht angenommen. Das muss
   man sehen, sonst drueckt jemand dreimal Esc und haelt das Terminal
   fuer eingefroren. */
.fern-tasten button.danebengegangen{background:var(--danger);
  color:var(--danger-ink);border-color:var(--danger)}

/* ── Kein Hineinzoomen beim Antippen ─────────────────────────────────────
 *
 * WAS PASSIERT IST: Safari auf dem iPhone zoomt beim Antippen in jedes
 * Eingabefeld, dessen Schrift kleiner als 16px ist - und zoomt danach
 * nicht wieder heraus. Die Grundschrift dieser Seite ist 15px, die Felder
 * erben sie: Ein Tippen ins Textfeld, und die Seite stand fuer den Rest
 * des Besuchs schief und halb abgeschnitten da.
 *
 * DIE ANTWORT IST NICHT "maximum-scale=1". Das verbietet auch das
 * absichtliche Zoomen - wer schlecht sieht, kann die Seite dann gar nicht
 * mehr vergroessern. Es genuegt, den Feldern auf Zeigegeraeten ohne
 * Maus 16px zu geben; dann sieht Safari keinen Grund mehr.
 *
 * NUR SCHRIFTGROESSE, sonst nichts: Kein Rahmen, keine Farbe, keine
 * Abstaende - was die Felder sonst ausmacht, steht anderswo und soll
 * dort bleiben. */
@media (pointer:coarse){
  input:not([type=checkbox]):not([type=radio]):not([type=range]),
  select,textarea{font-size:16px}
}


/* Wie weit ist der Entwurf? Vier Stationen und das Urteil des Waechters.
   Die Farben kommen aus den Rollen, nicht aus festen Werten - sonst leuchtet
   die Marke im dunklen Modus weiss (siehe Kopf dieser Datei). */
.entwurfsstand{min-width:210px}
.entwurfsmarke{display:inline-block;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:800;background:var(--chip);color:var(--chip-ink)}
.entwurfsmarke.ew-steht{background:var(--ok-bg);color:var(--ok-ink)}
.entwurfsmarke.ew-fehler{background:var(--danger);color:var(--danger-ink)}
.entwurfsmarke.ew-gebaut,.entwurfsmarke.ew-ausgerollt{background:var(--warn);color:var(--warn-ink)}
.entwurfsmarke.ew-beantragt{background:var(--info-bg);color:var(--info-ink)}
.entwurfsweg{display:flex;flex-wrap:wrap;gap:4px;margin:8px 0 4px;padding:0;list-style:none;counter-reset:none}
.entwurfsweg li{display:flex;align-items:center;gap:5px;padding:2px 8px 2px 6px;border:1px solid var(--line);border-radius:999px;background:var(--sunk);color:var(--muted);font-size:11px;font-weight:700}
/* Der Punkt vorne traegt die Aussage, nicht die Farbe des Textes allein:
   Wer Rot und Gruen nicht unterscheidet, liest sonst viermal dasselbe. */
.entwurfsweg li:before{content:"○";font-size:10px}
.entwurfsweg li.ew-fertig{border-color:var(--ok-ink);background:var(--ok-bg);color:var(--ok-ink)}
.entwurfsweg li.ew-fertig:before{content:"✓"}
.entwurfsweg li.ew-laeuft{border-color:var(--warn-line);background:var(--warn);color:var(--warn-ink)}
.entwurfsweg li.ew-laeuft:before{content:"◐"}
.entwurfsweg li.ew-fehler{border-color:var(--signal-rot);background:var(--danger);color:var(--danger-ink)}
.entwurfsweg li.ew-fehler:before{content:"✕"}
.entwurfsstand .wartet-lange{color:var(--warn-ink)}
/* "warten" ist der Normalfall bei einem frischen Entwurf und braucht keine
   eigene Farbe - erst "löschen vorschlagen" soll aus der Zeile herausstechen,
   sonst wirkt jede Zeile wie ein Alarm. */
.entwurf-empfehlung{display:block;color:var(--muted)}
.entwurf-empfehlung.entwurf-empfehlung-loeschen{color:var(--danger-ink);font-weight:700}

/* Dieselben vier Stationen noch einmal als Zahl - einmal je Zeile, einmal
   oben als Mittelwert. Marken lassen sich nicht mitteln, Prozente schon. */
.entwurfsprozent{margin-left:8px;font-size:12px;font-weight:800;color:var(--muted)}
.fortschrittsbalken{margin:6px 0;height:10px;border-radius:999px;background:var(--sunk);overflow:hidden}
.fortschrittsbalken.schmal{height:5px;margin:5px 0 0}
.fortschrittsbalken>span{display:block;height:100%;border-radius:999px;background:var(--ok-ink)}
.fortschritt-zahlen{display:flex;flex-wrap:wrap;gap:10px 22px;margin:0 0 10px;padding:0;list-style:none}
.fortschritt-zahlen li{display:flex;align-items:baseline;gap:6px}
.fortschritt-zahlen strong{font-size:22px;font-weight:800}
.fortschritt-zahlen span{color:var(--muted);font-size:13px}
.laeuft-jetzt,.naechste-schritte{margin:6px 0;padding:0;list-style:none}
.laeuft-jetzt li,.naechste-schritte li{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:6px 0;border-bottom:1px solid var(--line)}
.laeuft-jetzt li:last-child,.naechste-schritte li:last-child{border-bottom:none}
.laeuft-jetzt .ablauf{color:var(--muted);font-size:13px}
.laeuft-jetzt .prozent{font-weight:800;font-size:13px}
.laeuft-jetzt small{color:var(--muted)}
.ordner-frage{margin-top:10px;padding:10px 12px;border:1px solid var(--warn-line);border-radius:10px;background:var(--warn);color:var(--warn-ink)}
.ordner-frage ul{margin:6px 0;padding-left:18px}
.ordner-frage code{overflow-wrap:anywhere;font-size:12px}
.ordner-frage small{color:inherit}
@media(max-width:900px){.entwurfsstand{min-width:170px}}

/* --- Entwürfe im Mailcenter ----------------------------------------------
   Eine Zeile wie im Posteingang, aber mit zwei Bedienelementen: Der Verweis
   führt ins Schreibfenster, der Knopf verwirft. Ein Knopf INNERHALB eines
   Verweises ist auf dem Handy ein Glücksspiel – deshalb liegen sie
   nebeneinander und die Zeile selbst ist kein Link. */
.entwurfszeile{grid-template-columns:minmax(0,1fr) auto auto;gap:16px}
.entwurfszeile .entwurf-oeffnen{display:grid;grid-template-columns:minmax(170px,.8fr) minmax(240px,2fr);gap:16px;align-items:center;min-width:0;color:var(--ink);font-weight:400}
.entwurfszeile .entwurf-oeffnen:hover strong{color:var(--brand)}
.entwurf-stand{white-space:nowrap}
.entwurfszeile form{margin:0}
@media (max-width:900px){
  .entwurfszeile{grid-template-columns:1fr auto}
  .entwurfszeile .entwurf-oeffnen{grid-template-columns:1fr;gap:4px}
  .entwurf-stand{grid-column:1}
}

/* --- Briefwechsel auf der Kundenseite ------------------------------------
   Dieselbe Zeile wie im Posteingang, nur mit einem Pfeil vorn statt eines
   Punktes: Die Richtung ist hier die wichtigste Angabe, und „von" gegen „an"
   sind beim Überfliegen zwei Buchstaben Unterschied. */
.briefwechsel{padding:0;overflow:hidden}
.briefwechsel .panel-heading{padding:24px 26px;border-bottom:1px solid var(--line)}
.briefzeile{grid-template-columns:26px minmax(0,3fr) minmax(120px,.6fr)}
.brief-richtung{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;font-weight:900;font-size:13px;line-height:1}
.brief-richtung.ein{background:var(--info-bg);color:var(--info-ink)}
.brief-richtung.aus{background:var(--chip);color:var(--chip-ink)}
@media (max-width:700px){
  .briefzeile{grid-template-columns:26px minmax(0,1fr)}
  .briefzeile .mail-date{grid-column:2;text-align:left}
}

/* --- Aktionsvorschlag im Angebotsformular --------------------------------
   Er schlaegt vor und traegt nicht ein: Wer aus gutem Grund ein Angebot
   ohne Rabatt macht, muesste sonst erst etwas loeschen - und ein Feld, das
   man loeschen muss, wird irgendwann uebersehen.

   Nicht ".aktion-hinweis": Den Namen gibt es schon, fuer die Kleinschrift
   unter einer Angebotsvariante. */
.aktionsvorschlag{display:grid;gap:10px;justify-items:start;margin:0 0 18px;padding:14px 16px;border:1px solid var(--warn-line);border-left:4px solid var(--signal-bernstein);border-radius:0 10px 10px 0;background:var(--warn);color:var(--warn-ink)}
.aktionsvorschlag p{margin:0;color:inherit}
.aktionsvorschlag .field-note{color:inherit;opacity:.85}

/* --- Umkreissuche: Karte, Vorschläge, Abruflage ------------------------- */

/* Die Karte ist absichtlich hoch genug, dass ein Kreis über hundert
   Kilometer noch hineinpasst, ohne dass man scrollen muss. */
.umkreis-karte{position:relative;height:340px;margin:4px 0 6px;
  border:1px solid var(--line);border-radius:10px;overflow:hidden;
  background:var(--sunk);cursor:grab;touch-action:none;
  /* Die Kacheln sind fremde Bilder. Ohne diese Sperre zieht der Browser
     beim Schieben das Bild statt der Karte. */
  user-select:none}
.umkreis-karte:active{cursor:grabbing}
.umkreis-kacheln{position:absolute;inset:0}
.umkreis-kacheln img{position:absolute;width:256px;height:256px;
  pointer-events:none;display:block}

/* Der Kreis zeigt den Umkreis maßstabsgetreu - er ist die Antwort auf
   „was hole ich mir damit eigentlich". */
.umkreis-kreis{position:absolute;border:2px solid var(--brand);
  border-radius:50%;background:color-mix(in srgb, var(--brand) 12%, transparent);
  pointer-events:none}
.umkreis-nadel{position:absolute;width:10px;height:10px;margin:-5px 0 0 -5px;
  border-radius:50%;background:var(--brand);
  box-shadow:0 0 0 2px var(--paper);pointer-events:none}

/* Die Vorschlagsliste hängt unter dem Feld und deckt, was darunter liegt -
   deshalb eine eigene Ebene und ein deckender Hintergrund. */
.ort-feld{position:relative}
.ort-vorschlaege{position:absolute;z-index:20;left:0;right:0;top:100%;
  margin:2px 0 0;padding:4px;list-style:none;max-height:280px;overflow-y:auto;
  background:var(--paper);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,.18)}
.ort-vorschlaege li{margin:0}
.ort-vorschlaege button{display:block;width:100%;text-align:left;
  padding:7px 9px;border:0;border-radius:7px;background:transparent;
  color:var(--ink);cursor:pointer;font:inherit}
.ort-vorschlaege button:hover,.ort-vorschlaege button:focus-visible{
  background:var(--accent)}
.ort-vorschlaege strong{display:block;font-size:.95rem}
.ort-vorschlaege span{display:block;font-size:.8rem;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.abruf-lage{margin-top:14px}
.abruf-lage form{margin-top:8px}

/* ZWEI ZUSTAENDE OHNE BALKEN, und das mit Absicht: Wer wartet, hat keinen
   Fortschritt, sondern einen Platz in der Schlange; wer eine einzige Kachel
   abarbeitet, hat nichts zu zaehlen. Ein Balken auf null saehe an beiden
   Stellen aus wie einer, der nicht funktioniert. */
.abruf-wartet,.abruf-arbeitet{margin:0 0 4px;padding:9px 12px;
  border-radius:9px;border:1px solid var(--line);font-size:.9rem}
.abruf-wartet{color:var(--muted)}
.abruf-arbeitet{background:var(--accent);color:var(--ink)}
.abruf-wartet strong,.abruf-arbeitet strong{display:block;
  font-size:.78rem;letter-spacing:.06em;text-transform:uppercase}
.abruf-lage .field-note{margin:0;font-variant-numeric:tabular-nums}

/* Angehalten ist ein eigener Zustand und muss auch so aussehen - sonst
   sieht eine pausierte Prüfung genauso aus wie eine kaputte. */
.pruef-pause{margin:10px 0 4px;padding:9px 12px;border-radius:9px;
  background:var(--accent);border:1px solid var(--line);
  color:var(--ink);font-size:.9rem}

/* Die Warteschlange der Umgebungsabrufe. Der laufende steht oben und ist
   hervorgehoben - ohne das sucht man in einer Liste von fünf Städten, an
   welcher gerade gearbeitet wird. */
.abruf-schlange{list-style:none;margin:12px 0 4px;padding:0;
  border:1px solid var(--line);border-radius:10px;overflow:hidden}
.abruf-schlange li{display:flex;align-items:center;gap:10px;
  padding:8px 12px;border-top:1px solid var(--line);font-size:.9rem}
.abruf-schlange li:first-child{border-top:0}
.abruf-schlange li.jetzt{background:var(--accent);font-weight:600}
.abruf-schlange .ort{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.abruf-schlange .weite{flex:0 0 auto;color:var(--muted);
  font-variant-numeric:tabular-nums}
.abruf-schlange .lage{flex:0 0 auto;color:var(--muted)}
.abruf-schlange form{flex:0 0 auto;margin:0}

/* Ein ausgefallener Dienst ist keine Randnotiz: Dort wurde weder
   eingelesen noch aufgeräumt, und das Gebiet ist unvollständig. */
.warnung{color:var(--warn-ink)}

/* Die Begründung neben der Modellwahl. Schmal gehalten: Sie erklärt, sie
   ist nicht die Hauptsache. */
.modelltabelle .modellgrund{max-width:34ch;color:var(--muted);
  font-size:.82rem;line-height:1.45}

/* --- Der Vorchat --------------------------------------------------------- */

/* DER VERLAUF IST EIN GESPRÄCH UND KEINE LISTE.
   Vorher stand hier eine nummerierte Aufzählung – die las sich wie ein
   Formular, das man ausfüllt, und genau so wurde sie benutzt. Wer sehen
   soll, dass ihm geantwortet wird, muss die beiden Seiten unterscheiden
   können: der eigene Satz rechts angeschlagen, die Antwort links. */
.vorchat-verlauf{list-style:none;margin:0 0 18px;padding:0;
  display:flex;flex-direction:column;gap:10px}
/* DIE BLASE NIMMT DIE BREITE, DIE DA IST.
   Hier stand max-width:min(56ch,88%). Bei 1600 px Fensterbreite brach ein
   Satz von zwölf Wörtern dreimal um, während rechts daneben nichts stand –
   56 Zeichen sind eine Spalte und keine Nachricht. Ein Rest bleibt trotzdem
   frei: Daran, dass eine Blase nicht ganz bis zur Kante reicht, sieht man
   im Vorbeirollen, ob sie rechts oder links angeschlagen ist – und genau
   das sagt, wer spricht. */
.vorchat-verlauf > li{display:flex;flex-direction:column;gap:4px;
  min-width:0;max-width:90%;padding:10px 13px;border-radius:12px;
  border:1px solid var(--line)}
.vorchat-verlauf .von-mensch{align-self:flex-end;
  background:rgba(101,89,189,.09);border-color:rgba(101,89,189,.28)}
.vorchat-verlauf .von-chat{align-self:flex-start;background:var(--card)}
.vorchat-verlauf .wer{font-size:.74rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);font-weight:750}
.vorchat-verlauf .was{min-width:0}
.vorchat-verlauf .vorchat-text{white-space:pre-wrap;overflow-wrap:anywhere}
.vorchat-verlauf > li > form{margin:0;align-self:flex-end}
/* WAS AUS DIESER NACHRICHT GEWORDEN IST – klein und am Rand der Blase.
   Sie beantwortet die Frage, mit der man den Verlauf liest („steht das
   schon in einer Aufgabe?"), und sie darf den Satz darüber nicht
   überschreien: kleiner Text, keine Fläche, nur die Farbe unterscheidet.
   „Wartet noch" ist die auffälligere von beiden – das ist der Zustand,
   wegen dessen jemand nachsieht. */
.vorchat-marke{align-self:flex-end;font-size:.72rem;letter-spacing:.03em;
  font-weight:650;color:var(--muted)}
.vorchat-marke.marke-wartet{color:var(--brand)}
.vorchat-anhang{display:inline-flex;gap:7px;align-items:baseline;
  font-weight:650}
.vorchat-anhang .leise{font-weight:400;font-size:.85rem;color:var(--muted)}

/* SECHS BILDSCHIRMFOTOS SIND EIN VORGANG UND NICHT SECHS NACHRICHTEN.
   Sie standen als sechs Blasen untereinander, in denen jeweils nur ein
   Dateiname und eine Grösse stand. Jetzt eine Blase, je Datei eine Zeile –
   Name und Grösse bleiben lesbar, und beim Sammeln lässt sich jede
   einzeln entfernen. */
.anhang-buendel{display:flex;flex-direction:column;gap:2px}
.anhang-zeile{display:flex;gap:10px;align-items:baseline;min-width:0}
.anhang-zeile .vorchat-anhang{flex:1 1 auto;min-width:0;
  overflow-wrap:anywhere}
.anhang-zeile form{flex:0 0 auto;margin:0}

/* LANGE NACHRICHTEN KLAPPEN ZU – OHNE JAVASCRIPT.
   Ein Anliegen von dreissig Zeilen drückte alles Übrige aus dem Bild. Der
   Text steht deshalb im <summary> und nicht im Rumpf: Ein <details> zeigt
   von seinem Inhalt nichts, solange es zu ist, vom Summary aber alles –
   also wird dort abgeschnitten und beim Aufklappen freigegeben. Die Seite
   hat eine Inhaltssicherheitsrichtlinie mit nonce; ein eingestreutes
   Skript liefe hier ohnehin nicht. */
.vorchat-lang > summary{display:block;cursor:pointer;list-style:none}
.vorchat-lang > summary::-webkit-details-marker{display:none}
.vorchat-lang:not([open]) .vorchat-text{display:-webkit-box;
  -webkit-box-orient:vertical;-webkit-line-clamp:12;line-clamp:12;
  overflow:hidden}
.vorchat-lang .mehr{display:inline-block;margin-top:6px;color:var(--brand);
  font-weight:750;font-size:.85rem}
.vorchat-lang:not([open]) .mehr-auf,.vorchat-lang[open] .mehr-zu{display:none}

/* DER GRIFF ÜBER DEM SCHON VERPLANTEN. Er steht an beiden Stellen, an
   denen das Gespräch auftaucht: im Vorchat auf /admin/worker, wo offen
   nur bleibt, was noch nicht in Aufgaben zerlegt ist – und unter „Woraus
   das entstanden ist", dem längsten Abschnitt der Vorhabensseite, der
   ganz zugeklappt liegt. */
.verlauf-frueher{margin:0 0 12px}
.verlauf-frueher > summary{cursor:pointer;color:var(--brand);
  font-weight:750;font-size:.9rem;margin-bottom:10px}

/* AM TELEFON IST DIE BREITE DAS GANZE FENSTER. Bei rund 390 px bleibt von
   90 % zu wenig übrig; die Richtung erkennt man dort an der Farbe. */
@media(max-width:640px){
  .vorchat-verlauf > li{max-width:97%}
  .anhang-zeile{flex-wrap:wrap;gap:0 10px}
}

/* Die Sicht auf den Lauf – die Zeile, die das Terminal ersetzt. Sie ist
   eine Auskunft und keine Überschrift: eine Zeile, umbruchfähig, und die
   Meldung darin darf lang sein, ohne den Kasten zu sprengen. */
.vorchat-sicht{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;
  margin:0 0 16px;padding:10px 13px;border-radius:10px;
  background:var(--card);border:1px solid var(--line)}
.vorchat-sicht .vorchat-meldung{flex:1 1 240px;color:var(--muted);
  font-size:.9rem;min-width:0;overflow-wrap:anywhere}
/* WIE WEIT DIE ZERLEGUNG IST – eine Angabe, kein Satzteil: Sie steht
   neben dem, was der Lauf gerade meldet, und darf nicht mit ihm
   verschwimmen. Tabellenziffern, damit die Zeile beim Nachladen nicht
   bei jeder Minute zappelt. */
.vorchat-sicht .vorchat-zerlegung{flex:0 0 auto;font-size:.85rem;
  font-weight:650;font-variant-numeric:tabular-nums}
.vorchat-form fieldset{margin:14px 0 0}

.vorchat-eingaben{list-style:decimal;margin:0 0 16px;padding-left:22px}
.vorchat-eingaben li{display:flex;gap:12px;align-items:flex-start;
  padding:8px 0;border-bottom:1px solid var(--line)}
.vorchat-eingaben li:last-child{border-bottom:0}
.vorchat-eingaben .was{flex:1 1 auto;white-space:pre-wrap}
.vorchat-eingaben form{flex:0 0 auto;margin:0}

/* EIN BLOCK JE VORHABEN, NICHT EINE ZEILE. Als Flexzeile teilten sich
   Titel, Projekt, Statuschip und Zahl die Breite: Im halbbreiten Fenster
   blieb dem Titel eine Spalte von wenigen Wörtern, und er brach mitten im
   Wort um, während rechts daneben Platz frei stand. Jetzt bekommt der
   Titel seine eigene Zeile über die volle Breite, das Beiwerk steht
   darunter. */
.vorhaben-liste{list-style:none;margin:0;padding:0}
.vorhaben-liste li{padding:10px 0;border-bottom:1px solid var(--line)}
.vorhaben-liste li:last-child{border-bottom:0}
/* SO LANG WIE ER IST - und ein Titel ohne Leerzeichen (eine URL, ein
   Dateiname) bricht trotzdem, statt das Panel aufzuschieben. */
.vorhaben-liste .vorhaben-titel{display:block;overflow-wrap:anywhere}
.vorhaben-liste .vorhaben-meta{display:flex;flex-wrap:wrap;align-items:center;
  gap:4px 10px;margin:4px 0 0}
.vorhaben-liste .status,.vorhaben-liste .leise{color:var(--muted);
  font-size:.85rem}
/* DERSELBE BALKEN WIE AUF DER VORHABENSEITE, nur flacher und mit der Zahl
   daneben statt darunter - Farbe und Fuellung kommen unveraendert aus
   .pruef-balken. Wird das Fenster schmal, rutscht die Zahl unter den
   Balken, statt ihn aus dem Panel zu schieben. */
.vorhaben-liste .vorhaben-fortschritt{display:flex;flex-wrap:wrap;
  align-items:center;gap:4px 10px;margin:7px 0 0}
.vorhaben-liste .pruef-balken{flex:1 1 140px;min-width:0;height:6px;
  margin:0;border-radius:3px}
.vorhaben-liste .pruef-zahl{flex:0 0 auto;margin:0;font-size:.85rem}

/* DAS ABGESCHLOSSENE LIEGT ZU – und die Zahl steht im Kopf, damit man
   nicht aufmachen muss, um zu wissen, ob sich das Aufmachen lohnt. */
/* DIESELBE ZEILENBREITE WIE DIE LISTEN DARUEBER: Die holen sich ihre
   80ch aus „.panel > ul"; das Archiv steht im <details> und ist deshalb
   kein direktes Kind mehr. Ohne diese Zeile stünden dieselben Zeilen im
   Archiv doppelt so breit wie über ihm. */
.vorhaben-archiv{margin-top:12px;max-width:80ch}
.vorhaben-archiv > summary{cursor:pointer;color:var(--brand);
  font-weight:750;padding:6px 0}
.vorhaben-archiv[open] > summary{margin-bottom:6px}
.vorhaben-archiv > summary .status{margin-left:6px}

/* Eine Zeile Wahl mit Erklärung daneben - ohne das steht ein Häkchen da
   und niemand weiß, was es anrichtet.
   AUF .portal-form GEHOBEN, weil das Formular zwei Regeln mitbringt, die
   hier genau das kaputtmachen: .portal-form label{display:grid} stellte
   Kästchen und Text übereinander, und .portal-form input{width:100%;
   padding:11px 12px;border:1px solid} blies das Häkchen zum gerahmten
   Feld auf. Beide haben (0,1,1); die Selektoren hier liegen mit (0,2,0)
   bzw. (0,3,1) darüber und kommen deshalb ohne !important aus. */
.portal-form .wahlzeile{display:flex;gap:10px;align-items:flex-start;
  margin:0 0 10px;font-weight:400;cursor:pointer}

/* GEZEICHNET STATT NUR ZURÜCKGESETZT: Sobald irgendeine Autorenregel
   Rand oder Fläche einer Checkbox anfasst - und .portal-form input tut
   das - malt der Browser das Kästchen nicht mehr selbst. Ein blosses
   „border:0;background:none" ergab im Hellen ein weisses Häkchen auf
   Weiss, also gar nichts. Darum das Kästchen hier vollständig: Rahmen im
   Ungehakten, gefüllt mit dem Knopfton samt weissem Haken im Gehakten -
   in beiden Farbschemata sichtbar. */
.portal-form .wahlzeile input[type=checkbox]{appearance:none;
  -webkit-appearance:none;flex:0 0 auto;width:18px;height:18px;
  margin:2px 0 0;padding:0;border:1px solid var(--field-line);
  border-radius:5px;background:var(--paper);cursor:pointer}
.portal-form .wahlzeile input[type=checkbox]:checked{
  border-color:var(--knopf-bg);
  background:var(--knopf-bg)
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-6'/%3E%3C/svg%3E")
    center/12px 12px no-repeat}
.portal-form .wahlzeile input[type=checkbox]:focus-visible{
  outline:2px solid var(--brand);outline-offset:2px}
.wahlzeile span{flex:1 1 auto;font-size:.92rem;color:var(--muted)}
.wahlzeile strong{color:var(--ink)}

/* Die Aufgabenliste. Der Zustand steht links als Farbe: Wer eine Liste von
   dreissig überfliegt, liest keine Wörter, sondern sucht die eine Zeile,
   die anders aussieht. */
.aufgabenliste{list-style:none;margin:0;padding:0;counter-reset:aufgabe}
.aufgabe{padding:12px 14px;margin:0 0 8px;border:1px solid var(--line);
  border-left:4px solid var(--line);border-radius:10px;background:var(--paper)}
.aufgabe.stand-laeuft{border-left-color:var(--brand);background:var(--accent)}
.aufgabe.stand-fertig{border-left-color:var(--ok-ink)}
.aufgabe.stand-fehler{border-left-color:var(--danger-ink)}
.aufgabe.stand-uebersprungen{opacity:.55}
.aufgabe.abschluss{border-style:dashed}
.aufgabe .kopf{display:flex;gap:10px;align-items:baseline}
.aufgabe .nummer{flex:0 0 auto;min-width:1.6em;color:var(--muted);
  font-variant-numeric:tabular-nums}
.aufgabe .kopf strong{flex:1 1 auto}
.aufgabe .kopf .status{flex:0 0 auto;color:var(--muted);font-size:.82rem}
.aufgabe .beschreibung{margin:6px 0 0 2.3em;font-size:.92rem}
.aufgabe .ergebnis{margin:8px 0 0 2.3em;padding:8px 10px;border-radius:8px;
  background:var(--sunk);font-size:.88rem;white-space:pre-wrap}
/* AUF DEN EINEN KLAPPER GENAU: „Prompt ansehen und ändern" ist ein Griff
   MIT Beschriftung und steht eingerückt unter dem Kasten. Der Klapper um
   den Kasten herum (siehe unten) ist keiner von dieser Sorte - unqualifi-
   ziert als .aufgabe summary hätte er dessen Farbe und Fettung geerbt. */
.aufgabe .prompt-aendern{margin:8px 0 0 2.3em}
.aufgabe .prompt-aendern > summary{cursor:pointer;color:var(--brand);
  font-weight:750;font-size:.88rem}
.aufgabe textarea{font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}

/* WAS DURCH IST, STEHT ZUGEKLAPPT DA - ohne JavaScript.
   Zwanzig erledigte Aufgaben sind zwanzig Abschlussberichte, an denen
   vorbeigerollt werden muss, bevor jemand sieht, wo das Vorhaben steht.
   Fertig und übersprungen zeigen deshalb nur Kopfzeile, zwei Zeilen zum
   Anlesen und die Zeitzeile; läuft, offen und gescheitert bleiben offen.
   Welche das sind, entscheidet die Vorlage über das open-Attribut - hier
   steht nur, wie es aussieht.

   DER GANZE KOPF IST DER GRIFF: Ein Dreieck von zehn Pixeln trifft am
   Telefon niemand, eine Zeile über die volle Breite schon. Der eigene
   Pfeil ersetzt die Voreinstellung des Browsers, weil das <summary> hier
   zwei Zeilen hoch ist und die Marke sonst irgendwo dazwischen hinge. */
.aufgabe .aufgabe-klapp{margin:0}
.aufgabe .aufgabe-klapp > summary{display:block;cursor:pointer;
  list-style:none;color:inherit;font-weight:inherit;font-size:inherit}
.aufgabe .aufgabe-klapp > summary::-webkit-details-marker{display:none}
.aufgabe .aufgabe-klapp > summary:focus-visible{outline:2px solid var(--brand);
  outline-offset:3px;border-radius:8px}
/* Ein Pfeil und kein Wort: „mehr" neben „fertig" wären zwei Zustände in
   einer Zeile, und man liest dort nur einen. */
.klapp-pfeil{flex:0 0 auto;color:var(--brand);font-size:.8rem;line-height:1;
  transition:transform .15s ease}
.klapp-pfeil::before{content:"\25B8"}
.aufgabe-klapp[open] .klapp-pfeil{transform:rotate(90deg)}

/* HÖCHSTENS ZWEI ZEILEN, UND ZWAR IM BROWSER ABGESCHNITTEN. Eine
   Zeichenzahl in Python wäre geraten: Wie viele Zeilen ein Text ergibt,
   weiss erst, wer die Breite kennt. Genau daran sind im Nachrichtenverlauf
   Griff und Schnitt auseinandergelaufen, seit die Blasen breiter sind. */
.aufgabe .kurz{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden;
  margin:6px 0 0 2.3em;font-size:.92rem;color:var(--muted)}
/* KEIN TEXT DOPPELT: Aufgeklappt steht die ganze Beschreibung im Rumpf,
   der Anriss im Summary hat dann nichts mehr zu sagen. */
.aufgabe .aufgabe-klapp[open] > summary .kurz{display:none}

/* Wie weit DIESE eine Aufgabe ist – der schmale Balken unter dem Kasten.
   Er lehnt sich an .pruef-balken an (derselbe harte Farbumschlag an der
   Stelle --anteil), sieht ihm aber bewusst nicht gleich: halb so hoch,
   ohne Rahmen, eingerückt wie der übrige Text im Kasten. Der grosse oben
   sagt „wie viele Aufgaben sind durch", dieser „wie weit ist diese eine" –
   dasselbe Bild für zwei verschiedene Auskünfte wäre eine Falle.

   Versteckt wird über das hidden-Attribut, siehe [hidden] weiter oben:
   Die Elemente stehen immer im Dokument, damit der Selbstnachlader sie
   findet, sobald eine Aufgabe anfängt. */
.aufgabe-zeit{margin:8px 0 0 2.3em}
/* DERSELBE BALKEN FÜR DEN ZERLEGUNGSLAUF, nur nicht eingerückt: Er steht
   oben im Kasten „Wo es steht" und nicht unter einem Aufgabenkasten, hat
   also keine Nummer, an der er ausgerichtet wäre. Dass es dasselbe Bild
   ist, ist Absicht – „so weit ist es gediehen" heisst hier dasselbe. */
.zerlegung-zeit{margin:8px 0 0}
.zeit-balken{--anteil:0%;height:5px;border-radius:3px;
  background:linear-gradient(to right,
    var(--brand) 0 var(--anteil), var(--sunk) var(--anteil) 100%);
  transition:background .6s ease}
/* Klein, aber nicht zu klein: Die Seite wird vom Telefon bedient, und
   darunter wird aus einer Auskunft eine Andeutung. Tabellenziffern, damit
   die Zeile beim Nachladen nicht bei jeder Minute zappelt. */
.zeit-text{margin:5px 0 0;font-size:.82rem;line-height:1.45;
  color:var(--muted);font-variant-numeric:tabular-nums}
.aufgabe.stand-laeuft .zeit-text{color:var(--ink);font-weight:600}

/* WENN SICH NICHTS MEHR RÜHRT. Der Satz sagt, woran man es sieht, der
   Knopf daneben löst es von Hand – und beide stehen zusammen in einem
   Kasten, weil eine Warnung ohne Ausweg nur ärgert.

   AUFFÄLLIG, ABER NICHT ROT: Ein Hänger ist keine gescheiterte Aufgabe,
   sondern eine, an der gerade niemand sitzt. Deshalb die Warnfarbe und
   nicht die Gefahrfarbe – der Unterschied ist am Kasten selbst ablesbar
   (der Rand links bleibt der von „läuft").

   Versteckt wird über das hidden-Attribut, siehe [hidden] weiter oben:
   Kasten und Knopf stehen immer im Dokument, damit der Selbstnachlader
   sie findet, sobald eine Aufgabe stehenbleibt. Deshalb steht hier auch
   kein display im Ruhezustand, das [hidden] überstimmen könnte. */
.aufgabe-haenger{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;
  margin:8px 0 0 2.3em;padding:8px 10px;border-radius:8px;
  background:var(--warn);border:1px solid var(--warn-line)}
.aufgabe-haenger .haenger-satz{flex:1 1 12em;margin:0;font-size:.85rem;
  font-weight:700;color:var(--warn-ink)}
.aufgabe-haenger form{flex:0 0 auto;margin:0}
/* Kleiner als die Knöpfe oben im Kasten: Das hier ist der Ausweg aus
   einer Ausnahme und nicht der Weg, den man gewöhnlich geht. */
.aufgabe-haenger button{padding:6px 12px;font-size:.82rem}

/* WORAUF EINE AUFGABE WARTET – ruhiger als der Hänger darüber.
   Warten ist der Normalfall und keine Störung: Der Kasten soll gelesen
   werden, aber nicht nach einem Eingriff rufen. */
.aufgabe-wartet{margin:8px 0 0 2.3em;padding:8px 10px;border-radius:8px;
  background:var(--sunk);border:1px solid var(--line)}
.aufgabe-wartet .wartet-satz{margin:0;font-size:.85rem;color:var(--muted)}

/* „Dauert lang" ist keine Warnung, sondern eine Einordnung: Diese Aufgabe
   steht hinten, weil sie sonst alle anderen aufhielte. */
.marke-lang{flex:0 0 auto;padding:2px 8px;border-radius:999px;
  background:var(--warn);color:var(--warn-ink);font-size:.72rem;
  font-weight:800;letter-spacing:.02em}

/* Ersatzcodes nach der Einrichtung des zweiten Faktors.

   Zweispaltig und in Schreibmaschinenschrift, weil diese Codes ABGESCHRIEBEN
   werden: von Hand auf einen Zettel oder in einen Passwortspeicher. Bei einer
   Proportionalschrift stehen die Zeichen unterschiedlich weit auseinander, und
   genau dann verwechselt man beim Abschreiben eine Stelle. */
.ersatzcodes{list-style:none;padding:0;margin:20px 0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
.ersatzcodes li{margin:0}
.ersatzcodes code{display:block;padding:11px 12px;border:1px solid var(--line);
  border-radius:8px;background:var(--sunk);color:var(--ink);
  font:700 15px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;
  letter-spacing:.1em;text-align:center;user-select:all}

/* PREISWIRKUNG – die Auswertung der Preisvarianten.

   Zahlen sollen untereinander vergleichbar sein, deshalb Tabellenziffern:
   Ohne sie wandern die Kommastellen von Zeile zu Zeile, und zwei Quoten
   nebeneinander lassen sich nicht mehr auf einen Blick vergleichen. */
.preiswirkung th[scope=row]{min-width:200px}
.preiswirkung td strong{font-size:18px}
/* Der Trichter aus dem Ereignisstrom. Breitere Zeilenkoepfe, weil dort die
   Stufe UND ihre Erklaerung stehen: „Abo aktiv" allein liest sich wie eine
   fertige Website, und genau das ist es nicht. */
.trichter th[scope=row]{min-width:240px}
.trichter td strong{font-size:18px}
td strong,.quote{font-variant-numeric:tabular-nums}

/* Ein fehlender Nenner ist keine Null. Der Gedankenstrich steht deshalb
   ruhig da und sieht nicht aus wie ein Messwert. */
.quote-leer{color:var(--muted);font-weight:700}

/* Die Betriebe aus der Zeit vor dem Versuch stehen mit, gehören aber
   nicht in den Vergleich - sie sind hier zurückgenommen. */
tr.ohne-variante th[scope=row],tr.ohne-variante td{background:var(--sunk)}

/* Rolle setzen und entfernen stehen in derselben Zeile wie die Person.
   Untereinander sähen zwei Formulare aus wie zwei Vorgänge, dabei gehören
   beide zu dem einen Namen links daneben. */
.team-aktionen{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.team-aktionen .portal-form.inline{display:flex;align-items:center;gap:8px;margin:0}
.team-aktionen select{width:auto}

/* ══ Die Übersicht, mobil zuerst ══════════════════════════════════════════
 *
 * WARUM DAS HIER UNTEN STEHT UND NICHT OBEN BEI .metrics: Die Regeln für
 * .dashboard-metrics stehen weiter oben mehrfach (fünf Spalten, dann drei,
 * dann zwei, dann eine) und haben dieselbe Spezifität wie diese hier. Wer
 * gleich spezifisch ist, entscheidet über die Reihenfolge - also am Ende.
 * Sie ersetzen die festen Spaltenzahlen; die alten Regeln bleiben stehen,
 * weil sie ohne diese Datei (etwa in einem Zwischenstand) noch tragen.
 */

/* Eine Überschrift über einer Kachelreihe, die kein Panel ist. */
.abschnitt-titel{font-size:15px;font-weight:800;letter-spacing:.02em;
  color:var(--muted);margin:0 0 12px}

/* DIE KENNZAHLEN WACHSEN MIT, statt in vier oder fünf feste Spalten zu
 * springen. 168 Pixel ist die schmalste Kachel, in der „1.240 €" und
 * darunter „Monatsumsatz aus Abos" noch lesbar stehen. Bei 390 Pixeln
 * Fensterbreite (366 innen, 14 Lücke) ergibt das zwei Spalten, bei 1440
 * so viele, wie hineinpassen - ohne dass irgendwo eine Zahl bricht.
 */
.dashboard-metrics{grid-template-columns:repeat(auto-fit,minmax(168px,1fr))}
/* Sechs Kacheln teilen sich schlecht durch vier: Am Tablet blieben zwei
 * allein in der zweiten Reihe stehen und sahen aus wie nachgereicht. In
 * diesem Band also drei mal zwei; darunter passen zwei nebeneinander,
 * darüber alle sechs. */
@media (min-width:600px) and (max-width:1180px){
  .dashboard-metrics{grid-template-columns:repeat(3,minmax(0,1fr))}
}
.dashboard-metrics .metric-link,.dashboard-metrics article{padding:18px;
  min-width:0;overflow-wrap:anywhere}
.dashboard-metrics strong{font-size:clamp(21px,2.2vw,26px);line-height:1.15}
.dashboard-metrics span{display:block;margin-top:2px;font-size:13px;
  line-height:1.35}
/* Ein Geldbetrag ist das längste, was auf einer Kachel steht. */
.metric-geld strong{font-size:clamp(19px,2vw,26px)}

/* ── Aus jeder Tabelle wird am Telefon eine Liste von Karten ──────────────
 *
 * DAS PROBLEM, DAS DAMIT WEG IST: Vier Spalten auf 366 Pixeln geben jeder
 * Spalte achtzig. „AN-2026-0001" bricht darin auf zwei Zeilen, der Titel
 * auf sechs, und weil ein Rasterfeld (.dashboard-spalten) standardmäßig
 * mindestens so breit wird wie sein Inhalt, wuchs die ganze Seite mit -
 * daher das waagerechte Schieben in den Bildschirmfotos.
 *
 * WARUM KARTEN UND NICHT SEITWÄRTS SCROLLEN: Ein Rahmen mit overflow-x
 * versteckt die Hälfte der Zeile hinter einer Geste, von der niemand weiß,
 * dass es sie gibt. Als Karte steht jede Zelle untereinander, mit ihrer
 * Spaltenüberschrift davor - aus data-spalte, damit eine neue Spalte nichts
 * am CSS ändert.
 *
 * Das Markup bleibt eine echte Tabelle; nur die Darstellung wechselt.
 */
@media (max-width:760px){
  .tabelle-karten,.tabelle-karten tbody,.tabelle-karten tr,
  .tabelle-karten td{display:block;width:auto}
  /* Der Kopf trägt am Telefon nichts bei - die Beschriftung steht in der
     Zelle. Er bleibt für Vorleseprogramme im Dokument. */
  .tabelle-karten thead{position:absolute;width:1px;height:1px;padding:0;
    margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .tabelle-karten tbody tr{position:relative;padding:14px 0;
    border-bottom:1px solid var(--line)}
  .tabelle-karten tbody tr:last-child{border-bottom:0}
  .tabelle-karten td{border:0;padding:3px 0;min-width:0;
    overflow-wrap:anywhere}
  .tabelle-karten td[data-spalte]{display:grid;
    grid-template-columns:minmax(78px,auto) minmax(0,1fr);gap:12px;
    align-items:baseline}
  .tabelle-karten td[data-spalte]::before{content:attr(data-spalte);
    font-size:11px;font-weight:700;letter-spacing:.07em;
    text-transform:uppercase;color:var(--muted)}
  /* Die erste Zelle ist die Überschrift der Karte und braucht keine. */
  .tabelle-karten .karte-kopf{margin-bottom:4px}
  .tabelle-karten .karte-kopf strong{font-size:16px}
  .tabelle-karten .karte-leer td{padding:14px 0;color:var(--muted)}
  /* Ein Etikett ist so breit wie sein Wort. Als Rasterfeld würde es auf die
     ganze Spalte gedehnt - aus „Läuft" würde ein grüner Balken über die
     halbe Karte, der aussieht wie ein Fortschritt und keiner ist. */
  .tabelle-karten td>.status,.tabelle-karten td>.abrechnung{justify-self:start}
  /* Die aufgespannte Verknüpfung soll die ganze Karte treffen, nicht nur
     ihre Zelle: also hängt sie jetzt an der Zeile. */
  .tabelle-karten td{position:static}
}

/* Ein Rasterfeld ist standardmäßig mindestens so breit wie sein Inhalt -
 * 1fr allein reicht also nicht, eine breite Tabelle sprengt es trotzdem.
 * minmax(0,1fr) erlaubt dem Feld, schmaler zu werden als sein Inhalt; erst
 * dann greifen die Umbrüche darin. */
@media (max-width:1000px){
  .dashboard-spalten{grid-template-columns:minmax(0,1fr)}
}

/* Auch am breiten Bildschirm: die Tabellenspalte darf nicht am Inhalt
 * kleben bleiben und die rechte Spalte wegdrücken. */
.dashboard-spalten>*{min-width:0}

/* Lange Firmennamen in der Kurzliste brechen im Wort statt über den Rand. */
.kunden-kurz a{min-width:0}
.kunden-kurz strong,.kunden-kurz small{min-width:0;overflow-wrap:anywhere}

/* Bei 390 Pixeln ist auch die Kopfzeile der Panels knapp: Überschrift und
 * Verweis nebeneinander lassen der Überschrift zu wenig Platz. */
@media (max-width:430px){
  .posteingang .panel-heading{padding:16px}
  .pe-mehr{padding:12px 16px 14px}
  .pe-leer{padding:28px 16px}
  .panel-heading{flex-wrap:wrap;gap:6px 14px}
}

/* DIE 80ch-GRENZE GILT FÜR FLIESSTEXT, NICHT FÜR EINE VORGANGSLISTE.
 *
 * `.panel > p,.panel > ul,.panel > ol{max-width:80ch}` weiter oben hält
 * Absätze auf lesbarer Zeilenlänge - richtig für Text, falsch hier: Der
 * Posteingang ist ein ul unmittelbar im Panel und wurde damit bei 1440
 * Pixeln auf 686 gekappt. Die Zeilen endeten mitten in der Karte, und die
 * Zeitangabe rechts stand nicht am rechten Rand, sondern in der Mitte.
 *
 * Eng gefasst auf die zwei Listen der Übersicht, damit die Regel dort
 * weiter greift, wo sie gemeint ist. */
.posteingang .pe-liste,.kunden-kurz.breit{max-width:none}

/* ══ Zahlenwahl: 1 bis 10 zum Antippen ═══════════════════════════════════
 *
 * Auf der Vorhabenseite stehen zwei Zahlen zwischen 1 und der Decke. Als
 * Zahlenfeld hiess das am Handy: Tastatur auf, in ein schmales Feld
 * treffen, Tastatur zu - und die moeglichen Werte sah man nie. Hier stehen
 * sie offen da, und der geltende ist hervorgehoben.
 *
 * DAS NATIVE KAESTCHEN IST VERSTECKT, NICHT ENTFERNT. `display:none` naehme
 * dem Radio den Tastaturfokus und damit Tab und Pfeiltasten; es bleibt
 * deshalb ein Pixel gross und durchsichtig hinter seiner Kachel. Der Rest
 * ist `:checked` und `:focus-visible` - kein Skript, denn die Seite laeuft
 * unter einer Inhaltssicherheitsrichtlinie mit nonce.
 *
 * 44 x 44 IST KEINE ZIERDE, sondern die Flaeche, die ein Daumen trifft;
 * dieselbe Mindesthoehe hat `.portal-button`. Am breiten Bildschirm steht
 * die Reihe in einer Zeile, am schmalen bricht sie um. */
.zahlwahl{border:0;margin:0 0 16px;padding:0;min-width:0}
.zahlwahl>legend{padding:0;margin:0 0 8px;font-weight:750;color:var(--ink)}
.zahlwahl-reihe{position:relative;display:flex;flex-wrap:wrap;gap:8px}
.zahlwahl-knopf{position:absolute;width:1px;height:1px;margin:0;opacity:0;pointer-events:none}
.zahlwahl-kachel{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0 12px;border:1px solid var(--line);border-radius:999px;background:var(--sunk);color:var(--muted);font-weight:850;font-variant-numeric:tabular-nums;cursor:pointer;user-select:none}
.zahlwahl-kachel:hover{border-color:var(--brand);color:var(--ink)}
/* Die geltende Zahl auf den ersten Blick: gefuellt statt nur umrandet.
 * `--knopf-bg`/`--knopf-ink` statt `--brand`, weil das Paar in beiden Modi
 * geprueft ist - im dunklen ist `--brand` eine helle Flaeche, auf der
 * weisse Ziffern verschwaenden. */
.zahlwahl-knopf:checked+.zahlwahl-kachel{background:var(--knopf-bg);border-color:var(--knopf-bg);color:var(--knopf-ink);box-shadow:0 0 0 3px var(--accent)}
.zahlwahl-knopf:focus-visible+.zahlwahl-kachel{outline:2px solid var(--brand);outline-offset:3px}

/* ==========================================================================
   Politur: Bewegung und Tiefe im Dashboard
   Dieselbe Zurückhaltung wie auf der öffentlichen Seite - kurze, spürbare
   Reaktionen statt Spielerei. Ein Arbeitswerkzeug, das täglich genutzt wird,
   braucht keine einlaufenden Abschnitte; es braucht Knöpfe und Karten, die
   sich wie echte Flächen anfühlen.
   ========================================================================== */
.portal-button,.search-form button,.link-button{transition:transform .12s ease,box-shadow .15s ease,background .15s ease,border-color .15s ease}
.portal-button:not(:disabled):hover{transform:translateY(-1px);box-shadow:0 6px 16px var(--schatten-weich)}
.portal-button:not(:disabled):active{transform:scale(.97)}
.metrics article,.panel,.auth-card,.offer-document{transition:box-shadow .2s ease,border-color .2s ease}
.metrics article:hover{border-color:var(--brand);box-shadow:0 10px 30px var(--schatten-weich)}
@media (prefers-reduced-motion: reduce){
  .portal-button:hover,.portal-button:active,.metrics article:hover{transform:none}
}

/* Die Rohantwort von easyNova, aufklappbar in der Standspalte.

   WOZU: Meldet easyNova eine Ablehnung, steht in der Zeile oft nur ein
   Verweis – „Verarbeitungsfehler: Siehe errorList". Der Grund steht in der
   Antwort daneben. Die stand vorher im title-Attribut, also in einem Hover –
   und am Handy gibt es kein Hover. Wer unterwegs nachsah, warum ein Brief
   nicht rausging, erfuhr es nicht.

   Das <pre> bricht um: Eine JSON-Zeile ohne Leerzeichen hat keine
   Umbruchstelle und zieht sonst die ganze Tabelle in die Breite. */
.rohantwort{margin-top:6px}
.rohantwort>summary{cursor:pointer;color:var(--muted);font-weight:750;font-size:12px;padding:2px 0;list-style:none}
.rohantwort>summary::-webkit-details-marker{display:none}
.rohantwort>summary:before{content:"›";display:inline-block;margin-right:6px;transition:transform .15s}
.rohantwort[open]>summary:before{transform:rotate(90deg)}
.rohantwort>summary:hover{color:var(--brand)}
.rohantwort>pre{margin:6px 0 0;padding:10px;max-width:min(62ch,100%);max-height:16em;overflow:auto;
  white-space:pre-wrap;overflow-wrap:anywhere;background:var(--sunk);color:var(--ink);
  border:1px solid var(--line);border-radius:8px;
  font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}
