dental-soap / scripts /design_preview.py
DrZayed's picture
Design polish: ghost-document empty state, loading skeleton, provenance disclosure with print-safe evidence, Arabic heading typography
a73269f
Raw
History Blame Contribute Delete
3.76 kB
"""Faithful design preview: renders the REAL style.css + render.py output across all
UI states into a single static HTML file, so design iteration can be screenshot-verified
without launching Gradio or a GPU. Dev tool only β€” not part of the shipped app.
Usage: python scripts/design_preview.py -> writes design_preview_live.html
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
import render # noqa: E402
from schema import HandoffOutput # noqa: E402
CSS = (ROOT / "style.css").read_text(encoding="utf-8")
CACHE = ROOT / "data" / "example_cache"
def load(name: str) -> HandoffOutput:
return HandoffOutput.model_validate(json.loads((CACHE / f"{name}.json").read_text(encoding="utf-8")))
def sec(label: str) -> str:
return f'<div class="preview-sec">{label}</div>'
def build() -> str:
ahmed = load("ahmed")
arabic = load("arabic")
root_canal = load("root_canal")
# Pick a flagged case to exercise the fired safety panel / interrupt path.
flagged = next((c for c in (root_canal, ahmed, arabic) if c.red_flags), root_canal)
blocks: list[str] = [
render.header_html(),
render.footer_html(),
sec("Step rail"),
render.rail_html(),
sec("Agent dashboard β€” initial (Ready)"),
render.initial_agent_dashboard_html(),
sec("Agent dashboard β€” live auditable run"),
render.render_agent_dashboard(
"Cached", "Complete", f"{len(flagged.red_flags)} flags found", "Passed",
route_note="Cached case Β· model drafted narrative Β· sentinel ran between turns",
),
sec("Safety panel β€” clear"),
render.initial_safety_html(),
sec("Safety panel β€” fired (rule-based)"),
render.render_safety_html(flagged),
sec("Handoff card β€” empty / ghost state"),
render.placeholder_handoff_html(),
sec("Handoff card β€” loading skeleton"),
render.skeleton_handoff_html(),
sec("Handoff card β€” English (Ahmed, model-authored narrative)"),
render.render_handoff_html(ahmed, "English", model_authored=True),
sec("Handoff card β€” Bilingual (English + Arabic)"),
render.render_handoff_html(arabic, "Bilingual"),
]
# Show the hard-interrupt card if any cached case triggers it.
interrupt_case = next((c for c in (root_canal, ahmed, arabic) if render.is_hard_interrupt(c)), None)
if interrupt_case is not None:
blocks += [sec("Hard interrupt card"), render._interrupt_card(interrupt_case, "Bilingual")]
fonts = (
'<link rel="preconnect" href="https://fonts.googleapis.com">'
'<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>'
'<link href="https://fonts.googleapis.com/css2?'
"family=Inter:wght@400;500;600;700&family=Inter+Tight:wght@500;600;700&"
"family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans+Arabic:wght@400;500;600&"
'display=swap" rel="stylesheet">'
)
shell = (
"body{max-width:1180px;margin:0 auto;padding:28px 20px;background:#F5F4F0;}"
".preview-sec{margin:34px 0 12px;font-family:'IBM Plex Mono',monospace;font-size:11px;"
"letter-spacing:.14em;text-transform:uppercase;color:#8C887E;border-top:1px solid #E2DFD6;padding-top:14px;}"
)
return (
f"<!doctype html><html lang='en'><head><meta charset='utf-8'>{fonts}"
f"<style>{CSS}</style><style>{shell}</style></head><body>"
f"{''.join(blocks)}</body></html>"
)
if __name__ == "__main__":
out = ROOT / "design_preview_live.html"
out.write_text(build(), encoding="utf-8")
print(f"wrote {out}")