From 838b4c13decfd12b7bb796dc93b009de8cf4bbf2 Mon Sep 17 00:00:00 2001 From: Till JS Date: Tue, 31 Mar 2026 19:00:24 +0200 Subject: [PATCH] refactor(ui): apply elevation system across todo, contacts, calendar, clock apps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace all hardcoded hex/rgba colors with CSS custom properties throughout the todo web app and fix modal backgrounds in contacts, calendar, and clock. Removes all redundant :global(.dark) overrides — CSS vars handle both modes. - todo: TaskEditModal, SubtaskList, TagStrip, TagStripModal, SyncIndicator - todo: FokusLayout, GridLayout, KanbanLayout, ViewColumn (drop targets, add-column cards) - todo: ViewSelector, ViewColumnHeader, ViewEditorModal, TodoToolbarContent - todo: QuickAddTask, TagSelector, KanbanTaskCard, +layout (FAB) - todo: DurationPicker, StorypointsSelector, FunRatingPicker, PrioritySelector - contacts: NewContactModal background + remove Schnelleingabe quick input - calendar: EventDetailModal, VoiceRecordingModal backgrounds - clock: AuthGateModal background Co-Authored-By: Claude Sonnet 4.6 --- .../components/event/EventDetailModal.svelte | 5 +- .../voice/VoiceRecordingModal.svelte | 6 +- .../src/lib/components/AuthGateModal.svelte | 5 +- .../src/lib/components/NewContactModal.svelte | 102 +--------- .../src/lib/components/QuickAddTask.svelte | 38 +--- .../web/src/lib/components/SubtaskList.svelte | 77 +++---- .../src/lib/components/SyncIndicator.svelte | 14 +- .../web/src/lib/components/TagStrip.svelte | 62 ++---- .../src/lib/components/TagStripModal.svelte | 189 ++++-------------- .../src/lib/components/TaskEditModal.svelte | 135 ++++--------- .../lib/components/TodoToolbarContent.svelte | 13 +- .../components/board-views/FokusLayout.svelte | 30 +-- .../components/board-views/GridLayout.svelte | 18 +- .../board-views/KanbanLayout.svelte | 26 +-- .../components/board-views/ViewColumn.svelte | 16 +- .../board-views/ViewColumnHeader.svelte | 26 +-- .../board-views/ViewEditorModal.svelte | 12 +- .../board-views/ViewSelector.svelte | 27 +-- .../lib/components/form/DurationPicker.svelte | 58 ++---- .../components/form/FunRatingPicker.svelte | 14 +- .../components/form/PrioritySelector.svelte | 12 +- .../form/StorypointsSelector.svelte | 26 +-- .../lib/components/form/TagSelector.svelte | 30 +-- .../components/kanban/KanbanTaskCard.svelte | 35 +--- .../apps/web/src/routes/(app)/+layout.svelte | 24 +-- 25 files changed, 245 insertions(+), 755 deletions(-) diff --git a/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte b/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte index c61e08a4c..42f744c31 100644 --- a/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte +++ b/apps/calendar/apps/web/src/lib/components/event/EventDetailModal.svelte @@ -470,9 +470,10 @@ } .modal-container { - background: hsl(var(--color-surface)); + background: var(--color-surface-elevated-2); + border: 1px solid var(--color-border-strong); border-radius: var(--radius-lg); - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); width: 100%; max-width: 500px; max-height: 90vh; diff --git a/apps/calendar/apps/web/src/lib/components/voice/VoiceRecordingModal.svelte b/apps/calendar/apps/web/src/lib/components/voice/VoiceRecordingModal.svelte index 1e3b21d5a..6bdb147e4 100644 --- a/apps/calendar/apps/web/src/lib/components/voice/VoiceRecordingModal.svelte +++ b/apps/calendar/apps/web/src/lib/components/voice/VoiceRecordingModal.svelte @@ -146,11 +146,11 @@ left: 50%; transform: translate(-50%, -50%); z-index: 201; - background: hsl(var(--color-surface)); + background: var(--color-surface-elevated-2); border-radius: 1.5rem; box-shadow: - 0 25px 50px -12px rgba(0, 0, 0, 0.25), - 0 0 0 1px hsl(var(--color-border)); + 0 25px 50px -12px rgba(0, 0, 0, 0.5), + 0 0 0 1px var(--color-border-strong); padding: 2rem; min-width: 280px; max-width: 90vw; diff --git a/apps/clock/apps/web/src/lib/components/AuthGateModal.svelte b/apps/clock/apps/web/src/lib/components/AuthGateModal.svelte index 53f098b47..6f3c17552 100644 --- a/apps/clock/apps/web/src/lib/components/AuthGateModal.svelte +++ b/apps/clock/apps/web/src/lib/components/AuthGateModal.svelte @@ -117,9 +117,10 @@ } .modal-content { - background-color: var(--color-background, white); + background-color: var(--color-surface-elevated-2); + border: 1px solid var(--color-border-strong); border-radius: 0.75rem; - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); max-width: 28rem; width: 100%; padding: 1.5rem; diff --git a/apps/contacts/apps/web/src/lib/components/NewContactModal.svelte b/apps/contacts/apps/web/src/lib/components/NewContactModal.svelte index f5d8675dd..101ae5f1d 100644 --- a/apps/contacts/apps/web/src/lib/components/NewContactModal.svelte +++ b/apps/contacts/apps/web/src/lib/components/NewContactModal.svelte @@ -5,7 +5,6 @@ import { newContactModalStore } from '$lib/stores/new-contact-modal.svelte'; import SocialMediaFields from './forms/SocialMediaFields.svelte'; import DateFields from './forms/DateFields.svelte'; - import { parseContactInput, formatParsedContactPreview } from '$lib/utils/contact-parser'; import { findDuplicates, type DuplicateMatch } from '$lib/utils/duplicate-detector'; import { contactCollection } from '$lib/data/local-store'; import { @@ -30,7 +29,6 @@ let saving = $state(false); let error = $state(null); let firstNameInput: HTMLInputElement; - let quickInputRef: HTMLInputElement; let fileInput: HTMLInputElement; // Photo state @@ -70,50 +68,6 @@ let discord = $state(''); let bluesky = $state(''); - // ─── Quick Input (NL Parser) ─────────────────────────── - let quickInput = $state(''); - let quickPreview = $state(''); - let quickApplied = $state(false); - - function handleQuickInput(e: Event) { - const text = (e.target as HTMLInputElement).value; - quickInput = text; - quickApplied = false; - - if (!text.trim()) { - quickPreview = ''; - return; - } - - const parsed = parseContactInput(text); - quickPreview = formatParsedContactPreview(parsed); - } - - function applyQuickInput() { - if (!quickInput.trim() || quickApplied) return; - - const parsed = parseContactInput(quickInput); - - if (parsed.firstName) firstName = parsed.firstName; - if (parsed.lastName) lastName = parsed.lastName; - if (parsed.email) email = parsed.email; - if (parsed.phone) phone = parsed.phone; - if (parsed.company) company = parsed.company; - - quickApplied = true; - quickInput = ''; - quickPreview = ''; - } - - function handleQuickKeydown(e: KeyboardEvent) { - if (e.key === 'Enter') { - e.preventDefault(); - applyQuickInput(); - // Move focus to first name field - firstNameInput?.focus(); - } - } - // ─── Live Duplicate Detection ────────────────────────── let duplicates = $state([]); let dupDebounce: ReturnType | undefined; @@ -328,22 +282,6 @@