마스코트 한국vs남아공 only -> 전 경기에 반영

develop
jwkim 2026-06-26 17:15:26 +09:00
parent 906896afad
commit 59db1c4e9a
3 changed files with 73 additions and 86 deletions

View File

@ -41,14 +41,14 @@ const DOG_LINES = [
]; ];
const TIGER_LINES = [ const TIGER_LINES = [
"👈 여기서 투표하는 거야", "👈 여기서 투표하는 거야",
"한국 몇 대 몇? 찍어봐! 🇰🇷", "몇 대 몇? 찍어봐! 🎯",
"투표하고 AI랑 붙자 🔥", "투표하고 AI랑 붙자 🔥",
"네 픽 보여줘 봐!", "네 픽 보여줘 봐!",
"정확히 맞히면 네가 레전드 🏆", "정확히 맞히면 네가 레전드 🏆",
"망설이면 마감된다 ⏰", "망설이면 마감된다 ⏰",
"감으로라도 일단 ㄱㄱ", "감으로라도 일단 ㄱㄱ",
"예측 한 방에 인생역전? ㅋㅋ", "예측 한 방에 인생역전? ㅋㅋ",
"한국 이긴다에 한 표! 🇰🇷", "네 승부 예측은? 🤔",
"스코어까지 맞혀봐 🎯", "스코어까지 맞혀봐 🎯",
]; ];
// AI 박스 사자 — AI 예측에 대한 멘트. // AI 박스 사자 — AI 예측에 대한 멘트.
@ -99,10 +99,7 @@ export default function Arena({
const flip = match.teamB.code === "KOR" && match.teamA.code !== "KOR"; const flip = match.teamB.code === "KOR" && match.teamA.code !== "KOR";
const leftShort = flip ? bShort : aShort; const leftShort = flip ? bShort : aShort;
const rightShort = flip ? aShort : bShort; const rightShort = flip ? aShort : bShort;
// 마스코트(사자·버튼 양옆 캐릭터)는 한국-남아공 경기에서만 노출. // 마스코트(사자·버튼 양옆 캐릭터)는 모든 경기에서 노출.
const isKorRsa =
[match.teamA.code, match.teamB.code].includes("KOR") &&
[match.teamA.code, match.teamB.code].includes("RSA");
const [outcome, setOutcome] = useState<Outcome | null>("DRAW"); const [outcome, setOutcome] = useState<Outcome | null>("DRAW");
const [scoreA, setScoreA] = useState(0); const [scoreA, setScoreA] = useState(0);
const [scoreB, setScoreB] = useState(0); const [scoreB, setScoreB] = useState(0);
@ -230,8 +227,7 @@ export default function Arena({
{/* ===== 레이어드 화이트 시트 (002) ===== */} {/* ===== 레이어드 화이트 시트 (002) ===== */}
<section className="sheet relative mt-4 p-5 text-[var(--ink)]"> <section className="sheet relative mt-4 p-5 text-[var(--ink)]">
{/* AI 박스 오른쪽 위 사자 — 한국-남아공전 전용 */} {/* AI 박스 오른쪽 위 사자 — 모든 경기 노출 */}
{isKorRsa && (
<div className="absolute right-1 -top-4 z-10 h-20 sm:h-24"> <div className="absolute right-1 -top-4 z-10 h-20 sm:h-24">
<TalkingMascot <TalkingMascot
src="/assets/mascots/lion_point.webp" src="/assets/mascots/lion_point.webp"
@ -240,7 +236,6 @@ export default function Arena({
draggable draggable
/> />
</div> </div>
)}
<div className="mb-3"> <div className="mb-3">
<h2 className="text-[22px] font-extrabold">{t.aiBattle}</h2> <h2 className="text-[22px] font-extrabold">{t.aiBattle}</h2>
</div> </div>
@ -381,9 +376,8 @@ export default function Arena({
{error && ( {error && (
<p className="mt-2 text-[13px] font-bold text-[#ff6b6b]">{error}</p> <p className="mt-2 text-[13px] font-bold text-[#ff6b6b]">{error}</p>
)} )}
{/* 투표하기 버튼 — 한국-남아공전에서만 양옆에 한국·일본 캐릭터(자동 말풍선) */} {/* 투표하기 버튼 — 모든 경기에서 양옆에 캐릭터(자동 말풍선) */}
<div className="mt-3.5 flex items-end justify-center gap-1"> <div className="mt-3.5 flex items-end justify-center gap-1">
{isKorRsa && (
<TalkingMascot <TalkingMascot
src="/assets/mascots/dog_point.webp" src="/assets/mascots/dog_point.webp"
lines={DOG_LINES} lines={DOG_LINES}
@ -392,7 +386,6 @@ export default function Arena({
autoDelayMs={1200} autoDelayMs={1200}
autoIntervalMs={6000} autoIntervalMs={6000}
/> />
)}
<button <button
onClick={confirmSubmit} onClick={confirmSubmit}
disabled={!emailValid || submitting} disabled={!emailValid || submitting}
@ -400,7 +393,6 @@ export default function Arena({
> >
{submitting ? "…" : <>{t.submit} <span aria-hidden></span></>} {submitting ? "…" : <>{t.submit} <span aria-hidden></span></>}
</button> </button>
{isKorRsa && (
<TalkingMascot <TalkingMascot
src="/assets/mascots/tiger_point.webp" src="/assets/mascots/tiger_point.webp"
lines={TIGER_LINES} lines={TIGER_LINES}
@ -409,7 +401,6 @@ export default function Arena({
autoDelayMs={4200} autoDelayMs={4200}
autoIntervalMs={6000} autoIntervalMs={6000}
/> />
)}
</div> </div>
</div> </div>
)} )}

View File

@ -15,9 +15,7 @@ export default function MatchupHUD({ match, lang = "ko" }: { match: Match; lang?
const right = flip ? match.teamA : match.teamB; const right = flip ? match.teamA : match.teamB;
const leftScore = flip ? match.result?.scoreB : match.result?.scoreA; const leftScore = flip ? match.result?.scoreB : match.result?.scoreA;
const rightScore = flip ? match.result?.scoreA : match.result?.scoreB; const rightScore = flip ? match.result?.scoreA : match.result?.scoreB;
// 마스코트(파도타기 등)는 한국-남아공 경기에서만 노출. // 마스코트(파도타기 등)는 모든 경기에서 노출.
const codes = [match.teamA.code, match.teamB.code];
const isKorRsa = codes.includes("KOR") && codes.includes("RSA");
return ( return (
<section className="mt-6"> <section className="mt-6">
{/* 대결 카드 (녹색 글로우 보더) */} {/* 대결 카드 (녹색 글로우 보더) */}
@ -25,12 +23,10 @@ export default function MatchupHUD({ match, lang = "ko" }: { match: Match; lang?
className="relative rounded-3xl border-2 border-[var(--green)] bg-[#171b21] p-5" className="relative rounded-3xl border-2 border-[var(--green)] bg-[#171b21] p-5"
style={{ boxShadow: "0 0 28px rgba(74,255,160,0.35), inset 0 0 24px rgba(74,255,160,0.06)" }} style={{ boxShadow: "0 0 28px rgba(74,255,160,0.35), inset 0 0 24px rgba(74,255,160,0.06)" }}
> >
{/* 박스 오른쪽 상단 파도타기 (응원 5마리) — 한국-남아공전 전용 */} {/* 박스 오른쪽 상단 파도타기 (응원 5마리) — 모든 경기 노출 */}
{isKorRsa && (
<div className="absolute right-2 top-2 z-10"> <div className="absolute right-2 top-2 z-10">
<WaveStrip /> <WaveStrip />
</div> </div>
)}
{/* 헤더: 브랜드 아이콘 + 팀명 + 일시 */} {/* 헤더: 브랜드 아이콘 + 팀명 + 일시 */}
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">

View File

@ -2,83 +2,83 @@ import { useCallback, useEffect, useRef, useState } from "react";
// 페이지 맨 위 파도타기 — 5마리가 순차로 만세(팔 올림)했다 내린다. // 페이지 맨 위 파도타기 — 5마리가 순차로 만세(팔 올림)했다 내린다.
// 5마리는 한 그룹으로 묶여 함께 끌어 옮길 수 있고, 각 캐릭터를 탭하면 // 5마리는 한 그룹으로 묶여 함께 끌어 옮길 수 있고, 각 캐릭터를 탭하면
// 남아공전 응원 말풍선이 뜬다. // 경기 범용 응원 말풍선이 뜬다.
type Animal = { name: string; lines: string[] }; type Animal = { name: string; lines: string[] };
const WAVE: Animal[] = [ const WAVE: Animal[] = [
{ {
name: "bull", name: "bull",
lines: [ lines: [
"한국, 남아공 잡고 16강 가자! 🇰🇷", "오늘 경기 놓치지 마! 🐂",
"남아공 수비를 뚫어라! 🐂", "수비를 뚫어라! ⚽",
"오늘 이기면 16강이 보인다", "오늘 이기면 분위기 탄다",
"대~한민국! 짝짝짝 👏", "골! 골! 짝짝짝 👏",
"투우사도 한국 응원한다 ⚽",
"스페인도 한국 편이다 🇪🇸",
"남아공 골키퍼 긴장해라!",
"한 골이 16강을 가른다",
"투지로 밀어붙여! 💪", "투지로 밀어붙여! 💪",
"끝까지 간다, 대한민국!", "골키퍼 긴장해라!",
"한 골이 승부를 가른다",
"끝까지 간다, 파이팅!",
"오늘 주인공은 누구? 🔥",
"승점 3점 가져오자",
], ],
}, },
{ {
name: "eagle", name: "eagle",
lines: [ lines: [
"남아공전 무조건 이긴다 🦅", "오늘 승부 무조건 잡는다 🦅",
"한국 16강 가즈아 🇰🇷", "골문을 노려라!",
"남아공 골문을 노려라!",
"이 경기 잡으면 토너먼트행 ✈️", "이 경기 잡으면 토너먼트행 ✈️",
"골! 골! 대한민국! ⚽", "골! 골! 골! ⚽",
"아르헨도 한국 편 🇦🇷",
"역습 한 방이면 끝난다", "역습 한 방이면 끝난다",
"오늘 클린시트 가자 🧤", "오늘 클린시트 가자 🧤",
"남아공 수비 흔들어!", "수비 흔들어!",
"16강에서 또 보자 ✈️", "하늘에서 다 보인다 👀",
"끝까지 집중하자",
"다음 라운드에서 또 보자 ✈️",
], ],
}, },
{ {
name: "rooster", name: "rooster",
lines: [ lines: [
"꼬끼오~ 한국 남아공 이겨라! 🐓", "꼬끼오~ 오늘 이겨라! 🐓",
"16강 길목, 오늘이 중요해", "승부의 길목, 오늘이 중요해",
"남아공 막고 골 넣자!", "막고 골 넣자!",
"대한민국 파이팅 🇰🇷", "파이팅! 🙌",
"프랑스도 한국 편이다 🙌",
"전반부터 몰아쳐라 🐓", "전반부터 몰아쳐라 🐓",
"남아공 김빠지게 골 넣자", "김빠지게 골 넣자",
"한국 미드필드 최고지", "미드필드 장악하자",
"오늘 분위기 우리 거야", "오늘 분위기 우리 거야",
"꼬끼오! 승리의 함성 📣", "꼬끼오! 승리의 함성 📣",
"한 점이라도 앞서가자",
], ],
}, },
{ {
name: "parrot", name: "parrot",
lines: [ lines: [
"삼바 응원! 한국 남아공 격파 🥁", "삼바 리듬 타고 골 가자 🥁",
"골 넣고 16강 가자 💃", "골 넣고 앞서가자 💃",
"남아공 수비 흔들어! 🔥", "수비 흔들어! 🔥",
"대한민국 가즈아 🇰🇷", "가즈아 🎶",
"오늘 승점 3점 챙기자 ⚽", "오늘 승점 3점 챙기자 ⚽",
"리듬 타고 골 가자 🎶", "리듬 타고 골! 🎶",
"남아공? 삼바로 제압! 💃", "삼바로 제압! 💃",
"한 골 한 골 쌓아가자 ⚽", "한 골 한 골 쌓아가자 ⚽",
"응원석도 파도타기 🌊", "응원석도 파도타기 🌊",
"오늘 MVP는 대한민국 🏆", "오늘 MVP는 누구? 🏆",
], ],
}, },
{ {
name: "horse", name: "horse",
lines: [ lines: [
"달려라 대한민국, 남아공 잡자! 🏇", "달려라! 끝까지 간다 🏇",
"16강 가는 길, 오늘이 분수령", "승부의 분수령, 오늘!",
"남아공 골문 열어라 ⚽", "골문 열어라 ⚽",
"끝까지 응원! 한국 화이팅 📣", "끝까지 응원! 화이팅 📣",
"호날두도 한국 응원한다 🐴",
"측면 돌파로 무너뜨려!", "측면 돌파로 무너뜨려!",
"스피드로 남아공 제쳐라 🏇", "스피드로 제쳐라 🏇",
"한 점 차도 이기면 돼", "한 점 차도 이기면 돼",
"16강 티켓 가져오자 🎫", "승리 티켓 가져오자 🎫",
"포르투갈도 함께 외친다 🇵🇹", "막판 뒷심 보여주자 💨",
"포기란 없다, 달려! 🐴",
], ],
}, },
]; ];