# Project Kickoff

## The original goal

Replace a set of static, Python-generated day pages with a fully spreadsheet-driven system, so that building a new day's lesson means editing a Google Sheet — not writing code. The teacher (Erik) should be able to author, reorder, and revise content entirely from the spreadsheet, with the website handling layout, interactivity, and student progress tracking automatically.

## Where this project has actually landed

That goal is met. `day.html` builds itself entirely from spreadsheet rows, in the order those rows appear — reordering a lesson means reordering rows, not touching code. 16 widget types exist, covering everything from static instructional text to a real terminal simulation, real RSA cryptography, and drag-and-drop code arrangement.

Two courses' worth of pacing exist for a full school year (~173 days each, all 3 courses: AP CSA, AP CSP, AP Cybersecurity); actual lesson content currently covers the first 5 days of each — the rest is ongoing, expected work, not a gap in the system itself.

## Design decisions worth understanding, not just accepting

These came up as real judgment calls during development, not arbitrary choices — worth knowing the reasoning if you're extending this system later.

- **Row order is the ordering mechanism.** Early on, widget order was a fixed built-in sequence (story → vocab → quiz → terminal → ...) regardless of spreadsheet content. This was deliberately changed so the page always matches what's actually written in the sheet, top to bottom — a fairer mental model for a teacher who thinks in terms of "what happens when" during class, not "which widget type."

- **`rule` (Class Rules) is opt-in per day; `message` (General Messages) is automatic.** Both started as "always shown on every single day," which the teacher explicitly asked to change for Rules — static reference content shown on demand felt more useful than a constant fixture. Messages went the other way on purpose: they're time-sensitive announcements, and forcing a flag row on every day you want one seen defeats the point of an announcement.

- **The certificate auto-fills the student's name.** It used to require typing a name every time; since the site already has a confirmed student-ID system, retyping was pure friction. Falls back to manual entry only if a student somehow reaches a day page without ever confirming an ID.

- **"Silent Teacher" isn't a separate widget.** It was originally scoped as its own ladder-style widget (wrong answer → fresh randomized question, no explanation). The teacher's own conclusion, reached mid-project: this is just a quiz with leading questions, shown one at a time — so it became a mode (`sequential`) on the existing Quiz widget instead of new infrastructure. The lesson here: the actual hard part of that idea was always the content (writing a good ladder of questions), not the mechanism.

- **Two visual themes, deliberately.** Dark/terminal for pages where students do actual lesson work (`day.html`, `test.html`); light/friendly for landing and reference pages (`index.html`, `policies.html`, `ask-a-question.html`). Not an inconsistency — a dark terminal aesthetic fits code/cipher/firewall work; it doesn't fit a course-policies page.

- **Tab consolidation was selective, not blanket.** Merging the 3 pacing tabs into 1, and Vocabulary+Cheat Sheets into 1, were clear wins — near-identical schemas, real reduction in tab-bar clutter. FRQ+Quiz Questions was considered and rejected — their column shapes diverge enough (5 columns vs. up to 11) that merging would create a wide, sparse table for a marginal win. `rank_titles`+`bulletquestions` merging is feasible but was deliberately deferred, since it requires editing the live backend Apps Script rather than just the frontend — a genuinely different risk profile from the read-only frontend merges.

- **Lab tools reuse the hub's confirmed-ID system rather than building a parallel one.** When lab tools (standalone, hand-built pages like the compression lab) needed their own certificates with a graded save-to-sheet step, the tempting shortcut was a self-contained identity flow scoped to just that lab. Rejected in favor of reading/writing the exact same `localStorage` keys (`studentId`/`studentName`) `student-id.js` already uses site-wide, and posting to the same deployed Apps Script Web App — meaning a student who's confirmed their ID once, anywhere on the site, never has to retype it in a lab. The cost is one more file (`labs/js/lab-certificate.js`) needing to stay in sync with `student-id.js`'s conventions if those ever change; the alternative cost — two incompatible identity systems on the same domain — was worse.

## What this document is not

This isn't a running changelog. If the system changes meaningfully from what's described in `SYSTEM_REFERENCE.md`, that document gets rebuilt fresh rather than patched — so treat `SYSTEM_REFERENCE.md` as the single source of truth for *current* system behavior, and this document as background on *why* it ended up this way.
