--- name: course-viewer description: "Show an enrolled course and its lessons. Use lesson-design to author or repair the current lesson before delivering teaching; render published content and serve the local page with saved exercises." --- # Course viewer Render the enrolled course and its published lessons. The HTML page and its neighboring `assets/` directory can be read locally; the course server saves exercises to JSON and reveals answers after submission. Math uses KaTeX. Pale peach editorial page: top bar with GNOS + tabs, hero with giant title + field metadata, curriculum list + topic details. Use this skill when the learner asks to see the course or answers yes after the current lesson is ready. Re-render after a changed lesson or artifact before giving a page link. A learner who explicitly asks for only the outline may see its contents and sources through `--outline-only`. For an explicit context load at this step, use `assemble_context.py --mode viewer --subject --learner --course-id `. Render only from the enrolled workspace at `learners//courses/`, never from a blueprint `outputs/` file. ## Complete the lesson handoff before showing teaching Read the current topic and its published lesson. Course design supplies the outline; [lesson-design](../lesson-design/SKILL.md) supplies the teaching. If the current topic has no ready lesson, use that skill and its [lesson design reference](../lesson-design/references/lesson-design.md) to author it before delivering a lesson page. If the learner reports a shallow lesson, set its `publication` back to `draft`, use the same reference to repair its explanation and examples, write a new `design_receipt`, and re-publish as `ready` — do not edit a `ready` file in place. Do not write lesson content from `course.json` inside this viewer workflow. The renderer does not call a model or invoke skills: the host must perform the handoff, review the lesson, and publish it. A normal render requires a `ready` lesson for the current topic whose `design_receipt.course_fingerprint` equals the enrolled `course.json` fingerprint and whose `design_receipt.review` is `pass`. It fails otherwise with instructions to run lesson design first. Use `--outline-only` only for an explicitly requested outline or contents preview. If rendering fails, do not link an earlier `portal/index.html` or say the course is ready to view. The local server also checks the current lesson before starting and whenever it serves the page, so an old page cannot be used after the course moves on. The receipt checks a recorded handoff and course match. It cannot prove that the host read the skill or that the explanation is good; review the lesson. ## Render ```bash .venv/bin/python skills/course-viewer/scripts/render_viewer.py learners/alex/courses/motion ``` The script reads `course.json`, published lessons, and the artifact manifest, then writes `portal/index.html` and copies the bundled KaTeX, syntax-highlighting, and math-font assets to `portal/assets/`. Open it locally: ```bash .venv/bin/python skills/course-viewer/scripts/serve_course.py learners/alex/courses/motion --port 8080 # visit http://127.0.0.1:8080/portal/ ``` Use this server for exercise interaction. A plain file or generic static server cannot write a learner response to the course workspace. Save answer persists an attempt under `submissions//.json`; only a successful save enables Show answer. The solution is fetched on that explicit request and the reveal is recorded separately from the learner's response. ## The layout The design lives in [references/example.html](references/example.html). Follow that layout and the approved palette: - the approved forest palette: pale peach (#FDE5D4), dark ink (#001524), green links and dividers (#445D48), brown state labels (#5E3023); solid fills, 2–4 pixel radii, and monospace metadata - topbar: GNOS logo left, tabs center (Overview, Lessons, Exercises, Sources, Artifacts with teal underline for active), All courses → right - hero: giant condensed title + Rev, mono subtitle; right meta block with FIELD / LEVEL / RESOURCES behind a vertical divider - overview is Curriculum (left) + Topic details (right): chapters as "Chapter 01 + Title", topics as numbered rows with Current (navy) / Planned (plum) + › chevron; selected row has solid fill and a green edge; clicking a row updates Topic details (eyebrow, plum title, Subtopics / State / Formats / Evidence / Sources) - lessons show their actual block formats as chips: manim, image, simulation, text (kept as `chip manim` hooks, hidden in curriculum rows, visible in Lessons). Older course plans still show their planned formats. A chip turns ready (`chip manim ready`) when its artifact is registered - videos, images, and sandboxed simulations render full width inside frames with slight rounding, captions below, never overlapping - arrow keys step between lessons; lesson hooks (`#tabs`, `#lesson-list`, `.lesson`, `#prev-link` / `#next-link`) stay intact ## Compatibility with other skills The viewer renders whatever is registered in the course artifact manifest, whatever made it: - manim-voice-animation videos -> watch, inline `