diff --git a/CHANGELOG.md b/CHANGELOG.md index 590dd76..5cbd1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [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 diff --git a/package-lock.json b/package-lock.json index 39a0ce0..38c1c1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "oikos", - "version": "0.23.4", + "version": "0.23.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "oikos", - "version": "0.23.4", + "version": "0.23.5", "license": "MIT", "dependencies": { "bcrypt": "^6.0.0", diff --git a/package.json b/package.json index 57729f8..2a794f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.23.4", + "version": "0.23.5", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module", diff --git a/public/pages/dashboard.js b/public/pages/dashboard.js index ade8d1f..b318ede 100644 --- a/public/pages/dashboard.js +++ b/public/pages/dashboard.js @@ -215,7 +215,7 @@ function renderGreeting(user, stats = {}) { function renderUrgentTasks(tasks) { if (!tasks.length) { - return `
+ return `
${widgetHeader('check-square', t('nav.tasks'), 0, '/tasks')}
@@ -241,7 +241,7 @@ function renderUrgentTasks(tasks) { `; }).join(''); - return `
+ return `
${widgetHeader('check-square', t('nav.tasks'), tasks.length, '/tasks')}
${items}
`; @@ -249,7 +249,7 @@ function renderUrgentTasks(tasks) { function renderUpcomingEvents(events) { if (!events.length) { - return `
+ return `
${widgetHeader('calendar', t('nav.calendar'), 0, '/calendar')}
@@ -280,7 +280,7 @@ function renderUpcomingEvents(events) { `; }).join(''); - return `
+ return `
${widgetHeader('calendar', t('nav.calendar'), events.length, '/calendar')}
${items}
`; @@ -293,7 +293,7 @@ function renderTodayMeals(meals) { const slots = MEAL_ORDER.map((type) => { const meal = meals.find((m) => m.meal_type === type); return ` -
+
${mealLabels[type]}
${meal ? esc(meal.title) : '-'}
@@ -309,7 +309,7 @@ function renderTodayMeals(meals) { function renderPinnedNotes(notes) { if (!notes.length) { - return `
+ return `
${widgetHeader('pin', t('nav.notes'), 0, '/notes')}
@@ -326,7 +326,7 @@ function renderPinnedNotes(notes) {
`).join(''); - return `
+ return `
${widgetHeader('pin', t('nav.notes'), notes.length, '/notes')}
${items}
`; @@ -373,7 +373,7 @@ function renderShoppingLists(lists) { `; }).join(''); - return `
+ return `
${widgetHeader('shopping-cart', t('nav.shopping'), totalOpen, '/shopping')}
${listsHtml}
`; @@ -409,7 +409,7 @@ function renderWeatherWidget(weather) { }).join(''); return ` -
+
diff --git a/public/styles/dashboard.css b/public/styles/dashboard.css index 9bb6df4..dd812e0 100644 --- a/public/styles/dashboard.css +++ b/public/styles/dashboard.css @@ -158,6 +158,19 @@ background: var(--color-warning-translucent); } +/* -------------------------------------------------------- + * Widget-Modul-Akzentfarben + * Jedes Widget nutzt seine eigene Modulfarbe für Icon, Badge und Link. + * -------------------------------------------------------- */ +.widget--tasks { --widget-accent: var(--module-tasks); } +.widget--calendar { --widget-accent: var(--module-calendar); } +.widget--shopping { --widget-accent: var(--module-shopping); } +.widget--meals { --widget-accent: var(--module-meals); } +.widget--notes { --widget-accent: var(--module-notes); } +.widget--budget { --widget-accent: var(--module-budget); } +.widget--contacts { --widget-accent: var(--module-contacts); } +.widget--weather { --widget-accent: var(--module-dashboard); } + /* -------------------------------------------------------- * Basis-Widget (Card) * @@ -209,12 +222,12 @@ .widget__title-icon { width: 16px; height: 16px; - color: var(--color-accent); + color: var(--widget-accent, var(--color-accent)); } .widget__link { font-size: var(--text-xs); - color: var(--color-accent); + color: var(--widget-accent, var(--color-accent)); font-weight: var(--font-weight-medium); display: inline-flex; align-items: center; @@ -230,7 +243,7 @@ display: inline-flex; align-items: center; justify-content: center; - background-color: var(--color-accent); + background-color: var(--widget-accent, var(--color-accent)); color: var(--color-text-on-accent); font-size: var(--text-xs); font-weight: var(--font-weight-bold); @@ -260,17 +273,17 @@ .widget__empty .empty-state__icon { width: 28px; height: 28px; - color: var(--color-text-disabled); + color: var(--color-text-tertiary); margin-bottom: var(--space-1); } -/* Widget hover lift (desktop) - dezent, max 1px */ +/* Widget hover lift (desktop) */ @media (min-width: 1024px) { .widget { transition: transform var(--transition-fast), box-shadow var(--transition-fast); } .widget:hover { - transform: translateY(-1px); + transform: translateY(-2px); box-shadow: var(--shadow-md); } } @@ -470,6 +483,12 @@ border-bottom-right-radius: var(--radius-md); } +/* Meal-Typ-Farben aus tokens.css */ +.meal-slot[data-type="breakfast"] { --slot-color: var(--meal-breakfast); } +.meal-slot[data-type="lunch"] { --slot-color: var(--meal-lunch); } +.meal-slot[data-type="dinner"] { --slot-color: var(--meal-dinner); } +.meal-slot[data-type="snack"] { --slot-color: var(--meal-snack); } + .meal-slot__icon { width: 18px; height: 18px; @@ -478,7 +497,7 @@ } .meal-slot--filled .meal-slot__icon { - color: var(--color-accent); + color: var(--slot-color, var(--color-accent)); } .meal-slot__type { @@ -490,7 +509,7 @@ } .meal-slot--filled .meal-slot__type { - color: var(--color-text-secondary); + color: var(--slot-color, var(--color-text-secondary)); } .meal-slot__title { @@ -571,7 +590,7 @@ } .shopping-widget-list__progress { - height: 4px; + height: 6px; background-color: var(--color-surface-3); border-radius: var(--radius-full); overflow: hidden; @@ -649,7 +668,7 @@ cursor: pointer; transition: opacity var(--transition-fast), transform var(--transition-fast); border-left: 3px solid var(--note-color, var(--color-accent)); - background-color: var(--color-surface-2); + background-color: color-mix(in srgb, var(--note-color, var(--color-accent)) 6%, var(--color-surface-2)); } .note-item:hover { diff --git a/public/styles/layout.css b/public/styles/layout.css index 7b5888b..4c86bf6 100755 --- a/public/styles/layout.css +++ b/public/styles/layout.css @@ -408,6 +408,15 @@ color: var(--active-module-accent, var(--color-accent)); } +/* Pill-Hintergrund hinter dem Icon (nur Bottom-Nav, nicht Sidebar) */ +.nav-bottom .nav-item[aria-current="page"] .nav-item__icon-wrap { + background-color: color-mix(in srgb, var(--active-module-accent, var(--color-accent)) 14%, transparent); + border-radius: var(--radius-lg); + padding: var(--space-1) var(--space-4); + margin-bottom: 1px; + transition: background-color var(--transition-fast); +} + .nav-item__icon { width: var(--space-5); height: var(--space-5); @@ -776,7 +785,7 @@ } .card--interactive:hover { - transform: translateY(-1px); + transform: translateY(-2px); box-shadow: var(--shadow-md); }