ZWEI MELDUNGEN.
1. "DAS SIEHT JA MAL RICHTIG SCHEISSE AUS"
Die Rollenauswahl im Formular "Neue Person" lief unten aus dem
Formular heraus und legte sich ueber die Personenliste darunter.
Die Ursache war keine schlampige Gestaltung, sondern eine Regel, die
fuer etwas anderes gemacht ist: `.neu__raster > *` (aufgaben.css) gibt
JEDEM direkten Kind ein Raster mit fester Zeilenhoehe von 44 px, damit
Beschriftung und Eingabefeld in allen Spalten auf einer Linie sitzen.
Fuer ein einzeiliges Feld ist das genau richtig. Die Rollenauswahl ist
aber kein Feld, sondern ein Block aus vier hohen Karten -- die passten
nicht in 44 px, und was nicht hineinpasst, steht eben daneben.
Das Formular ist jetzt aus dem Spaltenraster geloest und liest sich
von oben nach unten: NAME (schmal, ein Name braucht keine 1200 px),
ROLLE (volle Breite, vier gleich breite Karten), Knoepfe. Das ist
nicht nur reparierter Ueberlauf, sondern auch die Reihenfolge, in der
man die Sache tatsaechlich entscheidet.
Dazu zwei Kleinigkeiten, die den Unterschied machen: Das Namensfeld
war ohne Rasterzeile 60 px hoch geworden (`height: 100%` einer Zeile,
die es nicht mehr gibt) -- hoeher als die Knoepfe daneben, was nach
Versehen aussieht, weil es eins war. Und die gewaehlte Rolle traegt
jetzt ein HAEKCHEN, nicht nur einen etwas helleren Rahmen: Genau die
Art Unterschied, die im Kontrastmodus verschwindet und fuer
farbunsichere Augen nie existiert hat.
2. "DIE MANAGER SOLLEN DIESE KATEGORIEN GARNICHT SEHEN"
"Personen & Zugaenge" und "Automationen" gehoeren ab sofort allein
DogFather.
Bei den Personen war es ohnehin ein Widerspruch im eigenen Haus: In
der Rollenauswahl steht seit jeher "Manager -- dieselben Rechte wie
DogFather, AUSSER der Personenverwaltung". Die Kachel stand trotzdem
bei ihm, und die Schranke liess ihn hinein: Codes erneuern, sperren,
Zuteilungen aendern. Eine Beschreibung, die etwas anderes sagt als die
Software, ist schlimmer als beides einzeln -- man weiss danach nicht
mehr, welcher von beiden man glauben soll.
Umgesetzt auf DREI Ebenen, weil Wegnehmen was man SIEHT kein
Rechteentzug ist:
1. die Kachel erscheint nicht mehr
2. die Seite leitet zur Startseite zurueck (GESCHUETZT)
3. die Schnittstellen antworten mit 404 -- Personenverwaltung,
Systemzustand, KI-Schalter
FOLGE, die bewusst in Kauf genommen wird: Die Betreuungs-Zuteilung
liegt auf der Personenseite. Ab jetzt kann also NUR DogFather
festlegen, wer welchen Creator betreut.
GEPRUEFT: server/pruef-personen-formular.mjs, 20 Pruefungen. Das Aussehen
wird gemessen, nicht angesehen: Endet die Rollenauswahl innerhalb des
Formulars? Ragt eine Karte seitlich hinaus? Liegt etwas ueber der Liste?
Sind alle vier Karten gleich breit (272-272 px)? Traegt die gewaehlte ein
Haekchen? Dazu zwei Gegenproben: DogFather kommt weiterhin an beide
Bereiche (sonst waere jede Sperr-Zeile auch bei einem fuer ALLE kaputten
Bereich gruen), und die Managerin arbeitet ansonsten unveraendert weiter.
Bestehende Laeufe gruen: Rollen 97, Handy 50, Sicherung 41, Personenliste
33, Team 30, Formulare 19, Code 17, Grosscheck 15.
Co-Authored-By: Claude Opus 5 <[email protected]>
304 lines
12 KiB
CSS
304 lines
12 KiB
CSS
/* ===================================================================
|
||
Personenverwaltung.
|
||
=================================================================== */
|
||
|
||
.person {
|
||
display: grid; gap: 4px 16px; align-items: center;
|
||
grid-template-columns: 1fr auto;
|
||
padding: 14px 16px; margin-bottom: 9px;
|
||
background: var(--flaeche);
|
||
border: 1px solid var(--rand);
|
||
border-radius: var(--radius-klein);
|
||
}
|
||
.person[data-aktiv="nein"] { opacity: .58; }
|
||
|
||
.person__name { font-weight: 600; font-size: .98rem; }
|
||
|
||
.person__zeile {
|
||
display: flex; flex-wrap: wrap; gap: 8px;
|
||
margin-top: 2px; font-size: .79rem; color: var(--text-still);
|
||
}
|
||
|
||
.marke-rolle {
|
||
padding: 1px 9px; border-radius: 999px;
|
||
font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
|
||
}
|
||
.marke-rolle[data-rolle="admin"] { background: rgba(63, 189, 245, .16); color: #7fd2fb; }
|
||
.marke-rolle[data-rolle="creator"] { background: rgba(138, 118, 255, .16); color: #b3a6ff; }
|
||
.marke-rolle[data-rolle="scout"] { background: rgba(77, 171, 119, .16); color: #79d1a2; }
|
||
|
||
.person__knoepfe { display: flex; gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
|
||
|
||
/* ---------- Code-Anzeige ---------------------------------------------- */
|
||
|
||
.code-kasten {
|
||
margin: 0 0 26px; padding: 20px 22px;
|
||
background: linear-gradient(100deg, rgba(63, 189, 245, .12), rgba(138, 118, 255, .09));
|
||
border: 1px solid rgba(63, 189, 245, .5);
|
||
border-radius: var(--radius);
|
||
}
|
||
.code-kasten__schild {
|
||
margin: 0 0 8px; font-size: .78rem; font-weight: 600;
|
||
letter-spacing: .06em; text-transform: uppercase; color: var(--text-leise);
|
||
}
|
||
.code-kasten__code {
|
||
margin: 0 0 12px;
|
||
font-family: "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
|
||
font-size: clamp(1.3rem, 3.4vw, 1.9rem); font-weight: 700;
|
||
letter-spacing: .12em; color: #eaf4fd;
|
||
user-select: all; /* ein Klick markiert den ganzen Code */
|
||
word-break: break-all;
|
||
}
|
||
.code-kasten__hinweis { margin: 0 0 14px; font-size: .85rem; color: var(--text-leise); }
|
||
|
||
/* ---------- Protokoll --------------------------------------------------- */
|
||
|
||
.protokoll-block { margin-top: 44px; }
|
||
|
||
/* Das Auf- und Zuklappen selbst steht in start.css (.klapp-kopf,
|
||
.klapp-pfeil, [data-klapp="zu"]) -- es wird auch auf der
|
||
Automationen-Seite gebraucht. */
|
||
|
||
.protokoll-zeile {
|
||
display: grid; gap: 10px;
|
||
grid-template-columns: 128px 190px 1fr auto;
|
||
padding: 7px 10px;
|
||
font-size: .8rem; color: var(--text-leise);
|
||
border-bottom: 1px solid rgba(150, 186, 220, .08);
|
||
}
|
||
.protokoll-zeile:first-child { border-top: 1px solid rgba(150, 186, 220, .08); }
|
||
.protokoll-zeit { color: var(--text-still); font-variant-numeric: tabular-nums; }
|
||
.protokoll-ip { color: var(--text-still); font-variant-numeric: tabular-nums; }
|
||
|
||
@media (max-width: 760px) {
|
||
.person { grid-template-columns: 1fr; }
|
||
.person__knoepfe { justify-content: flex-start; margin-top: 10px; }
|
||
.protokoll-zeile { grid-template-columns: 1fr; gap: 2px; padding: 10px; }
|
||
}
|
||
|
||
|
||
/* ---------- Zuständigkeit ------------------------------------------------
|
||
Wer betreut welchen Creator. Bewusst direkt in der Personenzeile und
|
||
nicht auf einer eigenen Seite: Es ist eine Eigenschaft der Person, kein
|
||
eigener Vorgang. */
|
||
.betreuung { display: flex; align-items: center; gap: 9px; margin-top: 9px; flex-wrap: wrap; }
|
||
.betreuung__schild {
|
||
font-size: .7rem; font-weight: 700; letter-spacing: .07em;
|
||
text-transform: uppercase; color: var(--text-still);
|
||
}
|
||
.betreuung__wahl {
|
||
padding: 6px 10px; min-width: 165px;
|
||
background: rgba(255, 255, 255, .05);
|
||
border: 1px solid var(--rand); border-radius: var(--radius-klein);
|
||
color: var(--text); font: inherit; font-size: .84rem;
|
||
}
|
||
.betreuung__wahl:focus {
|
||
outline: none; border-color: rgba(63, 189, 245, .65);
|
||
box-shadow: 0 0 0 3px rgba(63, 189, 245, .14);
|
||
}
|
||
|
||
/* ===================================================================
|
||
Rollenwahl (28.08.2026).
|
||
|
||
Ersetzt ein <select>. Bei vier Moeglichkeiten ist eine sichtbare Wahl
|
||
schneller -- und vor allem: Das aufgeklappte Systemmenue laesst sich
|
||
nicht gestalten, es kam in Windows-Weiss daher, mitten in einer
|
||
dunklen Oberflaeche. Hier steht ausserdem gleich dabei, was die Rolle
|
||
bedeutet; das ist bei "Manager" gegen "DogFather" der Unterschied
|
||
zwischen Raten und Wissen.
|
||
=================================================================== */
|
||
|
||
/* ---------- Das Formular "Neue Person" (neu gebaut 02.09.2026) ----------
|
||
|
||
Vorher lief die Rollenauswahl unten aus dem Formular heraus und legte
|
||
sich über die Personenliste darunter. Der Grund war keine schlampige
|
||
Gestaltung, sondern eine Regel, die für etwas anderes gemacht ist:
|
||
|
||
`.neu__raster > *` (aufgaben.css) gibt JEDEM direkten Kind ein Raster
|
||
mit fester Zeilenhöhe von 44 px -- damit Beschriftung und Eingabefeld
|
||
in allen Spalten auf derselben Linie sitzen. Für ein einzeiliges Feld
|
||
ist das genau richtig. Die Rollenauswahl ist aber kein Feld, sondern
|
||
ein Block aus vier hohen Karten. Die passten nicht in 44 px, und was
|
||
nicht hineinpasst, steht eben daneben -- sichtbar über allem, was
|
||
darunter liegt.
|
||
|
||
Deshalb wird das Formular hier bewusst aus dem Spaltenraster gelöst
|
||
und von oben nach unten gelesen:
|
||
|
||
NAME (schmal -- ein Name braucht keine 1200 px)
|
||
ROLLE (volle Breite, Karten nebeneinander)
|
||
Knöpfe
|
||
|
||
Das ist nicht nur reparierter Überlauf: Es ist auch die Reihenfolge,
|
||
in der man die Sache tatsächlich entscheidet. */
|
||
#neu .neu__raster {
|
||
grid-template-columns: 1fr;
|
||
/* 26 px, nicht 14: Zwischen "Name" und "Rolle" liegt ein Gedanken-
|
||
sprung -- erst WER, dann WAS DARF ER. Stehen die beiden Blöcke dicht
|
||
beieinander, liest man sie als einen. */
|
||
gap: 26px;
|
||
margin-bottom: 4px;
|
||
}
|
||
/* Die Feldregel aus aufgaben.css hier ausdrücklich zurücknehmen. */
|
||
#neu .neu__raster > * {
|
||
display: block;
|
||
grid-column: 1 / -1;
|
||
height: auto;
|
||
}
|
||
#neu .neu__raster > *:first-child { max-width: 420px; }
|
||
#neu .neu__raster > * > .feld-schild { margin-bottom: 7px; }
|
||
/* Ohne feste Höhe wird das Namensfeld hier gut 60 px hoch: Die Regel
|
||
`height: 100%` aus aufgaben.css bezieht sich auf eine Rasterzeile,
|
||
die es hier nicht mehr gibt. Ein Eingabefeld, das höher ist als die
|
||
Knöpfe daneben, sieht nach Versehen aus -- weil es eins wäre. */
|
||
#neu .neu__raster > * > input { height: 44px; }
|
||
|
||
.rollenwahl-block { grid-column: 1 / -1; }
|
||
.rollenwahl {
|
||
display: grid; gap: 10px; margin-top: 8px;
|
||
/* Vier Karten passen ab etwa 1100 px nebeneinander, darunter bricht
|
||
es von selbst auf zwei und dann auf eine Spalte um. */
|
||
grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
|
||
}
|
||
|
||
.rollenwahl__knopf {
|
||
--r: var(--text-still);
|
||
display: flex; align-items: flex-start; gap: 12px; text-align: left;
|
||
padding: 12px 14px; cursor: pointer;
|
||
background: linear-gradient(#151d2a, #111925);
|
||
border: 1px solid var(--rand); border-radius: 12px;
|
||
color: var(--text-leise); font: inherit;
|
||
transition: border-color .16s ease, background .16s ease, color .16s ease;
|
||
}
|
||
.rollenwahl__knopf:hover { border-color: rgba(255, 255, 255, .22); color: var(--text); }
|
||
.rollenwahl__knopf:focus-visible {
|
||
outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--r) 32%, transparent);
|
||
}
|
||
|
||
/* Eine Farbe je Rolle -- dieselbe Sprache wie überall sonst. */
|
||
.rollenwahl__knopf[data-rolle="admin"] { --r: #e8c07d; }
|
||
.rollenwahl__knopf[data-rolle="manager"] { --r: #8a76ff; }
|
||
.rollenwahl__knopf[data-rolle="scout"] { --r: #5fc99a; }
|
||
.rollenwahl__knopf[data-rolle="creator"] { --r: #3fbdf5; }
|
||
|
||
.rollenwahl__knopf[data-an="ja"] {
|
||
color: #fff;
|
||
border-color: color-mix(in srgb, var(--r) 60%, transparent);
|
||
background:
|
||
linear-gradient(color-mix(in srgb, var(--r) 16%, #151d2a),
|
||
color-mix(in srgb, var(--r) 9%, #111925));
|
||
box-shadow: 0 4px 16px -10px var(--r);
|
||
}
|
||
|
||
.rollenwahl__symbol {
|
||
width: 22px; height: 22px; flex: none; margin-top: 1px;
|
||
fill: none; stroke: var(--r); stroke-width: 1.6;
|
||
stroke-linecap: round; stroke-linejoin: round;
|
||
}
|
||
.rollenwahl__text { display: grid; gap: 2px; min-width: 0; }
|
||
.rollenwahl__name { font-size: .92rem; font-weight: 650; }
|
||
.rollenwahl__erklaerung { font-size: .76rem; color: var(--text-still); line-height: 1.42; }
|
||
.rollenwahl__knopf[data-an="ja"] .rollenwahl__erklaerung { color: var(--text-leise); }
|
||
|
||
/* Rollenmarke in der Liste bekommt dieselben Farben. */
|
||
.marke-rolle[data-rolle="manager"] {
|
||
color: #b6a9ff; border-color: rgba(138, 118, 255, .42); background: rgba(138, 118, 255, .12);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) { .rollenwahl__knopf { transition: none; } }
|
||
|
||
/* Die Betreuungs-Auswahl bleibt ein Systemmenue -- bei wechselnd vielen
|
||
Scouts waere eine feste Schalterreihe unpraktisch. Sie bekommt aber
|
||
genug Breite, damit kein Name abgeschnitten wird. */
|
||
.betreuung__wahl { min-width: 190px; }
|
||
|
||
/* Die beiden Knöpfe oben rechts. Der Aufklapper steht LINKS vom
|
||
"Person anlegen" – die Hauptsache gehört ganz nach außen, sonst
|
||
springt der Blick beim Suchen daran vorbei. */
|
||
.kopf-knoepfe { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
||
|
||
/* Die Anzahl neben der Rollen-Überschrift. Sitzt zwischen Name und
|
||
Erklärung, damit sie zur Überschrift gehört und nicht zum Zusatztext. */
|
||
.gruppe__zahl {
|
||
min-width: 20px; padding: 1px 7px; text-align: center;
|
||
font-size: .72rem; font-weight: 700; color: var(--text-still);
|
||
background: rgba(255, 255, 255, .06); border-radius: 999px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* In der Personenliste liegen die Karten direkt untereinander; der
|
||
Abstand zur nächsten Rolle kommt von .gruppe selbst. */
|
||
.gruppe .person:last-child { margin-bottom: 0; }
|
||
|
||
/* Der Löschknopf. Ruhig wie die anderen, bis man ihn ansieht – dann
|
||
deutlich rot. Ein dauerhaft roter Knopf in jeder Zeile macht die
|
||
ganze Liste nervös; einer, der erst beim Überfahren rot wird, warnt
|
||
genau im richtigen Moment. */
|
||
.schritt[data-gefahr="ja"] { color: var(--text-still); }
|
||
.schritt[data-gefahr="ja"]:hover:not(:disabled) {
|
||
color: var(--warn);
|
||
border-color: rgba(255, 154, 162, .55);
|
||
background: rgba(255, 154, 162, .1);
|
||
}
|
||
.schritt[data-gefahr="ja"]:focus-visible { outline-color: var(--warn); }
|
||
|
||
/* Die Rollen-Überschrift ist der Klappknopf. Sie sieht aus wie eine
|
||
Überschrift und verhält sich wie ein Knopf – deshalb hier nur der
|
||
Knopf-Rücksetzer und ein Zeiger, kein eigener Entwurf. */
|
||
.gruppe__kopf--klappbar {
|
||
width: 100%; text-align: left; cursor: pointer;
|
||
font: inherit; color: inherit;
|
||
background: none; border: 0;
|
||
border-bottom: 1px solid transparent;
|
||
border-image: linear-gradient(90deg, var(--rand-hell), transparent 70%) 1;
|
||
transition: opacity var(--tempo);
|
||
}
|
||
.gruppe__kopf--klappbar:hover { opacity: .82; }
|
||
.gruppe__kopf--klappbar:focus-visible {
|
||
outline: 2px solid var(--akzent); outline-offset: 3px; border-radius: 4px;
|
||
}
|
||
/* Der Pfeil ganz nach rechts – dort sucht ihn die Hand. */
|
||
.gruppe__kopf--klappbar .klapp-pfeil { margin-left: auto; color: var(--text-still); }
|
||
.gruppe__kopf--klappbar:hover .klapp-pfeil { color: var(--akzent); }
|
||
|
||
/* Zugeklappt zählt nur eines: Steckt da etwas Gesperrtes drin, das man
|
||
sehen müsste? Dann fällt der Zusatztext auf. */
|
||
.gruppe__unter[data-warn="ja"] { color: var(--warn); }
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.gruppe__kopf--klappbar { transition: none; }
|
||
}
|
||
|
||
/* ---------- Die gewählte Rolle: ein Häkchen, nicht nur ein Farbton ------
|
||
Bisher unterschied die gewählte Karte nur ein etwas hellerer Rahmen
|
||
und ein Hauch Farbe. Das ist genau die Art Unterschied, die im
|
||
Kontrastmodus verschwindet, bei hellem Umgebungslicht untergeht und
|
||
für farbunsichere Augen gar nicht erst existiert. Ein Häkchen sagt
|
||
dasselbe, ohne dass man Farben vergleichen muss. */
|
||
.rollenwahl__knopf { position: relative; padding-right: 44px; }
|
||
.rollenwahl__knopf::after {
|
||
content: "";
|
||
position: absolute; top: 13px; right: 14px;
|
||
width: 19px; height: 19px; border-radius: 50%;
|
||
border: 1.5px solid color-mix(in srgb, var(--r) 40%, var(--rand));
|
||
transition: background .16s ease, border-color .16s ease;
|
||
}
|
||
.rollenwahl__knopf[data-an="ja"]::after {
|
||
content: "✓";
|
||
display: grid; place-items: center;
|
||
border-color: var(--r);
|
||
background: var(--r);
|
||
color: #0b1017;
|
||
font-size: .8rem; font-weight: 800; line-height: 1;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.rollenwahl__knopf, .rollenwahl__knopf::after { transition: none; }
|
||
}
|
||
@media (forced-colors: active) {
|
||
/* Ohne Farben trägt allein das Häkchen die Aussage. */
|
||
.rollenwahl__knopf[data-an="ja"] { border: 2px solid Highlight; }
|
||
.rollenwahl__knopf::after { border-color: CanvasText; }
|
||
.rollenwahl__knopf[data-an="ja"]::after { background: Highlight; color: HighlightText; }
|
||
}
|