Commit Graph

75 Commits

Author SHA1 Message Date
Ulas 82e5b2cd85 feat(budget): auto-generate recurring entry instances per month
Adds schema migration v3 (recurrence_parent_id column + budget_recurrence_skipped
table). On every GET /api/v1/budget, the server checks all recurring originals
(is_recurring=1, no parent) and creates missing instances for the requested month
using the same day-of-month (clamped to the last day). Deleted instances are
recorded in budget_recurrence_skipped so they are not recreated on the next visit.
Generated instances are shown with a ↩ indicator in the transaction list.

Closes BL-05.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 10:13:37 +02:00
Ulas 26d3d12a22 feat(budget): add month-over-month comparison to summary cards
Each summary card (Einnahmen, Ausgaben, Saldo) now shows a trend line
comparing the current month to the previous one. The previous month's
summary is fetched in parallel via the existing /budget/summary endpoint,
so there is no extra round-trip latency. Positive deltas render in green
(▲), negative in red (▼), unchanged in neutral grey (—).

Closes BL-02.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:54:04 +02:00
Ulas 3e25339c86 fix: resolve event-listener leaks and CSS gaps found in code quality audit
- notes.js (Critical): move grid click listener from renderGrid() to
  render() — was re-registered on every save/pin/delete, causing
  multiple API calls per user action after several interactions
- dashboard.js (Major): introduce AbortController (_fabController) so
  the anonymous document click listener from initFab() is cancelled on
  each new render() cycle; also remove the redundant initFab() call on
  the skeleton render
- layout.css (Major): extend .label selector to include .form-label,
  covering usage in notes.js and settings.js without a mass-rename
- test-modal-utils.js (Major): 12 unit tests for wireBlurValidation,
  btnSuccess, btnError; registered as test:modal-utils in package.json
