Build a mobile-first, accessibility-optimized viewer page for non-technical audiences to watch agent-based simulations without seeing admin details, secrets, or technical controls
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Build a mobile-first, accessibility-optimized viewer page for non-technical audiences to watch agent-based simulations without seeing admin details, secrets, or technical controls
source
auto-skill
extracted_at
2026-05-30T16:19:44.775Z
Family Viewer Page
When building agent-based simulations that non-technical family members want to watch, create a dedicated viewer page that hides all admin details, provider settings, API keys, and technical controls while keeping the story readable and engaging.
Core Principles
Mobile-first — optimize for phone screens first, then desktop
Large text — minimum 22px body, 32px headings on mobile
Simple language — replace technical terms with plain English
No secrets — never expose API keys, provider config, model names, or raw JSON
Source boundary visible — always show that generated events are not scripture/source truth
"""Serve the family viewer page — no admin details, no secrets."""
"frontend"
"mom.html"
return
@app.post("/api/mom/tick")
def
mom_tick
"""Advance one tick for the family viewer. Does NOT change provider mode."""
return
"status"
"ok"
"event"
@app.post("/api/mom/reset")
def
mom_reset
"""Reset the simulation for the family viewer."""
return
Page Structure
Header: Title + subtitle
Source Notice: "This is a Bible-inspired simulation. It is not scripture."
Visual Scene: Garden sky, ground, Adam/Eve markers, boundary tree, peace indicator, animals
Chapter Card: Title, plain-language summary, Bible source
What This Means: One-sentence explanation of current chapter
Read Aloud Text: Clean paragraph for reading out loud
Tick Counter: "Moment N — Day N"
Extra Large Text Toggle: Persisted in localStorage
Controls: Next Moment (primary), Start Watching/Pause, Auto Play/Pause, Reset
Garden Summary: Day, Time, Garden state, Weather, Harmony, Boundary
Adam Card: What Adam is thinking, What Adam does
Eve Card: What Eve is thinking, What Eve does
What Changed: Plain-language description of world changes
Recent Moments: Latest 3 events with "Show more" button
Footer: Source boundary reminder
Visual Scene
Add a CSS-based visual scene above the chapter card that shows the garden state:
<divclass="visual-scene"><divclass="scene-sky"><!-- Changes color with time of day --><spanclass="time-icon">🌅</span><!-- 🌅 ☀️ 🌇 🌙 --></div><divclass="scene-ground"><!-- Changes color with garden condition --><divclass="scene-marker"id="adam-marker"><spanclass="icon">👤</span><spanclass="label">Adam</span><spanclass="action-text">—</span></div><divclass="scene-marker"id="eve-marker"><spanclass="icon">👤</span><spanclass="label">Eve</span><spanclass="action-text">—</span></div></div><divclass="boundary-tree calm"><!-- Glows when boundary respected --><spanclass="icon">🌳</span><spanclass="label">Boundary</span></div><divclass="peace-indicator">✨</div><!-- ✨ 🕊️ 🌤️ ⛈️ based on harmony --><divclass="scene-animals">🦁 🐑 🦅</div><divclass="scene-chapter-label">The Garden Is Good</div></div>
Visual State Mapping
World State
Visual
Time: morning
🌅 + warm sky (#fff3e0)
Time: midday
☀️ + blue sky (#e3f2fd)
Time: evening
🌇 + pink sky (#fce4ec)
Time: night
🌙 + dark sky (#1a237e)
Garden: pristine
🌿 + lush green
Garden: tended
🌱 + cared-for green
Garden: wild
🌾 + yellow-green
Garden: damaged
🍂 + brown
Harmony ≥ 0.9
✨ Perfect peace
Harmony ≥ 0.7
🕊️ Peaceful
Harmony ≥ 0.4
🌤️ Uneasy
Harmony < 0.4
⛈️ Troubled
Boundary respected
🌳 calm glow animation
Boundary violated
🌳 no glow
Safe Visual Data Endpoint
Create /api/mom/visual-state that returns ONLY sanitized visual data:
"Notice: This is a Bible-inspired simulation. It is not scripture."
"Reset Simulation"
"Reset Story"
Clean Agent Text
Remove mock/provider prefixes from display:
functioncleanText(text) {
if (!text) return'—';
text = text.replace(/^\[mock:[^\]]*\]\s*/i, '');
text = text.replace(/^\[nim-dry-run:[^\]]*\]\s*/i, '');
text = text.replace(/^\[nvidia_nim_placeholder:[^\]]*\]\s*/i, '');
text = text.replace(/^\[live-[^:]*:[^\]]*\]\s*/i, '');
text = text.replace(/^Processing:.*?\.\.\.\s*/i, '');
return text.trim() || '—';
}