Beteiligte in die Projekteinstellungen, TODOs aus Protokoll, Bewegung

Beteiligten-Zuordnung verlagert: p.assign ist jetzt ein Stammdatum und
nur noch in den Projekteinstellungen editierbar (planCycleAssign()).
Wochenbericht und Projektboard zeigen sie nur noch an, mit Verweis
dorthin (springZuEinstellungen()). cycleAssign() ist damit entfallen.

Neu "TODOs aus Protokoll": ein externes Besprechungsprotokoll als PDF
wird per KI eingelesen und daraus in einem zweiten KI-Schritt Aufgaben
abgeleitet. Eigener Bereich in der Aufgaben-/GANTT-Leiste, bewusst
unabhaengig von den gespeicherten Protokollen - nichts davon wird
abgelegt. Drei Schritte in einem Dialog mit fester Fusszeile; die
Vorschlagsliste als kompakte, aufklappbare Zeilen, weil ein echter
Import leicht 20 Vorschlaege liefert.

Sichtbarkeit je Aufgabe im GANTT: neue Spalte plan_todos.show_in_gantt
(Vorgabe 1, idempotente Migration) und eine Checkbox im Aufgaben-Dialog.
Eine terminierte Aufgabe kann damit gezielt aus dem Terminplan
herausgehalten werden, bleibt sonst aber eine vollwertige Aufgabe.
plan-build-gantt.js und plan-drag.js pruefen dieselbe Bedingung, damit
Zeilenzahl und Umsortierung nicht auseinanderlaufen.

KI-Timeout dritte Stufe: ein abweichender, aber entfernter Endpunkt
(Drittanbieter-Proxy) bekommt 2 Minuten statt der 45 Sekunden der
echten Anbieter-API. Gemessen: die Punkte-Erkennung eines realen
Protokolls brauchte dort 39 Sekunden, lag also stets knapp unter dem
alten Limit und brach bei jeder Schwankung ab.

Bewegung: Hover- und Klick-Rueckmeldung als Token-Satz in :root,
angewandt auf die anklickbaren Zeilen, Schalter und Dialoge. Die
Akzentleiste ist ein inset-Schatten statt eines positionierten
Elements, damit Drag-and-Drop unberuehrt bleibt; prefers-reduced-motion
war bisher gar nicht vorhanden und kippt jetzt einfach die Tokens.

Plan Checker: optionaler Projektabgleich des Plankopfs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Opus 5 committed 2026-10-17 15:14:26 +02:00
1 parent 6ba93b2a92
commit 93505e0e48
17 files changed
+1883 -334

No files matched your search