- notes.js (Minor): add btnError() shake feedback to save error handler
- calendar.js (Minor): add popup.isConnected guard to closePopup so
  the listener self-removes correctly after navigation without a click

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:26:49 +02:00
Ulas 36de5fa477 feat: merge UX polish v0.2.0 (14 tasks, 4 layers) 2026-03-30 22:02:03 +02:00
Ulas 0ac2769fac feat: blur-triggered inline validation and submit button feedback
Task 13: wireBlurValidation() activates error/valid state on required
fields after blur. Task 14: btnSuccess() shows a checkmark for 700ms
then closes the modal; btnError() triggers a shake animation on failure.
Both wired into the tasks form submit handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:22:36 +02:00
Ulas 1684215da8 feat: bottom sheet modal on mobile with swipe-to-close and Enter-key form navigation
- Add sheet drag handle (::before pseudo-element) and closing animation (sheet-out keyframe) for mobile < 768px in layout.css
- Add prefers-reduced-motion support disabling all modal animations
- Refactor closeModal() to extract _doClose() and play slide-out animation on mobile before removing the overlay
- Add _wireSheetSwipe() for touch drag-to-dismiss (threshold 80px)
- Extend trapFocus() Enter handler: advances focus through inputs/selects and triggers primary button on last field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:19:25 +02:00
Ulas b9ec36611d feat: consistent vibration feedback via vibrate() utility across modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:18:44 +02:00
Ulas 499ce2cd29 feat: delay install prompt, reset counter on dismiss, scroll inputs into view
- Install prompt now waits for 2 interactions before showing
- Dismiss duration reduced from 30d to 7d
- Interaction counter reset on dismiss (clean slate after 7d)
- Virtual keyboard: focused inputs scroll into view in modals (300ms delay)
2026-03-30 21:16:36 +02:00
Ulas e3e0b8081b feat: scroll focused inputs into view on virtual keyboard open 2026-03-30 17:31:09 +02:00
Ulas 4eacba2edd feat: delay install prompt until 2 interactions, reduce dismiss to 7 days
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:30:05 +02:00
Ulas 168cd387b4 fix: remove stale .meals-empty CSS, add .meal-slot--empty rule 2026-03-30 17:28:04 +02:00
Ulas 0eab480a0e style: unify all empty states to shared .empty-state class across all modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:25:13 +02:00
Ulas eb0ac95e1d fix: scope stagger selector to #budget-list in budget.js 2026-03-30 17:21:53 +02:00
Ulas bc6e759b79 feat: staggered fade-in for list items across all modules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:19:33 +02:00
Ulas f4eb567219 feat: add stagger() and vibrate() UX utilities with tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:14:15 +02:00
Ulas 20792e9894 fix: sync ROUTE_ORDER with nav order, guard against navigation race condition
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:11:53 +02:00
Ulas bc3f855fa9 feat: directional slide-x page transitions in router
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:08:49 +02:00
Ulas 0dbea82a22 fix: wire page-fab and fab-main to module-accent token 2026-03-30 17:02:05 +02:00
Ulas 194728bbe9 style: tie FAB colors to per-module accent tokens
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 16:55:33 +02:00
Ulas 624f3ab763 style: unify card padding to 16px across all modules 2026-03-30 16:43:05 +02:00
Ulas d1bbc9c8bb Fix inconsistent text alignment in meal cards
Force left-alignment at every level: meal-slot container, meal-card,
title, meta, and actions. Use align-self: stretch and explicit
text-align: left to prevent any parent from overriding alignment.
Left-aligned text is the correct UX choice for small scannable cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 16:20:12 +02:00
Ulas d3becbcf13 Remove global min-size touch target rule from pwa.css
The blanket 44px min-height/min-width on all buttons, links, and
checkboxes conflicted with the existing token-based touch target
system (--target-sm/md/lg + ::before pseudo-element expansion).
This caused oversized checkboxes in calendar (all-day toggle),
budget (recurring), and other form controls across all modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:57:33 +02:00
Ulas 26a42d001b Fix oversized task checkboxes and inconsistent meal text alignment
Exclude small buttons (task checkboxes, action buttons, color swatches)
from the 44px min-size rule in pwa.css — they already expand touch area
via ::before pseudo-elements. Force consistent left-alignment on meal
card titles, ingredients, and type labels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:51:28 +02:00
Ulas 41e88e0acf Add PWA native feel: manifest, meta tags, install prompt, SW optimization, dynamic theme-color
Configure manifest.json with scope, maskable icons, and categories. Add iOS/Android
meta tags for standalone behavior. Create pwa.css for native touch/scroll handling
and safe area insets. Add oikos-install-prompt Web Component with Chrome install
flow and iOS guidance. Optimize service worker with network-first navigation and
expanded precache (v19). Add dynamic theme-color per route and modal overlay dimming
in standalone mode. Generate placeholder icons via sharp script.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 15:35:01 +02:00
Ulas 8e01d4c749 Add theme-adaptive screenshots to README and fix manifest icons
Replace old screenshots with new mobile/tablet variants in light and dark
mode. README now uses <picture> elements with prefers-color-scheme so
screenshots automatically match the viewer's GitHub theme. Split manifest
icon purpose field into separate "any" and "maskable" entries per PWA spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 00:42:24 +01:00
Ulas cb8b108d3c fix: Notizen-Toolbar erweitert + Essen-Widget 2×2-Grid auf Desktop
Pinnwand: Pflichtfeld-Stern entfernt, Markdown-Hinweis ergänzt,
Formatierungs-Toolbar um Unterstreichen, Durchgestrichen, Überschrift,
nummerierte Liste, Checkliste, Link, Code, Zitat und Trennlinie erweitert.
Dashboard: Essen-Widget nutzt ab Desktop 2×2-Layout statt 4×1 für
bessere Lesbarkeit der Mahlzeiten-Labels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 15:31:50 +01:00
Ulas 2f0b0c05ec feat: Notizen — automatische Textkontrastfarbe + Formatierungs-Toolbar
Kontrastproblem: Titel, Inhalt und Footer-Elemente der Notizkarten
überschrieben die Inline-Textfarbe mit festen Token-Werten. Jetzt
erben alle Elemente die adaptiv berechnete Farbe (dunkel auf hellen
Karten, hell auf dunklen).

