fix: improve accessibility and tokenize remaining hardcoded CSS values
- FAB focus ring: double-ring pattern replacing invisible #fff outline - forced-colors media query for Windows High Contrast Mode - New tokens: --color-accent-secondary, --content-max-width-narrow, --cal-hour-height - Apple sync logo uses semantic tokens for correct dark mode inversion - Sidebar logo gradient references token instead of hardcoded #7C5CFC
This commit is contained in:
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.19.2] - 2026-04-14
|
||||||
|
|
||||||
|
### Improved
|
||||||
|
- Accessibility: FAB focus ring now uses a double-ring pattern (inner `--color-bg`, outer `--color-accent`) visible on any background - previously hardcoded `#fff` was invisible on light backgrounds
|
||||||
|
- Accessibility: added `forced-colors` media query fallback for Windows High Contrast Mode (buttons, cards, modals, active nav items)
|
||||||
|
- Design tokens: extracted `--color-accent-secondary`, `--content-max-width-narrow`, `--cal-hour-height` - eliminates last hardcoded values in layout, settings, and calendar CSS
|
||||||
|
- Dark mode: Apple sync logo in settings now uses semantic tokens (`--color-text-primary` / `--color-bg`) instead of fixed neutrals that didn't invert correctly
|
||||||
|
- Sidebar logo gradient now references `--color-accent-secondary` token instead of hardcoded `#7C5CFC`
|
||||||
|
|
||||||
## [0.19.1] - 2026-04-14
|
## [0.19.1] - 2026-04-14
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oikos",
|
"name": "oikos",
|
||||||
"version": "0.19.1",
|
"version": "0.19.2",
|
||||||
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
|
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
|
||||||
"main": "server/index.js",
|
"main": "server/index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -288,7 +288,7 @@
|
|||||||
|
|
||||||
.week-view__body {
|
.week-view__body {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: calc(24 * 56px); /* 24h × 56px pro Stunde */
|
min-height: calc(24 * var(--cal-hour-height)); /* 24h × 56px pro Stunde */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.week-view__time-slot {
|
.week-view__time-slot {
|
||||||
height: 56px;
|
height: var(--cal-hour-height);
|
||||||
padding-right: var(--space-2);
|
padding-right: var(--space-2);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -415,7 +415,7 @@
|
|||||||
|
|
||||||
.day-view__body {
|
.day-view__body {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: calc(24 * 56px);
|
min-height: calc(24 * var(--cal-hour-height));
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,8 +253,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page-fab:focus-visible {
|
.page-fab:focus-visible {
|
||||||
outline: 2px solid #fff;
|
outline: 2px solid var(--color-bg);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
|
box-shadow: 0 0 0 4px var(--color-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Desktop: FAB Position anpassen (keine Bottom-Nav) und etwas kleiner */
|
/* Desktop: FAB Position anpassen (keine Bottom-Nav) und etwas kleiner */
|
||||||
@@ -333,7 +334,7 @@
|
|||||||
width: var(--target-sm);
|
width: var(--target-sm);
|
||||||
height: var(--target-sm);
|
height: var(--target-sm);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: linear-gradient(135deg, var(--color-accent) 0%, #7C5CFC 100%);
|
background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-secondary) 100%);
|
||||||
color: var(--color-text-on-accent);
|
color: var(--color-text-on-accent);
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
@@ -942,8 +943,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fab:focus-visible {
|
.fab:focus-visible {
|
||||||
outline: 2px solid #fff;
|
outline: 2px solid var(--color-bg);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
|
box-shadow: 0 0 0 4px var(--color-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
@@ -1739,3 +1741,15 @@
|
|||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
border-radius: 0 0 var(--radius-sm) 0;
|
border-radius: 0 0 var(--radius-sm) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------
|
||||||
|
* Windows High Contrast / Forced Colors
|
||||||
|
* -------------------------------------------------------- */
|
||||||
|
@media (forced-colors: active) {
|
||||||
|
.btn,
|
||||||
|
.page-fab,
|
||||||
|
.fab { border: 1px solid ButtonText; }
|
||||||
|
.card { border: 1px solid CanvasText; }
|
||||||
|
.modal-panel { border: 2px solid CanvasText; }
|
||||||
|
.nav-item[aria-current="page"] { border-bottom: 2px solid Highlight; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
-------------------------------------------------------- */
|
-------------------------------------------------------- */
|
||||||
|
|
||||||
.settings-page {
|
.settings-page {
|
||||||
max-width: 720px;
|
max-width: var(--content-max-width-narrow);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +250,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-sync-logo--apple {
|
.settings-sync-logo--apple {
|
||||||
background: var(--neutral-900);
|
background: var(--color-text-primary);
|
||||||
color: var(--neutral-50);
|
color: var(--color-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-sync-info__name {
|
.settings-sync-info__name {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
--color-accent-hover: #1D4ED8;
|
--color-accent-hover: #1D4ED8;
|
||||||
--color-accent-active: #1E40AF;
|
--color-accent-active: #1E40AF;
|
||||||
--color-accent-deep: #1E5CB3; /* Tiefer Akzent für Gradienten, Wetter-Widget */
|
--color-accent-deep: #1E5CB3; /* Tiefer Akzent für Gradienten, Wetter-Widget */
|
||||||
|
--color-accent-secondary: #7C5CFC; /* Sekundärer Akzent für Logo-Gradient */
|
||||||
--color-accent-light: #EFF6FF;
|
--color-accent-light: #EFF6FF;
|
||||||
--color-accent-subtle: #DBEAFE;
|
--color-accent-subtle: #DBEAFE;
|
||||||
--color-btn-primary: #2554C7; /* WCAG AA: 6.62:1 auf weiß (weißer Text) */
|
--color-btn-primary: #2554C7; /* WCAG AA: 6.62:1 auf weiß (weißer Text) */
|
||||||
@@ -223,6 +224,8 @@
|
|||||||
--sidebar-width: 56px; /* collapsed icon-only (1024–1279px) */
|
--sidebar-width: 56px; /* collapsed icon-only (1024–1279px) */
|
||||||
--sidebar-width-expanded: 220px; /* full sidebar (1280px+), max 240px laut Spec */
|
--sidebar-width-expanded: 220px; /* full sidebar (1280px+), max 240px laut Spec */
|
||||||
--content-max-width: 1280px;
|
--content-max-width: 1280px;
|
||||||
|
--content-max-width-narrow: 720px;
|
||||||
|
--cal-hour-height: 56px;
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
* 13. Sidebar
|
* 13. Sidebar
|
||||||
@@ -362,6 +365,8 @@
|
|||||||
--color-btn-primary: #3B82F6;
|
--color-btn-primary: #3B82F6;
|
||||||
--color-btn-primary-hover: #2563EB;
|
--color-btn-primary-hover: #2563EB;
|
||||||
|
|
||||||
|
--color-accent-secondary: #A78BFA;
|
||||||
|
|
||||||
/* Semantische Farben - Dark Mode */
|
/* Semantische Farben - Dark Mode */
|
||||||
--color-success: #4ADE80;
|
--color-success: #4ADE80;
|
||||||
--color-warning: #F59E0B;
|
--color-warning: #F59E0B;
|
||||||
@@ -463,6 +468,7 @@
|
|||||||
--color-accent-subtle: #1E3050;
|
--color-accent-subtle: #1E3050;
|
||||||
--color-btn-primary: #3B82F6;
|
--color-btn-primary: #3B82F6;
|
||||||
--color-btn-primary-hover: #2563EB;
|
--color-btn-primary-hover: #2563EB;
|
||||||
|
--color-accent-secondary: #A78BFA;
|
||||||
|
|
||||||
/* Semantische Farben - Dark Mode */
|
/* Semantische Farben - Dark Mode */
|
||||||
--color-success: #4ADE80;
|
--color-success: #4ADE80;
|
||||||
|
|||||||
Reference in New Issue
Block a user