Anleitung, Etappe 1: die Einweisung fuer Creator steht
Erste von sieben Etappen aus dem geprueften Bauplan
(`02 Projekte/Anleitung-Kachel – Bauplan.md`). Ein Creator oeffnet die
neue Kachel und sieht seine vollstaendige Einweisung: drei Saetze „In
60 Sekunden", fuenf Erste Schritte, achtzehn Karten in drei Stufen,
„Das kannst du liegen lassen", sein Rhythmus und vier Fragen.
WAS NICHT IN DER DATENBANK STEHT -- und das ist der Kern.
Eine Karte zeigt Name, Symbol, Farbe und Adresse ihrer echten Kachel.
Nichts davon ist gespeichert. Es steht in bereiche.js, genau einmal,
und wird ueber einen abgeleiteten Schluessel verbunden
(`bereich.html?b=live` -> `bereich:live`). Haette ich den Namen
danebengeschrieben, erklaerte die Anleitung nach der ersten Umbenennung
eine Kachel, die es so nicht mehr gibt -- und niemandem fiele es auf.
Gespeichert ist nur, was der Bauplan NEU bringt: die Stufe und die drei
Saetze Wozu / Was du hier tust / Merke.
Der Schluessel muss abgeleitet sein, weil zwei Faelle sonst
zusammenfallen: `bereich.html` ist FUENF Kacheln, und `profil.html`
heisst beim Creator „Mein Profil" und beim Manager „Creator-Profile".
DIE WICHTIGSTE PRUEFUNG STEHT NICHT IM BAUPLAN.
pruef-anleitung.mjs fragt in BEIDE Richtungen: Hat jede Kachel, die
diese Rolle sieht, genau eine Karte -- und zeigt jede Karte auf eine
Kachel, die es wirklich gibt? Beides kann lautlos kaputtgehen, und der
Bauplan sah dafuer nur einen Hinweis in der Pflege-Ansicht vor. Der
hilft nur, wenn jemand hinsieht.
Dafuer wird bereiche.js in der Pruefung AUSGEFUEHRT (node:vm mit einem
winzigen Browser-Ersatz), nicht mit einem Muster durchsucht. Ein Muster
waere eine ungenaue Nachbildung und wuerde bei der ersten ungewohnten
Schreibweise „alles in Ordnung" melden.
DREI BEFUNDE BEIM BAUEN, ALLE GEMESSEN STATT GEAHNT:
1. Ton 48. Das Hauswerkzeug schlug #b0ec0a vor -- Abstand 0,0815 zur
Kachel „Agentur", die ein Creator direkt daneben sieht, und 13,28:1
Kontrast. Der Grund: Es rechnet gegen alle 47 Toene, aber die Haelfte
gehoert zum anderen Haus und erscheint nie auf demselben Bildschirm.
Gegen die 24 Toene DIESES Hauses gerechnet: #ff7eed, Abstand 0,1168
(43 % mehr) bei sanfteren 8,46:1. Die Herleitung steht in start.css,
samt Warnung, dass ein erneuter Werkzeuglauf es verschlechtern wuerde.
2. Die Erste-Schritte-Verweise waren 20 px hoch. Gemessen bei 412 px --
die halbe Hausgroesse fuer einen Daumen, auf der Seite, die fuer
Leute gebaut ist, die zum ersten Mal hier sind und auf dem Handy
sitzen. Jetzt ist die ganze Zeile das Ziel, 44 px.
3. Die Textbloecke standen ohne Flaeche auf der Seite. Auf dem ersten
Bild lief „Fast alles andere fuellt deine Betreuung fuer dich" quer
ueber das helle Wasserzeichen des Hintergrundbildes. Deshalb hat im
Haus jeder Textträger `--flaeche`: Ein Kontrast, der vom
Bildausschnitt abhaengt, ist keiner.
NEBENBEI ZWEI LUECKEN GESCHLOSSEN: `manager-ziele.html` und
`anleitung.html` fehlten in der Seitenliste von pruef-rollen. Ganz
ungeprueft waren sie nicht -- der Kachel-Durchgang oeffnet jede Kachel
--, aber er prueft nur, WO man landet. Konsolenfehler, 4xx-Antworten,
tote Verweise und Ueberstehen liefen fuer beide nie. Dieselbe Sorte
stiller Luecke wie am 28.08.2026 bei RunOne.
ENTSCHEIDUNGEN VON FILIPE (06.10.2026):
Pflege durch DogFather UND Spicy (nicht nur DogFather wie im Bauplan)
-- dieselbe Regel wie bei den Manager-Zielen am 02.10.
Vorerst nur das Agenturhaus, die Daten aber haus-bewusst angelegt.
DogFather bekommt keine Kachel (er braucht keine Einweisung), darf die
Seite aber oeffnen: Ueber den vorhandenen Sicht-Umschalter sieht er
jede Fassung. Eine zweite Rollenauswahl auf der Seite waere dieselbe
Funktion an einer Stelle, an der sie niemand sucht.
Gemessen
pruef-anleitung 47 Pruefungen, 0 Fehler (neu)
pruef-rollen 401 Pruefungen, 0 Fehler (vorher 384)
pruef-rechtetafel 19 Pruefungen, 0 Fehler
pruef-css-klassen alles in Ordnung, jetzt 40 Seiten, 42 Stellen
unter 11,5 px (unveraendert)
mess-anleitung kein Querschieben bei 412 und 1440 px, keine
Konsolenfehler, alle 18 Karten mit Kachelfarbe
Sicherung vor dem Ausliefern:
~/sicherungen/workspace-vor-anleitung-20261006-1325.db (integrity ok)
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,474 @@
|
||||
/* =====================================================================
|
||||
anleitung.css — die Einweisung je Rolle (06.10.2026)
|
||||
=====================================================================
|
||||
|
||||
VIER REGELN, DIE HIER ÜBERALL GELTEN:
|
||||
|
||||
1. KEINE EIGENEN FARBEN. Jede Karte trägt den Ton ihrer echten
|
||||
Kachel (`data-ton`, gesetzt von anleitung.js). Eine eigene
|
||||
Farbwelt hier wäre eine zweite Wahrheit über dieselben Kacheln --
|
||||
und man würde die Anleitung nicht mehr mit der Startseite
|
||||
zusammenlesen können.
|
||||
|
||||
2. DIE STUFE IST EIN WORT. Sie steht an jeder Karte als Text, nicht
|
||||
nur als Farbe. Ein Mensch, der Farben schlecht unterscheidet,
|
||||
läse die Seite sonst ohne ihre einzige Ordnung.
|
||||
|
||||
3. MOBILE FIRST ALS REGEL, NICHT ALS ZAHL. Das Kartengitter bricht
|
||||
über `auto-fill` um, nicht über eine Schwelle in Pixeln. Eine
|
||||
feste Zahl ist eine Rechnung von gestern und wird beim nächsten
|
||||
zusätzlichen Element still falsch.
|
||||
|
||||
4. NICHTS UNTER 11,5 PIXELN. Hausregel seit dem 01.09.2026,
|
||||
nachgemessen von pruef-css-klassen. Kleinster Wert hier: .78rem.
|
||||
===================================================================== */
|
||||
|
||||
.an-seite {
|
||||
/* Der Abstand zwischen den großen Blöcken -- einmal gesetzt, überall
|
||||
benutzt. Drei verschiedene Abstände sind der Grund, warum eine
|
||||
Seite „unruhig" aussieht, ohne dass man sagen kann, woran es liegt. */
|
||||
--an-luft: 26px;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
OHNE EIGENE FASSUNG (DogFather)
|
||||
===================================================================== */
|
||||
.an-ohne {
|
||||
margin: 18px 0 0;
|
||||
padding: 16px 18px;
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
background: var(--flaeche);
|
||||
color: var(--text-still);
|
||||
font-size: .95rem;
|
||||
line-height: 1.6;
|
||||
max-width: 62ch;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
BLÖCKE
|
||||
=====================================================================
|
||||
|
||||
JEDER TEXTBLOCK BEKOMMT EINE FLÄCHE (06.10.2026, nach dem ersten Bild).
|
||||
|
||||
Der erste Entwurf setzte „In 60 Sekunden", „Erste Schritte",
|
||||
„Nicht deins" und „Dein Rhythmus" ohne Hintergrund auf die Seite.
|
||||
Auf dem Bild bei 412 px lief der Satz „Fast alles andere füllt deine
|
||||
Betreuung für dich" quer über das helle Wasserzeichen des
|
||||
Hintergrundbildes und war dort kaum zu lesen.
|
||||
|
||||
Das ist kein Schönheitsfehler, sondern der Grund, warum im Haus
|
||||
JEDER Textträger `--flaeche` hat (`rgba(9,13,22,.89)`, also fast
|
||||
deckend): Die Startseite hat ein Foto im Hintergrund, und wie hell
|
||||
es an einer bestimmten Stelle ist, weiß niemand vorher. Ein
|
||||
Kontrast, der vom Bildausschnitt abhängt, ist kein Kontrast.
|
||||
|
||||
Die Fase (`--fase`) statt eines Radius: dieselbe Form wie `.mz-kopf`
|
||||
und die übrigen großen Träger im Haus. */
|
||||
.an-block {
|
||||
margin-top: var(--an-luft);
|
||||
padding: 16px 18px;
|
||||
border: 1px solid var(--rand);
|
||||
background: var(--flaeche);
|
||||
clip-path: polygon(var(--fase, 18px) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase, 18px));
|
||||
}
|
||||
|
||||
.an-block__titel {
|
||||
margin: 0 0 10px;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: .01em;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.an-leit {
|
||||
margin: 0 0 12px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text);
|
||||
max-width: 68ch;
|
||||
}
|
||||
|
||||
.an-saetze { margin: 0; padding: 0; list-style: none; }
|
||||
|
||||
.an-saetze__zeile {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 7px;
|
||||
font-size: .95rem;
|
||||
line-height: 1.55;
|
||||
color: var(--text-leise);
|
||||
max-width: 68ch;
|
||||
}
|
||||
/* Ein Punkt statt eines Aufzählungszeichens: Die drei Sätze sind keine
|
||||
Liste von Dingen, sondern drei Aussagen. Der Punkt gliedert, ohne zu
|
||||
zählen. */
|
||||
.an-saetze__zeile::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 4px; top: .62em;
|
||||
width: 6px; height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--akzent);
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
ERSTE SCHRITTE
|
||||
===================================================================== */
|
||||
.an-schritte {
|
||||
margin: 0;
|
||||
padding: 0 0 0 1.35em;
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.an-schritt { max-width: 68ch; }
|
||||
|
||||
/* DIE GANZE ZEILE IST DAS ZIEL, nicht nur das Stichwort.
|
||||
Gemessen am 06.10.2026: Der Verweis war 20 px hoch -- die halbe
|
||||
Hausgröße für etwas, das ein Daumen treffen soll. 44 px ist die
|
||||
Zahl, die im Haus für Berührziele gilt, und sie steht hier als
|
||||
Mindesthöhe und nicht als feste: Zwei Zeilen Text dürfen wachsen. */
|
||||
.an-schritt__rumpf {
|
||||
display: block;
|
||||
min-height: 44px;
|
||||
padding: 8px 10px;
|
||||
margin-left: -10px;
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
font-size: .95rem;
|
||||
line-height: 1.55;
|
||||
color: var(--text-leise);
|
||||
text-decoration: none;
|
||||
transition: background var(--tempo, .18s);
|
||||
}
|
||||
a.an-schritt__rumpf:hover {
|
||||
background: color-mix(in srgb, var(--akzent) 10%, transparent);
|
||||
}
|
||||
a.an-schritt__rumpf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
|
||||
|
||||
.an-schritt__name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
margin-right: .4em;
|
||||
}
|
||||
a.an-schritt__rumpf .an-schritt__name { color: var(--akzent); }
|
||||
a.an-schritt__rumpf:hover .an-schritt__name { text-decoration: underline; }
|
||||
|
||||
/* =====================================================================
|
||||
DER STUFEN-FILTER
|
||||
===================================================================== */
|
||||
.an-filter {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: var(--an-luft);
|
||||
}
|
||||
|
||||
.an-filter__knopf {
|
||||
font: inherit;
|
||||
font-size: .85rem;
|
||||
font-weight: 650;
|
||||
/* 40 Pixel hoch: Die Hausgröße für etwas, das ein Daumen trifft. */
|
||||
min-height: 40px;
|
||||
padding: 0 15px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--rand);
|
||||
/* NICHT durchsichtig: Der Filter steht zwischen zwei Flaechen und
|
||||
damit direkt auf dem Hintergrundbild. Ein durchsichtiger Knopf ist
|
||||
genau so gut lesbar, wie der Bildausschnitt es zulaesst -- und das
|
||||
weiss niemand vorher. */
|
||||
background: var(--flaeche);
|
||||
color: var(--text-still);
|
||||
cursor: pointer;
|
||||
transition: background var(--tempo, .18s), color var(--tempo, .18s),
|
||||
border-color var(--tempo, .18s);
|
||||
}
|
||||
.an-filter__knopf:hover { border-color: var(--rand-hell, var(--rand)); color: var(--text); }
|
||||
.an-filter__knopf:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
|
||||
|
||||
/* DER GEWÄHLTE ZUSTAND HÄNGT AN `aria-pressed`, NICHT AN EINER KLASSE.
|
||||
Damit ist er für Vorleseprogramme und fürs Auge dieselbe Tatsache --
|
||||
eine Klasse daneben wäre die, die beim nächsten Umbau vergessen
|
||||
wird, und dann sagt der Knopf etwas anderes, als er aussieht. */
|
||||
.an-filter__knopf[aria-pressed="true"] {
|
||||
/* Auf die FLAECHE gemischt und nicht auf `transparent`: Sonst waere
|
||||
ausgerechnet der gewaehlte Knopf der durchsichtigste von allen. */
|
||||
background: color-mix(in srgb, var(--akzent) 22%, var(--flaeche));
|
||||
border-color: color-mix(in srgb, var(--akzent) 45%, transparent);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EIN STUFENBLOCK
|
||||
===================================================================== */
|
||||
.an-stufe { margin-top: var(--an-luft); }
|
||||
|
||||
.an-stufe__falte {
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
background: var(--flaeche);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.an-stufe__griff {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 14px 16px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
user-select: none;
|
||||
}
|
||||
.an-stufe__griff::-webkit-details-marker { display: none; }
|
||||
.an-stufe__griff:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
|
||||
|
||||
/* Das Dreieck selbst gebaut, weil das eingebaute je nach Browser
|
||||
woanders sitzt und sich nicht färben lässt. */
|
||||
.an-stufe__griff::before {
|
||||
content: "";
|
||||
flex: none;
|
||||
width: 8px; height: 8px;
|
||||
border-right: 2px solid var(--text-still);
|
||||
border-bottom: 2px solid var(--text-still);
|
||||
transform: rotate(-45deg);
|
||||
transition: transform var(--tempo, .18s);
|
||||
}
|
||||
.an-stufe__falte[open] > .an-stufe__griff::before { transform: rotate(45deg); }
|
||||
|
||||
.an-stufe__titel {
|
||||
flex: 1 1 auto;
|
||||
font-size: 1.02rem;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.an-stufe__zahl {
|
||||
flex: none;
|
||||
min-width: 26px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
background: color-mix(in srgb, var(--text-still) 16%, transparent);
|
||||
color: var(--text-still);
|
||||
font-size: .8rem;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.an-stufe__unter {
|
||||
margin: 0;
|
||||
padding: 0 16px 4px;
|
||||
font-size: .85rem;
|
||||
color: var(--text-still);
|
||||
}
|
||||
|
||||
/* DAS GITTER MISST, STATT ZU RECHNEN. `auto-fill` mit einer
|
||||
Mindestbreite bricht genau dann um, wenn der Platz nicht reicht --
|
||||
auf einem 320er Telefon einspaltig, auf einem breiten Bildschirm
|
||||
dreispaltig, ohne eine einzige Schwelle in Pixeln. */
|
||||
.an-stufe__gitter {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
|
||||
gap: 12px;
|
||||
padding: 12px 16px 16px;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EINE KARTE
|
||||
===================================================================== */
|
||||
.an-karte {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 14px;
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
background: var(--flaeche);
|
||||
/* Der Ton der echten Kachel, als schmaler Streifen links. Nicht als
|
||||
Fläche: Achtzehn volle Farbflächen untereinander sind ein
|
||||
Jahrmarkt, und augenschonend ist etwas anderes. */
|
||||
border-left: 3px solid var(--ton, var(--rand));
|
||||
}
|
||||
|
||||
.an-karte__kopf { display: flex; align-items: center; gap: 10px; }
|
||||
|
||||
.an-karte__zeichen {
|
||||
flex: none;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 38px; height: 38px;
|
||||
border-radius: 10px;
|
||||
background: color-mix(in srgb, var(--ton, var(--akzent)) 14%, transparent);
|
||||
}
|
||||
.an-karte__svg { width: 24px; height: 24px; }
|
||||
|
||||
.an-karte__namen {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 4px 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.an-karte__name {
|
||||
margin: 0;
|
||||
font-size: .98rem;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.an-karte__stufe {
|
||||
font-size: .78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: .05em;
|
||||
text-transform: uppercase;
|
||||
color: var(--ton, var(--text-still));
|
||||
}
|
||||
|
||||
.an-karte__zeilen { margin: 0; display: grid; gap: 2px; }
|
||||
|
||||
.an-karte__schild {
|
||||
font-size: .78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: .05em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-still);
|
||||
}
|
||||
.an-karte__text {
|
||||
margin: 0 0 6px;
|
||||
font-size: .9rem;
|
||||
line-height: 1.5;
|
||||
color: var(--text-leise);
|
||||
}
|
||||
.an-karte__text:last-child { margin-bottom: 0; }
|
||||
|
||||
.an-karte__weg {
|
||||
align-self: flex-start;
|
||||
margin-top: auto;
|
||||
/* 40 Pixel: dieselbe Daumenhöhe wie der Filter. */
|
||||
min-height: 40px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0 14px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid color-mix(in srgb, var(--ton, var(--akzent)) 40%, transparent);
|
||||
color: var(--ton, var(--akzent));
|
||||
font-size: .85rem;
|
||||
font-weight: 650;
|
||||
text-decoration: none;
|
||||
transition: background var(--tempo, .18s);
|
||||
}
|
||||
.an-karte__weg:hover { background: color-mix(in srgb, var(--ton, var(--akzent)) 14%, transparent); }
|
||||
.an-karte__weg:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
|
||||
|
||||
/* =====================================================================
|
||||
NICHT DEINS
|
||||
===================================================================== */
|
||||
.an-nicht { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
|
||||
|
||||
.an-nicht__zeile {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 2px 8px;
|
||||
padding: 10px 14px;
|
||||
border: 1px dashed var(--rand);
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
font-size: .92rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
/* Gestrichelt und nicht durchgestrichen: Durchgestrichener Text ist
|
||||
schlecht lesbar, und „nicht deins" heißt nicht „erledigt". */
|
||||
.an-nicht__was { font-weight: 650; color: var(--text-still); }
|
||||
.an-nicht__wer { color: var(--text-leise); }
|
||||
|
||||
/* =====================================================================
|
||||
RHYTHMUS
|
||||
===================================================================== */
|
||||
.an-takt {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
/* Erste Spalte so breit wie ihr längster Eintrag, nicht breiter --
|
||||
„Vor und nach dem LIVE" soll nicht umbrechen, und „Täglich" soll
|
||||
keine halbe Zeile Leerraum erzeugen. */
|
||||
grid-template-columns: max-content 1fr;
|
||||
gap: 6px 16px;
|
||||
align-items: baseline;
|
||||
}
|
||||
.an-takt__wann {
|
||||
font-size: .85rem;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.an-takt__was {
|
||||
margin: 0;
|
||||
font-size: .92rem;
|
||||
line-height: 1.5;
|
||||
color: var(--text-leise);
|
||||
}
|
||||
/* Auf schmalen Geräten untereinander: Zwei Spalten mit „Vor und nach
|
||||
dem LIVE" links lassen rechts vier Wörter übrig. Die Regel misst
|
||||
nicht, deshalb hier doch eine Schwelle -- und sie steht direkt an
|
||||
dem, was sie betrifft. */
|
||||
@media (max-width: 460px) {
|
||||
.an-takt { grid-template-columns: 1fr; gap: 2px; }
|
||||
.an-takt__was { margin-bottom: 8px; }
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
FRAGEN
|
||||
===================================================================== */
|
||||
.an-fragen { display: grid; gap: 8px; }
|
||||
|
||||
.an-frage {
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein, 12px);
|
||||
background: var(--flaeche);
|
||||
overflow: hidden;
|
||||
}
|
||||
.an-frage__frage {
|
||||
padding: 12px 14px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
font-size: .94rem;
|
||||
font-weight: 650;
|
||||
color: var(--text);
|
||||
}
|
||||
.an-frage__frage::-webkit-details-marker { display: none; }
|
||||
.an-frage__frage:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }
|
||||
.an-frage__antwort {
|
||||
margin: 0;
|
||||
padding: 0 14px 13px;
|
||||
font-size: .92rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text-leise);
|
||||
max-width: 68ch;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
HILFE
|
||||
===================================================================== */
|
||||
.an-hilfe {
|
||||
margin: var(--an-luft) 0 0;
|
||||
/* Dieselbe Flaeche wie die Bloecke darueber, aus demselben Grund --
|
||||
nur leiser: kein Titel, kleinere Schrift. Ein Schlusssatz soll
|
||||
lesbar sein, ohne sich wie ein weiterer Abschnitt aufzufuehren. */
|
||||
padding: 14px 18px;
|
||||
border: 1px solid var(--rand);
|
||||
background: var(--flaeche);
|
||||
clip-path: polygon(var(--fase, 18px) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase, 18px));
|
||||
font-size: .9rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text-still);
|
||||
}
|
||||
.an-hilfe a { color: var(--akzent); }
|
||||
|
||||
/* =====================================================================
|
||||
WENIGER BEWEGUNG, WENN JEMAND DAS SO EINGESTELLT HAT
|
||||
===================================================================== */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.an-filter__knopf,
|
||||
.an-schritt__rumpf,
|
||||
.an-stufe__griff::before,
|
||||
.an-karte__weg { transition: none; }
|
||||
}
|
||||
@@ -1198,6 +1198,52 @@ body.start > main { position: relative; z-index: 1; }
|
||||
maximiert DANN den Abstand. Wer den 48. hinzufuegt, sollte wissen,
|
||||
dass es eng wird, und notfalls einen alten verschieben. */
|
||||
[data-ton="47"] { --ton: #7368ff; } /* Manager-Ziele (gerechnet 02.10.2026) */
|
||||
/* ======================================================================
|
||||
TON 48 -- UND WARUM ER NICHT VOM HAUSWERKZEUG STAMMT (06.10.2026)
|
||||
|
||||
Der Kommentar bei Ton 47 sagt: "Wer den 48. hinzufuegt, sollte wissen,
|
||||
dass es eng wird, und notfalls einen alten verschieben." Genau das ist
|
||||
eingetreten, und die Loesung war eine dritte.
|
||||
|
||||
`node tools/kachel-farbe-einzeln.mjs 48` schlug #b0ec0a vor:
|
||||
Abstand zum naechsten Ton ueberhaupt 0,0793
|
||||
davon zur naechsten AGENTUR-Kachel 0,0815 (Ton 17, "Agentur")
|
||||
Kontrast 13,28:1, Buntheit 0,220
|
||||
|
||||
Beides war unbefriedigend. 0,0815 waere der engste Abstand im Haus
|
||||
gewesen, und der Nachbar waere ausgerechnet eine Kachel, die ein
|
||||
Creator direkt daneben sieht -- zwei Gelbgruen nebeneinander. Dazu
|
||||
13,28:1 auf dunklem Grund: Von 47 Toenen sind nur zwei heller.
|
||||
|
||||
WAS DAS WERKZEUG NICHT WEISS: Es rechnet gegen ALLE 47 Toene. Die
|
||||
Haelfte davon gehoert aber zum anderen Haus (Team Dogi) und erscheint
|
||||
nie auf demselben Bildschirm. Es optimiert damit gegen Nachbarn, die
|
||||
es gar nicht gibt, und verschenkt dabei den Platz, der zwischen den
|
||||
Kacheln liegt, die man WIRKLICH zusammen sieht.
|
||||
|
||||
Nachgerechnet gegen die 24 Toene des Agenturhauses, mit einer
|
||||
Obergrenze beim Kontrast (11:1, damit nichts blendet) und der
|
||||
Buntheits-Untergrenze, die im Haus tatsaechlich vorkommt (0,125 --
|
||||
darunter liegt nur Ton 44):
|
||||
|
||||
#ff7eed
|
||||
Abstand zur naechsten AGENTUR-Kachel 0,1168 (Ton 6) -- 43 % mehr
|
||||
Abstand zur naechsten Crew-Kachel 0,0656
|
||||
Kontrast 8,46:1 (Hausmedian 6,95)
|
||||
Buntheit 0,202
|
||||
|
||||
Der Abstand zum anderen Haus ist kleiner, und das ist der bewusste
|
||||
Tausch: Dort sitzt niemand, der beide zugleich sieht. Innerhalb des
|
||||
Agenturhauses ist dieser Ton weiter von allem entfernt als jedes Paar,
|
||||
das heute schon im Haus steht (engstes Paar: 0,0899).
|
||||
|
||||
ACHTUNG BEIM NAECHSTEN MAL: `kachel-farbe-einzeln.mjs 48 --schreiben`
|
||||
wuerde diesen Wert durch #b0ec0a ERSETZEN. Das Werkzeug kennt die
|
||||
Haeuser nicht. Wer es laufen laesst, macht den Ton schlechter, ohne
|
||||
es zu merken -- entweder das Werkzeug haus-bewusst nachruesten oder
|
||||
Ton 48 auslassen.
|
||||
====================================================================== */
|
||||
[data-ton="48"] { --ton: #ff7eed; } /* Anleitung (gerechnet 06.10.2026, siehe oben) */
|
||||
/* WARUM ES KEINEN TON 46 GIBT (25.09.2026)
|
||||
|
||||
Die Tuer ins andere Haus trug bis heute Ton 40 -- dieselbe Nummer
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/* =====================================================================
|
||||
anleitung.js — die Einweisung je Rolle (Etappe 1)
|
||||
|
||||
---------------------------------------------------------------------
|
||||
DIE KARTEN ENTSTEHEN AUS ZWEI QUELLEN, UND DAS IST DER PUNKT
|
||||
|
||||
Der Server liefert je Kachel die STUFE und drei Sätze. Name, Symbol,
|
||||
Farbe und Adresse kommen aus `window.Bereiche` — derselben Liste, aus
|
||||
der die Startseite ihre Kacheln baut.
|
||||
|
||||
Deshalb sieht eine Karte hier aus wie die echte Kachel, und zwar
|
||||
dauerhaft: Wird eine Kachel umbenannt oder bekommt sie eine andere
|
||||
Farbe, ändert sich die Karte mit. Stünde der Name in der Datenbank,
|
||||
wäre die Anleitung ab diesem Tag eine Beschreibung von etwas, das es
|
||||
nicht mehr gibt — und niemandem würde es auffallen.
|
||||
|
||||
Verbunden wird über `Bereiche.schluesselVonZiel`.
|
||||
===================================================================== */
|
||||
(() => {
|
||||
'use strict';
|
||||
|
||||
const BASIS = '/workspace/api/anleitung';
|
||||
|
||||
const el = (tag, klasse, text) => {
|
||||
const k = document.createElement(tag);
|
||||
if (klasse) k.className = klasse;
|
||||
if (text !== undefined) k.textContent = text;
|
||||
return k;
|
||||
};
|
||||
const $ = (id) => document.getElementById(id);
|
||||
|
||||
async function hole(pfad, einst = {}) {
|
||||
const a = await fetch(pfad, { credentials: 'same-origin', ...einst });
|
||||
/* Abgemeldet heißt zurück zur Anmeldung — nicht eine leere Seite
|
||||
mit einer Fehlermeldung, die niemand einordnen kann. */
|
||||
if (a.status === 401) { location.assign('/workspace/'); throw new Error('abgemeldet'); }
|
||||
return a;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
DIE KACHELN DIESER ROLLE — abgeleitet, nicht abgeschrieben
|
||||
===================================================================== */
|
||||
function kachelnFuer(rolle) {
|
||||
const B = window.Bereiche;
|
||||
const nach = new Map();
|
||||
if (!B || !Array.isArray(B.GRUPPEN)) return nach;
|
||||
for (const gruppe of B.GRUPPEN) {
|
||||
for (const k of (gruppe.bereiche || [])) {
|
||||
if (Array.isArray(k.rollen) && !k.rollen.includes(rolle)) continue;
|
||||
const schluessel = B.schluesselVonZiel(k.ziel);
|
||||
if (schluessel) nach.set(schluessel, k);
|
||||
}
|
||||
}
|
||||
return nach;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EINE KARTE
|
||||
===================================================================== */
|
||||
function karteBauen(eintrag, kachel, stufe) {
|
||||
const karte = el('article', 'an-karte');
|
||||
if (kachel.ton !== undefined && kachel.ton !== null) {
|
||||
karte.dataset.ton = String(kachel.ton);
|
||||
}
|
||||
|
||||
const kopf = el('div', 'an-karte__kopf');
|
||||
const zeichen = el('span', 'an-karte__zeichen');
|
||||
zeichen.append(window.Bereiche.zeichenBauen(kachel.zeichen, 'an-karte__svg'));
|
||||
kopf.append(zeichen);
|
||||
|
||||
const namen = el('div', 'an-karte__namen');
|
||||
namen.append(el('h3', 'an-karte__name', kachel.name));
|
||||
/* DIE STUFE STEHT ALS WORT DA, nicht nur als Farbe. Wer Farben
|
||||
schlecht unterscheidet, läse sonst eine Karte ohne Stufe — und
|
||||
die Stufe ist das Einzige, was diese Seite überhaupt sortiert. */
|
||||
namen.append(el('span', 'an-karte__stufe', stufe.name));
|
||||
kopf.append(namen);
|
||||
karte.append(kopf);
|
||||
|
||||
const zeilen = el('dl', 'an-karte__zeilen');
|
||||
const zeile = (schild, text) => {
|
||||
if (!text) return;
|
||||
zeilen.append(el('dt', 'an-karte__schild', schild));
|
||||
zeilen.append(el('dd', 'an-karte__text', text));
|
||||
};
|
||||
zeile('Wozu', eintrag.wozu);
|
||||
zeile('Was du hier tust', eintrag.tust);
|
||||
zeile('Merke', eintrag.merke);
|
||||
karte.append(zeilen);
|
||||
|
||||
const weg = el('a', 'an-karte__weg', 'Zur Kachel');
|
||||
/* MIT dem Zusatz hinter dem Fragezeichen. `bereich.html?b=live` und
|
||||
`bereich.html?b=technik` sind dieselbe Seite und verschiedene
|
||||
Kacheln; ohne den Zusatz landeten fünf Karten am selben Ort. */
|
||||
weg.href = kachel.ziel;
|
||||
karte.append(weg);
|
||||
return karte;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EIN STUFENBLOCK — aufklappbar, Muss offen
|
||||
===================================================================== */
|
||||
function stufeBauen(stufe, eintraege, kacheln) {
|
||||
const block = el('section', 'an-stufe');
|
||||
block.dataset.stufe = stufe.schluessel;
|
||||
|
||||
/* <details> und kein nachgebautes Aufklappen: Es bringt Tastatur,
|
||||
Vorlesen und die Suche des Browsers mit. Jeder Nachbau vergisst
|
||||
davon mindestens eines. */
|
||||
const falte = el('details', 'an-stufe__falte');
|
||||
falte.open = !!stufe.offen;
|
||||
const griff = el('summary', 'an-stufe__griff');
|
||||
griff.append(el('span', 'an-stufe__titel', stufe.titel));
|
||||
griff.append(el('span', 'an-stufe__zahl', String(eintraege.length)));
|
||||
falte.append(griff);
|
||||
|
||||
if (stufe.unter) falte.append(el('p', 'an-stufe__unter', stufe.unter));
|
||||
|
||||
const gitter = el('div', 'an-stufe__gitter');
|
||||
let gebaut = 0;
|
||||
for (const e of eintraege) {
|
||||
const kachel = kacheln.get(e.kachel);
|
||||
/* EINE KARTE OHNE KACHEL WIRD NICHT GEZEIGT.
|
||||
Sie hätte keinen Namen, kein Symbol und keinen Weg — ein
|
||||
Kasten, der nichts tut. Dass das überhaupt nicht vorkommen
|
||||
darf, prüft pruef-anleitung.mjs in beide Richtungen; hier
|
||||
still zu übergehen ist die richtige Vorsicht, nicht die
|
||||
Prüfung. */
|
||||
if (!kachel) continue;
|
||||
gitter.append(karteBauen(e, kachel, stufe));
|
||||
gebaut++;
|
||||
}
|
||||
/* Die Zahl am Griff muss das zeigen, was wirklich dasteht. */
|
||||
griff.lastChild.textContent = String(gebaut);
|
||||
if (!gebaut) return null;
|
||||
|
||||
falte.append(gitter);
|
||||
block.append(falte);
|
||||
return block;
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
DER FILTER
|
||||
===================================================================== */
|
||||
function filterBauen(stufen, auswahl) {
|
||||
const leiste = $('filter');
|
||||
leiste.replaceChildren();
|
||||
const machen = (wert, text) => {
|
||||
const knopf = el('button', 'an-filter__knopf', text);
|
||||
knopf.type = 'button';
|
||||
knopf.dataset.wert = wert;
|
||||
knopf.setAttribute('aria-pressed', String(auswahl === wert));
|
||||
knopf.addEventListener('click', () => setzen(wert));
|
||||
leiste.append(knopf);
|
||||
};
|
||||
machen('alle', 'Alles');
|
||||
for (const s of stufen) machen(s.schluessel, s.name);
|
||||
|
||||
function setzen(wert) {
|
||||
for (const k of leiste.querySelectorAll('.an-filter__knopf')) {
|
||||
k.setAttribute('aria-pressed', String(k.dataset.wert === wert));
|
||||
}
|
||||
for (const b of $('stufen').querySelectorAll('.an-stufe')) {
|
||||
const dran = wert === 'alle' || b.dataset.stufe === wert;
|
||||
b.hidden = !dran;
|
||||
/* EINE GEFILTERTE STUFE WIRD AUFGEKLAPPT. Wer auf „Muss"
|
||||
drückt und dann einen zugeklappten Kasten sieht, hat einen
|
||||
Knopf gedrückt, der scheinbar nichts getan hat. */
|
||||
if (dran && wert !== 'alle') {
|
||||
const f = b.querySelector('.an-stufe__falte');
|
||||
if (f) f.open = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
AUFBAUEN
|
||||
===================================================================== */
|
||||
function zeigen(d) {
|
||||
$('ohne-fassung').hidden = true;
|
||||
$('fassung').hidden = false;
|
||||
|
||||
$('leitgedanke').textContent = d.leitgedanke || '';
|
||||
$('leitgedanke').hidden = !d.leitgedanke;
|
||||
|
||||
$('saetze').replaceChildren(
|
||||
...(d.saetze || []).map((t) => el('li', 'an-saetze__zeile', t)));
|
||||
|
||||
/* ==================================================================
|
||||
DIE GANZE ZEILE IST DER KNOPF, NICHT NUR DAS WORT (06.10.2026)
|
||||
|
||||
Zuerst war nur der Name verlinkt. Gemessen mit
|
||||
mess-anleitung.mjs bei 412 px: 20 Pixel hoch — die halbe
|
||||
Hausgröße für etwas, das ein Daumen treffen soll, und das
|
||||
ausgerechnet auf der Seite, die für Leute gebaut ist, die zum
|
||||
ersten Mal hier sind und auf dem Handy sitzen.
|
||||
|
||||
Jetzt umschließt der Verweis Name UND Text. Das ist auch die
|
||||
ehrlichere Form: Der ganze Schritt ist eine Sache, nicht ein
|
||||
Stichwort mit Erklärung daneben.
|
||||
|
||||
Ohne Ziel bleibt es ein `div` — „Installieren“ ist ein Knopf in
|
||||
der Kopfleiste, keine Seite. Ein Verweis ohne Ziel wäre genau
|
||||
der tote Knopf, den der Rollen-Rundgang sucht.
|
||||
================================================================== */
|
||||
$('schritte').replaceChildren(
|
||||
...(d.schritte || []).map((s) => {
|
||||
const li = el('li', 'an-schritt');
|
||||
const rumpf = s.ziel ? el('a', 'an-schritt__rumpf') : el('div', 'an-schritt__rumpf');
|
||||
if (s.ziel) rumpf.href = s.ziel;
|
||||
rumpf.append(el('span', 'an-schritt__name', s.titel));
|
||||
rumpf.append(el('span', 'an-schritt__text', s.text));
|
||||
li.append(rumpf);
|
||||
return li;
|
||||
}));
|
||||
|
||||
const kacheln = kachelnFuer(d.rolle);
|
||||
const stufen = $('stufen');
|
||||
stufen.replaceChildren();
|
||||
for (const s of (d.stufen || [])) {
|
||||
const eintraege = (d.karten || []).filter((k) => k.stufe === s.schluessel);
|
||||
const block = stufeBauen(s, eintraege, kacheln);
|
||||
if (block) stufen.append(block);
|
||||
}
|
||||
filterBauen(d.stufen || [], 'alle');
|
||||
|
||||
const liste = (id, blockId, zeilen, bau) => {
|
||||
const ziel = $(id);
|
||||
ziel.replaceChildren(...zeilen.map(bau));
|
||||
$(blockId).hidden = !zeilen.length;
|
||||
};
|
||||
liste('nicht', 'nicht-block', d.nicht || [], (z) => {
|
||||
const li = el('li', 'an-nicht__zeile');
|
||||
li.append(el('span', 'an-nicht__was', z.titel));
|
||||
li.append(el('span', 'an-nicht__wer', z.text));
|
||||
return li;
|
||||
});
|
||||
liste('takt', 'takt-block', d.takt || [], (z) => {
|
||||
const teil = document.createDocumentFragment();
|
||||
teil.append(el('dt', 'an-takt__wann', z.titel));
|
||||
teil.append(el('dd', 'an-takt__was', z.text));
|
||||
return teil;
|
||||
});
|
||||
liste('fragen', 'fragen-block', d.fragen || [], (z) => {
|
||||
const falte = el('details', 'an-frage');
|
||||
falte.append(el('summary', 'an-frage__frage', z.titel));
|
||||
falte.append(el('p', 'an-frage__antwort', z.text));
|
||||
return falte;
|
||||
});
|
||||
}
|
||||
|
||||
function ohneFassung(d) {
|
||||
$('fassung').hidden = true;
|
||||
const p = $('ohne-fassung');
|
||||
p.textContent = d.satz || 'Für diese Rolle gibt es keine Einweisung.';
|
||||
p.hidden = false;
|
||||
}
|
||||
|
||||
function melde(grund) {
|
||||
$('ladefehler-grund').textContent = grund || '';
|
||||
$('ladefehler').hidden = false;
|
||||
}
|
||||
|
||||
async function laden() {
|
||||
$('ladefehler').hidden = true;
|
||||
let a;
|
||||
try { a = await hole(BASIS); } catch { melde('Keine Verbindung.'); return; }
|
||||
if (a.status === 404) {
|
||||
melde('Diese Seite gibt es auf dieser Adresse nicht.');
|
||||
return;
|
||||
}
|
||||
if (!a.ok) { melde('Der Server hat nicht geantwortet.'); return; }
|
||||
const d = await a.json();
|
||||
if (!d.hat_fassung) { ohneFassung(d); return; }
|
||||
zeigen(d);
|
||||
}
|
||||
|
||||
$('nochmal').addEventListener('click', () => { laden().catch(() => {}); });
|
||||
laden().catch(() => melde('Unerwarteter Fehler.'));
|
||||
})();
|
||||
@@ -123,6 +123,16 @@
|
||||
'M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'
|
||||
],
|
||||
/* WEGWEISER, KEIN BUCH (06.10.2026). Die Anleitung steht direkt
|
||||
neben der Wissens-Bibliothek, und die ist schon ein Buch. Ein
|
||||
zweites daneben waere dieselbe Aussage zweimal -- und die
|
||||
Anleitung sagt etwas anderes: nicht "hier steht alles", sondern
|
||||
"da lang, das andere kannst du liegen lassen". Zwei Schilder in
|
||||
verschiedene Richtungen sind genau das. */
|
||||
anleitung: [
|
||||
'M4.5 5.5h12l2.5 2-2.5 2h-12z',
|
||||
'M19.5 12h-12L5 14l2.5 2h12z'
|
||||
],
|
||||
automation: [
|
||||
'M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'
|
||||
],
|
||||
@@ -299,6 +309,17 @@
|
||||
linien: ['M4 5h6.4c.9 0 1.6.7 1.6 1.6V19c0-.9-.7-1.6-1.6-1.6H4z',
|
||||
'M20 5h-6.4c-.9 0-1.6.7-1.6 1.6V19c0-.9.7-1.6 1.6-1.6H20z'],
|
||||
},
|
||||
anleitung: {
|
||||
/* Der Pfosten steht in den Linien und NICHT im Koerper: Die drei
|
||||
versetzten Tiefenlagen machen aus einer Flaeche eine Seitenwand
|
||||
-- bei einem 1,5 Punkt breiten Pfosten waere daraus ein Klumpen
|
||||
geworden. Die Schilder tragen die Tiefe, der Pfosten nur den
|
||||
Strich. */
|
||||
fuellung: ['M4.5 5.5h12l2.5 2-2.5 2h-12z'],
|
||||
linien: ['M12 4.5V20',
|
||||
'M4.5 5.5h12l2.5 2-2.5 2h-12z',
|
||||
'M19.5 12h-12L5 14l2.5 2h12z'],
|
||||
},
|
||||
automation: {
|
||||
fuellung: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||||
linien: ['M13.2 3.2 6 13.4h5.2l-.8 7.4 7.6-10.6h-5.2z'],
|
||||
@@ -670,6 +691,31 @@
|
||||
nameCreator: 'Wissen',
|
||||
unterCreator: 'Nachschlagen, wenn du etwas brauchst',
|
||||
bereiche: [
|
||||
/* ============================================================
|
||||
DIE ANLEITUNG STEHT GANZ VORN (06.10.2026)
|
||||
|
||||
Sie ist die einzige Kachel dieser Gruppe, die fuer JEDE der
|
||||
vier Rollen "Muss" ist -- und die einzige, die man braucht,
|
||||
bevor man die anderen versteht. Haette sie ihren Platz nach
|
||||
dem Alphabet oder nach Alter, stuende die Einweisung hinter
|
||||
den Dingen, in die sie einweisen soll.
|
||||
|
||||
Fuer einen Creator heisst die Gruppe "Wissen" (siehe
|
||||
nameCreator darueber); dort steht sie damit vor der
|
||||
Wissens-Bibliothek, so wie es der Bauplan verlangt.
|
||||
|
||||
OHNE 'admin'. DogFather bekommt keine Einweisung -- bei ihm
|
||||
oeffnet dieselbe Adresse spaeter die Pflege-Ansicht
|
||||
(Etappe 4). Bis die steht, hat er die Kachel nicht: Eine
|
||||
Kachel, die auf eine Seite fuehrt, die es fuer ihn noch
|
||||
nicht gibt, ist ein Knopf, der nichts tut.
|
||||
|
||||
Ton 48 gerechnet am 06.10.2026 gegen die 24 Toene DIESES
|
||||
Hauses -- die Herleitung steht in start.css bei [data-ton="48"]. */
|
||||
{ name: 'Anleitung', unter: 'Was du brauchst und was nicht',
|
||||
zeichen: 'anleitung', ton: 48,
|
||||
rollen: ['spicy', 'manager', 'scout', 'creator'],
|
||||
ziel: 'anleitung.html', szene: 'halle' },
|
||||
/* NUR DogFather (02.09.2026, Wunsch: "die manager sollen diese
|
||||
kategorien garnicht sehen").
|
||||
|
||||
@@ -1240,8 +1286,42 @@
|
||||
return [...nach].map(([titel, leute]) => ({ titel, rolle: leute[0].rolle, leute }));
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
DER KACHEL-SCHLUESSEL (06.10.2026, fuer die Anleitung)
|
||||
|
||||
Die Anleitung speichert je Rolle und Kachel drei Saetze. Verbunden
|
||||
wird ueber diesen Schluessel, und er wird ABGELEITET statt
|
||||
vergeben:
|
||||
|
||||
uebersicht.html -> uebersicht
|
||||
bereich.html?b=live -> bereich:live
|
||||
|
||||
Zwei Faelle zwingen dazu. `bereich.html` ist FUENF Kacheln (live,
|
||||
community, technik, schutz, agentur) -- ueber die Seite allein
|
||||
waeren sie eine, und fuenf Karten landeten uebereinander. Und
|
||||
`profil.html` heisst beim Creator "Mein Profil" und beim Manager
|
||||
"Creator-Profile"; die trennt die Rolle, nicht die Adresse.
|
||||
|
||||
NUR `b=` zaehlt. Ein Parameter, der nur an eine Stelle derselben
|
||||
Seite springt, unterscheidet keine Kachel.
|
||||
|
||||
Sie steht HIER und nicht im Server: Die Kachelliste liegt in
|
||||
dieser Datei, der Server kennt sie nicht (bereicheFuer gibt fuers
|
||||
Agenturhaus `null` zurueck -- "nimm die Liste aus dem Browser").
|
||||
Eine zweite Fassung dort haette nichts zu rechnen gehabt. */
|
||||
function schluesselVonZiel(ziel) {
|
||||
const roh = String(ziel || '').trim();
|
||||
if (!roh) return '';
|
||||
const teile = roh.split('?');
|
||||
const name = teile[0].replace(/\.html$/i, '');
|
||||
if (!teile[1]) return name;
|
||||
const b = new URLSearchParams(teile[1]).get('b');
|
||||
return b ? name + ':' + b : name;
|
||||
}
|
||||
|
||||
window.Bereiche = {
|
||||
ZEICHEN, GRUPPEN, zuSeite, zeichenBauen, merkzeichenBauen,
|
||||
LEITUNG, ROLLENFOLGE, ROLLEN_NAME, ROLLEN_GRUPPE, gruppieren,
|
||||
schluesselVonZiel,
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user