Add British literature puzzle and a two-tab shell

index.html 은 왼쪽 탭(러시아 문학 / 영국 문학)과 게임을 띄우는 iframe 만 갖는
셸로 바꾸고, 게임 본체는 편별 페이지로 분리했다. 탭 상태는 해시(#russian,
#british)에 남으므로 링크로 바로 들어갈 수 있고, 같은 탭을 다시 눌러도
프레임을 다시 읽어들이지 않아 풀던 내용이 유지된다.

두 편이 쓰는 화면 양식과 게임 엔진은 site/assets/ 로 빼내 한 벌만 둔다.
엔진에는 셸 안에서 열렸을 때 여백을 줄이는 표시와, 첫 렌더에서 단서 목록을
스크롤하지 않게 하는 처리(프레임 안에서 머리말이 밀려 올라감)를 더했다.

영국 문학 편은 9x9 39칸 12항목. 가로/세로로 길이 2 이상 이어지는 모든 구간이
단서가 붙은 항목과 일대일로 대응하는지 확인했다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 16:32:30 +09:00
co-authored by Claude Opus 5
parent 65588c339c
commit 96262fc690
6 changed files with 825 additions and 518 deletions
+74
View File
@@ -0,0 +1,74 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>가로세로 낱말풀이 · 영국 문학</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Black+Han+Sans&family=Gothic+A1:wght@300;500;700;900&family=Nanum+Myeongjo:wght@400;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/crossword.css">
</head>
<body>
<div class="wrap">
<header class="head">
<div class="eyebrow">British literature · 9 × 9</div>
<h1>영국 문학<em>가로세로 낱말풀이</em></h1>
<div class="meta">
<div><b id="timer">00:00</b><span>경과 시간</span></div>
<div><b id="progress">0/39</b><span>채운 칸</span></div>
</div>
</header>
<main class="stage">
<section>
<div class="cluebar">
<span class="cb-num" id="cbNum">–</span>
<span class="cb-dir" id="cbDir">가로</span>
<span class="cb-text" id="cbText">칸을 눌러 시작하세요.</span>
</div>
<div class="board-frame">
<div class="board" id="board" role="grid" aria-label="가로세로 낱말풀이 격자"></div>
<input id="ime" type="text" lang="ko" inputmode="text"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
aria-label="글자 입력">
</div>
<div class="tools">
<button type="button" data-act="flip">가로 ↔ 세로</button>
<button type="button" data-act="check">검사</button>
<button type="button" data-act="hint">이 칸 힌트</button>
<button type="button" data-act="reveal">정답 보기</button>
<button type="button" data-act="clear">전부 지우기</button>
</div>
<p class="tip">
같은 칸을 한 번 더 누르면 가로 ↔ 세로가 바뀌고, 오른쪽 단서도 그에 맞춰 바뀝니다.<br>
<kbd>화살표</kbd> 이동 · <kbd>Space</kbd> 방향 전환 · <kbd>Tab</kbd> 다음 단어 · <kbd>Backspace</kbd> 지우고 뒤로
</p>
</section>
<aside>
<section class="cluegroup">
<h2>가로 열쇠</h2>
<ol id="listA"></ol>
</section>
<section class="cluegroup">
<h2>세로 열쇠</h2>
<ol id="listD"></ol>
</section>
</aside>
</main>
</div>
<div class="done" id="done" hidden>
<span id="doneMsg">전부 맞혔습니다.</span>
</div>
<script>
const PUZZLE = {"size": 9, "grid": [[null, "크", null, "테", "스", null, null, null, null], [null, "리", null, null, "위", "대", "한", "유", "산"], ["히", "스", "클", "리", "프", null, "여", null, null], [null, "마", null, null, "트", null, "름", null, null], ["오", "스", "틴", null, null, null, "밤", null, "제"], [null, "캐", null, "베", "니", "스", "의", "상", "인"], [null, "럴", null, "오", null, null, "꿈", null, "에"], [null, null, null, "울", null, null, null, "모", "어"], [null, null, "울", "프", null, null, null, null, null]], "nums": [[0, 1, 0, 2, 3, 0, 0, 0, 0], [0, 0, 0, 0, 4, 0, 5, 0, 0], [6, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [7, 0, 0, 0, 0, 0, 0, 0, 8], [0, 0, 0, 9, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 10, 0], [0, 0, 11, 0, 0, 0, 0, 0, 0]], "entries": [{"num": 1, "dir": "D", "r": 0, "c": 1, "answer": "크리스마스캐럴", "clue": "스크루지가 세 유령을 만나는 디킨스의 이야기", "kind": "작품"}, {"num": 2, "dir": "A", "r": 0, "c": 3, "answer": "테스", "clue": "하디가 그린, 순결한 여인의 비극", "kind": "작품"}, {"num": 3, "dir": "D", "r": 0, "c": 4, "answer": "스위프트", "clue": "《걸리버 여행기》로 인간을 풍자한 더블린 태생의 작가", "kind": "작가"}, {"num": 4, "dir": "A", "r": 1, "c": 4, "answer": "위대한유산", "clue": "핍이 정체 모를 후원자의 돈으로 신사가 되는 장편", "kind": "작품"}, {"num": 5, "dir": "D", "r": 1, "c": 6, "answer": "한여름밤의꿈", "clue": "요정 퍽의 장난이 얽히는 숲의 희극", "kind": "작품"}, {"num": 6, "dir": "A", "r": 2, "c": 0, "answer": "히스클리프", "clue": "《폭풍의 언덕》에서 캐서린을 향한 사랑을 복수로 갚은 남자", "kind": "인물"}, {"num": 7, "dir": "A", "r": 4, "c": 0, "answer": "오스틴", "clue": "시골 젠트리의 결혼 풍속을 그린 《오만과 편견》의 작가", "kind": "작가"}, {"num": 8, "dir": "D", "r": 4, "c": 8, "answer": "제인에어", "clue": "손필드 저택의 가정교사가 화자인 샬럿 브론테의 장편", "kind": "작품"}, {"num": 9, "dir": "A", "r": 5, "c": 3, "answer": "베니스의상인", "clue": "샤일록의 살 한 파운드가 걸린 재판", "kind": "작품"}, {"num": 9, "dir": "D", "r": 5, "c": 3, "answer": "베오울프", "clue": "괴물 그렌델과 싸우는 고대 영시의 영웅 서사시", "kind": "작품"}, {"num": 10, "dir": "A", "r": 7, "c": 7, "answer": "모어", "clue": "《유토피아》를 지은 헨리 8세 시대의 인문주의자", "kind": "작가"}, {"num": 11, "dir": "A", "r": 8, "c": 2, "answer": "울프", "clue": "《등대로》 《댈러웨이 부인》을 쓴 블룸즈버리의 소설가", "kind": "작가"}]};
</script>
<script src="assets/crossword.js"></script>
</body>
</html>