Skip to content
v2026.1

Pure stylesheets.
No required depencencies.

BEAM ships as plain CSS you own, one optional build-time plugin for fluid styling, and a skill for your agents. Nothing else.

01 The global layer

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.

FileOwns
fonts.css@font-face or stylesheet imports and nothing else.
reset.cssBrowser normalization. No classes, by rule.
theme.cssAll three token layers. The only file that knows a color.
layout.cssThe l_* primitives.
utils.cssThe u_* zero-state behaviors.
generics.cssThe g_* global visual objects.
Download all five · run from your project root
curl -fsSL --fail-early --create-dirs -o "src/styles/#1.css" "https://beamcss.org/starter/{reset,theme,layout,utils,generics}.css"
Import them in this order 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';
02 The one dependency

@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
pnpm add -D @beam-css/postcss-fluid
npm
npm install --save-dev @beam-css/postcss-fluid
postcss.config.mjs TSX
import postcssBeamFluid from '@beam-css/postcss-fluid'

export default {
  plugins: [
    postcssBeamFluid({
      minViewport: '40rem',
      maxViewport: '80rem',
      tokenFiles: ['src/styles/theme.css'],
    }),
  ],
}
What you write / what ships 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);
}
OptionDefaultWhat it does
minViewport20remViewport width at which the minimum value is reached.
maxViewport80remViewport 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.
precision4Decimal 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.

Trust, then verify Shell
pnpm build && ! rg -q "fluid\(" dist
03 For the machine

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.

Install into a repo Shell
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
AgentWhere it goes
Claude.claude/skills/beam-css/
Codex.codex/skills/beam-css/
Cursor.cursor/skills/beam-css/
OthersPoint it at the three files, or paste SKILL.md into your system prompt.
04 Ship something

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.

ProfileCard.astro HTML
<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>
ProfileCard.css CSS
.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.