Naming Principles
Every name in BDS describes a role or slot — not a visual shape — and must match the canonical BEM pattern.
Intent, not shape
Every word in BDS describes a role or a slot. It does not dictate visual shape and does not dictate the HTML element. The HTML element is chosen by semantic intent at the call site.
This distinction is load-bearing for titles and headings — get it wrong and you ship outline-invisible content that looks correct visually. See HTML Semantics for the element-selection rules.
Slot pattern
Per ADR-017, slot names are governed by a structural pattern, not an enumerated list. A bds-* class is canonical if and only if it matches the ADR-008 §4 BEM grammar:
bds-<block>
bds-<block>--<modifier>
bds-<block>__<slot>
bds-<block>__<slot>--<modifier>Every segment is kebab-case (__item-label, never __itemLabel or __item_label). __ separates a slot; -- separates a modifier. No single underscores, no other separators, no doubled __/--, no uppercase.
A well-formed slot is canonical because it is well-formed — there is no registry to maintain and no PR needed to introduce a new one. Only malformed shapes fail.
The gate is scripts/slot-pattern-check.mjs — a pure source scan wired into .husky/pre-commit (staged) and CI (full-tree, via .github/workflows/slot-pattern-check.yml). It supersedes the closed enumerated allowlist, whose enforcing lint (ADR-008 Phase C) never shipped: by 2026-07 only 101 of the 396 slots in use were listed, so enumeration was unpayable. docs/SLOT-ALLOWLIST.md is repurposed from a list into the pattern spec (grammar + examples); the filename is kept to preserve inbound links.
Naming a new slot
- Identify the role the slot expresses; pick the most generic word that fits.
- Grep Slot Vocabulary for an existing slot that already covers the role — reuse before invent.
- Write it kebab-case. A well-formed name passes the gate automatically — no canon edit required.
- Keep it structural, not layout-specific (
bds-hero__title, neverbds-hero__hero-title) and not visual. Cross-block-generic slots (__title,__label,__icon) are expected and fine.
Blueprint naming rules
Blueprints (content-system/blueprints/*) are page-level layouts — the Section layer of the Composition Layers model. Their naming follows the same pattern canon.
- Single namespace. Every class uses
bds-. Thebp-prefix is deprecated — no newbp-*classes after ADR-008. - One block per family.
bds-hero,bds-cta,bds-services,bds-features,bds-about,bds-support-plan. Each family is one block with structural modifiers, not N separate blueprints. - Well-formed slots. Every
bds-{block}__{slot}must match the kebab-case BEM pattern above. The slot-pattern gate fails on malformed shapes, not on new well-formed words. - Structural-only modifiers. Modifier names describe structure (
--split-image,--two-column) — never appearance (--dark,--centered) or theme (--inverse). A "dark centered" CTA themed light makes the name a lie. - Compose, don't reimplement. A blueprint
.tsxthat imports nothing fromcomponents/ui/*is almost always drift. - Use
Framefor aspect-locked images. Never hardcodeaspect-ratioin blueprint CSS.
The bp-* prefix is being migrated to bds-* across existing blueprints — Phase D, one family per PR. Until Phase F, both prefixes coexist.
Related
docs/SLOT-ALLOWLIST.md— the pattern spec (grammar + examples); enforced byscripts/slot-pattern-check.mjs- ADR-017 — why the pattern gate superseded the closed allowlist
- ADR-008 — the naming canon (§1 namespace, §3 structural-only modifiers, §4 grammar); §2's closed allowlist is superseded by ADR-017
- Slot Vocabulary — what each canonical slot means and when to use it