From bea758e65112023a939f7347f54351f96c9c3b32 Mon Sep 17 00:00:00 2001 From: schakal00783 Date: Wed, 23 Sep 2026 10:47:26 +0200 Subject: [PATCH] feat(theme): Theme "Mobile" - kompakte Darstellung fuers Handy Perinco-Farben, aber rund 16 % dichter: --spacing 0.21rem statt 0.25rem, kleinere Ueberschriften (lg bis 5xl), Kopfleiste 3.5rem, flachere Schatten. text-sm/base bleiben, damit iOS beim Tippen in Felder nicht zoomt. Dunkel mit echtem Schwarz fuer OLED. Co-Authored-By: Claude Opus 5.5 --- README.md | 9 ++++-- index.html | 2 +- server/src/routes/auth.js | 2 +- src/index.css | 58 +++++++++++++++++++++++++++++++++++++++ src/lib/theme.tsx | 2 +- src/types.ts | 3 +- 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d136722..91b03f0 100644 --- a/README.md +++ b/README.md @@ -212,9 +212,12 @@ Modell mit einer echten Anfrage. ## Themes -Sieben Farbwelten, jede in hell und dunkel, gespeichert am Benutzer +Acht Farbwelten, jede in hell und dunkel, gespeichert am Benutzer (`pulse_users.theme`, `theme_mode`) und vor dem ersten Bild gesetzt (Inline-Skript -in `index.html`). Sie kommen 1:1 aus dem perinco CRM; vier bringen Bewegung mit: +in `index.html`). Sieben kommen 1:1 aus dem perinco CRM. Das achte, **Mobile**, gibt es nur +in Pulse: perinco-Farben, aber fürs Handy rund 16 % dichter (kleineres `--spacing`, +kleinere Überschriften, niedrigere Kopfleiste), dunkel mit echtem Schwarz für OLED. +Vier Themes bringen Bewegung mit: | Theme | Bewegung | Wo | | --- | --- | --- | @@ -312,7 +315,7 @@ Aus Auftrag und Call-Mitschrift. | Einstellungen (nur Admin): SSO-Credentials, Userverwaltung, Kopf/Fuß der Exporte | ✅ inkl. PDF-/Excel-Vorschau | Einstellungen | | Arbeitsstunden pro Woche (40) | ✅ | Einstellungen → Allgemein | | Projektbezeichnungen nach Muster | ✅ | Einstellungen → Allgemein | -| Themes wie CRM (perinco, Pixel Art, Outdoor, Cyberpunk, Rainy, Snow, Aura – jeweils hell/dunkel, am Benutzer gespeichert) | ✅ | Kopfleiste | +| Themes wie CRM (perinco, Pixel Art, Outdoor, Cyberpunk, Rainy, Snow, Aura, Mobile – jeweils hell/dunkel, am Benutzer gespeichert) | ✅ | Kopfleiste | | Lokaler Admin mit vorgegebenem Passwort, später änderbar | ✅ | Mein Konto | | Mobil: eigene Ansicht bei Handy | ✅ untere Navigation, Tagesstreifen, Bottom-Sheets, schwebender Plus-Knopf | | | SSO, anfangs normaler Login; AD-User auslesen, Rollen intern | ✅ vorbereitet, noch nicht gegen echten Tenant getestet | Einstellungen → SSO | diff --git a/index.html b/index.html index 561bf2c..8dd1aea 100644 --- a/index.html +++ b/index.html @@ -40,7 +40,7 @@ var palette = localStorage.getItem('pulse_palette'); // Whitelist, damit ein manipulierter Eintrag keine Klasse setzt. - if (['pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura'].indexOf(palette) !== -1) { + if (['pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura', 'mobile'].indexOf(palette) !== -1) { document.documentElement.classList.add('theme-' + palette); } } catch (e) { diff --git a/server/src/routes/auth.js b/server/src/routes/auth.js index 905f3e1..37b9b79 100644 --- a/server/src/routes/auth.js +++ b/server/src/routes/auth.js @@ -76,7 +76,7 @@ router.patch('/me', requireAuth, async (req, res, next) => { const updates = {}; if (req.body?.theme !== undefined) { const theme = req.body.theme; - if (theme !== null && !['perinco', 'pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura'].includes(theme)) { + if (theme !== null && !['perinco', 'pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura', 'mobile'].includes(theme)) { return res.status(400).json({ error: 'Unbekanntes Design.' }); } updates.theme = theme === 'perinco' ? null : theme; diff --git a/src/index.css b/src/index.css index 67f1d31..434290b 100644 --- a/src/index.css +++ b/src/index.css @@ -997,6 +997,64 @@ html.theme-aura.dark { --shadow-lift: 0 0 0 1px rgb(170 178 240 / 0.12), 0 14px 36px rgb(0 0 0 / 0.45); } +/* =========================================================================== + * Mobile + * + * Kein eigenes Motiv, sondern mehr Inhalt auf dem Handybildschirm. Farben und + * Gruen bleiben perinco; anders ist die Dichte. + * + * Tailwind v4 rechnet jeden Abstand, jede feste Hoehe und Breite aus + * --spacing (p-4 = 4 * --spacing). Den Grundwert von 0.25rem auf 0.21rem zu + * setzen, zieht also die ganze Oberflaeche um rund 16 % zusammen, ohne dass + * eine Komponente angefasst wird. Weiter nicht: ein h-10-Knopf hat dann noch + * knapp 34 px und laesst sich mit dem Daumen sicher treffen. + * + * Verkleinert werden nur die grossen Schriften (lg bis 5xl), also Ueberschriften + * und Kennzahlen. text-sm und text-base bleiben: darunter wird es auf dem Handy + * schwer lesbar, und iOS zoomt beim Tippen in jedes Feld unter 16 px. + * + * Hell ist reines Weiss auf hellgrauem Grund, dunkel echtes Schwarz - auf + * OLED-Displays schont das den Akku. Schatten fast flach: auf kleiner Flaeche + * trennen Rahmen ruhiger als Tiefe. + * =========================================================================== */ +html.theme-mobile { + --spacing: 0.21rem; + --app-bar-height: 3.5rem; + + --text-lg: 1.0625rem; + --text-xl: 1.1875rem; + --text-2xl: 1.375rem; + --text-3xl: 1.625rem; + --text-4xl: 2rem; + --text-5xl: 2.5rem; + + --radius-sm: 0.2rem; + --radius-md: 0.3rem; + --radius-lg: 0.45rem; + --radius-xl: 0.6rem; + --radius-2xl: 0.8rem; +} + +html.theme-mobile:not(.dark) { + --color-canvas: #f2f2f2; + --color-surface: #ffffff; + + --shadow-card: 0 1px 2px rgb(31 31 31 / 0.05); + --shadow-lift: 0 6px 18px rgb(31 31 31 / 0.12); +} + +html.theme-mobile.dark { + --color-canvas: #000000; + --color-surface: #121212; + + --color-ink-50: #1a1a1a; + --color-ink-100: #242424; + --color-ink-200: #333333; + + --shadow-card: 0 0 0 1px rgb(255 255 255 / 0.04); + --shadow-lift: 0 0 0 1px rgb(255 255 255 / 0.08), 0 10px 28px rgb(0 0 0 / 0.6); +} + @layer base { :root { /* diff --git a/src/lib/theme.tsx b/src/lib/theme.tsx index c636675..6d3061c 100644 --- a/src/lib/theme.tsx +++ b/src/lib/theme.tsx @@ -18,7 +18,7 @@ import { PixelRunner } from '../components/layout/PixelRunner'; /* * Darstellung der Oberflaeche. Sie hat zwei unabhaengige Achsen: * - * Farbwelt (palette) perinco | pixel | outdoor | cyberpunk | rainy | snow | aura + * Farbwelt (palette) perinco | pixel | outdoor | cyberpunk | rainy | snow | aura | mobile * -> Klasse theme-* am * Modus (mode) hell | dunkel -> Klasse dark am * diff --git a/src/types.ts b/src/types.ts index cfa8088..b561599 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -export const THEME_PALETTES = ['perinco', 'pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura'] as const; +export const THEME_PALETTES = ['perinco', 'pixel', 'outdoor', 'cyberpunk', 'rainy', 'snow', 'aura', 'mobile'] as const; export type ThemePalette = (typeof THEME_PALETTES)[number]; export const THEME_PALETTE_LABELS: Record = { @@ -9,6 +9,7 @@ export const THEME_PALETTE_LABELS: Record