Status: canonical
Audience: engineering, agents
Purpose: describe the current static-site architecture and target evolution
Firebase Hosting serves generated files from dist/.
The public runtime contains:
.html pagesdist/assets/dist/data/dist/images/sitemap.xml and robots.txtThere is no active Cloud Functions package and no /api/** rewrite.
The source model is intentionally transitional:
.html files are the current authored public page source for
unmigrated pages_src/pages/*.html files are source for migrated template-driven pages_src/layouts/base.html owns the first shared source page layout_src/partials/nav.html and _src/partials/footer.html own shared chromecss/src/*.css owns CSS source; css/style.css is generateddata/site.json owns site identity, domain, social links, and core assetsdata/site.config.json owns deploy, CSP, external allowlist, and budgetsdata/*.json owns migrated collection contentjs/ owns browser behaviorvendor/leaflet/ owns self-hosted Leaflet runtime assetsscripts/ owns build and validation logicadmin/ is source for a browser-based admin interface, excluded from Hostingroot HTML + _src pages/layouts/partials + css/src + data + js + vendor
-> scripts/build-site.js
-> css/style.css
-> data/pages.json
-> sitemap.xml / robots.txt
-> dist/
dist/ is generated and should not be hand-edited.
Run all local health checks:
npm run check
The check suite validates:
dist/After editing data/site.json, run:
node scripts/sync-site-config.js
After editing deploy/security/performance rules in data/site.config.json, run:
npm run build
npm run check
Firebase Hosting is the public serving layer. admin/** is intentionally ignored
by Hosting deploys. Firestore denies all non-admin documents and only allows the
configured admin email to access /admin/**.
The admin UI still runs in the browser. Do not treat client-side two-factor checks as a backend authorization boundary. Any future write-capable admin actions should move behind Cloud Functions or another server-side API that verifies Firebase ID tokens and second-factor state before writing data.
The target architecture is:
_src/
pages/
layouts/
partials/
components/
content/
styles/
dist/
Move one page type at a time. The generated output should remain visually and behaviorally equivalent unless a style/product change is explicitly requested.