Legal content
Four legal documents — Terms, Privacy, Cookies, DPA — ship in 4 languages (EN canonical + CS/DE/ES translated headers). Routes:
- EN canonical:
/legal/$slug(handled by
- Localized:
/$lang/legal/$slug(handled by
Content lives in apps/web/app/content/legal/:
en.ts— full EN bodies for all four documents.translated.ts— per-lang translated titles + canonical disclaimer.
CS/DE/ES use the EN body verbatim with a leading blockquote that says _"This translation is informative. The English version prevails on conflict."_ When a real translation is contracted, swap the body in this file.
types.ts+index.ts— barrel + types.
Rendering goes through apps/web/app/ui/legal-render.tsx — a tiny in-house Markdown subset (H2/H3, paragraphs, lists, blockquotes, tables, inline link/bold/code). No third-party Markdown dependency.
Sub-processor list — single source of truth
The Privacy Policy enumerates the sub-processors. When a new sub-processor is added (or one drops out), update en.ts Privacy body's "Sub-processors" table. The legal-page e2e (apps/web/app/e2e/legal.e2e.test.ts) asserts Hostinger + Sentry + OpenAI + "Zero Data Retention" appear on the live page — failing tests catch accidental removals.
Cookies
Banner + customize modal are already wired in _marketing.tsx (task 34). Choices persist in localStorage under drobek-cookies-v1. Categories:
- strict — always on (session, csrf, lang).
- func — theme, language remembered.
- analytics — off by default (we ship none currently).
To re-open the banner: localStorage.removeItem('drobek-cookies-v1').
Lawyer review
PRE-LAUNCH: the EN text in en.ts is plausible boilerplate authored by engineers. Before the public launch we must have a qualified lawyer review the four documents. Tracked as LEGAL_REVIEW_TODO in the launch checklist.