Client-First v3 Class Naming
The class naming, variable, and nesting conventions that govern the CAS.org build: utility versus custom classes, the Base/Theme/Spacing variable system, and the standard page skeleton.
Last Updated: August 12, 2026 | Audience: Developers
What Client-First Is and Why It Governs This Build
CAS.org is built on Client-First v3, a class naming and page structure framework for Webflow. It is not a CSS library you import; it is a set of conventions about how classes are named, how pages are nested, and which decisions belong to a variable rather than a hard-coded value.
The point is that someone who has never opened this site can look at the Navigator, read the class names, and know what each element does. On a 575-page site with 117 components and five secondary locales, that is the difference between a change taking twenty minutes and taking a day.
Two Kinds of Classes
Utility classes
Reusable, single-purpose, used across the whole site. Lowercase, hyphen-separated, no underscore. These are shared, so editing one changes every element that uses it. Check usage before you touch a utility class.
The structural ones you will use constantly:
page-wrapper— wraps the whole page bodymain-wrapper— wraps the main content regionsection_[name]— identifies a page section, e.g.section_heropadding-global— the global left and right page paddingcontainer-large,container-medium,container-small— max-width containerspadding-section-large,padding-section-medium,padding-section-small— vertical section rhythm
Custom classes
Specific to one block of the site, named [identifier]_[element] with a single underscore separating the two halves. Everything after the underscore describes the element's role inside that block. For example docs-hub_header-inner, docs-hub_recent-date, docs-hub_footer-links.
The identifier prefix is what makes a custom class safe to edit: if every class in a block shares one prefix, you know the blast radius of a change is that block.
Naming Rules
- Lowercase only. No capital letters, ever.
- Hyphens separate words. Underscores separate the identifier from the element, and there is only ever one underscore in a class name.
- Name by what the element is, not how it looks.
card_titlenotcard_blue-18px. Visual names go stale the first time the design changes. - No numbers as a versioning device.
hero_wrapper-2tells the next person nothing. - Never leave an element on a class Webflow generated automatically ("Div Block 12", "Heading 4"). Those are the main source of unused-style bloat.
The Variable System
Styling decisions belong in variables, not in the style panel. The site has three variable collections:
- Base — raw primitives: the full colour ramp, the type scale, radii.
- Theme — semantic tokens that point at Base values, e.g. a text colour token rather than a specific grey. Semantic tokens are what make a theme change a one-place edit.
- Spacing — fluid spacing tokens built on
clamp(), so spacing scales with the viewport instead of stepping at breakpoints.
Bind to the semantic token, not the primitive. If you point a heading colour at a Base grey instead of the Theme text token, that heading will not follow a theme change and someone will find it months later.
Hard-coded hex values, pixel font sizes, and one-off margins are the things to avoid. If a value does not exist as a token and you think it should, that is a conversation with Jimmy, not a hex code in the style panel.
Nesting
Client-First expects shallow, predictable nesting. The canonical page skeleton is:
page-wrapper > main-wrapper > section_[name] > padding-global > container-[size] > padding-section-[size] > content
Wrappers exist for a reason and skipping one breaks the rhythm the rest of the site relies on. Equally, adding div layers that carry no class and no purpose is how a site turns into div soup. If you cannot say what a div is for, it should not be there.
Components and Client-First
New components should use Client-First class names internally. Older components predate the convention and carry legacy classes; that is expected and is not something to fix opportunistically, because renaming a class inside a component definition affects every instance.
See the component naming and grouping conventions for how component names themselves are structured. Class naming and component naming are separate systems that happen to share a goal.
Practical Checks Before You Publish
- No auto-generated class names left on any element.
- No hard-coded colours or font sizes where a token exists.
- Custom classes all share the block's identifier prefix.
- Section structure follows the wrapper skeleton.
- You checked usage before editing any shared utility class.