Files
projektuebersicht/public/plan-styles.css
T
erikandClaude Opus 5.5 e12936444d Aufgaben im Wochenbericht, Meilensteine „Erreicht“, Panels als Planblatt
- Wochenbericht: Abschnitt „Aufgaben“ je Projekt (erledigt seit Vorwoche,
  überfällig, nächste zwei Wochen), rote Zahl in der Tagesordnung,
  Tabelle in der PDF-Akte; Klick öffnet das Aufgaben-Panel
- Meilensteine lassen sich als erreicht markieren (plan_milestones.erreicht);
  nur nicht erreichte vergangene gelten als überfällig
- Aufgabe- und Meilenstein-Panel neu aufgebaut: Stand oben, Lage im
  Terminplan, Angaben als Zeilen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:41:44 +01:00

1993 lines
111 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ===========================================================================
Projektbereich — Stile des Projektplan-Bereichs
---------------------------------------------------------------------------
Diese Regeln standen früher als <style>-Block in der eigenständigen Seite
public/project-plan.html. Seit der Projektbereich ein normaler Bereich der
Hauptseite ist (Test.html, Bereich #plan — er wird wie jeder andere über
showTab() eingeblendet), liegen sie in einer eigenen Datei, die Test.html
zusaetzlich zu styles.css laedt. Die Klassennamen sind unveraendert
(.plan-page, .plan-nav, .plan-section, .plan-kpi-*, .gantt-*, …), damit die
Module unter public/js/plan/ nichts davon wissen muessen.
=========================================================================== */
.plan-page { display: flex; flex-direction: column; }
.plan-header {
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
padding: 12px 24px; background: var(--surface); border-bottom: 1px solid var(--line-soft);
}
.plan-header h1 { font-size: 19px; margin: 0; font-weight: 500; white-space: nowrap; }
.plan-header .plan-id {
font-family: ui-monospace, 'SF Mono', monospace; font-size: 13px; color: var(--text-muted); white-space: nowrap;
}
.plan-header .subtitle { color: var(--text-muted); font-size: 13px; white-space: nowrap; }
.plan-header-spacer { flex: 1; min-width: 12px; }
.plan-header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.plan-body { flex: 1; display: flex; gap: 0; }
.plan-main { flex: 1; display: flex; flex-direction: column; background: var(--bg); min-width: 0; }
.plan-main-header {
padding: 0 0 16px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
}
.plan-main-content { flex: 1; padding: 20px 20px 20px; min-width: 0; }
.todo-row:last-child { margin-bottom: 0; }
/* .plan-avatar-stack: leicht überlappende Avatar-Kreise der Beteiligten in
der kompakten Titelzeile (siehe .board-avatar in styles.css für die
Kreis-/Farb-Definitionen selbst). */
.plan-avatar-stack { display: flex; flex-shrink: 0; }
.plan-avatar-stack .board-avatar { margin-left: -7px; border: 2px solid var(--surface); }
.plan-avatar-stack .board-avatar:first-child { margin-left: 0; }
.todo-row-item.done { opacity: .55; text-decoration: line-through; }
/* Farben aus den Theme-Variablen: `background: var(--text)` mit fester
weißer Schrift ergab im Dunkelmodus weiß auf weiß. */
/* Die Regeln der früheren TODO-Liste (.todo-item, .todo-list-main, .milestone-row …)
sind entfallen: Der Bereich "Aufgaben" rendert seit dem Umbau .plan-task-*
(siehe weiter unten und js/plan/plan-tasks.js). */
.plan-toast {
position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px);
background: var(--surface); color: var(--text); border: 1px solid var(--line);
padding: 12px 20px; border-radius: 8px;
font-size: 13px; opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s;
z-index: 1000; box-shadow: var(--sh-3);
}
.plan-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.plan-resource-grid {
display: grid !important;
grid-template-columns: repeat(auto-fill, minmax(140px, max-content)) !important;
gap: 8px !important;
justify-content: start !important;
}
.plan-resource-card {
padding: 8px 12px !important;
min-height: 0 !important;
width: 140px !important;
max-width: 140px !important;
}
.plan-resource-card h3 {
font-size: 12px !important;
margin-bottom: 2px !important;
}
.plan-resource-clickable { cursor: pointer; transition: box-shadow .15s, transform .15s; }
.plan-resource-clickable:hover { box-shadow: var(--sh-2); transform: translateY(-1px); }
.todo-depends-list {
display: flex;
flex-direction: column;
gap: 4px;
max-height: 180px;
overflow-y: auto;
border: 1px solid var(--line-soft);
border-radius: var(--r-md);
padding: 8px;
background: var(--surface-alt);
}
.todo-depends-item {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 6px;
border-radius: var(--r-sm);
cursor: pointer;
font-size: 12px;
transition: background .15s;
}
.todo-depends-item:hover { background: var(--surface-sunk); }
.todo-depends-item input { flex-shrink: 0; }
.todo-depends-group {
font-size: 11px;
color: var(--text-muted);
margin-top: 6px;
margin-bottom: 2px;
letter-spacing: 0;
}
.todo-depends-group:first-child { margin-top: 0; }
/* Im eingeklappten Bereich trägt bereits das <details> den Rahmen */
.todo-depends-list.flat {
border: none;
background: transparent;
padding: 0;
max-height: 168px;
}
/* Vorgänger, die einen Zirkelbezug erzeugen würden (siehe
cyclicDependencyIds() in js/plan/plan-modals.js) */
.todo-depends-item.is-blocked { color: var(--text-subtle); cursor: not-allowed; opacity: .6; }
.todo-depends-item.is-blocked:hover { background: transparent; }
.todo-depends-note {
margin-left: auto;
font-size: 11px;
color: var(--amber);
white-space: nowrap;
}
/* === TODO-Modal (Stufe B) =================================================
Kopfzeile mit Tastaturhinweis, Fehlermeldung am Feld, Dauer-Badge,
Zuständige als Personen-Chips, Status-Segment und eingeklappte
Abhängigkeiten. Befüllt von openTodoModal() in js/plan/plan-modals.js. */
.modal-head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
margin-bottom: 16px;
}
.modal-head h2 { margin: 0; }
.modal-kbd { font-size: 11px; color: var(--text-subtle); white-space: nowrap; }
/* Validierungshinweis direkt am Feld statt im alert() */
/* .field-error steht in styles.css: der Passwort-Dialog (js/auth.js) nutzt
sie auch ausserhalb des Projektbereichs. */
.modal input.is-error,
.modal textarea.is-error {
border-color: var(--red);
box-shadow: 0 0 0 3px rgba(215,0,21,.15);
}
.field-inline { display: flex; align-items: center; gap: 8px; }
.field-inline .range-picker-display { flex: 1; }
.field-badge {
font-size: 11px;
font-weight: 500;
color: var(--text-muted);
background: var(--surface-sunk);
border-radius: 6px;
padding: 4px 8px;
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
/* Zuständige: Kürzel + Name, gleiche Lesart wie die Board-Spalten */
.person-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.person-chip {
display: inline-flex;
align-items: center;
gap: 8px;
background: var(--surface);
color: var(--text-muted);
border: 1px solid var(--line);
border-radius: 6px;
padding: 4px 12px 4px 4px;
font-size: 13px;
font-weight: 500;
transition: border-color .15s var(--ease), background .15s var(--ease), color .15s var(--ease);
}
.person-chip:hover { background: var(--surface); border-color: var(--text-subtle); }
.person-chip-ini {
width: 21px;
height: 21px;
border-radius: 50%;
background: var(--surface-sunk);
color: var(--text-muted);
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 500;
}
.person-chip[aria-pressed="true"] {
background: var(--accent-soft);
border-color: var(--accent);
color: var(--accent);
}
.person-chip[aria-pressed="true"]:hover { background: var(--accent-soft); }
/* Zuständige, die dem Projekt (nicht mehr) zugeordnet sind (openTodoModal()):
gestrichelt wie die "fremden" Personen im Assistenten. */
.person-chip.ist-fremd { border-style: dashed; }
.person-chip[aria-pressed="true"] .person-chip-ini { background: var(--accent); color: #fff; }
/* Hover-Fläche im Status-Segment: eigene Abstufung, weil das Segment auf
--surface-sunk sitzt. Gleiche Drei-Zustands-Logik wie in styles.css —
:root deckt hell ab, die Media Query das System-Dunkel (außer bei
ausdrücklich hell), [data-theme="dark"] die manuelle Umschaltung. */
:root { --seg-hover: rgba(0,0,0,.06); }
@media (prefers-color-scheme: dark) {
html:not([data-theme="light"]) { --seg-hover: rgba(255,255,255,.10); }
}
html[data-theme="dark"] { --seg-hover: rgba(255,255,255,.10); }
/* Status: ersetzt das frühere Paar aus "Erledigt" und Fortschrittsregler */
.segmented {
display: inline-flex;
background: var(--surface-sunk);
border-radius: 8px;
padding: 2px;
gap: 2px;
width: fit-content;
}
.segmented button {
background: transparent;
color: var(--text-muted);
padding: 4px 16px;
font-size: 13px;
border-radius: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.segmented button:hover { background: var(--seg-hover); }
.segmented button[aria-pressed="true"] {
background: var(--surface);
color: var(--text);
font-weight: 500;
box-shadow: var(--sh-1);
}
.segmented-dot {
width: 7px; height: 7px; border-radius: 50%;
background: currentColor; opacity: .45;
}
.segmented button[aria-pressed="true"] .segmented-dot { opacity: 1; }
.segmented button[data-status="offen"][aria-pressed="true"] .segmented-dot { background: var(--text-subtle); }
.segmented button[data-status="arbeit"][aria-pressed="true"] .segmented-dot { background: var(--amber); }
.segmented button[data-status="fertig"][aria-pressed="true"] .segmented-dot { background: var(--green); }
.progress-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.progress-row[hidden] { display: none; }
.progress-row input[type=range] { flex: 1; accent-color: var(--accent); }
.progress-row output {
font-variant-numeric: tabular-nums;
font-size: 12px;
color: var(--text-muted);
min-width: 42px;
text-align: right;
}
/* Abhängigkeiten: selten gebraucht, daher eingeklappt mit Anzahl im Kopf */
.fold {
border: 1px solid var(--line);
border-radius: var(--r-md);
overflow: hidden;
background: var(--surface);
}
.fold > summary {
cursor: pointer;
list-style: none;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
user-select: none;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary:hover { background: var(--surface-alt); }
.fold-caret {
color: var(--text-subtle);
font-size: 11px;
transition: transform .18s var(--ease);
}
.fold[open] > summary .fold-caret { transform: rotate(90deg); }
.fold-count {
margin-left: auto;
font-size: 11px;
font-weight: 500;
background: var(--accent-soft);
color: var(--accent);
border-radius: 6px;
padding: 1px 8px;
font-variant-numeric: tabular-nums;
}
.fold-count.zero { background: var(--surface-sunk); color: var(--text-subtle); }
.fold-body {
padding: 8px 12px 12px;
border-top: 1px solid var(--line-soft);
display: flex;
flex-direction: column;
gap: 8px;
}
.fold-search { position: relative; }
.fold-search input { width: 100%; padding-left: 28px; }
.fold-search-icon {
position: absolute;
left: 9px;
top: 50%;
transform: translateY(-50%);
color: var(--text-subtle);
font-size: 13px;
pointer-events: none;
}
/* Drag-Handle für TODO- und Meilenstein-Zeilen direkt im GANTT */
.gantt-row.gantt-todo,
.gantt-row.gantt-milestone-row { cursor: default; }
.gantt-row.gantt-todo .gantt-label,
.gantt-row.gantt-milestone-row .gantt-label { display: flex; align-items: center; gap: 8px; }
.gantt-todo-drag {
color: var(--text-subtle); cursor: grab; font-size: 13px; line-height: 1;
user-select: none; flex-shrink: 0;
}
.gantt-row.gantt-todo.dragging,
.gantt-row.gantt-milestone-row.dragging { opacity: .5; }
.gantt-todo-drag:active { cursor: grabbing; }
.gantt-row.gantt-milestone-row .gantt-todo-drag { color: var(--text-subtle); }
/* Cockpit: KPI-Kacheln über dem GANTT (Gesamtfortschritt, offene Aufgaben,
nächster Meilenstein, Team-Auslastung) — siehe renderPlanKpis() in
js/plan/plan-gantt.js. */
.plan-kpi-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 16px;
}
.plan-kpi-tile {
background: var(--surface);
border: 1px solid var(--line-soft);
border-radius: var(--r-lg);
padding: 12px 16px;
box-shadow: var(--sh-1);
}
.plan-kpi-tile .kpi-label {
font-size: 11px; letter-spacing: 0;
color: var(--text-subtle); font-weight: 500; margin-bottom: 4px;
}
.plan-kpi-tile .kpi-value {
font-size: 24px; font-weight: 600; letter-spacing: 0; color: var(--text);
font-variant-numeric: tabular-nums;
}
.plan-kpi-tile .kpi-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.plan-kpi-tile.warn .kpi-value { color: var(--amber); }
/* Kompakt-Karten im Dashboard (Ressourcen-Auslastung, Dateien & Freigaben,
Verlauf) — springen in den zugehörigen Bereich bzw. öffnen den Verlauf,
siehe showPlanSection()/openHistoryModal(). */
.plan-card-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
gap: 12px;
margin-top: 16px;
}
.plan-mini-card {
background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-lg);
padding: 16px 16px; cursor: pointer; transition: box-shadow .15s, transform .15s;
}
.plan-mini-card:hover { box-shadow: var(--sh-2); transform: translateY(-1px); }
.plan-mini-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.plan-mini-card-title { font-size: 13px; font-weight: 500; }
.plan-mini-card-expand { font-size: 11px; color: var(--accent); font-weight: 500; flex-shrink: 0; }
.plan-mini-card-preview {
font-size: 13px; color: var(--text-muted); line-height: 1.5;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.plan-mini-chip-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.plan-mini-chip { font-size: 11px; padding: 2px 8px; border-radius: 6px; background: var(--surface-sunk); color: var(--text-muted); }
.plan-mini-chip.warn { background: rgba(178,80,0,.12); color: var(--amber); }
.plan-heat-row { display: flex; gap: 4px; }
.plan-heat-cell { flex: 1; height: 18px; border-radius: 4px; background: var(--accent); }
@media (max-width: 760px) {
.plan-kpi-row { grid-template-columns: repeat(2, 1fr); }
}
/* --- Geister-Balken: Termine der Vorwoche (plan-build-gantt.js) ---
Bewusst ohne Füllung und ohne Zeiger-Ereignisse: sie sind reine
Referenz-Anzeige und dürfen Drag/Resize des echten Balkens darunter
nicht abfangen. */
.gantt-bar.ghost {
background: transparent;
border: 1.5px dashed var(--text-subtle);
opacity: .7;
pointer-events: none;
box-shadow: none;
}
.gantt-milestone.ghost {
background: transparent;
border: 1.5px dashed var(--text-subtle);
opacity: .7;
pointer-events: none;
}
/* --- Urlaubs-Kollision (plan-build-gantt.js) --- */
.gantt-bar.todo.conflict-absence {
outline: 2px solid var(--amber);
outline-offset: 1px;
}
.gantt-conflict-badge {
color: var(--amber);
display: inline-flex;
align-items: center;
flex-shrink: 0;
margin-left: 4px;
cursor: help;
}
/* Hinweisband über dem GANTT (renderPlanWarnings in plan-gantt.js) */
.plan-warning-band {
background: var(--surface);
border: 1px solid var(--line-soft);
border-left: 3px solid var(--amber);
border-radius: var(--r-md);
padding: 12px 16px;
margin-bottom: 12px;
}
.plan-warning-head {
display: flex; align-items: center; gap: 8px;
font-size: 13px; font-weight: 500; color: var(--amber);
}
.plan-warning-list {
margin: 6px 0 0; padding-left: 28px;
font-size: 13px; color: var(--text-muted); line-height: 1.55;
}
/* Projektübergreifende Auslastung in der Ressourcen-Karte */
.plan-resource-other {
font-size: 11px; margin-top: 4px; font-weight: 500; color: var(--amber);
cursor: help;
}
.plan-resource-other.muted { color: var(--text-subtle); font-weight: 400; cursor: default; }
/* --- Verlaufs-Modal (plan-history.js) --- */
.history-list {
display: flex; flex-direction: column; gap: 8px;
max-height: 58vh; overflow-y: auto;
}
.history-entry {
border: 1px solid var(--line-soft); border-radius: var(--r-md);
background: var(--surface-alt); padding: 12px 12px;
}
.history-entry.current { border-color: var(--accent); background: var(--surface); }
.history-entry-head {
display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px;
}
.history-week { font-size: 13px; font-weight: 500; }
.history-date { font-size: 12px; color: var(--text-subtle); }
.history-badge {
font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 6px;
background: var(--accent-soft); color: var(--accent);
}
.history-badge.muted { background: var(--surface-sunk); color: var(--text-subtle); }
.history-entry-text { font-size: 13px; line-height: 1.5; color: var(--text); }
.history-entry-text p { margin: 0 0 4px; }
.history-entry-text p:last-child { margin-bottom: 0; }
/* --- Vorlagen-Modal (plan-templates.js) --- */
.template-head-grid {
display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
}
.template-admin-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.template-admin-row {
display: flex; align-items: center; gap: 8px;
font-size: 13px; padding: 4px 6px;
background: var(--surface-alt); border-radius: var(--r-sm);
}
.template-admin-title { flex: 1; min-width: 0; }
.template-add-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.template-add-row input[type=text] { flex: 1 1 200px; min-width: 140px; }
.template-add-row input[type=number] { width: 70px; }
/* --- Honorar-Terminplan (plan-honorar.js) --- */
.honorar-check { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: help; }
.honorar-plan-wrap { overflow-x: auto; margin-top: 4px; }
.honorar-table { font-size: 13px; }
.honorar-table th.num, .honorar-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.honorar-table td.nowrap { white-space: nowrap; }
.honorar-table input[type=number] { width: 58px; padding: 4px 6px; font-size: 12px; text-align: center; }
.honorar-table tfoot th, .honorar-table tfoot td {
border-top: 2px solid var(--line); font-weight: 500; background: var(--surface-alt);
}
.honorar-anteil-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
gap: 8px; margin-bottom: 8px;
}
.honorar-anteil-field { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.honorar-anteil-field span { width: 46px; flex-shrink: 0; color: var(--text-muted); }
.honorar-anteil-field input { width: 100%; min-width: 0; padding: 4px 6px; font-size: 12px; text-align: right; }
.honorar-admin-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.honorar-satz-field { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.honorar-satz-field input { width: 78px; padding: 4px 8px; font-size: 13px; text-align: right; }
.honorar-sum { font-size: 13px; font-weight: 500; }
.honorar-sum.ok { color: var(--green); }
.honorar-sum.warn { color: var(--amber); }
/* Beauftragte Leistungsphasen im Projektinfo */
@media (max-width: 620px) {
.template-head-grid { grid-template-columns: 1fr; }
}
/* Dateien-Modal (Upload, Freigabe, Kommentare) */
/* Upload-Maske des Bereichs "Dateien": oben ausgerichtet, damit
Dateiauswahl und Prüferliste in der breiten Karte auf gleicher Höhe
beginnen (im früheren Modal war sie unten ausgerichtet). */
.plan-files-upload { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; margin-bottom: 4px; }
.plan-files-upload .form-row { margin-bottom: 0; }
.plan-files-upload #fileUploadReviewers { width: 240px; }
.files-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; max-height: 50vh; overflow-y: auto; }
.file-item {
border: 1px solid var(--line-soft); border-radius: var(--r-md);
background: var(--surface-alt); padding: 12px 12px;
}
.file-item-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.file-item-name { font-weight: 500; font-size: 13px; word-break: break-all; }
.file-item-meta { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.file-status-badge {
font-size: 11px; padding: 2px 8px; border-radius: 6px; color: #fff; flex-shrink: 0;
}
.file-status-badge.pending, .file-reviewer-chip.pending { background: #d18b00; }
.file-status-badge.approved, .file-reviewer-chip.approved { background: var(--green); }
.file-status-badge.rejected, .file-reviewer-chip.rejected { background: var(--red); }
.file-reviewer-list { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.file-reviewer-chip { font-size: 11px; padding: 2px 8px; border-radius: 6px; color: #fff; }
.file-item-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.file-comments { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.file-comment-list { display: flex; flex-direction: column; gap: 6px; max-height: 160px; overflow-y: auto; }
.file-comment { font-size: 12px; background: var(--surface-sunk); border-radius: var(--r-sm); padding: 6px 8px; }
.file-comment-date { color: var(--text-subtle); font-size: 11px; margin-left: 6px; }
.file-comment-form { display: flex; gap: 6px; margin-top: 6px; }
.file-comment-form input { flex: 1; }
/* === Projektbereich: Bereichs-Navigation und Bereiche ====================
Die Seite ist der EIGENE BEREICH eines Projekts und gliedert sich in fünf
Unterbereiche (Dashboard, Terminplan, Aufgaben, Dateien, Einstellungen),
zwischen denen die Leiste .plan-nav umschaltet (showPlanSection() in
js/plan/plan-sections.js). Alle Bereiche liegen gleichzeitig im DOM und
werden nur ein-/ausgeblendet. */
.plan-nav {
display: flex;
gap: 4px;
padding: 0 24px;
background: var(--surface);
border-bottom: 1px solid var(--line-soft);
overflow-x: auto;
}
.plan-nav-item {
background: transparent;
color: var(--text-muted);
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
padding: 12px 16px;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
}
.plan-nav-item:hover { color: var(--text); background: var(--surface-alt); }
.plan-nav-item.is-active {
color: var(--accent);
border-bottom-color: var(--accent);
font-weight: 500;
}
.plan-section { display: none; }
.plan-section.is-active { display: block; }
/* Kartenraster der Bereiche (Dashboard, Einstellungen) */
.plan-panel-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 12px;
margin-top: 16px;
}
.plan-panel {
background: var(--surface);
border: 1px solid var(--line-soft);
border-radius: var(--r-lg);
padding: 16px 16px;
}
.plan-panel-wide { grid-column: 1 / -1; }
.plan-panel-title {
font-size: 13px;
font-weight: 500;
margin: 0 0 8px;
display: flex;
align-items: baseline;
gap: 8px;
}
.plan-panel-count {
font-size: 11px;
font-weight: 500;
color: var(--text-subtle);
font-variant-numeric: tabular-nums;
}
.settings-static {
font-size: 13px;
color: var(--text-muted);
padding: 6px 0;
font-variant-numeric: tabular-nums;
}
/* --- Aufgaben-Bereich: Listendarstellung von TODOs und Meilensteinen
(renderPlanTasks() in js/plan/plan-tasks.js). Ein Klick auf eine Zeile
öffnet denselben Dialog wie im GANTT (openTodoModal/openMilestoneModal). */
.plan-task-list { display: flex; flex-direction: column; gap: 6px; }
.plan-task-row {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
background: var(--surface-alt);
border: 1px solid var(--line-soft);
border-radius: var(--r-md);
cursor: pointer;
transition: border-color .15s, background .15s;
}
.plan-task-row:hover { border-color: var(--accent); }
.plan-task-row.is-done .plan-task-title { text-decoration: line-through; color: var(--text-subtle); }
.plan-task-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--text-subtle); }
.plan-task-dot.arbeit { background: var(--amber); }
.plan-task-dot.fertig { background: var(--green); }
.plan-task-title { flex: 1; font-size: 13px; font-weight: 500; min-width: 0; }
.plan-task-meta {
font-size: 12px;
color: var(--text-muted);
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
.plan-task-meta.overdue { color: var(--red); font-weight: 500; }
.plan-task-no-schedule { color: var(--text-subtle); font-style: normal; }
.plan-task-assignees { display: flex; flex-shrink: 0; }
.plan-task-assignees .board-avatar { margin-left: -7px; border: 2px solid var(--surface-alt); }
.plan-task-assignees .board-avatar:first-child { margin-left: 0; }
.plan-task-empty { font-size: 13px; color: var(--text-subtle); padding: 12px 0; }
/* --- Dashboard: Liste der nächsten Termine (renderPlanDashboard()) --- */
.plan-upcoming-list { display: flex; flex-direction: column; gap: 8px; }
.plan-upcoming-item { display: flex; align-items: baseline; gap: 8px; font-size: 13px; }
.plan-upcoming-date {
color: var(--text-muted);
white-space: nowrap;
font-variant-numeric: tabular-nums;
min-width: 82px;
}
.plan-upcoming-item.overdue .plan-upcoming-date { color: var(--red); font-weight: 500; }
.plan-upcoming-kind {
font-size: 11px;
letter-spacing: 0;
color: var(--text-subtle);
}
.plan-dash-team { display: flex; flex-direction: column; gap: 8px; }
.plan-dash-team-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
/* === Bereich "Protokolle" (js/plan/plan-protokoll.js) ===
Listenansicht (.protokoll-row je Protokoll) und Detailansicht
(.protokoll-field-grid Kopf, Teilnehmer- und Punkte-Block). Der
Punkte-Block ist ZWEIGETEILT (.protokoll-split): links eine schmale
Liste aller Punkte nach Gruppen (.protokoll-liste), rechts der
Schreibbereich für den gerade ausgewählten (.protokoll-schreiben) —
Begründung bei .protokoll-split weiter unten. Gruppierung bleibt freier
Text, keine feste Liste, siehe CLAUDE.md "### Protokolle".
Das Neu-Kennzeichen ist seit dieser Umstellung ein schlichter Chip
(.protokoll-chip-neu, Gelb-Token --protokoll-neu-bg/-border — bewusst
nicht --band-neu, das im Wochenbericht schon blau "neu kommentiert"
bedeutet) statt einer Einfärbung ganzer Zeilen und Felder; der Status
eines Punkts erscheint als farbiger Punkt im Listeneintrag
(.protokoll-punkt-dot) und als Umschalter im Kopf des Schreibbereichs.
Damit entfällt das frühere Gegeneinander von Zeilen-Gelb und
Feldrahmen. */
.protokoll-list-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.protokoll-row {
display: grid;
grid-template-columns: 64px 1fr 140px 170px 100px;
align-items: center;
gap: 12px;
padding: 12px 4px;
border-bottom: 1px solid var(--line-soft);
cursor: pointer;
transition: background .12s var(--ease);
}
.protokoll-row:last-child { border-bottom: none; }
.protokoll-row:hover { background: var(--surface-alt); }
.protokoll-nr { font-variant-numeric: tabular-nums; font-weight: 500; color: var(--text-muted); font-size: 13px; }
.protokoll-betreff { font-weight: 560; font-size: 13px; }
.protokoll-datum { display: block; font-weight: 400; color: var(--text-subtle); font-size: 12px; margin-top: 2px; }
.protokoll-verfasser { color: var(--text-muted); font-size: 13px; }
.protokoll-punkte-status { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); }
.protokoll-status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); flex-shrink: 0; }
.protokoll-punkte-status.ist-leer .protokoll-status-dot { background: var(--green); }
.protokoll-teilnehmer-count { color: var(--text-subtle); font-size: 13px; text-align: right; }
.protokoll-back-link { display: flex; align-items: center; gap: 6px; color: var(--text-muted); font-size: 13px;
margin-bottom: 12px; cursor: pointer; width: fit-content; }
.protokoll-back-link:hover { color: var(--text); }
.protokoll-import-banner { background: var(--protokoll-neu-bg); border: 1px solid var(--protokoll-neu-border);
border-radius: var(--r-md); padding: 12px 16px; font-size: 13px; color: var(--text); margin-bottom: 12px; }
/* KI-Erkennung angefordert, aber fehlgeschlagen (kein Schlüssel, Netzwerk-
fehler, unerwartete Antwort …) — eigene, wärmere Farbe als der neutrale
Import-Hinweis darüber, damit ein echter Fehlschlag nicht im selben Ton
wie eine normale Information untergeht. Rein clientseitig für GENAU den
Import, der ihn ausgelöst hat (currentProtokoll._kiFallbackHinweis,
js/plan/plan-protokoll.js) — beim erneuten Öffnen des Protokolls vom
Server aus ist er wieder weg, das einmalige Ereignis ist dann bereits
zur Kenntnis genommen. */
.protokoll-ki-fallback-banner { background: color-mix(in srgb, var(--amber) 10%, transparent); border: 1px solid var(--amber);
border-radius: var(--r-md); padding: 12px 16px; font-size: 13px; color: var(--text); margin-bottom: 12px; }
/* Ladehinweis im Import-Dialog (#protokollImportLoading, Test.html): ohne
ihn wirkte der Dialog während eines länger laufenden KI-Aufrufs (bis zu
KI_TIMEOUT_MS_LOKAL = 30 Minuten bei einem eigenen Server, server.js) wie
hängengeblieben — Felder und Knöpfe werden während der Anfrage zusätzlich
gesperrt (setzeProtokollImportLadezustand(), plan-protokoll.js), damit
kein zweiter Import gleichzeitig losgeschickt wird.
[hidden] MUSS hier explizit auf display:none gesetzt werden: das
HTML-Attribut hidden bewirkt das nur über eine UA-Regel niedrigster
Priorität, die eigene display:flex-Regel direkt darunter hätte sie sonst
überschrieben und den Kasten dauerhaft sichtbar gemacht — genau das ist
beim ersten Versuch ohne diese Zeile passiert. */
.protokoll-import-loading[hidden] { display: none; }
.protokoll-import-loading { display: flex; align-items: center; gap: 8px; margin-top: 12px;
padding: 12px 12px; background: var(--surface-alt); border: 1px solid var(--line-soft);
border-radius: var(--r-md); font-size: 13px; color: var(--text-muted); }
.protokoll-import-spinner { width: 15px; height: 15px; flex-shrink: 0; border-radius: 50%;
border: 2px solid var(--line); border-top-color: var(--accent);
animation: protokoll-import-spin .8s linear infinite; }
@keyframes protokoll-import-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* "TODOs aus Protokoll" (js/plan/plan-protokoll-todos.js): die drei Segmente
oben im Dialog zeigen den Fortschritt durch Hochladen → Punkte →
Aufgaben — erledigte/aktuelle Schritte gefüllt, kommende leer. Entwurf
"A — Schritt-Dialog" (Taste-Skill-Vergleich, Eriks Wahl). */
.protokoll-todos-steps { display: flex; gap: 4px; margin: 12px 0 16px; }
.protokoll-todos-steps .seg { flex: 1; height: 4px; border-radius: 4px; background: var(--line-soft); }
.protokoll-todos-steps .seg.done { background: var(--accent); }
/* Schritt 3 ("Aufgaben bestätigen"), Entwurfsrichtung "B — Kompakte Zeilen"
aus einem zweiten Taste-Skill-Vergleich (Eriks Wahl): eine Zeile je
Vorschlag statt einer ausführlichen Karte — ein echter Testlauf lieferte
bereits 19 Vorschläge aus einem Protokoll, als Karten wäre das nur noch
Scrollen gewesen. Termin/Zuständig stehen als Abzeichen schon in der
eingeklappten Zeile; Beschreibung und die volle Bearbeitung (Termin-Feld,
Zuständigen-Auswahl) erscheinen erst nach Antippen der Zeile
(.protokoll-todo-vorschlag.open). */
.pt-sel-bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.pt-sel-count { font-size: 13px; color: var(--text-muted); }
.pt-sel-count b { color: var(--accent); font-weight: 600; }
.pt-sel-actions button { appearance: none; border: none; background: none; font: inherit; font-size: 12px;
font-weight: 500; color: var(--accent); cursor: pointer; padding: 2px 4px; }
.pt-sel-actions button:hover { text-decoration: underline; }
.protokoll-todo-vorschlag { border-bottom: 1px solid var(--line-soft); }
.protokoll-todo-vorschlag:last-child { border-bottom: none; }
.pt-row-main { display: flex; align-items: center; gap: 8px; padding: 8px 6px; cursor: pointer; }
.protokoll-todo-vorschlag.off .pt-row-main { opacity: .45; }
.pt-row-main .pt-vorschlag-check { flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }
.pt-row-main .pt-vorschlag-titel { flex: 1; min-width: 0; border: none; background: none; font: inherit;
font-weight: 500; font-size: 12.8px; color: var(--text); padding: 2px 0;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pt-row-badges { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.pt-badge-date { font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 6px;
background: var(--accent-soft); color: var(--accent); white-space: nowrap; }
/* Pille statt perfektem Kreis: ein Kürzel ist 2-4 Zeichen lang (initialsForName(),
js/utils.js), ein starrer 18px-Kreis hätte "THK" o. Ä. abgeschnitten. */
.pt-badge-person { min-width: 18px; height: 18px; padding: 0 4px; border-radius: 999px;
background: var(--accent); color: var(--surface);
font-size: 11px; font-weight: 600; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.pt-chevron { color: var(--text-subtle); font-size: 11px; width: 12px; text-align: center;
transition: transform .15s; flex-shrink: 0; }
.protokoll-todo-vorschlag.open .pt-chevron { transform: rotate(90deg); }
.pt-row-detail { display: none; padding: 0 6px 12px; }
.protokoll-todo-vorschlag.open .pt-row-detail { display: block; }
.protokoll-todo-vorschlag-beschreibung { margin: 2px 0 8px 28px; }
.protokoll-todo-vorschlag-felder { margin-left: 28px; display: flex; flex-direction: column; gap: 6px; }
.protokoll-detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;
padding-bottom: 16px; border-bottom: 1px solid var(--line-soft); margin-bottom: 16px; }
.protokoll-detail-meta { color: var(--text-muted); font-size: 13px; }
.protokoll-field-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 20px; }
.protokoll-field { display: flex; flex-direction: column; gap: 4px; }
.protokoll-field label { font-size: 12px; color: var(--text-subtle); letter-spacing: 0; }
.protokoll-block { margin-top: 20px; }
.protokoll-block-head { margin-bottom: 8px; display: flex; align-items: center; justify-content: space-between; }
.protokoll-block-head h4 { margin: 0; font-size: 13px; font-weight: 500; }
.protokoll-teilnehmer-row { display: grid; grid-template-columns: 1fr 160px 100px 24px; gap: 8px; align-items: center;
padding: 8px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.protokoll-teilnehmer-row:last-of-type { border-bottom: none; }
.protokoll-anwesend-toggle { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); }
.protokoll-anwesend-toggle input { accent-color: var(--green); }
.protokoll-row-remove { color: var(--text-subtle); text-align: center; cursor: pointer; opacity: .6; flex-shrink: 0; }
.protokoll-row-remove:hover { opacity: 1; color: var(--red); }
/* ---------- Punkte: links Liste, rechts Schreibbereich ----------
Eriks Auswahl „Liste + Schreibbereich" aus dem Protokoll-schreiben-Mockup,
Ablösung der früheren durchgehenden Tabelle (eine Zeile je Punkt mit allen
Feldern nebeneinander). Begründung dort und im Kopf von
renderPunkteBlockHtml() (js/plan/plan-protokoll.js): ein Protokollpunkt ist
ein kleiner Fließtext, keine Tabellenzelle — in der Spalte blieb für den
Text weder Breite noch Höhe, Thema und Text klebten übereinander und die
Formatierungsleiste saß eingeklemmt dazwischen. */
.protokoll-split { display: grid; grid-template-columns: 290px minmax(0, 1fr); gap: 12px; align-items: start; }
.protokoll-liste {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
overflow: hidden; box-shadow: var(--sh-1);
}
.protokoll-liste-kopf {
padding: 8px 12px; background: var(--surface-alt); border-bottom: 1px solid var(--line);
font-size: 11px; font-weight: 600; letter-spacing: 0; color: var(--text-subtle);
}
/* Gruppen-Kopfzeile: Farbbalken links aus dem Gruppennamen gehasht
(protokollGruppeFarbe(), plan-protokoll.js — dasselbe Prinzip wie
projektFarbe() in der Auslastung), damit eine Gruppe ihre Farbe behält,
egal an welcher Position sie steht. Der Name selbst ist das Eingabefeld:
umbenennen wirkt auf alle Punkte der Gruppe. */
.protokoll-liste-gruppe {
display: flex; align-items: center; gap: 8px; padding: 8px 12px 8px 12px;
background: var(--surface-sunk); border-bottom: 1px solid var(--line-soft);
border-left: 3px solid var(--protokoll-gruppe-farbe, var(--accent));
}
.protokoll-liste-gruppe + .protokoll-liste-gruppe,
.protokoll-liste-zeile + .protokoll-liste-gruppe,
.protokoll-liste-neu + .protokoll-liste-gruppe { border-top: 1px solid var(--line); }
/* Dieselbe !important-Begründung wie bei den übrigen randlosen Feldern
weiter unten: die Dark-Mode-Fassung von input[type=text] (styles.css)
hängt ein html-Element vor den Selektor und gewinnt sonst. */
.protokoll-liste-gruppe input.protokoll-gruppe-heading {
flex: 1; min-width: 0; font-size: 12px; font-weight: 600; letter-spacing: .01em;
border: none !important; background: none !important; border-radius: 4px !important;
color: var(--text) !important; padding: 2px 4px !important;
}
.protokoll-liste-gruppe input.protokoll-gruppe-heading::placeholder { color: var(--text-subtle); font-weight: 500; }
.protokoll-liste-gruppe input.protokoll-gruppe-heading:focus { outline: none; }
.protokoll-liste-gruppe input.protokoll-gruppe-heading:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft) inset; }
.protokoll-liste-gruppe .count {
font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text-subtle);
background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; flex-shrink: 0;
}
.protokoll-liste-zeile {
display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; gap: 2px 8px; align-items: baseline;
padding: 8px 12px; cursor: pointer; border-bottom: 1px solid var(--line-soft);
border-left: 3px solid transparent;
}
.protokoll-liste-zeile:hover { background: var(--surface-alt); }
.protokoll-liste-zeile.ist-aktiv { background: var(--accent-soft); border-left-color: var(--accent); }
/* Jedes Kind bekommt seinen Platz im Raster AUSDRÜCKLICH zugewiesen. Mit
bloßer Auto-Platzierung zog der Status-Punkt (der als einziger eine
grid-row trug) die erste Spalte an sich, Nummer und Titel rutschten je
eine Spalte weiter und der Titel landete rechtsbündig in der schmalen
auto-Spalte — die Unterzeile blieb dann auf zwei Zeichen abgeschnitten. */
.protokoll-liste-zeile .nr {
grid-column: 1; grid-row: 1;
font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 600; color: var(--text-muted);
}
.protokoll-liste-zeile.ist-aktiv .nr { color: var(--accent); }
.protokoll-liste-zeile .titel {
grid-column: 2; grid-row: 1;
font-size: 13px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.protokoll-liste-zeile .titel.ist-leer { font-weight: 500; font-style: normal; color: var(--text-subtle); }
.protokoll-liste-zeile .sub {
grid-column: 2; grid-row: 2; font-size: 11px; color: var(--text-subtle);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Das Neu-Kennzeichen steht rechts unter dem Status-Punkt statt in einer
eigenen dritten Zeile — sonst wäre jeder Eintrag der Liste eine Zeile
höher, nur für einen Chip. */
.protokoll-liste-zeile .protokoll-chip-neu { grid-column: 3; grid-row: 2; justify-self: end; }
.protokoll-punkt-dot {
grid-column: 3; grid-row: 1; justify-self: end; align-self: center;
width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.protokoll-punkt-dot[data-status="offen"] { background: var(--status-offen); }
.protokoll-punkt-dot[data-status="erledigt"] { background: var(--status-erledigt); }
.protokoll-punkt-dot[data-status="info"] { background: var(--status-info); }
.protokoll-liste-neu {
padding: 8px 12px 8px 16px; color: var(--accent); font-size: 12px; font-weight: 500; cursor: pointer;
border-bottom: 1px solid var(--line-soft);
}
.protokoll-liste-neu:hover { background: var(--surface-alt); color: var(--accent-hover); }
.protokoll-liste-neu.ist-gruppe { border-bottom: none; border-top: 1px solid var(--line); }
.protokoll-liste-leer { padding: 16px 12px; font-size: 13px; color: var(--text-subtle); }
/* ---------- Schreibbereich ---------- */
.protokoll-schreiben {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
overflow: hidden; box-shadow: var(--sh-1);
}
.protokoll-schreiben.ist-leer { padding: 28px 24px; color: var(--text-muted); font-size: 13px; }
.protokoll-schreiben.ist-leer p { margin: 0 0 6px; }
.protokoll-schreiben.ist-leer p:last-child { margin-bottom: 0; }
.protokoll-schreiben-kopf {
display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
padding: 8px 16px; background: var(--surface-alt); border-bottom: 1px solid var(--line-soft);
}
.protokoll-schreiben-kopf .nr { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 13px; }
.protokoll-schreiben-kopf .gruppe {
font-size: 11px; font-weight: 600; letter-spacing: 0; color: var(--text-subtle);
}
.protokoll-schreiben-kopf .rechts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.protokoll-feld-label {
display: block; font-size: 11px; font-weight: 600; letter-spacing: 0;
color: var(--text-subtle); margin-bottom: 4px;
}
.protokoll-schreiben-feld { padding: 12px 16px; }
.protokoll-schreiben-feld + .protokoll-schreiben-feld { border-top: 1px solid var(--line-soft); }
/* Thema und Text sitzen randlos in ihrem beschrifteten Abschnitt — der
Abschnitt selbst (Linie + Label) sagt schon, wo man schreibt, ein
zusätzlicher Feldrahmen gäbe zwei Kästen umeinander. !important wie
überall hier gegen die Dark-Mode-Fassung von input[type=text]
(html:not([data-theme="light"]) …, styles.css), die sonst an Spezifität
gewinnt und ein abgerundetes Eingabefeld-Rechteck durchscheinen lässt. */
.protokoll-schreiben-feld input.protokoll-punkt-thema {
font: inherit; font-size: 19px; font-weight: 500; letter-spacing: 0; width: 100%; line-height: 1.3;
border: none !important; background: none !important; border-radius: 4px !important;
color: var(--text) !important; padding: 1px 2px !important; display: block;
}
.protokoll-schreiben-feld input.protokoll-punkt-thema::placeholder { font-weight: 500; color: var(--text-subtle); }
.protokoll-schreiben-feld .protokoll-punkt-text {
font: inherit; font-size: 13px; line-height: 1.65; color: var(--text);
min-height: 130px; max-width: 66ch; padding: 1px 2px; border-radius: 4px;
}
.protokoll-schreiben-feld .protokoll-punkt-text:empty::before { content: attr(data-placeholder); color: var(--text-subtle); }
.protokoll-schreiben-feld input.protokoll-punkt-thema:focus,
.protokoll-schreiben-feld .protokoll-punkt-text:focus { outline: none; }
.protokoll-schreiben-feld input.protokoll-punkt-thema:focus-visible,
.protokoll-schreiben-feld .protokoll-punkt-text:focus-visible { box-shadow: 0 0 0 2px var(--accent-soft) inset; }
/* ist-geaendert: NUR das geänderte Feld eines fortgeschriebenen Punkts gelb
markiert (Eriks Wunsch) — derselbe Gelb-Ton wie das Neu-Kennzeichen, hier
aber feldweise, weil der Punkt selbst ja derselbe geblieben ist, nur sein
Inhalt nicht. */
.protokoll-schreiben-feld input.protokoll-punkt-thema.ist-geaendert,
.protokoll-schreiben-feld .protokoll-punkt-text.ist-geaendert {
background: var(--protokoll-neu-bg) !important; padding: 4px 6px !important; margin: 0 -4px;
}
/* Die Formatierungsleiste sitzt zwischen Thema und Text — sie gehört zum
Textfeld darunter, nicht zum Thema darüber (Thema ist reiner Text ohne
Auszeichnung). */
.protokoll-schreiben .richtext-toolbar { border-top: 1px solid var(--line-soft); }
.protokoll-schreiben-raster {
display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
padding: 12px 16px; border-top: 1px solid var(--line-soft);
}
.protokoll-schreiben-raster input {
font: inherit !important; font-size: 13px !important; width: 100%; min-width: 0 !important;
color: var(--text) !important; background: var(--surface) !important;
border: 1px solid var(--line) !important; border-radius: var(--r-sm) !important; padding: 6px 8px !important;
}
.protokoll-schreiben-raster input:focus {
outline: none; border-color: var(--accent) !important; box-shadow: 0 0 0 3px var(--accent-soft);
}
.protokoll-schreiben-fuss {
padding: 8px 16px; border-top: 1px solid var(--line-soft); background: var(--surface-alt);
font-size: 11px; color: var(--text-subtle);
}
.protokoll-schreiben-fuss .hint { font-size: 11px; }
/* ---------- Chips, Verschieben, Entfernen ---------- */
.protokoll-chip-neu {
display: inline-block; width: fit-content; background: var(--protokoll-neu-border); color: #3d2e00;
font-size: 11px; font-weight: 600; letter-spacing: 0; padding: 1px 6px;
border-radius: 6px;
}
/* Gnadenrunde eines erledigten Punkts — bewusst Fließtext statt
Großbuchstaben-Pille: der Hinweistext ist zu lang dafür. */
.protokoll-chip-entfaellt {
display: inline-block; max-width: 100%;
background: color-mix(in srgb, var(--red) 15%, transparent); color: var(--red);
font-size: 11px; font-weight: 600; line-height: 1.3; padding: 2px 8px; border-radius: var(--r-sm);
}
.protokoll-gruppe-move, .protokoll-punkt-move { display: inline-flex; gap: 4px; flex-shrink: 0; }
/* button.secondary (styles.css) bringt eine eigene, leicht deckende Fläche
mit, die hier wie ein grauer Fleck wirkte. !important nötig: die
Dark-Mode-Fassung von button.secondary hängt ein html-Element vor den
Selektor und gewinnt sonst an Spezifität. */
.protokoll-gruppe-move button, .protokoll-punkt-move button {
padding: 1px 6px; line-height: 1.4; font-size: 11px;
background: transparent !important; color: var(--text-subtle) !important;
}
.protokoll-gruppe-move button:hover:not(:disabled),
.protokoll-punkt-move button:hover:not(:disabled) { color: var(--text) !important; }
.protokoll-gruppe-move button:disabled, .protokoll-punkt-move button:disabled { opacity: .3; cursor: default; }
/* ---------- Status-Umschalter ----------
Senkrecht gestapelt in der Grundform; im Kopf des Schreibbereichs ist
Platz, dort liegt er waagerecht. */
.protokoll-status-switch {
display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 8px; padding: 2px;
background: var(--surface-sunk); gap: 1px; width: 56px;
}
.protokoll-status-switch.ist-waagerecht { flex-direction: row; width: auto; border-radius: 8px; }
.protokoll-status-switch button {
appearance: none; border: none; background: none; font: inherit; font-size: 11px; font-weight: 600;
letter-spacing: .01em; padding: 4px 0; border-radius: 6px; cursor: pointer; color: var(--text-subtle);
text-align: center; transition: background .12s, color .12s;
}
.protokoll-status-switch.ist-waagerecht button { padding: 4px 12px; border-radius: 6px; }
.protokoll-status-switch button:hover:not(.is-active) { color: var(--text); }
.protokoll-status-switch button:disabled { cursor: default; }
.protokoll-status-switch button:disabled:hover { color: var(--text-subtle); }
.protokoll-status-switch button.offen.is-active { background: var(--status-offen); color: #fff; }
.protokoll-status-switch button.erledigt.is-active { background: var(--status-erledigt); color: #fff; }
.protokoll-status-switch button.info.is-active { background: var(--status-info); color: #fff; }
@media (max-width: 900px){
.protokoll-row { grid-template-columns: 1fr; gap: 4px; }
.protokoll-field-grid { grid-template-columns: 1fr; }
/* Unter 900px stehen Liste und Schreibbereich untereinander — nebeneinander
bliebe für den Text keine lesbare Zeilenlänge mehr. */
.protokoll-split { grid-template-columns: minmax(0, 1fr); }
.protokoll-schreiben-raster { grid-template-columns: 1fr; }
}
.add-row-btn { display: flex; align-items: center; gap: 6px; color: var(--accent); font-size: 13px;
font-weight: 500; cursor: pointer; padding: 8px 0; width: fit-content; }
.add-row-btn:hover { color: var(--accent-hover); }
.legend-swatch { width: 13px; height: 13px; border-radius: 4px; flex-shrink: 0; display: inline-block; }
.legend-swatch.neu { background: var(--protokoll-neu-bg); border: 1.5px solid var(--protokoll-neu-border); }
.legend-swatch.info { background: var(--status-info-bg); border: 1.5px solid var(--status-info); }
/* ============================================================
BEWEGUNG - Stufe "Spürbar", Teil Projektbereich
============================================================
Ergänzung zum gleichnamigen Block am Ende von styles.css; die
Tokens (--dur, --ease-out, --row-lift, --press) stehen dort in
:root und gelten hier mit. Erfasst die Zeilenarten, die es nur
im Projektbereich gibt.
============================================================ */
/* Anklickbare Zeilen: anheben + einfahrende Akzentleiste, exakt wie
die Projektliste. Auch hier als inset-Schatten statt ::before -
die Aufgabenzeilen des GANTT sind ziehbar (plan-drag.js), ein
Stapelkontext auf der Zeile wäre dort riskant. */
.todo-depends-item,
.pt-row-main,
.plan-task-row {
transition: background var(--dur) var(--ease-out),
box-shadow var(--dur) var(--ease-out),
transform var(--dur) var(--ease-out);
}
.todo-depends-item:hover,
.pt-row-main:hover,
.plan-task-row:hover {
transform: translateY(var(--row-lift));
box-shadow: inset 3px 0 0 0 var(--accent);
}
.todo-depends-item:active,
.pt-row-main:active,
.plan-task-row:active { transform: translateY(0); transition-duration: 60ms; }
/* Die Protokoll-Zeile ist der eine Sonderfall: sie trägt bereits einen
eigenen linken Rand (border-left: 3px solid transparent, oben), den
der aktive Punkt auf die Akzentfarbe setzt. Hier NICHT zusätzlich den
inset-Schatten verwenden - beides zusammen ergäbe 6 px Akzent statt 3.
Stattdessen wird genau dieser vorhandene Rand animiert, das Anheben
bleibt identisch zu allen anderen Zeilen. */
.protokoll-liste-zeile {
transition: background var(--dur) var(--ease-out),
border-left-color var(--dur) var(--ease-out),
transform var(--dur) var(--ease-out);
}
.protokoll-liste-zeile:hover {
transform: translateY(var(--row-lift));
border-left-color: var(--accent);
}
.protokoll-liste-zeile:active { transform: translateY(0); transition-duration: 60ms; }
/* Bereichs-Reiter des Projektbereichs: Druckpunkt wie jeder andere
Schalter. Die Unterstreichung des aktiven Reiters bleibt wie sie ist. */
.plan-nav-item { transition: color var(--dur) var(--ease-out),
border-color var(--dur) var(--ease-out),
transform var(--dur) var(--ease-out); }
.plan-nav-item:active { transform: scale(var(--press)); }
/* Aufklapp-Pfeil der Vorschlagszeile ("TODOs aus Protokoll"): dreht
sich jetzt mit derselben Dauer wie der Pfeil der Projektliste
(.board-chev), statt mit einem eigenen Wert. */
.pt-chevron { transition: transform var(--dur) var(--ease-out); }
/* ===========================================================================
Projekt-Dashboard "Lagebild" (Eriks Wahl aus drei Anordnungen):
Lageband oben (#planKpiRow), darunter zwei Spalten, die sich unabhängig
füllen — links Kommentar + Termine, rechts Phasen, Team, Unterlagen.
=========================================================================== */
.plan-lage-band {
display: grid; grid-template-columns: minmax(0, 1.35fr) repeat(3, minmax(0, 1fr));
background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-lg);
box-shadow: var(--sh-1); padding: 4px;
}
.plan-lage-zelle { padding: 12px 16px; min-width: 0; }
.plan-lage-zelle + .plan-lage-zelle { border-left: 1px solid var(--line-soft); }
.plan-lage-zelle .kpi-label { font-size: 11px; font-weight: 500; letter-spacing: 0; color: var(--text-subtle); }
.plan-lage-zelle .kpi-value { font-size: 24px; font-weight: 500; letter-spacing: 0; margin-top: 2px; font-variant-numeric: tabular-nums; }
.plan-lage-zelle .kpi-sub { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-lage-zelle .kpi-sub.ist-rot { color: var(--red); font-weight: 500; }
.plan-lage-phase { display: flex; align-items: center; gap: 12px; }
.plan-lage-ring {
flex: none; width: 54px; height: 54px; border-radius: 50%;
background: conic-gradient(var(--accent) calc(var(--p) * 1%), color-mix(in srgb, var(--text-subtle) 18%, transparent) 0);
-webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
mask: radial-gradient(farthest-side, transparent calc(100% - 7px), #000 calc(100% - 6px));
}
.plan-lage-raster { display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr); gap: 12px; align-items: start; margin-top: 12px; }
.plan-lage-spalte { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.plan-lage-spalte .plan-panel { box-shadow: var(--sh-1); }
@media (max-width: 1000px) {
.plan-lage-band { grid-template-columns: 1fr 1fr; }
.plan-lage-zelle + .plan-lage-zelle { border-left: 0; }
.plan-lage-raster { grid-template-columns: 1fr; }
}
.plan-panel-title .plan-panel-link, .plan-unterlage-kopf .plan-panel-link { margin-left: auto; }
.plan-panel-link {
appearance: none; border: 0; background: none !important; box-shadow: none !important; padding: 0;
color: var(--accent); font: inherit; font-size: 12px; font-weight: 500; cursor: pointer;
}
.plan-panel-link:hover { text-decoration: underline; }
.plan-panel-link:active { transform: none; }
.plan-kommentar-fuss { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.plan-kommentar-autor { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-subtle); }
.plan-kommentar-autor:empty { display: none; }
.plan-autor-ava { width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center; font-size: 11px; font-weight: 600; background: var(--accent-soft); color: var(--accent); }
.plan-kommentar-fuss .plan-verweis-row { margin-left: auto; }
.plan-termin-gruppe { display: flex; gap: 6px; align-items: baseline; font-size: 11px; font-weight: 600; letter-spacing: 0; color: var(--text-subtle); padding: 12px 0 2px; }
.plan-termin-gruppe:first-child { padding-top: 0; }
.plan-termin-gruppe span { font-weight: 500; letter-spacing: 0; }
.plan-termin-gruppe.ist-rot { color: var(--red); }
.plan-termin { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 8px; align-items: center; padding: 8px 6px; margin: 0 -6px; border-top: 1px solid var(--line-soft); border-radius: 8px; }
.plan-termin-gruppe + .plan-termin { border-top: 0; }
.plan-termin.ist-klickbar { cursor: pointer; }
.plan-termin.ist-klickbar:hover { background: var(--surface-sunk); }
.plan-termin-art { width: 22px; height: 22px; border-radius: 8px; display: grid; place-items: center; font-size: 11px; font-weight: 600; background: var(--surface-sunk); color: var(--text-muted); }
.plan-termin-art.ist-meins { background: var(--accent-soft); color: var(--accent); }
.plan-termin-art.ist-ms { background: color-mix(in srgb, #6d4bb3 14%, transparent); color: #6d4bb3; }
.plan-termin-text { min-width: 0; display: flex; flex-direction: column; }
.plan-termin-text b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-termin-text span { font-size: 12px; color: var(--text-subtle); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-termin-datum { text-align: right; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.plan-termin-datum em { display: block; font-style: normal; font-size: 11px; color: var(--text-subtle); }
.plan-termin-datum.ist-rot, .plan-termin-datum.ist-rot em { color: var(--red); }
.plan-termin-mehr { margin-top: 8px; }
.plan-team-zeile { display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; gap: 8px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line-soft); }
.plan-team-zeile:first-child { border-top: 0; padding-top: 0; }
.plan-team-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.plan-team-text b { font-weight: 500; }
.plan-team-rollen { display: flex; flex-wrap: wrap; gap: 4px; }
.plan-rolle { font-size: 11px; font-weight: 500; padding: 1px 8px; border-radius: 6px; background: var(--accent-soft); color: var(--accent); }
.plan-rolle.ist-neben { background: transparent; border: 1px dashed var(--line); color: var(--text-muted); }
.plan-team-offen { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.plan-unterlage { padding: 8px 6px; margin: 0 -6px; border-top: 1px solid var(--line-soft); border-radius: 8px; cursor: pointer; }
.plan-unterlage:first-child { border-top: 0; padding-top: 2px; }
.plan-unterlage:hover { background: var(--surface-sunk); }
.plan-unterlage-kopf { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.plan-unterlage-kopf b { font-weight: 500; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .plan-termin-art.ist-ms { color: #c3a6ff; } }
html[data-theme="dark"] .plan-termin-art.ist-ms { color: #c3a6ff; }
/* Kommentar der Sitzung im Projekt-Dashboard größer (Eriks Wunsch): Das
allgemeine .status-edit ist auf die enge Zeile des Boards ausgelegt
(11px). Hier ist er das wichtigste Lesefeld des Lagebilds. */
#planSection-dashboard #planStatusEdit {
font-size: 15px;
line-height: 1.6;
padding: 16px 16px;
min-height: 160px;
border-radius: var(--r-md);
border-style: solid;
}
/* Kommentar der Sitzung mit Verlauf (Eriks Wahl "A"): gezeigt wird der
zuletzt geschriebene Kommentar; stammt er aus einer früheren Sitzung,
sagt das der Hinweis darüber. Darunter eine Zeitleiste der früheren
Kommentare je Gewerk (renderPlanKommentarVerlauf(), plan-info.js). */
.plan-kommentar-hinweis {
margin-bottom: 8px; padding: 8px 12px; border-radius: var(--r-sm, 8px);
font-size: 13px; line-height: 1.45;
color: var(--text);
background: color-mix(in srgb, var(--amber) 16%, transparent);
border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
}
.plan-kommentar-verlauf { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.plan-verlauf-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.plan-verlauf-titel { font-size: 12px; font-weight: 500; letter-spacing: 0; color: var(--text-muted); }
.plan-verlauf-anzahl { font-size: 12px; color: var(--text-subtle); }
.plan-verlauf-liste { list-style: none; margin: 0; padding: 0; }
.plan-verlauf-eintrag { display: grid; grid-template-columns: 52px 12px minmax(0, 1fr); column-gap: 8px; }
.plan-verlauf-kw { font-size: 12px; font-weight: 500; color: var(--text); padding-top: 1px; white-space: nowrap; }
.plan-verlauf-punkt { position: relative; }
.plan-verlauf-punkt::before {
content: ""; position: absolute; left: 1.5px; top: 5px;
width: 9px; height: 9px; border-radius: 50%;
background: color-mix(in srgb, var(--accent) 45%, transparent);
}
.plan-verlauf-eintrag.ist-juengster .plan-verlauf-punkt::before { background: var(--accent); }
.plan-verlauf-punkt::after {
content: ""; position: absolute; left: 5px; top: 17px; bottom: 0; width: 2px; background: var(--line);
}
.plan-verlauf-eintrag:last-child .plan-verlauf-punkt::after { display: none; }
.plan-verlauf-inhalt { padding-bottom: 16px; min-width: 0; }
.plan-verlauf-text { font-size: 13px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere; }
.plan-verlauf-text p { margin: 0; }
.plan-verlauf-meta { font-size: 12px; color: var(--text-subtle); margin-top: 4px; }
.plan-verlauf-mehr {
border: 1px solid var(--line); background: var(--surface); color: var(--accent);
border-radius: 8px; padding: 6px 16px; font: inherit; font-size: 13px; cursor: pointer;
}
.plan-verlauf-mehr:hover { background: var(--surface-alt); }
/* Dashboard-Kachel "Protokolle" (Eriks Wunsch, renderProtokolleSummary()
in plan-protokoll.js): letztes Protokoll, seine offenen Punkte in der
Zeilenform der Termine, darunter die früheren als Kurzliste. */
#planDashProtokollePanel .plan-termin { grid-template-columns: auto minmax(0, 1fr) auto; }
#planDashProtokollePanel .plan-termin-art { width: auto; min-width: 34px; padding: 0 6px; box-sizing: border-box; }
.plan-prot-kopf {
display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
font: inherit; color: var(--text); background: var(--surface-sunk);
border: 1px solid var(--line-soft); border-radius: var(--r-md, 12px);
padding: 12px 12px; cursor: pointer;
}
.plan-prot-kopf:hover { border-color: var(--accent); }
.plan-prot-nr {
flex: none; font-size: 12px; font-weight: 600; color: var(--accent);
background: var(--accent-soft); border-radius: 8px; padding: 4px 8px;
}
.plan-prot-titel { min-width: 0; display: flex; flex-direction: column; }
.plan-prot-titel b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-prot-titel span { font-size: 12px; color: var(--text-subtle); }
.plan-prot-punkte { margin-top: 8px; }
.plan-prot-punkte:empty { display: none; }
.plan-prot-mehr { display: block; margin-top: 6px; }
.plan-prot-frueher {
display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: baseline;
width: 100%; text-align: left; font: inherit; font-size: 13px; color: var(--text-muted);
background: none; border: 0; border-top: 1px solid var(--line-soft); padding: 8px 6px; cursor: pointer; border-radius: 8px;
}
.plan-termin-gruppe + .plan-prot-frueher { border-top: 0; }
.plan-prot-frueher:hover { background: var(--surface-sunk); }
.plan-prot-frueher-titel { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-prot-frueher-zahl { color: var(--amber); font-size: 12px; white-space: nowrap; }
.plan-dash-leer { display: flex; align-items: center; gap: 8px; color: var(--text-subtle); font-size: 13px; }
/* Kachel "Team" nach Gewerk gruppiert (Eriks Wahl "A", plan-sections.js):
je Gewerk eine Überschrift mit Personenzahl; ein Gewerk des Projekts ohne
Beteiligte zeigt einen Hinweis statt zu verschwinden. */
.plan-team-gruppe + .plan-team-gruppe { margin-top: 6px; }
.plan-team-gewerk { display: flex; align-items: center; gap: 8px; padding: 6px 0 4px; }
.plan-team-gruppe:first-child .plan-team-gewerk { padding-top: 0; }
.plan-gewerk-schild { font-size: 11px; font-weight: 600; letter-spacing: .04em; padding: 2px 8px; border-radius: 6px; background: var(--accent-soft); color: var(--accent); }
.plan-gewerk-titel { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.plan-gewerk-linie { flex: 1; height: 1px; background: var(--line-soft); }
.plan-gewerk-anzahl { font-size: 12px; color: var(--text-subtle); white-space: nowrap; }
.plan-team-gewerk + .plan-team-zeile { border-top: 0; }
.plan-team-luecke { font-size: 13px; color: var(--amber); padding: 2px 0 6px; }
/* Einstellungen mit Unternavigation (Eriks Wahl "C", plan-settings.js):
links vier Abschnitte mit Kurzfassung, rechts immer genau einer. */
.plan-einst { display: flex; gap: 12px; align-items: flex-start; margin-top: 4px; }
.plan-einst-nav {
flex: none; width: 260px; position: sticky; top: 90px;
display: flex; flex-direction: column; gap: 4px; padding: 8px;
background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-lg);
}
.plan-einst-reiter {
display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left;
min-height: 56px; padding: 8px 16px; border: 0; border-radius: 12px;
background: transparent; color: var(--text); font: inherit; cursor: pointer;
}
.plan-einst-reiter b { font-size: 13px; font-weight: 500; }
.plan-einst-reiter span { font-size: 12px; color: var(--text-muted); line-height: 1.35; }
.plan-einst-reiter:hover { background: var(--surface-sunk); }
.plan-einst-reiter.is-active { background: var(--surface-sunk); box-shadow: inset 3px 0 0 var(--accent); }
.plan-einst-inhalt { flex: 1; min-width: 0; padding: 24px 28px; }
.plan-einst-titel { margin: 0 0 16px; font-size: 19px; font-weight: 500; }
.plan-einst-teil .form-row { max-width: 640px; }
.plan-einst-paar { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0 12px; max-width: 640px; }
.plan-einst-paar > .form-row { min-width: 0; margin-bottom: 6px; }
.plan-einst-teil[data-teil="auftrag"] .plan-einst-paar { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 460px; }
.plan-einst-hint { margin: 0 0 16px; max-width: 640px; line-height: 1.45; }
.form-row .plan-einst-hint { margin: 2px 0 0; }
.plan-einst-schmal { max-width: 320px; }
.plan-einst-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.plan-einst-chip {
min-height: 36px; padding: 0 16px; border-radius: 6px; font: inherit; font-size: 13px; cursor: pointer;
border: 1px solid var(--line); background: var(--surface); color: var(--text);
}
.plan-einst-chip.an { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 500; }
/* Umschalter (Leistungsphasen, Beteiligte) */
.plan-einst-seg { display: inline-flex; gap: 2px; padding: 4px; border-radius: 8px; background: var(--surface-sunk); }
.plan-einst-seg button {
border: 0; background: transparent; color: var(--text-muted); font: inherit; font-size: 13px;
min-height: 30px; padding: 0 12px; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.plan-einst-seg button.an { background: var(--surface); color: var(--accent); font-weight: 500; box-shadow: 0 1px 4px rgba(15,40,60,.12); }
.plan-einst-seg button:disabled { cursor: default; }
.plan-einst-phasen { display: flex; flex-direction: column; max-width: 760px; }
.plan-einst-phase { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line-soft); }
.plan-einst-phase-name { display: flex; align-items: center; gap: 12px; min-width: 0; }
.plan-einst-phase-name b { width: 52px; flex: none; font-size: 13px; }
.plan-einst-phase-name span { font-size: 13px; color: var(--text-muted); }
.plan-einst-phase.ist-an .plan-einst-phase-name span { color: var(--text); }
.plan-einst-phase-name em { font-style: normal; font-size: 11px; font-weight: 600; color: var(--accent); background: var(--accent-soft); border-radius: 6px; padding: 2px 8px; }
@media (max-width: 900px) {
.plan-einst { flex-direction: column; }
.plan-einst-nav { width: auto; position: static; flex-direction: row; overflow-x: auto; }
.plan-einst-reiter { flex: none; }
}
/* Zahlenfelder (Honorar, Projektgröße) wie die Textfelder daneben — die
allgemeine Feldregel in styles.css kennt type=number nicht; sie dort
aufzunehmen träfe auch kompakte Zahlenfelder anderer Bereiche. */
.plan-einst-teil input[type=number] {
padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--r-md);
font: inherit; font-size: 13px; color: var(--text); background: var(--surface);
}
.plan-einst-teil input[type=number]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
/* Dunkel ist der Akzent hell — weiße Schrift darauf wäre kaum lesbar. */
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .plan-einst-chip.an { color: #0b141b; } }
html[data-theme="dark"] .plan-einst-chip.an { color: #0b141b; }
/* Beteiligte als Personenliste (Eriks Wahl "B", renderEinstTeam() in
plan-settings.js): Besetzungsleiste, Suchfeld mit Vorschlägen, eine Zeile
je Person mit Rollen-Kapseln (umrandet = aus, voll = Haupt, gestrichelt
= Unterstützung), Entfernen mit "Rückgängig". */
.plan-einst-teil[data-teil="team"] { position: relative; }
.plan-einst-team-kopfzeile { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 8px 20px; }
.plan-einst-team-kopfzeile .plan-einst-hint { margin-bottom: 12px; }
.plan-einst-legende { display: flex; gap: 12px; font-size: 12px; color: var(--text-muted); margin-bottom: 16px; }
.plan-einst-legende span { display: inline-flex; align-items: center; gap: 6px; }
.plan-einst-legende i { width: 24px; height: 14px; border-radius: 999px; box-sizing: border-box; }
.plan-einst-legende i.ist-haupt { background: var(--accent); }
.plan-einst-legende i.ist-neben { border: 1.5px dashed var(--accent); background: var(--accent-soft); }
.plan-einst-sperre { padding: 12px 16px; border-radius: 12px; background: var(--surface-sunk); font-size: 13px; margin-bottom: 12px; }
.plan-einst-besetzung { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 16px; }
.plan-einst-besetzt { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 12px 12px; border-radius: 12px; background: var(--surface-sunk); border: 1px solid transparent; }
.plan-einst-besetzt b { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.plan-einst-besetzt span { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-einst-besetzt.ist-luecke { background: color-mix(in srgb, var(--amber) 10%, transparent); border: 1px dashed var(--amber); }
.plan-einst-besetzt.ist-luecke b, .plan-einst-besetzt.ist-luecke span { color: var(--amber); }
.plan-einst-suche { position: relative; display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; max-width: 640px; }
.plan-einst-suche[hidden] { display: none; }
.plan-einst-suche label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.plan-einst-suche input { height: 40px; box-sizing: border-box; font-size: 13px; }
.plan-einst-vorschlaege {
position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; max-height: 320px; overflow: auto;
padding: 6px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line);
box-shadow: 0 16px 40px rgba(15,40,60,.18);
}
html.glas .plan-einst-vorschlaege { background: var(--glas-dicht); }
.plan-einst-vorschlag-titel { font-size: 12px; font-weight: 500; color: var(--text-muted); padding: 8px 12px 4px; }
.plan-einst-vorschlag-leer { font-size: 13px; color: var(--text-muted); padding: 12px; }
.plan-einst-vorschlag {
display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; min-height: 48px; padding: 4px 12px;
border: 0; border-radius: 10px; background: transparent; color: var(--text); font: inherit; cursor: pointer;
}
.plan-einst-vorschlag:hover, .plan-einst-vorschlag:focus-visible { background: var(--surface-sunk); }
.plan-einst-vorschlag > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.plan-einst-vorschlag b { font-size: 13px; font-weight: 500; }
.plan-einst-vorschlag > span:last-child > span { font-size: 12px; color: var(--text-muted); }
.plan-einst-ava {
width: 34px; height: 34px; flex: none; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 600; background: var(--accent); color: #fff;
}
.plan-einst-gruppe { display: flex; align-items: center; gap: 8px; padding: 16px 0 6px; }
.plan-einst-zeile {
display: grid; grid-template-columns: minmax(200px, 1fr) auto 36px; gap: 8px 12px; align-items: center;
padding: 8px 12px; margin: 0 -10px; border-radius: 12px; border-top: 1px solid var(--line-soft);
transition: background-color var(--dur-lg, .2s) var(--ease-out, ease);
}
.plan-einst-gruppe + .plan-einst-zeile { border-top-color: transparent; }
.plan-einst-zeile.ist-neu { background: var(--accent-soft); }
.plan-einst-person { display: flex; align-items: center; gap: 12px; min-width: 0; }
.plan-einst-person b { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plan-einst-kapseln { display: flex; flex-wrap: wrap; gap: 6px; }
.plan-einst-kapsel {
min-height: 36px; padding: 0 16px; border-radius: 6px; box-sizing: border-box; white-space: nowrap;
border: 1px solid var(--line); background: transparent; color: var(--text-muted); font: inherit; font-size: 13px; cursor: pointer;
transition: transform var(--dur, .15s) var(--ease-out, ease), background-color var(--dur, .15s);
}
.plan-einst-kapsel:hover:not(:disabled) { border-color: var(--accent); color: var(--text); }
.plan-einst-kapsel:active:not(:disabled) { transform: scale(var(--press, .97)); }
.plan-einst-kapsel.ist-haupt { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 500; }
.plan-einst-kapsel.ist-neben { border: 1.5px dashed var(--accent); background: var(--accent-soft); color: var(--text); font-weight: 500; }
.plan-einst-kapsel.ist-fremd { border-color: transparent; opacity: .5; text-decoration: line-through; }
.plan-einst-kapsel:disabled { cursor: default; }
.plan-einst-weg { width: 36px; height: 36px; border-radius: 50%; border: 0; background: transparent; color: var(--text-muted); font-size: 19px; cursor: pointer; }
.plan-einst-weg:hover { background: var(--surface-sunk); color: var(--red); }
.plan-einst-leer { display: flex; flex-direction: column; gap: 6px; padding: 20px; border-radius: 14px; border: 1px dashed var(--line); margin-top: 8px; }
.plan-einst-leer b { font-size: 13px; font-weight: 500; }
.plan-einst-leer span { font-size: 13px; color: var(--text-muted); line-height: 1.5; }
.plan-einst-toast {
position: sticky; bottom: 16px; margin: 16px auto 0; width: max-content; max-width: 100%;
display: flex; align-items: center; gap: 12px; padding: 8px 8px 8px 16px; border-radius: 8px;
background: var(--text); color: var(--bg); font-size: 13px; box-shadow: 0 16px 40px rgba(15,40,60,.25);
}
.plan-einst-toast[hidden] { display: none; }
.plan-einst-toast button { min-height: 32px; padding: 0 16px; border-radius: 8px; border: 0; background: color-mix(in srgb, var(--bg) 18%, transparent); color: inherit; font: inherit; font-weight: 500; cursor: pointer; }
/* Dunkel ist der Akzent hell — Schrift darauf dunkel. */
@media (prefers-color-scheme: dark) {
html:not([data-theme="light"]) .plan-einst-kapsel.ist-haupt,
html:not([data-theme="light"]) .plan-einst-ava { color: #0b141b; }
}
html[data-theme="dark"] .plan-einst-kapsel.ist-haupt,
html[data-theme="dark"] .plan-einst-ava { color: #0b141b; }
@media (max-width: 900px) {
.plan-einst-besetzung { grid-template-columns: minmax(0, 1fr); }
.plan-einst-zeile { grid-template-columns: minmax(0, 1fr) 36px; }
.plan-einst-kapseln { grid-column: 1 / -1; order: 3; }
}
/* Gesperrte Sitzung: Die allgemeine :disabled-Regel (styles.css, 45 %)
machte "Haupt" und "aus" kaum unterscheidbar — die Kapseln sollen den
Stand weiter klar zeigen, nur nicht mehr klickbar sein. Fremde Rollen
bleiben bewusst blass. */
.plan-einst-kapsel:disabled:not(.ist-fremd) { opacity: 1; cursor: default; }
/* Leistungsphasen: kräftigere Hervorhebung (Eriks Wunsch). Vorher war die
gewählte Seite nur eine weiße Kapsel mit Akzentschrift auf hellgrauem
Grund — "Beauftragt" und "Nicht beauftragt" waren kaum auseinander-
zuhalten. Jetzt: beauftragt = gefüllte Akzentkapsel und die ganze Zeile
leicht getönt; nicht beauftragt = neutrale Kapsel, Zeile zurückgenommen;
"läuft" gefüllt. */
.plan-einst-phase { padding: 8px 12px; margin: 0 -10px; border-radius: 12px; }
.plan-einst-phase.ist-an { background: var(--accent-soft); border-top-color: transparent; }
.plan-einst-phase.ist-an + .plan-einst-phase { border-top-color: transparent; }
.plan-einst-phase .plan-einst-seg { background: var(--surface-sunk); border: 1px solid var(--line-soft); }
.plan-einst-phase .plan-einst-seg button { color: var(--text-muted); }
.plan-einst-phase .plan-einst-seg button.an:first-child { background: var(--accent); color: #fff; box-shadow: 0 1px 4px rgba(15,40,60,.18); }
.plan-einst-phase .plan-einst-seg button.an:last-child { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(15,40,60,.12); }
.plan-einst-phase:not(.ist-an) .plan-einst-phase-name b { color: var(--text-muted); }
.plan-einst-phase.ist-an .plan-einst-phase-name b { color: var(--accent); }
.plan-einst-phase-name em { background: var(--accent); color: #fff; }
.plan-einst-phase .plan-einst-seg button:disabled { opacity: 1; }
@media (prefers-color-scheme: dark) {
html:not([data-theme="light"]) .plan-einst-phase .plan-einst-seg button.an:first-child,
html:not([data-theme="light"]) .plan-einst-phase-name em { color: #0b141b; }
}
html[data-theme="dark"] .plan-einst-phase .plan-einst-seg button.an:first-child,
html[data-theme="dark"] .plan-einst-phase-name em { color: #0b141b; }
.plan-einst-phase + .plan-einst-phase { margin-top: 2px; }
@media (prefers-color-scheme: dark) {
html:not([data-theme="light"]) .plan-einst-phase .plan-einst-seg button.an:last-child { background: rgba(255,255,255,.16); }
}
html[data-theme="dark"] .plan-einst-phase .plan-einst-seg button.an:last-child { background: rgba(255,255,255,.16); }
/* Seitenpanel für Aufgabe und Meilenstein (Eriks Wahl "B"): rechts am
Rand, volle Höhe, der Terminplan bleibt links sichtbar (Hintergrund nur
leicht abgedunkelt, nicht verschwommen). Kopf und Fußleiste stehen fest,
nur der Inhalt scrollt. */
.modal-bg.als-panel {
justify-content: flex-end; align-items: stretch;
background: rgba(15,35,50,.14);
-webkit-backdrop-filter: none; backdrop-filter: none;
}
html.glas .modal-bg.als-panel { background: rgba(15,35,50,.14); -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .modal-bg.als-panel { background: rgba(0,0,0,.32); } }
html[data-theme="dark"] .modal-bg.als-panel { background: rgba(0,0,0,.32); }
.modal-bg.als-panel > .modal.pd {
width: 440px; max-width: 100%; height: 100%; max-height: none; padding: 0;
border-radius: var(--r-xl) 0 0 var(--r-xl);
display: flex; flex-direction: column; overflow: hidden;
box-shadow: -14px 0 44px rgba(15,40,60,.22);
animation: pd-rein var(--dur-lg, .2s) var(--ease-out, ease);
}
@keyframes pd-rein { from { transform: translateX(32px); opacity: 0; } to { transform: none; opacity: 1; } }
.pd-kopf { padding: 20px 24px 16px; border-bottom: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 8px; }
.pd-art { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; color: var(--text-muted); }
.pd-art .modal-kbd { margin-left: auto; font-weight: 400; }
.pd-kasten { width: 11px; height: 11px; border-radius: 4px; background: var(--accent); }
.pd-raute { width: 10px; height: 10px; background: var(--meilenstein, #6d4bb3); transform: rotate(45deg); margin: 0 1px; }
.pd-zu { width: 34px; height: 34px; border-radius: 50%; border: 0; background: transparent; color: var(--text-muted); font-size: 19px; line-height: 1; padding: 0; cursor: pointer; }
.pd-zu:hover { background: var(--surface-sunk); color: var(--text); }
.pd-kopf .pd-titel { width: 100%; box-sizing: border-box; font-size: 19px; font-weight: 500; padding: 8px 12px; }
.pd-inhalt { flex: 1; min-height: 0; overflow: auto; padding: 2px 24px 16px; }
.pd-abs { display: flex; flex-direction: column; gap: 8px; padding: 16px 0; border-bottom: 1px solid var(--line-soft); }
.pd-abs:last-child { border-bottom: 0; }
.pd-abs > h3 { margin: 0; font-size: 12px; font-weight: 500; color: var(--text-muted); }
.pd-abs .range-picker-display, .pd-abs select { width: 100%; box-sizing: border-box; }
.pd-abs .field-inline { display: flex; align-items: center; gap: 8px; }
.pd-abs .field-inline .range-picker-display { flex: 1; }
.pd-haken { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 400; }
.pd-hint { margin: 0; }
.pd-seg { width: 100%; }
.pd-seg button { flex: 1; justify-content: center; min-height: 32px; }
.pd-seg button:disabled { opacity: .45; }
.pd-liste { max-height: 300px; overflow: auto; }
.pd-abs .fold { margin: 0; }
.pd-fuss {
display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap;
padding: 16px 24px calc(16px + env(safe-area-inset-bottom, 0px));
border-top: 1px solid var(--line-soft); background: var(--surface-alt);
}
.pd-loeschen { margin-right: auto; background: transparent; border: 0; color: var(--red); padding: 8px 12px; font-weight: 500; }
.pd-loeschen:hover { background: color-mix(in srgb, var(--red) 10%, transparent); }
.pd-loeschen[hidden] { display: none; }
/* Aufwand einer Aufgabe in Stunden (zählt zur Auslastung). */
/* Aufwand im Aufgaben-Panel: Kopf, Stepper (−, Zahl, „Std.“, +),
Schnellwahl als kleine Kapseln, Umrechnung in Arbeitstage darunter.
Knöpfe tragen eigene Klassen bzw. stehen in eigenen Containern, damit die
allgemeine (Glas-)Knopfregel sie nicht akzentblau färbt. */
.pd-aufwand { display: grid; gap: 8px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.pd-aufwand-kopf { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.pd-aufwand-kopf label { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.pd-aufwand-kopf span { font-size: 11.5px; color: var(--text-subtle); }
.pd-aufwand-zeile { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pd-stepper {
display: inline-flex; align-items: center; height: 34px; border: 1px solid var(--line);
border-radius: 8px; background: var(--surface-sunk); overflow: hidden;
transition: border-color var(--dur, 150ms), box-shadow var(--dur, 150ms);
}
.pd-stepper:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.pd-stepper .pd-stepper-knopf {
all: unset; box-sizing: border-box; width: 32px; height: 100%; display: grid; place-items: center;
font-size: 15px; color: var(--text-muted); cursor: pointer;
}
.pd-stepper .pd-stepper-knopf:hover { background: var(--seg-hover); color: var(--text); }
.pd-stepper .pd-stepper-knopf:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pd-stepper input {
width: 52px; border: 0; background: transparent; padding: 0; text-align: right;
font: inherit; font-size: 15px; font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums;
-moz-appearance: textfield; appearance: textfield;
}
.pd-stepper input::-webkit-outer-spin-button, .pd-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pd-stepper input:focus { outline: none; }
/* Glas-/Dialog-Regeln für Eingabefelder geben dem Feld sonst eine eigene
Fläche mitten im Stepper — hier bewusst durchsichtig, der Rahmen ist die Kapsel. */
.pd-stepper input#todoEditAufwand { background: transparent !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
.pd-einheit { font-size: 12px; color: var(--text-muted); padding: 0 6px 0 4px; }
.pd-aufwand-schnell { display: flex; gap: 6px; flex-wrap: wrap; }
.pd-aufwand-schnell button {
all: unset; box-sizing: border-box; padding: 5px 11px; border-radius: var(--r-pill); cursor: pointer;
font-size: 12px; color: var(--text-muted); border: 1px solid var(--line); background: transparent;
transition: background var(--dur, 150ms), color var(--dur, 150ms), border-color var(--dur, 150ms);
}
.pd-aufwand-schnell button:hover { background: var(--seg-hover); color: var(--text); }
.pd-aufwand-schnell button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pd-aufwand-schnell button[aria-pressed="true"] {
background: var(--accent-soft); color: var(--accent); font-weight: 600;
border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.pd-aufwand-info { font-size: 12px; color: var(--text-subtle); }
/* Terminplan aufgeräumt (Eriks Wahl "A", plan-gantt.js / plan-build-gantt.js):
eine Leiste statt zwei, Menüs "Mehr" und "+ Neu", Gliederung nach
Leistungsphasen mit zuklappbaren Köpfen, Filter, Hinweis "Ohne Termin". */
.tp-leiste {
gap: 8px; padding: 8px 12px; margin-bottom: 12px; border-radius: var(--r-lg);
background: var(--surface); border: 1px solid var(--line-soft);
}
.tp-luecke { flex: 1; }
.tp-seg button { min-height: 30px; }
.tp-zeitraum { width: 200px; }
.tp-menue { position: relative; }
.tp-menue > summary {
list-style: none; cursor: pointer; display: inline-flex; align-items: center; min-height: 34px; padding: 0 16px;
border-radius: 8px; border: 1px solid var(--line); background: var(--surface); color: var(--text); font-size: 13px; user-select: none;
}
.tp-menue > summary::-webkit-details-marker { display: none; }
.tp-neu > summary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 500; }
.tp-menue-liste {
position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; min-width: 250px; padding: 6px;
border-radius: 14px; background: var(--surface); border: 1px solid var(--line-soft); box-shadow: 0 16px 40px rgba(15,40,60,.22);
display: flex; flex-direction: column;
}
html.glas .tp-menue-liste { background: var(--glas-dicht); }
.tp-menue-liste.nach-rechts { right: auto; left: 0; }
.tp-menue-liste button, .tp-menue-liste label {
display: flex; align-items: center; gap: 8px; width: 100%; min-height: 38px; padding: 0 12px; box-sizing: border-box;
border: 0; border-radius: 8px; background: transparent; color: var(--text); font: inherit; font-size: 13px; font-weight: 400; text-align: left; cursor: pointer;
}
.tp-menue-liste button:hover, .tp-menue-liste label:hover { background: var(--surface-sunk); }
.tp-menue-liste button.active { color: var(--accent); font-weight: 500; }
.tp-menue-liste hr { border: 0; border-top: 1px solid var(--line-soft); margin: 6px 4px; width: auto; }
.tp-sym-aufgabe { width: 10px; height: 10px; border-radius: 4px; background: var(--accent); flex: none; }
.tp-sym-ms { width: 9px; height: 9px; background: var(--meilenstein, #7a3fb8); transform: rotate(45deg); flex: none; margin: 0 1px; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .tp-neu > summary { color: #0b141b; } }
html[data-theme="dark"] .tp-neu > summary { color: #0b141b; }
/* Projektzeile ruhiger */
#planGanttContainer .tp-projektzeile .gantt-label { font-weight: 500; color: var(--text-muted); font-size: 12px; }
/* Phasenköpfe */
#planGanttContainer .gantt-row.gantt-phase { background: var(--surface-sunk); }
#planGanttContainer .gantt-row.gantt-phase .gantt-label { background: var(--surface-sunk); padding-left: 6px !important; font-weight: 500 !important; color: var(--text) !important; gap: 6px; }
#planGanttContainer .gantt-row.gantt-phase .gantt-bar.todo { top: 50%; height: 10px; margin-top: -5px; border-radius: 999px; }
.tp-klappen { width: 24px; height: 24px; flex: none; border: 0; border-radius: 6px; background: transparent; color: var(--text-muted); font-size: 11px; cursor: pointer; padding: 0; }
.tp-klappen:hover { background: var(--surface); color: var(--text); }
.tp-phase-info { margin-left: auto; font-size: 12px; font-weight: 400; color: var(--text-muted); white-space: nowrap; }
#planGanttContainer .gantt-row.tp-gruppe .gantt-label { font-weight: 500; color: var(--text-muted); font-size: 12px; background: var(--surface-sunk); }
#planGanttContainer .gantt-row.tp-gruppe { background: var(--surface-sunk); min-height: 30px; }
/* Unter einem Phasenkopf eingerückt */
#planGanttContainer .gantt-row.gantt-todo:not(.gantt-phase) .gantt-label,
#planGanttContainer .gantt-row.gantt-milestone-row .gantt-label { padding-left: 32px !important; }
#planGanttContainer .gantt-row.gantt-zu,
#planGanttContainer .gantt-row.gantt-gefiltert { display: none; }
#planGanttContainer .gantt-row.gantt-todo.done .gantt-todo-title { text-decoration: line-through; opacity: .7; }
/* Kürzel der Zuständigen rechts in der Namensspalte */
.gantt-label .gantt-leute { margin-left: auto; display: inline-flex; flex: none; padding-left: 6px; }
.gantt-label .gantt-leute span {
min-width: 20px; height: 20px; padding: 0 4px; box-sizing: border-box; border-radius: 999px; margin-left: -4px;
display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 500;
background: var(--surface-sunk); color: var(--text); border: 1.5px solid var(--surface);
}
.gantt-label .gantt-todo-title { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.gantt-vorgaenger-warn {
flex: none; width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 600; background: color-mix(in srgb, var(--amber) 20%, transparent); color: var(--amber);
}
/* Heute deutlicher */
#planGanttContainer .gantt-grid-today { border-left-width: 2px; opacity: 1; }
/* Hinweis auf Aufgaben ohne Termin */
.tp-ohne {
display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 8px; padding: 12px 16px; box-sizing: border-box;
border: 1px dashed var(--line); border-radius: var(--r-md); background: transparent; color: var(--text-muted); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.tp-ohne:hover { border-color: var(--accent); color: var(--text); }
.tp-ohne[hidden] { display: none; }
.tp-ohne-zahl { background: var(--surface-sunk); border-radius: 6px; padding: 1px 8px; font-weight: 500; color: var(--text); }
.tp-ohne-hinweis { margin-left: auto; font-size: 12px; }
#planGanttContainer .gantt-row.gantt-phase .gantt-todo-title { flex: 1 1 auto; min-width: 70px; }
#planGanttContainer .gantt-row.gantt-phase .tp-phase-info { flex: none; }
/* Die Glas-Darstellung gibt Knöpfen einen Rahmen — in Umschaltern und
Menüs soll es keinen geben; das Menü deckt den Plan dahinter ab. */
#planSection-terminplan .tp-seg button,
#planSection-terminplan .tp-menue-liste button { border: 0 !important; box-shadow: none; }
#planSection-terminplan .tp-seg button[aria-pressed="true"] { box-shadow: var(--sh-1); }
#planSection-terminplan .tp-menue-liste { -webkit-backdrop-filter: blur(24px) saturate(160%); backdrop-filter: blur(24px) saturate(160%); }
html.glas #planSection-terminplan .tp-menue-liste { background: var(--glas-dicht); }
@media (prefers-color-scheme: light) { html.glas:not([data-theme="dark"]) #planSection-terminplan .tp-menue-liste { background: rgba(255,255,255,.96); } }
html.glas[data-theme="light"] #planSection-terminplan .tp-menue-liste { background: rgba(255,255,255,.96); }
/* Getönte Namenszellen (Projektzeile, Phasenköpfe, Gruppen) liegen auf
einem deckenden Grund — sonst schienen beim waagerechten Scrollen die
Balken durch. --gantt-label-grund setzt glas.css; ohne Glas ist
--surface ohnehin deckend. */
#planGanttContainer .gantt-row.gantt-project.highlighted .gantt-label {
background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--gantt-label-grund, var(--surface));
}
#planGanttContainer .gantt-row.gantt-phase .gantt-label,
#planGanttContainer .gantt-row.tp-gruppe .gantt-label {
background: linear-gradient(var(--surface-sunk), var(--surface-sunk)), var(--gantt-label-grund, var(--surface));
}
.tp-sym-phase { width: 14px; height: 6px; border-radius: 999px; background: var(--accent); flex: none; opacity: .75; }
#todoEditPhaseAbs select { width: 100%; }
/* Aufgabenliste: Phasen-Kennzeichen je Aufgabe und Filter */
.plan-task-phase {
flex-shrink: 0; font-size: 11px; font-weight: 500; padding: 1px 8px; border-radius: 6px;
background: var(--accent-soft); color: var(--accent); white-space: nowrap;
}
.plan-task-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: -2px 0 8px; font-size: 12px; color: var(--text-muted); }
.plan-task-filter:empty { display: none; }
.plan-task-filter > span { margin-right: 2px; }
.plan-task-filter-btn {
min-height: 28px; padding: 0 12px; border-radius: 8px; font: inherit; font-size: 12px;
border: 1px solid var(--line); background: var(--surface); color: var(--text); cursor: pointer;
}
.plan-task-filter-btn.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 500; }
/* Leistungsphasen farblich von Aufgaben getrennt (Eriks Wunsch): Phasen-
balken in Blauviolett (bewusst bläulicher als das Lila der Meilensteine), Aufgaben bleiben im Akzentblau, erledigte grün,
Meilensteine lila — keine Farbe ist doppelt belegt. */
:root { --gantt-phase: #6a5fc7; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) { --gantt-phase: #a59ef2; } }
html[data-theme="dark"] { --gantt-phase: #a59ef2; }
#planGanttContainer .gantt-row.gantt-phase .gantt-bar.todo,
#planGanttContainer .gantt-row.gantt-phase .gantt-bar.todo.done { background: var(--gantt-phase); }
.tp-sym-phase { background: var(--gantt-phase); opacity: 1; }
/* Aufgaben-Vorlagen je Gewerk (Admin): Gewerk-Umschalter, Spaltenkopf und
bearbeitbare Zeilen — gleiche Spalten wie die Zeile „+ Schritt". */
.vorlagen-wahl { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 8px 0 12px; }
.vorlagen-gewerke { display: inline-flex; gap: 4px; padding: 4px; border-radius: 8px; background: var(--surface-sunk); }
.vorlagen-gewerk { border: 0; background: transparent; color: var(--text-muted); font: inherit; font-size: 13px; font-weight: 500;
padding: 6px 16px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.vorlagen-gewerk span { font-size: 11px; font-weight: 500; opacity: .75; }
.vorlagen-gewerk.is-active { background: var(--surface); color: var(--text); box-shadow: var(--sh-1); }
.vorlagen-kopf, .vorlagen-zeile, .vorlagen-neu {
display: grid !important; grid-template-columns: minmax(0, 1fr) 80px 90px 90px 120px; gap: 8px; align-items: center;
}
.vorlagen-kopf { font-size: 11px; letter-spacing: 0; color: var(--text-muted); padding: 0 6px 4px; }
.vorlagen-zeile input { width: 100%; box-sizing: border-box; min-width: 0; }
.vorlagen-neu input[type=text], .vorlagen-neu input[type=number] { width: 100%; min-width: 0; flex: none; box-sizing: border-box; }
.vorlagen-aktionen { display: inline-flex; gap: 4px; justify-content: flex-end; align-items: center; }
#planSection-terminplan .vorlagen-gewerk, #admin .vorlagen-gewerk { border: 0 !important; }
@media (max-width: 640px){
.vorlagen-kopf { display: none !important; }
.vorlagen-zeile, .vorlagen-neu { grid-template-columns: 1fr 1fr; }
.vorlagen-zeile input[type=text], .vorlagen-neu input[type=text] { grid-column: 1 / -1; }
.template-head-grid { grid-template-columns: 1fr; }
}
.vorlagen-summe { font-size: 13px; color: var(--text-muted); padding: 6px 6px 0; }
.vorlagen-summe b { color: var(--text); font-variant-numeric: tabular-nums; }
/* ---------- Termin aus Mail (js/plan/plan-mail-eintrag.js) ---------- */
.mail-ablage {
position: fixed; inset: 0; z-index: 250;
display: flex; align-items: center; justify-content: center;
background: color-mix(in srgb, var(--accent) 12%, transparent);
border: 3px dashed var(--accent);
pointer-events: none;
}
.mail-ablage[hidden] { display: none; }
.mail-ablage-karte {
display: flex; flex-direction: column; align-items: center; gap: 8px;
max-width: 420px; padding: 24px 28px; text-align: center;
background: var(--bg); color: var(--text);
border: 1px solid var(--line); border-radius: var(--r-lg, 14px);
box-shadow: 0 12px 40px rgba(0,0,0,.18);
}
.mail-ablage-karte svg { width: 32px; height: 32px; color: var(--accent); }
.mail-ablage-karte b { font-size: 1.1em; }
.mail-ablage-karte span { color: var(--text-subtle); font-size: .9em; }
.mail-ablage.ist-beschaeftigt .mail-ablage-karte svg { animation: mail-puls 1.2s ease-in-out infinite; }
@keyframes mail-puls { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .mail-ablage.ist-beschaeftigt .mail-ablage-karte svg { animation: none; } }
.pd-notiz {
width: 100%; box-sizing: border-box; resize: vertical; min-height: 80px;
font: inherit; font-size: .9em; line-height: 1.4;
}
.pd-mail-hinweis {
margin: 0 0 6px; padding: 6px 12px; border-radius: 8px;
background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--text);
}
.plan-task-notiz { display: inline-flex; color: var(--text-subtle); }
.plan-task-notiz svg { width: 14px; height: 14px; }
.mail-auswahl { width: min(560px, calc(100vw - 32px)); }
.mail-auswahl-liste { display: flex; flex-direction: column; gap: 4px; max-height: 50vh; overflow-y: auto; margin: 12px 0; }
.mail-auswahl-zeile {
display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center;
padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px;
}
.mail-auswahl-text { display: grid; gap: 2px; min-width: 0; }
.mail-auswahl-titel { overflow-wrap: anywhere; }
.mail-auswahl-datum { color: var(--text-subtle); font-size: .88em; white-space: nowrap; }
.mail-auswahl-art { flex: none; }
/* Eigene Flächen statt der .segmented-Vorgabe: deren gewählter Knopf ist
var(--surface) — unter Glas fast durchsichtig, gewählt und nicht gewählt
sahen gleich aus; dazu trug jeder Knopf einen eigenen Rand. */
.segmented.mail-auswahl-art button {
padding: 4px 12px; font-size: 12px;
border: 0; box-shadow: none;
background: transparent; color: var(--text-muted);
}
.segmented.mail-auswahl-art button:hover { background: var(--seg-hover); color: var(--text); }
.segmented.mail-auswahl-art button[aria-pressed="true"] {
background: var(--accent-soft); color: var(--accent); font-weight: 500;
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}
@media (max-width: 520px) {
.mail-auswahl-zeile { grid-template-columns: auto 1fr; }
.mail-auswahl-art { grid-column: 2; justify-self: start; }
}
/* ---------- Aufgaben-Panel: „Externe Personen“ (Kollegen außerhalb des
Projekts, todoExterneSetzen() in plan-modals.js) ---------- */
.pd-externe { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); display: grid; gap: 8px; }
.pd-externe-kopf { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.pd-externe-kopf .hint { font-weight: 400; margin: 0 0 0 4px; }
#todoEditExterne:empty { display: none; }
#todoEditExterneWahl { max-width: 100%; }
.person-chip-x { margin-left: 4px; opacity: .6; }
.person-chip:hover .person-chip-x { opacity: 1; }
/* ---------- Notizen (Eriks Wahl „A – Liste + Editor“, js/plan/plan-notizen.js) ----------
Links die Liste, rechts der Editor. Knöpfe tragen eigene Klassen bzw.
all: unset, damit die allgemeine (Glas-)Knopfregel sie nicht färbt. */
.notizen {
display: grid; grid-template-columns: minmax(240px, 300px) 1fr; min-height: 480px;
border: 1px solid var(--line); border-radius: var(--r-lg, 14px); background: var(--surface); overflow: hidden;
}
#planSection-notizen.notizen-zieht .notizen { outline: 2px dashed var(--accent); outline-offset: 4px; }
.notizen-liste { display: flex; flex-direction: column; gap: 8px; padding: 16px; background: var(--surface-alt); border-right: 1px solid var(--line-soft); min-width: 0; }
.notizen-suchzeile { display: flex; gap: 8px; }
.notizen-suche {
flex: 1; min-width: 0; padding: 8px 12px; border: 1px solid var(--line) !important; border-radius: 8px;
background: var(--surface) !important; color: var(--text); font: inherit; font-size: 13px; box-shadow: none !important;
}
.notizen-suche:focus { outline: none; border-color: var(--accent) !important; }
button.notizen-neu { white-space: nowrap; padding: 6px 16px; font-size: 13px; }
.notizen-eintraege { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; max-height: 62vh; }
.notizen-gruppe { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 500; letter-spacing: 0; color: var(--text-subtle); margin: 8px 4px 4px; }
.notizen-pin-punkt { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); }
button.notizen-eintrag, button.notizen-eintrag:hover, button.notizen-eintrag:active {
all: unset; box-sizing: border-box; display: grid; gap: 2px; padding: 8px 12px; border-radius: 10px; cursor: pointer; width: 100%;
transition: background var(--dur, 150ms);
}
button.notizen-eintrag:hover { background: var(--surface-sunk); }
button.notizen-eintrag:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
button.notizen-eintrag.ist-aktiv { background: var(--surface); box-shadow: inset 3px 0 0 var(--accent), var(--sh-1, 0 1px 2px rgba(0,0,0,.06)); }
.notizen-eintrag-titel { font-weight: 500; font-size: 13px; color: var(--text); display: flex; gap: 6px; align-items: center; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notizen-eintrag-text { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notizen-eintrag-meta { font-size: 11px; color: var(--text-subtle); }
.notizen-chip { flex: none; font-size: 11px; font-weight: 500; color: var(--accent); background: var(--accent-soft); border-radius: 8px; padding: 0 8px; }
.notizen-leer { font-size: 13px; color: var(--text-subtle); padding: 12px 4px; }
.notizen-leer.ist-fehler { color: var(--red); }
.notizen-ablage { margin-top: auto; border: 1.5px dashed var(--line); border-radius: 10px; padding: 8px; text-align: center; font-size: 12px; color: var(--text-subtle); }
.notizen-laedt { padding: 24px; color: var(--text-subtle); }
.notizen-editor { display: flex; flex-direction: column; gap: 12px; padding: 20px 24px; min-width: 0; }
.notizen-editor-leer { margin: auto; display: grid; gap: 6px; text-align: center; color: var(--text-muted); max-width: 320px; }
.notizen-editor-kopf { display: flex; align-items: center; gap: 8px; }
.notizen-titel {
/* 4 px Innenabstand, sonst saß der Cursor auf der Feldkante und war halb
verdeckt; der negative Rand hält den Titel auf seiner Linie. */
flex: 1; min-width: 0; border: 0 !important; background: transparent !important; box-shadow: none !important; padding: 2px 4px !important; margin-left: -4px;
font: 600 20px/1.3 var(--font-display, inherit); color: var(--text);
}
.notizen-titel:focus { outline: none; }
.notizen-titel::placeholder { color: var(--text-subtle); }
button.notizen-symbol, button.notizen-symbol:hover, button.notizen-symbol:active {
all: unset; box-sizing: border-box; padding: 4px 12px; border-radius: 8px; border: 1px solid var(--line);
font-size: 12px; color: var(--text-muted); cursor: pointer; white-space: nowrap; transition: background var(--dur, 150ms);
}
button.notizen-symbol:hover { background: var(--surface-sunk); color: var(--text); }
button.notizen-symbol:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button.notizen-symbol.ist-an { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 50%, var(--line)); font-weight: 500; }
button.notizen-symbol.ist-gefahr:hover { color: var(--red); }
/* Auch beim Darüberfahren weiß auf Rot — sonst gewann .ist-gefahr:hover (rote Schrift)
und „Wirklich löschen?“ verschwand auf der roten Fläche. */
button.notizen-symbol.ist-fragend, button.notizen-symbol.ist-fragend:hover { background: var(--red); color: #fff; border-color: var(--red); }
.notizen-richtext { display: flex; flex-direction: column; gap: 8px; flex: 1; }
.notizen-text {
flex: 1; min-height: 260px; outline: none; line-height: 1.55; font-size: 13px; color: var(--text);
padding: 4px 2px; overflow-wrap: anywhere;
}
.notizen-text:empty::before { content: attr(data-placeholder); color: var(--text-subtle); }
.notizen-fuss { display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap; border-top: 1px solid var(--line-soft); padding-top: 12px; font-size: 12px; color: var(--text-subtle); }
.notizen-status.ist-ok { color: var(--green); }
.notizen-status.ist-warnung { color: var(--amber); }
.notizen-status.ist-fehler { color: var(--red); }
button.notizen-link, button.notizen-link:hover { all: unset; cursor: pointer; color: var(--accent); text-decoration: underline; margin-left: 6px; }
@media (max-width: 760px){
.notizen { grid-template-columns: 1fr; }
.notizen-liste { border-right: 0; border-bottom: 1px solid var(--line-soft); }
.notizen-eintraege { max-height: 240px; }
}
/* ---------- Reiter des Projektkopfs wie die Seitenleiste (11/2026) ----------
Eriks Meldung: das Highlight sah anders aus als im übrigen Programm. Wie
.sidebar-nav .nav-item: inaktiv normal und gedämpft, aktiv eine Flächen-
stufe mit Haarlinie und dunkler Schrift (kein Akzentblau, keine
Unterstreichung). Unter Glas: glas.css (.plan-kopf .plan-nav-item). */
.plan-nav { padding: 8px 24px; gap: 2px; align-items: center; }
.plan-nav-item { height: 32px; padding: 0 12px; border-bottom: 0; border-radius: 8px; font-weight: 400; display: inline-flex; align-items: center; }
.plan-nav-item:hover { background: var(--surface-sunk); color: var(--text); }
.plan-nav-item.is-active { background: var(--surface-sunk); color: var(--text); font-weight: 500; border-bottom-color: transparent; box-shadow: inset 0 0 0 1px var(--line-soft); }
/* ===========================================================================
Planblatt — Seitenpanels Aufgabe und Meilenstein (Eriks Wahl, unslop,
11/2026). Kopf: Art, Projekt, Stand und die Lage im Terminplan
(lageBildHtml() in plan-modals.js); darunter die Angaben als Zeilen mit
Beschriftung links, wie im Schriftkopf eines Plans. Ersetzt die
Abschnitte .pd-abs. Werte im 4er-Raster, neutraler Schatten.
=========================================================================== */
.modal-bg.als-panel > .modal.pd { box-shadow: -12px 0 32px rgba(16,20,24,.14); }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .modal-bg.als-panel > .modal.pd { box-shadow: -12px 0 32px rgba(0,0,0,.5); } }
html[data-theme="dark"] .modal-bg.als-panel > .modal.pd { box-shadow: -12px 0 32px rgba(0,0,0,.5); }
.pd-kopf { padding: 16px 20px 0; gap: 12px; border-bottom: 0; }
.pd-art { gap: 8px; height: 32px; font-size: 12px; font-weight: 500; min-width: 0; }
.pd-art > span { flex: none; }
.pd-art .pd-wo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 400; color: var(--text-subtle); }
.pd-wo:not(:empty)::before { content: "· "; }
.pd-nr { font-family: var(--font-mono); font-size: 11px; }
.pd-art .modal-kbd { margin-left: 0; display: inline-flex; gap: 2px; align-items: center; }
.pd-kasten { width: 10px; height: 10px; border-radius: 3px; }
.pd-raute { width: 9px; height: 9px; }
kbd { font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: var(--text-subtle); border: 1px solid var(--line);
border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; line-height: 16px; background: var(--surface-alt); }
.pd-zu { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; }
.pd-zu svg { width: 16px; height: 16px; }
/* Titel als Überschrift, Rahmen nur beim Zeigen und im Fokus */
.modal-bg.als-panel .pd-kopf .pd-titel,
html.glas .modal-bg.als-panel .pd-kopf .pd-titel {
font-size: 19px; font-weight: 500; line-height: 28px; height: auto; padding: 2px 8px; margin: 0 -8px; width: calc(100% + 16px);
border: 1px solid transparent; border-radius: 8px; background: transparent; box-shadow: none;
}
.modal-bg.als-panel .pd-kopf .pd-titel:hover { border-color: var(--line-soft); }
.modal-bg.als-panel .pd-kopf .pd-titel:focus { border-color: var(--line); outline: none; background: var(--surface); }
.modal-bg.als-panel .pd-kopf .pd-titel.is-error { border-color: var(--red); }
/* Stand direkt unter dem Titel */
.pd-stand { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: 32px; }
.pd-stand .pd-seg { width: auto; flex: none; }
.pd-stand .pd-seg button { flex: none; min-height: 28px; padding: 0 12px; font-size: 12px; }
.pd-stand .progress-row { flex: 1; min-width: 140px; margin: 0; }
.pd-stand .progress-row output { min-width: 32px; font-family: var(--font-mono); }
#milestoneEditStand button[data-stand="offen"][aria-pressed="true"] .segmented-dot { background: var(--meilenstein); }
#milestoneEditStand button[data-stand="erreicht"][aria-pressed="true"] .segmented-dot { background: var(--green); }
.pd-warnung { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--red); }
.pd-warnung::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--red); }
.pd-warnung[hidden] { display: none; }
/* Lage im Terminplan: sechs Kalenderwochen um den Eintrag */
.pd-lage { margin: 0 -20px; padding: 12px 20px; background: var(--surface-alt); border-block: 1px solid var(--line-soft); display: grid; gap: 4px; }
.pd-lage-leer { font-size: 12px; color: var(--text-subtle); line-height: 20px; }
.pd-lage-skala { position: relative; height: 16px; }
.pd-lage-skala span { position: absolute; top: 0; padding-left: 4px; font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--text-subtle); }
.pd-lage-flaeche { position: relative; height: 52px; overflow: hidden;
background-image: repeating-linear-gradient(to right, var(--line-soft) 0 1px, transparent 1px calc(100% / 6)); }
.pd-lage-bar { position: absolute; height: 12px; border-radius: 3px; overflow: hidden; }
.pd-lage-bar.is-vor { background: color-mix(in srgb, var(--accent) 30%, var(--surface-alt)); }
.pd-lage-bar.is-fertig { background: var(--line); }
.pd-lage-bar.is-nach { background: color-mix(in srgb, var(--accent) 30%, var(--surface-alt)); }
.pd-lage-bar.is-diese { background: color-mix(in srgb, var(--accent) 24%, var(--surface)); box-shadow: inset 0 0 0 1px var(--accent); }
.pd-lage-bar.is-diese.is-fertig { background: color-mix(in srgb, var(--green) 30%, var(--surface)); box-shadow: inset 0 0 0 1px var(--green); }
.pd-lage-bar b { position: absolute; inset: 0 auto 0 0; background: var(--accent); }
.pd-lage-bar.is-fertig b { background: var(--green); }
.pd-lage-raute { position: absolute; width: 10px; height: 10px; margin-top: 1px; background: var(--meilenstein); transform: translateX(-50%) rotate(45deg); }
.pd-lage-raute.is-fertig { background: var(--text-subtle); }
.pd-lage-raute.is-diese { width: 12px; height: 12px; box-shadow: 0 0 0 2px var(--surface-alt), 0 0 0 3px var(--meilenstein); }
.pd-lage-raute.is-diese.is-fertig { background: var(--green); box-shadow: 0 0 0 2px var(--surface-alt), 0 0 0 3px var(--green); }
.pd-lage-raute.is-diese.is-ueber { background: var(--red); box-shadow: 0 0 0 2px var(--surface-alt), 0 0 0 3px var(--red); }
.pd-lage-heute { position: absolute; top: 0; bottom: 0; border-left: 1px dashed var(--text-subtle); }
.pd-lage-legende { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--text-subtle); }
.pd-lage-legende span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* Angaben als Zeilen */
.pd-inhalt { padding: 4px 20px 16px; }
.pd-zeile { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-soft); align-items: start; }
.pd-zeile:last-child { border-bottom: 0; }
.pd-zeile[hidden] { display: none; }
.pd-lab, .pd-lab label { font-size: 12px; font-weight: 400; color: var(--text-subtle); line-height: 32px; }
.pd-wert { display: grid; gap: 8px; min-width: 0; }
.pd-wert .range-picker-display, .pd-wert select { width: 100%; box-sizing: border-box; }
.pd-wert .field-inline { display: flex; align-items: center; gap: 8px; }
.pd-wert .field-inline .range-picker-display { flex: 1; min-width: 0; }
.pd-wert .field-badge { font-family: var(--font-mono); font-weight: 400; }
.pd-wert .pd-hint { font-size: 12px; }
.pd-haken { min-height: 24px; }
@media (max-width: 480px) {
.pd-zeile { grid-template-columns: minmax(0, 1fr); gap: 4px; }
.pd-lab, .pd-lab label { line-height: 20px; }
}
/* Aufwand: Kopf entfällt (Beschriftung steht links), Werte im Raster */
.pd-wert.pd-aufwand { margin: 0; padding: 0; border: 0; gap: 8px; }
.pd-aufwand-zeile { gap: 8px; }
.pd-stepper { height: 32px; }
.pd-stepper:focus-within { border-color: var(--accent); box-shadow: none; }
.pd-aufwand-schnell { gap: 4px; }
.pd-aufwand-schnell button { padding: 0 8px; height: 24px; line-height: 24px; border-radius: 6px; border-color: transparent; }
.pd-aufwand-schnell button[aria-pressed="true"] { font-weight: 500; border-color: transparent; }
.pd-externe { margin-top: 4px; padding-top: 8px; }
/* Vorgänger: gewählte offen, Auswahl eingeklappt */
.pd-vorg { display: grid; gap: 2px; }
.pd-vorg[hidden], .pd-vorg:empty { display: none; }
.pd-vorg-zeile { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 8px; align-items: center; height: 32px; padding: 0 8px; border-radius: 6px; background: var(--surface-alt); font-size: 13px; }
.pd-vorg-titel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pd-vorg-datum { font-family: var(--font-mono); font-size: 11px; color: var(--text-subtle); }
.pd-vorg-stand { width: 10px; height: 10px; border-radius: 3px; border: 1px solid var(--line); }
.pd-vorg-stand.is-fertig { background: var(--green); border-color: var(--green); }
.pd-vorg-stand.is-ms { border-radius: 0; transform: rotate(45deg) scale(.85); border-color: var(--meilenstein); }
.pd-vorg-stand.is-ms.is-fertig { background: var(--green); border-color: var(--green); }
.pd-wert .fold > summary { min-height: 32px; padding: 0 12px; font-size: 12px; color: var(--text-muted); }
.pd-wert .fold-caret { display: inline-grid; place-items: center; width: 16px; height: 16px; }
.pd-wert .fold-caret svg, .pd-wert .fold-search-icon svg { width: 14px; height: 14px; }
.pd-wert .fold-search-icon { display: inline-grid; place-items: center; color: var(--text-subtle); }
.pd-notiz { min-height: 64px; padding: 8px 12px; font-size: 13px; line-height: 20px; }
.pd-stand .progress-row input[type=range] { min-width: 0; width: auto; }
.pd-fuss { padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px)); }