DRAFT PROPOSAL · v0.1

The Firefly design system

A first pass at documenting Firefly Partners' visual language as tokens and components — built from what's already live in the site's codebase, and complemented by the shared brand book and moodboard, ready to react to and revise together.

Tokens sourced from design-system.css Accent mark integration Imagery direction — pending
01 · Foundations

Color

Semantic aliases point at a primitive for a specific job — surfaces, text, states — so a color's meaning can be looked up by name instead of memorized by hex.

Primitives

Orange#FF661F--p-orange
Yellow#FFC817--p-yellow
Purple#868BFC--p-purple
Light purple#C3C3FF--p-light-purple
Off-black#141414--p-off-black
Mid gray#5A6470--p-mid-gray
Gray#E3E3E3--p-gray
Light gray#F6F6F6--p-light-gray

Semantic — surfaces & text

Page bg--bg-page
Surface--bg-surface
Surface, sunken--bg-surface-sunken
Inverse (dark)--bg-inverse
Text primary--text-primary
Text secondary--text-secondary

Semantic — states

Success--state-success
Warning--state-warning
Error--state-error
Accent, primary--accent-primary
Accent, secondary--accent-secondary
Info--accent-info
Note: success / warning / error aliases don't exist in the current codebase yet — proposed here in a warm register (not a stock red/green) so state colors still feel like Firefly.
01 · Foundations

Typography

Three families, three jobs: Stabil Grotesk carries reading text, Monosten labels and technical metadata, Monosten Stencil is reserved for shouted emphasis. This page renders system fallbacks — open it inside the repo to see the real faces.

Type scale — Stabil Grotesk

H1 / step-6Aa96.5px / 400
H2 / step-5Aa Bb74.3px / 400
H3 / step-4Aa Bb Cc57.1px / 400
H4 / step-3Aa Bb Cc Dd43.9px / 400
H5 / step-2Aa Bb Cc Dd33.8px / 400
H6 / step-1Aa Bb Cc Dd26.0px / 400
Body / step-0The quick brown fox jumps over the lazy dog.20.0px / 300
Small / m1Caption and helper text sits here, at the small end of the scale.15.4px / 300

Monosten — labels & metadata

UppercaseCase study · sector tag · 202612px / 400
Stat4,300+33.8px / 400

Monosten Stencil — emphasis only

StencilRadically33.8px / 700
01 · Foundations

Graphic elements

Marks, shapes, and badge treatments from the Moodboard Integration Proposal.

Icons

Small functional marks.

Nav icon
Simple arrow

Firefly Arrow motif

Arrow motif

Hand-drawn accent marks

Proposal: pick one per emphasis (the underline is the safest default), never stack several on one page.

Underline
Circle
Rectangle
Arrow loop
Speech bubble
Scribble
Hand-drawn double swoosh accent mark
Swoosh
Hand-drawn square outline accent mark
Square, outline

Color on an accent mark

Propose a color for a mark by checking it against the background it sits on — the same rule already used for text on accent colors — rather than picking freely. A mark keyed to its container's background can land on a color it disappears into or fights with if that check is skipped.

BackgroundWorks wellAvoid
White / light-grayOff-black, orange, mid-grayYellow (fails contrast)
OrangeOff-black, whiteYellow (fails contrast — see Accessibility)
YellowOff-black, mid-grayOrange, white (both fail contrast)
Off-blackWhite, yellow, light-purpleOrange (fails contrast), mid-gray
Purple / light-purpleOff-black onlyYellow, orange, white (all fail contrast)
CorrectWhite mark on off-black
CorrectOff-black mark on light-purple
AvoidOrange mark on yellow — low contrast
AvoidYellow mark on orange — 1.9:1, fails even non-text minimum (3:1)
Implementation note: all 8 marks are inline <svg> with fill="currentColor" — so a single color value on a container recolors the mark, per the table above. No separate asset swap needed per color.

Tag pills

Open question: would tag pills actually be needed for taxonomies (e.g. categorizing projects or articles), or is this shape only useful as the in-text highlight below? Confirm the use case before treating this as a component.

Digital Strategy AI Adoption Case Study

Sector pills (white background, off-black text) and Platform pills (off-black background, white text):

Policy & Advocacy
Luminate Online Raiser's Edge WordPress

Pill highlight, in text

A second use of the same pill shape: not a taxonomy tag, but a solid-color highlight behind one word inside a sentence — the same job the yellow <mark> does in this page's own H1. This gives that treatment more colors to choose from, under the same contrast rule as accent marks: check the pill color against its background rather than picking it freely.

Where digital strategy meets progressive passion.

An outline-only variant, for a lighter touch where a solid fill feels too heavy.

Where digital strategy meets progressive passion.

Same rule as tag pills and accent marks: check the highlight color against the page background rather than choosing it freely per instance — see the table above.

Accent mark, applied

One mark, one job: underline a single emphasized word in a featured headline. Never more than once per page. Applied here to a real headline already live on the site (index.astro, the .radical__heading block).

Let's change
your tech,
RADICALLY

Second example — Homepage hero

The same swap applied to the live homepage hero (index.astro) — replacing .hero__underline's text-decoration: underline with the real accent mark on "slipping." Off-black is used here, not white, since the hero's own heading color is already off-black (per the pairing table: off-black is one of the two allowed marks on an orange background).

Serving mission-driven organizations since 2007

Your tools don't talk to each other. Your fundraising is slipping.
And now AI showed up.

We can help.

What changed: .hero__underline{ text-decoration: underline; } is replaced by the accent-mark SVG positioned under the word — everything else in the hero (copy, layout, CTAs) stays untouched.

