adding page visit animation and hero changes

This commit is contained in:
Ermin Zoronjic 2026-04-07 19:31:22 +02:00
parent b6e57ba551
commit 0b5d248c4e
7 changed files with 490 additions and 109 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 46.43 9.21">
<defs>
<style>
.cls-1 {
fill: #262626;
}
</style>
</defs>
<g>
<path class="cls-1" d="M4.05,8.93c-.82,0-1.53-.19-2.14-.58-.61-.39-1.08-.91-1.42-1.57-.34-.66-.5-1.38-.5-2.18s.17-1.53.5-2.19c.33-.65.81-1.17,1.42-1.56.61-.39,1.32-.58,2.14-.58.69,0,1.29.13,1.78.4s.9.63,1.21,1.09V.42h1.26v8.37h-1.26v-1.34c-.31.45-.72.8-1.21,1.07-.5.27-1.09.4-1.78.4ZM4.22,7.79c.62,0,1.15-.14,1.58-.44.43-.29.76-.68.98-1.16.22-.49.33-1.01.33-1.58s-.11-1.11-.33-1.59c-.22-.48-.55-.86-.98-1.16s-.96-.44-1.58-.44-1.14.15-1.59.44-.79.68-1.02,1.16c-.23.48-.35,1.01-.35,1.59s.12,1.1.35,1.58c.23.49.58.87,1.02,1.16.45.29.98.44,1.59.44Z"/>
<path class="cls-1" d="M43.01,8.93c-.77,0-1.42-.13-1.95-.39-.53-.26-.94-.59-1.21-1.01-.28-.42-.43-.87-.47-1.37h1.31c.03.28.13.55.29.81s.41.47.75.64c.33.16.77.24,1.31.24.17,0,.37-.02.62-.05s.48-.09.71-.18.42-.22.58-.4.23-.41.23-.69c0-.35-.13-.61-.4-.8-.27-.19-.61-.34-1.04-.44-.43-.11-.88-.21-1.35-.31-.47-.1-.92-.23-1.35-.39-.43-.16-.77-.39-1.04-.69s-.4-.7-.4-1.21c0-.76.28-1.35.83-1.77.55-.42,1.37-.63,2.45-.63.74,0,1.34.12,1.8.34.46.23.82.52,1.05.88.24.36.38.74.43,1.16h-1.27c-.04-.36-.22-.66-.53-.92-.31-.26-.81-.39-1.52-.39-1.33,0-1.99.4-1.99,1.21,0,.33.13.59.4.77.27.18.61.32,1.04.43.42.11.87.21,1.35.3.47.1.92.23,1.35.39s.77.4,1.04.71c.27.31.4.72.4,1.25,0,.82-.31,1.44-.93,1.87-.62.43-1.45.65-2.49.65Z"/>
</g>
<circle class="cls-1" cx="13.97" cy="4.6" r="4.6"/>
<circle class="cls-1" cx="24.01" cy="4.6" r="4.6"/>
<circle class="cls-1" cx="33.99" cy="4.6" r="4.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 46.43 9.21">
<defs>
<style>
.cls-1 {
fill: #eaeaea;
}
</style>
</defs>
<g>
<path class="cls-1" d="M4.05,8.93c-.82,0-1.53-.19-2.14-.58-.61-.39-1.08-.91-1.42-1.57-.34-.66-.5-1.38-.5-2.18s.17-1.53.5-2.19c.33-.65.81-1.17,1.42-1.56.61-.39,1.32-.58,2.14-.58.69,0,1.29.13,1.78.4s.9.63,1.21,1.09V.42h1.26v8.37h-1.26v-1.34c-.31.45-.72.8-1.21,1.07-.5.27-1.09.4-1.78.4ZM4.22,7.79c.62,0,1.15-.14,1.58-.44.43-.29.76-.68.98-1.16.22-.49.33-1.01.33-1.58s-.11-1.11-.33-1.59c-.22-.48-.55-.86-.98-1.16s-.96-.44-1.58-.44-1.14.15-1.59.44-.79.68-1.02,1.16c-.23.48-.35,1.01-.35,1.59s.12,1.1.35,1.58c.23.49.58.87,1.02,1.16.45.29.98.44,1.59.44Z"/>
<path class="cls-1" d="M43.01,8.93c-.77,0-1.42-.13-1.95-.39-.53-.26-.94-.59-1.21-1.01-.28-.42-.43-.87-.47-1.37h1.31c.03.28.13.55.29.81s.41.47.75.64c.33.16.77.24,1.31.24.17,0,.37-.02.62-.05s.48-.09.71-.18.42-.22.58-.4.23-.41.23-.69c0-.35-.13-.61-.4-.8-.27-.19-.61-.34-1.04-.44-.43-.11-.88-.21-1.35-.31-.47-.1-.92-.23-1.35-.39-.43-.16-.77-.39-1.04-.69s-.4-.7-.4-1.21c0-.76.28-1.35.83-1.77.55-.42,1.37-.63,2.45-.63.74,0,1.34.12,1.8.34.46.23.82.52,1.05.88.24.36.38.74.43,1.16h-1.27c-.04-.36-.22-.66-.53-.92-.31-.26-.81-.39-1.52-.39-1.33,0-1.99.4-1.99,1.21,0,.33.13.59.4.77.27.18.61.32,1.04.43.42.11.87.21,1.35.3.47.1.92.23,1.35.39s.77.4,1.04.71c.27.31.4.72.4,1.25,0,.82-.31,1.44-.93,1.87-.62.43-1.45.65-2.49.65Z"/>
</g>
<circle class="cls-1" cx="13.97" cy="4.6" r="4.6"/>
<circle class="cls-1" cx="24.01" cy="4.6" r="4.6"/>
<circle class="cls-1" cx="33.99" cy="4.6" r="4.6"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,87 @@
import { Link } from "react-router";
import IntroOverlay from "./IntroOverlay";
function HeroSection({
heroImageWrapRef,
setHeadlinePrimaryRef,
setHeadlineSecondaryRef,
setDescriptionRef,
setActionsRef,
overlayRef,
overlayTextRef,
}) {
return (
<header className="hero" id="home">
<div className="hero-media" ref={heroImageWrapRef}>
<img
src="/atmos-hero-image.png"
alt="Atmos Hero"
className="hero-media__image"
loading="eager"
fetchPriority="high"
/>
</div>
<Link to="/" className="hero-brand" aria-label="Atmos Startseite">
<img
src="/atmos-logo-light.svg"
alt="atmos"
className="hero-brand__logo"
loading="eager"
fetchPriority="high"
/>
</Link>
<nav className="navbar navbar--hero" aria-label="Hauptnavigation">
<div className="nav-pill">
<a href="#home" className="nav-link active">
atmos
</a>
<a href="#dufte" className="nav-link">
{"D\u00FCfte"}
</a>
<Link to="/discovery-set" className="nav-link">
Testen
</Link>
<a href="#cart" className="nav-link">
Cart
</a>
</div>
</nav>
<div className="hero-content">
<h1 className="hero-title">
<span className="hero-title-line" ref={setHeadlinePrimaryRef}>
{"D\u00DCFTE ALS"}
</span>
<span className="hero-title-line" ref={setHeadlineSecondaryRef}>
AUSDRUCK
</span>
</h1>
<p className="hero-text" ref={setDescriptionRef}>
{
"Konzeptionelle D\u00FCfte zwischen Materialit\u00E4t, Raum und Charakter."
}
</p>
<div className="hero-actions" ref={setActionsRef}>
<a href="#dufte" className="btn btn-primary">
{"Aktuelle D\u00FCfte"}
</a>
<Link to="/discovery-set" className="btn btn-secondary">
Discovery Set
</Link>
</div>
</div>
<IntroOverlay
overlayRef={overlayRef}
overlayTextRef={overlayTextRef}
logoSrc="/atmos-logo-dark.svg"
/>
</header>
);
}
export default HeroSection;

