여기서 직접 체험 → 협상 예시 체험 데모 요청 → 실제 데모 받기 두 버튼은 성격이 전혀 다른데 문구가 그걸 구분하지 못했다. 1차는 페이지 안에서 바로 조작하는 인터랙티브 데모고, 2차는 이름·이메일을 받는 리드 폼이다. 클릭 직후 경험이 다르므로 문구도 갈라야 한다. 협상 예시 체험 고정 데이터 시뮬레이션이라 "예시"를 밝힌다. 다만 "보기"로 낮추지는 않았다 — 도착 섹션이 "직접 경험해 보세요" 이고 역할 카드가 "공급사로 해보기" 라, 버튼만 구경하는 말이면 클릭 전 기대와 도착 후 요구가 어긋난다. 실제 데모 받기 누르면 폼이 뜨고 데모는 이메일로 온다. "직접 체험" 이라 쓰면 눌렀을 때 바로 만질 줄 알았다가 입력을 요구받아 낚인 느낌이 된다. "받기" 는 이메일로 온다는 사실이 드러나서 폼이 뜨는 게 자연스럽다. 모달 제목도 "데모 요청" → "실제 데모 받기" 로 맞췄다. 버튼이 "받기" 인데 열린 창이 "요청" 이면 전환 순간에 다른 화면처럼 읽힌다. 제출 버튼은 "데모 신청" 그대로 둔다. 같은 원칙을 적용하면 그 클릭으로 실제 일어나는 일은 신청 접수이지 데모 수령이 아니다(수령은 이메일로 나중에). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
134 lines
7.8 KiB
TypeScript
134 lines
7.8 KiB
TypeScript
import { useState } from "react"
|
|
import { ArrowRight } from "lucide-react"
|
|
|
|
import { Button } from "@/components/ui/button"
|
|
import { DemoRequestModal } from "@/components/ui/demo-request-modal"
|
|
import { CTA_GAP, DISPLAY_LEAD_GAP } from "@/components/ui/section-heading"
|
|
import { Typography } from "@/components/ui/typography"
|
|
|
|
/**
|
|
* 다크 무대 히어로 — 배경 루프 영상.
|
|
*
|
|
* 예전에는 캔버스가 negotium 파이프라인을 직접 그렸고(입자 240개·6단계 서사·무리 라벨),
|
|
* 배경이 곧 설명이었다. 지금은 배경을 배경으로만 쓴다 — 설명은 카피와 아래 섹션이 맡는다.
|
|
* 그래서 무리 라벨(CLUSTER_ANCHORS)도 함께 걷어냈다. 좌표 소스가 사라진 라벨은
|
|
* 화면비가 바뀔 때마다 어긋나기만 하고 아무것도 설명하지 못한다.
|
|
*
|
|
* 배경이 의미를 지지 않으므로 카피 가독성이 1순위다. 그래서:
|
|
* - 영상 위에 스크림을 깐다. 예전 캔버스는 하단 밴드에만 입자가 있어 상단이 비었지만,
|
|
* 이 영상은 화면 전체에 밝은 요소가 흩어져 흰 글자가 묻힌다.
|
|
* - 카피는 화면 중앙 정렬. 밴드 개념이 없으니 상하로 나눌 이유도 없다.
|
|
*/
|
|
export function HeroDataFlow() {
|
|
const [demoOpen, setDemoOpen] = useState(false)
|
|
|
|
return (
|
|
<section
|
|
data-stage-hero
|
|
className="stage-bg relative min-h-screen text-on-stage flex flex-col overflow-hidden"
|
|
>
|
|
{/* 영상은 가로 화면에서만 튼다.
|
|
16:9 소스를 세로 화면에 object-cover 로 깔면 가로가 62% 잘리고 남은 38% 가
|
|
1.7배로 확대된다(848x1220 실측) — 데이터 입자가 거대한 보케로 뭉개져서
|
|
배경이 아니라 노이즈가 된다. 캔버스는 뷰포트에 맞춰 그렸으니 없던 문제다.
|
|
세로에서는 무대 그라데이션(stage-bg)만 남긴다. 그게 브랜드 배경이라 빈 화면이 아니다.
|
|
prefers-reduced-motion 에서도 같은 이유로 영상을 감춘다 — 포스터가 뒤를 받친다. */}
|
|
<div
|
|
aria-hidden
|
|
className="absolute inset-0 hidden landscape:block motion-reduce:hidden bg-cover bg-center"
|
|
style={{ backgroundImage: "url(/gifs/hero_loop.jpg)" }}
|
|
>
|
|
<video
|
|
className="w-full h-full object-cover"
|
|
src="/gifs/hero_loop.mp4"
|
|
poster="/gifs/hero_loop.jpg"
|
|
autoPlay
|
|
muted
|
|
loop
|
|
playsInline
|
|
preload="metadata"
|
|
/>
|
|
</div>
|
|
|
|
{/* 카피 가독성용 스크림.
|
|
색은 하나(stage-deep)로 두고 알파만 움직인다 — 중간 stop 에서 색이 바뀌면
|
|
그 지점이 가로선으로 읽힌다.
|
|
|
|
알파는 90/60/95 였다가 낮췄다. 그 값은 헤드라인 둘째 줄이 회색(/60)이던 시절
|
|
그 글자를 살리려고 깐 것인데, 가장 옅은 지점에서도 영상이 40% 만 남아서
|
|
배경 전체가 탁해졌다. 헤드라인이 흰색이 된 지금은 이만큼 덮을 이유가 없다.
|
|
구간별로 필요한 만큼만 준다 — 위는 헤더 nav(작은 회색 글자), 가운데는 흰
|
|
헤드라인이라 가장 옅게, 아래는 다음 섹션으로 넘어가는 암전(h-32)이 따로 있다. */}
|
|
<div
|
|
aria-hidden
|
|
className="absolute inset-0 pointer-events-none bg-linear-to-b from-stage-deep/50 via-transparent to-stage-deep/45"
|
|
/>
|
|
|
|
{/* 카피 뒤만 국소적으로 누른다.
|
|
전면을 균일하게 덮으면 글자는 살지만 영상이 통째로 탁해진다. 반대로 다 걷으면
|
|
헤드라인(흰색 74px)은 버텨도 리드 문단(17px)이 밝은 입자 위에서 읽히지 않는다.
|
|
둘 다 만족하는 유일한 방법은 덮는 범위를 글자가 있는 자리로 좁히는 것이다.
|
|
가장자리는 영상이 그대로 보이고 가운데만 어두워진다. */}
|
|
<div
|
|
aria-hidden
|
|
className="absolute inset-0 pointer-events-none"
|
|
style={{
|
|
background:
|
|
"radial-gradient(58% 42% at 50% 45%," +
|
|
" color-mix(in srgb, var(--color-stage-deep) 85%, transparent) 0%," +
|
|
" color-mix(in srgb, var(--color-stage-deep) 55%, transparent) 45%," +
|
|
" transparent 72%)",
|
|
}}
|
|
/>
|
|
|
|
{/* 아래 라이트 섹션과의 경계를 부드럽게 */}
|
|
<div aria-hidden className="absolute inset-x-0 bottom-0 h-32 bg-linear-to-b from-transparent to-stage pointer-events-none" />
|
|
|
|
{/* pt-[104px] 는 fixed 헤더 회피용 바닥. 그 아래 남은 공간에서 수직 중앙 정렬한다. */}
|
|
<div className="relative z-10 w-full flex-1 pt-[104px] pb-16 flex items-center">
|
|
<div className="max-w-4xl mx-auto px-6 w-full text-center">
|
|
{/* 히어로 카피에는 진입 애니메이션을 걸지 않는다.
|
|
여기가 LCP 요소라 opacity:0 으로 시작하면 하이드레이션 전까지 첫 화면이 비고,
|
|
광고 유입처럼 JS 가 느린 환경에서 그대로 손실이 된다. 모션은 배경 영상이 맡는다. */}
|
|
{/* 여기는 2톤을 쓰지 않는다. 예전 캔버스 배경은 하단 밴드에만 입자가 있어 헤드라인
|
|
뒤가 거의 단색이었고, 그때는 투명도 60% 로 낮춘 둘째 줄도 읽혔다. 배경이 영상으로
|
|
바뀌면서 밝은 요소가 글자 뒤로 지나가 그 대비가 무너졌다 — 배경이 움직이는 위에서는
|
|
가독성이 조판 장치보다 우선한다. 2톤은 최종 CTA 에 남아 있다(그쪽은 배경이 정적). */}
|
|
<Typography variant="stageDisplay">
|
|
<span className="text-white">협력사 전원과 1:1로,</span>
|
|
<br />
|
|
<span className="text-white">동시에 협상합니다.</span>
|
|
</Typography>
|
|
|
|
{/* 히어로는 h1 이어야 해서 SectionHeading(h2 고정)을 못 쓴다. 대신 간격만은
|
|
같은 상수를 물려 최종 CTA 와 리듬이 어긋나지 않게 한다. */}
|
|
<p className={`${DISPLAY_LEAD_GAP} text-base sm:text-lg text-on-stage-soft leading-relaxed break-keep max-w-2xl mx-auto`}>
|
|
품목·목표가·마감일만 정하면 됩니다. 협상 에이전트가 협력사마다 따로 붙어 단가를 조율하고, 마감 시각에
|
|
최저 투찰가로 낙찰까지 판정합니다.
|
|
</p>
|
|
|
|
{/* 2차 CTA 는 상담 신청(#contact-section)과 목적지가 겹쳐 사실상 같은 버튼이었다.
|
|
데모 경로로 갈라서, 고관여 폼(상담 신청) 앞단에 저관여 리드 캡처를 둔다.
|
|
|
|
문구는 "클릭하면 무슨 일이 일어나는가"에 맞춘다.
|
|
협상 예시 체험 — 페이지 안에서 바로 조작한다. 고정 데이터라 "예시"를 밝히되,
|
|
도착 섹션이 "직접 경험해 보세요"·"해보기" 라 "보기"로 낮추면 어긋난다.
|
|
실제 데모 받기 — 누르면 폼이 뜨고 이메일로 온다. "체험"이라 쓰면 눌렀을 때
|
|
바로 만질 줄 알았다가 입력을 요구받아 낚인 느낌이 된다. */}
|
|
<div className={`${CTA_GAP} flex flex-col sm:flex-row gap-3 justify-center`}>
|
|
<Button href="#how-it-works" variant="stage" size="stageRound" className="group">
|
|
<span>협상 예시 체험</span>
|
|
<ArrowRight className="w-4 h-4 transition-transform group-hover:translate-x-0.5" />
|
|
</Button>
|
|
<Button type="button" variant="stageGhost" size="stageRound" onClick={() => setDemoOpen(true)}>
|
|
실제 데모 받기
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<DemoRequestModal open={demoOpen} onClose={() => setDemoOpen(false)} />
|
|
</section>
|
|
)
|
|
}
|