# theme _(no submodules)_ ## Purpose Provides the theme tokens consumed by every email component — colours, typography, spacing, branding, border-radius, and max-width. Themes are immutable plain objects: `createTheme` returns a fresh object every call and never mutates the shipped `defaultTheme`, so the module is safe to import in cross-tenant contexts where two consumers compose distinct themes side-by-side. The default palette is `#2563eb` primary (Tailwind blue-600), a slate secondary, and a 600 px max-width — sane email-client defaults that render correctly in Gmail, Apple Mail, Outlook 2016+, and the major web clients without further customisation. ## Features - `defaultTheme`: frozen default `EmailTheme` instance. - `createTheme(options?)`: deep-merges `options` into `defaultTheme`, returning a new object. - `mergeThemes(base, override)`: shallow-merges each section into `base`. - Every section is independently overridable — partial colour overrides leave other colours intact. ## Usage: Basic ```ts import { createTheme } from "@suaveplan/email-templates/theme"; const theme = createTheme({ colors: { primary: "#ff6600" }, branding: { companyName: "Acme Corp" }, }); ``` ## Usage: Advanced Compose a per-locale theme by layering region-specific tokens onto a base: ```ts import { createTheme, mergeThemes } from "@suaveplan/email-templates/theme"; const base = createTheme({ branding: { companyName: "Acme" }, typography: { fontFamily: "'Inter', sans-serif", }, }); const jaTheme = mergeThemes(base, { typography: { fontFamily: "'Noto Sans JP', sans-serif" }, }); ``` `mergeThemes` differs from `createTheme` in that it merges into the explicitly-supplied `base` (which may itself differ from `defaultTheme`) — useful when a multi-tenant pipeline pre-builds a per-tenant base and then layers a per-locale override on top. ## API Reference | Symbol | Kind | Description | | -------------- | -------- | ---------------------------------------------------------- | | `defaultTheme` | const | The shipped default `EmailTheme`. | | `createTheme` | function | `(options?) => EmailTheme` — overrides applied to default. | | `mergeThemes` | function | `(base, override) => EmailTheme`. | Types: `EmailTheme`, `EmailThemeColors`, `EmailThemeTypography`, `EmailThemeSpacing`, `EmailThemeBranding`, `EmailThemeOptions`. ## Implementation Notes Token defaults are declared as module-local `const … as const` expressions so they cannot be re-bound; the exported `defaultTheme` is a spread of those tokens. The exported value is intentionally **not** `Object.freeze`'d — TypeScript's `readonly` already prevents accidental re-assignment at the type level, and freezing would interact badly with serialise / hydrate flows in downstream tests. Spread-merging means deep nested fields cannot be partially overridden within the same `createTheme` call (e.g. you cannot override one branding field without losing the others) — each section is treated as a single unit. That matches upstream behaviour exactly; consumers who need a deeper merge can compose two `createTheme` calls with `mergeThemes`.