[feat] solution/frontend: 히어로를 첫 화면 높이로 · 검색창 pill · 쇼케이스 카드 축소

콘텐츠가 세로로 퍼져서 첫 화면에 임팩트가 없었다.

- 히어로 min-h-[calc(100dvh-3.5rem)] + 세로 가운데. 헤더(h-14)를 빼야 스크롤바가 안 생기고,
  vh 가 아니라 dvh 인 이유는 모바일에서 주소창이 접혔다 펴져 vh 가 흔들리기 때문
- 검색창·버튼을 rounded-full h-13 로. 아이콘 여백도 같이 밀었다
- 마퀴 카드 w-52 → w-40, 간격·글자 축소. 히어로 안에 들어와야 한 화면에 다 담긴다
This commit is contained in:
Mina Choi 2026-09-03 10:58:02 +09:00
parent d8ed0766d6
commit 0c3f8dd3b0
2 changed files with 14 additions and 14 deletions

View File

@ -130,11 +130,11 @@ export function ShowcasePeeks({limit = 10}: {limit?: number}) {
return (
<div
className="o2o-marquee relative mt-10 overflow-hidden [mask-image:linear-gradient(90deg,transparent,#000_8%,#000_92%,transparent)]"
className="o2o-marquee relative mt-8 overflow-hidden [mask-image:linear-gradient(90deg,transparent,#000_8%,#000_92%,transparent)]"
aria-label="발행된 홈페이지"
>
<div
className="o2o-marquee-track flex w-max gap-4 py-1"
className="o2o-marquee-track flex w-max gap-3 py-1"
style={{'--marquee-duration': duration} as CSSProperties}
>
{[...items, ...items].map((item, index) => (
@ -146,7 +146,7 @@ export function ShowcasePeeks({limit = 10}: {limit?: number}) {
// 두 벌째는 첫 벌의 복제다 — 스크린리더가 같은 목록을 두 번 읽지 않게 한다.
aria-hidden={index >= items.length}
tabIndex={index >= items.length ? -1 : undefined}
className="w-52 shrink-0 overflow-hidden rounded-xl border border-border bg-card text-left transition-transform hover:-translate-y-0.5"
className="w-40 shrink-0 overflow-hidden rounded-lg border border-border bg-card text-left transition-transform hover:-translate-y-0.5"
>
<div className="flex aspect-[16/10] items-center justify-center overflow-hidden bg-muted">
{item.thumbnailUrl ? (
@ -160,9 +160,9 @@ export function ShowcasePeeks({limit = 10}: {limit?: number}) {
<ImageOff className="size-5 text-muted-foreground/40" aria-hidden />
)}
</div>
<div className="px-3 py-2.5">
<p className="truncate text-xs font-semibold tracking-tight">{item.name}</p>
<p className="truncate text-[11px] text-muted-foreground">
<div className="px-2.5 py-2">
<p className="truncate text-[11px] font-semibold tracking-tight">{item.name}</p>
<p className="truncate text-[10px] text-muted-foreground">
{[item.region, CATEGORY_LABEL[item.category]].filter(Boolean).join(' · ')}
</p>
</div>

View File

@ -55,8 +55,8 @@ export function LandingPage() {
return (
<MarketingShell>
{/* ── 상단 ─────────────────────────────────────── */}
<section className="border-b border-border">
<div className="mx-auto w-full max-w-6xl px-5 py-16 text-center sm:py-20">
<section className="flex min-h-[calc(100dvh-3.5rem)] items-center border-b border-border">
<div className="mx-auto w-full max-w-6xl px-5 py-12 text-center">
<h1 className="mx-auto max-w-4xl text-4xl leading-[1.25] font-bold tracking-[-0.04em] sm:text-6xl">
{/* 앞말만 돈다. 마지막 항목은 첫 항목의 복제다 — 되감을 때 글자가 튀지 않게(index.css). */}
<span className="o2o-rotator">
@ -70,14 +70,14 @@ export function LandingPage() {
</span>
</h1>
<p className="mx-auto mt-4 max-w-xl text-sm text-muted-foreground sm:text-base">
<p className="mx-auto mt-3 max-w-xl text-sm text-muted-foreground sm:text-base">
</p>
<form onSubmit={submit} className="mx-auto mt-8 flex max-w-lg gap-2">
<form onSubmit={submit} className="mx-auto mt-6 flex max-w-lg gap-2">
<div className="relative flex-1">
<Search
className="pointer-events-none absolute top-1/2 left-4 size-4 -translate-y-1/2 text-muted-foreground"
className="pointer-events-none absolute top-1/2 left-5 size-4 -translate-y-1/2 text-muted-foreground"
aria-hidden
/>
<input
@ -85,16 +85,16 @@ export function LandingPage() {
onChange={(e) => setQuery(e.target.value)}
placeholder="가게 이름을 입력하세요"
aria-label="가게 이름"
className="h-12 w-full rounded-lg border border-border bg-card pr-4 pl-11 text-sm shadow-sm transition-colors outline-none placeholder:text-muted-foreground focus:border-ring focus:ring-1 focus:ring-ring"
className="h-13 w-full rounded-full border border-border bg-card pr-5 pl-12 text-sm shadow-sm transition-colors outline-none placeholder:text-muted-foreground focus:border-ring focus:ring-1 focus:ring-ring"
/>
</div>
<Button type="submit" variant="primary" size="lg" className="shrink-0">
<Button type="submit" variant="primary" size="lg" className="h-13 shrink-0 rounded-full px-7">
</Button>
</form>
{/* 업종은 고르지 않아도 된다 — 여기 있는 건 "누구를 위한 서비스인가" 를 말하기 위한 것이다. */}
<div className="mt-4 flex flex-wrap items-center justify-center gap-2">
<div className="mt-3 flex flex-wrap items-center justify-center gap-2">
{INDUSTRIES.map(({id, label, icon: Icon}) => (
<Link
key={id}