- modal/_validateField: set aria-invalid on invalid inputs so screen readers
announce field errors; login.js mirrors this for username/password fields
- color pickers (notes, calendar): wrap swatches in role="radiogroup" with
aria-labelledby, add aria-checked per swatch, localized aria-labels instead
of hex values, roving tabindex with Arrow/Enter/Space keyboard navigation
- nav badges: badge spans get aria-hidden="true"; nav link aria-label updated
to include overdue count (tasks) or pending reminder count (reminders)
- router: remove aria-live from <main> (caused full page re-reads on nav);
add dedicated #route-announcer sr-only region with aria-live=polite +
aria-atomic, announces page label 50ms after render completes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract shared esc() utility (public/utils/html.js) replacing 8
duplicate escHtml() functions across all page modules
- Apply HTML escaping to all user-controlled data in innerHTML
templates: titles, names, locations, descriptions, colors, notes
content, weather data, autocomplete suggestions
- Remove user-scalable=no and maximum-scale=1 from viewport meta
tag, restoring pinch-to-zoom for WCAG 1.4.4 compliance
- Bump version to 0.7.1
- 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>
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>
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>
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>
- 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>
- 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>
- connect-sqlite3 durch eigenen BetterSQLiteStore ersetzt (sessions-Tabelle
in der bestehenden DB, keine native Kompilierung nötig)
- db.init() vor require('./auth') gezogen damit BetterSQLiteStore-Konstruktor
db.get() erfolgreich aufrufen kann
- router.js: App-Shell und pageWrapper vor module.render() in DOM einfügen
damit document.getElementById() in Seiten-Modulen funktioniert
- Seiten-Module (meals, notes, contacts, calendar, budget): _container-Referenz
eingeführt, alle document.getElementById() auf _container.querySelector() bzw.
document.querySelector() für body-Elemente umgestellt
- login.js: User-Objekt nach erfolgreichem Login an navigate() übergeben
damit auth.me()-Roundtrip entfällt
- calendar.js: /users → /auth/users korrigiert (404-Fix)
- SW-Cache v8 (erzwingt Reload aller gecachten Seiten-Module)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>