"use client"; import React, { useEffect, useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { cn } from "@/lib/utils"; const TONE_PHRASES = [ { q: "주식이 너무 어려워요...", a: "걱정하지 마. JOORIN-E가 다 해줄게." }, { q: "내 돈, 정말 안전할까?", a: "안심해도 돼. 금융권 수준 보안키로 지키니까.", }, { q: "손실 날까 봐 불안해요...", a: "걱정하지 마. 안전 장치가 24시간 작동해.", }, { q: "복잡한 건 딱 질색인데..", a: "몰라도 돼. 클릭 몇 번이면 바로 시작이야.", }, ]; /** * @description 프리미엄한 텍스트 리빌 효과를 제공하는 브랜드 톤 컴포넌트 */ export function AnimatedBrandTone() { const [index, setIndex] = useState(0); useEffect(() => { const timer = setInterval(() => { setIndex((prev) => (prev + 1) % TONE_PHRASES.length); }, 5000); return () => clearInterval(timer); }, []); const answerText = TONE_PHRASES[index].a; const answerChars = answerText.split(""); const answerLength = answerChars.length; const answerFontSize = resolveAnswerFontSize(answerLength); const answerTracking = resolveAnswerTracking(answerLength); return (
{/* 질문 (Q) */} “{TONE_PHRASES[index].q}” {/* 답변 (A) - 타이핑 효과 */}

{answerChars.map((char, i) => ( {char === " " ? "\u00A0" : char} ))} {/* 깜빡이는 커서 */}

{/* 인디케이터 - 유휴 상태 표시 및 선택 기능 */}
{TONE_PHRASES.map((_, i) => (
); } function resolveAnswerFontSize(answerLength: number) { if (answerLength >= 30) { return "clamp(1rem,2.4vw,2.2rem)"; } if (answerLength >= 25) { return "clamp(1.15rem,2.9vw,2.9rem)"; } if (answerLength >= 20) { return "clamp(1.3rem,3.4vw,3.8rem)"; } return "clamp(1.45rem,4vw,4.8rem)"; } function resolveAnswerTracking(answerLength: number) { if (answerLength >= 30) { return "-0.008em"; } if (answerLength >= 25) { return "-0.012em"; } if (answerLength >= 20) { return "-0.016em"; } return "-0.018em"; }