Replace the separate CMS subdomain with path-based routing in Caddy:
/admin and /uploads go to Strapi, everything else to the frontend.
Strapi 5 nests its whole admin panel (UI and API) under /admin, so this
one prefix is enough and never collides with the frontend's own /api
routes. Drops CMS_DOMAIN and the unused STRAPI_URL env var on the cms
service; PUBLIC_STRAPI_URL now points at the same origin as the site.
Authentication is unchanged: Strapi's own admin login still gates the
panel, this only changes how it's reached.
The interface is translated through @nuxtjs/i18n: strings live in
i18n/locales/*.json, routes are prefixed except for the default English, and
useLocaleHead emits the lang attribute, the hreflang alternates and og:locale.
The switcher is a native select rather than a custom dropdown: keyboard
support, the platform picker on mobile and correct labelling come for free.
Article content stays single-language — this translates the site chrome only.
README gets step-by-step instructions for both: secrets generation and the
local stack on one side, DNS records, firewall, environment variables, TLS and
backups on the other.
CLAUDE.md records the decisions that are not visible in the code: why the
browser never reaches Strapi, why the content model stays this small, and where
the public permissions are granted.