Interactive, source-traced courses on the ARDC Nectar Research Cloud services. Each course is a single self-contained HTML file: no build step, no bundler, no dependencies beyond Google Fonts. Open any file directly in a browser.
One index for the whole repo. index.html at the root has a tab per service and
links to every course page.
index.html the only index: tabs for Nova, Neutron, Nectar
404.html not-found page; points stray /nova/ links at the right tab
nova/ compute message-flow walkthroughs (7 + 1 extra)
neutron/ OVN networking walkthroughs (2)
nectar/ services built on the cloud (1)
repo/ upstream source checkouts (git-ignored, not published)
wrangler.jsonc Cloudflare Workers config for the whole repo
.assetsignore what NOT to publish
Adding a course: drop the HTML file in the right service folder and add a card to
that service's panel in index.html. Adding a service: add a tab, a panel and a
folder.
Every page has a toggle: in the nav bar on course pages, top-right on the index,
the 404 and the aggregate example. There are three states. With nothing stored the
page follows the operating system via prefers-color-scheme; the toggle writes an
explicit dark or light to localStorage["courses-theme"], which every page
here reads, so the choice carries as you move between courses. A small script in
<head> applies it before first paint so there is no flash of the wrong theme.
Each page carries its own theme block, generated rather than hand-written, because
the pages are standalone files with no shared stylesheet. It appends a
:root[data-theme="dark"] override of the existing design tokens plus a
prefers-color-scheme copy for the follow-the-OS case. The neutrals are shared;
the accent is derived from that page's own light accent, lightened until it clears
about 6.5:1 against the dark background, so each course keeps its colour identity
and stays readable. All dark text pairs meet WCAG AA.
A new course needs a theme block too. Run the generator, which skips any page that already has one:
python3 tools/add-dark-mode.pyThe whole repo is served by one Cloudflare Worker named courses:
https://courses.yanshi-403.workers.dev/
Deploy from the repo root:
npx wrangler deployThe URL comes from two places. The courses label is the name field in
wrangler.jsonc; the yanshi-403 label is the account subdomain, set once in the
Cloudflare dashboard under Workers & Pages, not in this repo.
The assets directory is the repo root, so everything is published except the
paths listed in .assetsignore. That file exists mainly to keep repo/ (the
upstream source checkouts the courses were traced from, about 46 MB, including
graphify caches) off the public site. Check it before adding anything to the root
that should stay private.
not_found_handling: "404-page" makes unmatched paths serve 404.html, which
matters because the per-service index pages were merged into the root index: a
bookmark to /nova/ no longer resolves to a file, so the 404 page detects the
section and offers the matching tab.
Nova and Neutron were previously deployed as their own Workers. Those old Workers
still exist on Cloudflare until deleted (npx wrangler delete --name nova).