create-ax-project 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/bin/create.js +97 -40
  2. package/package.json +5 -2
  3. package/template/.claude/CLAUDE.md +0 -7
  4. package/template/.claude/commands/CLAUDE.md +0 -0
  5. package/template/.claude/hooks/CLAUDE.md +0 -0
  6. package/template/.claude/skills/ai-collaboration/CLAUDE.md +0 -0
  7. package/template/.claude/skills/auto-checkpoint/CLAUDE.md +0 -0
  8. package/template/.claude/skills/context-compression/CLAUDE.md +0 -0
  9. package/template/.claude/skills/context-compression/prompts/CLAUDE.md +0 -0
  10. package/template/.claude/skills/output-validator/CLAUDE.md +0 -0
  11. package/template/.claude/skills/smart-handoff/CLAUDE.md +0 -0
  12. package/template/.claude/skills/stage-transition/CLAUDE.md +0 -0
  13. package/template/.claude/skills/stage-transition/prompts/CLAUDE.md +0 -0
  14. package/template/config/CLAUDE.md +0 -0
  15. package/template/scripts/CLAUDE.md +0 -0
  16. package/template/stages/01-brainstorm/HANDOFF.md +0 -110
  17. package/template/stages/01-brainstorm/inputs/CLAUDE.md +0 -0
  18. package/template/stages/01-brainstorm/inputs/project_brief.md +0 -40
  19. package/template/stages/01-brainstorm/outputs/CLAUDE.md +0 -0
  20. package/template/stages/01-brainstorm/outputs/ideas.md +0 -159
  21. package/template/stages/01-brainstorm/outputs/requirements_analysis.md +0 -222
  22. package/template/stages/01-brainstorm/prompts/CLAUDE.md +0 -0
  23. package/template/stages/01-brainstorm/templates/CLAUDE.md +0 -0
  24. package/template/stages/02-research/HANDOFF.md +0 -158
  25. package/template/stages/02-research/outputs/CLAUDE.md +0 -0
  26. package/template/stages/02-research/outputs/feasibility_report.md +0 -176
  27. package/template/stages/02-research/outputs/tech_research.md +0 -403
  28. package/template/stages/02-research/prompts/CLAUDE.md +0 -0
  29. package/template/stages/03-planning/HANDOFF.md +0 -168
  30. package/template/stages/03-planning/outputs/CLAUDE.md +0 -0
  31. package/template/stages/03-planning/outputs/architecture.md +0 -400
  32. package/template/stages/03-planning/outputs/implementation.yaml +0 -209
  33. package/template/stages/03-planning/outputs/project_plan.md +0 -204
  34. package/template/stages/03-planning/outputs/tech_stack.md +0 -176
  35. package/template/stages/03-planning/prompts/CLAUDE.md +0 -0
  36. package/template/stages/04-ui-ux/HANDOFF.md +0 -165
  37. package/template/stages/04-ui-ux/outputs/CLAUDE.md +0 -0
  38. package/template/stages/04-ui-ux/outputs/design_system.md +0 -449
  39. package/template/stages/04-ui-ux/outputs/user_flows.md +0 -321
  40. package/template/stages/04-ui-ux/outputs/wireframes.md +0 -241
  41. package/template/stages/04-ui-ux/prompts/CLAUDE.md +0 -0
  42. package/template/stages/05-task-management/HANDOFF.md +0 -187
  43. package/template/stages/05-task-management/outputs/CLAUDE.md +0 -0
  44. package/template/stages/05-task-management/outputs/milestones.md +0 -253
  45. package/template/stages/05-task-management/outputs/sprint_plan.md +0 -203
  46. package/template/stages/05-task-management/outputs/tasks.md +0 -402
  47. package/template/stages/05-task-management/prompts/CLAUDE.md +0 -0
  48. package/template/stages/05-task-management/templates/CLAUDE.md +0 -0
  49. package/template/stages/06-implementation/HANDOFF.md +0 -184
  50. package/template/stages/06-implementation/prompts/CLAUDE.md +0 -0
  51. package/template/stages/07-refactoring/HANDOFF.md +0 -82
  52. package/template/stages/07-refactoring/outputs/refactoring_report.md +0 -102
  53. package/template/stages/07-refactoring/prompts/CLAUDE.md +0 -0
  54. package/template/stages/08-qa/HANDOFF.md +0 -114
  55. package/template/stages/08-qa/outputs/qa_report.md +0 -138
  56. package/template/stages/08-qa/prompts/CLAUDE.md +0 -0
  57. package/template/stages/09-testing/HANDOFF.md +0 -118
  58. package/template/stages/09-testing/outputs/test_report.md +0 -146
  59. package/template/stages/09-testing/prompts/CLAUDE.md +0 -0
  60. package/template/stages/10-deployment/HANDOFF.md +0 -141
  61. package/template/stages/10-deployment/prompts/CLAUDE.md +0 -0
  62. package/template/stages/10-deployment/templates/CLAUDE.md +0 -0
  63. package/template/state/templates/CLAUDE.md +0 -0