Organic-shape image mask

Three real clip-path shapes from the shared reference files. Proposal: we can build a two-layer system, not a single crop — a mask clips the base photo, and a second, separately-cropped overlay photo is placed so it appears to break out of the mask's edge. Each mask would be a reusable component; the overlay image would need to be prepared by hand before upload each time.

Shape 1 — notched column
Shape 2 — rounded blob
Shape 3 — angled slab
01 · Foundations

Spacing & radius

The live site uses a fluid Utopia scale (values shift with viewport width) — shown here at their minimum, mobile-width value. Always use a token; a hardcoded px/rem value is the exception, not the rule.

Spacing

--space-3xs5px
--space-2xs10px
--space-xs15px
--space-s20px
--space-m30px
--space-l40px
--space-xl60px
--space-2xl80px

Radius

--radius-sm16px
--radius-md22px
--radius-lg40px
--radius-btn / card22px
02 · Components

Buttons

Sourced from the live repo — .nav-link / .btn-primary and .home-logo in Header.astro, plus .hero__secondary-cta in index.astro. Primary and Secondary are the same two colors in opposite order; Link is the lowest-emphasis action in a group.

Primary

Off-black background, yellow text — used for nav pills and the site's main CTAs.

Default
Hover
Active
Disabled

Secondary

The same pairing, inverted — yellow background, off-black text. Used for the home icon pill in the header.

Default
Hover
Active
Disabled

Link

Underlined text, no background — the lowest-emphasis action in a group, like "See Our Work" next to the hero's primary CTA.

On a light background the link stays off-black with an underline in both states — the dark hover shown here only applies where the link sits on a dark surface, like the hero.

Play Episode

Sourced from untangled.astro — .episode__play. Off-black background, white mono text, a play-triangle icon. A distinct pattern from Primary/Secondary: hover doesn't invert color, it dims to 85% opacity.

Default
Hover

Subscribe

Sourced from untangled.astro — .newsletter-cta__btn. Orange background, white text — used only on the dark newsletter card, next to an email field. Same opacity-dim hover as Play Episode, not the off-black/yellow inversion pattern.

Default
Hover
02 · Components

Text inputs

Used in the slide-up contact form and the newsletter block. A 1.5px border keeps focus/error states visible without relying on color alone.

Default
Focus
Disabled
Error Enter a valid email address.
02 · Components

Checkbox

Used in the contact form's "Type of project" group (AI Adoption, Digital Tools, Website, Strategy & Performance, Other).

Default
Checked
Disabled
02 · Components

Cards

Sourced from the live repo — .card.article-card in resources/articles.astro. Image thumbnail, mono uppercase tag in orange, title, excerpt, and a meta row (author · date · read time). Hover adds a soft shadow, no border-color change.

03 · Governance

Accessibility

WCAG 2.1 AA is the project's stated minimum (per the Functional Spec). The pairings below are the ones actually in use — check any new pairing before shipping it.

PairingPreviewRatioResult
Off-black on whiteAa18.1:1AAA
Mid-gray on whiteAa6.3:1AA
Off-black on orangeAa7.2:1AAA
White on orangeAa2.9:1Fails AA
Off-black on yellowAa10.9:1AAA
White on off-blackAa18.1:1AAA
Rule of thumb: text on the orange or yellow accent always uses --text-on-accent (off-black), never white — white-on-orange fails AA at 2.9:1.
03 · Governance

Do's & don'ts

The short version of the rules already written into CONTRIBUTING.md and the "holistic, not bolted-on" principle from the design system plan.

Do

Add a new visual pattern as a shared token or component first, then use it everywhere it applies.

Don't

Style a one-off element directly on a single page — it's the fastest way to end up with the same thing looking different in three places.

Do

Use white or off-black text on orange/yellow accents.

Don't

Put white text on orange — it fails contrast at 2.9:1.

Do

Reach for a spacing token (--space-*) for every margin, padding, and gap.

Don't

Hardcode a px/rem value when a token already fits — per the project's own CSS rules.

03 · Governance

How to apply this

No new tool, no Figma — this system is applied by talking to Claude Code the same way you'd talk to a builder. These four steps are what keep a new style from ending up bolted onto just one page.

1

Name the pattern

Before adding anything new, describe it in one line — "a swoosh underline for one emphasized word in a headline," not "make it more playful."

2

Ask for it as a shared token or component

Tell Claude to add it to design-system.css / global.css, or as its own component — never written directly into one page's markup.

3

Apply it everywhere it belongs

Once it exists as a shared piece, every page that needs it references the same definition — so it reads as one decision, not several.

4

Audit before calling it done

Check 2–3 pages where it should appear and confirm it looks identical everywhere — that's the whole test.

The instruction that matters most

Say this explicitly, every time — it's the difference between a shared style and a one-off:

Add a swoosh underline under "RADICALLY" on the homepage. Apply it as a shared token/component, not just on this page — I want it reusable anywhere we need this kind of emphasis.

Vague vs. specific

Vague

"Make the homepage more playful."

→
Specific

"Add the swoosh accent mark under 'real behavior' in the hero headline, as a shared component."

Vague

"Use one of the moodboard tag colors here."

→
Specific

"Use the orange tag pill style from the design system on this Article card's topic tag."

Rule of thumb: if you can't point to which file the pattern lives in after asking for it, ask Claude where it put it — a real shared pattern always has one home.
One exception: the organic-shape image mask isn't fully automatic. The wavy mask is a shared component, but the overlay photo (the one that appears to spill past the edge) has to be pre-cropped by hand before it's uploaded — that step can't be delegated to a one-line instruction the way everything else on this page can.