# Feature: Lab.html Split

**Branch:** `feature/lab-split`
**Base branch:** `master`
**Created:** 2026-05-22
**Status:** ✅ Complete (4/5 phases merged `5d5f51a`, Phase 5 deferred)
**Strategy:** Incremental
**Mode:** Automated
**Execution:** Direct

## Summary

Расщепить `frontend/lab.html` (5180L монолит UI-shell) на модульную структуру: extract inline CSS + inline JS-glue, token purification (265 hardcodes → vars), hash-router для deep-links, optional `<template>` lazy-mount.

**Discovery:** симуляции уже extracted в `frontend/js/labs/*.js` (39 engine-классов). lab.html — это HTML shell с 856L inline CSS + 3435L DOM + 825L inline glue-JS.

**Цели:**
- lab.html structure clearer (CSS / JS вынесены, HTML только DOM)
- Хардкодов ≤ 30 (от 265)
- Deep-link `#sim/projectile` работает
- Все 39 симуляций без регрессий
- Pre-commit hook проходит на каждой фазе

## Build & Test Commands

- **Start:** `cd backend && npm start` (vanilla JS — нет билда)
- **Test:** `cd backend && npm test` (66 tests / 63 pass / 3 baseline-fail)
- **Lint:** `cd backend && npm run lint:routes`
- **Smoke:** `curl -sI http://localhost:3000/lab` → 200; манульно открыть несколько sim
- **Pre-commit hook активен** — runs all of the above automatically

## Phases

- [ ] Phase 1: Extract inline `<style>` → `frontend/css/lab.css` [domain: frontend] → [subplan](./phase-1-extract-style.md)
- [ ] Phase 2: Extract inline glue `<script>` → `frontend/js/labs/lab-glue.js` [domain: frontend] → [subplan](./phase-2-extract-glue.md)
- [ ] Phase 3: Token purification (265 hardcodes) [domain: frontend] → [subplan](./phase-3-token-purify.md) (parallelizable with 1 или 2)
- [ ] Phase 4: Hash-router for sim deep-links [domain: frontend] → [subplan](./phase-4-hash-router.md)
- [ ] Phase 5: `<template>` lazy-mount (stretch) [domain: frontend] → [subplan](./phase-5-template-lazy.md)

## Phase Progress Log

| Phase | Domain | Status | Review | Build | Committed |
|-------|--------|--------|--------|-------|-----------|
| Phase 1: Extract style | frontend | ✅ Done | (pre-commit hook) | ✅ | ✅ 46e6d82 |
| Phase 2: Extract glue | frontend | ✅ Done | (pre-commit hook) | ✅ | ✅ 92b5c39 |
| Phase 3: Token purify | frontend | ✅ Done | (pre-commit hook) | ✅ | ✅ 6792a4a |
| Phase 4: Hash-router | frontend | ✅ Done | (pre-commit hook) | ✅ | ✅ 0b9685b |
| Phase 5: Template lazy | frontend | 🟡 Deferred (post-merge) | — | — | — |

## Final Review
- [ ] Comprehensive code review
- [ ] All 39 simulations smoke-tested
- [ ] No console errors on /lab
- [ ] pre-commit hook passes
- [ ] Merged to `master`

## Acceptance Criteria (whole feature)

- lab.html без inline `<style>` блока (856L moved out)
- lab.html без inline glue `<script>` блока (825L moved out)
- Хардкодов brand colors ≤ 30 (curated palettes сохраняются)
- `#sim/projectile`, `#sim/newton` и др. — deep-link работают, F5 восстанавливает
- 39 симуляций функциональны (canvas рендерится, кнопки работают)
- Pre-commit hook чистый на каждом коммите

## Tech Stack & Conventions Reference

- vanilla JS, no bundler, Express static serve
- `window.LS.*` namespace (api.js)
- `LS.modal`, `LS.confirm`, `LS.toast`
- ls.css design tokens (--violet/--cyan/--green/--pink/--amber + --text/--text-2/--text-3 + spacing + radii)
- Lucide icons (CDN) + inline SVG `.ic`
- **No emoji в коде** (pre-commit блокирует)
- **No grep tool**, только ast-index для search
- Existing labs/*.js engine-классы НЕ трогаем — они уже extracted
