import { useState } from "react" import { AnimatePresence, motion } from "motion/react" import { Check, Monitor, Smartphone, type LucideIcon } from "lucide-react" import { BrowserFrame, PhoneFrame } from "@/components/ui/device-mockups" import { Section } from "@/components/ui/section" import { SectionHeading } from "@/components/ui/section-heading" import { Typography } from "@/components/ui/typography" /** 3단계 이용 가이드 — 탭 전환식 GIF 시연 (데스크톱/모바일 목업). */ export function HowItWorksDemo() { const [activeKey, setActiveKey] = useState("create") const activeTab = DEMO_TABS.find((tab) => tab.key === activeKey)! return (
{/* 탭 스위치 */}
{DEMO_TABS.map((tab) => ( ))}
{/* 좌: 단계 설명 */}
{/* 알약 배경 + 아이콘을 뺀 글자만의 라벨. 레퍼런스 라벨은 11px/600/자간 normal 에 배경도 아이콘도 없다. */}
{activeTab.badge.label}
{activeTab.heading} {activeTab.paragraphs.map((paragraph, idx) => ( {paragraph} ))}
{activeTab.checks.map((check, idx) => (
{check}
))}
{/* 우: 디바이스 목업 + GIF */}
{activeTab.mockup === "browser" ? ( ) : ( )}
) } /** GIF 로드 실패 시(파일 미배치) 배치 안내 폴백을 보여주는 슬롯. */ function GifSlot({ tab }: { tab: DemoTab }) { const [error, setError] = useState(false) if (error) { const phone = tab.mockup === "phone" return (

{tab.fallback.title}

프로젝트 루트의{" "} public{tab.gif} 경로에{" "} {tab.fallback.hint}

) } // video(mp4)가 있으면 우선 재생 — 줌 스크린캐스트는 GIF보다 용량 1/5·화질 우위. 없으면 GIF. if (tab.video) { return (