The personal project index for Dr Sohil Momin, served by GitHub Pages at https://drsamonline.github.io/.
Live site: https://drsamonline.github.io/ · Source: https://github.com/drsamonline/drsamonline.github.io
A single static page that lists every project. The data is built ahead of time and committed, so the page never depends on a rate-limited third-party call to render — it fetches one same-origin JSON file and falls back to an embedded snapshot if that is unavailable.
- A scheduled GitHub Actions workflow (
.github/workflows/refresh-hub.yml) runs daily at 03:17 UTC and onworkflow_dispatch, withpermissions: contents: write. - It calls the GitHub API with the runner's authenticated token (never the
60-requests/hour unauthenticated limit), drops forks and the
drsamonline/drsamonline.github.iorepos, and merges the rest with theCURATEDmap insideindex.html. A repo that is not in the map still appears, under the automatic Other / New category, using its GitHub description. tools/build_hub.pywrites the merged data torepos.jsonand regenerates the embedded snapshot inindex.html(so the offline fallback always matches) plus the JSON-LDItemListandsitemap.xml.tools/capture_shots.pyloads every project landing page at 1200×750, downscales to 600×375 and encodes WebP intoassets/shots/<repo>.webp. Images that already exist, are recent and were a successful capture are skipped; failures fall back to a branded placeholder and are retried.- Everything is committed back to the repository.
At runtime the page:
- renders instantly from the embedded snapshot, then
- fetches
repos.json(same origin, no rate limit, fast) and re-renders.
No third-party screenshot host, no runtime GitHub API call, no analytics.
- Calm, professional palette built on CSS custom properties in
:root, with a full override under[data-theme="dark"]. Body text meets WCAG AA (4.5:1) and UI borders meet 3:1 in both themes. - A theme toggle in the navigation that respects
prefers-color-schemeon a first visit, persists the choice inlocalStorage, applies the stored theme before first paint via a tiny inline<head>script, updates itsaria-label/aria-pressedand icon, and works with the keyboard. prefers-reduced-motionis honoured throughout.- Self-contained: inline CSS/JS, no external JS libraries, inline SVG icons.
| Path | Purpose |
|---|---|
index.html |
The hub. Contains the CURATED map (source of curated fields) and the embedded snapshot. |
repos.json |
Build-time data the page fetches at runtime. |
tools/build_hub.py |
Fetches the API, merges with CURATED, writes repos.json + snapshot + JSON-LD + sitemap. |
tools/capture_shots.py |
Captures and encodes the local thumbnails. |
tools/placeholders.py |
Branded fallback thumbnail. |
assets/shots/ |
Locally served thumbnails (<repo>.webp) + _manifest.json. |
.github/workflows/refresh-hub.yml |
The scheduled build. |
Everything configurable lives in the small block at the top of the inline
<script> in index.html:
| Setting | Purpose |
|---|---|
CURATED |
Per-repo cat, desc, demo, feat, rel, kicker, tag. |
CAT_LABEL / CAT_ORDER |
Category names and display order. |
FEATURED |
Repo keys pinned to the top of the Featured section. |
python3 -m http.server 8080
# then open http://localhost:8080/To regenerate the data locally without the API:
HUB_REPOS_FILE=repos_raw.json python3 tools/build_hub.pyThe page has no backend, no analytics and no cookies. It fetches only its own
repos.json and its own images; the Content-Security-Policy restricts network
access to 'self'.
MIT © 2026 Dr Sohil Momin — this covers the page's code.
The written content shown here (project descriptions, the profile text and any original prose) belongs to its author and is © 2026 Dr Sohil Momin, all rights reserved. Repository descriptions are pulled from the GitHub API and remain the property of their respective authors.