사이트 업그레이드 Day 2Playground 미니게임부터 Dark Place 보안 실습까지
Day 1에서 3D 히어로와 next/image 최적화를 끝냈다. 사이트의 뼈대는 잡혔는데, 콘텐츠와 인터랙션이 빠져있었다. 방문자가 들어와서 구경하고 나갈 거리가 없는 상태.
Day 2는 그 빈 공간을 채우는 작업이다. 미니게임, 보안 실습, 도구 페이지 리뉴얼, UI 세부 조정까지 — 33개 파일을 건드렸다.
Playground — 미니게임 4종

/playground 경로에 미니게임 허브를 만들었다. 2x2 그리드로 게임 4개가 배치된다.
- AI Memory Game — AI 모델 로고(Claude, GPT, Gemini 등)를 짝 맞추는 카드 매칭. 최단 시간 + 최소 moves 조합으로 순위를 매긴다.
- 가위바위보 vs AI — Math.random 기반 AI와의 대결. 연승 기록이 핵심.
- 반응속도 테스트 — 초록색 전환 시 클릭. 5라운드 평균을 측정한다.
- 숫자 기억 테스트 — 점점 길어지는 숫자열을 외우고 입력. 몇 자리까지 가는지가 기록.
기술적으로 특별한 건 없다. 전부 useState/useEffect 기반이고, 서버 통신은 전혀 없다.
리더보드는 useLeaderboard.ts 커스텀 훅으로 공통화했다. localStorage에 상위 10개 기록을 JSON으로 저장하고, 시간 순 정렬 후 슬라이스한다. 닉네임, 시간, moves, 날짜를 LeaderboardEntry로 관리하는 구조다.
// useLeaderboard.ts — 핵심 로직
const updated = [...current, entry]
.sort((a, b) => a.time - b.time || a.moves - b.moves)
.slice(0, MAX_ENTRIES);
localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
각 게임 카드에는 그라디언트 hover 배경이 깔린다. from-violet-500/10 to-purple-500/5 같은 반투명 그라디언트를 absolute positioned div로 겹쳐서 opacity 전환하는 방식이다.
Dark Place 확장 — Labs & Learn
White Place의 반대편인 Dark Place에 보안 교육 콘텐츠를 추가했다.
/dark/labs — 체험형 보안 실습
5개 실습을 만들었다.
| 실습 | 난이도 | 내용 |
|---|---|---|
| Password Cracker | Easy | 비밀번호 강도 분석 + 해독 시간 시뮬레이션 |
| SQL Injection | Medium | 안전한 코드 vs 위험한 코드 직접 비교 |
| Phishing Quiz | Easy | 진짜/피싱 이메일 8개 판별 퀴즈 |
| HTTPS vs HTTP | Medium | 평문/암호화 통신 시각적 비교 |
| Breach Timeline | Easy | 역대 대규모 데이터 유출 타임라인 |
모든 실습은 브라우저에서만 동작하는 시뮬레이션이다. 실제 공격이 아니라 원리를 체험하는 데 초점을 맞췄다. LabCard 컴포넌트에 난이도 뱃지(easy/medium)를 달아서 진입 장벽을 낮췄고, LabShell이 공통 레이아웃을 담당한다.
/dark/learn — 시각적 보안 학습
영상과 애니메이션 기반 학습 페이지다. securityLessons.ts에서 레슨 데이터를 관리하고, 난이도 필터(Easy/Medium/Hard)로 걸러서 보여준다. LearnCard와 VideoEmbed 컴포넌트로 구성.
보안 뉴스
src/content/security/ 디렉토리에 보안 뉴스 5건을 추가했다. SecurityNewsCard, SecurityNewsListClient, DarkPagination 세 컴포넌트가 Dark Place의 뉴스 피드를 담당한다. White Place의 BlogListClient와 비슷한 패턴인데, 다크 테마 전용 CSS 토큰(--dp-*)으로 완전히 분리된다.
darkplace.module.css에 309줄을 추가했다. Labs와 Learn 전용 스타일 — 카드 레이아웃, 난이도 뱃지 색상, 호버 효과 — 이 대부분이다.
Tools 페이지 리뉴얼
기존 /tools 페이지는 HeroIcons에 한 줄 설명만 달려있었다. 이번에 전면 재설계했다.
바뀐 점:
- 아이콘을 실제 브랜드 SVG 경로로 교체. Claude, ChatGPT, Grok, Gemini, VS Code, GitHub, Docker, Homebrew, Vercel, Notion, Figma, Slack까지 12개.
detail필드를 추가해서 hover 시 카드 아래에 상세 설명이 나타나는 확장형 UI를 구현했다.- 카테고리 뱃지(AI, 에디터, 개발, 배포, 생산성, 디자인, 커뮤니케이션)로 분류.
// hover detail — scale + fade in
<div className="
absolute inset-x-0 top-full mt-3 z-[100]
pointer-events-none
opacity-0 scale-95 translate-y-2
group-hover:opacity-100 group-hover:scale-100 group-hover:translate-y-0
transition-all duration-300 ease-out
origin-top
">
각 카드에는 bg-gradient-to-br 그라디언트가 적용된 아이콘 배경이 들어간다. Claude는 from-violet-500 to-purple-500, ChatGPT는 from-emerald-500 to-green-500 식으로 브랜드 컬러에 맞췄다.