View File

@ -0,0 +1,15 @@
function IntroOverlay({ overlayRef, overlayTextRef, logoSrc }) {
return (
<div className="intro-overlay" ref={overlayRef} aria-hidden="true">
<div className="intro-overlay__inner">
<div className="intro-overlay__text-mask">
<div className="intro-overlay__logo" ref={overlayTextRef}>
<img src={logoSrc} alt="atmos" />
</div>
</div>
</div>
</div>
);
}
export default IntroOverlay;

View File

@ -4,78 +4,135 @@
color: #1f1f1f; color: #1f1f1f;
} }
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* HERO */ /* HERO */
.hero { .hero {
position: relative; position: relative;
min-height: 720px; width: 100%;
margin-left: 20px; min-height: 100vh;
margin-right: 20px; min-height: 100svh;
margin-top: 0px; min-height: 100dvh;
border-radius: 0;
overflow: hidden; overflow: hidden;
background-image: url("/HERO.jpeg"); display: flex;
background-size: cover; align-items: center;
background-position: center; isolation: isolate;
background: #111;
} }
.hero-overlay { .hero-media {
position: absolute; position: absolute;
inset: 0; inset: 0;
background: z-index: 1;
linear-gradient(to right, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.1)), will-change: transform;
linear-gradient(to bottom, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.45)); }
.hero-media__image {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
object-position: center;
}
.hero .navbar--hero {
position: absolute;
top: 22px;
left: 0;
right: 0;
z-index: 12;
padding-top: 0;
}
.hero-brand {
position: absolute;
top: 22px;
left: clamp(1rem, 1.45vw, 20px);
z-index: 14;
display: inline-flex;
align-items: center;
}
.hero-brand__logo {
display: block;
width: clamp(74px, 8vw, 112px);
height: auto;
} }
.hero-content { .hero-content {
position: relative; position: relative;
z-index: 2; z-index: 6;
max-width: 460px; width: min(760px, 100%);
padding: 120px 0 0 38px; padding: clamp(6rem, 11vh, 9rem) clamp(1.2rem, 3.4vw, 3rem)
color: white; clamp(2.6rem, 7vh, 4rem);
display: flex;
flex-direction: column;
justify-content: center;
} }
.eyebrow { .hero-title {
margin-bottom: 16px; margin: 0;
font-size: 12px; font-size: clamp(2.8rem, 8.5vw, 6.4rem);
letter-spacing: 0.18em; line-height: 0.88;
opacity: 0.85;
}
.hero h1 {
margin: 0 0 18px;
font-size: 62px;
line-height: 0.95;
font-weight: 300; font-weight: 300;
letter-spacing: -0.04em; letter-spacing: -0.045em;
color: white; text-transform: uppercase;
color: #fff;
}
.hero-title-line {
display: block;
will-change: transform, opacity;
}
.hero-title-line + .hero-title-line {
margin-top: 0.1em;
} }
.hero-text { .hero-text {
max-width: 320px; margin-top: 1.25rem;
font-size: 15px; max-width: 29rem;
line-height: 1.5; font-size: 0.99rem;
color: rgba(255, 255, 255, 0.85); line-height: 1.58;
color: rgba(255, 255, 255, 0.86);
will-change: transform, opacity;
} }
.hero-actions { .hero-actions {
display: flex; display: flex;
flex-wrap: wrap;
gap: 12px; gap: 12px;
margin-top: 28px; margin-top: 1.9rem;
will-change: transform, opacity;
} }
.btn { .btn {
border: none; border: none;
border-radius: 999px; border-radius: 999px;
padding: 12px 18px; padding: 12px 20px;
font-size: 14px; font-size: 0.9rem;
cursor: pointer; cursor: pointer;
transition: transform 0.2s ease, opacity 0.2s ease; transition: transform 0.24s ease, opacity 0.24s ease;
text-decoration: none; text-decoration: none;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.hero .btn {
border-radius: 0;
}
.btn:hover { .btn:hover {
transform: translateY(-1px); transform: translateY(-1px);
} }
@ -86,14 +143,51 @@
} }
.btn-secondary { .btn-secondary {
background: rgba(255, 255, 255, 0.15); background: rgba(255, 255, 255, 0.16);
color: #fff; color: #fff;
border: 1px solid rgba(255, 255, 255, 0.22);
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
} }
.intro-overlay {
position: absolute;
inset: 0;
z-index: 26;
background: #fff;
display: grid;
place-items: center;
will-change: transform;
}
.intro-overlay__inner {
width: 100%;
height: 100%;
display: grid;
place-items: center;
padding: clamp(1rem, 4vw, 2.2rem);
}
.intro-overlay__text-mask {
width: min(96vw, 1200px);
display: flex;
justify-content: center;
overflow: hidden;
}
.intro-overlay__logo {
width: clamp(100px, 20vw, 340px);
max-width: 92vw;
}
.intro-overlay__logo img {
width: 100%;
height: auto;
display: block;
}
/* SECTIONS */ /* SECTIONS */
.section { .section {
padding: 28px 20px 10px; padding: 42px 20px 10px;
} }
.section-heading { .section-heading {
@ -123,7 +217,7 @@
overflow: hidden; overflow: hidden;
background: #f5f5f5; background: #f5f5f5;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
border-radius: 0px; border-radius: 0;
padding: 18px; padding: 18px;
min-height: 360px; min-height: 360px;
display: flex; display: flex;
@ -224,7 +318,7 @@
max-width: 600px; max-width: 600px;
height: auto; height: auto;
object-fit: contain; object-fit: contain;
border-radius: 0px; border-radius: 0;
transition: transform 0.4s ease; transition: transform 0.4s ease;
} }
@ -292,7 +386,7 @@
align-items: center; align-items: center;
background: #ff6a00; background: #ff6a00;
margin: 20px; margin: 20px;
border-radius: 0px; border-radius: 0;
padding: 40px 38px; padding: 40px 38px;
} }
@ -355,18 +449,19 @@
/* RESPONSIVE */ /* RESPONSIVE */
@media (max-width: 900px) { @media (max-width: 900px) {
.hero {
min-height: 620px;
}
.hero-content { .hero-content {
padding: 90px 24px 40px; width: min(640px, 100%);
padding-top: 7rem;
} }
.hero h1, .hero-title,
.section-heading h2, .section-heading h2,
.discovery-copy h2 { .discovery-copy h2 {
font-size: 42px; font-size: clamp(2.45rem, 9vw, 3.2rem);
}
.hero-text {
font-size: 0.94rem;
} }
.product-grid { .product-grid {
@ -379,20 +474,36 @@
} }
@media (max-width: 640px) { @media (max-width: 640px) {
.hero { .hero-brand {
margin: 12px; top: 14px;
min-height: 540px;
} }
.hero h1, .hero .navbar--hero {
top: 14px;
}
.hero-content {
padding: 6.2rem 1rem 2.3rem;
}
.hero-title,
.section-heading h2, .section-heading h2,
.discovery-copy h2 { .discovery-copy h2 {
font-size: 34px; font-size: clamp(2.05rem, 13vw, 2.7rem);
} }
.hero-actions { .hero-actions {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
width: min(300px, 100%);
}
.hero-actions .btn {
width: 100%;
}
.section {
padding: 34px 12px 10px;
} }
.product-grid { .product-grid {
@ -402,4 +513,21 @@
.product-card { .product-card {
min-height: 320px; min-height: 320px;
} }
}
.discovery-section {
margin: 12px;
padding: 28px 20px;
}
}
@media (prefers-reduced-motion: reduce) {
.hero-media,
.hero-title-line,
.hero-text,
.hero-actions,
.hero-brand,
.intro-overlay {
transition: none !important;
animation: none !important;
}
}

View File

@ -1,13 +1,162 @@
import { useEffect, useRef } from "react"; import {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react";
import { Link } from "react-router"; import { Link } from "react-router";
import { gsap } from "gsap"; import { gsap } from "gsap";
import HeroSection from "../components/landing/HeroSection";
import perfumes from "../data/perfumes"; import perfumes from "../data/perfumes";
import "../pages/LandingPage.css"; import "../pages/LandingPage.css";
import "../style/navbar.css"; import "../style/navbar.css";
const INTRO_SESSION_KEY = "atmos-landing-intro-played";
function LandingPage() { function LandingPage() {
const pageRef = useRef(null);
const overlayRef = useRef(null);
const overlayTextRef = useRef(null);
const heroImageWrapRef = useRef(null);
const headlineLineRefs = useRef([]);
const heroMetaRefs = useRef([]);
const cardRefs = useRef([]); const cardRefs = useRef([]);
const [introSettings] = useState(() => {
if (typeof window === "undefined") {
return { shouldPlayIntro: true };
}
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
const introAlreadyPlayed =
window.sessionStorage.getItem(INTRO_SESSION_KEY) === "true";
return {
shouldPlayIntro: !prefersReducedMotion && !introAlreadyPlayed,
};
});
const { shouldPlayIntro } = introSettings;
const setHeadlinePrimaryRef = useCallback((element) => {
headlineLineRefs.current[0] = element;
}, []);
const setHeadlineSecondaryRef = useCallback((element) => {
headlineLineRefs.current[1] = element;
}, []);
const setDescriptionRef = useCallback((element) => {
heroMetaRefs.current[0] = element;
}, []);
const setActionsRef = useCallback((element) => {
heroMetaRefs.current[1] = element;
}, []);
useLayoutEffect(() => {
const overlay = overlayRef.current;
const overlayText = overlayTextRef.current;
const heroImageWrap = heroImageWrapRef.current;
const headlineLines = headlineLineRefs.current.filter(Boolean);
const heroMeta = heroMetaRefs.current.filter(Boolean);
const revealTargets = [...headlineLines, ...heroMeta];
if (!overlay || !overlayText || !heroImageWrap || revealTargets.length === 0) {
return undefined;
}
const ctx = gsap.context(() => {
gsap.set(heroImageWrap, {
scale: 1.22,
transformOrigin: "center center",
});
gsap.set(revealTargets, {
y: 56,
autoAlpha: 0,
});
if (!shouldPlayIntro) {
gsap.set(heroImageWrap, { scale: 1 });
gsap.set(revealTargets, { y: 0, autoAlpha: 1 });
gsap.set(overlay, {
yPercent: -100,
autoAlpha: 0,
display: "none",
});
return;
}
gsap.set(overlay, { yPercent: 0, autoAlpha: 1, display: "block" });
gsap.set(overlayText, { xPercent: 28, yPercent: 140, autoAlpha: 0 });
const introTimeline = gsap.timeline({
defaults: { ease: "power3.out" },
onComplete: () => {
window.sessionStorage.setItem(INTRO_SESSION_KEY, "true");
},
});
introTimeline
.to(overlayText, {
xPercent: 0,
yPercent: 0,
autoAlpha: 1,
duration: 1.28,
ease: "expo.out",
})
.to({}, { duration: 0.34 })
.to(
overlay,
{
yPercent: -100,
duration: 1.46,
ease: "power4.out",
},
">"
)
.to(
heroImageWrap,
{
scale: 1,
duration: 1.6,
ease: "power2.out",
},
"<0.03"
)
.to(
headlineLines,
{
y: 0,
autoAlpha: 1,
duration: 1.04,
stagger: 0.16,
ease: "power3.out",
},
"<0.27"
)
.to(
heroMeta,
{
y: 0,
autoAlpha: 1,
duration: 0.98,
stagger: 0.14,
ease: "power3.out",
},
"<0.2"
)
.set(overlay, { display: "none" });
}, pageRef);
return () => {
ctx.revert();
};
}, [shouldPlayIntro]);
useEffect(() => { useEffect(() => {
const cards = cardRefs.current.filter(Boolean); const cards = cardRefs.current.filter(Boolean);
const cardStates = cards const cardStates = cards
@ -35,7 +184,7 @@ function LandingPage() {
try { try {
video.currentTime = 0; video.currentTime = 0;
} catch { } catch {
// Ignore errors when setting currentTime // Ignore errors when setting currentTime.
} }
}; };
@ -45,12 +194,12 @@ function LandingPage() {
try { try {
video.currentTime = 0; video.currentTime = 0;
} catch { } catch {
// Ignore errors when setting currentTime // Ignore errors when setting currentTime.
} }
const playAttempt = video.play(); const playAttempt = video.play();
if (playAttempt && typeof playAttempt.catch === "function") { if (playAttempt && typeof playAttempt.catch === "function") {
playAttempt.catch(() => { }); playAttempt.catch(() => {});
} }
}; };
@ -150,56 +299,24 @@ function LandingPage() {
}, []); }, []);
return ( return (
<div className="page"> <div className="page" ref={pageRef}>
<header className="hero"> <HeroSection
<nav className="navbar navbar--hero"> heroImageWrapRef={heroImageWrapRef}
<div className="nav-pill"> setHeadlinePrimaryRef={setHeadlinePrimaryRef}
<a href="#home" className="nav-link active"> setHeadlineSecondaryRef={setHeadlineSecondaryRef}
atmos setDescriptionRef={setDescriptionRef}
</a> setActionsRef={setActionsRef}
<a href="#dufte" className="nav-link"> overlayRef={overlayRef}
Düfte overlayTextRef={overlayTextRef}
</a> />
<a href="discovery-set" className="nav-link">
Testen
</a>
<a href="#cart" className="nav-link">
Cart
</a>
</div>
</nav>
<div className="hero-overlay" />
<div className="hero-content">
<p className="eyebrow">NISCHENDÜFTE</p>
<h1>
DÜFTE ALS
<br />
AUSDRUCK
<br />
VON KONZEPT
</h1>
<p className="hero-text">
Konzeptuelle Düfte zwischen Materialität, Raum und Charakter.
</p>
<div className="hero-actions">
<button className="btn btn-primary">Aktuelle Düfte</button>
<Link to="/discovery-set" className="btn btn-secondary">
Discovery Set
</Link>
</div>
</div>
</header>
<main> <main>
<section className="section" id="dufte"> <section className="section" id="dufte">
<div className="section-heading"> <div className="section-heading">
<h2> <h2>
WÄHLE EINE {"W\u00C4HLE EINE"}
<br /> <br />
ATMOSPHÄRE {"ATMOSPH\u00C4RE"}
</h2> </h2>
</div> </div>
@ -209,8 +326,8 @@ function LandingPage() {
to={`/duft/${item.slug}`} to={`/duft/${item.slug}`}
className="product-card" className="product-card"
key={item.id} key={item.id}
ref={(el) => { ref={(element) => {
cardRefs.current[index] = el; cardRefs.current[index] = element;
}} }}
> >
<div className="product-hover-fill" aria-hidden="true"> <div className="product-hover-fill" aria-hidden="true">
@ -244,7 +361,7 @@ function LandingPage() {
<div className="product-bottom"> <div className="product-bottom">
<p>{item.text}</p> <p>{item.text}</p>
<span className="arrow"></span> <span className="arrow">&rarr;</span>
</div> </div>
</Link> </Link>
))} ))}
@ -259,7 +376,7 @@ function LandingPage() {
DISCOVERY SET DISCOVERY SET
</h2> </h2>
<p> <p>
Alle 6 Düfte als 2ml Samples 2ml. {"Alle 6 D\u00FCfte als 2ml Samples."}
<br /> <br />
Jeden Duft eine Woche tragen. Jeden Duft eine Woche tragen.
<br /> <br />
@ -271,7 +388,7 @@ function LandingPage() {
</div> </div>
<div className="discovery-banner"> <div className="discovery-banner">
<img src="/DISCOVERYSET.png" alt="Discovery Set" /> <img src="/DISCOVERYSET.png" alt="Discovery Set" loading="lazy" />
</div> </div>
</section> </section>
</main> </main>
@ -279,4 +396,4 @@ function LandingPage() {
); );
} }
export default LandingPage; export default LandingPage;