Files
viberoom-web/src/app/(landing)/page.tsx
corpi cbd9017744 feat(fsd): 허브·스페이스 중심 UI 목업 구조로 재편
맥락:

- 기존 라우트/컴포넌트 구조를 FSD 기준으로 정리하고, /app 허브와 /space 집중 화면 중심의 목업 흐름을 구성하기 위해

변경사항:

- App Router 구조를 /landing, /app, /space, /stats, /settings 중심으로 재배치

- entities/session/room/user 더미 데이터와 타입 정의 추가

- features(커스텀 입장, 룸 선택, 체크인, 리액션, 30초 리스타트 등) 단위로 로직 분리

- widgets(허브, 룸 갤러리, 타이머 HUD, 툴 도크 등) 조합형 UI 추가

- shared 공용 UI(Button/Chip/Modal/Toast 등) 및 유틸(cn/useReducedMotion) 정비

- 로그인 후 이동 경로를 /dashboard 에서 /app 으로 변경

- README를 현재 프로젝트 구조/라우트/구현 범위 기준으로 갱신

검증:

- npx tsc --noEmit

세션-상태: 허브·스페이스 목업이 FSD 레이어로 동작 가능하도록 정리됨

세션-다음: /space 상단 및 도크의 인원 수 카피를 분위기형 카피로 후속 정리

세션-리스크: build는 네트워크 환경에서 Google Fonts fetch 실패 가능
2026-02-27 13:30:55 +09:00

