"""Generates standalone HTML pages from the real renderers + styles.css so the horror UI can be screenshotted headlessly (Edge --headless --screenshot). Dev tool only — not part of the app.""" import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT)) from render import render_entity, render_treasure # noqa: E402 OUT = ROOT / "tools" / "_visual" OUT.mkdir(exist_ok=True) CSS = (ROOT / "styles.css").read_text(encoding="utf-8") def page(name: str, body_html: str, width: int = 420) -> None: doc = ( "
" f"" f"empty page — judge the background
", width=1200) for a in (20, 40, 55, 65, 90): page(f"entity_{a}", render_entity(a)) page("flash", render_entity(40, "flash", seq=1)) page("ghost", render_entity(65, "flash_strong", seq=0), width=420) page("treasure", render_treasure([f"memory number {i}" for i in range(14)], claimed={"memory number 3"}), width=300) # frozen mid-animation states — headless screenshots can't advance CSS # animations, so force the peak frame to judge the look _FREEZE_FLASH = "" _FREEZE_GHOST = "" page("flash_frozen", _FREEZE_FLASH + render_entity(40, "flash", seq=1)) page("ghost_frozen", _FREEZE_GHOST + render_entity(65, "flash_strong", seq=0), width=420) # critical check: does the flash survive prefers-reduced-motion? Wrap the page so # the media query is forced ON; if the terror face still shows, the fix holds. _FORCE_RM = ( "" "" ) page("flash_reduced_motion", "prefers-reduced-motion forced — flash must still be visible
" + _FORCE_RM + render_entity(40, "flash", seq=1)) # gothic frames: portrait arch + treasure + mock bubble/button _goth = ( "