Every token, component and rule on one page. Dark is the primary theme; light exists for long-form reading and print. Toggle it top-right — the light theme is a selected set of steps, not an inverted filter.
A field of noise with a growth curve hidden inside it. Where your cursor goes, the field resolves — dots snap to the curve and shift to Grana. That's the thesis of the whole site: attribution is pulling signal out of noise, and the curve was always there.
Move your cursor · signal resolves
Grid
16px desktop · 20px tablet · 24px mobile. Capped at ~4,000 dots.
Resolve radius
190px, falloff (1−d/R)². Dots displace toward the curve, never away from it.
Reduced motion
Renders the fully-resolved static state. No RAF loop, no cursor tracking.
02 — Color
Ink, Grana, and five data slots
One accent. Grana is cochineal red — the pigment Mexico exported to the world, and for three centuries the most valuable dyestuff on earth. It's a story you can tell in an interview, and it gets you off the orange-and-yellow default every dev-tool site shares.
Ink ramp
Grana ramp
Text on canvas — measured contrast
Hard rule. The primary button is ink text on Grana, never white. White on Grana is 3.49:1 and fails AA. Ink on Grana is 5.71:1 and passes. Both reference sites ship white on their accent — don't copy the bug.
Chart palette — validated, assigned in fixed order
Validated OKLCH six-check · dark surface #0E1012 · adjacent pairs PASS at 5 slots · all-pairs PASS at 3 · beyond 3 series requires direct labels or texture
03 — Typography
Three families, three jobs
Geist carries everything structural. Instrument Serif italic gets exactly one phrase per headline. Geist Mono is not a garnish — it's the skeleton. If a piece of text is metadata about content rather than content itself, it's mono.
display-xl · Geist 600 · −0.042em · 0.95
Marketing is an engineering problem.
display-l · Geist 600 · −0.036em
I build the machine.
heading-l · Geist 600 · −0.028em
Systems over campaigns
body-l · Geist 400 · 1.65 · max 68ch
Most teams can't tell you what actually worked. I build the systems that can — attribution, automation, agent fleets, and the reporting cadence that keeps a team honest. Then I run them.
Case-study card — the headline is the outcome, not the client
Wizeline · Senior Marketing Lead · 2025—
Put an agent fleet into marketing production
Replicated a personal agent architecture on Cursor Enterprise, got it client-approved for a regulated financial client, and shipped it to 40+ daily users.
A number without a method reads like a claim. A number with one reads like a receipt. Every chart on this site ships a method line, a legend, direct labels, and a table view.
eCommerce revenue index · PMI Americas
Owned channels
Category baseline
Indexed to 100 at month 0 · 12 months · single market · methodology →View chart data table
Month
Owned
Baseline
M0
100
100
M3
124
104
M6
161
109
M9
213
113
M11
240
116
Brief-to-launch, working days
Before
After
Median across 4 workstreams · Adobe Workfront · n = 118 briefs · methodology →View chart data table
Stage
Before
After
Brief
5
1
Creative
12
9
Review
8
5
Launch
4
3
Never a dual-axis chart. Two measures of different scale become two charts, small multiples, or both indexed to 100. It's the single most common chart mistake and it silently misleads.
06 — Motion & accessibility
The part that backs up the claim
"Best looking without sacrificing usability" is only true if it's measured. These are build blockers, not polish.
Rule
Spec
Status
Body text contrast
≥ 4.5:1 — verified per token
PASS
Primary button contrast
ink on Grana = 5.71:1
PASS
Focus visible
2px Grana ring, 3px offset, every interactive element
PASS
Keyboard operable
Skip link first tab stop; canvas is aria-hidden and unfocusable
PASS
Touch targets
≥ 44×44px
PASS
Reduced motion
Entrances instant; Signal Field renders resolved & static
PASS
Charts
Never color-alone — legend + direct labels + table view
PASS
--text-faint
4.08:1 — decorative and disabled use only
BANNED FROM CONTENT
Motion tokens
--dur-fast 120ms
Micro-feedback
--dur 200ms
Hover, color, border
--dur-slow 320ms
Entrance: 8px rise + fade, 40ms stagger, capped at 6
--easecubic-bezier(.2,0,0,1)
Default
--ease-outcubic-bezier(.16,1,.3,1)
Entrances
No parallax. No scroll-scrubbed animation. Motion carries meaning or it doesn't ship.