Files
dogfather-universe/workspace/assets/css/automation.css
T
DogFatherGitandClaude Opus 5 1b2874299e Uhr und Glocke in die Begruessung, Teilen in die Leiste, ein echter Fehler weg
Neun Punkte aus Filipes Bildschirmfotos. Der wichtigste war kein
Aussehen, sondern ein Fehler:

UEBEREINANDERLIEGENDE TEXTE IN DER SICHERUNGSLISTE. Das Datum entstand
aus `name.split('-').slice(1).reverse().join('.')`. Bei
"woechentlich-2026-09-06.db" ging das gut; die Sicherungen vor einem
Umbau heissen aber "vorher-2026-09-02-160012438.db" -- mit Zeitstempel.
Heraus kam "160012438.02.09.2026", dreimal so lang wie die 96-px-Spalte,
und es lief ueber den Nachbartext. Ein Muster, das Bestandteile ZAEHLT
statt sie zu SUCHEN, bricht beim ersten Namen mit einem Teil mehr. Jetzt
ein Suchmuster nach vier-zwei-zwei Ziffern -- und in der CSS eine
Kuerzung, damit der NAECHSTE zu lange Text nur abgeschnitten wird. Eine
Spalte mit fester Breite ohne Kuerzung ist immer eine Zeitbombe.

DIE BEGRUESSUNGSKACHEL. Runde Digitaluhr rechts: zwei Ringe um dieselbe
Mitte -- innen die Sekunde, aussen der Stand der Stunde. Kein
setInterval(1000): Ein fester Takt laeuft mit der Zeit aus dem Tritt und
ueberspringt Sekunden; gewartet wird bis zur naechsten VOLLEN Sekunde.
Die Glocke ist aus der Kopfleiste hierhergezogen -- mit Rueckfall, denn
zwoelf andere Seiten haben diesen Platz nicht. Nebenbei ist die Leiste
damit um ein Element leichter; sie ist am 06.09. schon einmal an einem
sechsten zerbrochen.

TEILEN-KNOPF in der Leiste, nur fuer Scout, Manager und DogFather.
Geteilt wird der EINGANG, nicht die aktuelle Seite: Ein Link auf
bereich.html?b=schutz schickt jemanden auf eine Seite, die er nicht
sehen darf. Wo es navigator.share gibt, wird es benutzt; sonst
Zwischenablage; wo beides fehlt, erscheint der Knopf gar nicht -- ein
dritter Ausgang statt einer Schaltflaeche, die nichts tut.

WEITER: Kachelreihenfolge Steckbrief -> Profile -> Zahlen. Die
Tagesliste laesst sich zuklappen und zeigt dann SIEBEN Tage (die Woche,
nicht die vier von ueberall sonst). Dialoge, Automationen-Karten,
Sicherungsblock, KI-Kasten und Call-Karten bekommen dasselbe Material
wie die Kacheln -- Leuchtschiene, Materialstaerke, Glanz.

Profilbilder brauchten nichts: Der Weg gibt es fuer jede Rolle bereits
(steckbrief.html fuer die Betreuung, derselbe Block auf profil.html fuer
Creator, Hochladen schreibt immer auf req.person.id).

ZWEI EIGENE FEHLER, beide gemessen statt vermutet:
  - Die Koernung lag in vier neuen Bloecken auf DERSELBEN Ebene wie die
    Spiegelung und erbte deren 50 % Deckkraft. Gemessen rgb(56,44,58)
    statt rgb(20,26,38) -- die Karten sahen durchsichtig aus, obwohl sie
    zu 95 % decken. Derselbe Fehler wie heute Nachmittag an der
    Anmeldekarte. Koernung gehoert auf eine eigene Ebene mit overlay.
  - `.glocke-platz:empty { display: none }` liess die Kachel wachsen,
    sobald die Glocke geladen war. Layout-Sprung von start.html: 0,708.
    Platz wird jetzt reserviert -> 0,473.

