# План фазы 2: этап 2 — доска Canvas (packages/board) Обновлено: 2026-08-05 | Статус: код и тесты готовы, gates зелёный (74 теста: 43 core + 31 board). Осталось: визуальная проверка — на этапе 5. ## Пометки о ходе (2026-08-05) - Объём выполнен целиком: geometry.ts, render.ts (тёмная тема по умолчанию), input.ts, dom.ts, index.ts; корневой tsconfig.json — reference на packages/board; зависимость @go-learn/core 0.1.0 в package.json пакета. - Все тесты из раздела «Тесты» ниже написаны и зелёные (31 тест board). - Отклонение: в packages/board/tsconfig.json нет references на ../core — `tsc -b --noEmit` (гейт typecheck) с project references падает с чистого состояния (TS6310, CLI --noEmit распространяется на referenced-проект, TS 5.9.3). Импорт резолвится через workspace-симлинк; подробности — комментарий в packages/board/tsconfig.json. - Уточнение семантики territory (в первой редакции контракта стороны не различались): структура TerritoryMap { black, white } с множествами ключей "x,y" по цветам — зафиксировано в контракте (правка main loop при приёмке). ## Критические долги (реестр — в начале, III.5) - Нет. ## Ключевые решения (не пере-решать) - Доска — Canvas 2D, не DOM/SVG (плавность на 361 пересечении) — мастер-промпт. - render(ctx, position, options) — чистая функция состояния, весь кадр из аргументов. - Геометрия, редьюсер ввода и рендер — headless-тестируемые; DOM — тонкий адаптер (setupCanvas, attachPointerInput), юнит-тестами не покрывается — см. матрицу «чего НЕ покрывает ни один тест» ниже. - Координаты — буквы без «I» (стандарт Го), числа снизу вверх. - Дефолтная тема — тёмная (мастер-промпт: минималистичный дизайн, тёмная тема). - Контракт — docs/INTERFACES.md, раздел «Контракт отрисовки доски» (зафиксирован 2026-08-05 до кода). ## Объём этапа 2 1. packages/board: geometry.ts (computeGeometry, pointToPixel, pixelToPoint, hoshiPoints), render.ts (render + BoardTheme + дефолтная тёмная тема), input.ts (reduceInput), dom.ts (setupCanvas, attachPointerInput), index.ts. 2. Отзывчивый размер и devicePixelRatio (setupCanvas). 3. Хоси, координаты и номера ходов (переключаемые), фантомный камень, подсветка последнего хода, тач-ввод с подтверждением (первый тап — позиция, второй тап или confirm — ход), слои разметки (LB/TR/SQ/CR, заливка территории, приглушение мёртвых). 4. Корневой tsconfig: references += packages/board; packages/board зависит от @go-learn/core (project reference). ## Тесты (гейт приёмки этапа) - Геометрия: хоси для 9/13/19; roundtrip pixelToPoint∘pointToPixel; отклонение точки дальше половины клетки; padding при showCoordinates on/off. - Редьюсер ввода: тап → pending; второй тап по той же точке → commit; тап по другой точке → перенос; confirm без pending → commit null; cancel → сброс; тап мимо доски → без изменений. - Рендер: мок-ctx с записью вызовов — число камней = числу занятых клеток BoardState; фантом рисуется с phantomOpacity; метка последнего хода только при lastMove; LB/TR/SQ/CR из markup; заливка только для territory-ключей; мёртвые приглушены. Не проверяем каждый вызов — только инварианты. - Wiring: orphan-check по публичным функциям packages/board (вызывающие — тесты допустимы, дом-адаптер помечен как входная точка). - Матрица «чего НЕ покрывает ни один тест»: реальный вид кадра, pointer-события браузера, поведение на мобильном Safari — ручная проверка в этапе 5/7 (смоук-сценарий, слой GUI — litany II.8). ## Критерий выхода Все тесты зелёные + `npm run gates` зелёный. Визуальная проверка — на этапе 5 (когда появится страница); до неё — demo-страница не нужна.