# Brand and navigation

> Change brand copy, URLs, pricing and SEO defaults in src/config/site.ts, and edit the header and footer links in src/config/navigation.ts.

## Brand, copy and links

`src/config/site.ts` is the single source of truth for brand copy, URLs and SEO defaults. It is
imported by `astro.config.mjs`, the layout and the components, so changing a value here flows
everywhere. Edit it here, not inline in components.

The exported `siteConfig` object is grouped by concern:

| Group      | What it holds                                                                       |
| ---------- | ----------------------------------------------------------------------------------- |
| `company`  | `name`, `legalName`, contact `email`                                                 |
| `author`   | The human behind the product (name, title, URL, initials); feeds the schema.org graph |
| `links`    | `appUrl` (live demo SPA), `apiUrl` (API host), `repoUrl` (source); `buyFormEndpoint` + `buyFormRecaptchaSiteKey` are built from env (see below) |
| `demo`     | The live-demo logins surfaced in the hero (`adminEmail`/`adminPassword`, `userEmail`/`userPassword`) |
| `pricing`  | `amount`, `currency`, `display`, `vatNote`, `earlyUser`, `earlyBird`, `license`, `guarantee`, `launchNote`, `tiers[]` (each with `display` + `regularDisplay`); flows to the CTAs, hero early-bird pill and pricing cards |
| `site`     | `name`, `title`, `description`, `url`, `ogImage`, `keywords`                          |
| `seo`      | Default `title`, `description` and `twitterCard` used as a fallback on every page     |

Two things you will almost certainly change: the StaticForm checkout config and your `pricing`.
Checkout runs through `BuyDialog.astro`: the pricing-card buttons carry a `data-buy-tier`
(`solo`/`team`) that opens a dialog collecting the buyer's GitHub username and email, posts to
StaticForm, and redirects to the Stripe Checkout URL StaticForm returns. The Stripe product and prices
are configured in the StaticForm dashboard against the `type` field, so the tier `id` values must stay
`solo` / `team`. The price is read in one place (`pricing`) and reused by every CTA and the schema.org Offer.

The StaticForm form ID and reCAPTCHA site key are **build-time env vars**, not hardcoded:
`PUBLIC_STATICFORM_BUY_FORM_ID` and `PUBLIC_RECAPTCHA_SITE_KEY` (`site.ts` reads them into
`links.buyFormEndpoint` and `links.buyFormRecaptchaSiteKey`). Both are public client-side values (the
form ID is public; the reCAPTCHA *site* key is public, its secret stays in StaticForm). Copy
`.env.example` to `.env` for local dev, and set the same vars in your CI / secret store for deploys.

## Navigation and footer

Both menus are defined in `src/config/navigation.ts`: `mainNav` is the header links and `footerNav`
is the footer's grouped columns. `Header.astro` and `Footer.astro` import and render those arrays, so
you edit links in one place rather than in the markup. Links that point at the product (the demo, the
API reference, GitHub, the contact email) are built from `siteConfig`, so updating a value in
`site.ts` updates them too. The mobile menu is driven entirely by the CSS `:target` selector, so there
is no JavaScript to touch when you add or remove a link.

## Checklist

- [ ] Change brand copy, links and pricing in `src/config/site.ts`, not inline in components.
- [ ] Set `PUBLIC_STATICFORM_BUY_FORM_ID` and `PUBLIC_RECAPTCHA_SITE_KEY` (local `.env`, and your CI / secret store for deploys), configure Stripe in StaticForm against the `type` field, and set `pricing` to your commercial terms.
- [ ] Add or remove header and footer links in `src/config/navigation.ts`; no JavaScript change is needed.
