Security (launch blockers):
- src/middleware.ts (edge): forwards x-pathname + real client IP.
- access-guard.ts (Node, from root layout): routes non-staff to /maintenance
when maintenance mode is on, banned users to /banned. New /banned + /maintenance
pages (the consumers the admin toggle was missing). Admin layout enforces
force_staff_2fa before /admin.
- staff-activity.ts audit log wired into ban/lift/give-currency/set-rank actions.
Infra (parallel agents): alert service (alert_logs + Discord embed + email),
PayPal top-up (create/capture API routes + /shop/topup), cron worker
(scripts/jobs-worker.ts via croner: emulator-ping->alert, maintenance-check,
bans-cleanup), social connections page, admin radio settings/banners/ranks.
Public radio subsystem: /radio (+schedule, shouts+post, contests, giveaways,
apply, leaderboard) and /apply/staff + /apply/team submission forms. Radio nav
link added. .env.example documents the new optional vars.
(radio song-requests dropped: its table is a stub in AtomCMS — columns added by
un-modeled alter-migrations.)
Verified: tsc exit 0, vitest 48/48, next build exit 0 (82 page routes).
Faithful port of AtomCMS's "atom" theme look (light, Habbo-retro, golden
#eeb425 / amber #f59e0b accents, white cards, 12px radii, Nunito-first stack):
- globals.css: full token set + components (.site-header/.nav-item, .btn-*,
.card, .hero, currency pills, article cards, inputs, tables, footer).
- SiteHeader (brand + nav + currency pills + auth box, staff-aware) + SiteFooter;
layout wraps header/content/footer. Removed the bare SiteNav.
- Restyled home (hero + article cards), login (centered card).
- siteSettings now falls back to DEFAULTS on missing key OR DB error, so pages
render without a DB; DATABASE_CONNECT_TIMEOUT_MS env + pool acquireTimeout make
the no-DB fallback fast.
Verified in a real browser (computed styles): header white/sticky, golden logo
gradient, uppercase nav, amber primary button @12px radius, golden outline,
hero gradient — all correct. tsc exit 0, vitest 48/48, next build exit 0.