# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ## [0.23.17] - 2026-04-25 ### Fixed - Italian (it) locale: translated all missing strings in the recipes section (`nav.recipes`, `meals.savedRecipeLabel`, `meals.savedRecipePlaceholder`, `meals.saveAsRecipe`, `meals.recipeScaleLabel`, and all `recipes.*` keys) — contributed by @albanobattistella ## [0.23.16] - 2026-04-24 ### Changed - Design tokens: replaced all remaining hardcoded color and size values in `layout.css`, `glass.css`, `dashboard.css`, and `reminders.css` with CSS custom properties - Design tokens: added `--text-2xs`, `--color-overlay-glass`, `--color-backdrop-glass`, `--glass-border-overlay`, `--glass-highlight-mid`, `--glass-inset-bottom-base`, `--glass-inset-bottom-hover`, `--glass-inset-thumb`, and `--glass-inset-input` to `tokens.css` ## [0.23.15] - 2026-04-24 ### Fixed - All non-German locales (ar, el, en, es, fr, hi, it, ja, pt, ru, sv, tr, uk, zh): added missing translation keys for `nav.more`, `calendar.ics.reset/resetToast`, `settings.ics.*`, `tasks.filter*`, `tasks.swiped*`, `search.*`, and `reminders.*` — these were falling back to German strings for all non-German users ## [0.23.14] - 2026-04-23 ### Fixed - Swedish (sv) locale: corrected five translation errors in the recipes section (`titleRequired`, `copySuffix`, `urlLabel`, `openLink`, `emptyDescription`) — contributed by @olsson82 ## [0.23.13] - 2026-04-22 ### Security - Installer: replaced template-literal URL construction with the `URL` constructor when setting the final "Open Oikos" link, eliminating a potential DOM-based XSS vector (CodeQL js/xss-through-dom, GitHub Advisory #7) ## [0.23.12] - 2026-04-22 ### Fixed - iOS PWA: bottom navigation bar gap resolved by removing `overflow: hidden` from `` (iOS Safari bug: this property clips `position: fixed` descendants) and restoring the `body::after` fill approach; nav bar height is no longer inflated by the safe area padding ## [0.23.11] - 2026-04-22 ### Fixed - iOS PWA: bottom navigation bar now extends into the home indicator safe area via `padding-bottom: env(safe-area-inset-bottom)`, reliably eliminating the gap at the screen bottom ## [0.23.10] - 2026-04-22 ### Fixed - iOS PWA: safe area fill now uses the same surface color as the bottom navigation bar, so it matches in both light and dark mode ## [0.23.9] - 2026-04-22 ### Fixed - iOS PWA: a `body::after` pseudo-element now fills the home indicator safe area with the same glass background as the bottom navigation, eliminating the gap between the nav bar and the screen edge ## [0.23.8] - 2026-04-22 ### Fixed - iOS PWA: bottom navigation bar now extends into the home indicator safe area, removing the gap between the nav and the screen edge ## [0.23.7] - 2026-04-22 ### Fixed - Navigation: sidebar logo now uses the official `docs/logo.svg` artwork (house + chimney on gradient background) instead of a generic Lucide home icon; gradient colors are driven by CSS tokens ## [0.23.6] - 2026-04-22 ### Changed - Dashboard: greeting widget now adapts its gradient to the time of day — warm amber-orange in the morning (before 11:00), indigo during the day, and violet in the evening (after 18:00) - Dashboard: FAB speed-dial open/close rotation now uses a spring cubic-bezier for a more natural feel - Navigation: sidebar logo is now a proper SVG house icon on a gradient background instead of the CSS letter placeholder ## [0.23.5] - 2026-04-22 ### Changed - Dashboard: each widget now uses its module accent color (green for tasks, violet for calendar, orange for meals, pink for shopping, amber for notes) for its header icon, badge, and link instead of the global indigo accent - Dashboard: meal slots now display their type-specific color (amber for breakfast, green for lunch, indigo for dinner, orange for snack) on icon and label when a meal is planned - Dashboard: pinned note cards now show a subtle background tint matching the note's color - Dashboard: widget and card hover lift increased from 1 px to 2 px for more perceptible feedback on desktop - Navigation: active bottom-nav tab now shows a pill-shaped highlight behind the icon for a clearer location indicator - Shopping widget: progress bar height increased from 4 px to 6 px for better visual weight - Empty state icons inside widgets now use the tertiary text color instead of the disabled color for improved visibility ## [0.23.4] - 2026-04-22 ### Changed - Docs: web installer (`node tools/installer/install-server.js`) is now Option A in all installation guides (`README.md`, `docs/installation.md`, GitHub Pages `docs/install.html`); the pre-built Docker image method is relabelled Option B and the build-from-source method Option C ## [0.23.3] - 2026-04-22 ### Fixed - Weather widget: wind speed is no longer multiplied by 3.6 when `OPENWEATHER_UNITS=imperial` (the API already returns mph; the conversion was only correct for metric/standard) - Weather widget: wind unit label now shows `mph` for imperial and `km/h` for metric/standard instead of always showing `km/h` ## [0.23.2] - 2026-04-22 ### Fixed - Calendar: ICS-synced events now render at the correct local hour and day in week/day/month/agenda views; day-matching and hour-positioning previously used raw string slices which returned UTC values instead of browser-local time for events stored with a `Z` suffix ## [0.23.1] - 2026-04-22 ### Security - Installer: host and port inputs are now validated against a strict hostname regex and integer range check (1–65535) before being used in any DOM sink or URL template — prevents XSS-through-DOM (CodeQL js/xss-through-dom alert #7) ## [0.23.0] - 2026-04-21 ### Added - Calendar: `external_calendars` DB table (migration v14) stores display name and color per synced Google/Apple calendar; `calendar_events` gains a `calendar_ref_id` FK 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-label` badge when `cal_name` is present - Calendar: event popup and dashboard events list now display the event location using `fmtLocation()` which strips RFC 5545 backslash-escapes (`\n`, `\,`, `\;`, `\\`) and normalizes semicolons/newlines to comma-separated inline text - Utils: `fmtLocation(raw)` helper added to `html.js` for normalizing ICS `LOCATION` property 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 (`border-radius`, full `border`) 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 to `.list-tabs-bar` and `.budget-nav`, 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 (`width: 3px; align-items: stretch`), 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` ### Fixed - Tasks / Dashboard: sort order now strictly follows effective due date ascending; overdue tasks (due date+time in the past) always surface first in all views — list groups, Kanban columns, and the dashboard urgentTasks widget. Priority is used only as a tiebreaker for tasks sharing the same due datetime. Server-side sort moved from SQL to JavaScript using `effectiveDue()` for timezone-correct `due_time` handling (SQLite `DATE('now')` is UTC-only) - Tasks: due date chip now shows the time component when `due_time` is set; overdue/soon/today/tomorrow states are computed against the current moment rather than midnight - Dashboard: widget navigation links changed from `` to `