"""HTML fragment rendering — pure f-strings + html.escape, vivamais-style. Every fragment the frontend swaps in is built here, so the routes in app.py stay thin and the look lives in one place next to styles.css. """ from __future__ import annotations import html import re from checks import Evaluation, PASS, WARN, FAIL from guide import TAG_GLYPHS, TAG_SHORT_NAMES from icons import ICON_PATHS _esc = html.escape STATUS_META = { PASS: ("check", "ok", "all good"), WARN: ("triangle-alert", "warn", "worth a look"), FAIL: ("x", "fix", "needs fixing"), } VERDICT_META = { "READY TO SUBMIT": ("ok", "star", "Everything checks out — pitch your tent and submit it!"), "ALMOST READY": ("warn", "compass", "So close! No rule failures, just a few things worth a look below."), "NOT READY": ("fix", "tent", "Not there yet — a few trail markers to hit first. You've got this."), } def icon(name: str, cls: str = "", size: int = 18, sw: float = 1.8) -> str: return ( f'' ) def stamp(glyph: str, tone: str = "rose", size: int = 44, spin: bool = False) -> str: """Mini replica of the field guide's StampBadge: disc + dashed ring + glyph.""" return ( f'' f'{icon(glyph, size=int(size * 0.4), sw=1.7)}' ) def _inline_md(text: str) -> str: """Escape, then bring back `code` spans and clickable links.""" out = _esc(text) out = re.sub(r"`([^`]+)`", r"\1", out) out = re.sub(r"“([^”]*)”", r"“\1”", out) out = re.sub( r"(https?://[^\s<]+)", r'\1', out, ) return out def render_space_options(names: list[str]) -> str: if not names: return '' opts = "".join(f'' for n in names) return f'{opts}' def render_error(message: str) -> str: return ( f'
' f'
{stamp("x", "rose", 40)}' f'

Hmm, that didn’t work

' f'

{_inline_md(message)}

' ) def render_results(ev: Evaluation, model_id: str, model_label: str) -> str: """Block 1 (rule check) + Block 2 shell (LLM review, filled by bridge.js).""" next_cue = ( '' ) return (_render_checks_block(ev) + render_review_shell(ev.space_id, model_id, model_label) + next_cue) def _render_checks_block(ev: Evaluation) -> str: tone, glyph, blurb = VERDICT_META[ev.verdict] rows = "".join(_check_row(c.rule, c.status, c.evidence) for c in ev.checks) chips = _tag_chips(ev) opps = _opportunities(ev) return ( f'
' f'step 1 · rule check' f'
{stamp(glyph, _tone_color(tone), 52)}' f'

{_esc(ev.verdict.title())}

' f'

{_esc(blurb)}

' f'

{_esc(ev.space_id)}

' f'' f"{chips}{opps}" f"
" ) def _tone_color(tone: str) -> str: return {"ok": "mint", "warn": "butter", "fix": "rose"}[tone] def _check_row(rule: str, status: str, evidence: str) -> str: glyph, tone, label = STATUS_META[status] return ( f'
  • ' f'{icon(glyph, size=15, sw=2.4)}' f'
    ' f'{_inline_md(rule)}' f'{label}
    ' f'

    {_inline_md(evidence)}

  • ' ) def _tag_chips(ev: Evaluation) -> str: managed = ev.facts.get("managed_tags") or {} tags = managed.get("track", []) + managed.get("sponsor", []) + managed.get("achievement", []) known = [t for t in tags if t in TAG_GLYPHS] if not known: return ( '
    tags on this space' '

    No tracks or badges tagged yet — the judges’ ' "tooling reads these from the README frontmatter.

    " ) chips = "".join( f'{stamp(TAG_GLYPHS[t], "rose" if t.startswith("track") else "lilac" if t.startswith("sponsor") else "mint", 34)}' f'{_esc(TAG_SHORT_NAMES[t])}' f'{_esc(t)}' for t in known ) return f'
    tags on this space
    {chips}
    ' def _opportunities(ev: Evaluation) -> str: opps = ev.facts.get("opportunities") or [] if not opps: return "" items = "".join( f'
  • {icon("sparkles", size=15, sw=1.9)}{_inline_md(o)}
  • ' for o in opps ) return ( f'
    within reach' f'

    Badges & prizes this Space might claim but hasn’t yet:

    ' f'
    ' ) def render_review_shell(space_id: str, model_id: str, model_label: str) -> str: return ( f'
    ' f'step 2 · friendly review' f'
    {stamp("notebook-pen", "lilac", 52, spin=True)}' f'

    {_esc(model_label)} is reading your Space…

    ' f'

    Grounded in the rule check above — this takes a little ' f"longer the first time a model wakes up.

    " f'
    ' f'
    ' f'

    {icon("triangle-alert", size=14, sw=2)} This is an automated ' f"+ AI evaluation — lovingly assembled, occasionally wrong. Double-check everything " f'against the official field guide before you submit, ' f"regardless of what it says.

    " ) def render_review_chunk(markdown_html: str, done: bool) -> str: """The streamed inner body of Block 2 (already-rendered markdown HTML).""" state = "done" if done else "streaming" return ( f'
    ' f"{markdown_html}
    " )