Formatierungs-Toolbar: Fett, Kursiv und Liste als Buttons über dem
Textfeld im Editor. Fügt Markdown-Syntax ein, unterstützt Selektion
und Tastaturkürzel (Strg+B, Strg+I). Markdown-Rendering bleibt
unverändert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 09:05:28 +01:00
Ulas cacec64777 fix: Dashboard-Widgets zeigen jetzt alle offenen Aufgaben und neueste Notizen
Aufgaben-Widget zeigte nur high/urgent Tasks mit Fälligkeit ≤48h,
Pinnwand-Widget nur explizit gepinnte Notizen. Neue Einträge waren
dadurch im Dashboard unsichtbar.

- Aufgaben: alle offenen Tasks (sortiert nach Priorität), Limit 5
- Notizen: neueste 3 (gepinnte zuerst, dann nach Aktualisierung)
- Greeting-Chip zählt weiterhin nur high/urgent Tasks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 23:30:00 +01:00
Ulas 31b9760bc3 fix: SW-Cache-Version bumpen + fetch cache:no-store für API-Aufrufe
Dashboard-Widgets aktualisierten nicht, weil der Service Worker die
alte router.js aus dem Cache servierte (stale-while-revalidate).
Cache-Version v15→v16 erzwingt Invalidierung aller gecachten Dateien.
Zusätzlich fetch cache:no-store auf allen API-Aufrufen als Absicherung.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 23:24:11 +01:00
Ulas a7214f81e6 fix: 4 Bugs behoben — Dark-Mode Inputs, Essensplan, Dashboard-Refresh, Mengenfeld
1. Dark Mode: .form-input hatte kein Styling, Browser-Default führte zu
   weißem Text auf weißem Hintergrund. Jetzt mit .input zusammengefasst.
2. Essensplan: DATE_RE fehlte im Import (ReferenceError), db.transaction()
   wurde doppelt aufgerufen (3 Stellen).
3. Dashboard: Router-Guard verhinderte Re-Render bei Rücknavigation,
   Widgets zeigten veraltete Daten.
4. Einkaufsliste: Mengenfeld hatte abweichende Hintergrundfarbe und
   überdimensionierte min-height.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 23:13:15 +01:00
Ulas d69c5a0413 feat: Wetter-Widget responsive über volle Breite im Desktop-Dashboard
Auf Desktop wird das Wetter-Widget über allen anderen Widgets platziert
mit horizontalem Layout (aktuelles Wetter links, Vorhersage rechts).
Vorhersagezeitraum skaliert mit Bildschirmbreite: 3 Tage (Mobil),
4 Tage (Tablet), 5 Tage (Desktop/Wide).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 15:20:55 +01:00
ulsklyc e4760473a7 fix: Login-Seite zentriert + Hero-Bereich mit Tagline über dem Formular
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 14:29:31 +01:00
ulsklyc 5a2e2d3c48 a11y: prefers-reduced-motion Fix (Redesign Phase H)
- animation-duration/transition-duration: 0.01ms → 0s (kein Flicker)
- animation-delay: 0s hinzugefügt
- animation-iteration-count entfernt (unnötig bei duration 0s)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:51:58 +01:00
ulsklyc 4cd3299f38 a11y: --text-2xs Token entfernt, 12px Minimum (Redesign Phase G)
- --text-2xs (11px) aus tokens.css gelöscht
- Alle 8 Referenzen → --text-xs (12px) migriert:
  Nav-Labels, Badges, Event-Time, Meal-Slots, Avatare
- 12px Mindestgröße für alle sichtbaren Texte (Mobile-PWA-Lesbarkeit)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:50:31 +01:00
ulsklyc d5a0e701b0 a11y: aria-hidden auf allen Icons + aria-label auf icon-only Buttons (Redesign Phase F)
- Alle data-lucide Icons: aria-hidden="true" (dekorativ)
- Icon-only Buttons/Links: title→aria-label (Screenreader-zugänglich)
- Betrifft: modal.js, contacts, meals, budget, calendar, notes, tasks,
  shopping, dashboard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:48:23 +01:00
