Six files. That's it.
These are the exact stylesheets this website is wearing. Not a sanitized example – the real ones, copied out of src/styles at build time so they cannot drift from what you are looking at.
| File | Owns |
|---|---|
fonts.css | @font-face or stylesheet imports and nothing else. |
reset.css | Browser normalization. No classes, by rule. |
theme.css | All three token layers. The only file that knows a color. |
layout.css | The l_* primitives. |
utils.css | The u_* zero-state behaviors. |
generics.css | The g_* global visual objects. |
curl -fsSL --fail-early --create-dirs -o "src/styles/#1.css" "https://beamcss.org/starter/{reset,theme,layout,utils,generics}.css" /* Order is load-bearing: faces before anything
asks for them, resets before tokens, tokens
before anything that reads them. */
@import './fonts.css'; /* skip on system fonts, or when faces load in the head */
@import './reset.css';
@import './theme.css';
@import './layout.css';
@import './utils.css';
@import './generics.css'; @beam-css/postcss-fluid
It turns fluid(min, max) into a clamp() with the slope pre-computed. That is the entire scope of the package.
pnpm add -D @beam-css/postcss-fluid npm install --save-dev @beam-css/postcss-fluid import postcssBeamFluid from '@beam-css/postcss-fluid'
export default {
plugins: [
postcssBeamFluid({
minViewport: '40rem',
maxViewport: '80rem',
tokenFiles: ['src/styles/theme.css'],
}),
],
} /* authored */
.hero_title {
font-size: fluid(var(--text-4xl), var(--text-8xl));
}
/* built */
.hero_title {
font-size: clamp(2.25rem, -1.5rem + 9.375vw, 6rem);
} | Option | Default | What it does |
|---|---|---|
minViewport | 20rem | Viewport width at which the minimum value is reached. |
maxViewport | 80rem | Viewport width at which the maximum value is reached. |
tokenFiles | [] | Stylesheets to scan for --custom-property declarations, so fluid(var(--space-4), var(--space-8)) resolves. |
tokens | {} | Inline token map. Wins over tokenFiles, which is handy in tests. |
precision | 4 | Decimal places in the emitted math. Four is plenty; more is noise. |
Per-call bounds override the project defaults when a single element needs a different curve:
fluid(2rem, 8rem, 20rem, 60rem). Anything the plugin cannot resolve statically –
em, %, a mixed-unit pair, a token that does not exist – throws and fails the
build. That is deliberate. A wrong font size that nobody notices for three months is a worse outcome than
a red pipeline.
pnpm build && ! rg -q "fluid\(" dist The agent skill.
Three markdown files: the rules, the token catalog, and worked examples with their anti-patterns. Drop them where your agent looks for skills and it will write BEAM without being reminded – and review its own diff against the same checklist you would use.
mkdir -p .cursor/skills/beam-css && cd $_
for f in SKILL.md reference.md examples.md; do
curl -sO https://beamcss.org/skill/$f
done | Agent | Where it goes |
|---|---|
| Claude | .claude/skills/beam-css/ |
| Codex | .codex/skills/beam-css/ |
| Cursor | .cursor/skills/beam-css/ |
| Others | Point it at the three files, or paste SKILL.md into your system prompt. |
Your first component.
The whole architecture, in twenty lines. If this reads obvious to you, you already know BEAM – the rest of the specification is just the same idea applied consistently.
<article class="profile_card" data-featured="true">
<img class="profile_card-avatar" src={src} alt="" />
<div class="l_stack" data-gap="1">
<h3 class="profile_card-name">{name}</h3>
<p class="profile_card-role">{role}</p>
</div>
</article> .profile_card {
display: flex;
gap: var(--space-4);
padding: var(--space-4);
border: 1px solid var(--border-base);
border-radius: var(--radius-lg);
background: var(--bg-surface);
}
.profile_card[data-featured='true'] {
border-color: var(--border-focus);
}
.profile_card-avatar {
width: 3rem;
height: 3rem;
border-radius: var(--radius-full);
}
.profile_card-name {
color: var(--ink-main);
font-size: var(--text-base);
font-weight: var(--weight-semibold);
}
.profile_card-role {
color: var(--ink-muted);
font-size: var(--text-sm);
}
Read it once more and notice what is absent. No color. No breakpoint. No dark: anything. No margin
reaching out to push a neighbor around. The card describes itself and nothing else, which is why you can drop
it into a sidebar, a modal or an inverted footer and it will simply behave.