Auf dieser Seite
Building a brand page
A brand page is not "some CSS." It is CSS + JavaScript + structure, and all three are mandatory. Miss any one and the page is broken — usually invisibly, only on mobile, where nobody looks. That single fact is why pages keep shipping wrong. Every page — hand-authored or emitted by a build system — must satisfy all four points below.
- 1
All four CSS layers, in order
tokens.css → base.css → components.css → utilities.css. The order is load-bearing — each layer references the one before. Droppingbase.csssilently flattens every heading to weight 400. - 2
Load
components.js— not optionalIt is part of the system, not an enhancement. The nav's mobile hamburger, the scroll-shadow, Esc-to-close, the accordion, the docnav drawer — none exist without it. If you load the components, you load the JS. There is no JS-free option, and no reason to want one.
- 3
The real chrome, never a copy of it
navandfooterhave a required structure — the nav's.nav-togglebutton and.nav-menuwrapper are the mobile mechanism, not decoration. Don't retype the markup, and never paste the component's own CSS into a page<style>to "make it work" — that's a hand-rolled nav wearing brand class names. - 4
Tokens only
Style off
var(--color-*)/var(--font-*)and the semantic aliases (--fg-*,--bg-*,--shadow-*, …). Never a raw hex or font name.
components.css but not components.js looks perfect on desktop and is broken on mobile. There is no error, no warning — which is exactly why the mistake keeps shipping unnoticed. Point 2 is the one most often dropped.Mobile-first is the whole design — enhance up, never hide down
The brand CSS is mobile-first progressive enhancement. This is a deliberate principle, not an implementation detail — and misreading it is what breaks the nav.
- The base rules ARE the mobile layout. A component's default (no media query) is the smallest-screen state.
@media (min-width: …)blocks then add capability as the screen grows. You build up; you never strip down. - The nav is the canonical example — two independent reveal paths. By default (mobile) the links are
display:noneand the hamburger shows;components.jsreveals them on tap (the JS path). Atmin-width:768pxa media query lays the links out as a horizontal bar and hides the hamburger (the desktop path). - This is why copying nav markup without the toggle + JS breaks it: you inherit the desktop path (the media query lives in
components.css) but delete the mobile path (hamburger + JS). Desktop looks right; mobile has no way to open the menu. The failure is structural, and it is the most common brand-page bug. - For your own layout: author the small screen first, then add
@media (min-width: 640/768/1024/1280)to enhance. Never author desktop-first anddisplay:nonethings away on mobile.
Don't hand-roll — fork the starter
You satisfy the whole contract in one move: fork the standard page
starter. It is composition-only — it already wires the real
nav + footer Chrome, the four CSS layers in
order, and components.js. Swap the copy, set the nav links + CTA,
mark the current link is-current, fill the footer. If you catch
yourself writing <div class="my-nav"> or a footer {}
rule, stop — it already exists.
nav · footer · docnav · announce · breadcrumb.The check
One test catches the failure this whole page is about. Do it every time, on every page, including generated ones.
- 1
Load the page below 768px wide
Real narrow viewport, not a desktop window. 360px is the sanity floor.
- 2
The nav must collapse to a hamburger that opens
Tap it — the links and the CTA must both appear. If they vanish with no way back, you're missing contract point 2 or 3.
- 3
The page must not scroll sideways
One over-wide element makes the whole page pan and pinch-zoom like a canvas — it reads as "broken" on a phone. Wrap wide tables in
.table-wrap; backstop withhtml { overflow-x: clip }.
docnav chrome from JavaScript rather than hand-rolling app navigation.