ulsklyc 152246185e a11y: Touch-Target System mit Token-basierter Sizing (Redesign Phase E)
- Neue Tokens: --target-sm (32px), --target-md (40px), --target-lg (48px)
- Globale min-height:44px Regel aus reset.css entfernt
- Alle 28 min-height:unset Overrides eliminiert
- Strategy A: Buttons, Nav-Items, Inputs → 48px mobile, 40px desktop
- Strategy B: Kleine Elemente (Checkboxen, Swatches, Delete-Buttons)
  → ::before Pseudo-Element expandiert Touch-Area auf 48×48px

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:43:12 +01:00
ulsklyc 73cd322a71 a11y: Skip-Link für Keyboard-Navigation (Redesign Phase D)
- Skip-Link "Zum Inhalt springen" als erstes Element im App-Shell
- .sr-only:focus-visible CSS: sichtbar bei Tab-Focus, fixed top-left

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 13:37:07 +01:00
ulsklyc 3e63a7086d a11y: add h1 headings to all pages (Redesign Phase B)
Every page now has exactly one <h1> per spec §2.3.
Six pages use sr-only <h1>; notes uses visible <h1> in toolbar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:30:29 +01:00
ulsklyc c796d3ad6f feat: migrate remaining 5 modules to shared modal system
Migrate budget, contacts, notes, meals, calendar to use the shared
openModal/closeModal from components/modal.js. Each module now gets
focus-trap, escape-handler, overlay-click, focus-restore, scroll-lock.

Removed ~460 lines of duplicate modal CSS (.budget-modal-overlay,
.contact-modal-overlay, .note-modal-overlay, .meal-modal-overlay,
.event-modal-overlay and their children). Content-specific styles
(color-picker, autocomplete, ingredient-list, etc.) are preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:22:21 +01:00
ulsklyc 7e718e2422 feat: shared modal system + migrate tasks module
- Add public/components/modal.js with focus-trap, escape-handler,
  overlay-click, focus-restore, scroll-lock, aria-modal (Spec §5.1/§5.2)
- Migrate tasks.js from custom modal to shared openModal/closeModal API
- Remove .modal-backdrop/.modal/.modal__* styles from tasks.css
- Add .modal-panel--sm/--lg sizing variants to layout.css

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 12:04:57 +01:00
ulsklyc b51177b5e3 fix: WCAG AA color compliance (Redesign Phase A)
- Accent colors: #3478F6 → #2563EB (5.17:1), dark mode → #60A5FA
- Semantic colors: success #15803D, warning #B45309, danger #DC2626
- Text tertiary: #737370 (4.76:1), dark #A3A3A0
- Module calendar dark: #A78BFA (5.28:1)
- Greeting gradient: #1D4ED8 → #2563EB (both ≥ 4.5:1)
- Theme-color harmonized to #2563EB across meta/manifest/tokens
- --text-2xs: 0.625rem → 0.6875rem (11px)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 11:58:00 +01:00
ulsklyc e19df38e89 fix: Notizen-Leerstate zentrieren + FAB auf Desktop und Mobile einheitlich
- notes-empty: column-span:all für korrekte Zentrierung im Multicolumn-Layout
- Inline-Style grid-column entfernt (wirkte nicht bei CSS columns)
- FAB jetzt auch auf Desktop sichtbar (48px, unten rechts)
- Toolbar-"Neu"-Buttons auf allen Breakpoints versteckt — FAB ist einziger
  Erstellen-Button, kein Design-Bruch mehr zwischen Mobile und Desktop
- Service Worker Cache v15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 08:02:11 +01:00
ulsklyc c8c39930b5 feat: FAB auch auf der Einkaufsseite hinzufügen
- Blauer Plus-FAB unten rechts auf Mobile
- Fokussiert das Quick-Add-Eingabefeld und scrollt es ins Sichtfeld
- Erstellt eine neue Liste, wenn noch keine vorhanden ist
- Service Worker Cache v14

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:23:15 +01:00
ulsklyc b115b644c7 feat: FAB (Floating Action Button) auf allen Unterseiten für Mobile
- Einheitlicher blauer Plus-Button unten rechts auf Mobile (tasks, calendar,
  notes, contacts, budget) — konsistent mit Dashboard-FAB
