diff --git a/.gitignore b/.gitignore index 6553ee2e..f77cabf6 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,18 @@ server/abnahme-*.png # Messlaeufe von tools/mess-rueckgabewerte.sh -- Ergebnis eines Laufs, # kein Quelltext. Gehoert nicht in die Geschichte. rueckgabewerte-*.txt + +# --------------------------------------------------------------------- +# WEGWERF-MESSDATEIEN (09.09.2026) +# +# Beim Pruefen schreibe ich Bildschirmfotos und kleine Messkripte ins +# Arbeitsverzeichnis und loesche sie danach. Einmal ist eines davon +# (`ruf.png`) trotzdem im Repo gelandet und bis auf den Server +# gewandert -- `git add -A` nimmt alles mit, was zu dem Zeitpunkt da +# ist, und die Loeschung kam eine Zeile zu spaet. +# +# Deshalb tragen solche Dateien ab jetzt das Praefix `zz-`, und git +# sieht sie gar nicht erst. Eine Regel, die im Werkzeug steht, ist +# besser als eine, an die ich mich erinnern muss. +zz-* +/*.png.tmp diff --git a/ruf.png b/ruf.png deleted file mode 100644 index 9ee21722..00000000 Binary files a/ruf.png and /dev/null differ diff --git a/workspace/assets/css/gate.css b/workspace/assets/css/gate.css index dc322466..8c549b93 100644 --- a/workspace/assets/css/gate.css +++ b/workspace/assets/css/gate.css @@ -100,12 +100,36 @@ --spicy-zweit: #ff8a6b; --spicy-tief: #8c2f2b; - /* DOGFATHER (admin) — babyblau UND lila, wie gewünscht. Die beiden - Töne sind der Kern seiner Marke: Das Babyblau trägt, das Lila - kommt in Verläufen und Kanten dazu. */ - --dogi-haupt: #7ec8f2; - --dogi-zweit: #a78bfa; - --dogi-tief: #2c5f80; + /* DOGFATHER (admin) — SILBER, mit Babyblau als Auge (09.09.2026). + + Filipe: "die farbe von der rolle und die barre soll so richtig + geil silber sein. so wie mit sternen, also es soll nicht zu viel + sein aber geil sein und der husky soll eine geile babyblau + [Auge] haben ... es soll jetzt nicht viel mehr farbe haben." + + Damit kehrt die Rolle zu dem zurueck, was im allerersten Auftrag + stand ("husky: silber und blaue augen") -- unterwegs war daraus + Babyblau als Traegerfarbe geworden. + + NACHGERECHNET, WEIL SILBER GEFAEHRLICH IST: Es hat kaum Buntheit + und koennte deshalb neben einer anderen Rolle verschwinden. In + OKLab liegt #d8e0ec 0,1901 von seinem naechsten Nachbarn (Scout) + entfernt -- das BISHERIGE Babyblau lag bei 0,1349. Die fuenf + Rollen sind dadurch besser auseinanderzuhalten als vorher, nicht + schlechter. Kontrast auf dunklem Grund: 14,41:1. + + Creators Silber ist nur sein ZWEITTON neben Bronze; sein Traeger + bleibt warm, dieser hier ist kuehl. Die beiden stossen sich + nicht. + + "wie mit sternen" ist als GLANZ gebaut, nicht als Funken: ein + schmales Spitzlicht, das ueber das Silber laeuft (siehe + `.rolle[data-rolle="admin"]` weiter unten). Kein Blinken -- die + Anmeldeseite ist das Erste, was jemand sieht, und augenschonend + bleibt Vorgabe. */ + --dogi-haupt: #d8e0ec; + --dogi-zweit: #7ec8f2; + --dogi-tief: #38485c; /* MANAGER — lila, bleibt (Wunsch: "manager bleibt lila"). */ --manager-haupt: #8a76ff; @@ -2388,3 +2412,44 @@ body.gate { rgba(143, 216, 255, .55) 78%, transparent 100%); } + +/* ===================================================================== + DER SILBERGLANZ AUF DER DOGFATHER-ZEILE (screen3, 09.09.2026) + + Filipe: "so richtig geil silber ... so wie mit sternen, also es soll + nicht zu viel sein aber geil sein." + + "Wie mit Sternen" ist als GLANZ gebaut, nicht als Funkeln: ein + schmales Spitzlicht, das schraeg ueber die Zeile laeuft, plus drei + winzige Lichtpunkte. Zusammen ergibt das den Eindruck von poliertem + Metall, auf dem sich etwas spiegelt. + + NICHTS BEWEGT SICH. Ein wanderndes Glitzern auf der Anmeldeseite + waere genau das, was die Hausregel verbietet -- und diese Zeile ist + das Erste, was jemand von der Seite sieht. Der Glanz steht still; + er lebt davon, dass er schraeg liegt und nicht mittig. + + ER GILT NUR FUER DIESE EINE ROLLE. Die anderen vier bleiben, wie sie + sind: "immer noch im stil von den anderen kategorien". Der + Unterschied ist das Material, nicht die Lautstaerke. + ===================================================================== */ +.rolle[data-rolle="admin"] { + position: relative; +} +.rolle[data-rolle="admin"]::after { + content: ""; + position: absolute; inset: 0; + pointer-events: none; + background: + /* Das Spitzlicht -- schmal, schraeg, und weit vor der Mitte. */ + linear-gradient(104deg, + transparent 8%, + rgba(255, 255, 255, .11) 17%, + rgba(255, 255, 255, .03) 24%, + transparent 32%), + /* Drei Lichtpunkte, unregelmaessig gesetzt. Regelmaessig waeren sie + ein Muster; unregelmaessig sind sie Zufall auf einer Oberflaeche. */ + radial-gradient(1.4px 1.4px at 22% 30%, rgba(255, 255, 255, .5), transparent), + radial-gradient(1.1px 1.1px at 63% 72%, rgba(226, 238, 250, .38), transparent), + radial-gradient(1.6px 1.6px at 84% 26%, rgba(255, 255, 255, .3), transparent); +} diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index 27acab64..5db2b224 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -6695,3 +6695,167 @@ body[data-fremde-sicht="ja"]::after { @media (prefers-reduced-motion: reduce) { .uhr__kopf { transition: none; } } + +/* Die Zahlenkarten fuehren zu ihren Aufgaben (screen1, 09.09.2026). + + Der Link fuellt die ganze Kachel -- ein Ziel von 150 x 70 Pixeln + statt eines von der Groesse der Zahl. Die Kachel selbst bleibt das +
  • : Sie traegt die Fase und das Kantenlicht aus der Modulliste, + und die sollen nicht am Link haengen. */ +.zahl { position: relative; } +.zahl__link { + display: flex; flex-direction: column; gap: 2px; + color: inherit; text-decoration: none; +} +/* DIE TREFFERFLAECHE WIRD GESTRECKT, NICHT DER LINK GEPOLSTERT. + + Im ersten Anlauf stand hier `padding: inherit` -- das haette die + 14/16 der Kachel ein ZWEITES Mal aufgetragen, weil `.zahl` sie schon + hat. Die Kachel waere um 28 px gewachsen, und zwar siebenmal + nebeneinander. + + Ein durchsichtiges `::after` ueber die ganze Kachel loest dasselbe + ohne eine einzige Groessenangabe: Der Link bleibt, wo er ist, sein + ANKLICKBARER Bereich ist die Kachel. Das ist der uebliche Weg fuer + "die ganze Karte ist ein Link" und braucht kein JavaScript. */ +.zahl__link::after { + content: ""; position: absolute; inset: 0; +} +/* Beim Zeigen kommt die Kachel naeher -- dieselbe Sprache wie ueberall, + und der Cursor sagt zusaetzlich, dass es weitergeht. */ +.zahl:has(.zahl__link:hover) { background: rgba(255, 255, 255, .045); } +.zahl__link:focus-visible { + outline: 2px solid var(--akzent); outline-offset: -3px; + border-radius: 2px; +} + +/* ===================================================================== + DIE KATEGORIETITEL WERDEN TYPENSCHILDER (screen2, 09.09.2026) + + Filipe: "die titel von den kategorien sollen spezieller und geiler + sein." + + Sie waren ein kurzer Farbstrich, Grossbuchstaben und eine runde + Pille als Lesezone. Solide -- aber die runde Pille war inzwischen + das einzige Rund auf einer Seite, die sonst aus abgeschraegten + Platten besteht. Etwas, das als einziges anders geformt ist, sieht + nicht besonders aus, sondern uebriggeblieben. + + VIER SACHEN MACHEN AUS EINER BESCHRIFTUNG EIN TYPENSCHILD, und alle + vier gibt es hier schon als Sprache -- sie waren nur an dieser + Stelle nicht benutzt: + + 1. DIE FASE statt der Rundung. Dieselbe abgeschraegte Ecke wie + jede Kachel; das Schild gehoert damit sichtbar zur Seite. + 2. EIN GEPRAEGTER ANSCHLAG links statt des Strichs: drei kurze + Balken uebereinander in der Hausfarbe, wie die Kerbung an + einem Messinstrument. Er sagt "hier beginnt ein Abschnitt", + ohne ein Wort dafuer zu brauchen. + 3. GEBUERSTETES METALL in der Schrift -- oben hell, in der Mitte + dunkel, unten hell. Derselbe Verlauf wie auf dem Titel der + Anmeldekarte, nur kleiner. Ein Verlauf von hell nach dunkel + waere eine Faerbung; erst der WECHSEL liest sich als Material. + 4. EINE AUSLAUFENDE LINIE nach rechts. Sie gliedert, ohne die + Seite zu zerschneiden -- dieselbe Loesung wie bei den + Gruppenkoepfen. + + DIE LESEZONE BLEIBT. Sie ist der Grund, warum diese Schilder auf dem + Hintergrundbild lesbar sind, und sie wurde einmal aus einer + Kontrastmessung heraus eingebaut. Sie wird hier nur umgeformt, nicht + abgeschafft -- und eher dichter als vorher (.74 -> .82), weil die + Fase an den Ecken Flaeche wegnimmt. + + DER RUECKFALL IST VOLLWERTIG: `color` bleibt gesetzt, der + Metallverlauf kommt erst in einem `@supports`. Faellt + `background-clip: text` aus, steht dort schlicht heller Text -- + nicht unsichtbarer. + ===================================================================== */ +body.start .dran .feldschild, +body.start .zahlen-block .feldschild, +body.start .protokoll-block .feldschild, +body.start .k-leiste .feldschild { + /* `display: flex` MUSS HIER STEHEN, und das ist ein Fund. + + Weiter oben (Abschnitt "Abschnittsschilder") setzt + `.zahlen-block .feldschild` schon `display: flex` -- damit der + Strich davor ueberhaupt eine Box bekommt. Rund 1200 Zeilen + spaeter steht `.inhalt .feldschild { display: block }`. Beide + haben dieselbe Spezifitaet, also gewinnt die spaetere: Die + Schilder waren `block`, das Pseudoelement damit `inline`, und ein + Inline-Kasten ignoriert `width` und `height`. + + FOLGE: Der "leuchtende Strich", der weiter oben ausfuehrlich + begruendet ist, wurde nie gezeichnet. Aufgefallen ist es erst, + als mein neuer Anschlag ebenfalls unsichtbar blieb -- und die + Messung sagte, der Text beginne bei x=12, also genau an der + Polsterung, ohne dass davor irgendetwas Platz belegt. + + Diese Regel hat mit `body.start` eine Klasse mehr und gewinnt + ueber beide. */ + display: flex; align-items: center; + position: relative; + gap: 11px; + padding: 7px 30px 7px 12px; + margin-left: -12px; + border-radius: 0; + clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px); + background: + linear-gradient(96deg, rgba(6, 9, 16, .82), rgba(6, 9, 16, .42) 78%, transparent), + linear-gradient(180deg, rgba(150, 186, 220, .07), transparent 60%); + box-shadow: + inset 0 1px 0 rgba(170, 205, 240, .10), + inset 0 -1px 0 rgba(0, 0, 0, .45); +} + +/* Der Anschlag: drei Kerben statt eines Strichs. Ein + `repeating-linear-gradient` macht sie aus einer Flaeche -- kein + zusaetzliches Element fuer drei Striche. */ +body.start .dran .feldschild::before, +body.start .zahlen-block .feldschild::before, +body.start .protokoll-block .feldschild::before, +body.start .k-leiste .feldschild::before { + content: ""; + width: 13px; height: 12px; + border-radius: 0; + opacity: 1; + background: repeating-linear-gradient(180deg, + var(--akzent) 0 2px, transparent 2px 5px); + -webkit-mask: linear-gradient(90deg, #000 0 55%, rgba(0, 0, 0, .35) 100%); + mask: linear-gradient(90deg, #000 0 55%, rgba(0, 0, 0, .35) 100%); +} + +/* Die auslaufende Linie rechts. Sie beginnt hinter dem Text und + verliert sich -- eine durchgezogene Linie ueber die ganze Breite + zerschneidet die Seite, eine auslaufende gliedert sie nur. */ +body.start .dran .feldschild::after, +body.start .zahlen-block .feldschild::after, +body.start .protokoll-block .feldschild::after, +body.start .k-leiste .feldschild::after { + content: ""; + position: absolute; right: 8px; top: 50%; + width: 16px; height: 1px; + transform: translateY(-.5px); + background: linear-gradient(90deg, + color-mix(in srgb, var(--akzent) 55%, transparent), transparent); +} + +@supports ((-webkit-background-clip: text) or (background-clip: text)) { + body.start .dran .feldschild, + body.start .zahlen-block .feldschild, + body.start .protokoll-block .feldschild, + body.start .k-leiste .feldschild { + /* Der Verlauf faerbt NUR die Schrift. `background-clip: text` + braucht dafuer einen eigenen Hintergrund -- deshalb steht die + Lesezone hier noch einmal darunter, sonst waere sie mit + weggeschnitten. Die Reihenfolge ist entscheidend: erst der + Textverlauf, dann die Flaechen. */ + background: + linear-gradient(178deg, #ffffff 0%, #dbe6f2 34%, #91a6bd 62%, #d5e3f2 88%, #ffffff 100%) + text, + linear-gradient(96deg, rgba(6, 9, 16, .82), rgba(6, 9, 16, .42) 78%, transparent), + linear-gradient(180deg, rgba(150, 186, 220, .07), transparent 60%); + -webkit-background-clip: text, border-box, border-box; + background-clip: text, border-box, border-box; + color: transparent; + } +} diff --git a/workspace/assets/js/aufgaben.js b/workspace/assets/js/aufgaben.js index db1e9167..b6ad0882 100644 --- a/workspace/assets/js/aufgaben.js +++ b/workspace/assets/js/aufgaben.js @@ -586,6 +586,13 @@ const k = karte(a); k.dataset.status = a.status; if (a.status !== 'erledigt' && a.frist && a.frist < heute) k.dataset.faellig = 'ja'; + /* "Heute faellig" ist ein eigener Zustand, kein Sonderfall von + "ueberfaellig": Die Frist ist HEUTE und damit noch nicht + vorbei. Ohne dieses Merkmal koennte der Sprung von der + Startseite ("Heute faellig") nichts finden -- er zeigt dann + eine leere Auswahl, und man glaubt, man sei falsch + abgebogen. */ + if (a.status !== 'erledigt' && a.frist === heute) k.dataset.heute = 'ja'; spalte.append(k); } @@ -602,20 +609,51 @@ davon, dass man alle vier Spalten nebeneinander sieht -- wer nur die ueberfaelligen zeigt, nimmt genau den Ueberblick weg, wegen dem man hergekommen ist. */ + /* ZWEI SCHLUESSEL KAMEN AM 09.09.2026 DAZU (screen1). + + Filipe, mit Bild der sieben Zahlenkarten auf der Startseite: "wenn + ich auf die druecke soll ich auf zu denen punkten gebracht werden." + + Fuenf der sieben konnten das schon (offen, arbeit, review, + erledigt, ueberfaellig) -- nur wusste es niemand, weil die Karten + keine Links waren. "Heute faellig" und "Abgebrochen" fehlten + ganz. */ const ZEIG_TEXT = { offen: 'Aufgaben, die offen sind', arbeit: 'Aufgaben, die gerade laufen', review: 'Aufgaben, die auf Freigabe warten', erledigt: 'Aufgaben, die erledigt sind', ueberfaellig: 'Aufgaben, deren Frist vorbei ist', + heute: 'Aufgaben, die heute fällig sind', + abgebrochen: 'Aufgaben, die abgebrochen wurden', }; function sprungZeigen() { const was = window.zielSchluessel?.(); if (!was || !ZEIG_TEXT[was]) return; + + /* ABGEBROCHENE STEHEN NICHT IM BRETT, sondern in einem eigenen + Kasten weiter unten -- und der ist zugeklappt, solange niemand + ihn aufmacht. Ein Sprung dorthin muss ihn also erst OEFFNEN, + sonst landet man an einer Stelle, an der nichts zu sehen ist. + Genau die Sorte Sprung, die einen glauben laesst, der Knopf sei + kaputt. */ + if (was === 'abgebrochen') { + /* `#abgebrochen` IST das
    , nicht sein Behaelter. Im + ersten Anlauf stand hier `kasten.querySelector('details')` -- + das haette null geliefert und den Kasten zugeklappt gelassen. + Nachgesehen im Markup statt vermutet. */ + const kasten = $('abgebrochen'); + if (kasten) kasten.open = true; + window.zielMarkieren?.(document.querySelectorAll('.abbruch-karte'), ZEIG_TEXT[was]); + return; + } + const treffer = was === 'ueberfaellig' ? document.querySelectorAll('.karte[data-faellig="ja"]') - : document.querySelectorAll(`.karte[data-status="${was}"]`); + : was === 'heute' + ? document.querySelectorAll('.karte[data-heute="ja"]') + : document.querySelectorAll(`.karte[data-status="${was}"]`); window.zielMarkieren?.(treffer, ZEIG_TEXT[was]); } diff --git a/workspace/assets/js/start.js b/workspace/assets/js/start.js index 71ffa4db..17cad599 100644 --- a/workspace/assets/js/start.js +++ b/workspace/assets/js/start.js @@ -1280,14 +1280,44 @@ else block.removeAttribute('data-leer'); $('zahlen-leer').hidden = !!summe; + /* JEDE ZAHL FUEHRT ZU IHREN AUFGABEN (09.09.2026, screen1). + + Filipe: "wenn ich auf die druecke soll ich auf zu denen punkten + gebracht werden." + + Der Weg dahin gab es schon: `aufgaben.html?zeigen=` + springt zu den passenden Karten und legt eine Zeile darueber, + was gerade gezeigt wird (kopf.js, `zielMarkieren`). Nur waren + diese sieben Karten `
  • ` ohne Link -- die Auskunft war da, der + Weg dorthin nicht. Zwei fehlende Schluessel ("heute", + "abgebrochen") sind in aufgaben.js nachgetragen. + + EIN IM
  • , NICHT DAS
  • KLICKBAR. Ein Listenpunkt mit + einem Klick-Zuhoerer ist fuer Tastatur und Vorleseprogramm kein + Ziel -- man kann ihn nicht anspringen und bekommt nicht gesagt, + dass er irgendwohin fuehrt. Ein echter Link kann das alles, ohne + eine Zeile JavaScript. + + DIE NULL BLEIBT EIN LINK. Es waere naheliegend, sie abzuschalten + ("da ist ja nichts"). Aber der Sprung zeigt dann genau das -- + eine leere Spalte mit der Zeile "Aufgaben, die offen sind". Das + ist eine Antwort. Ein toter Knopf ist keine. + + Der volle Satz steht im `aria-label`: Vorgelesen wird "3 Aufgaben + sind überfällig — ansehen" und nicht "3 Überfällig". */ const liste = $('zahlen'); liste.textContent = ''; for (const z of ZAHLEN) { const wert = daten[z.schluessel] ?? 0; const li = el('li', 'zahl'); if (z.warn && wert > 0) li.dataset.warn = 'ja'; - li.append(el('span', 'zahl__wert', String(wert))); - li.append(el('span', 'zahl__name', z.name)); + const a = el('a', 'zahl__link'); + a.href = `aufgaben.html?zeigen=${encodeURIComponent(z.schluessel)}`; + a.setAttribute('aria-label', + `${wert} ${wert === 1 ? 'Aufgabe' : 'Aufgaben'}: ${z.name} — ansehen`); + a.append(el('span', 'zahl__wert', String(wert))); + a.append(el('span', 'zahl__name', z.name)); + li.append(a); liste.append(li); } } diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 22110c8a..31f670cc 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -14,10 +14,10 @@ - - - - + + + + @@ -217,10 +217,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 591129f7..64408137 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -140,10 +140,10 @@ - - - - - + + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index f71f3d28..ed7a31ea 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -149,14 +149,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 2aa14ac7..38ae21a5 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -82,11 +82,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index d2bd934f..62a3c59d 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -14,17 +14,17 @@ - - + + - - - + + + @@ -160,10 +160,10 @@ - - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index d243dbd0..2c32aff8 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -172,12 +172,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index 127899c7..76f3542e 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -101,10 +101,10 @@ - - - - - + + + + + diff --git a/workspace/index.html b/workspace/index.html index 3a031588..55513bbc 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -32,7 +32,7 @@ - + @@ -90,12 +90,11 @@ - - - - - - + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + - - + + @@ -580,10 +580,10 @@

    - - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 69af70d9..67096f64 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -78,11 +78,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index f12c5dfe..54a520b0 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -119,10 +119,10 @@ - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index 19412bc7..86db164a 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -14,13 +14,13 @@ - - + + - - - + + + @@ -142,11 +142,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 9d1c46a6..92d56879 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -14,11 +14,11 @@ - - - - - + + + + + @@ -183,10 +183,10 @@ - - - - - + + + + +