A plate
Sits up out of the canvas. The default for anything interactive or holding content.
Look 17 from Bandana. The kit sheet.
A cassette on a sky of one pigment, 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
Deep outside, cold inside: the same markup, one attribute apart.
Three surfaces, one library
data-surface="paper | ink | pigment"Paper. The native canvas.
Ink. The primary turns pigment.
Pigment. All text is paper.
Two materials
.bl-raised .bl-recessedPalette
That is the whole palette, and the contrast is solved, not eyeballed.
Four values
--ink --paper --pigment --pigment-deepEvery app screen. Text on paper. It never stands on the pigment.
The native canvas. Text on ink and on the pigment.
International Klein Blue. 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 17 from Bandana
A cassette on a sky of one pigment, bolted to an instrument panel. Cassette Sky is a locked look for sites built with Claude Code: poster type on a full-bleed field of Klein blue 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 17, 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 pigment.
Surfaces cut from paper to pigment 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 pigment. 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, pigment, and pigment 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 turns pigment on ink, its text paper. Nothing else changes.
The cassette, on the field.
The pigment 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.htmlDeep 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 cassette.
One shell lit from inside, on a sky of Klein blue.
The instrument panel.
Quiet, dense, one pigment reading.
The poster voice.
Cut by the frame, never below 2rem.
One primary per view.
Paper on pigment. 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 cassette.
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 Cassette Sky, $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 pigment 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 red. 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.htmlDeep outside, cold inside. Signal's system, one pigment.
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 cassette-sky --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 pigment on any container and everything inside re-tunes. On the pigment, everything is paper.
Cassette Sky 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 17.
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 pigment 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 Signal kit this system comes from raised its fields; Cassette Sky departs from it there, on purpose, as Signal did.
Cta, variant A
sections/cta.htmlEdition of fifty
Cassette Sky, Look 17 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="cassette-sky"] { … }| Token | Paper (native) |
|---|---|
| --ink | #0B0B0C |
| --paper | #F4F2ED |
| --pigment | #002FA7 |
| --pigment-deep | #001F72 |
| --pigment-tint | #2E5FE3 |
| --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 | #002FA7 |
| --accent-ink | #F4F2ED |
| --accent-line | rgba(0, 47, 167, 0.45) |
| --accent-glow | rgba(0, 47, 167, 0.22) |
| --act-fill | #0B0B0C |
| --act-text | #F4F2ED |
| --act-fill-hov | #23232A |
| --focus | #002FA7 |
| --ok | #0B0B0C |
| --warn | #46453F |
| --err | #001F72 |
| --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, #2E5FE3 0%, #002FA7 38%, #002285 100%) |
| --pool | radial-gradient(70% 70% at 62% 18%, rgba(157, 184, 255, 0.22), rgba(157, 184, 255, 0) 100%) |
| --hero-text | #F4F2ED |
| --hero-text-2 | rgba(244, 242, 237, 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 |