@@ -1,403 +0,0 @@
1
- # 🔬 Snake Game - 기술 리서치
2
-
3
- > 생성일: 2026-01-21
4
- > 스테이지: 02-research
5
- > 프로젝트: snake-game
6
- > AI 도구: Claude + Exa MCP
7
-
8
- ---
9
-
10
- ## 📋 조사 항목 요약
11
-
12
- | 항목 | 권장 기술 | 근거 |
13
- |------|----------|------|
14
- | 렌더링 | Canvas API | 게임 성능, 60fps 유지 |
15
- | 게임 루프 | requestAnimationFrame | 브라우저 최적화, 탭 비활성화 처리 |
16
- | 상태 관리 | useReducer + useRef | 복잡한 게임 상태, 리렌더링 최소화 |
17
- | 모바일 조작 | Custom useSwipe Hook | 터치 이벤트 직접 처리 |
18
- | 하이스코어 | localStorage | 백엔드 불필요, 간단한 구현 |
19
-
20
- ---
21
-
22
- ## 1. Canvas 게임 루프 구현
23
-
24
- ### 1.1 requestAnimationFrame 기반 게임 루프
25
-
26
- **핵심 패턴** (Exa 조사 결과):
27
-
28
- ```typescript
29
- // useGameLoop.ts
30
- const useGameLoop = (callback: (deltaTime: number) => void) => {
31
- const requestRef = useRef<number>();
32
- const previousTimeRef = useRef<number>();
33
-
34
- const animate = (time: number) => {
35
- if (previousTimeRef.current !== undefined) {
36
- const deltaTime = time - previousTimeRef.current;
37
- callback(deltaTime);
38
- }
39
- previousTimeRef.current = time;
40
- requestRef.current = requestAnimationFrame(animate);
41
- };
42
-
43
- useEffect(() => {
44
- requestRef.current = requestAnimationFrame(animate);
45
- return () => {
46
- if (requestRef.current) {
47
- cancelAnimationFrame(requestRef.current);
48
- }
49
- };
50
- }, []);
51
- };
52
- ```
53
-
54
- ### 1.2 setInterval vs requestAnimationFrame 비교
55
-
56
- | 특성 | setInterval | requestAnimationFrame |
57
- |------|-------------|----------------------|
58
- | **정확도** | 낮음 (지연 발생) | 높음 (브라우저 최적화) |
59
- | **탭 비활성화** | 계속 실행 (리소스 낭비) | 자동 일시정지 |
60
- | **프레임레이트** | 고정 (부정확) | 디스플레이 동기화 (60fps) |
61
- | **성능** | 보통 | 최적화됨 |
62
-
63
- **결론**: requestAnimationFrame 사용 권장
64
-
65
- ### 1.3 하이브리드 게임 루프 (고정 타임스텝)
66
-
67
- ```typescript
68
- // 물리 시뮬레이션과 렌더링 분리
69
- const TICK_RATE = 1000 / 60; // 60 TPS
70
- let accumulator = 0;
71
-
72
- const gameLoop = (currentTime: number) => {
73
- const deltaTime = currentTime - lastTime;
74
- accumulator += Math.min(deltaTime, 100); // 프레임 스킵 제한
75
-
76
- while (accumulator >= TICK_RATE) {
77
- updateGameState(); // 고정 타임스텝 업데이트
78
- accumulator -= TICK_RATE;
79
- }
80
-
81
- render(); // 가변 렌더링
82
- requestAnimationFrame(gameLoop);
83
- };
84
- ```
85
-
86
- ---
87
-
88
- ## 2. React + Canvas 통합 패턴
89
-
90
- ### 2.1 useRef로 Canvas 접근
91
-
92
- ```typescript
93
- const GameBoard: React.FC = () => {
94
- const canvasRef = useRef<HTMLCanvasElement>(null);
95
-
96
- useEffect(() => {
97
- const canvas = canvasRef.current;
98
- if (!canvas) return;
99
-
100
- const ctx = canvas.getContext('2d');
101
- if (!ctx) return;
102
-
103
- // 게임 렌더링 로직
104
- const draw = () => {
105
- ctx.clearRect(0, 0, canvas.width, canvas.height);
106
- // ... 렌더링
107
- };
108
-
109
- draw();
110
- }, [gameState]);
111
-
112
- return <canvas ref={canvasRef} width={400} height={400} />;
113
- };
114
- ```
115
-
116
- ### 2.2 리렌더링 최소화 전략
117
-
118
- **문제**: React setState가 너무 자주 호출되면 성능 저하
119
-
120
- **해결책**:
121
- 1. **useRef로 게임 상태 관리** - 리렌더링 없이 상태 업데이트
122
- 2. **Canvas 직접 업데이트** - React DOM 업데이트 우회
123
- 3. **requestAnimationFrame 내에서 렌더링** - 효율적인 드로잉
124
-
125
- ```typescript
126
- // 게임 상태는 useRef로 관리
127
- const gameStateRef = useRef<GameState>({
128
- snake: [{x: 10, y: 10}],
129
- food: {x: 5, y: 5},
130
- direction: 'RIGHT',
131
- score: 0
132
- });
133
-
134
- // UI에 표시할 점수만 useState로 관리
135
- const [displayScore, setDisplayScore] = useState(0);
136
- ```
137
-
138
- ---
139
-
140
- ## 3. 모바일 터치 조작 구현
141
-
142
- ### 3.1 useSwipe 커스텀 훅
143
-
144
- **Exa 조사 결과 기반 구현**:
145
-
146
- ```typescript
147
- interface SwipeHandlers {
148
- left?: () => void;
149
- right?: () => void;
150
- up?: () => void;
151
- down?: () => void;
152
- }
153
-
154
- const useSwipe = (handlers: SwipeHandlers) => {
155
- const touchCoordsRef = useRef({
156
- touchStart: { x: 0, y: 0, time: Date.now() }
157
- });
158
-
159
- useEffect(() => {
160
- const handleTouchStart = (e: TouchEvent) => {
161
- touchCoordsRef.current.touchStart = {
162
- x: e.targetTouches[0].clientX,
163
- y: e.targetTouches[0].clientY,
164
- time: Date.now()
165
- };
166
- };
167
-
168
- const handleTouchEnd = (e: TouchEvent) => {
169
- const threshold = 50; // 최소 스와이프 거리
170
- const maxTime = 500; // 최대 스와이프 시간 (ms)
171
-
172
- const { touchStart } = touchCoordsRef.current;
173
- const touchEnd = {
174
- x: e.changedTouches[0].clientX,
175
- y: e.changedTouches[0].clientY
176
- };
177
-
178
- const elapsed = Date.now() - touchStart.time;
179
- if (elapsed > maxTime) return;
180
-
181
- const xDiff = touchStart.x - touchEnd.x;
182
- const yDiff = touchStart.y - touchEnd.y;
183
-
184
- if (Math.abs(xDiff) > Math.abs(yDiff)) {
185
- // 수평 스와이프
186
- if (Math.abs(xDiff) > threshold) {
187
- xDiff > 0 ? handlers.left?.() : handlers.right?.();
188
- }
189
- } else {
190
- // 수직 스와이프
191
- if (Math.abs(yDiff) > threshold) {
192
- yDiff > 0 ? handlers.up?.() : handlers.down?.();
193
- }
194
- }
195
- };
196
-
197
- window.addEventListener('touchstart', handleTouchStart, { passive: true });
198
- window.addEventListener('touchend', handleTouchEnd, { passive: true });
199
-
200
- return () => {
201
- window.removeEventListener('touchstart', handleTouchStart);
202
- window.removeEventListener('touchend', handleTouchEnd);
203
- };
204
- }, [handlers]);
205
- };
206
- ```
207
-
208
- ### 3.2 모바일 방향 버튼 (대안)
209
-
210
- ```typescript
211
- const MobileControls: React.FC<{ onDirection: (dir: Direction) => void }> = ({ onDirection }) => (
212
- <div className="mobile-controls">
213
- <button onTouchStart={() => onDirection('UP')}>↑</button>
214
- <div>
215
- <button onTouchStart={() => onDirection('LEFT')}>←</button>
216
- <button onTouchStart={() => onDirection('RIGHT')}>→</button>
217
- </div>
218
- <button onTouchStart={() => onDirection('DOWN')}>↓</button>
219
- </div>
220
- );
221
- ```
222
-
223
- ---
224
-
225
- ## 4. 충돌 감지 알고리즘
226
-
227
- ### 4.1 벽 충돌 (O(1))
228
-
229
- ```typescript
230
- const checkWallCollision = (head: Position, boardSize: number): boolean => {
231
- return head.x < 0 || head.x >= boardSize || head.y < 0 || head.y >= boardSize;
232
- };
233
- ```
234
-
235
- ### 4.2 자기 몸 충돌 (O(n))
236
-
237
- ```typescript
238
- const checkSelfCollision = (head: Position, body: Position[]): boolean => {
239
- // body[0]은 머리이므로 1부터 시작
240
- return body.slice(1).some(segment =>
241
- segment.x === head.x && segment.y === head.y
242
- );
243
- };
244
- ```
245
-
246
- ### 4.3 먹이 충돌 (O(1))
247
-
248
- ```typescript
249
- const checkFoodCollision = (head: Position, food: Position): boolean => {
250
- return head.x === food.x && head.y === food.y;
251
- };
252
- ```
253
-
254
- ---
255
-
256
- ## 5. 상태 관리 구조
257
-
258
- ### 5.1 게임 상태 타입 정의
259
-
260
- ```typescript
261
- // types/game.ts
262
- type Direction = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT';
263
- type GameStatus = 'idle' | 'playing' | 'paused' | 'gameover';
264
-
265
- interface Position {
266
- x: number;
267
- y: number;
268
- }
269
-
270
- interface GameState {
271
- snake: Position[];
272
- food: Position;
273
- direction: Direction;
274
- nextDirection: Direction; // 입력 버퍼
275
- score: number;
276
- level: number;
277
- status: GameStatus;
278
- }
279
-
280
- interface GameConfig {
281
- boardSize: number;
282
- cellSize: number;
283
- initialSpeed: number;
284
- speedIncrement: number;
285
- }
286
- ```
287
-
288
- ### 5.2 useReducer 기반 상태 관리
289
-
290
- ```typescript
291
- type GameAction =
292
- | { type: 'START_GAME' }
293
- | { type: 'PAUSE_GAME' }
294
- | { type: 'RESUME_GAME' }
295
- | { type: 'GAME_OVER' }
296
- | { type: 'SET_DIRECTION'; payload: Direction }
297
- | { type: 'MOVE_SNAKE' }
298
- | { type: 'EAT_FOOD' }
299
- | { type: 'RESET_GAME' };
300
-
301
- const gameReducer = (state: GameState, action: GameAction): GameState => {
302
- switch (action.type) {
303
- case 'START_GAME':
304
- return { ...state, status: 'playing' };
305
- case 'SET_DIRECTION':
306
- // 반대 방향 이동 방지
307
- if (!isOppositeDirection(state.direction, action.payload)) {
308
- return { ...state, nextDirection: action.payload };
309
- }
310
- return state;
311
- case 'MOVE_SNAKE':
312
- // 뱀 이동 로직
313
- return moveSnake(state);
314
- // ... 기타 액션
315
- }
316
- };
317
- ```
318
-
319
- ---
320
-
321
- ## 6. localStorage 하이스코어
322
-
323
- ### 6.1 저장 및 로드
324
-
325
- ```typescript
326
- const HIGH_SCORE_KEY = 'snake_game_high_score';
327
-
328
- const saveHighScore = (score: number): void => {
329
- const currentHigh = getHighScore();
330
- if (score > currentHigh) {
331
- localStorage.setItem(HIGH_SCORE_KEY, score.toString());
332
- }
333
- };
334
-
335
- const getHighScore = (): number => {
336
- const stored = localStorage.getItem(HIGH_SCORE_KEY);
337
- return stored ? parseInt(stored, 10) : 0;
338
- };
339
- ```
340
-
341
- ### 6.2 커스텀 훅
342
-
343
- ```typescript
344
- const useHighScore = () => {
345
- const [highScore, setHighScore] = useState(() => getHighScore());
346
-
347
- const updateHighScore = useCallback((score: number) => {
348
- if (score > highScore) {
349
- setHighScore(score);
350
- saveHighScore(score);
351
- }
352
- }, [highScore]);
353
-
354
- return { highScore, updateHighScore };
355
- };
356
- ```
357
-
358
- ---
359
-
360
- ## 7. 성능 최적화 팁
361
-
362
- ### 7.1 Canvas 최적화
363
-
364
- 1. **오프스크린 캔버스**: 복잡한 요소 미리 렌더링
365
- 2. **부분 리드로잉**: 변경된 부분만 다시 그리기
366
- 3. **이미지 스프라이트**: 여러 이미지 하나로 합치기
367
-
368
- ### 7.2 React 최적화
369
-
370
- 1. **useCallback/useMemo**: 불필요한 재생성 방지
371
- 2. **React.memo**: 순수 컴포넌트 메모이제이션
372
- 3. **게임 로직 분리**: Canvas 업데이트는 React 외부에서
373
-
374
- ---
375
-
376
- ## 📚 참고 자료
377
-
378
- ### GitHub 오픈소스 프로젝트
379
- - [gimnathperera/snake-loop](https://github.com/gimnathperera/snake-loop) - React + RTK Query
380
- - [markkaylor/react-snake-ts](https://github.com/markkaylor/react-snake-ts) - TypeScript 구현
381
- - [v662-coder/SnakeGame](https://github.com/v662-coder/SnakeGame) - Canvas 기반
382
-
383
- ### 기술 문서
384
- - [30-seconds-of-code: useRequestAnimationFrame](https://github.com/Chalarangelo/30-seconds-of-code)
385
- - [react-use: useRafLoop](https://github.com/streamich/react-use)
386
- - [beautiful-react-hooks: useRequestAnimationFrame](https://github.com/antonioru/beautiful-react-hooks)
387
-
388
- ### 튜토리얼
389
- - [Learn Advance React Hooks by Building Snake Game](https://javascript.plainenglish.io/learn-advance-react-hooks-by-building-snake-game)
390
- - [Build Your First Snake Game with TypeScript React](https://javascript.plainenglish.io/build-your-first-snake-game-with-typescript-react)
391
- - [Create Dead-Simple Canvas Animations in React](https://spin.atomicobject.com/animations-react)
392
-
393
- ---
394
-
395
- ## ✅ 리서치 완료 체크리스트
396
-
397
- - [x] Canvas 게임 루프 구현 방법 조사
398
- - [x] React + Canvas 통합 패턴 분석
399
- - [x] 모바일 터치 이벤트 처리 조사
400
- - [x] 충돌 감지 알고리즘 정리
401
- - [x] localStorage 하이스코어 구현 방법
402
- - [x] 성능 최적화 기법 조사
403
- - [x] 오픈소스 프로젝트 사례 수집
File without changes
@@ -1,168 +0,0 @@
1
- # HANDOFF: 03-planning → 04-ui-ux
2
-
3
- > 생성일: 2026-01-21
4
- > 프로젝트: snake-game
5
- > 현재 스테이지: 03-planning (완료)
6
- > 다음 스테이지: 04-ui-ux
7
-
8
- ---
9
-
10
- ## ✅ 완료된 작업
11
-
12
- - [x] 시스템 아키텍처 설계 (컴포넌트 구조, 데이터 흐름)
13
- - [x] 기술 스택 최종 결정 (React 18 + TypeScript 5 + Vite 5 + Canvas API)
14
- - [x] 커스텀 훅 설계 (useGameLoop, useKeyboard, useSwipe, useHighScore)
15
- - [x] 타입 정의 (Point, Direction, GameStatus, GameState, GameAction)
16
- - [x] 게임 설정 상수 정의 (GAME_CONFIG, COLORS, DIRECTION_VECTORS)
17
- - [x] 프로젝트 계획 수립 (마일스톤, 스프린트 계획)
18
- - [x] 구현 규칙 정의 (implementation.yaml)
19
-
20
- ---
21
-
22
- ## 📋 핵심 아키텍처 결정사항
23
-
24
- ### 1. 컴포넌트 구조 (하이브리드)
25
-
26
- ```
27
- App
28
- └── GameEngine (상태 관리, 이벤트 처리)
29
- ├── CanvasLayer (Canvas 렌더링)
30
- └── UIOverlay (React UI)
31
- ├── ScoreBoard
32
- ├── GameOverModal
33
- ├── StartScreen
34
- └── MobileControls
35
- ```
36
-
37
- ### 2. 데이터 흐름
38
-
39
- - **useReducer**: UI 리렌더링 필요한 상태 (score, status)
40
- - **useRef**: 빠른 업데이트 (direction buffer, animationFrameId)
41
- - **Canvas 직접 조작**: 게임 렌더링 (리렌더링 최소화)
42
-
43
- ### 3. 게임 루프
44
-
45
- ```typescript
46
- requestAnimationFrame 기반
47
- ├── deltaTime 계산
48
- ├── dispatch({ type: 'TICK' })
49
- └── Canvas.draw()
50
- ```
51
-
52
- ---
53
-
54
- ## 📁 생성된 산출물
55
-
56
- | 파일 | 설명 |
57
- |------|------|
58
- | `outputs/architecture.md` | 시스템 아키텍처 상세 설계 |
59
- | `outputs/tech_stack.md` | 기술 스택 결정 및 근거 |
60
- | `outputs/project_plan.md` | 프로젝트 계획 및 마일스톤 |
61
- | `outputs/implementation.yaml` | 구현 규칙 설정 |
62
- | `HANDOFF.md` | 이 문서 |
63
-
64
- ---
65
-
66
- ## 🎨 UI/UX 스테이지 입력 정보
67
-
68
- ### 화면 구성 요소
69
-
70
- | 화면 | 구성 요소 |
71
- |------|----------|
72
- | **시작 화면** | 타이틀, 시작 버튼, 최고 점수 |
73
- | **게임 화면** | Canvas(뱀/먹이/그리드), 점수판 |
74
- | **일시정지** | 오버레이, 재개/재시작 버튼 |
75
- | **게임 오버** | 모달, 최종 점수, 최고 점수, 재시작 버튼 |
76
- | **모바일** | 방향 버튼 (상하좌우) |
77
-
78
- ### 색상 시스템 (확정)
79
-
80
- ```yaml
81
- background: "#1a1a2e" # 다크 배경
82
- grid: "#16213e" # 그리드 라인
83
- snake: "#00ff88" # 뱀 몸통 (네온 그린)
84
- snake_head: "#00cc6a" # 뱀 머리 (진한 그린)
85
- food: "#ff6b6b" # 먹이 (레드)
86
- text: "#ffffff" # 텍스트 (화이트)
87
- ```
88
-
89
- ### 반응형 기준
90
-
91
- | 브레이크포인트 | 대상 |
92
- |--------------|------|
93
- | < 480px | 모바일 (터치 컨트롤 활성화) |
94
- | 480px - 768px | 태블릿 |
95
- | > 768px | 데스크톱 |
96
-
97
- ### 게임 보드 크기
98
-
99
- ```yaml
100
- boardSize: 20 # 20x20 그리드
101
- cellSize: 20px # 각 셀 20px
102
- totalSize: 400x400px # 게임 보드 총 크기
103
- ```
104
-
105
- ---
106
-
107
- ## 🔜 04-ui-ux 스테이지 작업
108
-
109
- ### 필수 산출물
110
-
111
- 1. **wireframes.md**
112
- - 시작 화면 와이어프레임
113
- - 게임 화면 와이어프레임 (데스크톱/모바일)
114
- - 게임 오버 모달 와이어프레임
115
-
116
- 2. **design-tokens.md**
117
- - 색상 토큰
118
- - 타이포그래피
119
- - 간격 시스템
120
- - 애니메이션 토큰
121
-
122
- 3. **HANDOFF.md**
123
-
124
- ### 고려 사항
125
-
126
- - 레트로 게임 느낌 (네온 색상, 픽셀 폰트 고려)
127
- - 미니멀한 UI (게임에 집중)
128
- - 모바일 터치 영역 충분히 확보 (44x44px 최소)
129
- - 접근성 (키보드 네비게이션, 색상 대비)
130
-
131
- ---
132
-
133
- ## ⚠️ 제약 사항
134
-
135
- 1. **순수 React + Canvas**: 외부 게임 엔진 미사용
136
- 2. **함수형 컴포넌트**: Class 컴포넌트 미사용
137
- 3. **CSS Modules**: 스타일 스코프 격리
138
- 4. **60fps 목표**: Canvas 렌더링 최적화
139
-
140
- ---
141
-
142
- ## 📊 AI 호출 기록
143
-
144
- | AI | 시간 | 도구 | 결과 | 상태 |
145
- |----|------|------|------|------|
146
- | Gemini | 12:25 | tmux wrapper | 아키텍처 설계 | ✅ |
147
- | ClaudeCode | 12:30 | - | architecture.md 작성 | ✅ |
148
- | ClaudeCode | 12:32 | - | tech_stack.md 작성 | ✅ |
149
- | ClaudeCode | 12:35 | - | project_plan.md 작성 | ✅ |
150
- | ClaudeCode | 12:36 | - | implementation.yaml 작성 | ✅ |
151
-
152
- ---
153
-
154
- ## 🚀 다음 단계
155
-
156
- ```bash
157
- # 다음 스테이지 실행
158
- /run-stage 04-ui-ux
159
-
160
- # 또는
161
- /ui-ux
162
- ```
163
-
164
- ---
165
-
166
- **생성자**: ClaudeCode + Gemini
167
- **검토자**: -
168
- **승인**: 대기
File without changes