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.