Refactor the monolithic main-site contact page into a reusable
<ContactForm> component that encapsulates the Turnstile widget, cooldown
timer, email-verification flow, and tRPC submission. The main
/contact route becomes a thin wrapper that supplies the site-specific
disclaimer subline and Life-and-Lineage FAQ accordion (now exported as
<LineageContactQuestions> for reuse).
Add per-subdomain contact routes (gaze, inputhalo, lineage, nessa) that
render the shared component, with site-aware subject prefix, recipient,
heading, and PageHead metadata derived via useSite() from CONTACT_CONTEXT.
Introduce src/lib/contact-config.ts (with tests) centralizing the contact
recipient/sender addresses and subject building. The misc.sendContactRequest
mutation accepts an optional subjectPrefix (defaulting to "freno.me") so
inbound call sites continue emitting byte-identical legacy subjects, while
subdomain submissions route distinct subjects (e.g. "[Gaze] Contact Request")
to the same inbox.
Consolidate privacy policies per-subdomain:
- Migrate Gaze and Life and Lineage privacy policies verbatim from the
legacy /privacy-policy/* routes to their subdomain paths
(gaze.freno.me/privacy, lineage.freno.me/privacy), and replace the old
routes with 308 permanent redirects to preserve SEO equity and stable
link resolution.
- Add net-new privacy policies for the InputHalo and Nessa subdomains.
- Update the contact page link to point at the Lineage subdomain privacy
policy.
Move the Gaze marketing home from the legacy /marketing/gaze route to
a dedicated gaze subdomain landing page (src/routes/gaze). The new page
adds a richer hero, feature highlights, and a direct .dmg download flow
that resolves a signed S3 URL via the tRPC downloads.getDownloadUrl
endpoint.
Extract the download-resolution logic into a shared, testable
downloadAsset helper (src/lib/download-asset) so current and future
subdomain landing pages (InputHalo, Lineage, …) share one code path.
The helper is pure over an injected DownloadApi + redirect sink, keeping
it unit-testable without importing solid-js / CSRF cookie code.
Replace the old marketing/gaze route with a permanent 308 redirect to
https://gaze.freno.me so existing inbound links keep resolving to the
canonical home.
Add unit tests covering the tRPC call shape, redirect sink, and error
handling.