From 566e8117e2cd3254130e8e18caf148075ac138c3 Mon Sep 17 00:00:00 2001 From: Ermin Zoronjic Date: Tue, 5 May 2026 14:34:31 +0200 Subject: [PATCH] add accessibility fixes --- parfum-shop/src/App.css | 3 +- parfum-shop/src/components/Footer.css | 7 ++ parfum-shop/src/components/Footer.jsx | 56 ++++++--- .../src/components/ProductDetailPage.css | 16 +-- parfum-shop/src/components/ShopDrawer.css | 28 +++-- parfum-shop/src/components/ShopDrawer.jsx | 58 ++++++++- parfum-shop/src/components/SupportChatbot.css | 27 ++--- parfum-shop/src/index.css | 31 ++++- parfum-shop/src/pages/AboutPage.css | 6 +- parfum-shop/src/pages/DiscoverySetPage.css | 10 +- parfum-shop/src/pages/DiscoverySetPage.jsx | 2 +- parfum-shop/src/pages/LandingPage.css | 22 +++- parfum-shop/src/pages/LandingPage.jsx | 110 +++++++++--------- parfum-shop/src/pages/SupportPage.css | 10 +- parfum-shop/src/style/tokens.css | 14 +++ 15 files changed, 268 insertions(+), 132 deletions(-) diff --git a/parfum-shop/src/App.css b/parfum-shop/src/App.css index 9e9bf2b..9366ba2 100644 --- a/parfum-shop/src/App.css +++ b/parfum-shop/src/App.css @@ -81,7 +81,8 @@ main { [class*="-box"], button, input, -textarea { +textarea, +select { transition: background-color var(--duration-med) var(--ease-out), border-color var(--duration-med) var(--ease-out), diff --git a/parfum-shop/src/components/Footer.css b/parfum-shop/src/components/Footer.css index 956edae..47f7d48 100644 --- a/parfum-shop/src/components/Footer.css +++ b/parfum-shop/src/components/Footer.css @@ -74,9 +74,16 @@ } .site-footer__nav { + display: block; +} + +.site-footer__nav ul { display: flex; flex-direction: column; gap: 0.72rem; + list-style: none; + margin: 0; + padding: 0; } .site-footer__nav a { diff --git a/parfum-shop/src/components/Footer.jsx b/parfum-shop/src/components/Footer.jsx index f0aa705..40d331a 100644 --- a/parfum-shop/src/components/Footer.jsx +++ b/parfum-shop/src/components/Footer.jsx @@ -1,6 +1,28 @@ import { Link } from "react-router"; import "./Footer.css"; +const footerLinkGroups = [ + { + heading: "Navigation", + ariaLabel: "Footer Navigation", + links: [ + { to: "/", label: "Startseite" }, + { to: "/#dufte", label: "D\u00FCfte" }, + { to: "/discovery-set", label: "Discovery Set" }, + ], + }, + { + heading: "Rechtliches & Info", + ariaLabel: "Footer Rechtliches und Info", + links: [ + { to: "/about", label: "About Us" }, + { to: "/support", label: "Support" }, + { to: "/impressum", label: "Impressum" }, + { to: "/datenschutz", label: "Datenschutz" }, + ], + }, +]; + function Footer({ flushTop = false }) { return ( ); diff --git a/parfum-shop/src/components/ProductDetailPage.css b/parfum-shop/src/components/ProductDetailPage.css index d600caa..c0bbeb8 100644 --- a/parfum-shop/src/components/ProductDetailPage.css +++ b/parfum-shop/src/components/ProductDetailPage.css @@ -369,8 +369,8 @@ min-height: 44px; padding: 0 1rem; border-radius: var(--radius-lg); - background: var(--theme-accent); - color: #fff; + background: var(--theme-accent-fill); + color: var(--theme-accent-contrast); text-decoration: none; white-space: nowrap; font-size: var(--text-sm); @@ -403,9 +403,9 @@ } .buy-button { - border-color: var(--theme-accent); - background: var(--theme-accent); - color: #fff; + border-color: var(--theme-accent-fill); + background: var(--theme-accent-fill); + color: var(--theme-accent-contrast); } .restock-button { @@ -880,13 +880,13 @@ overflow: hidden; background: radial-gradient(circle at 86% 12%, rgba(255, 255, 255, 0.24), transparent 18rem), - linear-gradient(135deg, var(--theme-accent), #e95700); + linear-gradient(135deg, var(--theme-accent-fill), var(--theme-accent-fill-strong)); } .detail-bottom-cta .eyebrow, .detail-bottom-cta h2, .detail-bottom-cta p { - color: #fff; + color: var(--theme-accent-contrast); } .detail-bottom-cta p { @@ -905,7 +905,7 @@ border: 0; border-radius: var(--radius-lg); background: #fff; - color: var(--theme-accent); + color: var(--theme-accent-fill-strong); box-shadow: 0 18px 42px rgba(0, 0, 0, 0.18); font-size: var(--text-sm); letter-spacing: 0; diff --git a/parfum-shop/src/components/ShopDrawer.css b/parfum-shop/src/components/ShopDrawer.css index 71be3bc..1795e1a 100644 --- a/parfum-shop/src/components/ShopDrawer.css +++ b/parfum-shop/src/components/ShopDrawer.css @@ -119,9 +119,9 @@ .shop-field input { width: 100%; min-height: 42px; - border: 1px solid var(--theme-border); + border: 1px solid var(--theme-control-border); border-radius: 0; - background: var(--theme-surface-soft); + background: var(--theme-control-bg); padding: 10px 11px; color: var(--theme-text); font: inherit; @@ -129,6 +129,16 @@ text-transform: none; } +.shop-field input:hover { + border-color: var(--theme-control-border-hover); +} + +.shop-field input:focus { + border-color: var(--theme-control-border-focus); + outline: 2px solid var(--theme-focus-ring); + outline-offset: 2px; +} + .drawer-primary, .drawer-secondary, .cart-remove, @@ -251,8 +261,8 @@ } .payment-card.active { - border-color: #ff6a00; - background: rgba(255, 106, 0, 0.12); + border-color: var(--theme-accent); + background: rgba(var(--theme-accent-rgb) / 0.12); } .totals-box { @@ -306,7 +316,7 @@ } .drawer-error { - border-color: #ff6a00; + border-color: var(--theme-accent); } .profile-head { @@ -366,8 +376,8 @@ } .pref-toggle.active { - border-color: #ff6a00; - background: rgba(255, 106, 0, 0.12); + border-color: var(--theme-accent); + background: rgba(var(--theme-accent-rgb) / 0.12); } .subscription-list { @@ -415,7 +425,7 @@ } .subscription-row button:hover { - border-color: #ff6a00; + border-color: var(--theme-accent); } .requirement-row { @@ -423,7 +433,7 @@ } .requirement-row strong.met { - color: #ff6a00; + color: var(--theme-accent); } .order-card { diff --git a/parfum-shop/src/components/ShopDrawer.jsx b/parfum-shop/src/components/ShopDrawer.jsx index 938a074..be38df2 100644 --- a/parfum-shop/src/components/ShopDrawer.jsx +++ b/parfum-shop/src/components/ShopDrawer.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useId, useState } from "react"; import { Link } from "react-router"; import { formatChf } from "../shop/money"; import { useShop } from "../shop/useShop"; @@ -18,14 +18,36 @@ const notificationLabels = [ ["discovery_enabled", "Discovery Set Updates"], ]; -function Field({ label, value, onChange, type = "text", readOnly = false }) { +function Field({ + label, + value, + onChange, + type = "text", + readOnly = false, + id, + name, + autoComplete, + inputMode, +}) { + const generatedId = useId(); + const fallbackName = label + .toLowerCase() + .replace(/[^a-z0-9]+/g, "_") + .replace(/^_|_$/g, ""); + const fieldName = name || fallbackName; + const fieldId = id || `shop-field-${fieldName}-${generatedId}`; + return ( -