Source: LLC Course Web App
Repo: VHCosta/llc-course
Stack: React 18 + Vite 5, deployed to Cloudflare Pages
Status: Complete — all 10 modules have full content; actively polished
Architecture
No backend. Web lesson content is data-driven: each module is a JS object in
src/data/modules/m{N}.js exporting lessons with typed sections. Canonical
exercise content lives in content/chNN/exN_M/. A simulated terminal
(terminalScripts.js, ~73K) provides per-lesson interactive practice when the
local companion is absent or the command is unsupported. Progress is stored in
localStorage via a custom useProgress hook.
Section Types
text, heading, code, callout, breakdown, stages, list, action, shell, expect
Component Map
| Component | Role |
|---|---|
App.jsx | Root: theme state, intro/course routing, showSetup state, shared companion polling |
IntroScreen.jsx | Hero + roadmap (~18K — largest component) |
Sidebar.jsx | Left nav — collapsible module tree, progress bar, theme toggle |
LessonView.jsx | Main reading pane; owns terminal visible/expanded state; fires onShowSetup |
Section.jsx | Renders individual section types |
Terminal.jsx | Simulated terminal — fully controlled (open + onToggle props from LessonView) |
CompanionSetup.jsx | Modal: guided setup for companion app or manual gcc install (see below) |
Companion Setup Modal (as of 2026-04-13)
CompanionSetup.jsx — position-fixed modal (zIndex: 300) with two tabs:
- Companion App: OS selector (mac-arm / mac-intel / linux / windows), curl install command with copy button, live
useCompanion()status bar (blinking dot → green “Companion connected” on detection). Auto-triggered once per session on first M5+ visit when companion absent (sessionStoragegate +useRefStrictMode guard). Also reachable via “set up C environment →” button in the terminal bar. - Manual Setup: apt / pacman / xcode-select / WSL2 install commands, platform notes,
gcc --versionverify block.
Replaces the ghost-text span + raw GitHub URL that previously appeared next to the terminal button in M5+.
Terminal (as of 2026-04-11)
- Hidden behind ”▸ TERMINAL (experimental)” opt-in button
- Click button → terminal appears expanded (324px: 38px header + 244px output + 42px input)
- Header click toggles collapse (80px: header + input only; output area is
flex:0 / overflow:hidden / padding:0) - Clicking backdrop (dim overlay above expanded terminal) collapses it
- Red traffic light / onClose returns to the opt-in button
?button in header prints a disclaimer explaining why the terminal is simulated- Terminal is fully controlled:
openandonToggleare props; LessonView owns state
Design
Dark terminal aesthetic. JetBrains Mono (body/code), Bebas Neue (headings), DM Serif Display (decorative). Inline styles + CSS variables — no Tailwind, no CSS modules. Dark/light theme toggle, persisted in localStorage under llc_theme.
Sidebar collapses to a 52px icon rail on desktop; slides in as a full-width drawer on mobile.
Root-level documents
| File | Contents |
|---|---|
CLAUDE.md | Project instructions for Claude Code |
PRODUCT_STRATEGY.md | Audience, free/paid model, pricing, distribution, non-decisions — see source-product-strategy |
plans/README.md | Current plan index: points at the implementation-gap assessment and the April 2026 archive |
plans/implementation-gap-assessment-2026-04-17.md | Current cross-repo assessment of closed plans, real open work, and doc-pruning results |
plans/archive/2026-04/*.md | Completed April planning set plus superseded status snapshots |
PROJECT_HISTORY.md | Chronological build log for the web app |
REPOS.md | Lists all three repos in the project |
Checks and Deploy
GitHub Actions CI now runs npm run check on pull requests and pushes to
master. The local check path is:
npm run buildbash scripts/check-content-sync.shbash scripts/validate.sh
Release assembly is handled by scripts/dist.sh, which now builds the four
Gumroad upload folders and can zip exports via zip, a python3 zipfile
fallback, or PowerShell Compress-Archive depending on the host environment.
The old top-level plan docs were archived on 2026-04-16 to keep plans/
focused on the current status surface instead of completed historical plans.
Deploy remains in .github/workflows/deploy.yml: npm ci → npm run build →
wrangler pages deploy dist --project-name=c-systems-lab. Secrets required:
CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID (set in repo settings).
Redirects: /companion → Gumroad; /repo → VHCosta/c-systems-lab-exercises
PWA
PWA manifest + service worker via vite-plugin-pwa. Works offline after first load. Mobile-installable.