server: restructure the frontend into a typed core lib + custom-element islands
audit Run 15 Phase 5: CSP script-src drops 'unsafe-inline'
ux: extract all executable inline JS from templates into static files