Header shows current date and time instead of user name + separate date line.
urgentCount replaced by overdueCount (overdue tasks) and dueSoonCount (due today/soon),
each with a distinct chip color. formatDueDate updated to accept due_time and return
accurate overdue/soon states against the current moment.
dashboard grid expands to 4 columns at 1280px instead of 1440px.
widgetHeader replaces <a href> with <button type="button"> so iOS Safari
does not intercept the touch event before the JS click handler fires.
widget__header gets position: relative; z-index: 2 to appear above the
backdrop-filter ::after pseudo-element stacking context.
Imports fmtLocation; renderUpcomingEvents adds event-item__cal span for
cal_name and shows location with normalized ICS escapes via fmtLocation().
Event color dot gets filter: saturate(0.4) to match calendar view style.
Page-in animations drop 'forwards' fill mode — a .page-transition base class
(opacity:0) serves as the initial state, and .page-transition--in-{left,right}
force opacity:1 after the animation ends, preventing a flash-back-to-invisible
on some WebKit versions. Sidebar expands at 1440px instead of 1280px.
Glass desktop toolbar loses the rounded card border in favour of a flat
accent-top-border + bottom border consistent with other module headers.
pwa.css safe-area padding-bottom rule and body::after fill-overlay commented out.
glass.css nav-bottom uses margin-bottom: 0 instead; --hidden state uses
translateY(100%) + negative margin so the bar disappears without leaving a gap.
layout.css removes redundant padding-bottom from .nav-bottom rule.
group-mode toggle moved before view toggle in markup order.
Filter panel, task list, and FAB wrapped in .tasks-body for scroll containment.
tasks-toolbar flex-wrap removed — actions stay on one line on narrow screens.
effectiveDue() and sortTasks() added — same logic on client (tasks.js)
and server (dashboard.js urgentTasks moved from SQL to JS sort).
Applies in list-group, Kanban, and dashboard widget views.
SQLite DATE('now') replaced with new Date() for timezone-safe due_time.
formatDueDate now accepts due_time; displays it on today/tomorrow entries.
Overdue state is computed against the current moment, not midnight, so a
task due at 09:00 is correctly marked overdue once that time has passed.
allday-cell gets min-width: 0; overflow: hidden so long event titles
no longer stretch week-view column widths beyond their grid allocation.
Agenda event color dot replaced by a 3px full-height left bar matching
the dashboard upcoming-events style (align-items: stretch on parent).
Event popup, agenda, month, week, and day views now show the external
calendar name as an event-cal-label badge. Event popup and dashboard
event list display the location via fmtLocation(). Incorrect
|| 'var(--color-accent)' fallback removed from all five rendering sites.
Sheet swipe: add 10 px dead zone before transform, reset via rAF in touchend
so iOS WebKit does not cancel subsequent click events on child buttons.
Modal close: capture active overlay before animation to prevent race where
_doClose() removes the new modal instead of the old one when a confirm dialog
opens immediately after another modal closes (delete button not responding).
- Implemented new recipes page with UI for managing recipes.
- Added REST API routes for recipes including create, read, update, and delete operations.
- Introduced database schema for recipes and recipe ingredients.
- Updated meals to link with recipes, allowing meals to reference specific recipes.
- Enhanced validation for recipe-related fields in meals.
- Added styles for the recipes page and components.
Root cause: when auth.me() failed during initial navigation, the catch block
called navigate('/login') without clearing _pendingLoginRedirect. The outer
finally then fired a second concurrent navigate('/login'), which held
isNavigating=true while running. If the user submitted the login form (or
iCloud Keychain autofilled credentials) before the second navigation
completed, navigate('/', user) was silently blocked by the isNavigating guard —
login appeared to succeed but the app never advanced to the dashboard.
Fix: clear _pendingLoginRedirect in the catch block so the finally handler
does not spawn the duplicate navigation.
Also adds a GET /api/v1/version endpoint (no auth required) and shows the
version on the login page, so users can verify their PWA has received the
latest cached JS.
Resolves#68
Co-authored-by: Ulas Kalayci <ulas.kalayci@googlemail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
On Safari/iOS PWA cold start or after cookie clear, logging in with wrong
credentials triggered auth:expired, re-rendering the login page and losing
the error message. The login endpoint returns 401 for invalid credentials,
not for session expiry, so apiFetch must not fire auth:expired in that path.
Resolves#68
Co-authored-by: Ulas Kalayci <ulas.kalayci@googlemail.com>
'Sonstiges' ist DEFAULT_CATEGORY_NAME und dient als allgemeiner Fallback für
Zutaten (Gewürze, Saucen etc.). Beim Ausschluss würde die Kategorie bestehender
Zutaten beim Bearbeiten einer Mahlzeit lautlos überschrieben (Datenintegrität).
Nur haushaltsfremde Kategorien (Haushalt, Drogerie) werden ausgeblendet.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All tokens with dark-mode overrides gain a private --_name counterpart in :root.
Public tokens (--color-*, --module-*, --glass-* etc.) become stable var(--_name)
references. Both dark blocks now only override compact private tokens — no more
manual two-block sync for every future colour change.
Also removes the redundant --color-surface-2 dark override (already auto-derived
via var(--neutral-50)). No visual change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bundles the Indigo accent migration, module-colour decoupling, WCAG
contrast improvements and nav-badge base-style relocation into one
release. See CHANGELOG.md [0.20.15] for full details.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The .nav-badge base styles (background, size, color) were defined in tasks.css,
which is dynamically unloaded when navigating away from /tasks. This caused the
overdue badge in the nav to become invisible on every other page, even though
the badge element remained in the DOM.
Also refactors subtask checkbox icon to use a CSS class instead of inline styles.
Resolves#56
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>