+238 -81
View File
@@ -64,6 +64,31 @@
--sh-3: 0 8px 28px rgba(0,0,0,.12), 0 2px 8px rgba(0,0,0,.06);
--ease: cubic-bezier(.4, 0, .2, 1);
/* === Bewegung (Stufe "Spürbar", Eriks Wahl aus dem Interaktions-
Vergleich) ============================================================
Die gesamte Rückmeldung der Oberfläche hängt an diesen fünf Werten.
Eine andere Stufe wäre ein Wechsel HIER, nicht in den Komponenten:
jede Regel weiter unten liest ausschliesslich über var().
--dur kurze Rückmeldung (Fläche, Farbe, Anheben, Druck)
--dur-lg grössere Zustandswechsel (Aufklappen, Dialog, Band)
--ease-out Ausschwingen: schnell los, weich aus. Bewusst anders als
das ältere --ease (symmetrisch), das für Bestandsregeln
unverändert bleibt.
--row-lift wie weit sich eine anklickbare Zeile beim Zeigen hebt
--press Stauchung beim Drücken (Knöpfe, Chips, Zeilen)
Grundregeln, die überall gelten: bewegt wird nur transform und
opacity (nie Höhe/Breite, das ruckelt), nichts läuft in Dauerschleife,
und jede Regung quittiert eine echte Handlung. Wer im Betriebssystem
"Bewegung reduzieren" gesetzt hat, bekommt am Dateiende alles auf
praktisch null gesetzt - dort genügt es, diese Variablen zu kippen. */
--dur: 150ms;
--dur-lg: 200ms;
--ease-out: cubic-bezier(.2, .8, .2, 1);
--row-lift: -1px;
--press: .97;
}
/* === Basis & Reset === */
@@ -1449,16 +1474,24 @@ tr:nth-child(even) td { background: var(--surface-alt); }
}
/* === Dichte Fassung der Karte (.board-drawer-dicht, Wochenbericht) ===
Fokus-Modus (Eriks Wahl "C" aus dem Darstellungs-Vergleich): nur der
Kommentar liegt offen, Leistungsphasen und Beteiligte stecken in
aufklappbaren Abschnitten (.bericht-disclosure, siehe renderBoardDrawer()s
dichte Fassung in js/board/board.js) statt dauerhaft nebeneinander zu
stehen — bei 29 Projekten wurde der Bericht mit allem gleichzeitig
sichtbar als "zu überladen" zurückgemeldet. Kein eigenes Raster mehr (die
drei Blöcke stehen schlicht untereinander), deshalb sitzt die dichte
Fassung flächig in ihrem Container statt als eigene Schublade mit
zusätzlichem Rahmen/Hintergrund darin. */
Fokus-Modus, zweite Fassung (Eriks Rückmeldung zum Entwurfsvergleich "A -
Aktenregal"): der Kommentar bleibt das größte, offene Element; Leistungs-
phasen und Beteiligte stehen darunter dauerhaft sichtbar nebeneinander
(.bericht-meta-grid, siehe renderBoardDrawer()s dichte Fassung in
js/board/board.js) statt in aufklappbaren Abschnitten versteckt zu sein -
"die Beteiligten sollen mit angezeigt werden". Die erste Fassung hatte
beide hinter Aufklappern verborgen (gegen die Rückmeldung "zu überladen"
bei allem gleichzeitig sichtbar); jetzt sind beide bewusst KOMPAKT
gehalten (Kästchen-Leiste bzw. schmale Rollenzeilen statt breiter
Balkenzeilen), damit sie nebeneinander Platz finden, ohne den Kommentar zu
überragen. Nur die Anwesenheit (renderAttendance(),
js/wochenbericht/wochenbericht.js) bleibt ein Aufklapper
(.bericht-disclosure, weiter unten) — sie ist eine Sitzungs-, keine
Projekt-Angabe und sitzt ohnehin außerhalb dieser Karte am Seitenfuß. */
.board-drawer-dicht { padding: 0; background: transparent; border-top: none; }
.bericht-meta-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
@media (max-width: 860px) { .bericht-meta-grid { grid-template-columns: 1fr; gap: 16px; } }
.bericht-meta-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-subtle); margin-bottom: 8px; }
.bericht-disclosure {
border: 1px solid var(--line-soft);
@@ -1496,33 +1529,6 @@ tr:nth-child(even) td { background: var(--surface-alt); }
.bericht-disclosure[open] summary { border-bottom: 1px solid var(--line-soft); }
.bericht-disclosure-body { padding: 10px 14px 12px; }
/* Leistungsphasen als Balkenzeilen statt der Kästchen-Leiste des
Projektboards (.board-lph-leiste/-cell bleiben dort unverändert) — in der
schmalen Fokus-Spalte brauchen zehn Kästchen nebeneinander zu wenig Platz
je Phase, eine Zeile je Phase dagegen hat Raum für Label, Balken UND
Eingabefeld. */
.bericht-lph-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 12.5px; }
.bericht-lph-label { width: 48px; flex-shrink: 0; color: var(--text-muted); }
.bericht-lph-track { flex: 1; height: 4px; background: var(--line-soft); border-radius: 2px; overflow: hidden; }
.bericht-lph-track i { display: block; height: 100%; background: var(--text-subtle); }
.bericht-lph-row.is-aktiv .bericht-lph-track i { background: var(--accent); }
.bericht-lph-row.is-aktiv .bericht-lph-label { color: var(--accent); font-weight: 650; }
.bericht-lph-pct {
display: flex; align-items: center; gap: 1px; flex-shrink: 0;
color: var(--text-subtle); font-variant-numeric: tabular-nums; font-size: 11.5px;
}
/* .bericht-lph-row (zwei Klassen) statt der bloßen Element-Klasse: nötig, um
den globalen input[type=text]-Grundstil (Polsterung/Rahmen/Hintergrund,
weiter oben) zu schlagen — sonst gewinnt dessen höhere Spezifität und die
Polsterung von 7px 10px ließ "100" im 42px schmalen Feld auf "10"
abschneiden. */
.bericht-lph-row .bericht-lph-input {
width: 28px; flex-shrink: 0; border: none; border-radius: 0; background: transparent;
text-align: right; font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--text);
font-family: inherit; padding: 1px 0;
}
.bericht-lph-row .bericht-lph-input:focus { outline: 1.5px solid var(--accent); outline-offset: -1px; border-radius: 3px; box-shadow: none; }
.bericht-lph-row .bericht-lph-input.locked-cell { cursor: default; }
/* Der Kommentar bleibt das größte Element der dichten Fassung — etwas
größere Schrift als im Projektboard, wo er eine Spalte unter mehreren
@@ -2368,11 +2374,14 @@ a.secondary:hover { background: var(--surface-sunk); border-color: var(--text-su
/* === Anwesenheit der Sitzung ============================================
Fokus-Modus (Eriks Wahl "C"): ein aufklappbarer Abschnitt wie Leistungs-
phasen/Beteiligte im Wochenbericht (.bericht-disclosure, siehe weiter
oben), kein dauerhaft sichtbarer Block mehr. Zustände bleiben binär
(anwesend / nicht anwesend, Tabelle attendance); der Zähler in der
Kopfzeile macht sichtbar, wenn noch niemand geklickt hat. */
Fokus-Modus: ein aufklappbarer Abschnitt (.bericht-disclosure, siehe
weiter oben) am Seitenfuß des Wochenberichts, UNABHÄNGIG vom gewählten
Projekt (eine Sitzungs-, keine Projekt-Angabe) - anders als Leistungs-
phasen/Beteiligte, die seit Eriks Rückmeldung zum Entwurfsvergleich wieder
dauerhaft sichtbar sind (.bericht-meta-grid, siehe weiter oben), bleibt
dies der einzige Aufklapper. Zustände bleiben binär (anwesend / nicht
anwesend, Tabelle attendance); der Zähler in der Kopfzeile macht sichtbar,
wenn noch niemand geklickt hat. */
#weekAttendance .bericht-disclosure { margin-top: 16px; }
.attendance-actions { display: flex; gap: 8px; margin-bottom: 10px; }
@@ -4174,12 +4183,15 @@ td.actions-cell button { margin: 2px; }
color: var(--text-muted);
}
/* === Wochenbericht als Tagesordnung, Fokus-Modus (Eriks Wahl "C" aus dem
Darstellungs-Vergleich, js/wochenbericht/wochenbericht.js) ===
Links eine schmale Nummern-Leiste (jedes Projekt nur eine Position + ggf.
ein Änderungs-Punkt, Name im Tooltip), rechts das gewählte Projekt — nur
Kommentar und Kernstatus liegen dort offen, Leistungsphasen/Beteiligte/
Anwesenheit stecken in aufklappbaren Abschnitten (.bericht-disclosure).
/* === Wochenbericht als Tagesordnung, Fokus-Modus "Aktenregal" (Eriks Wahl
aus dem Entwurfsvergleich, js/wochenbericht/wochenbericht.js) ===
Links eine Leiste mit Nummer, Gruppe UND Name direkt sichtbar (keine
schmale Icon-Spalte mit Namen nur im Hover-Tooltip mehr), rechts das
gewählte Projekt: Kommentar (inkl. Scrollrad zum Verlauf), darunter
Leistungsphasen und Beteiligte dauerhaft sichtbar nebeneinander
(.bericht-meta-grid). Nur die Anwesenheit der Sitzung bleibt ein
aufklappbarer Abschnitt (.bericht-disclosure) - sie ist sitzungs-, nicht
projektbezogen und sitzt am Seitenfuß, unabhängig vom gewählten Projekt.
Ersetzt die vorherige ausgeschriebene Liste|Detail-Darstellung, die mit
Gewerke-Dropdown, Fortschrittsbalken, Suchfeld, mehreren Badges je Zeile
und allem gleichzeitig sichtbar als "zu überladen" zurückgemeldet wurde.
@@ -4201,7 +4213,12 @@ td.actions-cell button { margin: 2px; }
}
.bericht-gewerk-select {
font-size: 12px; font-weight: 600; padding: 5px 10px;
border-radius: var(--r-sm); background: var(--surface-alt);
/* background-color statt background (Kurzform): die Kurzform setzt das vom
globalen select-Selektor gesetzte Pfeil-Icon (background-image/-repeat/
-position) auf die Vorgabewerte zurück, wodurch das 10x6px-Pfeilchen
über das ganze Feld kachelt statt einmal rechts zu sitzen - derselbe
Fehler wie zuvor bei .pc-select. */
border-radius: var(--r-sm); background-color: var(--surface-alt);
border: 1px solid var(--line); color: var(--text); cursor: pointer;
}
.bericht-ring {
@@ -4347,46 +4364,42 @@ td.actions-cell button { margin: 2px; }
border: 1px solid var(--line-soft); border-radius: var(--r-sm); background: var(--surface-alt);
}
.pc-result-shot:hover img { border-color: var(--accent); }
.bericht-layout { display: grid; grid-template-columns: 64px minmax(0, 1fr); }
@media (max-width: 760px) { .bericht-layout { grid-template-columns: 48px minmax(0, 1fr); } }
/* Entwurf "Aktenregal" (zweite Fassung des Fokus-Modus, Eriks Wahl aus dem
Entwurfsvergleich): die Leiste zeigt Nummer, Gruppe UND Name direkt statt
nur eine Nummer mit Name im Hover-Tooltip (die vorherige, schmale 64px-
Fassung) — man sieht die ganze Tagesordnung auf einen Blick, nicht nur
beim Drüberfahren. */
.bericht-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); }
@media (max-width: 860px) { .bericht-layout { grid-template-columns: 1fr; } }
.bericht-rail {
background: var(--surface-alt);
border-right: 1px solid var(--line-soft);
padding: 10px 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
/* Die Leiste bleibt beim Scrollen im Blick — sie IST die Tagesordnung. Kein
eigener Rahmen/Radius/Schatten mehr und keine eigene Höhenbegrenzung:
die Fläche gehört zu .bericht-panel, und eine gedeckelte Höhe zwang den
eigenen (inzwischen entfernten) Tooltip zum Abschneiden — ein Element mit
overflow-y ungleich visible schneidet nach der CSS-Spezifikation auch in
X-Richtung ab. */
position: sticky; top: 64px;
padding: 10px 8px; display: flex; flex-direction: column; gap: 2px;
position: sticky; top: 64px; max-height: calc(100vh - 64px); overflow-y: auto;
}
.bericht-rail-gruppe {
font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
color: var(--text-subtle); padding: 12px 8px 5px;
}
.bericht-rail-gruppe:first-child { padding-top: 2px; }
.bericht-rail-item {
position: relative; width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
color: var(--text-subtle); cursor: pointer;
position: relative; display: flex; align-items: center; gap: 8px;
padding: 6px 8px; border-radius: var(--r-sm); cursor: pointer; color: var(--text); font-size: 12.5px;
}
.bericht-rail-item:hover { background: var(--surface-sunk); color: var(--text); }
.bericht-rail-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bericht-rail-item.is-aktiv { background: var(--accent); color: #fff; }
.bericht-rail-item:hover { background: var(--surface-sunk); }
.bericht-rail-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.bericht-rail-item.is-aktiv { background: var(--accent-soft); }
.bericht-rail-item.is-aktiv .bericht-rail-name { color: var(--accent); font-weight: 650; }
/* Abgehakt: zurückgenommen, aber erkennbar — man muss im Meeting noch sehen
können, was man schon besprochen hat. */
.bericht-rail-item.is-ab { opacity: .55; }
.bericht-rail-item.is-aktiv.is-ab { opacity: 1; }
.bericht-rail-num { font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.bericht-rail-dot { position: absolute; top: 3px; right: 3px; width: 6px; height: 6px; border-radius: 50%; }
.bericht-rail-num { font-size: 11px; color: var(--text-subtle); font-variant-numeric: tabular-nums; flex-shrink: 0; width: 16px; }
.bericht-rail-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.bericht-rail-dot.is-new, .bericht-rail-dot.is-status { background: var(--band-neu); }
.bericht-rail-dot.is-progress { background: var(--band-fortschritt); }
.bericht-rail-item.is-aktiv .bericht-rail-dot { outline: 1.5px solid var(--accent-soft); outline-offset: -1px; }
.bericht-rail-tooltip {
position: absolute; left: 48px; top: 50%; transform: translateY(-50%);
background: var(--text); color: var(--surface); font-size: 11px; padding: 4px 8px;
border-radius: var(--r-sm); white-space: nowrap; opacity: 0; pointer-events: none;
transition: opacity .12s var(--ease); z-index: 5;
}
.bericht-rail-item:hover .bericht-rail-tooltip,
.bericht-rail-item:focus-visible .bericht-rail-tooltip { opacity: 1; }
.bericht-rail-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* max-width: die Hauptspalte bleibt eine schmale Lesespalte statt bis zum
rechten Rand zu laufen — Teil der Fokus-Idee, nicht nur die Nebeninfos
@@ -4412,17 +4425,36 @@ td.actions-cell button { margin: 2px; }
color: var(--amber); font-size: 12px; margin-bottom: 16px;
}
/* Der Kommentar der Vorwoche steht ÜBER dem Eingabefeld: "Was hatten wir
letzte Woche vereinbart?" ist die häufigste Frage im Meeting. */
.bericht-vorwoche {
background: var(--surface-sunk); border-radius: var(--r-md);
padding: 9px 12px; margin-bottom: 14px; font-size: 12px; color: var(--text-muted);
/* Scrollrad über dem Kommentar-Eingabefeld: "Was hatten wir letzte Woche
vereinbart?" ist die häufigste Frage im Meeting - stand bis hierhin als
starre Einzeile mit nur der unmittelbaren Vorwoche da. Erik wollte mit dem
Mausrad durch MEHRERE vergangene Kommentare blättern können
(renderVorwocheRad(), js/wochenbericht/wochenbericht.js), nicht nur die
eine Vorwoche sehen - die Quelle ist derselbe, bereits geprüfte Verlauf wie
im Verlaufs-Dialog (projectStatusHistory(), js/utils.js). */
.bericht-vorwoche-rad {
display: flex; align-items: center; gap: 8px; background: var(--surface-sunk);
border-radius: var(--r-md); padding: 7px 9px; margin-bottom: 14px; cursor: ns-resize;
}
.bericht-vorwoche-nav {
width: 22px; height: 22px; border: none; background: none; border-radius: 50%;
color: var(--text-muted); cursor: pointer; font-size: 13px; flex-shrink: 0;
display: flex; align-items: center; justify-content: center; font-family: inherit;
}
.bericht-vorwoche-nav:hover:not(:disabled) { background: var(--surface); color: var(--text); }
.bericht-vorwoche-nav:disabled { opacity: .3; cursor: default; }
.bericht-vorwoche-inhalt { flex: 1; min-width: 0; }
.bericht-vorwoche-label {
display: block; font-weight: 600; color: var(--text-subtle);
text-transform: uppercase; font-size: 10.5px; letter-spacing: .05em; margin-bottom: 3px;
}
.bericht-vorwoche-text { color: var(--text-muted); }
.bericht-vorwoche-text {
color: var(--text-muted); font-size: 12px; display: block;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bericht-vorwoche-dots { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.bericht-vorwoche-dots .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--line); }
.bericht-vorwoche-dots .dot.aktiv { background: var(--accent); }
.bericht-detail-fuss { display: flex; align-items: center; gap: 14px; margin-top: 20px; }
.bericht-fuss-spacer { flex: 1; }
@@ -5095,3 +5127,128 @@ td.actions-cell button { margin: 2px; }
.wiz-plan-zeile span:nth-child(2),
.wiz-plan-zeile span:nth-child(4) { display: none; }
}
/* ============================================================
BEWEGUNG - Stufe "Spürbar"
============================================================
Von Erik aus einem Dreier-Vergleich gewählt (dezent / spürbar /
lebendig). Die Werte stehen als Tokens oben in :root; hier wird
nur angewendet.
Bewusst NICHT enthalten: Eintritts-Animationen für Listen und
aufziehende Balken (das war Stufe 3). Die Oberfläche bewegt sich
ausschliesslich als Antwort auf Zeigen oder Klicken, nie von
selbst - bei einer Liste mit dreissig Projekten, die mehrmals
täglich neu gerendert wird, wäre alles andere Unruhe.
Die Wandtafel (body.wandtafel-aktiv) bleibt bewusst aussen vor:
ein Touch-Monitor kennt kein Hover, und die Tafel trägt ohnehin
ihre eigene Gestaltung (--dash-*).
============================================================ */
/* --- 1. Anklickbare Zeilen: anheben + Akzentleiste ---------------
Die Leiste entsteht als inset-Schatten, NICHT als ::before mit
position:absolute. Grund: .board-row ist draggable (Drag-and-Drop
der Projektliste, js/projects/projects.js). Ein zusätzliches
positioniertes Element bzw. ein Stapelkontext auf der Zeile kann
das Ziehbild und die Trefferflächen verschieben; ein inset-Schatten
kann das nicht, weil er weder Layout noch Stapelkontext anfasst.
Der Schatten wächst von 0 auf 3px, wirkt also wie eine von links
einfahrende Leiste. */
.board-row-main,
.bericht-rail-item,
.planung-row,
.dash-rand-zeile {
transition: background var(--dur) var(--ease-out),
box-shadow var(--dur) var(--ease-out),
transform var(--dur) var(--ease-out);
}
.board-row-main:hover,
.bericht-rail-item:hover,
.planung-row:hover,
.dash-rand-zeile:hover {
transform: translateY(var(--row-lift));
box-shadow: inset 3px 0 0 0 var(--accent);
}
/* Beim Drücken wieder absetzen: die Zeile geht unter den Finger
zurück, statt angehoben zu bleiben. */
.board-row-main:active,
.bericht-rail-item:active,
.planung-row:active,
.dash-rand-zeile:active {
transform: translateY(0);
transition-duration: 60ms;
}
/* Eine bereits ausgewählte Zeile trägt die Leiste dauerhaft - sonst
verschwände beim Wegfahren der Maus die einzige Markierung. */
.bericht-rail-item.is-aktiv { box-shadow: inset 3px 0 0 0 var(--accent); }
/* --- 2. Druckpunkt für alles Klickbare -------------------------
button:active trug schon scale(.97); hier kommen die übrigen
Bedienelemente auf denselben Wert, damit sich nicht das eine
Element gedrückt anfühlt und das Nachbarelement nicht. */
.board-avatar,
.person-chip,
.nav-item,
.attendance-tile,
.plan-verweis,
.tag-chip .tag-remove,
.richtext-btn,
.pc-btn {
transition: background var(--dur) var(--ease-out),
border-color var(--dur) var(--ease-out),
color var(--dur) var(--ease-out),
transform var(--dur) var(--ease-out);
}
.board-avatar:not(.is-ansicht):active,
.person-chip:active,
.nav-item:active,
.attendance-tile:active,
.plan-verweis:active,
.richtext-btn:active,
.pc-btn:active { transform: scale(var(--press)); }
/* --- 3. Dialoge: auftauchen statt aufblitzen -------------------
.modal-bg wird per JS von display:none auf flex geschaltet. Ein
display-Wechsel ist nicht übergangsfähig, eine ANIMATION dagegen
startet neu, sobald das Element wieder gerendert wird - deshalb
hier animation statt transition. Die Fläche blendet auf, der
Dialog kommt dabei minimal aus der Tiefe. */
.modal-bg { animation: modal-bg-auf var(--dur-lg) var(--ease-out); }
.modal-bg > .modal { animation: modal-auf var(--dur-lg) var(--ease-out); }
@keyframes modal-bg-auf { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-auf {
from { opacity: 0; transform: translateY(6px) scale(.985); }
to { opacity: 1; transform: none; }
}
/* --- 4. Tastatur-Fokus sichtbar halten ------------------------
Die Hebe-/Druck-Effekte oben reagieren auf Maus und Finger. Wer
mit der Tastatur arbeitet, braucht eine eigene, deutliche Marke;
ohne sie wäre die Oberfläche nach diesem Umbau für Tastatur-
Bedienung schlechter lesbar als vorher. */
.board-row-main:focus-visible,
.bericht-rail-item:focus-visible,
.planung-row:focus-visible,
.person-chip:focus-visible,
.board-avatar:focus-visible,
.nav-item:focus-visible {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
/* --- 5. Bewegung abbestellt ------------------------------------
Pflichtteil, in dieser Datei bisher gar nicht vorhanden. Weil die
Stufe an Variablen hängt, genügt es, sie zu kippen: ohne Hub und
ohne Stauchung bleibt reine Farb-Rückmeldung übrig. Die
transition-/animation-Zeilen fangen zusätzlich die rund sechzig
älteren Regeln ab, die ihre Dauer noch fest eingetragen haben. */
@media (prefers-reduced-motion: reduce) {
:root { --row-lift: 0px; --press: 1; --dur: 1ms; --dur-lg: 1ms; }
*, *::before, *::after {
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
transition-duration: 1ms !important;
scroll-behavior: auto !important;
}
}