add accessibility fixes
This commit is contained in:
parent
b76ebac099
commit
566e8117e2
@ -81,7 +81,8 @@ main {
|
|||||||
[class*="-box"],
|
[class*="-box"],
|
||||||
button,
|
button,
|
||||||
input,
|
input,
|
||||||
textarea {
|
textarea,
|
||||||
|
select {
|
||||||
transition:
|
transition:
|
||||||
background-color var(--duration-med) var(--ease-out),
|
background-color var(--duration-med) var(--ease-out),
|
||||||
border-color var(--duration-med) var(--ease-out),
|
border-color var(--duration-med) var(--ease-out),
|
||||||
|
|||||||
@ -74,9 +74,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__nav {
|
.site-footer__nav {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer__nav ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.72rem;
|
gap: 0.72rem;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer__nav a {
|
.site-footer__nav a {
|
||||||
|
|||||||
@ -1,6 +1,28 @@
|
|||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
import "./Footer.css";
|
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 }) {
|
function Footer({ flushTop = false }) {
|
||||||
return (
|
return (
|
||||||
<footer className={`site-footer${flushTop ? " site-footer--flush" : ""}`}>
|
<footer className={`site-footer${flushTop ? " site-footer--flush" : ""}`}>
|
||||||
@ -10,28 +32,24 @@ function Footer({ flushTop = false }) {
|
|||||||
ATMOS
|
ATMOS
|
||||||
</Link>
|
</Link>
|
||||||
<p className="site-footer__text">
|
<p className="site-footer__text">
|
||||||
Konzeptuelle Düfte zwischen Materialität, Raum und Charakter.
|
{"Konzeptuelle D\u00FCfte zwischen Materialit\u00E4t, Raum und Charakter."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="site-footer__nav-group">
|
{footerLinkGroups.map((group) => (
|
||||||
<span className="site-footer__heading">Navigation</span>
|
<div className="site-footer__nav-group" key={group.heading}>
|
||||||
<nav className="site-footer__nav">
|
<span className="site-footer__heading">{group.heading}</span>
|
||||||
<Link to="/">Startseite</Link>
|
<nav className="site-footer__nav" aria-label={group.ariaLabel}>
|
||||||
<Link to="/#dufte">Düfte</Link>
|
<ul>
|
||||||
<Link to="/discovery-set">Discovery Set</Link>
|
{group.links.map((link) => (
|
||||||
</nav>
|
<li key={link.to}>
|
||||||
</div>
|
<Link to={link.to}>{link.label}</Link>
|
||||||
|
</li>
|
||||||
<div className="site-footer__nav-group">
|
))}
|
||||||
<span className="site-footer__heading">Rechtliches & Info</span>
|
</ul>
|
||||||
<nav className="site-footer__nav">
|
</nav>
|
||||||
<Link to="/about">About Us</Link>
|
</div>
|
||||||
<Link to="/support">Support</Link>
|
))}
|
||||||
<Link to="/impressum">Impressum</Link>
|
|
||||||
<Link to="/datenschutz">Datenschutz</Link>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -369,8 +369,8 @@
|
|||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
@ -403,9 +403,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.buy-button {
|
.buy-button {
|
||||||
border-color: var(--theme-accent);
|
border-color: var(--theme-accent-fill);
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.restock-button {
|
.restock-button {
|
||||||
@ -880,13 +880,13 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 86% 12%, rgba(255, 255, 255, 0.24), transparent 18rem),
|
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 .eyebrow,
|
||||||
.detail-bottom-cta h2,
|
.detail-bottom-cta h2,
|
||||||
.detail-bottom-cta p {
|
.detail-bottom-cta p {
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-bottom-cta p {
|
.detail-bottom-cta p {
|
||||||
@ -905,7 +905,7 @@
|
|||||||
border: 0;
|
border: 0;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: var(--theme-accent);
|
color: var(--theme-accent-fill-strong);
|
||||||
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.18);
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
|
|||||||
@ -119,9 +119,9 @@
|
|||||||
.shop-field input {
|
.shop-field input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 42px;
|
min-height: 42px;
|
||||||
border: 1px solid var(--theme-border);
|
border: 1px solid var(--theme-control-border);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: var(--theme-surface-soft);
|
background: var(--theme-control-bg);
|
||||||
padding: 10px 11px;
|
padding: 10px 11px;
|
||||||
color: var(--theme-text);
|
color: var(--theme-text);
|
||||||
font: inherit;
|
font: inherit;
|
||||||
@ -129,6 +129,16 @@
|
|||||||
text-transform: none;
|
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-primary,
|
||||||
.drawer-secondary,
|
.drawer-secondary,
|
||||||
.cart-remove,
|
.cart-remove,
|
||||||
@ -251,8 +261,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.payment-card.active {
|
.payment-card.active {
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-accent);
|
||||||
background: rgba(255, 106, 0, 0.12);
|
background: rgba(var(--theme-accent-rgb) / 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.totals-box {
|
.totals-box {
|
||||||
@ -306,7 +316,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drawer-error {
|
.drawer-error {
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-head {
|
.profile-head {
|
||||||
@ -366,8 +376,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pref-toggle.active {
|
.pref-toggle.active {
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-accent);
|
||||||
background: rgba(255, 106, 0, 0.12);
|
background: rgba(var(--theme-accent-rgb) / 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.subscription-list {
|
.subscription-list {
|
||||||
@ -415,7 +425,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.subscription-row button:hover {
|
.subscription-row button:hover {
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.requirement-row {
|
.requirement-row {
|
||||||
@ -423,7 +433,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.requirement-row strong.met {
|
.requirement-row strong.met {
|
||||||
color: #ff6a00;
|
color: var(--theme-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-card {
|
.order-card {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useId, useState } from "react";
|
||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
import { formatChf } from "../shop/money";
|
import { formatChf } from "../shop/money";
|
||||||
import { useShop } from "../shop/useShop";
|
import { useShop } from "../shop/useShop";
|
||||||
@ -18,14 +18,36 @@ const notificationLabels = [
|
|||||||
["discovery_enabled", "Discovery Set Updates"],
|
["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 (
|
return (
|
||||||
<label className="shop-field">
|
<label className="shop-field" htmlFor={fieldId}>
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
<input
|
<input
|
||||||
|
id={fieldId}
|
||||||
|
name={fieldName}
|
||||||
type={type}
|
type={type}
|
||||||
value={value}
|
value={value}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
|
autoComplete={autoComplete}
|
||||||
|
inputMode={inputMode}
|
||||||
onChange={(event) => onChange?.(event.target.value)}
|
onChange={(event) => onChange?.(event.target.value)}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@ -60,16 +82,40 @@ function AuthPanel() {
|
|||||||
|
|
||||||
{mode === "register" && (
|
{mode === "register" && (
|
||||||
<div className="drawer-grid drawer-grid--two">
|
<div className="drawer-grid drawer-grid--two">
|
||||||
<Field label="Name" value={form.first_name} onChange={(value) => update("first_name", value)} />
|
<Field
|
||||||
<Field label="Surname" value={form.surname} onChange={(value) => update("surname", value)} />
|
label="Name"
|
||||||
|
name="first_name"
|
||||||
|
value={form.first_name}
|
||||||
|
autoComplete="given-name"
|
||||||
|
onChange={(value) => update("first_name", value)}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
label="Surname"
|
||||||
|
name="surname"
|
||||||
|
value={form.surname}
|
||||||
|
autoComplete="family-name"
|
||||||
|
onChange={(value) => update("surname", value)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Field label="Email address" value={form.email} onChange={(value) => update("email", value)} />
|
|
||||||
<Field
|
<Field
|
||||||
|
id="auth-email"
|
||||||
|
label="Email address"
|
||||||
|
name="email"
|
||||||
|
type="email"
|
||||||
|
value={form.email}
|
||||||
|
autoComplete="email"
|
||||||
|
inputMode="email"
|
||||||
|
onChange={(value) => update("email", value)}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
id="auth-password"
|
||||||
label="Password"
|
label="Password"
|
||||||
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
|
autoComplete={mode === "login" ? "current-password" : "new-password"}
|
||||||
onChange={(value) => update("password", value)}
|
onChange={(value) => update("password", value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
z-index: 1200;
|
z-index: 1200;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: #ff6a00;
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
padding: 14px 20px;
|
padding: 14px 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -107,8 +107,8 @@
|
|||||||
|
|
||||||
.chatbot-message--user {
|
.chatbot-message--user {
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
background: #ff6a00;
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatbot-message--typing {
|
.chatbot-message--typing {
|
||||||
@ -153,15 +153,16 @@
|
|||||||
|
|
||||||
.chatbot-input {
|
.chatbot-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid var(--theme-border);
|
border: 1px solid var(--theme-control-border);
|
||||||
background: var(--theme-paper);
|
background: var(--theme-control-bg);
|
||||||
padding: 12px 14px;
|
padding: 12px 14px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatbot-input:focus {
|
.chatbot-input:focus {
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-control-border-focus);
|
||||||
|
outline: 2px solid var(--theme-focus-ring);
|
||||||
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatbot-send {
|
.chatbot-send {
|
||||||
@ -183,7 +184,7 @@
|
|||||||
.chatbot-link {
|
.chatbot-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #ff6a00;
|
color: var(--theme-accent);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -238,9 +239,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chatbot-feedback-btn--primary {
|
.chatbot-feedback-btn--primary {
|
||||||
background: #ff6a00;
|
background: var(--theme-accent-fill);
|
||||||
border-color: #ff6a00;
|
border-color: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatbot-secondary-actions {
|
.chatbot-secondary-actions {
|
||||||
@ -250,7 +251,7 @@
|
|||||||
.chatbot-text-button {
|
.chatbot-text-button {
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #ff6a00;
|
color: var(--theme-accent);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@ -109,6 +109,29 @@ select {
|
|||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
border: 1px solid var(--theme-control-border);
|
||||||
|
background: var(--theme-control-bg);
|
||||||
|
color: var(--theme-text);
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover,
|
||||||
|
textarea:hover,
|
||||||
|
select:hover {
|
||||||
|
border-color: var(--theme-control-border-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
textarea:focus,
|
||||||
|
select:focus {
|
||||||
|
border-color: var(--theme-control-border-focus);
|
||||||
|
outline: 2px solid var(--theme-focus-ring);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
[role="button"],
|
[role="button"],
|
||||||
a {
|
a {
|
||||||
@ -116,7 +139,7 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:focus-visible {
|
:focus-visible {
|
||||||
outline: 2px solid var(--theme-accent);
|
outline: 2px solid var(--theme-focus-ring);
|
||||||
outline-offset: 4px;
|
outline-offset: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +168,8 @@ a {
|
|||||||
left: 0.75rem;
|
left: 0.75rem;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
padding: 0.6rem 1rem;
|
padding: 0.6rem 1rem;
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transform: translateY(-150%);
|
transform: translateY(-150%);
|
||||||
@ -156,7 +179,7 @@ a {
|
|||||||
.skip-link:focus,
|
.skip-link:focus,
|
||||||
.skip-link:focus-visible {
|
.skip-link:focus-visible {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
outline: 2px solid #ffffff;
|
outline: 2px solid var(--theme-accent-contrast);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -264,13 +264,13 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 92% 0%, rgba(255, 255, 255, 0.22), transparent 20rem),
|
radial-gradient(circle at 92% 0%, rgba(255, 255, 255, 0.22), transparent 20rem),
|
||||||
var(--theme-accent);
|
var(--theme-accent-fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-bottom-copy .about-label,
|
.about-bottom-copy .about-label,
|
||||||
.about-bottom-copy h2,
|
.about-bottom-copy h2,
|
||||||
.about-bottom-copy p {
|
.about-bottom-copy p {
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-bottom-copy p {
|
.about-bottom-copy p {
|
||||||
@ -310,7 +310,7 @@
|
|||||||
|
|
||||||
.about-btn--primary {
|
.about-btn--primary {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: var(--theme-accent);
|
color: var(--theme-accent-fill-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-btn--secondary {
|
.about-btn--secondary {
|
||||||
|
|||||||
@ -177,10 +177,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 48px;
|
min-height: 48px;
|
||||||
padding: 0.8rem 1.35rem;
|
padding: 0.8rem 1.35rem;
|
||||||
border: 1px solid var(--theme-accent);
|
border: 1px solid var(--theme-accent-fill);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
letter-spacing: 0.12em;
|
letter-spacing: 0.12em;
|
||||||
@ -537,13 +537,13 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 86% 12%, rgba(255, 255, 255, 0.24), transparent 18rem),
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
.discovery-final-cta .discovery-label,
|
.discovery-final-cta .discovery-label,
|
||||||
.discovery-final-cta h2,
|
.discovery-final-cta h2,
|
||||||
.discovery-final-cta p {
|
.discovery-final-cta p {
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discovery-final-cta p {
|
.discovery-final-cta p {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import PageMeta from "../components/seo/PageMeta";
|
|||||||
import { useShop } from "../shop/useShop";
|
import { useShop } from "../shop/useShop";
|
||||||
import "./DiscoverySetPage.css";
|
import "./DiscoverySetPage.css";
|
||||||
|
|
||||||
const DISCOVERY_SET_IMAGE = "/atmos-discovery-set-thumbnail.png";
|
const DISCOVERY_SET_IMAGE = "/atmos-discovery-set-thumbnail.webp";
|
||||||
|
|
||||||
const discoveryPanelFacts = [
|
const discoveryPanelFacts = [
|
||||||
{ label: "Umfang", value: "6 × 2ml" },
|
{ label: "Umfang", value: "6 × 2ml" },
|
||||||
|
|||||||
@ -192,8 +192,8 @@ body.theme-light .hero-wordmark__image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
@ -313,6 +313,14 @@ body.theme-light .hero-wordmark__image {
|
|||||||
.product-grid only contributes container queries here. */
|
.product-grid only contributes container queries here. */
|
||||||
.product-grid {
|
.product-grid {
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-card-item {
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-card {
|
.product-card {
|
||||||
@ -339,6 +347,10 @@ body.theme-light .hero-wordmark__image {
|
|||||||
box-shadow var(--duration-med) var(--ease-out);
|
box-shadow var(--duration-med) var(--ease-out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.product-card-item .product-card {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.product-card::before {
|
.product-card::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -543,7 +555,7 @@ body.theme-light .hero-wordmark__image {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 14% 18%, rgba(255, 255, 255, 0.22), transparent 16rem),
|
radial-gradient(circle at 14% 18%, rgba(255, 255, 255, 0.22), transparent 16rem),
|
||||||
linear-gradient(135deg, #ff6a00, #d84f00);
|
linear-gradient(135deg, var(--theme-accent-fill), var(--theme-accent-fill-strong));
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,14 +575,14 @@ body.theme-light .hero-wordmark__image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.discovery-copy h2 {
|
.discovery-copy h2 {
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
font-size: clamp(2.2rem, 5.8vw, 6rem);
|
font-size: clamp(2.2rem, 5.8vw, 6rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discovery-copy p {
|
.discovery-copy p {
|
||||||
max-width: 29rem;
|
max-width: 29rem;
|
||||||
margin: clamp(1rem, 2vw, 1.4rem) 0 0;
|
margin: clamp(1rem, 2vw, 1.4rem) 0 0;
|
||||||
color: rgba(255, 255, 255, 0.86);
|
color: var(--theme-accent-contrast);
|
||||||
font-size: var(--text-base);
|
font-size: var(--text-base);
|
||||||
line-height: 1.62;
|
line-height: 1.62;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -469,64 +469,68 @@ function LandingPage() {
|
|||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Grid gap="sm" className="product-grid">
|
<Grid as="ul" gap="sm" className="product-grid">
|
||||||
{perfumes.map((item, index) => (
|
{perfumes.map((item, index) => (
|
||||||
<Link
|
<li
|
||||||
to={`/duft/${item.slug}`}
|
className="product-card-item col-span-12 md:col-span-6 lg:col-span-4"
|
||||||
className="product-card col-span-12 md:col-span-6 lg:col-span-4"
|
|
||||||
key={item.id}
|
key={item.id}
|
||||||
onClick={(event) => startProductTransition(event, item)}
|
|
||||||
ref={(element) => {
|
|
||||||
cardRefs.current[index] = element;
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div className="product-hover-fill" aria-hidden="true">
|
<Link
|
||||||
{item.fillVideo ? (
|
to={`/duft/${item.slug}`}
|
||||||
<video
|
className="product-card"
|
||||||
className="product-hover-video"
|
onClick={(event) => startProductTransition(event, item)}
|
||||||
src={item.fillVideo}
|
ref={(element) => {
|
||||||
muted
|
cardRefs.current[index] = element;
|
||||||
loop
|
}}
|
||||||
playsInline
|
>
|
||||||
preload="metadata"
|
<div className="product-hover-fill" aria-hidden="true">
|
||||||
|
{item.fillVideo ? (
|
||||||
|
<video
|
||||||
|
className="product-hover-video"
|
||||||
|
src={item.fillVideo}
|
||||||
|
muted
|
||||||
|
loop
|
||||||
|
playsInline
|
||||||
|
preload="metadata"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="product-hover-image"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${item.fillImage || item.image})`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="product-top">
|
||||||
|
<span className="product-id">{item.id}</span>
|
||||||
|
<h3>{item.name}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="product-image-wrap">
|
||||||
|
<img
|
||||||
|
src={item.image}
|
||||||
|
srcSet={buildPublicImageSrcSet(item.image, {
|
||||||
|
folder: "/images/products",
|
||||||
|
widths: [540, 720],
|
||||||
|
originalWidth: 1080,
|
||||||
|
})}
|
||||||
|
sizes={PRODUCT_CARD_IMAGE_SIZES}
|
||||||
|
alt={item.name}
|
||||||
|
className="product-image"
|
||||||
|
data-product-transition-source
|
||||||
|
loading={index < 3 ? "eager" : "lazy"}
|
||||||
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
) : (
|
</div>
|
||||||
<div
|
|
||||||
className="product-hover-image"
|
|
||||||
style={{
|
|
||||||
backgroundImage: `url(${item.fillImage || item.image})`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="product-top">
|
<div className="product-bottom">
|
||||||
<span className="product-id">{item.id}</span>
|
<p>{item.text}</p>
|
||||||
<h3>{item.name}</h3>
|
<span className="arrow" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
|
</Link>
|
||||||
<div className="product-image-wrap">
|
</li>
|
||||||
<img
|
|
||||||
src={item.image}
|
|
||||||
srcSet={buildPublicImageSrcSet(item.image, {
|
|
||||||
folder: "/images/products",
|
|
||||||
widths: [540, 720],
|
|
||||||
originalWidth: 1080,
|
|
||||||
})}
|
|
||||||
sizes={PRODUCT_CARD_IMAGE_SIZES}
|
|
||||||
alt={item.name}
|
|
||||||
className="product-image"
|
|
||||||
data-product-transition-source
|
|
||||||
loading={index < 3 ? "eager" : "lazy"}
|
|
||||||
decoding="async"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="product-bottom">
|
|
||||||
<p>{item.text}</p>
|
|
||||||
<span className="arrow" aria-hidden="true" />
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -205,8 +205,8 @@
|
|||||||
margin-top: 1.15rem;
|
margin-top: 1.15rem;
|
||||||
padding: 0 1.1rem;
|
padding: 0 1.1rem;
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: var(--theme-accent);
|
background: var(--theme-accent-fill);
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
font-size: var(--text-sm);
|
font-size: var(--text-sm);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition:
|
transition:
|
||||||
@ -240,13 +240,13 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at 92% 0%, rgba(255, 255, 255, 0.22), transparent 20rem),
|
radial-gradient(circle at 92% 0%, rgba(255, 255, 255, 0.22), transparent 20rem),
|
||||||
var(--theme-accent);
|
var(--theme-accent-fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
.support-bottom-copy .support-label,
|
.support-bottom-copy .support-label,
|
||||||
.support-bottom-copy h2,
|
.support-bottom-copy h2,
|
||||||
.support-bottom-copy p {
|
.support-bottom-copy p {
|
||||||
color: #fff;
|
color: var(--theme-accent-contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
.support-bottom-copy p {
|
.support-bottom-copy p {
|
||||||
@ -286,7 +286,7 @@
|
|||||||
|
|
||||||
.support-btn--primary {
|
.support-btn--primary {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: var(--theme-accent);
|
color: var(--theme-accent-fill-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
.support-btn--secondary {
|
.support-btn--secondary {
|
||||||
|
|||||||
@ -22,6 +22,11 @@
|
|||||||
--theme-white: #eaeaea;
|
--theme-white: #eaeaea;
|
||||||
--theme-accent: #ff6a00;
|
--theme-accent: #ff6a00;
|
||||||
--theme-accent-rgb: 255 106 0;
|
--theme-accent-rgb: 255 106 0;
|
||||||
|
--theme-accent-fill: #c24700;
|
||||||
|
--theme-accent-fill-rgb: 194 71 0;
|
||||||
|
--theme-accent-fill-strong: #a83b00;
|
||||||
|
--theme-accent-contrast: #ffffff;
|
||||||
|
--theme-focus-ring: #ff9440;
|
||||||
|
|
||||||
/* Surfaces (dark theme — default) */
|
/* Surfaces (dark theme — default) */
|
||||||
--theme-bg: #262626;
|
--theme-bg: #262626;
|
||||||
@ -32,6 +37,10 @@
|
|||||||
--theme-text-muted: #c8c8c8;
|
--theme-text-muted: #c8c8c8;
|
||||||
--theme-border: #4a4a4a;
|
--theme-border: #4a4a4a;
|
||||||
--theme-border-strong: rgba(234, 234, 234, 0.26);
|
--theme-border-strong: rgba(234, 234, 234, 0.26);
|
||||||
|
--theme-control-bg: var(--theme-surface);
|
||||||
|
--theme-control-border: #8a8a8a;
|
||||||
|
--theme-control-border-hover: #9a9a9a;
|
||||||
|
--theme-control-border-focus: var(--theme-focus-ring);
|
||||||
--theme-shadow: 0 24px 70px rgba(0, 0, 0, 0.28);
|
--theme-shadow: 0 24px 70px rgba(0, 0, 0, 0.28);
|
||||||
--theme-shadow-soft: 0 16px 42px rgba(0, 0, 0, 0.18);
|
--theme-shadow-soft: 0 16px 42px rgba(0, 0, 0, 0.18);
|
||||||
|
|
||||||
@ -121,6 +130,11 @@ body.theme-light {
|
|||||||
--theme-text-muted: #5f5f5f;
|
--theme-text-muted: #5f5f5f;
|
||||||
--theme-border: #d6d6d6;
|
--theme-border: #d6d6d6;
|
||||||
--theme-border-strong: rgba(38, 38, 38, 0.22);
|
--theme-border-strong: rgba(38, 38, 38, 0.22);
|
||||||
|
--theme-focus-ring: #a83b00;
|
||||||
|
--theme-control-bg: #ffffff;
|
||||||
|
--theme-control-border: #767676;
|
||||||
|
--theme-control-border-hover: #5f5f5f;
|
||||||
|
--theme-control-border-focus: var(--theme-focus-ring);
|
||||||
--theme-shadow: 0 24px 70px rgba(38, 38, 38, 0.13);
|
--theme-shadow: 0 24px 70px rgba(38, 38, 38, 0.13);
|
||||||
--theme-shadow-soft: 0 16px 42px rgba(38, 38, 38, 0.1);
|
--theme-shadow-soft: 0 16px 42px rgba(38, 38, 38, 0.1);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user