A plate
Sits up out of the canvas. The default for anything interactive or holding content.
Look 12 from Bandana. The kit sheet.
A billboard bolted to an instrument panel. Everything on this page is the real markup from sections and components. If a page built from the look disagrees with this sheet, this sheet wins.
Surfaces
Loud outside, cold inside: the same markup, one attribute apart.
Three surfaces, one library
data-surface="paper | ink | signal"Paper. The native canvas.
Ink. The primary turns signal.
Signal. All text is ink.
Two materials
.bl-raised .bl-recessedPalette
That is the whole palette, and the contrast is solved, not eyeballed.
Four values
--ink --paper --signal --signal-deepEvery app screen. Text on paper and on signal.
The native canvas. Text on ink.
The field, the focus ring, the live pill, the link underline.
Errors, and nothing else.
Text tiers
--text --text-2 --text-3 --text-4Headlines, names, values.
Body. 7.5:1 on the press.
Labels, captions, eyebrows.
Placeholders and decorative glyphs on a plate only.
Type
The poster voice for display, the panel voice for everything else, including every number.
The poster voice
--font-display .bl-display-xl .bl-display .bl-display-mThe panel voice
--font-body .bl-h1 .bl-h2 .bl-h3 .bl-lede .bl-body .bl-meta .bl-micro .bl-eyebrowShape and space
Radii 8, 12, 18, 26 and the pill. Space from 4 to 112.
Shape
--radius-sm 8 --radius-md 12 --radius 18 --radius-xl 26 --radius-pillSpace
--space-1 … --space-9 = 4 8 12 16 24 32 48 72 112Icons
One construction, one weight, one door.
Twelve icons
.bl-icon .bl-icon--lg .bl-icon--xl <use href="#i-name">Components
Hover, focus, pressed, selected, disabled, loading, invalid, open. Inspect them without a pointer.
Buttons
components/buttons.htmlInputs
components/inputs.htmlCards
components/cards.htmlSits up out of the canvas. The default for anything interactive or holding content.
The plate lifts one step and its shadow lengthens. Nothing changes colour.
Pushed into the canvas. The only expression of chosen, active or current.
Badges
components/badges.htmlTabs
components/tabs.htmlAccordion
components/accordion.htmlThe open item is the press. Pushed into the canvas, hairline gone, the plus turned to a dash on an ink dot.
A plate, raised.
No shadow, a hairline, for dense pages.
Modal
components/modal.htmlThe fiftieth copy has sold. Retiring archives the listing for good; every site that bought it keeps it.
Toast
components/toast.htmlTable
components/table.html| Rep | Sessions | Talk ratio | Status |
|---|---|---|---|
| Dana Moreno | 24 | 38% | Coached |
| Chris Mao | 18 | 44% | Recording |
| Natalie Cruz | 31 | 29% | Archived |
| Ravi Sethi | 9 | 51% | Processing |
Motion
Presets only, in motion.css, with a reduced-motion fallback.
Presets
.bl-reveal .bl-stagger .bl-lines .bl-words .bl-rise .bl-hover-lift .bl-page-enter .bl-skeleton .bl-spinner .bl-progressThe switch and the jam
Surfaces cut, no fade. Headlines drop the last of the way and stop dead. Ledes and keys follow.
Loading
Sections
Every section in variant A and variant B, the real markup the demo is built from.
Nav, variant A
sections/nav.htmlNav, variant B
sections/nav.htmlHero, variant A
sections/hero.htmlLook 12 from Bandana
A billboard bolted to an instrument panel. Signal is a locked look for sites built with Claude Code: poster type on a full-bleed field for anything public, the same tokens quiet and dense for anything logged in. One folder, one prompt, fifty copies.
Hero, variant B
sections/hero.htmlLook 12, inner page
The split hero for pricing, about and work pages. No field: the poster line on the left, three panel-voice numbers on the right, one primary.
Feature grid, variant A
sections/feature-grid.htmlThe parts
Every part reads the tokens of the surface it stands on. Set one attribute on a container and the same markup re-tunes: paper, ink or signal.
Surfaces cut from paper to signal on a hard cut. Nothing fades, nothing slides. Off, then on.
The plate sits up out of the canvas. The press is pushed into it. Selected, active and current are always the press. There is no third.
Paper, ink and signal. One component library. No dark variant, no on-accent variant, ever.
Display type at 2rem or more, uppercase, jammed to .88. Never labels, never body, never numbers, even big ones.
Ink, paper, signal, and signal deep. That is the whole palette. Status is carried by weight and material, never by hue.
Sold fifty times, then retired for good. A new look takes the slot. Yours is numbered.
Feature grid, variant B
sections/feature-grid.htmlThe parts
Bento, variant A
sections/bento.htmlCold inside
The same tokens, quiet and dense, for anything logged in. Fifteen-pixel body, tabular numbers, one primary per view.
Kitchen remodel. 24 min. Yesterday.
Copies, then retired.
Numbers are set in the panel voice, never the poster voice.
Same markup, ink surface.
The primary inverts to signal on ink. Nothing else changes.
The field.
The signal surface is a moment, not a mode. Once per page.
One look. Three for $300, five for $425.
Installed with one command and one pasted prompt.
Bento, variant B
sections/bento.htmlLoud outside.
The field, wide. One moment per page.
Materials, and no third.
The plate and the press.
Gallery, variant A
sections/gallery.htmlThe world
Everything below is drawn from the tokens. No stock, no filler. The caption plate is the kit's own: dark glass, one line, one number.
The billboard at dusk.
Three panels lit from inside on one field.
The instrument panel.
Quiet, dense, one signal reading.
The poster voice.
Cut by the frame, never below 2rem.
One primary per view.
Ink on signal. If a screen needs two, the screen is wrong.
The marquee.
Display type between two hairlines, running.
The plate and the press.
Up out of the canvas, and pushed into it.
Gallery, variant B
sections/gallery.htmlThe billboard at dusk.
Wide, two to a row, for work pages.
The marquee.
Between two hairlines, on ink.
Pricing, variant A
sections/pricing.htmlEditions
Every look is sold fifty times and then archived for good. A new look is built to take its slot. The one you buy is numbered.
$125
Installs with one command and one pasted prompt.
$300$100 a look
Twenty percent off the single price.
$425$85 a look
Thirty-two percent off the single price.
No free tier, no subscription, no whole-rack bundle. Prices in US dollars.
Pricing, variant B
sections/pricing.html$125
Get Signal, $125Three looks for $300, five for $425. No free tier, no subscription.
Testimonial, variant A
sections/testimonial.htmlThe rules
The constraints of the direction, in the kit's own words. They ship in CLAUDE.md and the buyer's Claude obeys them.
The signal surface is a moment, not a mode. One per page, at most. Using it twice halves it.
One primary per view. If a screen seems to need two, the screen is wrong, not the kit.
No semantic green, amber or blue. Status is carried by weight and material, not by hue.
Display type is for display only. Never labels, never body, never numbers, even big ones.
A second icon set is the most common way a system starts to look assembled rather than designed.
Testimonial, variant B
sections/testimonial.htmlLoud outside, cold inside. Same system, one attribute apart.
Faq, variant A
sections/faq.htmlQuestions
Everything a buyer asks before the first install, answered in the look's own terms.
One folder. CLAUDE.md is the product: the rules your Claude obeys. Beside it, theme.css with every token and class, motion.css with the presets, eleven sections in two variants, ten components with every state drawn, the kit sheet, this demo, and the fonts.
Run npx bandana add signal --key YOUR-KEY in your project, then paste the starter prompt from the README into Claude Code. It reads CLAUDE.md and builds from the sections and components, nothing else.
No, and that is the point. Four values are the whole palette. Adding a fifth colour is a kit change, not an app decision. What you can change is the surface: set data-surface to paper, ink or signal on any container and everything inside re-tunes.
Signal is retired for good. It stays live on every site that bought it, and nobody else ever gets it. A new look is built to take slot 12.
Yes. A copy covers the sites you build with it. What you cannot do is resell the folder, redistribute the fonts, or ship the look as a theme of your own.
Paper is native. Set data-scheme="dark" and the whole page reads the ink surface, or auto to follow the system. The field stays signal in both. Only colour tokens change.
Faq, variant B
sections/faq.htmlQuestions
Because it is the loudest thing the system can do, and using it twice halves it. The hero takes it. Everything else is paper or ink.
A field is a well you type into, and every Bandana look draws fields as its recessed material. The kit Signal was built from raised its fields; the look departs from the kit there, on purpose.
Cta, variant A
sections/cta.htmlEdition of fifty
Signal, Look 12 from Bandana. One folder, one prompt, one numbered copy. $125.
Cta, variant B
sections/cta.htmlThe drop list
Contact form, variant A
sections/contact-form.htmlWrite
Fields are the press: you type into a well. The one key on the form is the primary. Nothing else on the plate is raised.
Contact form, variant B
sections/contact-form.htmlWrite
Footer, variant A
sections/footer.htmlFooter, variant B
sections/footer.htmlTokens
Every custom property in theme.css with its native value.
Every token, native values
[data-look="signal"] { … }| Token | Paper (native) |
|---|---|
| --ink | #0B0B0C |
| --paper | #F4F2ED |
| --signal | #FF3B14 |
| --signal-deep | #D42B08 |
| --signal-tint | #FF5A38 |
| --bg | #F4F2ED |
| --surface | #FFFFFF |
| --surface-2 | #E6E3DB |
| --text | #0B0B0C |
| --text-2 | #46453F |
| --text-3 | #5F5E57 |
| --text-4 | #78776F |
| --line | rgba(11, 11, 12, 0.13) |
| --line-2 | rgba(11, 11, 12, 0.06) |
| --accent | #FF3B14 |
| --accent-ink | #0B0B0C |
| --accent-line | rgba(255, 59, 20, 0.45) |
| --accent-glow | rgba(255, 59, 20, 0.22) |
| --act-fill | #0B0B0C |
| --act-text | #F4F2ED |
| --act-fill-hov | #23232A |
| --focus | #FF3B14 |
| --ok | #0B0B0C |
| --warn | #46453F |
| --err | #D42B08 |
| --raised-bg | #FFFFFF |
| --raised-border | rgba(11, 11, 12, 0.10) |
| --raised-hi | inset 0 1px 0 rgba(255, 255, 255, 0.90) |
| --raised-in | inset 0 -1px 0 rgba(11, 11, 12, 0.05) |
| --raised-drop | 0 1px 2px rgba(11, 11, 12, 0.05), 0 10px 28px -14px rgba(11, 11, 12, 0.22) |
| --raised-drop-up | 0 2px 4px rgba(11, 11, 12, 0.06), 0 18px 40px -16px rgba(11, 11, 12, 0.30) |
| --raised-shadow | var(--raised-hi), var(--raised-in), var(--raised-drop) |
| --raised-shadow-up | var(--raised-hi), var(--raised-in), var(--raised-drop-up) |
| --recessed-bg | #E6E3DB |
| --recessed-hi | inset 0 1px 0 rgba(255, 255, 255, 0.65) |
| --recessed-in | inset 0 2px 6px rgba(11, 11, 12, 0.11) |
| --recessed-shadow | var(--recessed-hi), var(--recessed-in) |
| --glass | color-mix(in srgb, var(--bg) 78%, transparent) |
| --blur | 14px |
| --pattern | linear-gradient(180deg, #FF5A38 0%, #FF3B14 38%, #D62C0A 100%) |
| --pool | radial-gradient(70% 70% at 62% 18%, rgba(255, 176, 138, 0.22), rgba(255, 176, 138, 0) 100%) |
| --hero-text | #0B0B0C |
| --hero-text-2 | rgba(11, 11, 12, 0.72) |
| --font-display | "Anton", "Haettenschweiler", "Arial Narrow", sans-serif |
| --font-body | "Inter Tight", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif |
| --display-weight | 400 |
| --text-display-xl | clamp(3.5rem, 13.5vw, 11rem) |
| --text-display | clamp(2.75rem, 8vw, 6rem) |
| --text-display-m | clamp(2rem, 4.5vw, 3.25rem) |
| --text-h1 | clamp(1.75rem, 3vw, 2.5rem) |
| --text-h2 | 1.5rem |
| --text-h3 | 1.125rem |
| --text-lede | clamp(1rem, 1.6vw, 1.25rem) |
| --text-md | 0.9375rem |
| --text-sm | 0.8125rem |
| --text-xs | 0.75rem |
| --text-micro | 0.6875rem |
| --text-price | clamp(2.5rem, 5vw, 3.75rem) |
| --track-caps | 0.14em |
| --leading-display | 0.88 |
| --leading-body | 1.55 |
| --radius | 18px |
| --radius-xl | 26px |
| --radius-md | 12px |
| --radius-sm | 8px |
| --radius-pill | 999px |
| --rule | 1px |
| --space-1 | 4px |
| --space-2 | 8px |
| --space-3 | 12px |
| --space-4 | 16px |
| --space-5 | 24px |
| --space-6 | 32px |
| --space-7 | 48px |
| --space-8 | 72px |
| --space-9 | 112px |
| --wrap | 1240px |
| --control | 44px |
| --control-sm | 34px |
| --icon | 18px |
| --dur-fast | 150ms |
| --dur | 320ms |
| --dur-slow | 560ms |
| --ease | cubic-bezier(0.2, 0.7, 0.2, 1) |
| --ease-jam | cubic-bezier(0.1, 0.9, 0.1, 1) |
| --reveal-y | 0.4em |