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.
Google and Apple sync services now fetch calendar metadata and persist it via
upsertExternalCalendar(). The /calendar and /upcoming endpoints JOIN on
external_calendars to return cal_name and cal_color with every event.
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.
POST /api/v1/auth/setup — unauthenticated, only succeeds when the
users table is empty. Enables first-admin creation via HTTP for
Docker deployments without shell access to the container volume.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
- Add CRUD routes for /subscriptions (GET, POST, PATCH, DELETE)
- Add manual sync trigger: POST /subscriptions/:id/sync
- Add ICS visibility filter to GET /calendar (private vs. shared)
- Set user_modified=1 on PUT /:id for ICS events
- Add POST /:id/reset to clear user_modified on ICS events
- Wire icsSubscription.sync() into runSync() in server/index.js