UI 폴리시
큰 기능 외에 자잘한 개선들.
Footer
기존 Footer를 framer-motion으로 전면 교체했다. staggerChildren: 0.06으로 각 요소가 순차적으로 나타나는 stagger 애니메이션을 넣었다. Brand 영역 + 3개 링크 그룹(탐색, 콘텐츠, 도구)을 4컬럼 그리드로 배치하고, 각 그룹에 그라디언트 아이콘을 달았다.
하단 바에는 GitHub, Instagram, Email 소셜 링크가 glass 스타일 아이콘으로 별도 배치된다. whileHover: scale 1.1, whileTap: scale 0.95로 spring 기반 마이크로 인터랙션을 넣었다.
ThemeToggle → Dark Place 포탈
기존 다크모드 토글 버튼을 Dark Place 진입 포탈로 바꿨다. 달 아이콘을 클릭하면 /dark로 이동하고, hover 시 "Dark Place" 텍스트가 slide-in된다.
30초마다 아이콘에 attention pulse가 한 번 돌고, 세션 첫 방문 시 5초 후에 "Dark Place 구경하기" 툴팁이 3초간 표시된다. sessionStorage로 세션당 한 번만 보여주는 것까지 처리했다. prefers-reduced-motion 미디어 쿼리도 체크해서 모션 감소 설정 사용자에게는 펄스와 툴팁 모두 비활성화된다.
Navbar & Sitemap
Navbar에 Playground, Tools 링크를 추가하고, sitemap.ts에 /playground, /dark/labs, /dark/learn, /dark/news 등 신규 경로를 전부 반영했다.
변경 규모

| 항목 | 수치 |
|---|---|
| 수정/추가 파일 | 33개 |
| 추가 라인 | ~1,500 |
| 삭제 라인 | ~940 |
| 신규 컴포넌트 | 12개 (Playground 4 + Dark Place 6 + Tools 리뉴얼 + Footer) |
| 신규 라우트 | 8개 (/playground/*, /dark/labs, /dark/learn, /dark/news) |

남은 과제
Labs의 인터랙티브 실습은 아직 UI 껍데기만 있고 내부 로직 구현이 남아있다. Password Cracker의 해독 시간 알고리즘, SQL Injection의 쿼리 파싱 시뮬레이터 같은 것들. 보안 뉴스 수동 작성도 자동화로 바꿔야 한다 — RSS 피드 파싱이나 Firecrawl 연동을 고려 중이다.
Day 1이 구조를 잡는 날이었다면, Day 2는 살을 붙이는 날이었다. 다음은 그 살에 움직임을 넣는 차례다.