add responsive changes

This commit is contained in:
Ermin Zoronjic 2026-04-29 17:30:47 +02:00
parent 088d01b256
commit 2eea587e8b
11 changed files with 132 additions and 71 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -516,16 +516,37 @@
} }
.story-visual-panel { .story-visual-panel {
position: relative;
min-height: clamp(360px, 42vw, 620px); min-height: clamp(360px, 42vw, 620px);
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
padding: clamp(1.2rem, 3vw, 2.4rem); padding: clamp(1.2rem, 3vw, 2.4rem);
border: 1px solid var(--theme-border); border: 1px solid var(--theme-border);
overflow: hidden;
background: var(--theme-surface-soft);
}
.story-visual-panel::after {
content: "";
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
background: background:
radial-gradient(circle at 66% 32%, rgba(255, 255, 255, 0.11), transparent 14rem), linear-gradient(180deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.72)),
radial-gradient(circle at 38% 68%, rgba(var(--theme-accent-rgb) / 0.1), transparent 17rem), linear-gradient(90deg, rgba(0, 0, 0, 0.24), transparent 45%);
linear-gradient(135deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.01)), }
var(--theme-paper);
.story-visual-image {
position: absolute;
inset: 0;
z-index: 0;
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
filter: saturate(0.92) contrast(1.04);
} }
.character-facts { .character-facts {
@ -540,14 +561,16 @@
min-height: 132px; min-height: 132px;
} }
.story-visual-panel > div { .story-visual-content {
position: relative;
z-index: 2;
width: 100%; width: 100%;
} }
.story-visual-panel > div > span:first-child { .story-visual-content > span:first-child {
display: block; display: block;
margin-bottom: var(--gap-sm); margin-bottom: var(--gap-sm);
color: var(--theme-text-muted); color: rgba(255, 255, 255, 0.68);
font-size: var(--text-xs); font-size: var(--text-xs);
letter-spacing: 0.22em; letter-spacing: 0.22em;
text-transform: uppercase; text-transform: uppercase;
@ -564,9 +587,9 @@
align-items: center; align-items: center;
min-height: 40px; min-height: 40px;
padding: 0.55rem 0.85rem; padding: 0.55rem 0.85rem;
border: 1px solid var(--theme-border); border: 1px solid rgba(255, 255, 255, 0.22);
background: rgba(255, 255, 255, 0.035); background: rgba(0, 0, 0, 0.24);
color: var(--theme-text); color: #fff;
font-size: var(--text-sm); font-size: var(--text-sm);
letter-spacing: 0; letter-spacing: 0;
text-transform: none; text-transform: none;

View File

@ -7,6 +7,8 @@ import { formatChf } from "../shop/money";
import { useShop } from "../shop/useShop"; import { useShop } from "../shop/useShop";
import "./ProductDetailPage.css"; import "./ProductDetailPage.css";
const STORY_PANEL_IMAGE = "/placeholder-character-panel.jpg";
const priceToCents = (price) => { const priceToCents = (price) => {
const match = String(price).match(/(\d+)/); const match = String(price).match(/(\d+)/);
return match ? Number(match[1]) * 100 : 0; return match ? Number(match[1]) * 100 : 0;
@ -207,7 +209,14 @@ function ProductStorySection({ perfume }) {
</div> </div>
<div className="story-visual-panel" data-reveal="fade"> <div className="story-visual-panel" data-reveal="fade">
<div> <img
className="story-visual-image"
src={STORY_PANEL_IMAGE}
alt=""
loading="lazy"
decoding="async"
/>
<div className="story-visual-content">
<span>Material-Komposition</span> <span>Material-Komposition</span>
<div className="material-tags"> <div className="material-tags">
{perfume.materialTags.map((tag) => ( {perfume.materialTags.map((tag) => (
@ -528,7 +537,7 @@ function ProductDetailContent({ perfumeSlug }) {
return ( return (
<div className={`detail-page ${isTransitionArriving ? "is-transition-arriving" : ""}`}> <div className={`detail-page ${isTransitionArriving ? "is-transition-arriving" : ""}`}>
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<div className="detail-topbar" data-product-transition-reveal> <div className="detail-topbar" data-product-transition-reveal>

View File

@ -3,7 +3,7 @@ import { useShop } from "../shop/useShop";
import { useTheme } from "../theme/useTheme"; import { useTheme } from "../theme/useTheme";
import "../style/navbar.css"; import "../style/navbar.css";
function SharedNavbar({ variant = "light", active = "" }) { function SharedNavbar({ variant = "hero", active = "" }) {
const { cart, openCart, openProfile, user } = useShop(); const { cart, openCart, openProfile, user } = useShop();
const { isLight, toggleTheme } = useTheme(); const { isLight, toggleTheme } = useTheme();
const cartLabel = const cartLabel =

View File

@ -5,7 +5,7 @@ import "./AboutPage.css";
function AboutPage() { function AboutPage() {
return ( return (
<div className="about-page"> <div className="about-page">
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<section className="about-hero" data-reveal-group> <section className="about-hero" data-reveal-group>

View File

@ -4,7 +4,7 @@ import "./DatenschutzPage.css";
function DatenschutzPage() { function DatenschutzPage() {
return ( return (
<div className="datenschutz-page"> <div className="datenschutz-page">
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<section className="datenschutz-hero" data-reveal-group> <section className="datenschutz-hero" data-reveal-group>

View File

@ -2,9 +2,7 @@
min-height: 100vh; min-height: 100vh;
padding: 0 0 var(--section-y-sm); padding: 0 0 var(--section-y-sm);
color: var(--theme-text); color: var(--theme-text);
background: background: var(--theme-bg);
radial-gradient(circle at 88% 6%, rgba(var(--theme-accent-rgb) / 0.12), transparent 30rem),
linear-gradient(180deg, var(--theme-bg), color-mix(in srgb, var(--theme-bg) 88%, #000 12%));
} }
.discovery-topbar { .discovery-topbar {
@ -95,10 +93,10 @@
} }
.discovery-hero-copy h1 { .discovery-hero-copy h1 {
max-width: 10.8ch; max-width: 9ch;
margin: clamp(0.75rem, 1.5vw, 1.15rem) 0 clamp(1rem, 2vw, 1.4rem); margin: clamp(0.75rem, 1.5vw, 1.15rem) 0 clamp(1rem, 2vw, 1.4rem);
color: var(--theme-text); color: var(--theme-text);
font-size: clamp(2.8rem, 4.8vw, 6rem); font-size: clamp(3.35rem, 6.2vw, 7.6rem);
line-height: 0.9; line-height: 0.9;
font-weight: 300; font-weight: 300;
letter-spacing: 0; letter-spacing: 0;
@ -107,7 +105,7 @@
} }
.discovery-intro { .discovery-intro {
max-width: var(--text-measure); max-width: 36ch;
margin: 0; margin: 0;
color: var(--theme-text-muted); color: var(--theme-text-muted);
font-size: var(--text-lg); font-size: var(--text-lg);
@ -117,13 +115,14 @@
.discovery-hero-visual { .discovery-hero-visual {
position: relative; position: relative;
grid-column: 4 / 10; grid-column: 5 / 10;
grid-row: 1; grid-row: 1;
justify-self: center; justify-self: center;
align-self: center; align-self: center;
z-index: 1; z-index: 1;
display: grid; display: grid;
place-items: center; place-items: center;
justify-items: end;
width: 100%; width: 100%;
min-height: inherit; min-height: inherit;
margin: 0; margin: 0;
@ -134,10 +133,13 @@
position: relative; position: relative;
z-index: 2; z-index: 2;
display: block; display: block;
width: min(100%, 560px); width: min(100%, 520px);
height: min(56svh, 640px);
max-height: min(68svh, 760px); max-height: min(68svh, 760px);
object-fit: contain; border: 1px solid var(--theme-border);
filter: drop-shadow(0 34px 72px rgba(0, 0, 0, 0.42)); object-fit: cover;
object-position: center;
filter: saturate(0.92) contrast(1.04) drop-shadow(0 34px 72px rgba(0, 0, 0, 0.42));
} }
.discovery-panel-facts div, .discovery-panel-facts div,
@ -151,6 +153,7 @@
color: var(--theme-text); color: var(--theme-text);
font-size: var(--text-base); font-size: var(--text-base);
line-height: 1.55; line-height: 1.55;
overflow-wrap: anywhere;
} }
.discovery-order-panel { .discovery-order-panel {
@ -216,15 +219,15 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 100%; width: 100%;
min-height: 52px; 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);
border-radius: 999px; border-radius: 0;
background: var(--theme-accent); background: var(--theme-accent);
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
font-size: var(--text-sm); font-size: var(--text-sm);
letter-spacing: 0.1em; letter-spacing: 0.12em;
line-height: 1.25; line-height: 1.25;
text-align: center; text-align: center;
text-transform: uppercase; text-transform: uppercase;
@ -250,6 +253,7 @@
color: var(--theme-text-muted); color: var(--theme-text-muted);
font-size: var(--text-sm); font-size: var(--text-sm);
line-height: 1.45; line-height: 1.45;
overflow-wrap: anywhere;
} }
.discovery-story-grid, .discovery-story-grid,
@ -338,21 +342,46 @@
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
align-content: end; align-content: end;
gap: var(--gap-md); gap: clamp(0.9rem, 1.8vw, 1.25rem);
min-height: clamp(360px, 42vw, 620px); min-height: clamp(360px, 42vw, 620px);
padding: clamp(1.2rem, 3vw, 2.4rem); padding: clamp(1.2rem, 3vw, 2.4rem);
border: 1px solid var(--theme-border); border: 1px solid var(--theme-border);
background: background:
radial-gradient(circle at 66% 32%, rgba(255, 255, 255, 0.1), transparent 14rem), linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.008)),
linear-gradient(135deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.01)), color-mix(in srgb, var(--theme-bg) 88%, #000 12%);
var(--theme-paper); }
.discovery-benefit-panel-head {
display: flex;
justify-content: space-between;
align-items: end;
gap: var(--gap-sm);
padding-bottom: clamp(1rem, 2vw, 1.35rem);
border-bottom: 1px solid var(--theme-border);
}
.discovery-benefit-panel-head span {
color: var(--theme-text-muted);
font-size: var(--text-xs);
letter-spacing: 0.22em;
text-transform: uppercase;
}
.discovery-benefit-panel-head strong {
color: var(--theme-text);
font-size: clamp(1.9rem, 4vw, 3.8rem);
font-weight: 300;
line-height: 0.9;
letter-spacing: 0;
white-space: nowrap;
} }
.discovery-benefit { .discovery-benefit {
display: grid; display: grid;
grid-template-columns: 2.2rem minmax(0, 1fr); grid-template-columns: 1.75rem minmax(0, 1fr);
gap: var(--gap-sm); gap: var(--gap-sm);
align-items: start; align-items: start;
padding-top: 1rem;
} }
.discovery-benefit-icon, .discovery-benefit-icon,
@ -360,12 +389,12 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 2rem; width: 1.55rem;
height: 2rem; height: 1.55rem;
border: 1px solid rgba(var(--theme-accent-rgb) / 0.48); border: 1px solid rgba(var(--theme-accent-rgb) / 0.48);
border-radius: 999px; border-radius: 0;
color: var(--theme-accent); color: var(--theme-accent);
font-size: 1rem; font-size: 0.82rem;
line-height: 1; line-height: 1;
} }
@ -391,13 +420,14 @@
} }
.discovery-section-heading { .discovery-section-heading {
display: grid; display: block;
grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
gap: var(--gap-lg);
align-items: end;
margin-bottom: clamp(1.8rem, 4vw, 3.8rem); margin-bottom: clamp(1.8rem, 4vw, 3.8rem);
} }
.discovery-section-heading h2 {
max-width: 11ch;
}
.discovery-steps-grid, .discovery-steps-grid,
.discovery-products-grid, .discovery-products-grid,
.discovery-comparison-grid { .discovery-comparison-grid {
@ -481,9 +511,7 @@
place-items: center; place-items: center;
min-height: 0; min-height: 0;
overflow: hidden; overflow: hidden;
background: background: transparent;
radial-gradient(circle at 50% 44%, rgba(255, 255, 255, 0.08), transparent 48%),
var(--theme-paper);
} }
.discovery-product-image img { .discovery-product-image img {
@ -629,12 +657,14 @@
.discovery-hero-visual { .discovery-hero-visual {
grid-column: auto; grid-column: auto;
grid-row: auto; grid-row: auto;
justify-items: center;
min-height: 0; min-height: 0;
height: min(42svh, 420px); height: min(42svh, 420px);
} }
.discovery-hero-visual img { .discovery-hero-visual img {
width: min(78%, 480px); width: min(100%, 480px);
height: 100%;
max-height: 100%; max-height: 100%;
} }
@ -705,7 +735,7 @@
} }
.discovery-hero-visual img { .discovery-hero-visual img {
width: min(88%, 380px); width: 100%;
} }
.discovery-panel-facts, .discovery-panel-facts,

View File

@ -4,7 +4,7 @@ import SharedNavbar from "../components/SharedNavbar";
import { useShop } from "../shop/useShop"; import { useShop } from "../shop/useShop";
import "./DiscoverySetPage.css"; import "./DiscoverySetPage.css";
const DISCOVERY_SET_IMAGE = "/DISCOVERYSET.png"; const DISCOVERY_SET_IMAGE = "/atmos-discovery-set-thumbnail.png";
const discoveryPanelFacts = [ const discoveryPanelFacts = [
{ label: "Umfang", value: "6 × 2ml" }, { label: "Umfang", value: "6 × 2ml" },
@ -81,9 +81,9 @@ function DiscoveryOrderPanel({ onBuy }) {
<div className="discovery-panel-actions"> <div className="discovery-panel-actions">
<button type="button" className="discovery-primary-btn" onClick={onBuy}> <button type="button" className="discovery-primary-btn" onClick={onBuy}>
DISCOVERY SET BESTELLEN CHF 48. Discovery Set bestellen CHF 48.
</button> </button>
<p>Nur das erste Set erstellt einen einmaligen CHF 48 Full-Size-Rabatt</p> <p>Nur das erste Set erstellt einen einmaligen CHF 48 Full-Size-Rabatt.</p>
</div> </div>
</aside> </aside>
); );
@ -94,18 +94,13 @@ function DiscoveryHero({ onBuy }) {
<section className="discovery-hero"> <section className="discovery-hero">
<div className="discovery-hero-stage"> <div className="discovery-hero-stage">
<div className="discovery-hero-copy"> <div className="discovery-hero-copy">
<span className="discovery-kicker">DISCOVERY SET</span> <span className="discovery-kicker">Der Einstieg</span>
<h1> <h1>Discovery Set</h1>
DER SICHERSTE EINSTIEG
<br />
IN DIE WELT DER NISCHEN-
<br />
DÜFTE
</h1>
<p className="discovery-intro"> <p className="discovery-intro">
6 Düfte × 2ml. Jeden Duft eine Woche tragen. Verstehen, was 6 Düfte × 2ml. Jeden Duft eine Woche tragen. Verstehen, was
wirklich funktioniert. Ohne Risiko. wirklich funktioniert. Ohne Risiko. Der sichere Einstieg in die
Welt der Nischendüfte, bevor du dich für eine Full Size entscheidest.
</p> </p>
</div> </div>
@ -117,7 +112,6 @@ function DiscoveryHero({ onBuy }) {
decoding="async" decoding="async"
/> />
</figure> </figure>
</div> </div>
<DiscoveryOrderPanel onBuy={onBuy} /> <DiscoveryOrderPanel onBuy={onBuy} />
@ -130,9 +124,9 @@ function DiscoveryStorySection() {
<section className="discovery-story-grid" data-reveal-group> <section className="discovery-story-grid" data-reveal-group>
<div className="discovery-story-copy"> <div className="discovery-story-copy">
<span className="discovery-label" data-reveal="fade"> <span className="discovery-label" data-reveal="fade">
WARUM DISCOVERY SET Warum Discovery Set
</span> </span>
<h2 data-reveal="lines">DER KLÜGERE EINSTIEG IN NISCHENDÜFTE.</h2> <h2 data-reveal="lines">Der klügere Einstieg in Nischendüfte.</h2>
<p data-reveal="fade"> <p data-reveal="fade">
Nischen-Parfums sind keine Impulskäufe. Sie brauchen Zeit, um zu Nischen-Parfums sind keine Impulskäufe. Sie brauchen Zeit, um zu
verstehen, wie sie auf deiner Haut funktionieren, wie sie sich im verstehen, wie sie auf deiner Haut funktionieren, wie sie sich im
@ -141,6 +135,11 @@ function DiscoveryStorySection() {
</div> </div>
<div className="discovery-benefit-panel" data-reveal="fade"> <div className="discovery-benefit-panel" data-reveal="fade">
<div className="discovery-benefit-panel-head">
<span>Testlogik</span>
<strong>6 × 2ml</strong>
</div>
{discoveryBenefits.map((benefit) => ( {discoveryBenefits.map((benefit) => (
<article className="discovery-benefit" key={benefit.title}> <article className="discovery-benefit" key={benefit.title}>
<span className="discovery-benefit-icon" aria-hidden="true"> <span className="discovery-benefit-icon" aria-hidden="true">
@ -162,7 +161,7 @@ function DiscoveryProcessSection() {
<section className="discovery-process-section" data-reveal-group> <section className="discovery-process-section" data-reveal-group>
<div className="discovery-section-intro"> <div className="discovery-section-intro">
<span className="discovery-label" data-reveal="fade"> <span className="discovery-label" data-reveal="fade">
ABLAUF Ablauf
</span> </span>
<h2 data-reveal="lines">So funktioniert&apos;s</h2> <h2 data-reveal="lines">So funktioniert&apos;s</h2>
</div> </div>
@ -185,9 +184,9 @@ function DiscoveryIncludedSection() {
<section className="discovery-included" data-reveal-group> <section className="discovery-included" data-reveal-group>
<div className="discovery-section-heading"> <div className="discovery-section-heading">
<span className="discovery-label" data-reveal="fade"> <span className="discovery-label" data-reveal="fade">
IM SET ENTHALTEN Im Set enthalten
</span> </span>
<h2 data-reveal="lines">ALLE 6 SIGNATURE-DÜFTE ZUM TESTEN.</h2> <h2 data-reveal="lines">Alle 6 Signature-Düfte zum Testen.</h2>
</div> </div>
<div className="discovery-products-grid"> <div className="discovery-products-grid">
@ -252,9 +251,9 @@ function DiscoveryFinalCta({ onBuy }) {
<section className="discovery-final-cta" data-reveal-group> <section className="discovery-final-cta" data-reveal-group>
<div> <div>
<span className="discovery-label" data-reveal="fade"> <span className="discovery-label" data-reveal="fade">
DISCOVERY SET Discovery Set
</span> </span>
<h2 data-reveal="lines">DER SICHERSTE EINSTIEG.</h2> <h2 data-reveal="lines">Der sichere Einstieg.</h2>
<p data-reveal="fade"> <p data-reveal="fade">
Kostenloser Versand · 23 Werktage · Einmalige Anrechnung bei Full-Size Kostenloser Versand · 23 Werktage · Einmalige Anrechnung bei Full-Size
</p> </p>
@ -262,7 +261,7 @@ function DiscoveryFinalCta({ onBuy }) {
<div className="discovery-final-actions" data-reveal="fade"> <div className="discovery-final-actions" data-reveal="fade">
<button type="button" className="discovery-primary-btn" onClick={onBuy}> <button type="button" className="discovery-primary-btn" onClick={onBuy}>
DISCOVERY SET BESTELLEN CHF 48. Discovery Set bestellen CHF 48.
</button> </button>
</div> </div>
</section> </section>
@ -277,7 +276,7 @@ function DiscoverySetPage() {
return ( return (
<div className="discovery-page"> <div className="discovery-page">
<SharedNavbar variant="light" active="testen" /> <SharedNavbar variant="hero" active="testen" />
<main className="shell"> <main className="shell">
<div className="discovery-topbar"> <div className="discovery-topbar">

View File

@ -4,7 +4,7 @@ import "./ImpressumPage.css";
function ImpressumPage() { function ImpressumPage() {
return ( return (
<div className="impressum-page"> <div className="impressum-page">
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<section className="impressum-hero" data-reveal-group> <section className="impressum-hero" data-reveal-group>

View File

@ -60,7 +60,7 @@ function SmallBatchPage() {
return ( return (
<div className="small-page"> <div className="small-page">
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<section className="small-hero" data-reveal-group> <section className="small-hero" data-reveal-group>

View File

@ -5,7 +5,7 @@ import "./SupportPage.css";
function SupportPage() { function SupportPage() {
return ( return (
<div className="support-page"> <div className="support-page">
<SharedNavbar variant="light" /> <SharedNavbar variant="hero" />
<main className="shell"> <main className="shell">
<section className="support-hero" data-reveal-group> <section className="support-hero" data-reveal-group>