diff --git a/server/pruef-start-ansicht.mjs b/server/pruef-start-ansicht.mjs index 2b4b0ba1..8cd4794e 100644 --- a/server/pruef-start-ansicht.mjs +++ b/server/pruef-start-ansicht.mjs @@ -501,9 +501,25 @@ console.log("\n=== Das Licht folgt dem Zeiger"); ok(await anzahlAn() === 0, `in der Luecke geht es aus (${await anzahlAn()})`); /* 2. Direkt von einer Kachel auf die naechste -- es darf nie mehr - als eine gleichzeitig leuchten. */ + als eine gleichzeitig leuchten. + + ERST INS BILD ROLLEN, DANN MESSEN, DANN ZIELEN. Diese Datei + schreibt denselben Satz zwanzig Zeilen weiter unten schon + einmal, und trotzdem stand er hier nicht: Am 07.09.2026 wurde + die Begruessungskachel hoeher, Kachel 3 rutschte auf y = 1134 bei + einem 1200 px hohen Fenster -- ihre Mitte lag bei 1210, also + UNTER dem Bildrand. Der Zeiger landete im Nichts, keine Kachel + leuchtete, und die Pruefung meldete einen Fehler am Licht, + obwohl das Licht in Ordnung war. + + Der Kasten wird NACH dem Rollen neu gelesen. Ein vor dem Rollen + gemessener Kasten ist danach falsch -- das waere derselbe Fehler + mit einem Zwischenschritt mehr. */ + await seite.locator(".kachel").nth(2).scrollIntoViewIfNeeded(); + await seite.waitForTimeout(250); const k2 = await seite.locator(".kachel").nth(2).boundingBox(); - await seite.mouse.move(k1.x + k1.width / 2, k1.y + k1.height / 2); + const k1neu = await seite.locator(".kachel").nth(1).boundingBox(); + await seite.mouse.move(k1neu.x + k1neu.width / 2, k1neu.y + k1neu.height / 2); await seite.waitForTimeout(250); await seite.mouse.move(k2.x + k2.width / 2, k2.y + k2.height / 2); await seite.waitForTimeout(300); @@ -542,6 +558,13 @@ console.log("\n=== Das Licht folgt dem Zeiger"); { const farben = []; for (const nr of [1, 2, 3]) { + /* Auch hier: erst ins Bild rollen, dann den Kasten lesen. Eine + Kachel unter dem Bildrand bekommt keinen Zeiger, also auch + kein Licht-Element -- und `licht: null` fuer zwei von drei + Kacheln sah aus wie "zwei Kacheln leuchten gleich". Ein Fehler, + der etwas ganz anderes meldet, als er ist. */ + await seite.locator(".kachel").nth(nr).scrollIntoViewIfNeeded(); + await seite.waitForTimeout(200); const b = await seite.locator(".kachel").nth(nr).boundingBox(); if (!b) continue; await seite.mouse.move(b.x + b.width / 2, b.y + b.height / 2); @@ -555,6 +578,10 @@ console.log("\n=== Das Licht folgt dem Zeiger"); }; }, nr)); } + /* DIE ANZAHL GEHOERT IN DIE BEDINGUNG. Waeren keine Kacheln + messbar, waere `farben` leer -- und "0 verschiedene Toene bei 0 + Kacheln" ist immer wahr. Grün, ohne etwas angesehen zu haben. */ + ok(farben.length === 3, `drei Kacheln wirklich gemessen (${farben.length})`); const toene = new Set(farben.map((f) => f.ton)); ok(toene.size === farben.length, `jede Kachel hat ihren eigenen Ton (${[...toene].join(", ")})`); diff --git a/workspace/assets/css/heim.css b/workspace/assets/css/heim.css index 9f39577f..a24b24cc 100644 --- a/workspace/assets/css/heim.css +++ b/workspace/assets/css/heim.css @@ -48,74 +48,176 @@ Der Sprung ist außerdem ehrlicher: Die Anzeige ist digital. ===================================================================== */ -/* Die Kachel selbst: dasselbe Material wie die Bereichskacheln, damit - nicht zwei Oberflächen nebeneinanderliegen. Sie hat KEINE eigene - Farbschiene -- sie gehört zu keiner Kategorie, sie ist der Anfang. */ +/* ===================================================================== + DIE KONSOLE — sie gehoert absichtlich NICHT zu den Modulen + (07.09.2026) + + Filipe: "diese hauptkachel muss komplett aus der rolle fliegen im + gegenzug zu den anderen, VIEL SPEZIELLER AUFFAELLIGER UND KRASSER." + + Hier stand vorher woertlich: "dasselbe Material wie die + Bereichskacheln, damit nicht zwei Oberflaechen nebeneinanderliegen." + Das war eine vernuenftige Regel -- und genau sie war das Problem. + Eine Flaeche, die sich an alle anderen anpasst, kann nicht + herausstechen. Die Begruessung ist aber keine Kachel unter Kacheln, + sondern der Anfang der Seite. + + DREI DINGE MACHEN SIE ZU ETWAS ANDEREM, und alle drei sind FORM, + nicht Farbe -- das ist die Lehre aus den drei Anlaeufen, die Filipe + zu Recht als "wieder nur eine kleine Aenderung" bezeichnet hat: + + 1. SIE IST BREITER ALS DIE SEITE. Sie tritt links und rechts ueber + die Spalte hinaus, in der alle Kacheln stehen. Das ist + "aus der Reihe fliegen", woertlich genommen: Ihre Kante liegt + dort, wo bei allem anderen keine mehr ist. + 2. SIE IST EIN ACHTECK. Die Module haben EINE abgeschnittene Ecke + oben links. Diese Flaeche hat VIER -- eine andere geometrische + Klasse, erkennbar aus fuenf Metern, ohne ein Wort zu lesen. + 3. SIE HAT EINE METALLFASSUNG. Ein Kegelverlauf mit acht Stopps, + wie ihn VanVans Business-Hub fuer sein Medaillon benutzt: Hell, + dunkel, hell, dunkel rundherum -- so wirft gebuerstetes Metall + das Licht zurueck. Kein Rahmen, sondern ein Werkstoff. + + Deshalb steht `.willkommen` seit heute NICHT mehr in der Modulliste + von module.css. Stuende sie dort, bekaeme sie dieselbe Silhouette wie + siebzehn andere Flaechen -- und module.css laedt nach dieser Datei, + haette also das letzte Wort. Sie herauszunehmen ist keine Auslassung, + sondern die Voraussetzung. + ===================================================================== */ + .willkommen { + /* Zwei Groessen, ein Ort. Die Fase steht als Variable da, damit + Silhouette, Fassung und Innenglas garantiert dieselbe benutzen -- + drei getippte Zahlen waeren drei Gelegenheiten, dass die Kante + einen halben Pixel danebenliegt. */ + --k-fase: 26px; + --k-rand: 4px; + position: relative; - padding: 22px 24px; - border: 1px solid var(--rand); - border-radius: 4px 20px 20px 4px; + padding: 26px 30px; + border: 0; + border-radius: 0; + + /* SIE TRITT AUS DER SPALTE HERAUS -- ABER NIE UEBER DEN BILDRAND. + + Der Wert ist an die Polsterung der Inhaltsspalte GEBUNDEN und + nicht danebengeschrieben: `.inhalt` hat + `padding: … clamp(16px, 4vw, 40px)`, also 40 px am Rechner und + nur 16 px auf dem Handy. Eine feste Zahl waere hier genau die + Sorte Fehler, die dieses Haus schon zweimal teuer bezahlt hat: + Bei 1600 px sieht 34 px gut aus, bei 412 px ragt die Flaeche + 17 px aus dem Bildschirm und die Seite laesst sich seitlich + schieben. + + `min(34px, 3.6vw)` bleibt an jeder Breite unter der Polsterung -- + 3,6 % sind immer weniger als 4 %, und bei den 13 px unter 380 px + Breite (eigene Regel in start.css) ebenfalls. Gedeckelt bei + 34 px, weil der Ueberstand ein Hinweis sein soll und kein + Vorsprung. + + Er steht in einer Variablen, weil ihn drei Regeln brauchen + (Breite, linker Rand, rechter Rand); drei getippte Zahlen waeren + drei Gelegenheiten, dass die Konsole schief steht. */ + --k-ueber: min(34px, 3.6vw); + width: calc(100% + 2 * var(--k-ueber)); + margin-left: calc(-1 * var(--k-ueber)); + margin-right: calc(-1 * var(--k-ueber)); + + /* DIE FASSUNG: gebuerstetes Metall als Kegelverlauf. Acht Stopps, + nicht zwei -- ein Verlauf von hell nach dunkel ist eine Flaeche mit + Farbverlauf; erst der WECHSEL hell/dunkel/hell liest sich als + geschliffenes Metall. Dieselbe Bauart wie das Medaillon auf + VanVans Business-Hub, nur rechteckig gefasst und mit den beiden + Hausfarben statt reinem Silber. */ + /* DIE FASSUNG: gebuerstetes Metall, LAENGS gerichtet. + + ZWEI FEHLER LAGEN HIER HINTEREINANDER, beide im Bildschirmfoto + gesehen und nicht im Kopf: + + (1) HALBDURCHSICHTIG. Metall, durch das der Hintergrund scheint, + ist kein Metall -- es las sich als graue Linie. Derselbe + Fehler stand gleichzeitig an der Uhr. Jetzt deckende Farben. + + (2) KEGELVERLAUF AUF EINER BREITEN FLAECHE. Bei der runden Uhr ist + `conic-gradient` genau richtig: Jede Stelle des Rings liegt in + einem anderen Winkel, also wandert das Licht rundherum. Bei + einem 1200 px breiten Balken liegt die GANZE Oberkante in + einem Winkelausschnitt von wenigen Grad -- der Verlauf + passiert dort fast nichts, und die Fassung sah wieder flach + aus. Ein gebuersteter Metallbalken glaenzt der LAENGE nach: + helle und dunkle Zonen wandern von links nach rechts. Deshalb + hier ein linearer Verlauf mit zwoelf Stopps, und nur an den + beiden Stellen, an denen das Haus seine Farben hat, eine + warme und eine kuehle Spiegelung. + + Die Lehre gilt allgemein: Die Verlaufsart muss zur FORM passen, + nicht zum Material. Rund -> conic, lang -> linear. */ background: - linear-gradient(90deg, - rgba(63, 189, 245, .10) 0%, - rgba(63, 189, 245, .03) 14%, - transparent 40%), - linear-gradient(163deg, - rgba(23, 31, 45, .95) 0%, - rgba(11, 15, 24, .95) 58%, - rgba(8, 11, 18, .95) 100%); - box-shadow: - inset 0 1px 0 rgba(255, 255, 255, .10), - inset 0 -1px 0 rgba(0, 0, 0, .50), - inset 2px 0 0 -1px color-mix(in srgb, var(--akzent) 34%, transparent), - 0 2px 5px -2px rgba(0, 0, 0, .55), - 0 16px 34px -20px rgba(0, 0, 0, .88); - overflow: hidden; + linear-gradient(96deg, + #cfdcec 0%, + #f6fbff 4%, + #64768d 9%, + #e3ecf7 15%, + #7d8fa6 22%, + #ff8a94 27%, + #f8fcff 31%, + #55677e 38%, + #dbe6f3 46%, + #6b7d94 55%, + #f2f8ff 63%, + #8fd8ff 70%, + #5d6f87 77%, + #e9f1fb 85%, + #7a8ca3 92%, + #f4f9ff 97%, + #cfdcec 100%); + clip-path: polygon( + var(--k-fase) 0, calc(100% - var(--k-fase)) 0, + 100% var(--k-fase), 100% calc(100% - var(--k-fase)), + calc(100% - var(--k-fase)) 100%, var(--k-fase) 100%, + 0 calc(100% - var(--k-fase)), 0 var(--k-fase)); + + /* Die Tiefe liegt im `filter`, nicht im `box-shadow`: Ein + box-shadow folgt immer dem Rechteck und zeichnete Schatten fuer + vier Ecken, die es nicht mehr gibt. */ + filter: + drop-shadow(0 3px 5px rgba(0, 0, 0, .6)) + drop-shadow(0 22px 44px rgba(0, 0, 0, .7)); } -/* Die Leuchtschiene links -- dieselbe Sprache wie überall, hier im - Hausakzent statt in einer Kategoriefarbe. */ + +/* DAS INNENGLAS. Eigene Ebene, damit die Fassung ringsum stehen bleibt + -- genau wie bei der Uhr und beim Medaillon. Der Horizont unten ist + der einzige farbige Akzent: Rot links, Babyblau rechts, beide weit + unter der Blendschwelle. */ .willkommen::before { - content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; - border-radius: 4px 0 0 4px; - background: linear-gradient(180deg, - color-mix(in srgb, var(--akzent) 55%, #fff) 0%, - var(--akzent) 26%, - color-mix(in srgb, var(--akzent) 50%, transparent) 100%); - box-shadow: - 0 0 9px 0 color-mix(in srgb, var(--akzent) 55%, transparent), - 3px 0 20px -3px color-mix(in srgb, var(--akzent) 42%, transparent); - opacity: .9; - z-index: 2; -} -/* Körnung und ein fester Glanz. Kein wandernder wie bei den Kacheln: - Diese Fläche wird nicht angeklickt, also gibt es nichts zu quittieren. */ -.willkommen::after { - content: ""; position: absolute; inset: 0; pointer-events: none; - border-radius: inherit; + content: ""; position: absolute; inset: var(--k-rand); + z-index: 0; pointer-events: none; + clip-path: polygon( + calc(var(--k-fase) - var(--k-rand)) 0, calc(100% - var(--k-fase) + var(--k-rand)) 0, + 100% calc(var(--k-fase) - var(--k-rand)), 100% calc(100% - var(--k-fase) + var(--k-rand)), + calc(100% - var(--k-fase) + var(--k-rand)) 100%, calc(var(--k-fase) - var(--k-rand)) 100%, + 0 calc(100% - var(--k-fase) + var(--k-rand)), 0 calc(var(--k-fase) - var(--k-rand))); background: - linear-gradient(104deg, - transparent 26%, - rgba(255, 255, 255, .05) 40%, - rgba(255, 255, 255, .085) 47%, - rgba(255, 255, 255, .03) 55%, - transparent 70%); - /* KEINE Körnung auf DIESER Ebene (07.09.2026, gemessen). - - Sie stand hier als zweite Schicht und hat die Deckkraft der - Spiegelung geerbt -- 50 % eines mittelgrauen Rauschens heben jeden - Bildpunkt um rund 30 Stufen an. Gemessen: rgb(56,44,58) statt der - berechneten rgb(20,26,38), und über einer hellen Stelle des - Motivs rgb(85,83,81). Die Karte sah dadurch durchsichtig aus, - obwohl sie zu 95 % deckt. - - Derselbe Fehler wie an der Anmeldekarte heute Nachmittag, und - genau derselbe Grund: Körnung gehört auf eine EIGENE Ebene mit - `mix-blend-mode: overlay` und 3 bis 4 Prozent -- so wie bei den - Kacheln der Startseite. Auf einer geteilten Ebene ist sie kein - Material, sondern ein grauer Schleier. */ - opacity: .5; + radial-gradient(120% 90% at 4% 108%, rgba(255, 95, 109, .16), transparent 52%), + radial-gradient(120% 90% at 96% 108%, rgba(143, 216, 255, .17), transparent 52%), + linear-gradient(168deg, #131a27 0%, #0a0e17 62%, #06090f 100%); } + +/* RASTER UND KANTENLICHT auf einer zweiten Ebene. Das Raster ist + feiner als das der Module (16 statt 26 px) -- eine Konsole ist ein + Messgeraet, kein Modul, und der Unterschied soll auch aus der Naehe + tragen. */ +.willkommen::after { + content: ""; position: absolute; inset: var(--k-rand); + z-index: 0; pointer-events: none; + clip-path: inherit; + background: + linear-gradient(180deg, rgba(255, 255, 255, .12) 0 1px, transparent 1px), + repeating-linear-gradient(0deg, rgba(150, 186, 220, .30) 0 1px, transparent 1px 16px), + repeating-linear-gradient(90deg, rgba(150, 186, 220, .30) 0 1px, transparent 1px 16px); + opacity: .30; +} + .willkommen > * { position: relative; z-index: 1; } .willkommen__reihe { @@ -172,79 +274,153 @@ -> rot. Wo der eine warm ist, ist der andere kuehl; so bleiben sie auseinanderzuhalten, wo sie sich ueberlagern. -------------------------------------------------------------------- */ +/* ===================================================================== + DIE UHR — ein Instrument, keine Anzeige (07.09.2026, zweiter Anlauf) + + Filipe: "AUCH MIT DER UHR RECHTS; DAS IST VIEL ZU EINFACH; ICH WILL + SIE NOCH VIEEEEEEL KRASSER; WIE IN DER BUISNESS HUB SEITE VON VANVAN, + WIE DIE UHR BEI IHR ABER NOCH KRASSER UND SPEZIELLER." + + NACHGESEHEN, NICHT GERATEN. Auf VanVans Business-Hub gibt es keine + Uhr -- gemeint ist das `gate-medaillon` auf der Anmeldeseite: ein + runder Kegelverlauf, der wie gebuerstetes Metall aussieht, gefasst in + zwei eingelassenen Ringen. Genau diese Bauart steht jetzt hier, in + drei Punkten weitergetrieben: + + 1. FASSUNG STATT RAND. Der Kegelverlauf laeuft rundherum durch + hell/dunkel/hell -- deshalb sieht die Fassung gedreht aus und + nicht bemalt. Sie ist 5 px breit statt 3; darunter liegt ein + zweiter, dunkler Ring, der sie einlaesst. + 2. AUFGESETZTE STUNDENMARKEN. Zwoelf kraeftige Striche aus einem + einzigen sich wiederholenden Kegelverlauf, dazu sechzig feine. + Sechzig Elemente im HTML waeren dieselbe Optik mit sechzig + Elementen mehr im Baum. + 3. GLASKUPPE. Eine Spiegelung von oben links plus ein heller Bogen + an der Oberkante. Ohne den Bogen wirkt jede runde Flaeche flach. + + UND SIE IST GROESSER: 164 statt 124 px. Das ist kein Detail -- + "krasser" heisst bei einem Instrument zuerst "lesbar". Auf dem Handy + bleibt sie bei 118 px, dort steht sie unter dem Text statt daneben. + ===================================================================== */ .uhr { position: relative; - width: 124px; height: 124px; flex: none; + width: 164px; height: 164px; flex: none; display: grid; place-items: center; border-radius: 50%; - /* SCHICHT 1: der Metallrand. Ein Verlauf von hell (oben links, wo das - Licht herkommt) nach dunkel und wieder etwas heller unten rechts -- - so sieht eine gedrehte Metallfassung aus. Als `padding` gebaut, - damit die Scheibe darin sitzt statt daneben. */ - padding: 3px; + padding: 10px; + /* SCHICHT 1: DIE LUENETTE. Zehn Pixel breit und DECKEND. + Halbdurchsichtig war der Fehler des ersten Anlaufs: Metall, durch + das der Hintergrund scheint, sieht nicht nach Metall aus, sondern + nach grauem Glas -- im Bildschirmfoto gemessen, es las sich als + flacher grauer Ring. Echtes Metall ist undurchsichtig; sein + Aussehen entsteht allein daraus, WIE es das Licht zurueckwirft. + Deshalb hier volle Farben und ein harter Wechsel hell/dunkel. */ background: - linear-gradient(150deg, - rgba(255, 255, 255, .20) 0%, - rgba(255, 120, 132, .16) 26%, - rgba(8, 12, 20, .9) 52%, - rgba(143, 216, 255, .16) 78%, - rgba(255, 255, 255, .10) 100%); + conic-gradient(from 208deg, + #eaf2fb 0deg, + #8fa3bd 26deg, + #f6fbff 52deg, + #6f8299 84deg, + #dfe9f5 116deg, + #ff8a94 150deg, + #f4f9ff 176deg, + #5d6f87 214deg, + #e6eff9 246deg, + #8fd8ff 282deg, + #f8fcff 312deg, + #7c8ea6 340deg, + #eaf2fb 360deg); box-shadow: - /* Der Rand wirft nach aussen einen sehr weichen zweifarbigen - Schein -- rot oben links, blau unten rechts, wie der Rahmen im - Motiv. Beides weit unter der Schwelle, an der es blendet. */ - -3px -3px 22px -12px rgba(255, 95, 109, .55), - 3px 3px 22px -12px rgba(143, 216, 255, .55), - 0 12px 26px -14px rgba(0, 0, 0, .95); + /* Der zweifarbige Schein nach aussen, weit unter der Blendschwelle. */ + -4px -4px 26px -13px rgba(255, 95, 109, .6), + 4px 4px 26px -13px rgba(143, 216, 255, .6), + 0 14px 30px -14px rgba(0, 0, 0, .95), + /* Und der dunkle Ring, der die Fassung einlaesst -- ohne ihn liegt + sie auf dem Zifferblatt statt darin. */ + inset 0 0 0 1px rgba(6, 10, 18, .85); } -/* SCHICHT 2: die vertiefte Scheibe. Eigene Ebene, damit der Metallrand - darum stehen bleibt. */ +/* SCHICHT 2: die vertiefte Scheibe. */ .uhr::before { - content: ""; position: absolute; inset: 3px; border-radius: 50%; + content: ""; position: absolute; inset: 10px; border-radius: 50%; background: - radial-gradient(circle at 50% 28%, rgba(255, 255, 255, .055), transparent 58%), - radial-gradient(circle at 50% 50%, #0c121e 58%, #05080e 100%); + radial-gradient(circle at 50% 26%, rgba(255, 255, 255, .06), transparent 56%), + radial-gradient(circle at 50% 50%, #0c121e 56%, #04070d 100%); box-shadow: - inset 0 2px 6px -2px rgba(0, 0, 0, .95), + inset 0 2px 7px -2px rgba(0, 0, 0, .95), + inset 0 0 0 1px rgba(190, 205, 225, .16), inset 0 -1px 0 rgba(255, 255, 255, .05); } -/* Die Skala: sechzig feine Striche, aus EINEM sich wiederholenden - Kegelverlauf. Sechzig Elemente im HTML waeren dieselbe Optik mit - sechzig Elementen mehr im Baum. Jeder fuenfte Strich ist kraeftiger - -- das ist der Unterschied zwischen "Punkte im Kreis" und "Skala". */ +/* DIE SKALA LIEGT AUF DER LUENETTE, NICHT AUF DEM ZIFFERBLATT. + + Im ersten Anlauf lag sie bei 90 bis 99 Prozent des Radius -- und + genau dort laeuft der Sekundenring. Sie war vollstaendig verdeckt, + und zwar so, dass man es nicht merkt: Eine unsichtbare Skala sieht + aus wie gar keine, nicht wie ein Fehler. Im Bildschirmfoto gesehen, + nicht im Kopf ausgerechnet. + + Jetzt sitzt sie dort, wo sie bei einer echten Uhr sitzt: eingraviert + in den Metallring. Deshalb sind die Striche DUNKEL -- eine Gravur ist + eine Vertiefung, in der Schatten steht, kein aufgemalter heller + Strich. Zwoelf kraeftige fuer die Stunden, sechzig feine dazwischen, + beide aus je EINEM sich wiederholenden Kegelverlauf. */ .uhr__skala { - /* Die Skala liegt GANZ AUSSEN, jenseits des Stundenrings -- zwischen - den Ringen waere sie ein vierter Kreis und der Grund, warum das - Zifferblatt unruhig wirkt. Zwoelf kraeftige Striche fuer die - Stunden, sechzig feine dazwischen. */ - position: absolute; inset: 1px; border-radius: 50%; + position: absolute; inset: 0; border-radius: 50%; + /* NUR die zwoelf Stundenmarken -- lang und kraeftig. Die sechzig + feinen Minutenstriche liegen auf einer eigenen Ebene (.uhr::after), + weil sie eine ANDERE Laenge brauchen: Auf einer echten Luenette + reichen Stundenmarken durch den ganzen Ring, Minutenstriche nur + ein Stueck vom Rand herein. Zwei Laengen heissen zwei Masken, und + zwei Masken heissen zwei Ebenen -- eine Ebene kann nur eine haben. + + Beim ersten Anlauf lagen beide hier, gleich lang: Aus der Skala + wurde ein Zahnkranz. Im Bildschirmfoto gesehen. */ background: repeating-conic-gradient(from 0deg, - rgba(226, 234, 244, .70) 0deg 0.8deg, - transparent 0.8deg 30deg), - repeating-conic-gradient(from 0deg, - rgba(150, 186, 220, .22) 0deg 0.4deg, - transparent 0.4deg 6deg); - -webkit-mask: radial-gradient(circle, transparent 0 92%, #000 92% 99%, transparent 99%); - mask: radial-gradient(circle, transparent 0 92%, #000 92% 99%, transparent 99%); - opacity: .8; - pointer-events: none; z-index: 1; + rgba(6, 10, 18, .85) 0deg 1.5deg, + transparent 1.5deg 30deg); + /* `closest-side` IST HIER PFLICHT, NICHT GESCHMACK. + + Ohne Angabe rechnet ein `radial-gradient` seine Prozente auf die + WEITESTE ECKE des Kastens -- bei 164 px Kantenlaenge sind das + 116 px, nicht die 82 px des Radius. "89 % bis 99,5 %" lag damit + bei 103 bis 115 px und komplett AUSSERHALB der runden Uhr: Die + Skala war unsichtbar, und zwar seit es sie gibt. Eine unsichtbare + Verzierung sieht aus wie gar keine, nicht wie ein Fehler -- genau + deshalb ist sie nie aufgefallen. + + Mit `closest-side` sind 100 % der Radius, und die Prozente + bedeuten das, wonach sie aussehen. */ + -webkit-mask: radial-gradient(circle closest-side, transparent 0 88%, #000 88% 99.5%, transparent 99.5%); + mask: radial-gradient(circle closest-side, transparent 0 88%, #000 88% 99.5%, transparent 99.5%); + pointer-events: none; z-index: 4; } -/* SCHICHT 3: das Glas. Eine Spiegelung von oben links ueber die Kuppe, - dazu ein hauchfeiner heller Bogen am oberen Rand -- die Kante der - Scheibe. Ohne diesen Bogen wirkt die Uhr flach. */ +/* Die sechzig feinen Minutenstriche -- kurz, vom Aussenrand herein, + und deutlich leiser als die Stundenmarken. Das Verhaeltnis der beiden + ist der ganze Unterschied zwischen "Skala" und "Zahnkranz". */ +.uhr::after { + content: ""; position: absolute; inset: 0; border-radius: 50%; + z-index: 4; pointer-events: none; + background: + repeating-conic-gradient(from 0deg, + rgba(6, 10, 18, .42) 0deg 0.4deg, + transparent 0.4deg 6deg); + -webkit-mask: radial-gradient(circle closest-side, transparent 0 94%, #000 94% 99.5%, transparent 99.5%); + mask: radial-gradient(circle closest-side, transparent 0 94%, #000 94% 99.5%, transparent 99.5%); +} + +/* SCHICHT 3: die Glaskuppe. */ .uhr__glas { - position: absolute; inset: 3px; border-radius: 50%; + position: absolute; inset: 10px; border-radius: 50%; background: linear-gradient(146deg, - rgba(255, 255, 255, .13) 0%, - rgba(255, 255, 255, .03) 20%, - transparent 44%); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .16); + rgba(255, 255, 255, .15) 0%, + rgba(255, 255, 255, .035) 19%, + transparent 42%); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2); pointer-events: none; z-index: 3; } .uhr__ring { - position: absolute; inset: 3px; width: calc(100% - 6px); height: calc(100% - 6px); + position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); /* Bei Null soll der Ring OBEN beginnen, nicht rechts. */ transform: rotate(-90deg); z-index: 2; @@ -317,7 +493,7 @@ display: grid; justify-items: center; gap: 2px; line-height: 1; } .uhr__zeit { - font-size: 1.46rem; font-weight: 700; letter-spacing: -.015em; + font-size: 1.86rem; font-weight: 700; letter-spacing: -.015em; /* Gleiche Zifferbreite: Ohne sie zappelt die Anzeige bei jedem Minutenwechsel, weil die 1 schmaler ist als die 8. */ font-variant-numeric: tabular-nums; @@ -365,8 +541,8 @@ keine Zeile mehr übrig. */ .willkommen { padding: 18px 16px; } .willkommen__rechts { margin-left: 0; width: 100%; justify-content: flex-start; } - .uhr { width: 96px; height: 96px; } - .uhr__zeit { font-size: 1.18rem; } + .uhr { width: 118px; height: 118px; padding: 4px; } + .uhr__zeit { font-size: 1.3rem; } } @media (prefers-reduced-motion: reduce) { diff --git a/workspace/assets/css/module.css b/workspace/assets/css/module.css index dc5f8c33..9f556115 100644 --- a/workspace/assets/css/module.css +++ b/workspace/assets/css/module.css @@ -89,7 +89,7 @@ } /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { +:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { position: relative; clip-path: polygon(var(--fase) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fase)); border-radius: 0; @@ -104,7 +104,7 @@ was übrig bleibt, ist eine Linie, die exakt der Form folgt, Schräge inklusive. Ein `border` könnte das nicht: Er folgt dem Rechteck. */ /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { +:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { content: ""; position: absolute; inset: 0; pointer-events: none; @@ -127,7 +127,7 @@ /* RASTER UND ECKWINKEL. Beides auf ::after -- ein drittes Element gibt es nicht, und beides ist reine Optik ohne Klicks. */ /* MODULLISTE */ -:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { +:is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { content: ""; position: absolute; inset: 0; pointer-events: none; @@ -147,9 +147,24 @@ /* Der Inhalt gehört ÜBER Raster und Kantenlicht. Ohne diese Zeile liegt bei Karten ohne eigenen Stapelwert der Text unter dem Raster - und wird von ihm überzeichnet. */ -:is(.eintrag-karte, .call, .datei, .kachel, .willkommen, .leer-hinweis, - .team-karte, .zahl, .k-listentag, .person, .creator) > * { + und wird von ihm überzeichnet. + + `:not(.licht)` IST KEINE FEINHEIT, SONDERN DIE REPARATUR EINES + FEHLERS, DEN DIESE ZEILE SELBST VERURSACHT HAT (07.09.2026). + + Das Licht, das dem Zeiger folgt, ist ein und + damit ein direktes Kind jeder Karte. `position: relative` hat ihm + sein `position: absolute` genommen: Aus einer Fläche über der ganzen + Karte wurde ein leerer Inline-Span ohne Ausdehnung. Im Browser + gemessen -- `display: inline`, obwohl in start.css `absolute` + steht -- und genau deshalb war das Licht weg, das Filipe + zurückhaben wollte. + + Merksatz: Eine Regel auf `> *` trifft auch das, was gar kein Inhalt + ist. Wer sie schreibt, muss wissen, was sonst noch als Kind in + diesen Karten liegt. */ +:is(.eintrag-karte, .call, .datei, .kachel, .leer-hinweis, + .team-karte, .zahl, .k-listentag, .person, .creator) > *:not(.licht) { position: relative; z-index: 1; } @@ -171,7 +186,7 @@ /* Dieselbe Form, kleiner -- keine zweite Gestaltung. */ :root { --fase: 12px; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { + :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { filter: drop-shadow(0 3px 8px rgba(0, 0, 0, .7)); } } @@ -185,15 +200,15 @@ /* Im Kontrastmodus zählt die Kante, und die muss ein echter `border` sein. Die Schräge bleibt: Sie ist Geometrie, keine Farbe. */ /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { + :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu) { filter: none; border: 1px solid CanvasText; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { + :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::after { display: none; } /* MODULLISTE */ - :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .willkommen, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { + :is(.eintrag-karte, .call, .datei, .ablage, .zahlkarte, .regel, .zustand, .ki-kasten, .k-ansicht, .spalte, .balance, .saeulen-kasten, .neu, .call-raum, .creator, .summe, .pdf, .pdf-ablage, .suchleiste, .person, .kk, .fortschritt, .punkt, .unterweisung, .warnkarte, .kachel, .tagesblick, .leer-hinweis, .team-karte, .zahl, .k-listentag, .import-vorschau, .code-fenster, .schulung__neu)::before { display: none; } } diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index 5aa4dab7..2272362a 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -1819,7 +1819,25 @@ body.start > main { position: relative; z-index: 1; } nur Beiwerk. ===================================================================== */ -body.start .willkommen, +/* `.willkommen` STAND HIER UND IST AM 07.09.2026 HERAUSGENOMMEN. + + Die Begruessung ist seit heute eine eigene Konsole mit Metallfassung + und Achteck-Silhouette (heim.css). Diese Regel hier hat sie + ueberschrieben -- und zwar nicht ueber die Ladereihenfolge, sondern + ueber die SPEZIFITAET: `body.start .willkommen` ist (0,2,1), die neue + Regel `.willkommen` nur (0,1,0). Sie hat also gewonnen, obwohl sie + frueher geladen wird, und die Konsole trug weiter die alte Glastafel: + 20 px Polsterung, abgerundete Ecken, ein grauer Verlauf. Im + Bildschirmfoto gemessen -- die Metallfassung war nie zu sehen. + + Das ist derselbe Fehler wie mit `:where()` heute Frueh, nur + andersherum: damals zu SCHWACH geschrieben, hier zu STARK stehen + gelassen. Wer eine Flaeche neu baut, muss zuerst nachsehen, wer sie + vorher beschrieben hat -- und mit welchem Gewicht. + + Der Weichzeichner faellt damit auch weg, und das ist gut so: Er + holt die Neonfarben von AUSSERHALB der Flaeche herein und hat schon + zweimal dafuer gesorgt, dass eine Karte grau statt dunkelblau aussah. */ body.start .kopf-zeile, body.start .k-kopf { padding: 20px 24px; diff --git a/workspace/assets/js/kopf.js b/workspace/assets/js/kopf.js index 287d05a9..9b19da61 100644 --- a/workspace/assets/js/kopf.js +++ b/workspace/assets/js/kopf.js @@ -349,7 +349,21 @@ verlaesst, wird geloescht -- sonst flackerte das Licht bei jeder Bewegung ueber ein Wort hinweg. */ if (karte.contains(e.relatedTarget)) return; - letzte = null; /* den angemeldeten Bildaufbau entwerten */ + /* NUR DEN EIGENEN Bildaufbau entwerten (07.09.2026). + + Hier stand `letzte = null` ohne Bedingung -- und das hat beim + Wechsel von einer Karte auf die naechste das Licht GANZ + ausgeschaltet. Der Grund ist die Reihenfolge der Ereignisse: + `pointermove` auf der neuen Karte kommt zuerst und meldet + einen Bildaufbau an; `pointerout` der alten Karte kommt danach + und hat ihn geloescht, obwohl er gar nicht ihr gehoerte. Der + Bildaufbau lief, fand `letzte === null` und tat nichts. + + Gemessen mit pruef-start-ansicht: "beim Wechsel leuchtet + weiterhin nur eine (0)" -- null statt einer. Ein Fehler, den + man von Hand nur bemerkt, wenn man zufaellig schnell genug + von Kachel zu Kachel faehrt. */ + if (letzte && letzte.karte === karte) letzte = null; aus(karte); }, { capture: true, passive: true }); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index e4dd2bfd..78ad5931 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -9,10 +9,10 @@ - - - - + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index b26b2011..a433d6b0 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -135,10 +135,10 @@ - - - - - + + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index ed082ed6..fac97f15 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -144,14 +144,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 13585f18..338dea8a 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -77,11 +77,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index 2cc8f97c..9abf069a 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -9,17 +9,17 @@ - - + + - - - + + + @@ -155,9 +155,9 @@ - - - - + + + + diff --git a/workspace/content.html b/workspace/content.html index 381c645d..173a2065 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -167,12 +167,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index baef23ae..da8db37b 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -96,10 +96,10 @@ - - - - - + + + + + diff --git a/workspace/index.html b/workspace/index.html index 776654d7..aa45fbf6 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -27,7 +27,7 @@ - + @@ -202,6 +202,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index bca2ee8a..9e1b60e1 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -258,11 +258,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index 4b0836e4..023b83bd 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 4e719c04..857eba14 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -137,10 +137,10 @@ - - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 88c42bd0..3640697f 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -202,11 +202,11 @@ - - - - - - + + + + + + diff --git a/workspace/report.html b/workspace/report.html index 1d2f687c..76d33e36 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -94,11 +94,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index fe90e634..64f83543 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -127,10 +127,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index d6f51667..40fbfd78 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -9,12 +9,12 @@ - - + + - - + + @@ -264,10 +264,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 3f875af1..2b3c4716 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -73,11 +73,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index 30c81f44..60e3256d 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -114,10 +114,10 @@ - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index 7b3c0434..a3d72c9c 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -9,13 +9,13 @@ - - + + - - - + + + @@ -137,10 +137,10 @@ - + - - - + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 76aa01be..3a36a683 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -178,10 +178,10 @@ - - - - - + + + + +