-

+
+
+
+
+

+
+
+
+
+
+

+
+
+
-
-
+
+
- {"D\u00DCFTE ALS"}
+ {"Konzeptionelle D\u00FCfte"}
-
+
- AUSDRUCK
+ {"zwischen Materialit\u00E4t,"}
+
+ Raum und Charakter.
+
-
- {
- "Konzeptionelle D\u00FCfte zwischen Materialit\u00E4t, Raum und Charakter."
- }
-
-
+
+
+ SCROLL RUNTER
+
+
-
+
);
}
diff --git a/parfum-shop/src/pages/LandingPage.css b/parfum-shop/src/pages/LandingPage.css
index aebebe6..af9129b 100644
--- a/parfum-shop/src/pages/LandingPage.css
+++ b/parfum-shop/src/pages/LandingPage.css
@@ -1,9 +1,6 @@
.page {
position: relative;
min-height: 100vh;
- background:
- radial-gradient(circle at 82% 12%, rgba(var(--theme-accent-rgb) / 0.13), transparent 28rem),
- linear-gradient(180deg, var(--theme-bg), color-mix(in srgb, var(--theme-bg) 88%, #000 12%));
color: var(--theme-text);
}
@@ -27,112 +24,139 @@
.hero {
position: relative;
width: 100%;
- min-height: clamp(680px, 100svh, 980px);
+ min-height: 720px;
+ min-height: max(720px, 100vh);
+ min-height: max(720px, 100dvh);
overflow: hidden;
- display: grid;
- align-items: center;
isolation: isolate;
- background: #111;
+ background: var(--theme-bg);
+ transition: background-color var(--duration-med) var(--ease-out);
}
-.hero::before {
+.hero::after {
content: "";
position: absolute;
inset: 0;
- z-index: 2;
+ z-index: 1;
pointer-events: none;
+ background: none;
}
-.hero::before {
- background:
- radial-gradient(circle at 72% 42%, rgba(255, 255, 255, 0.1), transparent 24rem),
- linear-gradient(90deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.42) 44%, rgba(0, 0, 0, 0.08) 100%),
- linear-gradient(0deg, rgba(0, 0, 0, 0.44), transparent 46%);
+.hero-material {
+ position: absolute;
+ inset: 0;
+ z-index: 0;
+ overflow: hidden;
+ background: var(--theme-bg);
+ will-change: transform;
}
-.hero-media {
+.hero-material__texture {
position: absolute;
inset: 0;
z-index: 1;
+ background: var(--theme-bg);
will-change: transform;
}
-.hero-media__image {
+.hero-wordmark {
+ position: absolute;
+ top: clamp(3.4rem, 6vh, 5.5rem);
+ left: var(--page-x);
+ right: var(--page-x);
+ z-index: 2;
+ pointer-events: none;
+ user-select: none;
+}
+
+.hero-wordmark__mask {
+ overflow: hidden;
+ padding-top: 0.08rem;
+}
+
+.hero-wordmark__image {
+ display: block;
+ width: 100%;
+ height: auto;
+ opacity: 0.96;
+ will-change: transform, opacity, filter;
+}
+
+body.theme-light .hero-wordmark__image {
+ filter: invert(1);
+ opacity: 0.86;
+}
+
+.hero-product {
+ position: absolute;
+ top: clamp(22rem, 58vh, 44rem);
+ left: 50%;
+ z-index: 5;
+ width: clamp(19rem, 29vw, 38rem);
+ aspect-ratio: 1078 / 1284;
+ margin: 0;
+ display: grid;
+ place-items: center;
+ transform: translate(-50%, -50%);
+ will-change: transform;
+}
+
+.hero-product__inner {
+ position: relative;
width: 100%;
height: 100%;
- display: block;
- object-fit: cover;
- object-position: 60% center;
- will-change: transform;
-}
-
-.hero .navbar--hero {
- position: fixed;
- top: clamp(0.75rem, 2.1vw, 1.4rem);
- right: 0;
- left: 0;
- z-index: 998;
- padding-top: 0;
-}
-
-.hero-content {
- position: relative;
- z-index: 6;
- width: var(--container-wide);
- margin: 0 auto;
- padding: clamp(7rem, 14vh, 11rem) 0 clamp(3rem, 8vh, 6rem);
display: grid;
- grid-template-columns: repeat(12, minmax(0, 1fr));
- gap: var(--gap-md);
- align-items: center;
-}
-
-.hero-title {
- grid-column: 1 / span 7;
- max-width: 10.8ch;
- margin: 0;
- font-size: clamp(3.2rem, 8.4vw, 8.8rem);
- line-height: 0.9;
- font-weight: 300;
- letter-spacing: 0;
- text-transform: uppercase;
- color: #fff;
- text-wrap: balance;
-}
-
-.hero-title-line {
- display: block;
- overflow: hidden;
- padding-right: 0.12em;
- padding-bottom: 0.08em;
- margin-right: -0.12em;
- margin-bottom: -0.08em;
-}
-
-.hero-title-line .reveal-line {
- will-change: transform;
-}
-
-.hero-title-line + .hero-title-line {
- margin-top: 0.02em;
-}
-
-.hero-text {
- grid-column: 1 / span 5;
- max-width: 31rem;
- margin: 0;
- font-size: var(--text-base);
- line-height: 1.62;
- color: rgba(255, 255, 255, 0.84);
+ place-items: center;
will-change: transform, opacity;
}
+.hero-product__image {
+ position: relative;
+ z-index: 1;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+}
+
+.hero-content {
+ position: absolute;
+ left: var(--page-x);
+ bottom: clamp(7.5rem, 19vh, 17rem);
+ z-index: 6;
+ width: min(25rem, calc(50vw - var(--page-x) - 8rem));
+ color: var(--theme-text);
+}
+
+.hero-copy {
+ max-width: 25rem;
+ margin: 0;
+ font-size: clamp(1.65rem, 2.25vw, 2.25rem);
+ line-height: 1.08;
+ font-weight: 300;
+ letter-spacing: 0;
+ color: var(--theme-text);
+}
+
+.hero-copy-line {
+ display: block;
+ overflow: hidden;
+ padding-right: 0.08em;
+ padding-bottom: 0.03em;
+ margin-right: -0.08em;
+ margin-bottom: -0.03em;
+}
+
+.hero-copy-line .reveal-line {
+ display: inline-block;
+ will-change: transform;
+}
+
.hero-actions {
- grid-column: 1 / span 5;
display: flex;
flex-wrap: wrap;
- gap: var(--gap-xs);
- margin-top: clamp(0.2rem, 1vw, 0.7rem);
+ gap: clamp(0.75rem, 1.2vw, 1rem);
+ margin-top: clamp(1.25rem, 3.2vh, 1.75rem);
will-change: transform, opacity;
}
@@ -173,10 +197,34 @@
}
.btn-secondary {
- background: rgba(255, 255, 255, 0.13);
- color: #fff;
- border: 1px solid rgba(255, 255, 255, 0.24);
- backdrop-filter: blur(12px);
+ background: color-mix(in srgb, var(--theme-surface) 72%, transparent);
+ color: var(--theme-text);
+ border: 1px solid var(--theme-border-strong);
+ backdrop-filter: blur(10px);
+}
+
+.hero-scroll {
+ position: absolute;
+ right: var(--page-x);
+ bottom: clamp(7.5rem, 19vh, 17rem);
+ z-index: 6;
+ width: min(28vw, 420px);
+ padding-top: 0.55rem;
+ border-top: 1px solid var(--theme-border-strong);
+ color: var(--theme-text-muted);
+}
+
+.hero-scroll__line {
+ display: none;
+}
+
+.hero-scroll__label {
+ display: block;
+ margin: 0;
+ font-size: var(--text-xs);
+ line-height: 1.4;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
}
.intro-overlay {
@@ -579,17 +627,20 @@
/* RESPONSIVE */
@media (max-width: 1180px) {
+ .hero-copy {
+ font-size: clamp(1.45rem, 2.35vw, 1.9rem);
+ }
+
+ .hero-product {
+ width: clamp(21rem, 45vw, 34rem);
+ }
+
.hero-content {
- grid-template-columns: repeat(8, minmax(0, 1fr));
+ width: min(23rem, calc(50vw - var(--page-x) - 5rem));
}
- .hero-title {
- grid-column: 1 / span 6;
- }
-
- .hero-text,
- .hero-actions {
- grid-column: 1 / span 4;
+ .hero-scroll {
+ width: clamp(9rem, 16vw, 12rem);
}
.section-heading {
@@ -621,45 +672,55 @@
@media (max-width: 760px) {
.hero {
- min-height: clamp(620px, 91svh, 760px);
+ min-height: 720px;
+ min-height: max(720px, 100vh);
+ min-height: max(720px, 100dvh);
}
- .hero::before {
- background:
- linear-gradient(90deg, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0.28)),
- linear-gradient(0deg, rgba(0, 0, 0, 0.62), transparent 48%);
+ .hero-material__texture {
+ inset: 0;
}
- .hero-media__image {
- object-position: 64% center;
+ .hero-wordmark {
+ top: clamp(5.8rem, 14svh, 7.5rem);
+ left: var(--page-x);
+ right: var(--page-x);
+ }
+
+ .hero-product {
+ top: clamp(20.75rem, 49svh, 25.5rem);
+ left: 44%;
+ width: min(72vw, 19rem);
+ transform: translate(-50%, -58%);
}
.hero-content {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-end;
- gap: var(--gap-sm);
- padding-top: clamp(6.5rem, 18svh, 8.5rem);
- padding-bottom: clamp(2.4rem, 8svh, 4rem);
+ left: clamp(1rem, 5vw, 1.5rem);
+ right: clamp(1rem, 5vw, 1.5rem);
+ bottom: clamp(2rem, 7svh, 4rem);
+ transform: none;
+ width: auto;
+ max-width: 27rem;
}
- .hero-title {
- max-width: 9.6ch;
- font-size: clamp(3rem, 17.5vw, 5.1rem);
- }
-
- .hero-text {
- max-width: 25rem;
- font-size: var(--text-sm);
+ .hero-copy {
+ font-size: clamp(1.55rem, 7vw, 2rem);
+ line-height: 1.08;
}
.hero-actions {
- width: min(100%, 22rem);
+ gap: 0.65rem;
+ margin-top: 1.1rem;
}
.hero-actions .btn {
- width: 100%;
+ min-height: 44px;
+ padding-inline: 0.95rem;
+ font-size: 0.78rem;
+ }
+
+ .hero-scroll {
+ display: none;
}
.product-grid {
@@ -693,8 +754,20 @@
}
@media (max-width: 430px) {
- .hero-title {
- max-width: 9.2ch;
+ .hero {
+ min-height: 700px;
+ min-height: max(700px, 100vh);
+ min-height: max(700px, 100dvh);
+ }
+
+ .hero-product {
+ top: clamp(20.25rem, 48svh, 24.5rem);
+ left: 43%;
+ width: min(74vw, 18.25rem);
+ }
+
+ .hero-copy {
+ font-size: clamp(1.42rem, 7vw, 1.72rem);
}
.section-heading h2,
@@ -723,11 +796,14 @@
}
@media (prefers-reduced-motion: reduce) {
- .hero-media,
- .hero-title-line,
- .hero-text,
+ .hero-material,
+ .hero-material__texture,
+ .hero-copy-line,
+ .hero-wordmark__image,
+ .hero-product,
+ .hero-product__inner,
+ .hero-product__image,
.hero-actions,
- .hero-brand,
.intro-overlay,
.product-card,
.product-image,
diff --git a/parfum-shop/src/pages/LandingPage.jsx b/parfum-shop/src/pages/LandingPage.jsx
index 24a18d7..fa762f2 100644
--- a/parfum-shop/src/pages/LandingPage.jsx
+++ b/parfum-shop/src/pages/LandingPage.jsx
@@ -25,6 +25,7 @@ function LandingPage() {
const overlayTextRef = useRef(null);
const heroImageWrapRef = useRef(null);
const heroImageRef = useRef(null);
+ const heroWordmarkRef = useRef(null);
const discoveryImageRef = useRef(null);
const headlineLineRefs = useRef([]);
const heroMetaRefs = useRef([]);
@@ -56,6 +57,10 @@ function LandingPage() {
headlineLineRefs.current[1] = element;
}, []);
+ const setWordmarkRef = useCallback((element) => {
+ heroWordmarkRef.current = element;
+ }, []);
+
const setDescriptionRef = useCallback((element) => {
heroMetaRefs.current[0] = element;
}, []);
@@ -64,23 +69,31 @@ function LandingPage() {
heroMetaRefs.current[1] = element;
}, []);
+ const setScrollRef = useCallback((element) => {
+ heroMetaRefs.current[2] = element;
+ }, []);
+
useLayoutEffect(() => {
const overlay = overlayRef.current;
const overlayText = overlayTextRef.current;
const heroImageWrap = heroImageWrapRef.current;
+ const heroWordmark = heroWordmarkRef.current;
const headlineLines = headlineLineRefs.current.filter(Boolean);
- const heroMeta = heroMetaRefs.current.filter(Boolean);
+ const heroProduct = heroMetaRefs.current[0];
+ const heroMeta = heroMetaRefs.current.slice(1).filter(Boolean);
- if (!overlay || !overlayText || !heroImageWrap || headlineLines.length === 0) {
+ if (
+ !overlay ||
+ !overlayText ||
+ !heroImageWrap ||
+ !heroWordmark ||
+ !heroProduct ||
+ headlineLines.length === 0
+ ) {
return undefined;
}
const ctx = gsap.context(() => {
- gsap.set(heroImageWrap, {
- scale: 1.22,
- transformOrigin: "center center",
- });
-
gsap.set(headlineLines, {
yPercent: 115,
rotate: 2.2,
@@ -88,13 +101,69 @@ function LandingPage() {
force3D: true,
});
+ gsap.set(heroWordmark, {
+ yPercent: 118,
+ autoAlpha: 0,
+ force3D: true,
+ });
+
+ gsap.set(heroProduct, {
+ scale: 0.82,
+ y: 54,
+ autoAlpha: 0,
+ transformOrigin: "50% 50%",
+ force3D: true,
+ });
+
gsap.set(heroMeta, {
- y: 36,
+ y: 30,
autoAlpha: 0,
});
- if (!shouldPlayIntro) {
- gsap.set(heroImageWrap, { scale: 1 });
+ const revealHero = () =>
+ gsap
+ .timeline({ defaults: { ease: "power4.out" } })
+ .to(heroWordmark, {
+ yPercent: 0,
+ autoAlpha: 1,
+ duration: 1.18,
+ ease: "expo.out",
+ })
+ .to(
+ heroProduct,
+ {
+ scale: 1,
+ y: 0,
+ autoAlpha: 1,
+ duration: 1.42,
+ ease: "expo.out",
+ },
+ "<0.16"
+ )
+ .to(
+ headlineLines,
+ {
+ yPercent: 0,
+ rotate: 0,
+ duration: 1.08,
+ stagger: 0.08,
+ },
+ "<0.34"
+ )
+ .to(
+ heroMeta,
+ {
+ y: 0,
+ autoAlpha: 1,
+ duration: 0.86,
+ stagger: 0.1,
+ },
+ "<0.18"
+ );
+
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
+ gsap.set(heroWordmark, { yPercent: 0, autoAlpha: 1 });
+ gsap.set(heroProduct, { scale: 1, y: 0, autoAlpha: 1 });
gsap.set(headlineLines, { yPercent: 0, rotate: 0 });
gsap.set(heroMeta, { y: 0, autoAlpha: 1 });
gsap.set(overlay, {
@@ -105,6 +174,16 @@ function LandingPage() {
return;
}
+ if (!shouldPlayIntro) {
+ gsap.set(overlay, {
+ yPercent: -100,
+ autoAlpha: 0,
+ display: "none",
+ });
+ revealHero();
+ return;
+ }
+
gsap.set(overlay, { yPercent: 0, autoAlpha: 1, display: "block" });
gsap.set(overlayText, { xPercent: 28, yPercent: 140, autoAlpha: 0 });
@@ -133,37 +212,7 @@ function LandingPage() {
},
">"
)
- .to(
- heroImageWrap,
- {
- scale: 1,
- duration: 1.6,
- ease: "power2.out",
- },
- "<0.03"
- )
- .to(
- headlineLines,
- {
- yPercent: 0,
- rotate: 0,
- duration: 1.18,
- stagger: 0.1,
- ease: "power4.out",
- },
- "<0.27"
- )
- .to(
- heroMeta,
- {
- y: 0,
- autoAlpha: 1,
- duration: 1.02,
- stagger: 0.12,
- ease: "power4.out",
- },
- "<0.16"
- )
+ .add(revealHero(), "<0.1")
.set(overlay, { display: "none" });
}, pageRef);
@@ -385,8 +434,10 @@ function LandingPage() {
heroImageRef={heroImageRef}
setHeadlinePrimaryRef={setHeadlinePrimaryRef}
setHeadlineSecondaryRef={setHeadlineSecondaryRef}
+ setWordmarkRef={setWordmarkRef}
setDescriptionRef={setDescriptionRef}
setActionsRef={setActionsRef}
+ setScrollRef={setScrollRef}
overlayRef={overlayRef}
overlayTextRef={overlayTextRef}
/>
diff --git a/parfum-shop/src/style/navbar.css b/parfum-shop/src/style/navbar.css
index eb5b02d..93c1c04 100644
--- a/parfum-shop/src/style/navbar.css
+++ b/parfum-shop/src/style/navbar.css
@@ -218,6 +218,11 @@
.nav-theme-switch {
padding-inline: 0.45rem;
}
+
+ .navbar--hero .nav-pill {
+ width: fit-content;
+ max-width: calc(100vw - 1.5rem);
+ }
}
@media (max-width: 390px) {