M2: 오셀로 추가, 게임 공통 E2E, 접근성 검사(axe) 통과

- 오셀로: 8방향 뒤집기, 자동 패스, 종료·점수(빈칸 승자 몫 옵션), 한 수/피셔 시계·자동 착수,
  무르기·무승부·기권, 놓을 곳 점·뒤집힐 돌 미리 보기·뒤집기 애니메이션 (테스트 31개)
- 카탈로그에 오셀로·체스·장기·바둑 추가(엔진이 등록된 게임만 화면에 나옴)
- e2e/games.e2e.ts: PC 방장 + 휴대폰 친구, 게임 소개→방 만들기→링크 입장→시작→차례대로 첫 수
- e2e/a11y.e2e.ts: 홈·게임 소개·대기실 × PC/휴대폰 × 밝게/어둡게, axe 위반 0건
  (h1, 랜드마크, 제목 순서 정리)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-10-04 05:19:05 +09:00
parent aa7f6bffef
commit c5c30d4ada
16 changed files with 1781 additions and 11 deletions

View File

@@ -30,7 +30,7 @@ export function ChatPanel({ room, me, title = true }: { room: RoomView; me: Publ
}, []);
return (
<section className="chat-panel" aria-label="채팅">
{title && <h3>채팅</h3>}
{title && <h2 style={{ fontSize: '1.1rem' }}>채팅</h2>}
<div ref={listRef} className="chat-list" aria-live="polite">
{chat.length === 0 && <p className="muted small">아직 메시지가 없어요. Enter를 누르면 바로 입력할 수 있어요.</p>}
{chat

View File

@@ -150,7 +150,7 @@ export function CodeLabel({ code }: { code: string }) {
export function TopBar({ title, onBack, right }: { title: ReactNode; onBack?: () => void; right?: ReactNode }) {
return (
<header className="topbar">
<nav className="topbar" aria-label="페이지 메뉴">
{onBack && (
<button className="icon-btn" onClick={onBack} aria-label="뒤로">
←<span className="lbl">뒤로</span>
@@ -158,6 +158,6 @@ export function TopBar({ title, onBack, right }: { title: ReactNode; onBack?: ()
)}
<div className="topbar-title">{title}</div>
{right}
</header>
</nav>
);
}