Added
- Calendar:
external_calendarsDB table (migration v14) stores display name and color per synced Google/Apple calendar;calendar_eventsgains acalendar_ref_idFK used for join-based name/color lookup in all calendar and dashboard queries - Calendar: Google and Apple sync services now fetch the calendar's display name and background color via
upsertExternalCalendar()and persist them to the new table - Calendar: event popup, agenda, month, week, and day views now show the external calendar name as a colored
event-cal-labelbadge whencal_nameis present - Calendar: event popup and dashboard events list now display the event location using
fmtLocation()which strips RFC 5545 backslash-escapes and normalizes semicolons/newlines to comma-separated inline text - Utils:
fmtLocation(raw)helper added tohtml.jsfor normalizing ICSLOCATIONproperty strings - i18n: task due-date keys (
tasks.overdue,tasks.dueSoon,tasks.dueToday,tasks.dueTomorrow,tasks.noDueDate) added to all 16 supported locale files
Changed
- Dashboard: widget headers flattened — glass card replaced with transparent surface + bottom border; clock icon added to the urgent-tasks chip; overdue and due-soon counts computed separately using
effectiveDue()for accuracy - Glass toolbar (desktop ≥ 1024 px): rounded card style replaced with flat background +
border-top: 3px solid var(--module-accent)+ bottom border only, consistent with other page toolbars - Shopping and Budget page headers:
border-top: 3px solid var(--module-accent)accent stripe added, matching the visual language of all other module headers - Calendar agenda: event color indicator changed from a 10 px circle to a 3 px full-height left bar, matching the dashboard upcoming-events style
- Tasks: filter panel now defaults to
status: 'open'on first load instead of showing all tasks including completed ones - SW cache: bumped to
oikos-shell-v50/oikos-pages-v45/oikos-assets-v45; strategy changed from Stale-While-Revalidate to Cache-First with post-update bypass window
Fixed
- Tasks / Dashboard: sort order now strictly follows effective due date ascending; overdue tasks always surface first; priority used only as tiebreaker. Server-side sort moved to JavaScript for timezone-correct
due_timehandling - Tasks: due date chip now shows the time component when
due_timeis set; overdue/soon/today/tomorrow states computed against current moment rather than midnight - Dashboard: widget navigation links changed from
<a href>to<button type="button">to prevent iOS Safari touch-event interception - Dashboard: FAB shortcut buttons now programmatically open the target page's add modal directly without requiring a second tap
- Dashboard: task items open a quick-action sheet (Edit / Mark done) instead of navigating directly
- Calendar: week-view allday row no longer stretches column widths when event titles are long
- Calendar: incorrect
|| 'var(--color-accent)'color fallback removed from all five event rendering sites - Modal: sheet swipe adds a 10 px dead zone;
touchendtransform reset deferred viarequestAnimationFrame— fixes iOS buttons not responding after a partial swipe - Modal: race condition fixed where opening a confirm dialog before the previous close animation finished caused its buttons to be permanently unresponsive
- Router: page auto-reloads 8 s after the SW-update toast is shown
- Layout: modal overlay
overflow: hidden; form inputs getmin-width: 0; box-sizing: border-boxto prevent overflow in two-column grid containers - PWA: double
padding-bottomon PWA bottom nav removed, fixing extra gap on iPhone safe-area screens - Reminders: field grid changed to
repeat(2, minmax(0, 1fr))to prevent content overflow