DIE PERSONENTABELLE WURDE NEU GEBAUT. Eine Rolle ist ein erlaubter Wert in einer Spalte, und der steckt in einem CHECK -- den kann SQLite nicht aendern. Auf `personen` zeigen ZWEIUNDFUENFZIG Fremdschluessel. Deshalb wird der Bauplan NICHT abgeschrieben, sondern gelesen: Der CREATE-Text kommt aus sqlite_master, darin wird ausschliesslich die Rollenliste ersetzt, und die Kopierliste kommt aus PRAGMA table_info. Die beiden aelteren Umstellungen schreiben ihre Spalten von Hand ab -- `personen` hat seit damals SIEBEN dazubekommen (bild, ueber_mich, tiktok ...). Wer hier abschreibt, verliert alle Profilbilder. ZWEI FRAGEN, DIE MAN AUSEINANDERHALTEN MUSS: siehtAlles() = DogFather ODER Spicy Media -> Listen, Uebersichten istDogFather() = nur DogFather -> loeschen, Rollen, Codes Es waere weniger Arbeit gewesen, istDogFather() um "spicy" zu erweitern -- und genau das waere der Fehler: Spicy Media koennte dann DogFather loeschen. DER CHAT BRAUCHTE NICHTS. Er haengt allein an der Teilnehmerliste und kennt kein "das Management sieht alles". Spicy Media sieht fremde Gespraeche nicht, weil es dafuer keinen Weg gibt -- nicht, weil eine Abfrage es verbietet. DREI ECHTE FEHLER, alle von pruef-spicy gefunden, keiner vorher sichtbar: 1. MEIN EIGENER KOMMENTAR STAND IM BAUPLAN. SQLite hebt den CREATE-Text woertlich auf, samt Kommentaren. Ich hatte "'spicy' steht HIER mit drin" hineingeschrieben -- und die Erkennung suchte genau dieses Wort im ganzen Text. Ergebnis: Die Umstellung hielt die Tabelle fuer erledigt, obwohl die CHECK-Regel noch die alte war. Jetzt wird die Regel herausgeschnitten und NUR darin gesucht; der Kommentar steht ausserhalb des SQL. 2. DER SICHERUNGSNAME HATTE NUR MINUTEN. `VACUUM INTO` weigert sich, eine vorhandene Datei zu ueberschreiben -- zu Recht. Zwei Umstellungen in derselben Minute wollten in dieselbe Datei, die zweite scheiterte, und weil ohne Sicherung nicht umgestellt wird, blieb sie aus. Es sah nach "lief" aus (die Datei lag ja da) und war keine. Jetzt mit Sekunden. 3. EINE FRISCHE DATENBANK LEGTE DIE ALTE ROLLENLISTE AN und stellte beim allerersten Start sofort um -- Tabelle neu bauen, Sicherung schreiben, fuer nichts. Ein Bauplan, der sofort umgebaut werden muss, ist der falsche. Und ein vierter in der Pruefung selbst: Der Chat-Aufbau benutzte einen falschen Weg, das Gespraech entstand gar nicht -- "Spicy Media sieht 0 Gespraeche" war trotzdem gruen, weil es keine gab. Jetzt ist das Anlegen selbst eine Pruefung, und eine Gegenprobe zeigt, dass Max es sehr wohl sieht. DAZU: Manager sehen die Kachel "Personen & Zugaenge" -- die SEITE geht auf, die Schnittstellen nicht. Alles unter /verwaltung haengt weiter an `nurAdmin` und antwortet 404; sie sehen genau den Teil, fuer den es einen Weg gibt. Spicy Media legt Creator UND Manager an (zweite enge Tuer, Rolle steht auch dort nicht im Aufruf; ein Manager kommt durch sie nicht). Der Rollentext des Managers stimmte nicht mehr -- er legt jetzt Creator an. pruef-spicy: 36 Pruefungen, alle gruen. Ausserdem gruen: personen-liste (33), creator-anlegen (29), sicht (48), css-klassen (15), alle-wege (19), haerte (20), manager-sicht (43). Co-Authored-By: Claude Opus 5 <[email protected]>
320 lines
13 KiB
CSS
320 lines
13 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; }
|
||
}
|
||
|
||
/* =====================================================================
|
||
ZWEI AUSBAUSTUFEN DERSELBEN SEITE (07.09.2026)
|
||
|
||
DogFather sieht diese Seite wie bisher. Manager und Spicy Media sehen
|
||
nur das Anlegen -- alles andere hier haengt am Server an `nurAdmin`
|
||
und antwortet ihnen mit 404.
|
||
|
||
DAS AUSBLENDEN IST NICHT DIE SICHERUNG, sondern die Zusage, dass
|
||
niemand vor leeren Kaesten sitzt, die sich nie fuellen. Der Schutz
|
||
steht in den Schnittstellen; wuerde diese Regel fehlen, saehen sie
|
||
Ladefehler, aber keine Daten.
|
||
===================================================================== */
|
||
body[data-nur-anlegen="ja"] #liste,
|
||
body[data-nur-anlegen="ja"] .protokoll-block,
|
||
body[data-nur-anlegen="ja"] #rest-schalter { display: none; }
|