This commit is contained in:
hbyang 2026-09-21 15:42:16 +09:00
commit 94ae4a825a
2 changed files with 58 additions and 46 deletions

View File

@ -17,7 +17,13 @@ const NAV = [
{to: '/pricing', label: '요금'}, {to: '/pricing', label: '요금'},
]; ];
export function MarketingShell({children}: {children: ReactNode}) { export function MarketingShell({
children,
showAuthCta = true,
}: {
children: ReactNode;
showAuthCta?: boolean;
}) {
const user = useAuthStore((s) => s.user); const user = useAuthStore((s) => s.user);
return ( return (
@ -52,7 +58,7 @@ export function MarketingShell({children}: {children: ReactNode}) {
히어로의 큰 입력 카드가 이미 그 자리다 — 시작하는 문이 한 화면에 둘이면 히어로의 큰 입력 카드가 이미 그 자리다 — 시작하는 문이 한 화면에 둘이면
어느 쪽이 진짜인지 고르게 만든다. 헤더는 로그인만 받는다. 어느 쪽이 진짜인지 고르게 만든다. 헤더는 로그인만 받는다.
*/} */}
{user ? ( {showAuthCta && (user ? (
<Link <Link
to="/sites" to="/sites"
className="rounded-md bg-primary px-4 py-2 text-[13px] font-medium text-primary-foreground transition-colors hover:bg-primary/90" className="rounded-md bg-primary px-4 py-2 text-[13px] font-medium text-primary-foreground transition-colors hover:bg-primary/90"
@ -66,7 +72,7 @@ export function MarketingShell({children}: {children: ReactNode}) {
> >
로그인 로그인
</Link> </Link>
)} ))}
</div> </div>
</div> </div>
</header> </header>

View File

@ -1,5 +1,5 @@
import {useState, type FormEvent} from 'react'; import {useState, type FormEvent} from 'react';
import {Link, useNavigate} from 'react-router'; import {Link, useNavigate, useSearchParams} from 'react-router';
import {ArrowRight, ArrowUp, Check} from 'lucide-react'; import {ArrowRight, ArrowUp, Check} from 'lucide-react';
import {MarketingShell, Section, SectionHead} from '@/components/layout/MarketingShell'; import {MarketingShell, Section, SectionHead} from '@/components/layout/MarketingShell';
import {ShowcaseGrid, ShowcasePeeks} from '@/features/marketing/ShowcaseGrid'; import {ShowcaseGrid, ShowcasePeeks} from '@/features/marketing/ShowcaseGrid';
@ -74,6 +74,8 @@ const HEADLINES = [
export function LandingPage() { export function LandingPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const [query, setQuery] = useState(''); const [query, setQuery] = useState('');
const [searchParams] = useSearchParams();
const buildMode = searchParams.get('build') === '1';
const submit = (event: FormEvent) => { const submit = (event: FormEvent) => {
event.preventDefault(); event.preventDefault();
@ -84,7 +86,7 @@ export function LandingPage() {
}; };
return ( return (
<MarketingShell> <MarketingShell showAuthCta={buildMode}>
{/* ── 상단 ─────────────────────────────────────── */} {/* ── 상단 ─────────────────────────────────────── */}
<section className="relative flex min-h-[calc(100dvh-4rem)] items-center overflow-hidden border-b border-border"> <section className="relative flex min-h-[calc(100dvh-4rem)] items-center overflow-hidden border-b border-border">
<div className="mx-auto w-full max-w-6xl px-5 text-center"> <div className="mx-auto w-full max-w-6xl px-5 text-center">
@ -101,56 +103,60 @@ export function LandingPage() {
</span> </span>
홈페이지 홈페이지
</h1> </h1>
<p className="mx-auto mt-6 text-base text-muted-foreground sm:text-lg"> {buildMode && (
가게 이름 한 줄로 시작해 보세요 <p className="mx-auto mt-6 text-base text-muted-foreground sm:text-lg">
</p> 가게 이름 한 줄로 시작해 보세요
</p>
)}
{/* ★ 입력 카드와 발행 사이트 띠를 **같은 밴드**에 겹친다(아임웹과 같은 구조). {/* ★ 입력 카드와 발행 사이트 띠를 **같은 밴드**에 겹친다(아임웹과 같은 구조).
띠를 카드 아래 따로 두면 첫 화면이 세로로 길어지고, 카드가 뜬금없이 혼자 뜬다. */} 띠를 카드 아래 따로 두면 첫 화면이 세로로 길어지고, 카드가 뜬금없이 혼자 뜬다. */}
<div className="relative mt-14"> <div className={`relative mt-14 ${buildMode ? '' : 'min-h-52'}`}>
<div className="pointer-events-none absolute top-1/2 left-1/2 w-screen -translate-x-1/2 -translate-y-1/2"> <div className="pointer-events-none absolute top-1/2 left-1/2 w-screen -translate-x-1/2 -translate-y-1/2">
<ShowcasePeeks /> <ShowcasePeeks />
</div> </div>
<form {buildMode && (
onSubmit={submit} <form
className="relative z-10 mx-auto max-w-2xl rounded-2xl border border-border bg-card p-4 text-left shadow-[0_18px_50px_-20px_rgb(20_22_34/0.35)]" onSubmit={submit}
> className="relative z-10 mx-auto max-w-2xl rounded-2xl border border-border bg-card p-4 text-left shadow-[0_18px_50px_-20px_rgb(20_22_34/0.35)]"
<div className="flex items-center gap-2"> >
<img src="/brand/web4ai-wordmark.svg" alt="Web4Ai" className="h-4 w-auto" /> <div className="flex items-center gap-2">
<span className="rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground"> <img src="/brand/web4ai-wordmark.svg" alt="Web4Ai" className="h-4 w-auto" />
가게 이름으로 시작 <span className="rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground">
</span> 가게 이름으로 시작
{/* 업종부터 고르고 싶은 사람을 위한 갈래. 위저드의 업종 단계로 바로 보낸다. */} </span>
<Link {/* 업종부터 고르고 싶은 사람을 위한 갈래. 위저드의 업종 단계로 바로 보낸다. */}
to="/builder?new=1&step=industry" <Link
className="ml-auto rounded-full border border-border px-3 py-1 text-xs text-muted-foreground transition-colors hover:border-foreground/25 hover:text-foreground" to="/builder?new=1&step=industry"
> className="ml-auto rounded-full border border-border px-3 py-1 text-xs text-muted-foreground transition-colors hover:border-foreground/25 hover:text-foreground"
업종부터 고르기 >
</Link> 업종부터 고르기
</div> </Link>
</div>
<input <input
value={query} value={query}
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
placeholder="가게 이름을 입력하세요" placeholder="가게 이름을 입력하세요"
aria-label="가게 이름" aria-label="가게 이름"
className="mt-4 w-full border-0 bg-transparent px-1 text-base outline-none placeholder:text-muted-foreground sm:text-lg" className="mt-4 w-full border-0 bg-transparent px-1 text-base outline-none placeholder:text-muted-foreground sm:text-lg"
/> />
<div className="mt-8 flex items-center justify-between gap-3"> <div className="mt-8 flex items-center justify-between gap-3">
<p className="truncate text-xs text-muted-foreground"> <p className="truncate text-xs text-muted-foreground">
숙박 · 카페 · 음식점 · 피부과 · 성형외과 숙박 · 카페 · 음식점 · 피부과 · 성형외과
</p> </p>
<button <button
type="submit" type="submit"
aria-label="확인하기" aria-label="확인하기"
className="grid size-9 shrink-0 place-items-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90" className="grid size-9 shrink-0 place-items-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90"
> >
<ArrowUp className="size-4" aria-hidden /> <ArrowUp className="size-4" aria-hidden />
</button> </button>
</div> </div>
</form> </form>
)}
</div> </div>
</div> </div>
</section> </section>