- Toolbar-"Neu"-Buttons auf Mobile versteckt, auf Desktop weiterhin sichtbar
- Wiederverwendbare .page-fab CSS-Klasse in layout.css
- Dashboard-FAB Position an neue Nav-Höhe angepasst
- Service Worker Cache v13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:09:15 +01:00
ulsklyc a2adb2b94c feat: Mobile Bottom-Navigation mit Swipe und Dot-Indikator
- Alle 9 Menüpunkte jetzt auf Mobile erreichbar (2 Seiten)
- Horizontaler Scroll-Snap für seitenweises Swipen
- Dezente Dot-Indikatoren zeigen aktive Seite an
- Automatischer Scroll zur richtigen Seite bei Navigation zu Seite-2-Items
- Service Worker Cache v12

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 07:02:17 +01:00
ulsklyc 2e3e67baeb fix: Error Handling in Backend und Frontend verbessern (Phase 5, Schritt 31)
- Backend: JSON-Parse-Error + Payload-Too-Large Middleware in index.js
- Backend: Dashboard äußerer try/catch für db.get()-Fehler
- Backend: contacts/meta Route mit try/catch
- Frontend: try/catch + Toast-Fallback in loadMonth (budget), loadRange (calendar),
  loadWeek (meals), loadLists/switchList (shopping), initiales Laden (notes)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 00:35:16 +01:00
ulsklyc f507ef8488 feat: Dark Mode Toggle + RRULE UI für wiederkehrende Aufgaben/Termine
Dark Mode: Manueller Theme-Switch (System/Hell/Dunkel) in Einstellungen
mit localStorage-Persistenz und Flash-Prevention via data-theme Attribut.

RRULE UI: Wiederholungs-Formular in Aufgaben- und Kalender-Modals mit
Frequenz (Täglich/Wöchentlich/Monatlich), Intervall, Wochentag-Auswahl
und optionalem Enddatum. Backend-Routen für is_recurring/recurrence_rule
in POST/PUT erweitert. Repeat-Icon auf wiederkehrenden Einträgen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 00:11:45 +01:00
ulsklyc 520b8eb11a fix: HSTS/CSP für lokale HTTP-Entwicklung deaktivieren + SW-Cache v10
- helmet: upgrade-insecure-requests und HSTS nur bei SESSION_SECURE=true
- Service Worker Cache-Version auf v10 hochgezählt
- Debug-Code aus router.js entfernt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 23:50:47 +01:00
ulsklyc 76165da592 design: Frontend-Redesign v2 — Design-System, kompaktere UI, Mikrointeraktionen
Umfassendes Redesign des gesamten Frontends in 9 Schritten:

1. Design-Tokens: Neutral-Farbskala (50–950), Modul-Akzentfarben,
   --text-2xs Token, Easing-Kurven, Z-Index-System, Dark-Mode-Overrides
2. Reset: Reduced-motion Query (prefers-reduced-motion)
3. Sidebar/Navigation: Flaches Design, Glassmorphismus Bottom-Nav,
   Akzentstreifen-Indikator, collapsed/expanded States
4. Layout-Grid: Master-Detail, Content-Aside, Sticky-Header-Primitives
5. Cards/Container: Einheitliches Card-Pattern, Modal-System (Bottom-Sheet
   mobil, zentriert Desktop), Skeleton-Loading, Empty-States
6. Dashboard: Kompaktere Widgets, Token-basierte Farben/Schatten,
   4-Spalten-Grid ab 1440px
7. Module: Mobile-first Kanban/Day-Slots/Budget-Summary, border-subtle
   für sekundäre Trennlinien, responsive Quick-Add, Token-Migration
   aller hardcoded px/rgba-Werte
8. Mikrointeraktionen: Page-out Fade, Checkbox-Pop-Animation,
   Hover-States für Filter/Tabs/Toggles, Toast-Ausblendung,
   done-State Opacity-Transition
9. Feinschliff: Print-Styles, --text-2xs Token für Micro-Labels,
   Konsistenz-Audit (alle 9/10/11px → Token)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:46:45 +01:00
ulsklyc 1bea4f1428 fix: Sidebar-Menüpunkte kompakter + Tiefeneffekte stark reduziert
- padding 6px statt space-3/space-2, min-height entfernt
- Hover: box-shadow 2px statt 4px (kaum sichtbar, subtil)
- Aktiv: inset 1px statt 3px (ganz leicht gedrückt)
- border-radius xs statt sm (weniger klobig)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 14:27:10 +01:00