diff --git a/server/pruef-buehne.png b/server/pruef-buehne.png index c950a4b3..ac2fb5f4 100644 Binary files a/server/pruef-buehne.png and b/server/pruef-buehne.png differ diff --git a/server/pruef-handy.png b/server/pruef-handy.png index 1041faed..dcdb116e 100644 Binary files a/server/pruef-handy.png and b/server/pruef-handy.png differ diff --git a/server/pruef-lesbarkeit-scouting.png b/server/pruef-lesbarkeit-scouting.png index 56fb6042..c06ca73d 100644 Binary files a/server/pruef-lesbarkeit-scouting.png and b/server/pruef-lesbarkeit-scouting.png differ diff --git a/server/pruef-lesbarkeit-wissen.png b/server/pruef-lesbarkeit-wissen.png index 561e1c99..aa9993f3 100644 Binary files a/server/pruef-lesbarkeit-wissen.png and b/server/pruef-lesbarkeit-wissen.png differ diff --git a/server/pruef-rollen-admin.png b/server/pruef-rollen-admin.png index 1fbf53f5..bdff4468 100644 Binary files a/server/pruef-rollen-admin.png and b/server/pruef-rollen-admin.png differ diff --git a/server/pruef-rollen-creator.png b/server/pruef-rollen-creator.png index 371638b1..3321135c 100644 Binary files a/server/pruef-rollen-creator.png and b/server/pruef-rollen-creator.png differ diff --git a/server/pruef-rollen-manager.png b/server/pruef-rollen-manager.png index 51fa080d..a6cd1157 100644 Binary files a/server/pruef-rollen-manager.png and b/server/pruef-rollen-manager.png differ diff --git a/server/pruef-rollen-scout.png b/server/pruef-rollen-scout.png index d2dd5065..01f04055 100644 Binary files a/server/pruef-rollen-scout.png and b/server/pruef-rollen-scout.png differ diff --git a/server/pruef-start-computer.png b/server/pruef-start-computer.png index 5c2d3925..1ca1d23e 100644 Binary files a/server/pruef-start-computer.png and b/server/pruef-start-computer.png differ diff --git a/server/pruef-start-creator.png b/server/pruef-start-creator.png index 89a7bbca..3227c57e 100644 Binary files a/server/pruef-start-creator.png and b/server/pruef-start-creator.png differ diff --git a/server/pruef-start-handy.png b/server/pruef-start-handy.png index cc10fa91..3dba29bb 100644 Binary files a/server/pruef-start-handy.png and b/server/pruef-start-handy.png differ diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index 997b06ed..97742fdb 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -736,25 +736,69 @@ body.start > main { position: relative; z-index: 1; } /* Das Zeichen sitzt in einem eigenen Feld -- dadurch bekommt der Ton eine Fläche, ohne dass die ganze Kachel farbig wird. Der Verlauf und der innere Lichtrand darin lassen es geprägt statt gemalt wirken. */ +/* ---------- Die Plakette (neu gebaut 03.09.2026) ------------------------- + + Sie war ein leicht getöntes Quadrat. Jetzt ist sie ein KÖRPER: + + * ein Verlauf über die Diagonale statt einer flachen Tönung + * eine Lichtkante oben INNEN und eine Schattenkante unten innen -- + zusammen ergibt das eine Wölbung, das Feld wirkt geprägt + * ein Hof in der eigenen Farbe darunter, der die Plakette von der + Kachel abhebt + * darüber ein Glanzbogen (::before), der von links oben einfällt + + Alles bleibt gedeckt. Ein leuchtender Kasten wäre in einer dunklen + Oberfläche eine Lampe -- und Lampen schaut man nicht stundenlang an. */ .kachel__zeichen { position: relative; z-index: 1; - flex: none; + flex: none; overflow: hidden; display: grid; place-items: center; - width: 52px; height: 52px; border-radius: 15px; + width: 58px; height: 58px; border-radius: 17px; background: - linear-gradient(160deg, - color-mix(in srgb, var(--ton) 30%, transparent), - color-mix(in srgb, var(--ton) 10%, transparent)); - border: 1px solid color-mix(in srgb, var(--ton) 32%, transparent); - /* Lichtkante innen oben, weicher Schein nach aussen -- dadurch wirkt - das Feld geprägt statt gemalt. Der Schein bleibt schwach; ein - leuchtender Kasten wäre in einer dunklen Oberfläche eine Lampe. */ + radial-gradient(120% 100% at 22% 8%, + color-mix(in srgb, var(--ton) 46%, transparent) 0%, + color-mix(in srgb, var(--ton) 22%, transparent) 46%, + color-mix(in srgb, var(--ton) 8%, transparent) 100%); + border: 1px solid color-mix(in srgb, var(--ton) 40%, transparent); box-shadow: - inset 0 1px 0 color-mix(in srgb, var(--ton) 38%, transparent), - 0 4px 14px -8px color-mix(in srgb, var(--ton) 60%, transparent); + /* Wölbung: Licht oben innen, Schatten unten innen. */ + inset 0 1.5px 0 color-mix(in srgb, #fff 26%, transparent), + inset 0 -2px 6px -3px color-mix(in srgb, #000 55%, transparent), + /* Der Hof -- er trägt die Plakette, ohne zu leuchten. */ + 0 6px 18px -9px color-mix(in srgb, var(--ton) 85%, transparent), + 0 0 0 1px color-mix(in srgb, var(--ton) 10%, transparent); transition: background var(--tempo), border-color var(--tempo), transform var(--tempo), box-shadow var(--tempo); } +/* Der Glanzbogen. Ein schmaler heller Streifen, der von links oben über + die Plakette läuft -- dasselbe Licht, das auch die Zeichen von oben + trifft. Er liegt UNTER dem Zeichen (z-index 0 gegen 1), damit er es + nicht überstrahlt. */ +.kachel__zeichen::before { + content: ""; + position: absolute; inset: 0; + background: linear-gradient(150deg, + rgba(255, 255, 255, .22) 0%, + rgba(255, 255, 255, .07) 28%, + rgba(255, 255, 255, 0) 55%); + pointer-events: none; + transition: opacity var(--tempo); +} +.kachel:hover .kachel__zeichen { + transform: translateY(-1px); + border-color: color-mix(in srgb, var(--ton) 62%, transparent); + box-shadow: + inset 0 1.5px 0 color-mix(in srgb, #fff 34%, transparent), + inset 0 -2px 6px -3px color-mix(in srgb, #000 55%, transparent), + 0 10px 24px -10px color-mix(in srgb, var(--ton) 95%, transparent), + 0 0 0 1px color-mix(in srgb, var(--ton) 18%, transparent); +} +@media (prefers-reduced-motion: reduce) { + .kachel__zeichen, .kachel:hover .kachel__zeichen { transition: none; transform: none; } +} +@media (forced-colors: active) { + .kachel__zeichen::before { display: none; } +} .kachel:hover .kachel__zeichen { background: linear-gradient(160deg, @@ -766,7 +810,7 @@ body.start > main { position: relative; z-index: 1; } inset 0 1px 0 color-mix(in srgb, var(--ton) 55%, transparent), 0 6px 20px -8px color-mix(in srgb, var(--ton) 85%, transparent); } -.kachel[data-gross="ja"] .kachel__zeichen { width: 62px; height: 62px; border-radius: 18px; } +.kachel[data-gross="ja"] .kachel__zeichen { width: 70px; height: 70px; border-radius: 21px; } /* ---------- Die Zeichen (überarbeitet 03.09.2026) ------------------------ @@ -787,7 +831,9 @@ body.start > main { position: relative; z-index: 1; } SVG -- so nimmt derselbe eine Verlauf den Ton jeder der siebzehn Kacheln an. Siebzehn Farben, ein Verlauf. */ .kachel__svg { - width: 25px; height: 25px; + /* 29 statt 25: Zusammen mit der kräftigeren Linie ist das der + sichtbarste Teil der Überarbeitung. */ + width: 29px; height: 29px; color: var(--ton); fill: none; stroke-linecap: round; stroke-linejoin: round; @@ -797,8 +843,12 @@ body.start > main { position: relative; z-index: 1; } transition: transform var(--tempo), filter var(--tempo); } .kachel__svg .zeichen__linie { - stroke: url(#zeichen-verlauf); - stroke-width: 1.65; + stroke: url(#zeichen-linie); + /* 2,05 statt 1,65: Die Zeichen sollen TRAGEN, nicht andeuten. Eine + dünne Linie wirkt neben kräftigem Text zaghaft -- und zaghaft war + genau das Problem. */ + stroke-width: 2.05; + paint-order: stroke fill; } /* DIE SCHEIN-LAGE IST WIEDER WEG (03.09.2026) -- und der Weg dorthin gehört aufgeschrieben, damit sie niemand ein zweites Mal einbaut. @@ -829,7 +879,7 @@ body.start > main { position: relative; z-index: 1; } filter: drop-shadow(0 2px 7px color-mix(in srgb, var(--ton) 62%, transparent)); } -.kachel[data-gross="ja"] .kachel__svg { width: 31px; height: 31px; } +.kachel[data-gross="ja"] .kachel__svg { width: 36px; height: 36px; } @media (prefers-reduced-motion: reduce) { .kachel__svg, .kachel:hover .kachel__svg { transition: none; transform: none; } @@ -2809,21 +2859,32 @@ body[data-fremde-sicht="ja"]::after { gar nicht mehr. Beim Überfahren geht sie auf 30 %, so als käme Licht dazu. */ .kachel__svg .zeichen__fuellung { - fill: currentColor; + /* Ein VERLAUF statt einer flachen Deckkraft: oben satt, unten fast + weg. Eine gleichmässig gefüllte Form ist ein Aufkleber; eine, die + nach unten ausläuft, ist ein Körper. */ + fill: url(#zeichen-flaeche); stroke: none; - opacity: .2; transition: opacity var(--tempo); } -.kachel:hover .kachel__svg .zeichen__fuellung { opacity: .3; } +/* Die Spiegelung liegt auf demselben Körper -- ein schmaler heller + Streifen quer über die obere Hälfte, wie Licht auf gewölbtem Glas. */ +.kachel__svg .zeichen__glanz { + fill: url(#zeichen-glanz); + stroke: none; + transition: opacity var(--tempo); +} +.kachel:hover .kachel__svg .zeichen__glanz { opacity: 1.35; } /* Im Wasserzeichen NICHT -- dort liegt das Zeichen riesig hinter dem Text der Kachel. Eine Fläche würde ihn hinterlegen. */ -.kachel__wasserzeichen .zeichen__fuellung { display: none; } +.kachel__wasserzeichen .zeichen__fuellung, +.kachel__wasserzeichen .zeichen__glanz { display: none; } @media (prefers-reduced-motion: reduce) { .kachel__svg .zeichen__fuellung { transition: none; } } @media (forced-colors: active) { /* Ohne Farben würde die Fläche zu einem massiven Block. */ - .kachel__svg .zeichen__fuellung { display: none; } + .kachel__svg .zeichen__fuellung, + .kachel__svg .zeichen__glanz { display: none; } } diff --git a/workspace/assets/js/bereiche.js b/workspace/assets/js/bereiche.js index aebc0140..6adb0c86 100644 --- a/workspace/assets/js/bereiche.js +++ b/workspace/assets/js/bereiche.js @@ -329,52 +329,80 @@ entsteht aus den Pfaden, die ohnehin schon da waren. */ const NS = 'http://www.w3.org/2000/svg'; - const VERLAUF_ID = 'zeichen-verlauf'; + const VERLAUF_ID = 'zeichen-verlaeufe'; - /** Legt den gemeinsamen Verlauf einmal ins Dokument. Alle Zeichen - * verweisen darauf; ein zweiter Aufruf tut nichts. */ + /* ---------- Die drei Verläufe ------------------------------------------ + + Ein Zeichen wird aus drei Lagen aufgebaut, und jede hat ihren + eigenen Verlauf. Alle drei stehen EINMAL im Dokument und arbeiten + mit currentColor -- dadurch nehmen sie den Ton jeder der siebzehn + Kacheln an, ohne dass es einundfünfzig Verläufe braucht. + + flaeche die gefüllte Grundform: oben kräftig, unten fast weg. + Das ist der Körper des Gegenstands. + linie die Kontur: oben fast WEISS, unten im Farbton. Genau so + sieht Metall aus, auf das Licht von oben fällt -- und + genau das lässt ein Zeichen plastisch wirken statt + gezeichnet. + glanz ein schmaler heller Streifen quer über die obere Hälfte. + Die Spiegelung. Sie ist der Unterschied zwischen "gut + gemacht" und "das will ich anfassen". + + ALLE in Benutzerkoordinaten (userSpaceOnUse) über die festen 24 + Einheiten des Rasters. In Objektkoordinaten -- der Vorgabe -- würde + der Verlauf auf den Umriss JEDES einzelnen Pfades gerechnet, und + eine waagerechte Linie hat die Höhe null: Der Verlauf wäre entartet + und der Browser zeichnete den Pfad gar nicht. Genau daran sind am + 03.09.2026 die Querlinie im Kalender, die Regler in Technik und die + Grundlinie der Berichte verschwunden. */ function verlaufSicherstellen() { if (document.getElementById(VERLAUF_ID)) return; const svg = document.createElementNS(NS, 'svg'); + svg.setAttribute('id', VERLAUF_ID); svg.setAttribute('aria-hidden', 'true'); svg.setAttribute('width', '0'); svg.setAttribute('height', '0'); svg.style.position = 'absolute'; const defs = document.createElementNS(NS, 'defs'); - const lg = document.createElementNS(NS, 'linearGradient'); - lg.setAttribute('id', VERLAUF_ID); - /* userSpaceOnUse, NICHT die Vorgabe objectBoundingBox -- und das ist - kein Detail, sondern der Unterschied zwischen "sieht toll aus" und - "die Hälfte des Zeichens fehlt". - Ein Verlauf in Objektkoordinaten wird auf den Umriss JEDES - einzelnen Pfades gerechnet. Eine waagerechte Linie (M4 12h16) hat - aber eine Höhe von null: Der Verlauf ist damit entartet, und der - Browser zeichnet den Pfad einfach GAR NICHT. + const bauen = (id, stops, x2 = '0', y1 = '2', y2 = '22') => { + const lg = document.createElementNS(NS, 'linearGradient'); + lg.setAttribute('id', id); + lg.setAttribute('gradientUnits', 'userSpaceOnUse'); + lg.setAttribute('x1', '0'); lg.setAttribute('y1', y1); + lg.setAttribute('x2', x2); lg.setAttribute('y2', y2); + for (const [pos, farbe, deck] of stops) { + const st = document.createElementNS(NS, 'stop'); + st.setAttribute('offset', pos); + st.setAttribute('stop-color', farbe); + st.setAttribute('stop-opacity', deck); + lg.append(st); + } + defs.append(lg); + }; - Genau das ist passiert: Beim Kalender verschwand die Querlinie, - beim Technik-Zeichen alle drei Regler-Striche, bei den Berichten - die Grundlinie. Zurück blieb ein leerer Kasten und drei Punkte -- - und es sah aus, als sei die Idee mit dem Verlauf schuld. + /* Der Körper: oben satt, unten fast durchsichtig. */ + bauen('zeichen-flaeche', [ + ['0', 'currentColor', '0.62'], + ['0.5', 'currentColor', '0.34'], + ['1', 'currentColor', '0.1'], + ]); + + /* Die Kontur: Licht von oben. Oben fast weiss, unten im Farbton -- + das ist der Trick, der die Zeichen aus der Fläche hebt. */ + bauen('zeichen-linie', [ + ['0', '#ffffff', '0.96'], + ['0.42', '#ffffff', '0.72'], + ['1', 'currentColor', '0.9'], + ]); + + /* Die Spiegelung, diagonal von links oben nach rechts unten. */ + bauen('zeichen-glanz', [ + ['0', '#ffffff', '0.55'], + ['0.45', '#ffffff', '0.12'], + ['0.7', '#ffffff', '0'], + ], '18', '0', '20'); - In Benutzerkoordinaten läuft der Verlauf über die festen 24 - Einheiten des Rasters, unabhängig davon, wie hoch oder flach der - einzelne Pfad ist. Damit bekommt jede Linie den Farbwert, der - ihrer Höhe im Zeichen entspricht -- was ohnehin richtiger ist: - Das Licht kommt von oben, nicht von jedem Strich einzeln. */ - lg.setAttribute('gradientUnits', 'userSpaceOnUse'); - lg.setAttribute('x1', '0'); lg.setAttribute('y1', '2'); - lg.setAttribute('x2', '0'); lg.setAttribute('y2', '22'); - /* currentColor statt einer festen Farbe: Der Verlauf erbt damit den - Ton der Kachel, auf der er gerade liegt. */ - for (const [pos, deck] of [['0', '1'], ['0.55', '0.92'], ['1', '0.6']]) { - const s = document.createElementNS(NS, 'stop'); - s.setAttribute('offset', pos); - s.setAttribute('stop-color', 'currentColor'); - s.setAttribute('stop-opacity', deck); - lg.append(s); - } - defs.append(lg); svg.append(defs); document.body.append(svg); } @@ -390,9 +418,13 @@ die Zeichnung oben. Ein Zeichen ohne Füllung (ältere Einträge, die noch ein reines Feld sind) bekommt einfach keine. */ const eintrag = ZEICHEN[name] || {}; + /* Drei Lagen, von hinten nach vorn: Körper, Spiegelung auf dem + Körper, dann die Kontur. Die Spiegelung benutzt dieselben Pfade + wie der Körper -- sie liegt also GENAU auf ihm und nicht daneben. */ const teile = Array.isArray(eintrag) ? [['zeichen__linie', eintrag]] : [['zeichen__fuellung', eintrag.fuellung || []], + ['zeichen__glanz', eintrag.fuellung || []], ['zeichen__linie', eintrag.linien || []]]; for (const [lage, pfade] of teile) { diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 569c5de8..0f68d96a 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -7,9 +7,9 @@ - - - + + +
@@ -152,9 +152,9 @@ - - - - + + + +