Foundry injects the CSS you save in **Foundry → Settings → Advanced → Custom CSS** on every published page for your domain. This page is the styling contract: what you can change, which selectors stay stable, and how to have an AI assistant write the CSS for you.

## Give this page to an AI assistant

Open Cursor, Claude Code, ChatGPT, or Codex and paste:

```
Write custom CSS for my Zerply Foundry site.

Follow this spec exactly:
https://zerply.ai/docs/foundry-custom-css/

Brand notes:
- Site to match:
- Colors:
- Fonts:
- Other notes:

Output only CSS I can paste into Foundry → Settings → Advanced → Custom CSS.
Prefer CSS variables, then [data-foundry-*] selectors. Do not target Tailwind class names.
```

Fill in the brand notes (a homepage URL is enough if you have one). Paste the CSS it returns into Foundry settings and save. Pages revalidate after save.

Or install the [Foundry CSS skill](https://zerply.ai/.well-known/agent-skills/foundry-css/SKILL.md) so the assistant already knows the contract:

```bash
mkdir -p ~/.cursor/skills/foundry-css
curl -fsSL https://zerply.ai/.well-known/agent-skills/foundry-css/SKILL.md \
  -o ~/.cursor/skills/foundry-css/SKILL.md
```

Claude Code: use `~/.claude/skills/foundry-css/SKILL.md`. Codex-style layouts: `~/.agents/skills/foundry-css/SKILL.md`.

## How CSS is applied

- Your stylesheet is injected after Foundry's defaults, so a rule with the same specificity as a default rule wins.
- CSS only. No JavaScript, HTML, or `<link>` tags.
- `@import` and `@font-face` are allowed. Put `@import` on the first line.
- Do **not** target Tailwind class names (`px-8`, `text-3xl`, `bg-card`). Those can change. Use CSS variables and `[data-foundry-*]` attributes.
- Start with variables. Reach for element selectors only when a variable is not enough.
- `!important` is almost never required. Prefer variables, then `[data-foundry-*]`. A few values (reading-progress width, TOC highlight) are still set inline because they change at runtime.

Root of every page:

```html
<html data-color-scheme="light|dark">
  ...
  <div data-foundry-tenant>
    <header data-foundry-region="header">...</header>
    <main data-foundry-region="main">
      <div data-foundry-page="hub|landing|blog-index|blog-all|blog-post|authors|author">
        ...
      </div>
    </main>
    <footer data-foundry-region="footer">...</footer>
  </div>
</html>
```

## Theme variables

Override these on `[data-foundry-tenant]`. They already switch with light and dark mode.

| Variable | Used for |
| --- | --- |
| `--background` | Page surface |
| `--foreground` | Body text |
| `--card` | Cards, header default |
| `--card-foreground` | Text on cards |
| `--muted` | Subtle bands (features grid, hub explore) |
| `--muted-foreground` | Secondary text |
| `--border` | Dividers and card edges |
| `--input` | Form field borders |
| `--brand-color` | Links, accents, text on light surfaces |
| `--brand-fill` | Solid buttons and CTA fills with white text |

`--brand-color` and `--brand-fill` are derived from the brand color in Foundry settings so they stay readable on light and dark surfaces. Override them only if you need a specific hex.

Dark-mode overrides need both attributes:

```css
[data-color-scheme="dark"] [data-foundry-tenant] {
  --background: #0b0b0c;
  --foreground: #f5f5f4;
}
```

## Layout variables

These default to Foundry's built-in look. Changing them is the fastest way to restyle chrome, hero, and CTA bands.

| Variable | Default | Used for |
| --- | --- | --- |
| `--foundry-font-sans` | `Arial, Helvetica, sans-serif` | All Foundry UI text |
| `--foundry-header-bg` | `var(--card)` | Sticky header |
| `--foundry-header-border` | `var(--border)` | Header bottom border |
| `--foundry-footer-bg` | `#111827` in light, `var(--background)` in dark | Footer surface |
| `--foundry-footer-fg` | `#d1d5db` / muted in dark | Footer body text |
| `--foundry-footer-muted` | `#9ca3af` / muted in dark | Footer links, description, copyright |
| `--foundry-footer-heading` | `#ffffff` / foreground in dark | Footer headings and site name |
| `--foundry-footer-border` | `#1f2937` / border in dark | Footer bar divider |
| `--foundry-footer-logo-filter` | `brightness(0) invert(1)` in light, `none` in dark | Footer logo treatment |
| `--foundry-hero-bg` | slate gradient | Landing hero background |
| `--foundry-hero-fg` | `#ffffff` | Landing hero text |
| `--foundry-hero-cta-bg` | `var(--brand-fill)` | Hero button |
| `--foundry-hero-cta-fg` | `#ffffff` | Hero button text |
| `--foundry-cta-band-bg` | `var(--brand-fill)` | Landing CTA section |
| `--foundry-cta-band-fg` | `#ffffff` | CTA section text |
| `--foundry-cta-band-button-bg` | `#ffffff` | CTA section button |
| `--foundry-cta-band-button-fg` | `var(--brand-color)` | CTA section button text |
| `--foundry-font-mono` | system monospace | Fenced and inline code |
| `--foundry-code-bg` / `--foundry-code-fg` | GitHub-like light / dark | Code snippet surface |
| `--foundry-code-border` | `var(--border)` | Code snippet border |
| `--foundry-inline-code-bg` / `--foundry-inline-code-fg` | warm orange tint | Inline `code` |
| `--foundry-code-comment` | muted gray | Comments |
| `--foundry-code-keyword` | red | Keywords |
| `--foundry-code-string` | navy / light blue | Strings |
| `--foundry-code-number` / `--foundry-code-literal` | blue | Numbers and literals |
| `--foundry-code-function` | purple | Functions |
| `--foundry-code-attr` | blue | Attributes and properties |
| `--foundry-code-built-in` | brown / orange | Built-ins |
| `--foundry-code-tag` | green | Tags |

## Pages

`[data-foundry-page]` on the main content wrapper:

| Value | URL | What it is |
| --- | --- | --- |
| `hub` | `/{base_path}` | Site home under Foundry |
| `landing` | `/{base_path}/{slug}` | Landing page |
| `blog-index` | `/{base_path}/blog` | Blog home |
| `blog-all` | `/{base_path}/blog/all` | All articles + filters |
| `blog-post` | `/{base_path}/blog/{slug}` | Single article |
| `authors` | `/{base_path}/blog/authors` | Author index |
| `author` | `/{base_path}/blog/authors/{slug}` | Author profile |

Example: hide landing-page cards on the hub, keep articles.

```css
[data-foundry-page="hub"] [data-foundry-section="pages"] {
  display: none;
}
```

## Chrome

### Header — `[data-foundry-region="header"]`

| `data-foundry-part` | Element |
| --- | --- |
| `inner` | Max-width row |
| `brand` | Logo / site name link |
| `logo` | Logo image |
| `site-name` | Text fallback when there is no logo |
| `nav` | Desktop links |
| `link` | Each nav link (desktop and mobile) |
| `cta` | Header button |
| `search` | Blog search control |
| `search-form` | Expanded search field |
| `menu-button` | Mobile menu toggle |
| `menu` | Mobile drawer |

### Footer — `[data-foundry-region="footer"]`

| `data-foundry-part` | Element |
| --- | --- |
| `inner` | Link columns |
| `brand` | Logo, description, socials |
| `logo` | Footer logo (inverted to white in light theme only) |
| `site-name` | Text fallback |
| `description` | Site description |
| `social` | Social icon row |
| `link-group` | A column of links |
| `heading` | Column title |
| `link` | Footer link |
| `bar` | Bottom bar |
| `copyright` | Copyright line |
| `theme` | Light / dark / auto control (only when color theme is Auto) |
| `credit` | “Powered by Zerply” |

Light theme keeps a dark footer and inverts the logo so a typical dark-on-light mark stays visible. Dark theme uses the page background and shows the logo as uploaded. To force either treatment:

```css
[data-foundry-tenant] {
  --foundry-footer-logo-filter: none;
}
```

To lighten the footer in light theme:

```css
[data-foundry-region="footer"] {
  --foundry-footer-bg: #f4f4f5;
  --foundry-footer-fg: #18181b;
  --foundry-footer-muted: #52525b;
  --foundry-footer-heading: #18181b;
  --foundry-footer-border: #e4e4e7;
  --foundry-footer-logo-filter: none;
}
```

## Hub, blog index, authors

Shared `data-foundry-section` values on listing pages:

| Section | Where |
| --- | --- |
| `intro` | Hub title and description |
| `latest-articles` | Hub and blog index article grids |
| `pages` | Hub landing-page grid |
| `empty` | Empty hub state |
| `featured` | Blog index hero post |
| `category` | Blog index category block (`data-foundry-category="{slug}"`) |

Other hooks:

| Selector | Element |
| --- | --- |
| `[data-foundry-part="recommended"]` | Blog index “Recommended” column |
| `[data-foundry-part="filters"]` | All-articles category chips |
| `[data-foundry-part="category-pills"]` | Category pills on the blog hub and all-articles page |
| `[data-foundry-part="search"]` | Author search |
| `[data-foundry-part="pagination"]` | Page numbers |
| `[data-foundry-part="breadcrumbs"]` | Breadcrumb row |
| `[data-foundry-part="profile"]` | Author header on the author page |
| `[data-foundry-card="blog"]` | Article card |
| `[data-foundry-card="landing"]` | Landing-page card |
| `[data-foundry-card="author"]` | Author card |

## Landing page sections

Each block is `<section data-foundry-section="{type}">`. Inner pieces use `data-foundry-part`.

### `hero`

`inner`, `heading`, `subheading`, `cta`

```css
[data-foundry-tenant] {
  --foundry-hero-bg: #0f172a;
}

[data-foundry-section="hero"] [data-foundry-part="heading"] {
  font-size: 3.5rem;
}
```

### `text`

`inner`, `heading`, `body` (markdown/HTML)

### `features`

`inner`, `item`, `icon`, `title`, `description`

### `faq`

`inner`, `heading`, `item` (`<details>`), `title` (`<summary>`), `description`

### `cta`

`inner`, `heading`, `cta`

```css
[data-foundry-tenant] {
  --foundry-cta-band-bg: #111827;
  --foundry-cta-band-button-bg: var(--brand-fill);
  --foundry-cta-band-button-fg: #ffffff;
}
```

### `testimonials`

`inner`, `heading`, `item`, `quote-mark`, `quote`, `rating`, `author`, `avatar`, `name`, `role`

### `image_text`

`inner`, `media`, `image`, `copy`, `heading`, `description`, `cta`

Also `data-foundry-image-position="left"` or `"right"`.

### `stats`

`inner`, `heading`, `item`, `value`, `label`

### `team`

`inner`, `heading`, `item`, `photo`, `name`, `role`, `bio`

### `contact_details`

`inner`, `heading`, `subheading`, `details`, `address`, `phone`, `email`, `label`, `map`

### `contact_form`

`inner`, `heading`, `subheading`, `form`, `field`, `label`, `input`, `submit`

### `logo_cloud`

`inner`, `heading`, `logos`, `logo`

### `pricing`

`inner`, `heading`, `item`, `name`, `price`, `period`, `features`, `cta`

Featured plan: `[data-foundry-featured="true"]`.

```css
[data-foundry-section="pricing"] [data-foundry-featured="true"] {
  background: var(--brand-fill);
  color: #fff;
}
```

## Blog post — `[data-foundry-page="blog-post"]`

| `data-foundry-part` | Element |
| --- | --- |
| `progress` | Reading progress bar |
| `heading` | Article title |
| `byline` | Author, dates, read time |
| `cover` | Featured image |
| `toc` | Table of contents (mobile card and desktop sidebar) |
| `body` | Article HTML (`.prose`) |
| `table-wrap` | Wrapper around markdown tables (cells wrap; column widths from the editor are kept) |
| `code-block` | Fenced code snippet (`<pre>`, `data-language` when set) |
| `inline-code` | Inline code (`<code>`) |
| `author-card` | “Written by” block |
| `sidebar` | Desktop TOC + sidebar CTA |
| `sidebar-cta` | Mobile sidebar CTA |
| `related` | Related articles |
| `bottom-cta` | Bottom CTA |

Article HTML is normal markdown output: `h2`–`h6`, `p`, `a`, `img`, `blockquote`, lists, `<small class="blog-subtext">` for small text, `.iframe-embed` for video, `.tool-card-embed` for in-article free tools, `[data-foundry-part="table-wrap"]` around tables, `[data-foundry-part="code-block"]` around fenced snippets (syntax-highlighted, with `data-language`), and `[data-foundry-part="inline-code"]` for backtick code.

Blog CTAs from the CTA library:

| Selector | Placement |
| --- | --- |
| `[data-foundry-cta="inline"]` | Inside the article |
| `[data-foundry-cta="sidebar"]` | Sidebar |
| `[data-foundry-cta="bottom"]` | Below the article |
| `[data-foundry-cta] [data-foundry-part="card"]` | The CTA card itself |

## Starter recipes

Load a font and set the typeface:

```css
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap");

[data-foundry-tenant] {
  --foundry-font-sans: "Inter", sans-serif;
}
```

Warm page surface, keep Foundry’s brand buttons:

```css
[data-foundry-tenant] {
  --background: #fffaf5;
  --card: #ffffff;
  --muted: #fff1e6;
  --border: #fed7aa;
}
```

Match a serif article column:

```css
[data-foundry-page="blog-post"] [data-foundry-part="body"] {
  font-family: Georgia, "Times New Roman", serif;
}

[data-foundry-page="blog-post"] [data-foundry-part="heading"] {
  letter-spacing: -0.03em;
}
```

Rounder header button:

```css
[data-foundry-region="header"] [data-foundry-part="cta"] {
  border-radius: 9999px;
  padding-inline: 1.25rem;
}
```

## Limits

- Custom CSS cannot add markup or change which sections exist. Edit the page in Foundry for that.
- Contact forms still submit through Foundry. You can style fields; you cannot change the POST behavior.
- Images in CSS must be absolute `https://` URLs you already host.
- After you save, published pages refresh. If a page looks stale, wait a few seconds and hard-reload.
