o2o-infinith-demo/src/components/discovery/WhyNow.tsx
Haewon Kam 14c4b82155 refactor(design): 요청문과 설명문을 텍스트 역할 토큰으로 가른다
"한 장씩 봐 주세요" 같은 요청문이 읽고 넘어가는 설명문과 같은 무게로 놓여 있어
지나치기 쉬웠다. 역할별 토큰과 클래스를 두고 화면에 적용한다.

  .ui-ask   요청문. 사람이 무엇을 해야 하는지 말하는 문장 (17px·600·인디고)
  .ui-ask-block  문단으로 서는 요청문. 왼쪽 규칙선으로 설명과 구분한다
  .ui-body  설명 본문 (16px·slate-600)
  .ui-note  보조·출처 (14px·slate-400)

크기는 기존 화면을 세어 맞췄다. text-base 167회·text-sm 58회가 지배적이라
body 를 16px, note 를 14px 로 두면 치환해도 크기가 변하지 않고 역할과 색만 정리된다.

한글 줄바꿈: word-break keep-all 로 어절을 지키고, 긴 URL·영문 토큰만
overflow-wrap anywhere 로 자른다. text-wrap 으로 마지막 줄에 한 어절만 남는 것을
줄이고, 62ch 로 줄 길이를 묶는다. 제목에도 keep-all 과 balance 를 건다.

다크 섹션은 .on-dark 로 값을 뒤집고, 그 안의 흰 카드는 .on-light 로 되돌린다.
이걸 두지 않으면 흰 글씨가 흰 배경에 얹혀 보이지 않는다(디자인 시스템 기록된 실수).

사진 확인 화면의 썸네일 줄이 누를 수 있는 것으로 안 읽혀 같이 고친다. 72px 카드,
호버 반응, 순번 배지, 현재 위치 표시, 안 정한 것 아래 띠, 범례, 이전·다음 이동을 둔다.
상태가 안 보이는 것이 크기보다 큰 문제였다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:56:52 +09:00

71 lines
2.9 KiB
TypeScript

/**
* Why Now 다크 밴드.
* ⚠️ 3개 수치(12종 크롤러 / 네이버 기여 0건 / Direct 유실 35~70%)는 근거 있는 실측·문헌 값.
* 새 시장 통계를 임의로 추가하지 않는다 (근거 확인 후에만).
*/
import { motion } from 'motion/react';
const STATS = [
{
figure: '12종',
title: 'AI 크롤러가 이미 읽는 중',
detail:
'GPTBot·OAI-SearchBot·PerplexityBot 등이 오늘도 병원 사이트를 수집합니다. 문제는 접근이 아니라 인용할 내용입니다.',
},
{
figure: '0건',
title: '네이버 자산의 AI 기여',
detail:
'네이버 블로그·플레이스는 robots.txt로 AI 크롤러를 전면 차단합니다(2026-08 실측). 지금까지의 네이버 마케팅은 AI 답변에 닿지 않습니다.',
},
{
figure: '35~70%',
title: 'Direct로 숨는 AI 유입',
detail:
'AI가 보낸 방문의 상당수는 유입 경로 없이 도착합니다. 측정 인프라 없이는 이미 오는 환자도 세지 못합니다.',
},
];
export default function WhyNow() {
return (
<section id="why-now" className="on-dark bg-[#0A1128] px-6 py-22">
<div className="max-w-7xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<div className="text-sm font-bold tracking-[0.24em] text-[#AF90FF] mb-4">WHY NOW</div>
<h2 className="font-serif text-3xl md:text-[40px] font-bold leading-tight text-white mb-3 break-keep">
, .
</h2>
<p className="text-[17px] leading-[1.7] text-slate-400 mb-14 break-keep">
.
.
</p>
</motion.div>
<div className="grid md:grid-cols-3 gap-8">
{STATS.map((stat, index) => (
<motion.div
key={stat.figure}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: index * 0.1 }}
className="flex flex-col gap-2.5 p-7 bg-[#0F1B45] border border-[#2A3A6B] rounded-2xl"
>
<div className="font-serif text-[46px] font-bold text-[#AF90FF] leading-tight">
{stat.figure}
</div>
<div className="text-base font-semibold text-white break-keep">{stat.title}</div>
<p className="text-[14.5px] leading-[1.7] text-slate-400 break-keep">{stat.detail}</p>
</motion.div>
))}
</div>
</div>
</section>
);
}