Visual System
State of Stick — Visual System
Section titled “State of Stick — Visual System”This is the technical reference. Every color, type, and component pattern shipped in the codebase is documented here with its Tailwind class, its CSS variable, and its intent. The implemented tokens are the source of truth — the values below match what’s in src/styles/global.css.
When you need to make a styling decision, look here first. If you can’t find a token for what you need, the answer is probably “you don’t need a new token, use an existing one.”
Color system
Section titled “Color system”Foundation (dark base — 65% of any composition)
Section titled “Foundation (dark base — 65% of any composition)”| Token | Hex | Tailwind | Use |
|---|---|---|---|
--color-ink | #07090a | bg-ink text-ink | Page background, deepest base. The canvas. |
--color-ink-2 | #0e1113 | bg-ink-2 | Sections that sit on bg-ink. Slightly raised. |
--color-ink-3 | #15191c | bg-ink-3 | Inset elements (badges, chips, inputs). |
Rule: Never use pure black (#000). The brand black is --color-ink. It’s warmer and lets us layer ink-2 / ink-3 without losing depth.
Neutrals (silver / steel — 20%)
Section titled “Neutrals (silver / steel — 20%)”| Token | Hex | Tailwind | Use |
|---|---|---|---|
--color-steel-50 | #f5f6f7 | text-steel-50 | Headline white. Maximum readability. |
--color-steel-100 | #e1e3e5 | text-steel-100 text-metal | Default body text, primary readable color. |
--color-steel-200 | #c4c8cb | text-steel-200 | Strong body / list items. |
--color-steel-300 | #9ea2a6 | text-steel-300 | Secondary copy, descriptions, lede paragraphs. |
--color-steel-400 | #6f7479 | text-steel-400 | Muted text, fine print, captions. |
--color-steel-500 | #4a4f53 | text-steel-500 border-steel-500 | Hover border state, disabled text. |
--color-steel-600 | #2f3337 | border-steel-600 | Default panel border on darker panels. |
--color-steel-700 | #1e2124 | border-steel-700 | Subtle dividers, default card border. |
Class alias: text-metal = text-steel-100. Use text-metal semantically for product names and brand-voice headlines.
Accent — Rust / Impact Orange (10% — primary action)
Section titled “Accent — Rust / Impact Orange (10% — primary action)”| Token | Hex | Tailwind | Use |
|---|---|---|---|
--color-rust | #e85d2f | text-rust bg-rust border-rust | Primary CTAs, pricing emphasis, key icons, dividers, sales-critical highlights. |
--color-rust-bright | #ff7a3d | text-rust-bright | Hover state on rust elements. |
--color-rust-deep | #b8431f | text-rust-deep | Pressed / active state. Rare. |
This is the action color. Buttons that convert use rust. Prices use rust. Stat numbers use rust. If a piece of UI is meant to drive a click or read as money, it’s rust.
Accent — Precision Cyan (5% — info / premium tech)
Section titled “Accent — Precision Cyan (5% — info / premium tech)”| Token | Hex | Tailwind | Use |
|---|---|---|---|
--color-precision | #0abab5 | text-precision bg-precision border-precision | Secondary accent, info labels, instructional callouts, premium-tech moments. |
--color-precision-bright | #5fe3dd | text-precision-bright text-precision-shine | Highlights inside headlines, hover state, glow. |
--color-precision-deep | #067e7a | border-precision-deep | Pressed state on precision elements. |
Precision Cyan is the cool counterweight. Use it when:
- The section is informational (FAQ, how-it-works, instructions)
- The moment is premium-tech (digital layer, certificates, NFC/QR)
- A headline needs a single highlighted phrase (
text-precision-shine) - A secondary button needs to feel premium without competing with the primary rust CTA
- A label introduces a non-sales section
Never use Precision Cyan for:
- Primary sales CTAs (use rust)
- Pricing (use rust)
- Dominant background blocks
- Replacing rust as the brand’s energy color
The 65 / 20 / 10 / 5 rule
Section titled “The 65 / 20 / 10 / 5 rule”Every composition should roughly hit:
- 65% dark base —
bg-ink,bg-ink-2,bg-ink-3and their textured variants - 20% steel / white — readable text, neutral borders
- 10% rust — action, money, key emphasis
- 5% precisionany — info, premium-tech, single highlighted moments
If a page feels off, check the ratio. The most common drift is too much Precision Cyan.
Textures and backgrounds
Section titled “Textures and backgrounds”Layered patterns are part of the brand. Use them deliberately — they add weight to sections that deserve it. Don’t apply them everywhere or the page becomes noise.
| Class | Use |
|---|---|
bg-hex | Subtle hexagonal pattern. Use behind heroes and section openers. Pair with opacity-25 to keep it subtle. |
bg-grunge | Distressed texture. Use on full-width “moat” sections where you want industrial weight. |
bg-ink-2 | Flat dark panel. Use for content sections where texture would compete with the content. |
| Radial gradient overlays | bg-[radial-gradient(circle_at_70%_30%,rgba(10,186,181,0.22),transparent_60%)] — use sparingly behind hero badges or premium moments. |
Rule: A page should have at least one textured section. It should not have all textured sections.
Typography
Section titled “Typography”Font families
Section titled “Font families”| Variable | Stack | Use |
|---|---|---|
--font-display | "Bebas Neue", "Oswald", "Impact", system-ui, sans-serif | Headlines, section titles, labels, buttons, anything bold and tracked. |
--font-body | "Inter", system-ui, -apple-system, sans-serif | All body copy, descriptions, list items, fine print. |
Black Ops One | (loaded) | Reserved for special hero moments only. Use sparingly. |
Oswald | (loaded fallback) | Available if Bebas Neue fails. |
Hierarchy
Section titled “Hierarchy”Headline (.font-display)
- Always uppercase
- Always tracked (
tracking-widerortracking-[0.18em]for labels) - Sizes:
text-3xl→text-7xldepending on hero vs section - Color:
text-metal(steel-100) for the primary phrase,text-precision-shinefor a single highlighted phrase inside
<h1 class="font-display text-6xl tracking-wider text-metal leading-tight"> BUILT TO STICK. <span class="text-precision-shine">MADE TO LAST.</span></h1>Eyebrow / label (.label-rust / .label-precision)
- Small, uppercase, tracked
- Prefixed by a 1ch colored bar (
::before) - Use
label-rustabove sales-critical sections - Use
label-precisionabove informational / how-it-works sections
<div class="label-precision mb-3">Who Brand Activations are built for</div>Body copy
font-body(inherited), regular weighttext-steel-300for descriptions and ledetext-steel-200for stronger body / list itemstext-steel-400for fine printleading-relaxedon multi-line paragraphs
Section titles inside cards
font-display tracking-wider text-steel-100- Always uppercase via
.toUpperCase()in templates or visually withuppercaseclass
What not to do
Section titled “What not to do”- No script fonts. Ever.
- No serif fonts for headlines.
- No lowercase headlines.
- No
tracking-tighton display type. - No headline weight under 400.
- No more than two display sizes in a single section.
Components
Section titled “Components”Buttons
Section titled “Buttons”Primary action — .btn-rust
Rust fill, uppercase tracked display type, sharp corners. This is what we want every visitor to click.
<a href="/wholesale" class="btn-rust">Become a Retail Partner <span aria-hidden>→</span></a>Secondary — .btn-ghost
Transparent fill, steel border, hover transitions to rust border. Use alongside a primary action, never as the sole CTA on a sales page.
<a href="#packages" class="btn-ghost">See the packages <span aria-hidden>→</span></a>Rule: A hero gets exactly one .btn-rust. Multiple rust buttons in one viewport dilute the action. If you need two CTAs, primary is rust and secondary is ghost.
Cards — .tactical-card
Section titled “Cards — .tactical-card”The default content container. Dark panel, thin steel border, subtle inner detail.
<div class="tactical-card p-7 flex flex-col gap-5 h-full"> <!-- content --></div>Variants (via class:list):
!border-rust— featured / “most popular” card!border-precision/60— flagship-tier / premium-info cardrelative overflow-hidden— needed when adding a corner badge
Corner badges for emphasis (positioned absolute top-0 right-0):
bg-rust text-white— MOST POPULARbg-precision text-ink— FLAGSHIP TIER- Always
font-display tracking-[0.18em] text-[10px] px-3 py-1
Dividers — .divider-rust
Section titled “Dividers — .divider-rust”Thin horizontal rule that fades rust → rust-bright → precision-bright → precision → transparent. Use to separate full-width sections. Never use a plain <hr>.
Form inputs
Section titled “Form inputs”- Background:
bg-ink-3 - Border:
border border-steel-700 - Focus:
focus:border-rustfor sales/intake forms,focus:border-precisionfor instructional forms - Padding: minimum
px-4 py-3 - Label: small uppercase tracked
text-steel-300
Layout patterns
Section titled “Layout patterns”- Section container:
mx-auto max-w-7xl px-4 py-20 - Narrower content (CTA, signup):
mx-auto max-w-4xl px-4 - Section border:
border-y border-steel-700to delineate full-width bands - Scroll target: add
scroll-mt-24to anchored sections so they don’t hide under the sticky header
Hero pattern
Section titled “Hero pattern”The canonical hero structure used across /, /wholesale, /brand-activations, /collab-lab:
<section class="relative overflow-hidden"> <div class="absolute inset-0 bg-hex opacity-25 pointer-events-none"></div> <div class="absolute inset-x-0 top-0 h-[420px] bg-[radial-gradient(circle_at_70%_30%,rgba(10,186,181,0.22),transparent_60%)] pointer-events-none"></div> <div class="mx-auto max-w-7xl px-4 py-20 grid lg:grid-cols-12 gap-10 items-center relative"> <div class="lg:col-span-7"><!-- eyebrow + headline + lede + CTAs --></div> <div class="lg:col-span-5"><!-- product / badge visual --></div> </div></section>Don’t reinvent this. Match it.
Iconography
Section titled “Iconography”- Line weight: thin to medium
- Style: industrial / tactical
- Color: monochrome
currentColorwith rust or precision highlights only on critical icons - No filled illustrations, no flat-style mascots, no playful spot illustrations
- Checkmarks in feature lists use
<span class="text-rust flex-shrink-0">✓</span>
Photography and product imagery
Section titled “Photography and product imagery”- Subject: the product, centered, dramatically lit
- Background: black surface, brushed metal, gunmetal, or studio black
- Lighting: hard rim light, strong shadow, no soft beauty lighting
- Crop: tight, often square or 3:2
- No people unless they’re founder portraits (Andrea + Amy) in the workshop
- No stock business photography ever
When background removal is needed, process the image through the studio’s background-removal pipeline before publishing.
Motion
Section titled “Motion”- Subtle. Never bouncy. Never spring-physics.
- Hover transitions on buttons and cards:
transitionwith default duration - No autoplaying carousels
- No marquee text unless deliberately tactical / retail-display flavored
- Page transitions: none. The page is solid; it doesn’t dance.
Implementation conventions
Section titled “Implementation conventions”Class organization
Section titled “Class organization”Match the order used in existing components:
- Layout (
flex,grid,block, position) - Box model (
p-,m-,gap-,w-,h-) - Border (
border,border-steel-700) - Background (
bg-ink-2,bg-hex) - Typography (
font-display,text-2xl,text-metal) - State (
hover:,focus:,transition)
Conditional classes
Section titled “Conditional classes”Use class:list={[...]} in Astro for conditional styling. See brand-activations.astro for the pattern:
<div class:list={[ "tactical-card p-7 flex flex-col gap-5 h-full", i === 1 && "!border-rust relative overflow-hidden", i === 2 && "!border-precision/60 relative overflow-hidden",]}>When you need a new token
Section titled “When you need a new token”Default answer: you don’t. The existing palette covers every reasonable case. If you genuinely need a new token (new accent color, new spacing scale, new font), it’s a brand decision, not a styling decision — open the conversation before adding it.
Audit checklist (for new pages)
Section titled “Audit checklist (for new pages)”Before merging a new page, walk through this list:
- Dark background (
bg-inkorbg-ink-2), never white - At least one
bg-hexorbg-grungetextured section - Exactly one primary CTA per viewport (
btn-rust) - Headlines use
font-display tracking-widerand are uppercase - Precision Cyan used only for info / premium-tech moments, not sales
- Color ratio roughly 65/20/10/5
-
.tactical-cardfor content containers, not bespoke divs - Section eyebrows use
.label-rustor.label-precision - No rounded-full elements anywhere except product badges
- No soft drop shadows, no glassmorphism, no gradient backgrounds outside the documented radial pattern
- All links and buttons have sharp corners (no
rounded-lgon CTAs) - Body copy uses
leading-relaxedfor any paragraph over one line - Section padding is
py-20minimum on top-level sections