From d27216203f96417cbf541196363a84b3dae060d2 Mon Sep 17 00:00:00 2001 From: Ulas Date: Mon, 13 Apr 2026 17:05:19 +0200 Subject: [PATCH] feat: Phase 2 - Glass Modul-Komponenten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit glass.css - Phase 2 Ergänzungen: Form-Inputs: - Glass-Border (--glass-border-subtle) + verbesserter Focus-Ring mit color-mix-basiertem Glow statt einfacher box-shadow - Modal-Inputs: explizit --color-surface-2 als Hintergrund Sticky Headers: - backdrop-filter auf --blur-sm + saturate(160%) mit Glass-Tokens - Hintergrund 80% opak statt 90% für mehr sichtbaren Blur-Effekt - Glass-Border unten Toasts: - --radius-glass-card (20px) statt --radius-sm - Standard-Toast: Dark-Glass mit backdrop-filter - Farbige Toasts: specular inset-highlight Filter-Chips: - Inaktiv: --glass-border-subtle - Aktiv: Glass backdrop-filter + Accent-Tint + specular highlight Priority Badges: - Capsule-Radius (--radius-glass-chip) - 1px semi-transparente Farb-Border Toggle Switch: - Specular Highlight + Gegenlicht auf Thumb via inset box-shadow - Animation verwendet --transition-glass Easing Dashboard Widgets: - Glass-Border + --glass-shadow-sm - Specular ::before Highlight-Linie oben FAB-Backdrop (Dashboard): - blur(4px) + 18% Dimming statt 25% contacts.css, notes.css, shopping.css: - Search-Inputs direkt auf Glass-Tokens migriert (--radius-glass-button, --glass-border-subtle, Glass-Focus-Ring) --- public/styles/contacts.css | 7 +- public/styles/glass.css | 220 +++++++++++++++++++++++++++++++++++++ public/styles/notes.css | 11 +- public/styles/shopping.css | 7 +- 4 files changed, 234 insertions(+), 11 deletions(-) diff --git a/public/styles/contacts.css b/public/styles/contacts.css index 2a7a56f..6fae55b 100644 --- a/public/styles/contacts.css +++ b/public/styles/contacts.css @@ -58,12 +58,12 @@ .contacts-toolbar__search-input { width: 100%; padding: var(--space-2) var(--space-3) var(--space-2) 36px; - border-radius: var(--radius-sm); - border: 1.5px solid var(--color-border); + border-radius: var(--radius-glass-button); + border: 1.5px solid var(--glass-border-subtle); background-color: var(--color-surface-2); color: var(--color-text-primary); font-size: var(--text-md); - transition: border-color var(--transition-fast); + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); min-height: 36px; } @@ -71,6 +71,7 @@ outline: none; border-color: var(--color-accent); background-color: var(--color-surface); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent); } @media (min-width: 1024px) { diff --git a/public/styles/glass.css b/public/styles/glass.css index c0486d6..350d48d 100644 --- a/public/styles/glass.css +++ b/public/styles/glass.css @@ -220,3 +220,223 @@ transition-duration: 0.01ms !important; } } + +/* ================================================================ + * PHASE 2 — Modul-Komponenten + * ================================================================ */ + +/* ================================================================ + * 8. Form-Inputs — Glass Border + verbesserter Focus-Ring + * + * Kein backdrop-filter auf Inputs (würde Inhalte hinter dem Input + * in Modals unattraktiv unscharf rendern). Stattdessen: subtile + * Glass-Border + abgestufter Focus-Glow via CSS-Shadow. + * ================================================================ */ +.input, +.form-input, +select.form-input, +textarea.form-input { + border-color: var(--glass-border-subtle); + background-color: color-mix(in srgb, var(--color-surface) 95%, transparent); +} + +.input:focus, +.form-input:focus { + border-color: var(--color-accent); + box-shadow: + 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent), + inset 0 1px 2px rgba(0, 0, 0, 0.04); +} + +/* ================================================================ + * 9. Sticky Header — Glass-Token-Upgrade + * + * Bestehender backdrop-filter (blur(12px)) in layout.css wird auf + * --glass-* Tokens umgestellt. Hintergrund transparenter machen + * damit der Blur-Effekt besser sichtbar ist. + * ================================================================ */ +@supports (backdrop-filter: blur(1px)) { + .sticky-header { + background-color: color-mix(in srgb, var(--color-bg) 80%, transparent); + backdrop-filter: var(--blur-sm) saturate(160%); + -webkit-backdrop-filter: var(--blur-sm) saturate(160%); + border-bottom: 1px solid var(--glass-border-subtle); + } +} + +/* ================================================================ + * 10. Toasts — Glass + Capsule + * + * Standard-Toast: Dark-Glass (neutrales --neutral-800 bleibt als + * Fallback). Farbige Toasts (success/danger/warning) bekommen nur + * den Capsule-Radius. + * ================================================================ */ +.toast { + border-radius: var(--radius-glass-card); + box-shadow: var(--glass-shadow-md); +} + +@supports (backdrop-filter: blur(1px)) { + .toast:not(.toast--success):not(.toast--danger):not(.toast--warning) { + background-color: color-mix(in srgb, var(--neutral-800) 90%, transparent); + backdrop-filter: var(--blur-sm); + -webkit-backdrop-filter: var(--blur-sm); + border: 1px solid rgba(255, 255, 255, 0.10); + } +} + +/* Farbige Toasts: nur Capsule + specular, kein Blur */ +.toast--success, +.toast--danger, +.toast--warning { + border-radius: var(--radius-glass-card); + box-shadow: + var(--glass-shadow-md), + inset 0 1px 0 rgba(255, 255, 255, 0.18); +} + +/* ================================================================ + * 11. Filter-Chips — Glass Active State + * + * Inaktiver Chip: glass border (subtil). + * Aktiver Chip: voller Glass-Pip mit backdrop-filter + Accent-Tint. + * ================================================================ */ +.filter-chip { + border-color: var(--glass-border-subtle); +} + +.filter-chip:hover:not(.filter-chip--active) { + border-color: var(--glass-border); + background-color: color-mix(in srgb, var(--color-text-tertiary) 8%, transparent); +} + +@supports (backdrop-filter: blur(1px)) { + .filter-chip--active { + background: color-mix(in srgb, var(--color-accent) 18%, transparent); + backdrop-filter: var(--blur-xs); + -webkit-backdrop-filter: var(--blur-xs); + border-color: color-mix(in srgb, var(--color-accent) 50%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.20); + } +} + +/* ================================================================ + * 12. Priority Badges — Capsule Radius + Glass Border + * + * Upgradet --radius-xs auf --radius-glass-chip (capsule) für einen + * moderneren Look. Behält semantic colors bei. + * ================================================================ */ +.priority-badge { + border-radius: var(--radius-glass-chip); + border: 1px solid color-mix(in srgb, currentColor 25%, transparent); +} + +/* Nav-Badge (Overdue-Indikator) */ +.nav-badge { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.20); +} + +/* ================================================================ + * 13. Toggle-Switch — Specular Thumb + * + * Der weiße Thumb bekommt einen subtilen inset-Schatten der eine + * Specular-Highlight-Illusion erzeugt (Lichtquelle von oben-rechts). + * Die Animation verwendet bereits --ease-glass cubic-bezier. + * ================================================================ */ +.toggle__track::after { + box-shadow: + var(--shadow-sm), + inset 0 1px 0 rgba(255, 255, 255, 0.90), + inset 0 -1px 0 rgba(0, 0, 0, 0.08); +} + +.toggle input:checked + .toggle__track::after { + transition: transform var(--transition-glass); +} + +/* ================================================================ + * 14. Dashboard-Widgets — Glass Cards + * + * .widget bekommt eine leichte Glass-Behandlung: + * Stärkere Border, subtiles Highlight oben. + * Kein backdrop-filter (Widgets sind über normalem Seitenhintergrund, + * kein dramatischer Tiefeneffekt nötig). + * ================================================================ */ +.widget { + border: 1px solid var(--glass-border-subtle); + box-shadow: var(--glass-shadow-sm); +} + +.widget::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 1px; + background: var(--glass-highlight-subtle); + border-radius: var(--radius-md) var(--radius-md) 0 0; + pointer-events: none; +} + +/* Relative-Positionierung für ::before */ +.widget { + position: relative; +} + +/* ================================================================ + * 15. FAB-Backdrop (Dashboard) — Glass Blur + * + * Der Overlay-Hintergrund beim Dashboard-FAB-Menü bekommt einen + * dezenten Blur-Effekt für mehr Tiefe. + * ================================================================ */ +@supports (backdrop-filter: blur(1px)) { + .fab-backdrop--visible { + backdrop-filter: var(--blur-xs); + -webkit-backdrop-filter: var(--blur-xs); + background: rgba(0, 0, 0, 0.18); + } +} + +/* ================================================================ + * 16. Search-Inputs (Modul-Toolbars) + * + * Modul-CSS wird on-demand nach glass.css geladen. Glass-Styles für + * modul-spezifische Search-Inputs stehen daher in den jeweiligen + * Modul-CSS-Dateien (contacts.css, notes.css, shopping.css). + * Hier werden nur token-basierte Fallback-Regeln für generische Inputs + * innerhalb von Modals definiert (via .modal-panel .form-input). + * ================================================================ */ +.modal-panel .form-input, +.modal-panel .input { + background-color: var(--color-surface-2); +} + +/* ================================================================ + * 17. Accessibility — Phase 2 Overrides + * ================================================================ */ +@media (prefers-reduced-transparency: reduce) { + .filter-chip--active, + .toast:not(.toast--success):not(.toast--danger):not(.toast--warning) { + background-color: var(--color-accent-light); + border-color: var(--color-accent); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } + + .sticky-header { + background-color: var(--color-bg); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +} + +@media (prefers-reduced-motion: reduce) { + .toggle__track::after { + transition: none; + } + + .toast { + animation-duration: 0.01ms !important; + } +} diff --git a/public/styles/notes.css b/public/styles/notes.css index 7eaa417..c683d8d 100644 --- a/public/styles/notes.css +++ b/public/styles/notes.css @@ -65,17 +65,18 @@ .notes-toolbar__search-input { width: 100%; padding: var(--space-2) var(--space-2) var(--space-2) calc(var(--space-2) * 2 + 16px); - border: 1px solid var(--color-border); - border-radius: var(--radius-md); + border: 1px solid var(--glass-border-subtle); + border-radius: var(--radius-glass-button); background: var(--color-surface); color: var(--color-text-primary); font-size: var(--text-md); - outline-offset: 2px; + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); } .notes-toolbar__search-input:focus { - outline: 2px solid var(--color-accent); - border-color: transparent; + outline: none; + border-color: var(--color-accent); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent); } @media (min-width: 1024px) { diff --git a/public/styles/shopping.css b/public/styles/shopping.css index ba00e95..35d0d85 100644 --- a/public/styles/shopping.css +++ b/public/styles/shopping.css @@ -166,18 +166,19 @@ width: 100%; padding: var(--space-3) var(--space-4); padding-right: var(--space-20, 80px); - border-radius: var(--radius-sm); - border: 1.5px solid var(--color-border); + border-radius: var(--radius-glass-button); + border: 1.5px solid var(--glass-border-subtle); background-color: var(--color-surface); color: var(--color-text-primary); font-size: var(--text-md); - transition: border-color var(--transition-fast); + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); min-height: 44px; } .quick-add__input:focus { outline: none; border-color: var(--color-accent); + box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent); } .quick-add__qty {