209 lines
13 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from "next/link";
import { Button } from "@/shared/ui/Button";
export default function MarketingPage() {
return (
<div className="min-h-screen bg-slate-50 text-brand-dark font-sans selection:bg-brand-soft/50">
{/* Navigation Bar */}
<header className="sticky top-0 z-50 w-full border-b border-brand-dark/10 bg-slate-50/80 backdrop-blur-md">
<div className="container mx-auto px-6 h-16 flex items-center justify-between">
<Link href="/" className="text-xl font-bold text-brand-dark tracking-tight flex items-center gap-2">
<span className="text-2xl">🪴</span> VibeRoom
</Link>
<nav className="hidden md:flex items-center gap-6 text-sm font-medium text-brand-dark/80">
<Button variant="ghost" size="sm" href="#features"> </Button>
<Button variant="ghost" size="sm" href="#pricing"></Button>
<Button variant="ghost" size="sm" href="/login"></Button>
<Button variant="primary" size="md" href="/login"> </Button>
</nav>
</div>
</header>
<main>
{/* Hero Section */}
<section className="pt-24 pb-32 px-6">
<div className="container mx-auto max-w-5xl flex flex-col md:flex-row items-center gap-16">
<div className="flex-1 text-center md:text-left">
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6 tracking-tight leading-tight text-brand-dark">
,<br />
<span className="text-brand-primary">VibeRoom</span>
</h1>
<p className="text-lg md:text-xl text-brand-dark/70 mb-10 max-w-xl mx-auto md:mx-0 leading-relaxed">
, .
.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
<Button variant="primary" size="lg" href="/login">
</Button>
<Button variant="outline" size="lg" href="#features">
</Button>
</div>
</div>
{/* Hero Illustration */}
<div className="flex-1 w-full max-w-md md:max-w-full hidden sm:block">
<div className="aspect-square md:aspect-video bg-brand-soft/20 rounded-3xl border border-brand-soft/30 shadow-sm flex items-center justify-center p-8 relative overflow-hidden">
<div className="relative z-10 w-full h-full bg-white rounded-2xl shadow-sm border border-brand-dark/5 flex flex-col p-6">
<div className="flex gap-3 mb-6">
<div className="w-3 h-3 rounded-full bg-brand-dark/20"></div>
<div className="w-3 h-3 rounded-full bg-brand-dark/20"></div>
<div className="w-3 h-3 rounded-full bg-brand-dark/20"></div>
</div>
<div className="flex-1 flex gap-6">
<div className="flex-1 bg-slate-50 rounded-xl border border-brand-dark/5 p-4 flex flex-col items-center justify-center">
<div className="text-4xl mb-2">🧑💻</div>
<div className="h-2 w-16 bg-brand-primary/50 rounded-full mt-2"></div>
</div>
<div className="flex-1 bg-slate-50 rounded-xl border border-brand-dark/5 p-4 flex flex-col items-center justify-center">
<div className="text-4xl mb-2"></div>
<div className="h-2 w-16 bg-brand-soft rounded-full mt-2"></div>
</div>
</div>
<div className="mt-6 h-12 bg-brand-soft/20 rounded-xl border border-brand-primary/20 flex items-center justify-center text-brand-primary font-medium text-sm">
45:00
</div>
</div>
</div>
</div>
</div>
</section>
{/* Features Section */}
<section id="features" className="py-24 bg-white px-6">
<div className="container mx-auto max-w-6xl">
<div className="text-center max-w-2xl mx-auto mb-16">
<h2 className="text-3xl md:text-4xl font-bold mb-4 text-brand-dark tracking-tight"> </h2>
<p className="text-brand-dark/70 text-lg"> . .</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{[
{ icon: "⏳", title: "구조화된 세션 타이머", desc: "부담 없이 시작할 수 있는 짧은 몰입과 확실한 휴식. 당신만의 작업 리듬을 부드럽게 설정하고 관리하세요." },
{ icon: "🌱", title: "다정한 연대와 코워킹", desc: "화면 너머 누군가와 함께하는 바디 더블링 효과. 감시가 아닌, 조용하지만 강력한 동기를 서로 나누어보세요." },
{ icon: "🛋️", title: "나만의 심미적 공간", desc: "비 오는 다락방, 햇살 드는 카페. 백색소음과 함께 내가 가장 편안함을 느끼는 가상 공간을 꾸미고 머무르세요." }
].map((feature, idx) => (
<div key={idx} className="p-8 bg-brand-soft/10 rounded-2xl border border-brand-soft/30 transition-transform hover:-translate-y-1 duration-300 hover:shadow-md">
<div className="w-14 h-14 bg-white text-brand-primary rounded-2xl flex items-center justify-center mb-6 text-2xl shadow-sm border border-brand-dark/5">
{feature.icon}
</div>
<h3 className="text-xl font-bold text-brand-dark mb-3">{feature.title}</h3>
<p className="text-brand-dark/70 leading-relaxed">
{feature.desc}
</p>
</div>
))}
</div>
</div>
</section>
{/* Pricing Section */}
<section id="pricing" className="py-24 px-6 bg-slate-50">
<div className="container mx-auto max-w-5xl">
<div className="text-center max-w-2xl mx-auto mb-16">
<h2 className="text-3xl md:text-4xl font-bold mb-4 text-brand-dark tracking-tight"> </h2>
<p className="text-brand-dark/70 text-lg"> .</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 items-center">
{/* Starter Plan */}
<div className="p-8 bg-white rounded-3xl border border-brand-dark/10 shadow-sm">
<h3 className="text-xl font-bold text-brand-dark mb-2">Starter</h3>
<p className="text-brand-dark/60 text-sm mb-6 h-10"> </p>
<div className="mb-8">
<span className="text-4xl font-bold text-brand-dark"></span>
</div>
<ul className="space-y-4 mb-8 text-brand-dark/80 text-sm">
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> </li>
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> 1:1 ( 3)</li>
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> </li>
</ul>
<Button variant="secondary" size="full" href="/login">
</Button>
</div>
{/* Pro Plan */}
<div className="p-8 bg-brand-dark rounded-3xl border border-brand-dark shadow-xl relative transform md:-translate-y-4">
<div className="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-brand-primary text-white px-4 py-1 rounded-full text-xs font-bold tracking-wide">
</div>
<h3 className="text-xl font-bold text-white mb-2">Pro</h3>
<p className="text-white/60 text-sm mb-6 h-10"> </p>
<div className="mb-8 flex items-baseline gap-1">
<span className="text-4xl font-bold text-white">6,900</span>
<span className="text-white/60">/</span>
</div>
<ul className="space-y-4 mb-8 text-white/90 text-sm">
<li className="flex items-center gap-3"><span className="text-brand-soft"></span> </li>
<li className="flex items-center gap-3"><span className="text-brand-soft"></span> 1:1 </li>
<li className="flex items-center gap-3"><span className="text-brand-soft"></span> </li>
<li className="flex items-center gap-3"><span className="text-brand-soft"></span> </li>
</ul>
<Button variant="primary" size="full" href="/login?plan=pro">
Pro
</Button>
</div>
{/* Teams Plan */}
<div className="p-8 bg-white rounded-3xl border border-brand-dark/10 shadow-sm">
<h3 className="text-xl font-bold text-brand-dark mb-2">Teams</h3>
<p className="text-brand-dark/60 text-sm mb-6 h-10"> </p>
<div className="mb-8 flex items-baseline gap-1">
<span className="text-4xl font-bold text-brand-dark">12,000</span>
<span className="text-brand-dark/60 text-sm">/·</span>
</div>
<ul className="space-y-4 mb-8 text-brand-dark/80 text-sm">
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> Pro </li>
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> </li>
<li className="flex items-center gap-3"><span className="text-brand-primary"></span> </li>
</ul>
<Button variant="secondary" size="full" href="#contact">
</Button>
</div>
</div>
</div>
</section>
</main>
{/* Footer */}
<footer className="bg-brand-dark pt-16 pb-8 px-6 text-white/80">
<div className="container mx-auto max-w-6xl">
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12">
<div className="md:col-span-2">
<Link href="/" className="text-xl font-bold text-white tracking-tight flex items-center gap-2 mb-4">
<span className="text-2xl">🪴</span> VibeRoom
</Link>
<p className="text-white/60 text-sm leading-relaxed max-w-xs">
.
</p>
</div>
<div>
<h4 className="font-bold text-white mb-4"></h4>
<ul className="space-y-3 text-sm text-white/60">
<li><a href="#features" className="hover:text-brand-soft transition-colors"> </a></li>
<li><a href="#pricing" className="hover:text-brand-soft transition-colors"></a></li>
<li><Link href="/login" className="hover:text-brand-soft transition-colors"> </Link></li>
</ul>
</div>
<div>
<h4 className="font-bold text-white mb-4"></h4>
<ul className="space-y-3 text-sm text-white/60">
<li><a href="#" className="hover:text-brand-soft transition-colors"></a></li>
<li><a href="#" className="hover:text-brand-soft transition-colors"></a></li>
<li><a href="#" className="hover:text-brand-soft transition-colors"></a></li>
</ul>
</div>
</div>
<div className="border-t border-white/10 pt-8 text-center text-sm text-white/40">
&copy; 2026 VibeRoom. All rights reserved.
</div>
</div>
</footer>
</div>
);
}