The meter
At rest. Lifts on hover.
Look 04, the kit sheet
Nothing in the red. Everything the look is made of, on one page. Every block below is the real markup from sections/ and components/, so if a page built from the look disagrees with this sheet, this sheet wins.
Palette
--bg --surface --surface-2 --text --accent#070A09#121A16#0C110F#D3E9DA#7EDBA5#071A11#7EDBA5#E3C77A#E08080Decoration only. The haze and the grain over everything, the pool of meter light under a key, the lip and the deep green. The forest is a film and appears in hero A alone. Never behind text.
linear-gradient(180deg, #0E1613, #070A09)radial-gradient(50% 40% at 50% 100%, rgba(126, 219, 165, 0.30), rgba(126, 219, 165, 0))inlinedType
Control Meter is the original face drawn for this look and ships in fonts/. The scale is closed: eyebrow, display, h2, lede, body, meta, price.
Nothing in the red.
Every level, set once.
$125one of fifty
A look for sites built with Claude Code. A black desk at night, a forest moving above it, rubber keys and the slots they press into, one cold green hit per screen.
Raised is soft-touch rubber on a machined lip. Recessed is the slot it presses into. There is no third material, and state is depth, never a colour.
Look 04, an edition of fifty
Materials
Icons
24-unit grid, one two-unit stroke, round caps, currentColor, no fill: the symbol printed beside a control. Use inline as <svg class="bl-icon"><use href="#i-name"/></svg> or as the files in assets/icons/.
Motion
Everything arrives the way a meter answers a hit: fast attack, one overshoot, a damped settle. Headlines kick in word by word (.bl-words). Blocks rise into place (.bl-reveal, staggered by .bl-stagger). Eyebrows and ledes follow (.bl-rise). The needle swings and settles on its own (.bl-meter__needle). The lamp breathes (.bl-lamp-breathe). Keys lift on hover and sink when pressed. Reduced motion lands everything instantly.
.bl-reveal .bl-words .bl-rise .bl-rise--x .bl-rise--late .bl-hover-lift .bl-lamp-breatheReplay
Nothing in the red.
Click to play it again.
.bl-skeleton .bl-spinner .bl-progressComponents
Helper classes (.is-hover, .is-focus, .is-active, .is-selected, .is-disabled, .is-loading, .is-invalid, .is-open, .is-checked) draw each state without a pointer. theme.css styles the helper and the real pseudo-class identically.
Buttons are rubber keys on a machined lip. The primary carries the lit green edge and is the one hit per screen. Hover lifts the key and leaks a little light from the slot; pressed sinks it into the slot. Loading swaps the label for a spinner.
components/buttons.htmlFields are slots. Focus brings the green up inside the slot from the bottom edge; invalid draws a red line along it; disabled dims. The checkbox is a small slot with a lamp in it.
components/inputs.htmlThat does not look like an email.
No mailing list. We only write back.
Cards are raised modules with recessed media. Media is the pool, the meter or an icon on the pattern, never a photograph. Hover lifts; selected sinks the whole card into the desk.
components/cards.htmlAt rest. Lifts on hover.
Hover, drawn.
Selected, recessed.
Badges are small slots with a lamp. The plain badge is a dim lamp; ok, warn and err light it. They are the only place the status colours appear besides toasts and field errors.
components/badges.htmlTabs are keys in a raised strip. The active tab is recessed. Hover brightens, focus rings in the accent line, disabled dims.
components/tabs.htmlThe accordion is a stack of raised keys. The open item sinks into a well and its plus becomes a minus.
components/accordion.htmlFifty sites get to wear Ground Control. Yours is one of them, with its own edition number and licence key.
CLAUDE.md is a set of rules with teeth. If a part does not exist, Claude stops and says so.
Something has to be moving above the desk.
The modal is a raised module over a scrim. The static modifier renders it inline on the sheet, in a well with the pool behind it.
components/modal.htmlWhen the fiftieth copy sells, Ground Control is archived for good and a new look takes its place on the rack. This cannot be undone.
Toasts are small raised keys with a lamp. Plain, ok, warn and err. The static modifier renders them inline.
components/toast.htmlThe table is a channel list in a well. Numbers are set in Control Meter Regular and ranged right. Hover brightens a row; selected raises it out of the well.
components/table.html| Look | Status | Copies | Left |
|---|---|---|---|
| Aura Glow | Edition open | 50 | 43 |
| Radio | Edition open | 50 | 50 |
| Ground Control | Twelve left | 50 | 12 |
| Plinth | Archived | 50 | 0 |
Sections
Variant A is what the demo uses. Variant B is the alternative for the same job. Page recipes are in CLAUDE.md.
Variant A
Variant B
The opening screen. A is the film: the top of the forest at night, smoke moving through the crowns, looping behind the headline, with the drawn meter and three stats on a module rail beside it. B is the split hero for inner pages: headline left, the meter module right, no film. Headlines use .bl-words so they kick in word by word.
sections/hero.htmlVariant A
Look 04 from Bandana
A black desk at night, every level set, one meter lit. Ground Control is a locked look for sites built with Claude Code: one folder, one prompt, fifty copies.
Variant B
Look 04, inner page
The split hero. Headline on the left, the meter on the right, one lit key. For pricing, about and work pages.
Three or six things. A is the icon grid: modules on the desk, each with an icon in a recessed well, a number in Control Meter, a title and a paragraph. B is the numbered two-column list for denser pages, no icons.
sections/feature-grid.htmlVariant A
The parts
A look is one folder. Everything in it obeys one file, and the file is not negotiable.
Soft-touch rubber on a machined lip, and the slot it presses into. Buttons are raised, fields are recessed, and anything selected sinks. State is depth, never a colour.
The accent is the meter's green, and it lands once per screen, on the primary key. Nothing else on the page is lit.
An original display face, condensed and rounded like a console legend, drawn from scratch and bundled only. Headlines, prices, big numbers. Never a paragraph.
The symbols printed beside a control: fader, needle, knob, jack, pad, reel, sub, patch, cue, wave, mic, cans. One drawing each, none a variation of another.
Everything arrives the way a meter answers a hit: fast attack, one overshoot, a damped settle. Presets only. Nothing is animated in a page.
Native is the desk at night. Lights on is the same desk with the room lit. Only the colour tokens change; nothing else does.
Variant B
The rules
One green, one hit per screen. Status colours live on badges, toasts and field errors and nowhere else.
Rubber that is raised, a slot that is recessed. No flat, no outlined, no glass.
The legend face is for headlines, prices and big numbers. Reading is IBM Plex Sans.
The film sits behind the headline in hero A and nowhere else. Body copy never sits on it.
Headlines sit left on the desk. Nothing is centred by default.
Presets only. The needle ease is the look's and it lives in motion.css.
The parts, unevenly. A is the wide materials tile plus the legend face, the meter, the pool and the three status lamps. B is three even tiles, each with the pool as art, for a lighter page.
sections/bento.htmlVariant A
The rules, made visible
The key has a grain, a lip and a shadow. Press it and it sinks into the slot. Every field is a slot too, and the green comes up inside it on focus.
Regular for prices and stats, Bold for headlines and the mark.
Drawn in the theme, needle live. One per page, never behind text.
The one gradient. Hero and CTA backdrops, tile art, card media. Never behind a paragraph.
Ok, warn and err exist for badges, toasts and field errors, and nowhere else. They are never the accent.
Variant B
Three tiles
CLAUDE.md. Nine sections, numbered rules, page recipes, a starter prompt.
theme.css and motion.css. Every token, every class, both schemes.
Eleven sections, ten components, the kit sheet and this demo.
Work, products, presets. A is six portrait tiles, each a part of the desk drawn in CSS with a caption and a code. B is wide tiles, two per row, for landscape pieces.
sections/gallery.htmlVariant A
The desk, close up
Variant B
Wide
Plans. A is three plans with the middle one chosen, which is recessed into the desk and carries the one lit key on the screen. B is two plans.
sections/pricing.htmlVariant A
Editions
Every look on the rack is sold fifty times and archived. No reprints, no free tier, no second run.
$125Ground Control
$300any three
$425any five
Variant B
Editions
One voice. A is one big quote on a module, set in Control Meter Bold, offset left. B is three quote cards in a row.
sections/testimonial.htmlVariant A
It refuses a second accent. That is the whole trick.
Variant B
Buttons are raised. Fields are recessed. That is the whole material system.
Display face for display only. Never a paragraph in Control Meter.
If a part you need does not exist, stop and say so.
Questions. A is the split: the head on the left, an accordion of raised keys on the right, the open one sunk into a well. B is a two-column grid with every answer visible.
sections/faq.htmlVariant A
Questions
Short answers. The long ones are in the file.
Variant B
Questions
One folder: the file, the two stylesheets, the face, the sections, the components, the icons, the tile, the film and the kit sheet.
Yes. Put the folder in, set data-look, link the stylesheets, paste the prompt.
No. If you want another colour, you want another look.
The look is archived. The fifty owners keep it forever.
Licensed for sites wearing Ground Control, never sold apart.
Lights on. Set data-scheme to light, or auto to follow the system.
The ask. A is the band: a module with the pool rising from the bottom, headline, lede and the one lit key. B is the compact bar for the end of an inner page.
sections/cta.htmlVariant A
Look 04
Fifty copies. When they are gone, Ground Control is archived and the rack moves on.
Variant B
Variant A
Variant B
Write to us. A is the split, head on the left and the fields on the right, every field a slot. B is the whole form in a raised module for a contact page of its own.
sections/contact-form.htmlVariant A
Write to us
Tell us what you are building and which looks you have your eye on. We answer within a day.
Variant B
Write to us
Tokens
Native values first; the light scheme overrides only the colour tokens. The same list is in theme.json.
| Token | Group | Native | light |
|---|---|---|---|
| --bg | canvas | #070A09 | #E3E6E1 |
| --surface | canvas | #121A16 | #EEF0EC |
| --surface-2 | canvas | #0C110F | #D6DAD4 |
| --text | canvas | #D3E9DA | #10201A |
| --text-2 | canvas | rgba(211, 233, 218, 0.62) | rgba(16, 32, 26, 0.66) |
| --text-3 | canvas | rgba(211, 233, 218, 0.38) | rgba(16, 32, 26, 0.42) |
| --line | canvas | rgba(211, 233, 218, 0.10) | rgba(16, 32, 26, 0.10) |
| --accent | accent | #7EDBA5 | #2F8A5E |
| --accent-ink | accent | #071A11 | #EAF7EF |
| --accent-line | other | rgba(126, 219, 165, 0.42) | rgba(47, 138, 94, 0.45) |
| --accent-glow | other | rgba(126, 219, 165, 0.28) | rgba(47, 138, 94, 0.22) |
| --deep | other | #3E8C68 | #3E8C68 |
| --lip | other | #6F7D75 | #8C948E |
| --lip-dark | other | #2A3330 | #B4BAB5 |
| --lip-line | other | rgba(111, 125, 117, 0.26) | rgba(16, 32, 26, 0.18) |
| --haze | other | radial-gradient(60% 50% at 45% 62%, rgba(62, 140, 104, 0.22), rgba(62, 140, 104, 0)) | radial-gradient(60% 50% at 45% 62%, rgba(62, 140, 104, 0.12), rgba(62, 140, 104, 0)) |
| --grain-opacity | other | 0.07 | 0.05 |
| --hero-text | other | #D3E9DA | |
| --hero-text-2 | other | rgba(211, 233, 218, 0.66) | |
| --hero-scrim | other | linear-gradient(180deg, rgba(7, 10, 9, 0.10) 0%, rgba(7, 10, 9, 0.35) 55%, rgba(7, 10, 9, … | |
| --module-bg | other | linear-gradient(180deg, #141C18, #0E1411) | linear-gradient(180deg, #F2F4F0, #E6E9E4) |
| --module-shadow | other | inset 0 1px 0 rgba(111, 125, 117, 0.28), inset 0 -1px 0 rgba(0, 0, 0, 0.8), 0 30px 60px -3… | inset 0 1px 0 #FFFFFF, inset 0 -1px 0 rgba(16, 32, 26, 0.16), 0 30px 60px -30px rgba(16, 3… |
| --dial | other | #0B1410 | #101A15 |
| --dial-light | other | radial-gradient(100% 110% at 30% 105%, #7EDBA5 0%, #3E8C68 28%, #1B3A2F 62%, #0C1512 100%) | radial-gradient(100% 110% at 30% 105%, #7EDBA5 0%, #3E8C68 28%, #1B3A2F 62%, #0C1512 100%) |
| --dial-shade | other | linear-gradient(90deg, rgba(5, 8, 7, 0) 35%, rgba(5, 8, 7, 0.82) 100%) | |
| --dial-ink | other | #D3E9DA | #D3E9DA |
| --pattern | aura | linear-gradient(180deg, #0E1613, #070A09) | linear-gradient(180deg, #D6DAD4, #E3E6E1) |
| --pool | aura | radial-gradient(50% 40% at 50% 100%, rgba(126, 219, 165, 0.30), rgba(126, 219, 165, 0)) | radial-gradient(50% 40% at 50% 100%, rgba(47, 138, 94, 0.22), rgba(47, 138, 94, 0)) |
| --grain | aura | url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='1… | |
| --ok | status | #7EDBA5 | #2F8A5E |
| --warn | status | #E3C77A | #9A7A1E |
| --err | status | #E08080 | #B54A4A |
| --raised-bg | materials | linear-gradient(180deg, #26302B 0%, #161D19 48%, #10161300 48.5%, #0F1512 100%), #121815 | linear-gradient(180deg, #FBFCFA 0%, #ECEFEA 48%, #E6E9E400 48.5%, #DFE3DE 100%), #E8EBE6 |
| --raised-shadow | materials | inset 0 1px 0 rgba(255, 255, 255, 0.09), inset 0 -2px 0 rgba(0, 0, 0, 0.65), inset 1px 0 0… | inset 0 1px 0 #FFFFFF, inset 0 -2px 0 rgba(16, 32, 26, 0.14), 0 0 0 1px var(--lip-dark), 0… |
| --raised-shadow-up | materials | inset 0 1px 0 rgba(255, 255, 255, 0.12), inset 0 -2px 0 rgba(0, 0, 0, 0.65), 0 0 0 1px var… | inset 0 1px 0 #FFFFFF, inset 0 -2px 0 rgba(16, 32, 26, 0.14), 0 0 0 1px var(--lip-dark), 0… |
| --raised-hit | materials | inset 0 1px 0 rgba(255, 255, 255, 0.09), inset 0 -2px 0 rgba(0, 0, 0, 0.65), 0 0 0 1px rgb… | inset 0 1px 0 #FFFFFF, inset 0 -2px 0 rgba(16, 32, 26, 0.14), 0 0 0 1px rgba(47, 138, 94, … |
| --raised-sheen | materials | linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0)) | linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0)) |
| --raised-grain-opacity | materials | 0.09 | 0.05 |
| --recessed-bg | materials | linear-gradient(180deg, #030504 0%, #070B09 30%, #0B110E 100%) | linear-gradient(180deg, #C4C9C3 0%, #D0D4CE 30%, #D8DCD6 100%) |
| --recessed-shadow | materials | inset 0 2px 0 rgba(0, 0, 0, 0.95), inset 0 10px 18px -4px rgba(0, 0, 0, 0.9), inset 0 -1px… | inset 0 2px 0 rgba(16, 32, 26, 0.22), inset 0 10px 18px -4px rgba(16, 32, 26, 0.28), inset… |
| --recessed-shadow-deep | materials | inset 0 3px 0 rgba(0, 0, 0, 0.95), inset 0 14px 26px -6px rgba(0, 0, 0, 0.92), inset 0 -1p… | inset 0 3px 0 rgba(16, 32, 26, 0.24), inset 0 14px 26px -6px rgba(16, 32, 26, 0.3), inset … |
| --recessed-lit | materials | inset 0 2px 0 rgba(0, 0, 0, 0.95), inset 0 10px 18px -4px rgba(0, 0, 0, 0.9), inset 0 -1px… | inset 0 2px 0 rgba(16, 32, 26, 0.22), inset 0 10px 18px -4px rgba(16, 32, 26, 0.28), inset… |
| --recessed-rule | materials | linear-gradient(90deg, transparent, rgba(111, 125, 117, 0.25), transparent) | linear-gradient(90deg, transparent, rgba(16, 32, 26, 0.18), transparent) |
| --scrim | materials | rgba(3, 5, 4, 0.72) | rgba(227, 230, 225, 0.78) |
| --chevron | materials | url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'… | url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'… |
| --font-display | type | "Control Meter", "IBM Plex Sans Condensed", "Arial Narrow", sans-serif | |
| --font-body | type | "IBM Plex Sans", system-ui, sans-serif | |
| --display-weight | type | 700 | |
| --text-xs | type | .75rem | |
| --text-sm | type | .875rem | |
| --text-md | type | 1.0625rem | |
| --text-lg | type | 1.1875rem | |
| --text-xl | type | 1.5rem | |
| --text-h3 | type | 1.75rem | |
| --text-h2 | type | clamp(2.4rem, 4.6vw, 4rem) | |
| --text-display | type | clamp(3.4rem, 9.4vw, 8.5rem) | |
| --text-price | type | 3rem | |
| --track-caps | type | .16em | |
| --leading-tight | type | .92 | |
| --leading-body | type | 1.55 | |
| --radius | shape | 14px | |
| --radius-sm | shape | 10px | |
| --radius-pill | shape | 999px | |
| --rule | shape | 1px | |
| --space-1 | space | .25rem | |
| --space-2 | space | .5rem | |
| --space-3 | space | .75rem | |
| --space-4 | space | 1rem | |
| --space-5 | space | 1.5rem | |
| --space-6 | space | 2rem | |
| --space-7 | space | 3rem | |
| --space-8 | space | 4.5rem | |
| --space-9 | space | 7rem | |
| --wrap | space | 1200px | |
| --control | space | 50px | |
| --control-sm | space | 38px | |
| --icon | space | 22px | |
| --dur-fast | motion | 160ms | |
| --dur | motion | 420ms | |
| --dur-slow | motion | 900ms | |
| --dur-needle | motion | 1100ms | |
| --ease | motion | cubic-bezier(.2, .7, .2, 1) | |
| --ease-needle | motion | cubic-bezier(.18, 1.35, .32, 1) | |
| --reveal-y | motion | 16px |