pruef-struktur: `-breit` gehoert in die Stufen-Ausnahme. Schaerfe kostet
Bytes (hohe Frequenzen lassen sich nicht wegrechnen), die mittlere Stufe
wuchs auf 230-300 KB. Die Regel bleibt inhaltlich: gross nur, WENN eine
kleinere Stufe daneben steht. Die Verkettung der beiden replace() waere
ein stiller Fehler gewesen -- fuer uhd haette sie nach `-schmal` gesucht.

Gruen: kopf-messen (3), breiten (23), glocke (26), css-klassen (15),
struktur (32), buehne (38), start-ansicht (136), handy (59),
formulare (19), barrierefrei (18), lesbarkeit (14), tempo (8).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-07 03:40:49 +02:00

438 lines
17 KiB
CSS

/* ===================================================================
Automationen.
Ein Zustandsbild, keine Bedienoberflaeche: Der einzige Schalter ist
der fuer die KI, weil sie als einzige Rechenzeit kostet, die der
Website gehoert. Alles andere laeuft und wird hier nur gezeigt.
=================================================================== */
.block { margin-bottom: 34px; }
.block__kopf { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.block__titel {
margin: 0; font-size: .78rem; font-weight: 700;
letter-spacing: .08em; text-transform: uppercase; color: var(--akzent);
}
.block__zahl {
min-width: 22px; padding: 1px 8px; text-align: center;
font-size: .74rem; font-weight: 700; color: var(--text-still);
background: rgba(255, 255, 255, .06); border-radius: 999px;
}
.block__frage { margin: 0 0 14px; font-size: .85rem; color: var(--text-still); max-width: 76ch; }
/* ---------- KI ------------------------------------------------------------ */
.ki-kasten {
margin-bottom: 34px; padding: 20px 22px;
border: 1px solid var(--rand); border-radius: var(--radius);
background: var(--flaeche);
}
.ki-kasten[data-zustand="laeuft"] {
border-color: rgba(138, 118, 255, .34);
background: rgba(138, 118, 255, .05);
}
.ki-kasten[data-zustand="weg"] {
border-color: rgba(255, 154, 162, .3);
background: rgba(255, 154, 162, .045);
}
.ki-kasten__kopf {
display: flex; gap: 20px; align-items: flex-start;
justify-content: space-between; flex-wrap: wrap;
}
.ki-kasten__titel { margin: 2px 0 6px; font-size: 1.1rem; font-weight: 700; }
.ki-kasten__text { margin: 0; font-size: .88rem; color: var(--text-leise); max-width: 62ch; }
.ki-kasten__daten {
display: grid; gap: 7px; margin: 18px 0 0; padding: 16px 0 0; list-style: none;
border-top: 1px solid var(--rand);
grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.ki-kasten__daten li { display: flex; gap: 10px; font-size: .83rem; color: var(--text-leise); }
.ki-kasten__schild {
flex: none; min-width: 74px;
font-size: .7rem; font-weight: 700; letter-spacing: .07em;
text-transform: uppercase; color: var(--text-still); padding-top: 2px;
}
/* ---------- Sicherung & Zustand -------------------------------------------
Derselbe Kasten wie bei der KI, aber mit eigener Farbgebung fuer den
Zustand: Gruen gibt es hier bewusst nicht -- "es lief" ist der
Normalfall und soll nicht feiern. Auffaellig wird es nur, wenn eine
Nacht ausgefallen ist oder etwas schiefging.
-------------------------------------------------------------------------- */
.zustand {
margin-bottom: 34px; padding: 20px 22px;
border: 1px solid var(--rand); border-radius: var(--radius);
background: var(--flaeche);
}
.zustand[data-zustand="alt"] {
border-color: rgba(232, 192, 125, .34); background: rgba(232, 192, 125, .05);
}
.zustand[data-zustand="fehler"] {
border-color: rgba(255, 154, 162, .34); background: rgba(255, 154, 162, .05);
}
.zustand__kopf {
display: flex; gap: 20px; align-items: flex-start;
justify-content: space-between; flex-wrap: wrap;
}
.zustand__titel { margin: 2px 0 6px; font-size: 1.1rem; font-weight: 700; }
.zustand[data-zustand="fehler"] .zustand__titel { color: var(--warn); }
.zustand__text { margin: 0; font-size: .88rem; color: var(--text-leise); max-width: 68ch; }
.zustand__daten {
display: grid; gap: 7px; margin: 18px 0 0; padding: 16px 0 0; list-style: none;
border-top: 1px solid var(--rand);
grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
}
.zustand__daten li { display: flex; gap: 10px; font-size: .83rem; color: var(--text-leise); }
.zustand__daten .ki-kasten__schild { min-width: 128px; }
.zustand__listenkopf { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--rand); }
/* ---------- Hinweise ------------------------------------------------------- */
.hinweise { display: grid; gap: 7px; }
.hinweis {
position: relative; display: flex; align-items: center; gap: 12px;
padding: 11px 15px 11px 18px;
text-decoration: none; color: var(--text); font-size: .89rem;
border: 1px solid var(--rand); border-radius: var(--radius-klein);
background: var(--flaeche);
transition: border-color .18s ease, background .18s ease;
}
.hinweis::before {
content: ""; position: absolute; left: 0; top: 9px; bottom: 9px; width: 2px;
border-radius: 0 2px 2px 0; background: var(--rand);
}
.hinweis[data-stufe="warnung"] {
border-color: rgba(255, 154, 162, .3); background: rgba(255, 154, 162, .05);
}
.hinweis[data-stufe="warnung"]::before { background: var(--warn); }
.hinweis[data-stufe="offen"]::before { background: var(--akzent); opacity: .7; }
.hinweis[data-stufe="ruhig"] { opacity: .8; }
.hinweis:hover { border-color: rgba(255, 255, 255, .2); background: rgba(255, 255, 255, .05); }
.hinweis__zahl {
flex: none; min-width: 30px; text-align: center;
font-size: 1.05rem; font-weight: 700;
}
.hinweis[data-stufe="warnung"] .hinweis__zahl { color: var(--warn); }
.hinweis__text { flex: 1; color: var(--text-leise); }
.hinweis__pfeil { color: var(--text-still); }
.hinweis:hover .hinweis__pfeil { color: var(--akzent); }
/* ---------- Regeln --------------------------------------------------------- */
.regeln {
display: grid; gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
}
.regel {
padding: 15px 17px;
border: 1px solid var(--rand); border-radius: var(--radius-klein);
background: var(--flaeche);
}
.regel__name { margin: 0 0 5px; font-size: .93rem; font-weight: 650; }
.regel__text { margin: 0; font-size: .83rem; color: var(--text-still); line-height: 1.55; }
/* ---------- Verlauf -------------------------------------------------------- */
.verlauf { display: grid; gap: 2px; }
.verlauf__zeile {
display: grid; gap: 12px; align-items: baseline;
grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1.2fr);
padding: 8px 12px; border-radius: var(--radius-klein);
font-size: .82rem;
}
.verlauf__zeile:nth-child(odd) { background: var(--flaeche); }
/* ÜBERLAUF WIRD GEKÜRZT, NICHT ÜBERGESTELLT.
Die erste Spalte ist 96 px breit und hatte keine Bremse -- ein zu
langer Text lief einfach weiter und legte sich über den Nachbarn.
Am 07.09.2026 ist genau das passiert (ein falsch gebautes Datum,
siehe automation.js). Der Auslöser ist behoben; diese drei Zeilen
sorgen dafür, dass der NÄCHSTE zu lange Text nur abgeschnitten wird,
statt etwas unlesbar zu machen. Eine Spalte mit fester Breite ohne
Kürzung ist immer eine Zeitbombe. */
.verlauf__zeit {
color: var(--text-still); font-variant-numeric: tabular-nums;
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.verlauf__was {
color: var(--text);
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.verlauf__wer { color: var(--text-still); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 700px) {
.verlauf__zeile { grid-template-columns: 1fr; gap: 2px; }
}
@media (prefers-reduced-motion: reduce) { .hinweis { transition: none; } }
/* =====================================================================
AUTOMATIONEN — dasselbe Material wie überall (07.09.2026)
Filipe zu den Regelkarten: "diese kacheln sollen alle viel viel
krasser sein bitte." Und zum Sicherungsblock: "das soll auch viel
viel spezieller aussehen und die texte auch nicht übereinander."
Der zweite Satz ist der wichtigere -- die Überlappung war ein echter
Fehler und ist in automation.js behoben (ein falsch gebautes Datum)
und in .verlauf__zeit abgesichert (feste Spaltenbreite ohne Kürzung).
Optisch war der Befund derselbe wie überall: Diese Seite bestand aus
flachen Rechtecken mit `var(--flaeche)` und einem Rand -- gebaut,
bevor es die Leuchtschienen gab. Sie sah dadurch aus wie aus einer
anderen Anwendung.
ZWEI STUFEN, NICHT EINE. Die Regelkarten bekommen eine RUHIGE
Schiene: Es sind neun gleichrangige Karten, und neun leuchtende
Schienen nebeneinander ergeben einen Zaun. Der Sicherungsblock
dagegen ist EINE Karte mit einer Aussage ("zuletzt gesichert vor 23
Stunden") und bekommt die volle Behandlung -- er ist das Erste, was
man auf dieser Seite wissen will.
UND DIE SCHIENE SAGT ETWAS. Am Sicherungsblock nimmt sie die Farbe
des Zustands an: grün, wenn frisch, bernstein, wenn alt, rot bei
Fehler. Damit ist der Zustand aus dem Augenwinkel erkennbar, und der
Text daneben sagt dasselbe noch einmal in Worten -- Farbe allein
reicht nie.
===================================================================== */
/* ---------- Der Sicherungsblock -------------------------------------- */
.zustand {
--z: var(--k-gut);
position: relative;
overflow: hidden;
border-radius: 4px 20px 20px 4px;
background:
linear-gradient(90deg,
color-mix(in srgb, var(--z) 26%, transparent) 0%,
color-mix(in srgb, var(--z) 9%, transparent) 12%,
color-mix(in srgb, var(--z) 3%, transparent) 26%,
transparent 46%),
linear-gradient(163deg,
rgba(23, 31, 45, .95) 0%,
rgba(11, 15, 24, .95) 58%,
rgba(8, 11, 18, .95) 100%);
border-color: color-mix(in srgb, var(--z) 20%, rgba(150, 186, 220, .13));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .10),
inset 0 -1px 0 rgba(0, 0, 0, .50),
0 2px 5px -2px rgba(0, 0, 0, .55),
0 16px 34px -20px rgba(0, 0, 0, .88);
}
.zustand::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
border-radius: 4px 0 0 4px;
background: linear-gradient(180deg,
color-mix(in srgb, var(--z) 55%, #fff) 0%,
var(--z) 26%,
color-mix(in srgb, var(--z) 48%, transparent) 100%);
box-shadow:
0 0 9px 0 color-mix(in srgb, var(--z) 55%, transparent),
3px 0 20px -3px color-mix(in srgb, var(--z) 42%, transparent);
z-index: 2;
}
.zustand::after {
content: ""; position: absolute; inset: 0; pointer-events: none;
border-radius: inherit;
background:
linear-gradient(112deg,
transparent 24%,
rgba(255, 255, 255, .045) 40%,
rgba(255, 255, 255, .08) 47%,
rgba(255, 255, 255, .025) 55%,
transparent 70%);
/* KEINE Körnung auf DIESER Ebene (07.09.2026, gemessen).
Sie stand hier als zweite Schicht und hat die Deckkraft der
Spiegelung geerbt -- 50 % eines mittelgrauen Rauschens heben jeden
Bildpunkt um rund 30 Stufen an. Gemessen: rgb(56,44,58) statt der
berechneten rgb(20,26,38), und über einer hellen Stelle des
Motivs rgb(85,83,81). Die Karte sah dadurch durchsichtig aus,
obwohl sie zu 95 % deckt.
Derselbe Fehler wie an der Anmeldekarte heute Nachmittag, und
genau derselbe Grund: Körnung gehört auf eine EIGENE Ebene mit
`mix-blend-mode: overlay` und 3 bis 4 Prozent -- so wie bei den
Kacheln der Startseite. Auf einer geteilten Ebene ist sie kein
Material, sondern ein grauer Schleier. */
opacity: .5;
}
.zustand > * { position: relative; z-index: 1; }
/* Der Zustand steckt in EINER Größe. Die beiden Regeln darunter setzen
nur noch sie -- vorher standen Rand und Fläche zweimal getrennt da
und konnten auseinanderlaufen. */
.zustand[data-zustand="alt"] { --z: var(--k-mittel); }
.zustand[data-zustand="fehler"] { --z: var(--k-warn); }
/* Die Kennzahlen darunter als eingelassene Felder statt als bloße
Aufzählung -- so liest man sie als Anzeige und nicht als Fließtext. */
.zustand__daten {
gap: 10px;
}
.zustand__daten li {
padding: 9px 12px;
border-radius: var(--radius-klein);
background: rgba(0, 0, 0, .28);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
align-items: baseline;
}
/* ---------- Die Regelkarten ------------------------------------------ */
.regeln { gap: 12px; }
.regel {
position: relative;
overflow: hidden;
padding: 16px 18px 16px 20px;
border-radius: 3px 16px 16px 3px;
border-color: rgba(150, 186, 220, .12);
background:
linear-gradient(90deg,
color-mix(in srgb, var(--akzent) 13%, transparent) 0%,
color-mix(in srgb, var(--akzent) 4%, transparent) 16%,
transparent 40%),
linear-gradient(163deg,
rgba(21, 28, 41, .95) 0%,
rgba(11, 15, 24, .95) 62%,
rgba(8, 11, 18, .95) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .075),
inset 0 -1px 0 rgba(0, 0, 0, .45),
0 2px 4px -2px rgba(0, 0, 0, .5),
0 12px 26px -18px rgba(0, 0, 0, .85);
transition: border-color var(--tempo), transform var(--tempo), box-shadow var(--tempo);
}
/* Die ruhige Schiene: 3 px, kein Leuchten. Neun leuchtende Schienen
nebeneinander ergäben einen Zaun -- hier zählt, dass die Karten eine
Reihe bilden, nicht dass jede für sich strahlt. */
.regel::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
border-radius: 3px 0 0 3px;
background: linear-gradient(180deg,
color-mix(in srgb, var(--akzent) 78%, transparent) 0%,
color-mix(in srgb, var(--akzent) 40%, transparent) 100%);
opacity: .6;
transition: opacity var(--tempo);
}
.regel::after {
content: ""; position: absolute; inset: 0; pointer-events: none;
border-radius: inherit;
background-image: var(--koernung);
background-size: 140px 140px;
opacity: .03;
mix-blend-mode: overlay;
}
.regel > * { position: relative; z-index: 1; }
/* Beim Überfahren hebt sich die Karte an und ihre Schiene brennt --
dieselbe Bewegung wie bei den Kacheln der Startseite, damit man nicht
zwei Oberflächen lernt. Angeklickt wird hier nichts; das Anheben sagt
nur "das gehört zusammen". */
.regel:hover {
transform: translateY(-2px);
border-color: color-mix(in srgb, var(--akzent) 30%, rgba(150, 186, 220, .16));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .10),
inset 0 -1px 0 rgba(0, 0, 0, .45),
0 4px 9px -4px rgba(0, 0, 0, .55),
0 18px 36px -20px rgba(0, 0, 0, .9);
}
.regel:hover::before { opacity: 1; }
.regel__name { margin: 0 0 6px; font-size: .96rem; font-weight: 700; color: #eaf2fb; }
.regel__text { color: var(--text-leise); }
@media (prefers-reduced-motion: reduce) {
.regel, .regel:hover { transform: none; }
}
@media (forced-colors: active) {
.zustand, .regel { background: Canvas; box-shadow: none; border: 1px solid CanvasText; }
.zustand::after, .regel::after { display: none; }
}
/* =====================================================================
DIE KI-KACHEL bekommt dasselbe Material wie der Sicherungsblock.
Sie stand als einzige Fläche dieser Seite noch flach da. Zwei
Materialien auf einer Seite wirken zusammengesucht -- und ausgerechnet
die oberste Kachel hätte den ersten Eindruck gemacht.
===================================================================== */
.ki-kasten {
--z: var(--violett);
position: relative;
overflow: hidden;
border-radius: 4px 20px 20px 4px;
background:
linear-gradient(90deg,
color-mix(in srgb, var(--z) 24%, transparent) 0%,
color-mix(in srgb, var(--z) 8%, transparent) 12%,
color-mix(in srgb, var(--z) 3%, transparent) 26%,
transparent 46%),
linear-gradient(163deg,
rgba(23, 31, 45, .95) 0%,
rgba(11, 15, 24, .95) 58%,
rgba(8, 11, 18, .95) 100%);
border-color: color-mix(in srgb, var(--z) 20%, rgba(150, 186, 220, .13));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, .10),
inset 0 -1px 0 rgba(0, 0, 0, .50),
0 2px 5px -2px rgba(0, 0, 0, .55),
0 16px 34px -20px rgba(0, 0, 0, .88);
}
.ki-kasten::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
border-radius: 4px 0 0 4px;
background: linear-gradient(180deg,
color-mix(in srgb, var(--z) 55%, #fff) 0%,
var(--z) 26%,
color-mix(in srgb, var(--z) 48%, transparent) 100%);
box-shadow:
0 0 9px 0 color-mix(in srgb, var(--z) 55%, transparent),
3px 0 20px -3px color-mix(in srgb, var(--z) 42%, transparent);
z-index: 2;
}
.ki-kasten::after {
content: ""; position: absolute; inset: 0; pointer-events: none;
border-radius: inherit;
background:
linear-gradient(112deg,
transparent 24%,
rgba(255, 255, 255, .045) 40%,
rgba(255, 255, 255, .08) 47%,
rgba(255, 255, 255, .025) 55%,
transparent 70%);
/* KEINE Körnung auf DIESER Ebene (07.09.2026, gemessen).
Sie stand hier als zweite Schicht und hat die Deckkraft der
Spiegelung geerbt -- 50 % eines mittelgrauen Rauschens heben jeden
Bildpunkt um rund 30 Stufen an. Gemessen: rgb(56,44,58) statt der
berechneten rgb(20,26,38), und über einer hellen Stelle des
Motivs rgb(85,83,81). Die Karte sah dadurch durchsichtig aus,
obwohl sie zu 95 % deckt.
Derselbe Fehler wie an der Anmeldekarte heute Nachmittag, und
genau derselbe Grund: Körnung gehört auf eine EIGENE Ebene mit
`mix-blend-mode: overlay` und 3 bis 4 Prozent -- so wie bei den
Kacheln der Startseite. Auf einer geteilten Ebene ist sie kein
Material, sondern ein grauer Schleier. */
opacity: .5;
}
.ki-kasten > * { position: relative; z-index: 1; }
/* Der Zustand steckt wieder in EINER Größe. */
.ki-kasten[data-zustand="laeuft"] { --z: var(--violett); }
.ki-kasten[data-zustand="weg"] { --z: var(--k-warn); }
.ki-kasten__daten { gap: 10px; }
.ki-kasten__daten li {
padding: 9px 12px;
border-radius: var(--radius-klein);
background: rgba(0, 0, 0, .28);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
align-items: baseline;
}
@media (forced-colors: active) {
.ki-kasten { background: Canvas; box-shadow: none; border: 1px solid CanvasText; }
.ki-kasten::after { display: none; }
}