feat(design): neues Theme Snow mit Schneefall und Schneedecke

Eisblau in hell und dunkel. Flocken fallen per Canvas und sammeln sich
am unteren Fensterrand in einer Hoehenkarte, die per Diffusion
geglaettet wird; nach rund vier Minuten ist die Decke voll (26 px).
Bei prefers-reduced-motion bleibt es still.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-09-17 18:02:06 +02:00
co-authored by Claude Opus 5
parent 77b61b4a04
commit 831429d559
11 changed files with 606 additions and 23 deletions
+25 -4
View File
@@ -138,7 +138,7 @@ Die Darstellung hat **zwei unabhängige Achsen**, beide als Klasse am `<html>`:
| Achse | Klasse | Werte |
| --- | --- | --- |
| Farbwelt | `theme-perinco`, `theme-pixel`, `theme-outdoor`, `theme-cyberpunk`, `theme-rainy` | perinco ist der Standard |
| Farbwelt | `theme-perinco`, `theme-pixel`, `theme-outdoor`, `theme-cyberpunk`, `theme-rainy`, `theme-snow` | perinco ist der Standard |
| Modus | `dark` bzw. keine | hell, dunkel, oder der Systemeinstellung folgen |
`src/index.css` tauscht darin nur Variablenwerte: `canvas`, `surface`, `ink-*`,
@@ -173,7 +173,7 @@ er liest den Benutzer.
Alle Themes außer perinco legen eine Grafik hinter die obere Leiste und die
Seitenleiste: 8-bit-Himmel und Steinmauer, blauer Himmel und Wiese,
Neonröhren und regnerische Gasse, Regenwolken und nasse Hügel. Die Dateien liegen als **SVG** in
Neonröhren und regnerische Gasse, Regenwolken und nasse Hügel, verschneite Berge und Waldrand. Die Dateien liegen als **SVG** in
`public/themes/` und sind von Hand gezeichnet - stilisierte Grafik statt Foto,
damit sie in jeder Auflösung scharf bleibt und wenige Kilobyte wiegt.
@@ -212,9 +212,9 @@ Das ist kein Umweg, sondern erledigt zwei Dinge zugleich:
> nur Licht - über Dunkel leuchtet das Neon, über Weiss bleiben blasse farbige
> Linien. Wer eine Grafik ergänzt: **keine deckenden Flächen**, nur Motiv.
### Rainy: das Theme mit Wetter
### Rainy und Snow: Themes mit Wetter
Rainy ist das einzige Theme mit Bewegung. Farben und Grafiken funktionieren wie
Rainy und Snow sind die Themes mit Bewegung. Hier zuerst Rainy, Snow folgt unten. Farben und Grafiken funktionieren wie
bei den anderen; dazu kommt `src/components/RainyWeather.tsx`, das der
`ThemeProvider` nur bei aktivem Rainy einhängt - auch auf der Anmeldeseite, und
beim Wechsel auf ein anderes Theme verschwindet es samt Animationsschleife.
@@ -238,6 +238,27 @@ noch Blitz. Die Canvas-Schleife läuft über `requestAnimationFrame` und ruht
damit in Hintergrund-Tabs; der Zeitschritt ist auf 50 ms begrenzt, damit nach
der Rückkehr nichts nachgeholt wird.
#### Snow
`src/components/SnowWeather.tsx`, eingehängt vom `ThemeProvider` wie der Regen:
ein `<canvas>` über dem Fenster (`z-[90]`, `pointer-events: none`), bei
`prefers-reduced-motion` still.
| Teil | Umsetzung |
| --- | --- |
| **Flocken** | Alle 70–160 ms eine neue, höchstens 70 gleichzeitig. Radius 1–3 px, große fallen schneller, alle schaukeln seitlich (Sinus). Farbe `--snow-flake`, im hellen Modus mit Kontur `--snow-flake-edge` - weiss auf fast weiss wäre unsichtbar |
| **Schneedecke** | Eine Höhenkarte in 3-px-Spalten über die Fensterbreite. Eine Flocke landet, sobald sie die Oberfläche **ihrer** Spalte erreicht, und verteilt sich auf fünf Spalten |
| **Glätten** | Diffusion: jede Spalte gleicht sich an ihre Nachbarn an, Faktor an der Zeit (`SPREAD`), nicht an der Framezahl - gleich auf 60 und 144 Hz. Mengenerhaltend, aus Einzelflocken werden flache Hügel |
| **Deckel** | `MAX_DEPTH` = 26 px, voll nach rund vier Minuten. Was danach landet, verschwindet |
Die Decke lebt nur im Speicher; beim Ändern der Fensterbreite wird sie auf die
neue Spaltenzahl umgerechnet, nach dem Neuladen ist der Boden frei.
> **Erfahrungswert Wachstum:** Das Flockenlimit bestimmt die Landerate, nicht
> das Spawn-Intervall - eine Flocke braucht gut 10 s durchs Fenster, bei 70
> gleichzeitig landen also nur etwa 5 je Sekunde. Wer die Wachstumszeit
> ändert, rechnet mit dieser Zahl.
### Was ein neues Theme können muss
Die Rollen der Skalen sind über die ganze App gleich; ein Theme, das sie
+20 -11
View File
@@ -66,7 +66,7 @@ die Scanner-Einstellungen. Alles andere ist für beide Rollen gleich.
zusammen - hilfreich auf kleinen Bildschirmen.
* Rechts oben stehen zwei Schalter. Der rechte wechselt zwischen **hell und
dunkel**; ein **Doppelklick** darauf folgt wieder der Systemeinstellung.
* Links daneben steht das **Design**. Es gibt fünf zur Wahl, jedes in hell und
* Links daneben steht das **Design**. Es gibt sechs zur Wahl, jedes in hell und
dunkel:
| Design | Aussehen |
@@ -76,6 +76,7 @@ die Scanner-Einstellungen. Alles andere ist für beide Rollen gleich.
| **Outdoor** | Wanderkarte: Sandpapier, Bergsee-Türkis, weiche Ecken |
| **Cyberpunk** | Neon in der Nacht: scharfe Kanten, violettes Leuchten, Blaustahl |
| **Rainy** | Regenwetter: Schieferblau, leichter Nieselregen, Wolken mit Wetterleuchten |
| **Snow** | Winter: Eisblau, Schneefall, der sich am unteren Rand zu einer Schneedecke sammelt |
> **Die Wahl gehört dir, nicht dem Rechner.** Sie wird an deinem Benutzerkonto
> gespeichert. Meldest du dich an einem anderen Rechner an, ist dein Design
@@ -88,17 +89,25 @@ die Scanner-Einstellungen. Alles andere ist für beide Rollen gleich.
Die Designs neben perinco haben zusätzlich eine **Grafik** hinter der
oberen Leiste und der Seitenleiste: 8-bit-Himmel und Steinmauer, blauer Himmel
und Wiese, Neonröhren und Regen, Regenwolken und nasse Hügel. Sie liegt hinter
einem Schleier, damit die Schrift darauf lesbar bleibt, und ist dort am
deutlichsten, wo die Leisten frei sind - in der Mitte oben und unten links. perinco bleibt einfarbig.
und Wiese, Neonröhren und Regen, Regenwolken und nasse Hügel, verschneite
Berge und Tannen. Sie liegt hinter einem Schleier, damit die Schrift darauf
lesbar bleibt, und ist dort am deutlichsten, wo die Leisten frei sind - in der
Mitte oben und unten links. perinco bleibt einfarbig.
**Rainy** ist das einzige Design, in dem sich etwas bewegt: ein paar
Regentropfen fallen über den Bildschirm und zerspritzen am unteren Rand, und
die Wolken in der oberen Leiste leuchten alle paar Sekunden kurz auf. Der
Regen liegt nur optisch über der Oberfläche - er verdeckt keine Knöpfe und
fängt keine Klicks ab, und in geöffneten Dialogen regnet es nicht. Wer im
Betriebssystem **„Bewegung reduzieren"** eingeschaltet hat, sieht nur die
Farben und die Wolken, ohne Regen und Blitz.
**Rainy** und **Snow** sind die Designs, in denen sich etwas bewegt. Das
Wetter liegt nur optisch über der Oberfläche: es fängt keine Klicks ab, und
geöffnete Dialoge liegen darüber.
* Bei **Rainy** fallen ein paar Regentropfen über den Bildschirm und
zerspritzen am unteren Rand, und die Wolken in der oberen Leiste leuchten
alle paar Sekunden kurz auf.
* Bei **Snow** schneit es, und der Schnee bleibt unten liegen: nach etwa vier
Minuten ist am unteren Rand eine Schneedecke gewachsen. Sie bleibt ein
schmaler Streifen und wächst nicht weiter. Neu laden, und der Boden ist
wieder frei.
Wer im Betriebssystem **„Bewegung reduzieren"** eingeschaltet hat, sieht bei
beiden nur Farben und Grafiken - ohne Regen, Blitz und Schnee.
![Dieselbe Ansicht im dunklen Design](bilder/aus-mails-dunkel.png)
* Die Menüpunkte **Akquise**, **Opportunities**, **Kontakte**, **Mails** und
+1 -1
View File
@@ -295,7 +295,7 @@ Uhrzeit, dieses Jahr Tag und Monat, sonst mit Jahr.
| Datei | Hält | Eigenheit |
| --- | --- | --- |
| `auth.tsx` | Benutzer, `isAdmin`, `login`, `logout`, `updateUser` | prüft beim Start das gespeicherte Token gegen `/auth/me` |
| `theme.tsx` | Farbwelt (perinco/Pixel Art/Outdoor/Cyberpunk/Rainy, Hintergrundgrafiken in `public/themes/`; bei Rainy hängt er zusätzlich `components/RainyWeather.tsx` mit Regen und Wetterleuchten ein) und Modus (hell/dunkel/System) | Beides gehört dem Benutzer und steht in `crm_users`; `localStorage` ist nur der Zwischenspeicher fürs Inline-Skript in `index.html`. Doppelklick auf den Modus-Schalter folgt wieder dem System |
| `theme.tsx` | Farbwelt (perinco/Pixel Art/Outdoor/Cyberpunk/Rainy/Snow, Hintergrundgrafiken in `public/themes/`; bei Rainy hängt er zusätzlich `components/RainyWeather.tsx` mit Regen und Wetterleuchten ein, bei Snow `components/SnowWeather.tsx` mit Schneefall und Schneedecke) und Modus (hell/dunkel/System) | Beides gehört dem Benutzer und steht in `crm_users`; `localStorage` ist nur der Zwischenspeicher fürs Inline-Skript in `index.html`. Doppelklick auf den Modus-Schalter folgt wieder dem System |
| `navigation.tsx` | `currentView`, `goTo(view, { tab, leadId })` | erspart es, Callbacks durch vier Ebenen zu reichen; `leadId` öffnet den Kontakt direkt |
| `whisper.tsx` | Modellstatus, Worker, Fortschritt, `transcribe` | ein Worker für die ganze App |