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

ComponentRole
App.jsxRoot: theme state, intro/course routing, showSetup state, shared companion polling
IntroScreen.jsxHero + roadmap (~18K — largest component)
Sidebar.jsxLeft nav — collapsible module tree, progress bar, theme toggle
LessonView.jsxMain reading pane; owns terminal visible/expanded state; fires onShowSetup
Section.jsxRenders individual section types
Terminal.jsxSimulated terminal — fully controlled (open + onToggle props from LessonView)
CompanionSetup.jsxModal: 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 (sessionStorage gate + useRef StrictMode 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 --version verify 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: open and onToggle are 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

FileContents
CLAUDE.mdProject instructions for Claude Code
PRODUCT_STRATEGY.mdAudience, free/paid model, pricing, distribution, non-decisions — see source-product-strategy
plans/README.mdCurrent plan index: points at the implementation-gap assessment and the April 2026 archive
plans/implementation-gap-assessment-2026-04-17.mdCurrent cross-repo assessment of closed plans, real open work, and doc-pruning results
plans/archive/2026-04/*.mdCompleted April planning set plus superseded status snapshots
PROJECT_HISTORY.mdChronological build log for the web app
REPOS.mdLists 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 build
  • bash scripts/check-content-sync.sh
  • bash 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 cinpm run buildwrangler pages deploy dist --project-name=c-systems-lab. Secrets required: CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID (set in repo settings).

Redirects: /companion → Gumroad; /repoVHCosta/c-systems-lab-exercises

PWA

PWA manifest + service worker via vite-plugin-pwa. Works offline after first load. Mobile-installable.