8 changed files with 944 additions and 807 deletions
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 9.3 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
@ -0,0 +1,148 @@
|
||||
:root{ |
||||
--header-height:96px; |
||||
--color-primary:#3A4081; |
||||
--color-primary-hover:#2F5DAA; |
||||
--color-primary-light:#6B78B5; |
||||
--color-primary-soft:rgba(58,64,129,.08); |
||||
--color-primary-soft-strong:rgba(58,64,129,.12); |
||||
--color-primary-soft-border:rgba(58,64,129,.16); |
||||
--color-primary-border:rgba(58,64,129,.2); |
||||
--color-primary-border-strong:rgba(58,64,129,.24); |
||||
--color-primary-shadow:rgba(58,64,129,.18); |
||||
} |
||||
|
||||
html{scrollbar-gutter:inherit;} |
||||
body{overflow-x:hidden;} |
||||
|
||||
.main-layout{min-height:calc(100vh - var(--header-height));padding-top:var(--header-height);} |
||||
.sub-layout{min-height:calc(100vh - var(--header-height));padding-top:var(--header-height);} |
||||
|
||||
|
||||
/*main visual*/ |
||||
.main-page{position:relative;background:linear-gradient(180deg,#f7f9ff 0%,#eef2fb 52%,#f8faff 100%);color:#111827;overflow:hidden;} |
||||
.main-section{position:relative;width:100%;} |
||||
.section-inner{position:relative;width:100%;max-width:1400px;margin:0 auto;padding:0 56px;} |
||||
.section-head,.split-head,.showcase-head{margin-bottom:72px;} |
||||
.section-kicker{display:inline-block;margin-bottom:18px;font-size:12px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:rgba(58,64,129,.58);} |
||||
.section-title{margin:0;font-size:clamp(38px,5vw,72px);line-height:.98;font-weight:700;letter-spacing:-.04em;color:#111827;} |
||||
.section-desc{margin:20px 0 0;font-size:17px;line-height:1.8;color:rgba(17,24,39,.68);} |
||||
|
||||
.section-hero{position:relative;min-height:calc(100vh - var(--header-height));display:flex;align-items:center;overflow:hidden;background:linear-gradient(135deg,rgba(58,64,129,.06) 0%,rgba(58,64,129,.02) 36%,rgba(255,255,255,.85) 100%);} |
||||
.hero-inner{position:relative;display:grid;grid-template-columns:minmax(0,1.15fr) minmax(320px,.85fr);align-items:center;gap:40px;min-height:calc(100vh - var(--header-height));padding-top:40px;padding-bottom:60px;} |
||||
.hero-title-block{position:relative;z-index:3;max-width:900px;} |
||||
.hero-mini{display:block;margin-bottom:22px;font-size:12px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:rgba(58,64,129,.72);} |
||||
.hero-title{margin:0;} |
||||
.hero-title-fill{display:flex;flex-direction:column;gap:2px;} |
||||
.hero-title-line{position:relative;display:block;font-size:clamp(64px,10vw,168px);line-height:.9;font-weight:800;letter-spacing:-.07em;} |
||||
.hero-title-outline{display:block;color:transparent;-webkit-text-stroke:1px rgba(58,64,129,.26);} |
||||
.hero-title-solid{position:absolute;left:0;top:0;display:block;color:var(--color-primary);white-space:nowrap;overflow:hidden;} |
||||
.hero-sub{max-width:640px;margin:30px 0 0;font-size:18px;line-height:1.8;color:rgba(17,24,39,.72);} |
||||
.hero-meta{display:flex;flex-wrap:wrap;gap:10px;margin-top:30px;} |
||||
.hero-meta span{display:inline-flex;align-items:center;height:38px;padding:0 16px;border:1px solid var(--color-primary-border);border-radius:999px;background:rgba(255,255,255,.72);backdrop-filter:blur(8px);font-size:12px;font-weight:700;letter-spacing:.14em;color:var(--color-primary);} |
||||
.hero-side-visual{position:relative;z-index:2;display:flex;flex-direction:column;align-items:flex-end;gap:16px;perspective:1000px;} |
||||
.hero-side-card{width:min(100%,360px);padding:24px 24px 26px;border:1px solid rgba(58,64,129,.12);border-radius:28px;background:rgba(255,255,255,.68);box-shadow:0 24px 60px rgba(58,64,129,.10);backdrop-filter:blur(14px);} |
||||
.hero-side-label{display:block;margin-bottom:16px;font-size:12px;font-weight:700;letter-spacing:.18em;color:rgba(58,64,129,.55);} |
||||
.hero-side-card strong{display:block;font-size:26px;line-height:1.04;letter-spacing:-.04em;color:#111827;} |
||||
.hero-side-card-a{margin-right:72px;} |
||||
.hero-side-card-b{margin-right:8px;} |
||||
.hero-side-card-c{margin-right:96px;} |
||||
.hero-grid{position:absolute;inset:0;z-index:0;background-image:linear-gradient(rgba(58,64,129,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(58,64,129,.06) 1px,transparent 1px);background-size:56px 56px;mask-image:radial-gradient(circle at 50% 50%,rgba(0,0,0,1) 0%,rgba(0,0,0,.34) 70%,rgba(0,0,0,.08) 100%);} |
||||
.hero-orb{position:absolute;border-radius:50%;filter:blur(10px);pointer-events:none;z-index:1;} |
||||
.hero-orb-a{right:10%;top:12%;width:420px;height:420px;background:radial-gradient(circle,rgba(58,64,129,.18) 0%,rgba(58,64,129,.06) 42%,rgba(58,64,129,0) 72%);} |
||||
.hero-orb-b{left:-4%;bottom:-10%;width:520px;height:520px;background:radial-gradient(circle,rgba(107,120,181,.18) 0%,rgba(107,120,181,.08) 38%,rgba(107,120,181,0) 70%);} |
||||
|
||||
.section-showcase{height:360vh;background:linear-gradient(180deg,#f8faff 0%,#eef2fb 100%);} |
||||
.showcase-sticky{position:relative;height:100vh;} |
||||
.showcase-shell{display:flex;flex-direction:column;justify-content:center;height:100vh;overflow:hidden;} |
||||
.showcase-head{margin-bottom:48px;} |
||||
.showcase-rail-wrap{position:relative;padding-left:56px;padding-right:56px;} |
||||
.showcase-rail{display:flex;align-items:stretch;gap:24px;width:max-content;will-change:transform;} |
||||
.showcase-card-item{position:relative;flex:0 0 480px;min-height:360px;padding:32px;border:1px solid rgba(58,64,129,.12);border-radius:32px;background:linear-gradient(180deg,rgba(255,255,255,.92) 0%,rgba(244,247,255,.86) 100%);box-shadow:0 26px 70px rgba(58,64,129,.10);overflow:hidden;} |
||||
.showcase-card-item::before{content:'';position:absolute;right:-40px;top:-30px;width:180px;height:180px;border-radius:50%;background:radial-gradient(circle,rgba(58,64,129,.12) 0%,rgba(58,64,129,0) 72%);} |
||||
.showcase-index{display:block;margin-bottom:52px;font-size:12px;font-weight:700;letter-spacing:.2em;color:rgba(58,64,129,.5);} |
||||
.showcase-card-item strong{display:block;max-width:280px;font-size:34px;line-height:1.04;font-weight:700;letter-spacing:-.04em;color:#111827;} |
||||
.showcase-card-item p{max-width:300px;margin:22px 0 0;font-size:16px;line-height:1.8;color:rgba(17,24,39,.68);} |
||||
|
||||
.section-immersive{height:280vh;background:linear-gradient(180deg,#eef2fb 0%,#e8eef9 100%);} |
||||
.immersive-sticky{position:relative;height:100vh;} |
||||
.immersive-sticky-inner{position:relative;height:100vh;padding:80px 56px;display:grid;grid-template-columns:1fr 1.2fr 1fr;align-items:center;gap:32px;max-width:1600px;margin:0 auto;} |
||||
.immersive-copy{position:relative;z-index:2;} |
||||
.immersive-label{display:block;margin-bottom:18px;font-size:12px;font-weight:700;letter-spacing:.22em;color:rgba(58,64,129,.5);} |
||||
.immersive-copy h2{margin:0;font-size:clamp(34px,4.2vw,68px);line-height:1.05;font-weight:700;letter-spacing:-.04em;color:#111827;} |
||||
.immersive-copy p{margin:0;font-size:17px;line-height:1.9;color:rgba(17,24,39,.7);} |
||||
.immersive-visual{display:flex;align-items:center;justify-content:center;} |
||||
.visual-frame{position:relative;width:min(42vw,700px);aspect-ratio:1/1.08;border-radius:36px;border:1px solid rgba(58,64,129,.12);background:linear-gradient(180deg,rgba(255,255,255,.72) 0%,rgba(241,245,255,.92) 100%);overflow:hidden;box-shadow:0 40px 120px rgba(58,64,129,.14);} |
||||
.visual-grid{position:absolute;inset:0;background-image:linear-gradient(rgba(58,64,129,.08) 1px,transparent 1px),linear-gradient(90deg,rgba(58,64,129,.08) 1px,transparent 1px);background-size:40px 40px;mask-image:linear-gradient(180deg,rgba(0,0,0,1) 0%,rgba(0,0,0,.35) 100%);} |
||||
.visual-core{position:absolute;left:50%;top:50%;display:flex;flex-direction:column;align-items:center;gap:14px;transform:translate(-50%,-50%);text-align:center;} |
||||
.visual-core span{font-size:clamp(28px,4vw,64px);font-weight:800;letter-spacing:-.05em;color:var(--color-primary);} |
||||
.visual-core small{font-size:12px;font-weight:700;letter-spacing:.18em;color:rgba(58,64,129,.58);} |
||||
|
||||
.section-split{padding:200px 0 240px;background:linear-gradient(180deg,#f8faff 0%,#eef2fb 100%);} |
||||
.split-stage{position:relative;display:grid;grid-template-columns:1fr minmax(320px,420px) 1fr;align-items:center;gap:28px;max-width:1400px;margin:0 auto;padding:0 56px;} |
||||
.split-panel{min-height:360px;padding:34px;border:1px solid rgba(58,64,129,.12);border-radius:36px;background:linear-gradient(180deg,rgba(255,255,255,.92) 0%,rgba(241,245,255,.84) 100%);box-shadow:0 24px 70px rgba(58,64,129,.10);} |
||||
.split-label{display:block;margin-bottom:24px;font-size:12px;font-weight:700;letter-spacing:.2em;color:rgba(58,64,129,.52);} |
||||
.split-panel strong{display:block;margin-bottom:18px;font-size:clamp(38px,4vw,64px);line-height:.95;font-weight:800;letter-spacing:-.05em;color:#111827;} |
||||
.split-panel p{margin:0;max-width:360px;font-size:16px;line-height:1.8;color:rgba(17,24,39,.68);} |
||||
.split-center-card{position:relative;z-index:2;min-height:300px;padding:30px;border:1px solid rgba(58,64,129,.16);border-radius:32px;background:linear-gradient(180deg,rgba(58,64,129,.98) 0%,rgba(47,93,170,.96) 100%);box-shadow:0 30px 90px rgba(58,64,129,.22);color:#fff;} |
||||
.split-center-kicker{display:block;margin-bottom:18px;font-size:12px;font-weight:700;letter-spacing:.18em;color:rgba(255,255,255,.66);} |
||||
.split-center-card strong{display:block;margin-bottom:18px;font-size:34px;line-height:1.02;font-weight:700;letter-spacing:-.04em;} |
||||
.split-center-card p{margin:0;font-size:15px;line-height:1.8;color:rgba(255,255,255,.82);} |
||||
|
||||
.section-ending{padding:220px 0 240px;background:linear-gradient(180deg,#eef2fb 0%,#f8faff 100%);} |
||||
.ending-inner{text-align:center;} |
||||
.ending-label{display:block;margin-bottom:22px;font-size:12px;font-weight:700;letter-spacing:.24em;color:rgba(58,64,129,.46);} |
||||
.ending-title{display:flex;flex-wrap:wrap;justify-content:center;gap:14px;margin:0;font-size:clamp(42px,6vw,96px);line-height:.95;font-weight:800;letter-spacing:-.06em;color:#111827;} |
||||
.ending-title .word{display:inline-block;} |
||||
.ending-desc{margin:30px 0 0;font-size:18px;line-height:1.9;color:rgba(17,24,39,.68);} |
||||
|
||||
@media (max-width:1280px){ |
||||
.hero-inner{grid-template-columns:1fr;gap:28px;padding-top:80px;padding-bottom:80px;} |
||||
.hero-side-visual{align-items:flex-start;} |
||||
.hero-side-card-a,.hero-side-card-b,.hero-side-card-c{margin-right:0;} |
||||
.showcase-rail-wrap{padding-left:56px;} |
||||
.immersive-sticky-inner{grid-template-columns:1fr;grid-template-rows:auto auto auto;align-content:center;text-align:center;} |
||||
.immersive-copy-top,.immersive-copy-bottom{max-width:820px;margin:0 auto;} |
||||
.visual-frame{width:min(78vw,760px);} |
||||
.split-stage{grid-template-columns:1fr;max-width:880px;} |
||||
.split-center-card{order:2;} |
||||
} |
||||
|
||||
@media (max-width:767px){ |
||||
.section-inner{padding:0 20px;} |
||||
.section-head,.split-head,.showcase-head{margin-bottom:40px;} |
||||
.section-desc{font-size:15px;line-height:1.7;} |
||||
.hero-inner{padding-top:72px;padding-bottom:56px;} |
||||
.hero-title-line{font-size:clamp(52px,15vw,88px);} |
||||
.hero-sub{font-size:15px;line-height:1.7;} |
||||
.hero-meta{gap:8px;} |
||||
.hero-meta span{height:34px;padding:0 12px;font-size:11px;} |
||||
.hero-side-card{width:100%;padding:20px 20px 22px;border-radius:22px;} |
||||
.hero-side-card strong{font-size:22px;} |
||||
.hero-grid{background-size:34px 34px;} |
||||
.hero-orb-a{right:-10%;top:8%;width:260px;height:260px;} |
||||
.hero-orb-b{left:-18%;bottom:-12%;width:320px;height:320px;} |
||||
|
||||
.section-showcase{height:320vh;} |
||||
.showcase-rail-wrap{padding-left:20px;padding-right:20px;} |
||||
.showcase-card-item{flex:0 0 84vw;min-height:300px;padding:24px;border-radius:24px;} |
||||
.showcase-index{margin-bottom:28px;} |
||||
.showcase-card-item strong{font-size:28px;} |
||||
.showcase-card-item p{font-size:15px;line-height:1.7;} |
||||
|
||||
.section-immersive{height:220vh;} |
||||
.immersive-sticky-inner{padding:56px 20px;} |
||||
.visual-frame{width:100%;border-radius:28px;} |
||||
.visual-core small{font-size:11px;} |
||||
|
||||
.section-split{padding:120px 0 140px;} |
||||
.split-stage{padding:0 20px;} |
||||
.split-panel{min-height:auto;padding:24px;border-radius:24px;} |
||||
.split-panel strong{font-size:34px;} |
||||
.split-panel p{font-size:15px;line-height:1.7;} |
||||
.split-center-card{min-height:auto;padding:24px;border-radius:24px;} |
||||
.split-center-card strong{font-size:28px;} |
||||
.split-center-card p{font-size:14px;line-height:1.7;} |
||||
|
||||
.section-ending{padding:140px 0 160px;} |
||||
.ending-desc{font-size:15px;line-height:1.8;} |
||||
} |
||||
@ -0,0 +1,717 @@
|
||||
import { useLayoutEffect, useRef } from "react"; |
||||
import { gsap } from "gsap"; |
||||
import { ScrollTrigger } from "gsap/ScrollTrigger"; |
||||
|
||||
gsap.registerPlugin(ScrollTrigger); |
||||
|
||||
function MainPage() { |
||||
const pageRef = useRef(null); |
||||
|
||||
useLayoutEffect(() => { |
||||
const ctx = gsap.context(() => { |
||||
ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); |
||||
|
||||
const heroTrigger = ".section-hero"; |
||||
const showcaseTrigger = ".section-showcase"; |
||||
const immersiveTrigger = ".section-immersive"; |
||||
const splitTrigger = ".section-split"; |
||||
const endingTrigger = ".section-ending"; |
||||
|
||||
/* hero - 진입할 때마다 다시 보이도록 fromTo + reverse */ |
||||
gsap.fromTo( |
||||
".hero-title-line", |
||||
{ |
||||
y: 80, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.95, |
||||
stagger: 0.12, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 70%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-title-solid", |
||||
{ |
||||
clipPath: "inset(0 100% 0 0)", |
||||
}, |
||||
{ |
||||
clipPath: "inset(0 0% 0 0)", |
||||
duration: 1, |
||||
stagger: 0.1, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 68%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-mini", |
||||
{ |
||||
y: 18, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.65, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 72%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-sub", |
||||
{ |
||||
y: 28, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.8, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 70%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-meta span", |
||||
{ |
||||
y: 18, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.55, |
||||
stagger: 0.08, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 68%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-side-card", |
||||
{ |
||||
y: 42, |
||||
opacity: 0, |
||||
rotateY: 8, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
rotateY: 0, |
||||
duration: 0.8, |
||||
stagger: 0.1, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 66%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".hero-orb", |
||||
{ |
||||
scale: 0.72, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
scale: 1, |
||||
opacity: 1, |
||||
duration: 1.1, |
||||
stagger: 0.12, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top 72%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.to(".hero-title-block", { |
||||
yPercent: -10, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top top", |
||||
end: "bottom top", |
||||
scrub: 0.8, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".hero-side-visual", { |
||||
yPercent: -14, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top top", |
||||
end: "bottom top", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".hero-grid", { |
||||
yPercent: -8, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top top", |
||||
end: "bottom top", |
||||
scrub: 1.1, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".hero-orb-a", { |
||||
xPercent: 10, |
||||
yPercent: -10, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top top", |
||||
end: "bottom top", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".hero-orb-b", { |
||||
xPercent: -8, |
||||
yPercent: -12, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: heroTrigger, |
||||
start: "top top", |
||||
end: "bottom top", |
||||
scrub: 1.1, |
||||
}, |
||||
}); |
||||
|
||||
/* showcase - pinned horizontal */ |
||||
const showcaseTl = gsap.timeline({ |
||||
scrollTrigger: { |
||||
trigger: showcaseTrigger, |
||||
start: "top top", |
||||
end: "+=260%", |
||||
scrub: 1, |
||||
pin: ".showcase-sticky", |
||||
anticipatePin: 1, |
||||
}, |
||||
}); |
||||
|
||||
showcaseTl |
||||
.fromTo( |
||||
".showcase-head", |
||||
{ |
||||
y: 40, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.35, |
||||
}, |
||||
) |
||||
.fromTo( |
||||
".showcase-card-item", |
||||
{ |
||||
opacity: 0.35, |
||||
scale: 0.88, |
||||
y: 60, |
||||
}, |
||||
{ |
||||
opacity: 1, |
||||
scale: 1, |
||||
y: 0, |
||||
duration: 0.4, |
||||
stagger: 0.08, |
||||
}, |
||||
0, |
||||
) |
||||
.to( |
||||
".showcase-rail", |
||||
{ |
||||
xPercent: -48, |
||||
duration: 1, |
||||
ease: "none", |
||||
}, |
||||
0, |
||||
); |
||||
|
||||
gsap.to(".showcase-card-item", { |
||||
yPercent: -10, |
||||
stagger: 0.04, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: showcaseTrigger, |
||||
start: "top top", |
||||
end: "+=260%", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
/* immersive - 기존 무드 유지 */ |
||||
gsap.fromTo( |
||||
".immersive-sticky-inner", |
||||
{ |
||||
scale: 0.88, |
||||
opacity: 0.45, |
||||
}, |
||||
{ |
||||
scale: 1, |
||||
opacity: 1, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: immersiveTrigger, |
||||
start: "top top", |
||||
end: "+=180%", |
||||
scrub: 1, |
||||
pin: ".immersive-sticky", |
||||
anticipatePin: 1, |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".immersive-copy-top", |
||||
{ |
||||
y: 80, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: -36, |
||||
opacity: 1, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: immersiveTrigger, |
||||
start: "top top", |
||||
end: "+=180%", |
||||
scrub: 1, |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".immersive-copy-bottom", |
||||
{ |
||||
y: 110, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: -18, |
||||
opacity: 1, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: immersiveTrigger, |
||||
start: "top top", |
||||
end: "+=180%", |
||||
scrub: 1, |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.to(".visual-grid", { |
||||
yPercent: -8, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: immersiveTrigger, |
||||
start: "top top", |
||||
end: "+=180%", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
/* split - 등장 + 스크롤 중 역동성 */ |
||||
gsap.fromTo( |
||||
".split-head", |
||||
{ |
||||
y: 36, |
||||
opacity: 0, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
duration: 0.8, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: splitTrigger, |
||||
start: "top 76%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".split-panel-left", |
||||
{ |
||||
xPercent: -12, |
||||
opacity: 0, |
||||
rotate: -2, |
||||
}, |
||||
{ |
||||
xPercent: 0, |
||||
opacity: 1, |
||||
rotate: 0, |
||||
duration: 1, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: ".split-stage", |
||||
start: "top 75%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".split-panel-right", |
||||
{ |
||||
xPercent: 12, |
||||
opacity: 0, |
||||
rotate: 2, |
||||
}, |
||||
{ |
||||
xPercent: 0, |
||||
opacity: 1, |
||||
rotate: 0, |
||||
duration: 1, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: ".split-stage", |
||||
start: "top 75%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".split-center-card", |
||||
{ |
||||
y: 60, |
||||
opacity: 0, |
||||
scale: 0.9, |
||||
}, |
||||
{ |
||||
y: 0, |
||||
opacity: 1, |
||||
scale: 1, |
||||
duration: 0.9, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: ".split-stage", |
||||
start: "top 72%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.to(".split-panel-left", { |
||||
yPercent: -10, |
||||
xPercent: -3, |
||||
rotate: -2, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: splitTrigger, |
||||
start: "top bottom", |
||||
end: "bottom top", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".split-panel-right", { |
||||
yPercent: 10, |
||||
xPercent: 3, |
||||
rotate: 2, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: splitTrigger, |
||||
start: "top bottom", |
||||
end: "bottom top", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
gsap.to(".split-center-card", { |
||||
yPercent: -8, |
||||
scale: 1.04, |
||||
ease: "none", |
||||
scrollTrigger: { |
||||
trigger: splitTrigger, |
||||
start: "top bottom", |
||||
end: "bottom top", |
||||
scrub: 1, |
||||
}, |
||||
}); |
||||
|
||||
/* ending - 초기 렌더 말고 스크롤 진입 기준 */ |
||||
gsap.fromTo( |
||||
".ending-label", |
||||
{ |
||||
opacity: 0, |
||||
y: 26, |
||||
}, |
||||
{ |
||||
opacity: 1, |
||||
y: 0, |
||||
duration: 0.6, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: endingTrigger, |
||||
start: "top 78%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".ending-title .word", |
||||
{ |
||||
opacity: 0, |
||||
y: 60, |
||||
}, |
||||
{ |
||||
opacity: 1, |
||||
y: 0, |
||||
duration: 0.85, |
||||
ease: "power4.out", |
||||
stagger: 0.08, |
||||
scrollTrigger: { |
||||
trigger: endingTrigger, |
||||
start: "top 74%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
gsap.fromTo( |
||||
".ending-desc", |
||||
{ |
||||
opacity: 0, |
||||
y: 22, |
||||
}, |
||||
{ |
||||
opacity: 1, |
||||
y: 0, |
||||
duration: 0.7, |
||||
ease: "power3.out", |
||||
scrollTrigger: { |
||||
trigger: endingTrigger, |
||||
start: "top 72%", |
||||
toggleActions: "play none none reverse", |
||||
}, |
||||
}, |
||||
); |
||||
|
||||
ScrollTrigger.refresh(); |
||||
}, pageRef); |
||||
|
||||
return () => { |
||||
ctx.revert(); |
||||
}; |
||||
}, []); |
||||
|
||||
return ( |
||||
<main className="main-page" ref={pageRef}> |
||||
<section className="main-section section-hero"> |
||||
<div className="hero-grid"></div> |
||||
<div className="hero-orb hero-orb-a"></div> |
||||
<div className="hero-orb hero-orb-b"></div> |
||||
|
||||
<div className="section-inner hero-inner"> |
||||
<div className="hero-title-block"> |
||||
<span className="hero-mini">PALNETWORKS RENEWAL</span> |
||||
|
||||
<h1 className="hero-title hero-title-fill"> |
||||
<span className="hero-title-line"> |
||||
<span className="hero-title-outline">STRUCTURED</span> |
||||
<span className="hero-title-solid">STRUCTURED</span> |
||||
</span> |
||||
|
||||
<span className="hero-title-line"> |
||||
<span className="hero-title-outline">MOTION</span> |
||||
<span className="hero-title-solid">MOTION</span> |
||||
</span> |
||||
</h1> |
||||
|
||||
<p className="hero-sub"> |
||||
정적인 소개보다 인터랙션과 패럴랙스로 |
||||
<br /> |
||||
리뉴얼 방향성과 무드를 먼저 보여주는 메인 비주얼 |
||||
</p> |
||||
|
||||
<div className="hero-meta"> |
||||
<span>PARALLAX</span> |
||||
<span>INTERACTION</span> |
||||
<span>VISUAL FLOW</span> |
||||
</div> |
||||
</div> |
||||
|
||||
<div className="hero-side-visual"> |
||||
<div className="hero-side-card hero-side-card-a"> |
||||
<span className="hero-side-label">01</span> |
||||
<strong>Visual Depth</strong> |
||||
</div> |
||||
|
||||
<div className="hero-side-card hero-side-card-b"> |
||||
<span className="hero-side-label">02</span> |
||||
<strong>Scroll Rhythm</strong> |
||||
</div> |
||||
|
||||
<div className="hero-side-card hero-side-card-c"> |
||||
<span className="hero-side-label">03</span> |
||||
<strong>Brand Direction</strong> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<section className="main-section section-showcase"> |
||||
<div className="showcase-sticky"> |
||||
<div className="showcase-shell"> |
||||
<div className="section-inner showcase-head"> |
||||
<span className="section-kicker">SECTION 01</span> |
||||
<h2 className="section-title">Dynamic Scroll Showcase</h2> |
||||
<p className="section-desc">단순한 카드 나열이 아니라, 스크롤 흐름 자체가 메인 비주얼의 연장처럼 느껴지도록 구성한 구간</p> |
||||
</div> |
||||
|
||||
<div className="showcase-rail-wrap"> |
||||
<div className="showcase-rail"> |
||||
<article className="showcase-card-item"> |
||||
<span className="showcase-index">01</span> |
||||
<strong>Refined Direction</strong> |
||||
<p>과하게 복잡하지 않지만 첫 화면에서 분명한 인상을 남기는 인터랙션 구조</p> |
||||
</article> |
||||
|
||||
<article className="showcase-card-item"> |
||||
<span className="showcase-index">02</span> |
||||
<strong>Layered Visual Flow</strong> |
||||
<p>텍스트, 패널, 배경이 각기 다른 속도로 반응하며 화면에 깊이감을 더합니다.</p> |
||||
</article> |
||||
|
||||
<article className="showcase-card-item"> |
||||
<span className="showcase-index">03</span> |
||||
<strong>Clean Motion</strong> |
||||
<p>빠르고 자극적인 효과보다 정돈된 모션 리듬으로 브랜드 톤을 만듭니다.</p> |
||||
</article> |
||||
|
||||
<article className="showcase-card-item"> |
||||
<span className="showcase-index">04</span> |
||||
<strong>White Space First</strong> |
||||
<p>여백과 구조를 먼저 잡고 포인트 컬러는 필요한 부분에만 사용합니다.</p> |
||||
</article> |
||||
|
||||
<article className="showcase-card-item"> |
||||
<span className="showcase-index">05</span> |
||||
<strong>Interactive Mood</strong> |
||||
<p>리뉴얼 방향성 제안용 샘플로도 충분히 설득력 있게 보일 수 있는 무드 중심 섹션</p> |
||||
</article> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<section className="main-section section-immersive"> |
||||
<div className="immersive-sticky"> |
||||
<div className="immersive-sticky-inner"> |
||||
<div className="immersive-copy immersive-copy-top"> |
||||
<span className="immersive-label">SECTION 02</span> |
||||
<h2> |
||||
스크롤에 반응하는 |
||||
<br /> |
||||
집중도 높은 구간 |
||||
</h2> |
||||
</div> |
||||
|
||||
<div className="immersive-visual"> |
||||
<div className="visual-frame"> |
||||
<div className="visual-grid"></div> |
||||
<div className="visual-core"> |
||||
<span>INTERACTION</span> |
||||
<small>VISUAL SYSTEM / SCROLL / RHYTHM</small> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div className="immersive-copy immersive-copy-bottom"> |
||||
<p>이 섹션은 추후 실제 이미지나 UI 캡처, 숫자 데이터, 솔루션 키워드 등으로 교체하기 좋은 구조입니다. 지금은 비주얼 없이도 무드가 살아 있도록 최소한의 구성만 유지했습니다.</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<section className="main-section section-split"> |
||||
<div className="section-inner split-head"> |
||||
<span className="section-kicker">SECTION 03</span> |
||||
<h2 className="section-title">Split Motion Panels</h2> |
||||
<p className="section-desc">의미 없는 겹침 박스 대신, 서로 다른 방향의 패널과 중앙 카드가 한 화면 안에서 움직이며 역동적인 인상을 만드는 섹션</p> |
||||
</div> |
||||
|
||||
<div className="split-stage"> |
||||
<div className="split-panel split-panel-left"> |
||||
<span className="split-label">LEFT PANEL</span> |
||||
<strong>STRUCTURE</strong> |
||||
<p>정돈된 레이아웃과 여백을 기반으로 모션이 들어가도 과해 보이지 않는 화면 구조</p> |
||||
</div> |
||||
|
||||
<div className="split-center-card"> |
||||
<span className="split-center-kicker">CENTER FLOW</span> |
||||
<strong>Balanced Motion</strong> |
||||
<p>패널은 좌우로 긴장감을 만들고, 중앙 카드는 정보의 중심축처럼 보이도록 구성합니다.</p> |
||||
</div> |
||||
|
||||
<div className="split-panel split-panel-right"> |
||||
<span className="split-label">RIGHT PANEL</span> |
||||
<strong>RHYTHM</strong> |
||||
<p>스크롤에 따라 요소마다 반응 속도를 달리 주어 지루하지 않은 인터랙션을 만듭니다.</p> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<section className="main-section section-ending"> |
||||
<div className="section-inner ending-inner"> |
||||
<span className="ending-label">FINAL SECTION</span> |
||||
|
||||
<h2 className="ending-title"> |
||||
<span className="word">SIMPLE.</span> |
||||
<span className="word">MODERN.</span> |
||||
<span className="word">IMMERSIVE.</span> |
||||
</h2> |
||||
|
||||
<p className="ending-desc"> |
||||
메인 비주얼은 과하지 않게, |
||||
<br /> |
||||
이후 섹션에서는 스크롤과 인터랙션으로 브랜드의 감도를 보여주는 구조입니다. |
||||
</p> |
||||
</div> |
||||
</section> |
||||
</main> |
||||
); |
||||
} |
||||
|
||||
export default MainPage; |
||||
Loading…
Reference in new issue