Files
projektuebersicht/public/plan-styles.css
T
erikandClaude Opus 5.5 b7e0bd0d92 Termin aus Mail, Rollen & Rechte, Abwesenheiten, Glas-Darstellung und Pi-Betrieb
- Termin aus Mail: Mailtext oder .eml per Drag & Drop/Strg+V auf Terminplan
  oder Aufgaben, KI schlägt Aufgaben vor, Prüfung im Aufgaben-Panel; neues
  Notizfeld je Aufgabe (plan_todos.notiz)
- Terminplan: Meilensteine ohne Aufgabenbezug je in eigener Zeile,
  "+ Neu"-Menü klappt neben schmaler Seitenleiste nach rechts, Leistungsphasen
- Rollen & Rechte, Abwesenheiten-Seite, Benachrichtigungen, Rundgang
- Glas-Darstellung, Logo als Favicon
- Pi-Betrieb: PDF-Arbeit im Kindprozess, Wächter, Einrichtungs- und
  Prüfskript inkl. WLAN-Wächter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:16:52 +01:00

1792 lines
97 KiB
CSS

/* ===========================================================================
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: 14px; flex-wrap: wrap;
padding: 12px 24px; background: var(--surface); border-bottom: 1px solid var(--line-soft);
}
.plan-header h1 { font-size: 16px; margin: 0; font-weight: 600; white-space: nowrap; }
.plan-header .plan-id {
font-family: ui-monospace, 'SF Mono', monospace; font-size: 12.5px; color: var(--text-muted); white-space: nowrap;
}
.plan-header .subtitle { color: var(--text-muted); font-size: 12.5px; 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 14px; 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: 10px 18px; border-radius: var(--r-pill);
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: 10px !important;
justify-content: start !important;
}
.plan-resource-card {
padding: 8px 10px !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: 5px 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;
text-transform: uppercase;
letter-spacing: .03em;
}
.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: 10.5px;
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: 18px;
}
.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: var(--r-pill);
padding: 3px 9px;
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: 7px;
background: var(--surface);
color: var(--text-muted);
border: 1px solid var(--line);
border-radius: var(--r-pill);
padding: 4px 12px 4px 4px;
font-size: 12.5px;
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: 10px;
font-weight: 600;
}
.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: var(--r-pill);
padding: 2px;
gap: 2px;
width: fit-content;
}
.segmented button {
background: transparent;
color: var(--text-muted);
padding: 5px 14px;
font-size: 12.5px;
border-radius: var(--r-pill);
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: 600;
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: 10px; margin-top: 10px; }
.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: 9px 11px;
display: flex;
align-items: center;
gap: 9px;
font-size: 12.5px;
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: 10px;
transition: transform .18s var(--ease);
}
.fold[open] > summary .fold-caret { transform: rotate(90deg); }
.fold-count {
margin-left: auto;
font-size: 11px;
font-weight: 600;
background: var(--accent-soft);
color: var(--accent);
border-radius: var(--r-pill);
padding: 1px 9px;
font-variant-numeric: tabular-nums;
}
.fold-count.zero { background: var(--surface-sunk); color: var(--text-subtle); }
.fold-body {
padding: 9px 11px 11px;
border-top: 1px solid var(--line-soft);
display: flex;
flex-direction: column;
gap: 7px;
}
.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: 10.5px; text-transform: uppercase; letter-spacing: .05em;
color: var(--text-subtle); font-weight: 600; margin-bottom: 4px;
}
.plan-kpi-tile .kpi-value {
font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--text);
font-variant-numeric: tabular-nums;
}
.plan-kpi-tile .kpi-sub { font-size: 11.5px; 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: 14px;
margin-top: 18px;
}
.plan-mini-card {
background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-lg);
padding: 14px 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: 600; }
.plan-mini-card-expand { font-size: 11px; color: var(--accent); font-weight: 500; flex-shrink: 0; }
.plan-mini-card-preview {
font-size: 12.5px; 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: 10.5px; padding: 2px 8px; border-radius: var(--r-pill); 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: 10px 14px;
margin-bottom: 12px;
}
.plan-warning-head {
display: flex; align-items: center; gap: 7px;
font-size: 12.5px; font-weight: 600; color: var(--amber);
}
.plan-warning-list {
margin: 6px 0 0; padding-left: 26px;
font-size: 12.5px; color: var(--text-muted); line-height: 1.55;
}
/* Projektübergreifende Auslastung in der Ressourcen-Karte */
.plan-resource-other {
font-size: 10px; margin-top: 4px; font-weight: 600; 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: 10px;
max-height: 58vh; overflow-y: auto;
}
.history-entry {
border: 1px solid var(--line-soft); border-radius: var(--r-md);
background: var(--surface-alt); padding: 10px 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: 12.5px; font-weight: 600; }
.history-date { font-size: 11.5px; color: var(--text-subtle); }
.history-badge {
font-size: 10px; font-weight: 600; padding: 2px 7px; border-radius: var(--r-pill);
background: var(--accent-soft); color: var(--accent);
}
.history-badge.muted { background: var(--surface-sunk); color: var(--text-subtle); }
.history-entry-text { font-size: 12.5px; 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: 14px;
}
.template-admin-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.template-admin-row {
display: flex; align-items: center; gap: 8px;
font-size: 12.5px; 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: 7px; font-size: 12.5px; cursor: help; }
.honorar-plan-wrap { overflow-x: auto; margin-top: 4px; }
.honorar-table { font-size: 12.5px; }
.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: 3px 6px; font-size: 12px; text-align: center; }
.honorar-table tfoot th, .honorar-table tfoot td {
border-top: 2px solid var(--line); font-weight: 600; background: var(--surface-alt);
}
.honorar-anteil-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
gap: 8px; margin-bottom: 10px;
}
.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: 14px; flex-wrap: wrap; }
.honorar-satz-field { display: flex; align-items: center; gap: 6px; font-size: 12.5px; }
.honorar-satz-field input { width: 78px; padding: 4px 7px; font-size: 12.5px; text-align: right; }
.honorar-sum { font-size: 12.5px; font-weight: 600; }
.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: 14px; 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: 10px; margin-top: 10px; max-height: 50vh; overflow-y: auto; }
.file-item {
border: 1px solid var(--line-soft); border-radius: var(--r-md);
background: var(--surface-alt); padding: 10px 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: var(--r-pill); 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: 5px; margin-top: 6px; }
.file-reviewer-chip { font-size: 11px; padding: 2px 8px; border-radius: var(--r-pill); 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: 10px 14px;
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: 600;
}
.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: 14px;
margin-top: 16px;
}
.plan-panel {
background: var(--surface);
border: 1px solid var(--line-soft);
border-radius: var(--r-lg);
padding: 14px 16px;
}
.plan-panel-wide { grid-column: 1 / -1; }
.plan-panel-title {
font-size: 13px;
font-weight: 600;
margin: 0 0 10px;
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: 10px;
padding: 8px 10px;
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: 11.5px;
color: var(--text-muted);
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
.plan-task-meta.overdue { color: var(--red); font-weight: 600; }
.plan-task-no-schedule { color: var(--text-subtle); font-style: italic; }
.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: 12.5px; color: var(--text-subtle); padding: 10px 0; }
/* --- Dashboard: Liste der nächsten Termine (renderPlanDashboard()) --- */
.plan-upcoming-list { display: flex; flex-direction: column; gap: 7px; }
.plan-upcoming-item { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; }
.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: 600; }
.plan-upcoming-kind {
font-size: 10px;
text-transform: uppercase;
letter-spacing: .04em;
color: var(--text-subtle);
}
.plan-dash-team { display: flex; flex-direction: column; gap: 7px; }
.plan-dash-team-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
/* === 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: 10px; }
.protokoll-row {
display: grid;
grid-template-columns: 64px 1fr 140px 170px 100px;
align-items: center;
gap: 14px;
padding: 11px 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: 650; 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: 11.5px; margin-top: 2px; }
.protokoll-verfasser { color: var(--text-muted); font-size: 12.5px; }
.protokoll-punkte-status { display: flex; align-items: center; gap: 6px; font-size: 12.5px; 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: 12.5px; text-align: right; }
.protokoll-back-link { display: flex; align-items: center; gap: 6px; color: var(--text-muted); font-size: 13px;
margin-bottom: 14px; 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: 10px 14px; font-size: 12.5px; color: var(--text); margin-bottom: 14px; }
/* 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: 10px 14px; font-size: 12.5px; color: var(--text); margin-bottom: 14px; }
/* 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: 10px; margin-top: 12px;
padding: 10px 12px; background: var(--surface-alt); border: 1px solid var(--line-soft);
border-radius: var(--r-md); font-size: 12.5px; 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: 5px; margin: 12px 0 16px; }
.protokoll-todos-steps .seg { flex: 1; height: 4px; border-radius: 2px; 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: 12.5px; color: var(--text-muted); }
.pt-sel-count b { color: var(--accent); font-weight: 700; }
.pt-sel-actions button { appearance: none; border: none; background: none; font: inherit; font-size: 11.5px;
font-weight: 650; color: var(--accent); cursor: pointer; padding: 2px 3px; }
.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: 9px; 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: 650; 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: 10.5px; font-weight: 650; padding: 2px 8px; border-radius: 999px;
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 5px; border-radius: 999px;
background: var(--accent); color: var(--surface);
font-size: 9px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.pt-chevron { color: var(--text-subtle); font-size: 10.5px; 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: 12.5px; }
.protokoll-field-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 20px; }
.protokoll-field { display: flex; flex-direction: column; gap: 5px; }
.protokoll-field label { font-size: 11.5px; color: var(--text-subtle); text-transform: uppercase; letter-spacing: .04em; }
.protokoll-block { margin-top: 20px; }
.protokoll-block-head { margin-bottom: 10px; display: flex; align-items: center; justify-content: space-between; }
.protokoll-block-head h4 { margin: 0; font-size: 13.5px; font-weight: 650; }
.protokoll-teilnehmer-row { display: grid; grid-template-columns: 1fr 160px 100px 24px; gap: 10px; align-items: center;
padding: 7px 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: 12.5px; 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: 14px; 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: 9px 12px; background: var(--surface-alt); border-bottom: 1px solid var(--line);
font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; 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: 7px; padding: 8px 10px 8px 11px;
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: 700; letter-spacing: .01em;
border: none !important; background: none !important; border-radius: 4px !important;
color: var(--text) !important; padding: 2px 3px !important;
}
.protokoll-liste-gruppe input.protokoll-gruppe-heading::placeholder { color: var(--text-subtle); font-weight: 550; }
.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: 10px; font-variant-numeric: tabular-nums; color: var(--text-subtle);
background: var(--surface); border: 1px solid var(--line); border-radius: 980px; 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 11px; 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: 11.5px; font-weight: 700; 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: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.protokoll-liste-zeile .titel.ist-leer { font-weight: 500; font-style: italic; color: var(--text-subtle); }
.protokoll-liste-zeile .sub {
grid-column: 2; grid-row: 2; font-size: 10.5px; 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 11px 8px 14px; color: var(--accent); font-size: 12px; font-weight: 600; 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: 14px 12px; font-size: 12.5px; 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 22px; 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: 9px; flex-wrap: wrap;
padding: 9px 16px; background: var(--surface-alt); border-bottom: 1px solid var(--line-soft);
}
.protokoll-schreiben-kopf .nr { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px; }
.protokoll-schreiben-kopf .gruppe {
font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-subtle);
}
.protokoll-schreiben-kopf .rechts { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.protokoll-feld-label {
display: block; font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
color: var(--text-subtle); margin-bottom: 5px;
}
.protokoll-schreiben-feld { padding: 13px 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: 17px; font-weight: 650; letter-spacing: -.01em; 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: 13.5px; 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: 3px 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: 14px;
padding: 13px 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 9px !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: 9px 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: 9.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; padding: 1px 6px;
border-radius: var(--r-pill);
}
/* 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: 9.5px; font-weight: 700; line-height: 1.3; padding: 2px 7px; 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: 7px; padding: 2px;
background: var(--surface-sunk); gap: 1px; width: 56px;
}
.protokoll-status-switch.ist-waagerecht { flex-direction: row; width: auto; border-radius: 980px; }
.protokoll-status-switch button {
appearance: none; border: none; background: none; font: inherit; font-size: 10.5px; font-weight: 700;
letter-spacing: .01em; padding: 4px 0; border-radius: 5px; cursor: pointer; color: var(--text-subtle);
text-align: center; transition: background .12s, color .12s;
}
.protokoll-status-switch.ist-waagerecht button { padding: 3px 11px; border-radius: 980px; }
.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: 600; 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: 650; letter-spacing: .05em; text-transform: uppercase; color: var(--text-subtle); }
.plan-lage-zelle .kpi-value { font-size: 22px; font-weight: 600; letter-spacing: -.01em; 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: 600; }
.plan-lage-phase { display: flex; align-items: center; gap: 14px; }
.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: 14px; align-items: start; margin-top: 14px; }
.plan-lage-spalte { display: flex; flex-direction: column; gap: 14px; 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: 550; cursor: pointer;
}
.plan-panel-link:hover { text-decoration: underline; }
.plan-panel-link:active { transform: none; }
.plan-kommentar-fuss { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.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: 9.5px; font-weight: 700; 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: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--text-subtle); padding: 10px 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: 10px; 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: 7px; display: grid; place-items: center; font-size: 10px; font-weight: 700; 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: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-termin-text span { font-size: 11.5px; 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: 10px; align-items: center; padding: 7px 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: 3px; min-width: 0; }
.plan-team-text b { font-weight: 550; }
.plan-team-rollen { display: flex; flex-wrap: wrap; gap: 4px; }
.plan-rolle { font-size: 10px; font-weight: 600; padding: 1px 7px; border-radius: 999px; 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: 9px 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: 600; }
@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: 14.5px;
line-height: 1.6;
padding: 14px 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: 10px; padding: 8px 12px; border-radius: var(--r-sm, 8px);
font-size: 12.5px; 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: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.plan-verlauf-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.plan-verlauf-titel { font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; 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: 10px; }
.plan-verlauf-kw { font-size: 12px; font-weight: 600; 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: 14px; min-width: 0; }
.plan-verlauf-text { font-size: 13.5px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere; }
.plan-verlauf-text p { margin: 0; }
.plan-verlauf-meta { font-size: 11.5px; color: var(--text-subtle); margin-top: 3px; }
.plan-verlauf-mehr {
border: 1px solid var(--line); background: var(--surface); color: var(--accent);
border-radius: 999px; padding: 6px 14px; font: inherit; font-size: 12.5px; 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: 10px 12px; cursor: pointer;
}
.plan-prot-kopf:hover { border-color: var(--accent); }
.plan-prot-nr {
flex: none; font-size: 12px; font-weight: 700; 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: 600; 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: 10px; align-items: baseline;
width: 100%; text-align: left; font: inherit; font-size: 12.5px; color: var(--text-muted);
background: none; border: 0; border-top: 1px solid var(--line-soft); padding: 7px 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: 10px; 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: 10.5px; font-weight: 700; 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: 12.5px; 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: 14px; 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: 3px; text-align: left;
min-height: 56px; padding: 9px 14px; border: 0; border-radius: 12px;
background: transparent; color: var(--text); font: inherit; cursor: pointer;
}
.plan-einst-reiter b { font-size: 14px; font-weight: 600; }
.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: 22px 26px; }
.plan-einst-titel { margin: 0 0 16px; font-size: 18px; font-weight: 650; }
.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: 999px; 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: 600; }
/* Umschalter (Leistungsphasen, Beteiligte) */
.plan-einst-seg { display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--surface-sunk); }
.plan-einst-seg button {
border: 0; background: transparent; color: var(--text-muted); font: inherit; font-size: 12.5px;
min-height: 30px; padding: 0 12px; border-radius: 999px; cursor: pointer; white-space: nowrap;
}
.plan-einst-seg button.an { background: var(--surface); color: var(--accent); font-weight: 600; 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: 9px 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: 14px; 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: 700; color: var(--accent); background: var(--accent-soft); border-radius: 999px; 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: 7px 10px; 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 rgba(0,113,227,.18); }
/* 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: 14px; }
.plan-einst-legende { display: flex; gap: 14px; 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: 10px 14px; border-radius: 12px; background: var(--surface-sunk); font-size: 13px; margin-bottom: 14px; }
.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: 3px; min-width: 0; padding: 10px 12px; border-radius: 12px; background: var(--surface-sunk); border: 1px solid transparent; }
.plan-einst-besetzt b { font-size: 12px; font-weight: 650; color: var(--text-muted); }
.plan-einst-besetzt span { font-size: 12.5px; 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: 14px; }
.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: 11.5px; font-weight: 650; color: var(--text-muted); padding: 8px 10px 4px; }
.plan-einst-vorschlag-leer { font-size: 13px; color: var(--text-muted); padding: 10px; }
.plan-einst-vorschlag {
display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; min-height: 48px; padding: 4px 10px;
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: 13.5px; font-weight: 600; }
.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: 700; background: var(--accent); color: #fff;
}
.plan-einst-gruppe { display: flex; align-items: center; gap: 10px; padding: 16px 0 6px; }
.plan-einst-zeile {
display: grid; grid-template-columns: minmax(200px, 1fr) auto 36px; gap: 10px 14px; align-items: center;
padding: 9px 10px; 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: 14px; font-weight: 600; 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 14px; border-radius: 999px; box-sizing: border-box; white-space: nowrap;
border: 1px solid var(--line); background: transparent; color: var(--text-muted); font: inherit; font-size: 12.5px; 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: 600; }
.plan-einst-kapsel.ist-neben { border: 1.5px dashed var(--accent); background: var(--accent-soft); color: var(--text); font-weight: 600; }
.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: 18px; 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: 14px; font-weight: 600; }
.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: 14px; padding: 8px 8px 8px 16px; border-radius: 999px;
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 14px; border-radius: 999px; border: 0; background: color-mix(in srgb, var(--bg) 18%, transparent); color: inherit; font: inherit; font-weight: 600; 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: 9px 10px; 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: 18px 22px 14px; border-bottom: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 10px; }
.pd-art { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 650; color: var(--text-muted); }
.pd-art .modal-kbd { margin-left: auto; font-weight: 400; }
.pd-kasten { width: 11px; height: 11px; border-radius: 3px; 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: 20px; 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: 17px; font-weight: 600; padding: 9px 12px; }
.pd-inhalt { flex: 1; min-height: 0; overflow: auto; padding: 2px 22px 16px; }
.pd-abs { display: flex; flex-direction: column; gap: 8px; padding: 14px 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: 650; 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: 14px 22px calc(14px + 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 10px; 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). */
.pd-aufwand { display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 400; margin-top: 4px; }
.pd-aufwand > span:first-child { font-weight: 600; color: var(--text-muted); font-size: 12px; }
.pd-aufwand > span:last-child { color: var(--text-muted); font-size: 12px; }
.pd-aufwand input { width: 96px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-md); font: inherit; font-size: 13px; color: var(--text); background: var(--surface); text-align: right; }
.pd-aufwand input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(0,113,227,.18); }
/* 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: 10px; padding: 8px 10px; 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 14px;
border-radius: 999px; 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: 600; }
.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: 10px; width: 100%; min-height: 38px; padding: 0 10px; box-sizing: border-box;
border: 0; border-radius: 9px; background: transparent; color: var(--text); font: inherit; font-size: 13.5px; 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: 600; }
.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: 3px; 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: 650 !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: 10px; cursor: pointer; padding: 0; }
.tp-klappen:hover { background: var(--surface); color: var(--text); }
.tp-phase-info { margin-left: auto; font-size: 11.5px; font-weight: 400; color: var(--text-muted); white-space: nowrap; }
#planGanttContainer .gantt-row.tp-gruppe .gantt-label { font-weight: 650; 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: 30px !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 3px; box-sizing: border-box; border-radius: 999px; margin-left: -4px;
display: inline-flex; align-items: center; justify-content: center; font-size: 8.5px; font-weight: 700;
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: 10px; font-weight: 800; 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: 10px 14px; 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: 999px; padding: 1px 8px; font-weight: 600; 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%; }
/* ===================== Bereich Leistungsphasen =====================
Eriks Wahl "B": Ablaufbalken über alle Phasen, darunter eine Kachel je
Phase (renderPlanPhasen(), js/plan/plan-phasen.js). Text auf Akzent-
flächen in festem Weiß — unter Glas ist var(--surface) durchscheinend. */
.phasen-zusammenfassung {
display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
font-size: 13px; color: var(--text-muted); margin: 0 2px 12px;
}
.phasen-zusammenfassung span { font-size: 12px; color: var(--text-subtle); }
.phasen-kopf { font-size: 11px; font-weight: 650; letter-spacing: .02em; color: var(--text-muted); text-transform: uppercase; margin-bottom: 8px; }
.phasen-ablauf { margin-bottom: 16px; }
.phasen-ablauf-spur { position: relative; height: 30px; }
.phasen-ablauf-seg {
position: absolute; top: 0; bottom: 0; min-width: 0;
display: flex; align-items: center; padding: 0 8px; overflow: hidden;
border: 0; border-radius: var(--r-md); cursor: pointer;
font: inherit; font-size: 12px; font-weight: 600; white-space: nowrap;
color: var(--text); background: var(--surface-sunk);
}
.phasen-ablauf-seg + .phasen-ablauf-seg { box-shadow: -2px 0 0 var(--surface); }
.phasen-ablauf-seg.is-fertig { background: var(--green); color: #fff; }
.phasen-ablauf-seg.is-laeuft {
color: #fff;
background: linear-gradient(90deg, var(--accent) var(--fort), color-mix(in srgb, var(--accent) 45%, transparent) var(--fort));
}
.phasen-ablauf-seg span { overflow: hidden; text-overflow: ellipsis; }
.phasen-ablauf-heute { position: absolute; top: -4px; bottom: -4px; border-left: 2px solid var(--red); pointer-events: none; }
.phasen-ablauf-achse { position: relative; display: flex; justify-content: space-between; margin-top: 6px; font-size: 11.5px; color: var(--text-muted); }
.phasen-ablauf-heute-text { position: absolute; top: 0; transform: translateX(-50%); color: var(--red); font-weight: 600; white-space: nowrap; }
.phasen-raster { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.phasen-kachel {
display: flex; flex-direction: column; gap: 12px;
background: var(--surface); border: 1px solid var(--line-soft);
border-radius: var(--r-lg); padding: 14px 16px;
}
.phasen-kachel.is-laeuft { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.phasen-kachel.is-fertig { opacity: .8; }
.phasen-kachel.ist-markiert { animation: phasen-markiert 1.2s var(--ease-out, ease-out); }
@keyframes phasen-markiert { 0%, 40% { box-shadow: 0 0 0 3px var(--accent); } 100% { box-shadow: none; } }
.phasen-kachel-kopf { display: flex; align-items: flex-start; gap: 12px; }
.phasen-ring {
--ring: var(--text-subtle);
width: 52px; height: 52px; border-radius: 50%; flex: none;
display: flex; align-items: center; justify-content: center;
background: conic-gradient(var(--ring) var(--fort), var(--surface-sunk) 0);
}
.phasen-kachel.is-laeuft .phasen-ring { --ring: var(--accent); }
.phasen-kachel.is-fertig .phasen-ring { --ring: var(--green); }
.phasen-ring span {
width: 42px; height: 42px; border-radius: 50%; background: var(--surface-alt);
display: flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.phasen-kachel-name { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.phasen-kachel-name b { font-size: 15px; }
.phasen-kachel-name span { font-size: 12.5px; color: var(--text-muted); }
.phasen-chip { font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 999px; background: var(--surface-sunk); color: var(--text-muted); white-space: nowrap; }
.phasen-chip.is-laeuft { background: var(--accent); color: #fff; }
.phasen-chip.is-fertig { background: color-mix(in srgb, var(--green) 18%, transparent); color: var(--green); }
.phasen-hinweis { font-size: 12px; color: var(--amber); margin-top: -4px; }
.phasen-werte { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; font-size: 12.5px; }
.phasen-werte > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.phasen-werte small { font-size: 11.5px; color: var(--text-muted); }
.phasen-werte b { font-weight: 600; font-variant-numeric: tabular-nums; }
.phasen-leer { color: var(--text-subtle); font-weight: 400; font-style: italic; }
.phasen-knoepfe { display: flex; flex-wrap: wrap; gap: 8px; }
/* Aufgabenliste: Phasen-Kennzeichen je Aufgabe und Filter */
.plan-task-phase {
flex-shrink: 0; font-size: 11px; font-weight: 600; padding: 1px 8px; border-radius: 999px;
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 10px; 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: 999px; 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: 600; }
@media (max-width: 600px) { .phasen-werte { grid-template-columns: 1fr 1fr; } }
/* 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: 10px 0 12px; }
.vorlagen-gewerke { display: inline-flex; gap: 4px; padding: 3px; border-radius: 999px; background: var(--surface-sunk); }
.vorlagen-gewerk { border: 0; background: transparent; color: var(--text-muted); font: inherit; font-size: 13px; font-weight: 600;
padding: 6px 14px; border-radius: 999px; 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: .04em; text-transform: uppercase; 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: 12.5px; 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 10px; 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: 10px; align-items: center;
padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; cursor: pointer;
}
.mail-auswahl-datum { color: var(--text-subtle); font-size: .88em; white-space: nowrap; }