Theme implementation contract
Inspect the runtime theme, token, and site-override contracts shipped by Core.
- Owner
- Foundry Core
- Source
core/docs/THEMING.md- Ref
v0.1.15- Policy
- release-bound
Component pins for v0.2.1
| Component | Role | Version |
|---|---|---|
| core | runtime | v0.1.15 |
| theme-shield | theme | v0.1.14 |
| restricted-component-1 | brand-theme | v0.1.4 |
| dark-mode | runtime-addon | v0.1.0 |
| i18n | runtime-addon | v0.1.0 |
| starter | reference | v0.1.2 |
| docs | reference | v0.1.4 |
| distribution | tooling | v0.3.0 |
| restricted-component-2 | consumer-reference | v0.1.4 |
Foundry theming is governed by the cross-platform styling policy. The short version is: tokens are the contract; Tailwind is not.
Four-layer CSS cascade
Foundry resolves styles in this order:
assets/css/foundry-base.css— neutral--foundry-*fallback variables.- Optional compiled utility/theme layer — may include Tailwind-generated CSS where a site or theme already uses it.
- Optional theme module CSS (for example theme-shield
assets/css/theme.css) — overrides variables and adds presentation rules. - Optional site override layer (
assets/css/foundry-overrides.css) — loaded after theme CSS for downstream fixes that truly must win.
This ordering is implemented in layouts/_partials/css.html, which loads foundry-base.css before higher-level styling layers.
Theme base templates should then load theme CSS and finally partial "foundry/head/site-overrides-css.html" ..
Using the framework without a theme
foundry-base.css provides neutral defaults for every required token, so blocks render correctly even with no theme module imported.
Using theme-shield
theme-shield adds a complete visual identity layer: typography system, color palette, dark mode, card interactions, and section treatments.
It notably sets --foundry-bg: #f2f5fb, Playfair Display heading fonts, and alternating section backgrounds/dividers.
Sites with a full custom brand system (for example restricted proof consumer) should typically import Foundry core without theme-shield.
Add it with module imports:
module:
imports:
- path: github.com/jerrybroughton/likestyle-foundry-core
- path: github.com/jerrybroughton/likestyle-foundry-theme-shield
Creating a custom theme
Create a Hugo module with assets/css/theme.css and override only the --foundry-* tokens you need. Keep structure/components in core; keep visual language in the theme.
Do not make Tailwind the only path to a usable theme. A pinned downstream site should still render correctly from shipped CSS and token overrides.
Recommended structure:
my-foundry-theme/
assets/
css/
theme.css
layouts/
partials/
head/
theme-css.html
Downstream site structure:
my-foundry-site/
assets/
css/
foundry-overrides.css
Use foundry-overrides.css only for:
- theme-level bug fixes that must load after theme CSS
- site-specific component overrides that cannot be expressed by tokens alone
- temporary compatibility patches during migration
Do not treat foundry-overrides.css as the main site stylesheet.
Dark mode pattern:
:root {
--foundry-bg: #ffffff;
--foundry-surface: #ffffff;
--foundry-surface-soft: #f6f8fc;
--foundry-text: #0f172a;
--foundry-text-muted: #475569;
--foundry-border: #dbe4f4;
--foundry-brand-primary: #1f3b82;
--foundry-brand-accent: #c7352f;
}
.dark,
[data-theme="dark"] {
--foundry-bg: #0a122e;
--foundry-surface: #0f1d49;
--foundry-surface-soft: #162a5d;
--foundry-text: #edf2ff;
--foundry-text-muted: #c1cff2;
--foundry-border: #2d4276;
}
Optional component tokens
When a shared block needs more control than the global surface/link tokens provide, Foundry can expose block-scoped component tokens instead of forcing downstream selector overrides.
The search block supports optional --foundry-search-* tokens for panel, input, result card, media border, pill/tag, and title hover styling.
The table of contents widget supports optional --foundry-toc-* tokens for panel background, toggle surface, progress rail, and active/completed link states.
Themes should prefer those tokens over overriding internal .foundry-search__* or .foundry-table-of-contents__* selectors in site CSS.
Variable reference
Full comparison of core defaults and theme-shield overrides.
| Variable | Purpose | Core base (foundry-base.css) | theme-shield value (light) | theme-shield value (dark) |
|---|---|---|---|---|
--foundry-bg | Page background color. | #ffffff | #f2f5fb | #0a122e |
--foundry-border | Default border color. | #e2e8f0 | #dbe4f4 | #2d4276 |
--foundry-border-strong | High-contrast border color. | #cbd5e1 | #c4d2ed | #3d5696 |
--foundry-brand-accent | Secondary accent color. | #3b82f6 | #c7352f | inherits light |
--foundry-brand-primary | Primary brand accent used for key UI elements. | #0f172a | #1f3b82 | inherits light |
--foundry-duration-base | Base motion duration token. | 200ms | 200ms | inherits light |
--foundry-ease-standard | Default easing curve for transitions. | cubic-bezier(0.2, 0, 0, 1) | cubic-bezier(0.2, 0, 0, 1) | inherits light |
--foundry-radius | Default radius token. | 1rem | 1rem | inherits light |
--foundry-radius-lg | Large radius token. | 1.5rem | 1.4rem | inherits light |
--foundry-radius-sm | Small radius token. | 0.5rem | 0.65rem | inherits light |
--foundry-shadow-md | Medium elevation shadow token. | 0 4px 12px rgba(0, 0, 0, 0.1) | 0 18px 36px rgba(15, 23, 42, 0.14) | 0 20px 38px rgba(2, 8, 26, 0.5) |
--foundry-shadow-sm | Small elevation shadow token. | 0 1px 3px rgba(0, 0, 0, 0.1) | 0 10px 20px rgba(15, 23, 42, 0.08) | 0 12px 24px rgba(2, 8, 26, 0.36) |
--foundry-surface | Primary surface/card background. | #ffffff | #ffffff | #0f1d49 |
--foundry-surface-soft | Subtle section and muted surface background. | #f8fafc | #f8faff | #162a5d |
--foundry-text | Primary text color. | #0f172a | #0f172a | #edf2ff |
--foundry-text-muted | Secondary/muted text color. | #475569 | #475569 | #c1cff2 |
Theme-shield also defines additional optional tokens for links, typography, focus styles, and extended shadows.