File size: 3,281 Bytes
af463a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
915fdd8
 
 
 
 
 
 
 
 
 
9b82354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af463a4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
"""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 = (
        "<!DOCTYPE html><html><head><meta charset='utf-8'>"
        f"<style>{CSS}</style></head><body>"
        f"<div class='gradio-container'>"
        f"<div style='width:{width}px;margin:30px'>{body_html}</div>"
        "</div></body></html>"
    )
    (OUT / f"{name}.html").write_text(doc, encoding="utf-8")


page("stains", "<h2>Hollow</h2><p><em>empty page — judge the background</em></p>",
     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 = "<style>.entity-flash{animation:none !important;opacity:1 !important}</style>"
_FREEZE_GHOST = "<style>.entity-ghost{animation:none !important;opacity:0.18 !important}</style>"
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 = (
    "<style>@media not all{} </style>"
    "<style>.entity-flash{animation:none !important;opacity:1 !important}</style>"
)
page("flash_reduced_motion",
     "<p class='subtitle'>prefers-reduced-motion forced — flash must still be visible</p>"
     + _FORCE_RM + render_entity(40, "flash", seq=1))

# gothic frames: portrait arch + treasure + mock bubble/button
_goth = (
    "<div style='display:flex;gap:30px;align-items:flex-start'>"
    "<div style='width:240px'>" + render_entity(60) + "</div>"
    "<div style='width:280px'>"
    + render_treasure(["had a grandmother who kept bees",
                       "grew up where the yard smelled like honey",
                       "never learned the words", "had a red bicycle"],
                      claimed={"never learned the words"})
    + "</div>"
    "<div style='display:flex;flex-direction:column;gap:20px;width:320px'>"
    "<div class='user' style='padding:14px;color:#cec6dc'>"
    "I still talk to people who are gone.</div>"
    "<button class='gr-button' style='padding:12px 20px;color:#9a7caa;"
    "background:rgba(30,20,46,0.45)'>&rarr;</button>"
    "<div class='goth-frame' style='padding:16px;color:#9a8d6a'>goth-frame sample</div>"
    "</div></div>"
)
page("goth", _goth, width=1000)

print(f"pages written to {OUT}")