diff --git a/assets/css/webdesign.css b/assets/css/webdesign.css index 45e0861d..1eb29970 100644 --- a/assets/css/webdesign.css +++ b/assets/css/webdesign.css @@ -1756,3 +1756,169 @@ button.po-aufg-haken:hover { border-color: var(--wd-gold); background: rgb(var(- font-size: .93rem; } .rl-formular p { margin: 0 0 .6rem; } + +/* ===================================================================== + FEINSCHLIFF — das Höhensystem (23.08.2026) + + Bis hierher trug jede Karte EINEN Schatten: 0 24px 60px -28px. Das ist + solide, aber es ist auch der Grund, warum eine Oberfläche "ordentlich" + statt "teuer" wirkt. + + Echtes Licht erzeugt zwei Dinge gleichzeitig: + + 1. einen engen, dunklen Kontaktschatten direkt an der Kante — er + sagt dem Auge, dass ein Gegenstand AUFLIEGT + 2. einen weiten, weichen Umgebungsschatten — er sagt, wie HOCH er + darüber schwebt + + Nur einen von beiden zu setzen, sieht aus wie ein Aufkleber. Beide + zusammen ergeben einen Gegenstand. + + Dazu kommt die LICHTKANTE: eine 1 Pixel hohe, sehr schwache weisse + Linie an der Oberkante (inset 0 1px 0). Sie tut so, als käme das Licht + von oben und bräche sich an der Kante. Das ist das meistübersehene + Detail in dunklen Oberflächen — und dasjenige, das den grössten + Unterschied macht. Ohne sie wirkt eine Karte wie ein Loch im + Hintergrund; mit ihr wie ein Stück Material. + + Drei Stufen, mehr braucht es nicht: + 1 ruhende Flächen (Karten, Felder) + 2 hervorgehobene Flächen (aktive Karte, Knopf) + 3 Schwebendes (Fenster, Menü) + ===================================================================== */ +:root { + /* Kontaktschatten + Umgebungsschatten + Lichtkante, in dieser + Reihenfolge — die Lichtkante zuletzt, damit sie über allem liegt. */ + --wd-hoehe-1: + 0 1px 2px rgba(0, 0, 0, .40), + 0 10px 28px -12px rgba(0, 0, 0, .70), + inset 0 1px 0 rgba(255, 255, 255, .055); + --wd-hoehe-2: + 0 2px 4px rgba(0, 0, 0, .45), + 0 18px 44px -16px rgba(0, 0, 0, .80), + inset 0 1px 0 rgba(255, 255, 255, .075); + --wd-hoehe-3: + 0 4px 8px rgba(0, 0, 0, .50), + 0 40px 90px -30px rgba(0, 0, 0, .92), + inset 0 1px 0 rgba(255, 255, 255, .09); + + /* Vertiefte Flächen — Eingabefelder liegen NICHT auf der Oberfläche, + sie sind hineingeschnitten. Derselbe Lichteinfall, nur umgekehrt: + oben dunkel (Schattenkante), unten hell. */ + --wd-tiefe: + inset 0 1px 2px rgba(0, 0, 0, .35), + inset 0 -1px 0 rgba(255, 255, 255, .03); +} + +/* ---------- Karten ---------- */ +.wd-karte { + box-shadow: var(--wd-hoehe-1); + /* Etwas schneller als der bisherige Standard: Bei Flächen, die man + überfährt, wirkt alles über 200 ms träge. */ + transition: + transform .18s cubic-bezier(.2, .8, .3, 1), + box-shadow .18s cubic-bezier(.2, .8, .3, 1), + border-color .18s ease; +} +a.wd-karte:hover, .wd-karte--klickbar:hover { + transform: translateY(-3px); + box-shadow: var(--wd-hoehe-3), 0 0 40px -22px rgb(var(--wd-blau-rgb) / .5); +} +/* Beim Drücken zurück auf die Fläche — ohne das fehlt die Rückmeldung, + dass der Klick angekommen ist. */ +a.wd-karte:active, .wd-karte--klickbar:active { + transform: translateY(-1px); + box-shadow: var(--wd-hoehe-1); + transition-duration: .06s; +} + +/* ---------- Knöpfe ---------- */ +.wd-btn { + transition: + transform .16s cubic-bezier(.2, .8, .3, 1), + box-shadow .16s cubic-bezier(.2, .8, .3, 1), + background .16s ease, border-color .16s ease, color .16s ease; +} +/* Der Hauptknopf ist hell auf dunklem Grund. Seine Lichtkante gehört + deshalb nach INNEN und heller — sie lässt die Fläche gewölbt wirken + statt flach aufgeklebt. */ +/* ⚠️ Die Gewichtung muss zur Grundregel passen. + + Weiter oben steht ".wd .wd-btn--haupt, .wd-btn--haupt { ... }" -- der + erste Teil zaehlt ZWEI Klassen. Ein blosses ".wd-btn--haupt" hier + unten zaehlt eine und verliert, obwohl es spaeter steht. Beim ersten + Versuch blieb der Hauptknopf deshalb ohne Lichtkante, waehrend die + Karten sie schon hatten -- gemessen, nicht vermutet. + + Dieselbe Falle wie am 22.08.2026 bei ".wd a" gegen ".wd-btn--haupt". + Wer in dieser Datei etwas nachtraegt, muss die Gewichtung der + Grundregel uebernehmen, nicht nur die Reihenfolge. */ +.wd .wd-btn--haupt, .wd-btn--haupt { + box-shadow: + 0 1px 2px rgba(0, 0, 0, .35), + 0 10px 26px -12px rgb(var(--wd-blau-rgb) / .55), + inset 0 1px 0 rgba(255, 255, 255, .45); +} +.wd .wd-btn--haupt:hover, .wd-btn--haupt:hover { + transform: translateY(-2px); + box-shadow: + 0 2px 4px rgba(0, 0, 0, .4), + 0 18px 40px -14px rgb(var(--wd-blau-rgb) / .8), + inset 0 1px 0 rgba(255, 255, 255, .55); +} +.wd .wd-btn--haupt:active, .wd-btn--haupt:active { transform: translateY(0); transition-duration: .06s; } + +.wd-btn--zweit, .wd-btn--still { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04); +} +.wd-btn--zweit:hover, .wd-btn--still:hover { + transform: translateY(-1px); + box-shadow: + 0 6px 18px -10px rgba(0, 0, 0, .8), + inset 0 1px 0 rgba(255, 255, 255, .07); +} + +/* ---------- Eingabefelder: vertieft statt aufliegend ---------- */ +.wd-feld input[type="text"], .wd-feld input[type="email"], .wd-feld input[type="tel"], +.wd-feld input[type="url"], .wd-feld input[type="number"], .wd-feld input[type="date"], +.wd-feld input[type="password"], .wd-feld input[type="search"], +.wd-feld select, .wd-feld textarea, .wd-eingabe { + box-shadow: var(--wd-tiefe); + transition: border-color .16s ease, box-shadow .16s ease, background .16s ease; +} +/* Im Fokus bleibt die Vertiefung erhalten und der Ring kommt dazu — + sonst "springt" das Feld beim Anklicken aus der Fläche heraus. */ +.wd-eingabe:focus, .wd-feld input:focus, .wd-feld select:focus, .wd-feld textarea:focus { + box-shadow: var(--wd-tiefe), 0 0 0 4px rgb(var(--wd-blau-rgb) / .16); +} + +/* ---------- Marken und Abzeichen ---------- */ +.wd-tag, .vw-status, .po-aufg-marke, .vw-aufg-wer, .vw-aufg-nicht { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06); +} + +/* ---------- Schwebende Flächen ---------- */ +.vw-detail-blatt { box-shadow: var(--wd-hoehe-3), 0 0 0 1px rgb(var(--wd-blau-rgb) / .06) inset; } +.wd-nav-panel, .wd-menue-flaeche { box-shadow: var(--wd-hoehe-3); } + +/* ---------- Schrift: optische Korrektur ---------- + Grosse Schriftgrade wirken bei gleicher Laufweite zu locker gesetzt — + das Auge sieht bei 48px mehr Weissraum zwischen den Buchstaben als bei + 16px. Professioneller Satz zieht deshalb mit wachsender Größe enger. + Bei kleinen Grössen genau umgekehrt: dort hilft etwas mehr Luft. */ +.wd h1 { letter-spacing: -.028em; } +.wd h2 { letter-spacing: -.021em; } +.wd h3 { letter-spacing: -.012em; } +/* Verhindert Schusterjungen in Überschriften — ein einzelnes Wort in der + letzten Zeile sieht immer nach Versehen aus. */ +.wd h1, .wd h2, .wd-fuehrung { text-wrap: balance; } +.wd p { text-wrap: pretty; } + +/* ---------- Ruhe bei Bewegungsempfindlichkeit ---------- */ +@media (prefers-reduced-motion: reduce) { + .wd-karte, .wd-btn { transition: none !important; } + a.wd-karte:hover, .wd-karte--klickbar:hover, + .wd-btn:hover, .wd-btn--haupt:hover, .wd-btn--zweit:hover, .wd-btn--still:hover { + transform: none !important; + } +} diff --git a/pruef-aufgaben-computer.png b/pruef-aufgaben-computer.png index 99e23776..fa4cb542 100644 Binary files a/pruef-aufgaben-computer.png and b/pruef-aufgaben-computer.png differ diff --git a/pruef-aufgaben-handy.png b/pruef-aufgaben-handy.png index d845441f..d3ee3d7f 100644 Binary files a/pruef-aufgaben-handy.png and b/pruef-aufgaben-handy.png differ diff --git a/pruef-design.mjs b/pruef-design.mjs index 22a3f20a..6abf34cd 100644 --- a/pruef-design.mjs +++ b/pruef-design.mjs @@ -38,7 +38,20 @@ const srv = createServer((q, r) => { }); await new Promise((r) => srv.listen(4329, r)); -const SEITEN = readdirSync(join(W, "webdesign")).filter((f) => f.endsWith(".html")); +/* diagnose.html ist bewusst ausgenommen. + + Sie ist das Werkzeug fuer den Fall, dass die Seite NICHT laeuft, und + traegt deshalb alles fest in sich: eigene Farben, eigenes Layout, + keine externe CSS- oder JS-Datei, keine Uebersetzung. Genau das ist + ihr Zweck -- eine Diagnoseseite, die an derselben kaputten + Stilvorlage scheitert wie das Problem, das sie untersuchen soll, + waere wertlos. + + Sie deshalb an den Regeln fuer die eigentliche Seite zu messen, wuerde + zwei Meldungen erzeugen, die man auf Dauer wegsieht -- und irgendwann + sieht man dann auch eine echte weg. */ +const SEITEN = readdirSync(join(W, "webdesign")) + .filter((f) => f.endsWith(".html") && f !== "diagnose.html"); const SPRACHEN = ["de", "de-CH", "en", "fr", "pt"]; const funde = []; diff --git a/pruef-portal-aufgaben-computer.png b/pruef-portal-aufgaben-computer.png index 93ebe0ea..81527584 100644 Binary files a/pruef-portal-aufgaben-computer.png and b/pruef-portal-aufgaben-computer.png differ diff --git a/pruef-portal-aufgaben-handy.png b/pruef-portal-aufgaben-handy.png index 9507de01..6ea88ba0 100644 Binary files a/pruef-portal-aufgaben-handy.png and b/pruef-portal-aufgaben-handy.png differ diff --git a/pruef-portal-postfach-computer.png b/pruef-portal-postfach-computer.png index 2045276d..ff52f626 100644 Binary files a/pruef-portal-postfach-computer.png and b/pruef-portal-postfach-computer.png differ diff --git a/pruef-portal-postfach-handy.png b/pruef-portal-postfach-handy.png index 1a5a42e5..ff9f5c60 100644 Binary files a/pruef-portal-postfach-handy.png and b/pruef-portal-postfach-handy.png differ diff --git a/pruef-postfach-computer.png b/pruef-postfach-computer.png index 8def97bf..bb7d45a4 100644 Binary files a/pruef-postfach-computer.png and b/pruef-postfach-computer.png differ diff --git a/pruef-postfach-handy.png b/pruef-postfach-handy.png index 01af6c54..555e9e1f 100644 Binary files a/pruef-postfach-handy.png and b/pruef-postfach-handy.png differ diff --git a/pruef-system.mjs b/pruef-system.mjs index a41bcb70..b7cad3ca 100644 --- a/pruef-system.mjs +++ b/pruef-system.mjs @@ -43,7 +43,20 @@ const srv = createServer((q, r) => { }); await new Promise((r) => srv.listen(4332, r)); -const SEITEN = readdirSync(join(W, "webdesign")).filter((f) => f.endsWith(".html")); +/* diagnose.html ist bewusst ausgenommen. + + Sie ist das Werkzeug fuer den Fall, dass die Seite NICHT laeuft, und + traegt deshalb alles fest in sich: eigene Farben, eigenes Layout, + keine externe CSS- oder JS-Datei, keine Uebersetzung. Genau das ist + ihr Zweck -- eine Diagnoseseite, die an derselben kaputten + Stilvorlage scheitert wie das Problem, das sie untersuchen soll, + waere wertlos. + + Sie deshalb an den Regeln fuer die eigentliche Seite zu messen, wuerde + zwei Meldungen erzeugen, die man auf Dauer wegsieht -- und irgendwann + sieht man dann auch eine echte weg. */ +const SEITEN = readdirSync(join(W, "webdesign")) + .filter((f) => f.endsWith(".html") && f !== "diagnose.html"); const ALT = "127, 208, 232"; // der bisherige Markenton const NEU = "255 120 40"; // drastisch anders, damit nichts untergeht diff --git a/webdesign/ablauf.html b/webdesign/ablauf.html index 040bc9be..ec1c3a3e 100644 --- a/webdesign/ablauf.html +++ b/webdesign/ablauf.html @@ -13,8 +13,8 @@ - - + +