# Sansonnet Deploy Runbook > **As of 2026-05-18**: Sansonnet site is built but not yet deployed. > Prod domains `sansonnet.maison` and `maisonsansonnet.com` are not > registered. This doc captures the deploy shape so the runbook is > ready when DNS goes live. --- ## What this feature ships A bilingual (Français-first, English second) historical-office site for Sansonnet, the Paris-based management cabinet. 11 routes: | Route | Locale | Page | |------------------------|--------|---------------------------------| | `/` | — | Language splash + auto-redirect | | `/fr/` | fr | Accueil (home) | | `/fr/about/` | fr | À propos | | `/fr/services/` | fr | Services | | `/fr/clients/` | fr | Clientèle | | `/fr/contact/` | fr | Contact | | `/en/` | en | Home | | `/en/about/` | en | About | | `/en/services/` | en | Services | | `/en/clients/` | en | Clients | | `/en/contact/` | en | Contact | Default locale is **fr** (the site’s natural register). The lang splash redirects to `/fr/` unless the visitor’s browser prefers English. --- ## Architecture Sansonnet uses **Astro** with built-in `i18n` routing (`defaultLocale: fr`, `locales: [fr, en]`) and the `@cocotte/*` package scope: | Package | Role | |-----------------------------|---------------------------------------------| | `@cocotte/astro-tokens` | CSS variable contract (theme-agnostic) | | `@cocotte/astro-chrome` | `BaseLayout` primitive | | `@cocotte/astro-config` | `defineBrandSiteConfig({ i18n })` factory | Layout discipline: `SansonnetLayout.astro` composes `BaseLayout` and owns the office’s chrome — per-page wordmark + subtitle, bottom text-nav listing the other pages (current page is excluded), and the page-footer colophon + lang-switch. Per-page subtitle is a layout prop (each page passes its own `subtitle="…"`), since each Sansonnet page has its own “wordmark-sub” line under the brandmark. i18n strings (nav labels, colophon text, page paths) live in `src/i18n/strings.ts`. Brand palette: cream paper, deep ink, EB Garamond serif. Lives in `src/styles/tokens.css`. --- ## Source of truth | Surface | Path | |--------------------------|-------------------------------------------------------------------| | Astro project | `codebase/@features/sansonnet-web/site/` | | Pages | `codebase/@features/sansonnet-web/site/src/pages/` | | Layout | `codebase/@features/sansonnet-web/site/src/layouts/SansonnetLayout.astro` | | i18n strings | `codebase/@features/sansonnet-web/site/src/i18n/strings.ts` | | Brand tokens | `codebase/@features/sansonnet-web/site/src/styles/tokens.css` | | Globals | `codebase/@features/sansonnet-web/site/src/styles/globals.css` | | Legacy HTML stubs | `codebase/@features/sansonnet-web/web/` (kept until cutover) | --- ## Local build \`\`\` cd codebase/@features/sansonnet-web/site bun install bun run build # → dist/{index,fr/*,en/*}/index.html + sitemap bun run preview # localhost:4321 bun run dev # hot-reload dev server \`\`\` --- ## Deploy (pending — sansonnet.maison not yet registered) When the domain is live: \`\`\` cd codebase/@features/sansonnet-web/site bun install bun run build rsync -avz --delete \\ dist/ \\ vps-0:/var/www/sansonnet-web/web/ \`\`\` Nginx vhost: `deployments/@domains/sansonnet.maison/nginx/prod.conf` (not yet authored). Optional alias: `maisonsansonnet.com` → 301 to canonical. --- ## Adding a new page 1. Pick a key (e.g., `press`) and extend `SansonnetPage` union in `src/i18n/strings.ts`. 2. Add the nav label per locale to `STRINGS` and the href per locale to `PAGE_HREF`. 3. Create `src/pages/{fr,en}/press.astro` declaring ``. The text-nav at the bottom of every other page now automatically includes the new page.