Classic era ultimul motor bespoke: CFG/norm/beep/confetti/star-logic/
finalWord/payload campanie inline. Acum injecteaza libJS(cfg) si foloseste
checkAnswer/starsFor/finalWord/choiceOpts/campaignDone/roomReady ca celelalte
4 motoare. UI-ul bespoke (card sStart/sGame/sFinal) ramane intentionat -
fortarea modalului/overlay-ului SNIP ar fi regresie vizuala pe demo-ul implicit
(aceeasi decizie ca terminalul cu finale CRT).
- payload parent.nextRoom traieste o singura data in libJS.campaignDone()
- net -70 linii duplicate
- exemplu-clasic.html regenerat; celelalte demo-uri byte-identice
- smoke 27/27 (regresie clasic standalone + campanie E2E cu clasic ca odaie)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Audit faptic (masurat) pe 5 motoare + campanie. Deja OK din restyle S3:
tap targets (arcade 56x52, classic 44/48, chat 44), contrast (terminal .dim
9.4:1, classic hint 6:1), focus/keyboard (butoane reale, navigare cu sageti).
Reparat:
- reduced-motion (lacune): .confetti display:none in classic + SNIP.baseCss +
campanie; flipin final in SNIP.finalCss (#fOverlay .fword span) + campanie
(#fin-word span); dt-blink in campanie. (pop/flip/shake/bin/tile-pop/tp/
door-glow/crt-flicker erau deja acoperite.) flipin/pop au 'backwards' fill ->
animation:none le revine la starea vizibila, nu raman ascunse.
- tap: overworld dpad 42x42 -> 44x44 (singura tinta sub prag).
- aria: #dots role=group+label; fiecare dot role=img cu aria-label ce reflecta
starea (neinceputa/in curs/rezolvata) via setDot; dpad arcade+overworld cu
aria-label (Sus/Jos/Stanga/Dreapta/Pune bomba); spacere .sp aria-hidden.
Test nou smoke #9c (emulateMedia reducedMotion -> confetti display:none;
tap>=44px pe dpad; aria dinamic pe dots). 26/26. Demo-uri regenerate (terminal
neatins - nu foloseste SNIP base/final).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adauga al 6-lea stil de joc: campanie multi-stil care leaga puzzle-urile
in camere de stiluri diferite (clasic/terminal/arcade/chat/point in rotatie),
conectate prin coridoare cu usa, litera si stele.
Contract de montare (verificat la gate T1):
- gameCampaign: un <iframe srcdoc> per camera; camerele cheama parent.*
pe un nivel (merge si pe file://); template per stil cu sentinel __CFG__
injectat prin replace-functie (D1) + json.replace(/</g,'<') (D6)
- roomReady/roomError + timeout 4s -> skip cu 0 stele + cod eroare;
idx detinut de parinte, accepta nextRoom doar de la contentWindow activ (D5)
- parent.beep in mod campanie (un singur AudioContext, D2)
- resume prin safeStore try/catch (D3) + cheie djb2 peste CFG embedat (D11)
Builder:
- selector de stil per puzzle ("Auto (stil)") + optiunea Campanie multi-stil
- normalizePuzzle() la load + import (sursa unica pt forma puzzle, D8)
- blocare export+preview la 0 puzzle-uri; persist() guarded (D12)
- letter normalizat [A-Za-z0-9] + esc la SVG point (D13)
Design (DESIGN.md): tokens --c-*, intro poster, coridor "usa ca erou",
chrome unica sursa de progres, 5 usi CSS/SVG (normal/stuck/crescendo),
mod camera per motor, buget vertical mobil, baseline a11y.
Tooling: tests/smoke.mjs (Playwright, zero-dependente prin npx), TODOS.md,
sectiune ## Testing in CLAUDE.md. Demo-uri regenerate + exemplu-campanie.html.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Builder single-file HTML cu editor + preview live jucabil si export
de jocuri standalone. Stiluri: clasic (quiz), terminal retro, arcade
pixel, story chat, point-and-click. Fara backend, fara build.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>