Skip to main content
Brand ⬩ Design system

Bryn, by Civic. The system as shipped.

A bryn is a hill. From the high ground you see the whole field before you move, and every choice on this page serves that one job: a Bryn surface shows you what a buyer did and what to do about it, with nothing in the way. Every mark, token, and idiom here is the one civic.com renders today; the swatches paint from the live tokens, the type is the live scale, the motion is the live contract.

01 ⬩ Marks

The horizon mark, the lockup, the Civic mark

The mark is a figure on a hill, watching the horizon: the whole product in one glyph, someone who sees the field before they move. The hill fills with the stones gradient, the brand purple family stepped from soft to tint, and figure, ridge, and horizon line draw in brand purple on light and dark grounds alike. The mark goes white only when it sits on the brand drench.

--brand
--brand
--on-brand

Horizon mark

One mark, one colour. Inline as <use href="#horizon">, it binds figure, ridge, and horizon line to currentColor, and that colour is brand purple on light and dark grounds, white on the drench. The standalone SVG pins the same paths in brand purple, the mark exactly as the lockups draw it, for places that live outside the page CSS.

symbol#horizon ⬩ 300 × 300
Bryn, by Civic lockup on a light groundbryn-lockup-civic-ink.svg
Bryn, by Civic lockup on a dark groundbryn-lockup-civic.svg

Lockup

The product leads and the company signs it. Glyph at 24px in brand purple, BRYN in Geist extrabold at 17px, a 1px hairline, then by Civic with Civic in medium weight. This is the header composition on every page; the SVG lockups ship with the type outlined, one drawn for light grounds and one for dark.

BRYN ⬩ by Civic
--text
--text

Civic mark

The company stands behind the product, so its mark rides the Company menu at 18px and links to civic.com. Inline it with fill="currentColor" and it takes the ink of its surface.

civic-mark.svg ⬩ currentColor

Use it like this

The same glyph sits in the header, as a watermark, and on the drench without a variant for each: brand purple on light and dark grounds, border-strong when it fades into a watermark, white on the drench.

BRYNby CivicHeader lockup, light
BRYNby CivicHeader lockup, dark
Mark in brand, light
Mark in brand, dark

Bryn delivers revenue.

Watermark, border-strong

Bryn delivers revenue.

Drench glyph, on-brand

Clear space

The mark reads as a figure watching, and it needs room to do that. The unit is x, the head of the figure: one quarter of the mark's width. The mark keeps at least 1x clear on every side; the lockup keeps the glyph's height, 4x, clear on every side.

mark 96px ⬩ x = 24px
mark 48px ⬩ x = 12px
BRYNby Civic
glyph 24px ⬩ 4x = 24px
x = head Ø 76 / 300 box = 0.25 × mark width ⬩ lockup clear = glyph height = 4x

Sizes in use

Each size is tied to a job on the page, so the mark is always as loud as its role and never louder.

  • 18pxCivic mark, Company menu.nav-civic__mark
  • 24pxHorizon glyph, header lockup.brand__glyph
  • 180 to 340pxSection watermark, border-strong at 50%.glyph-watermark
  • 220 to 340pxDrench glyph, on-brand at 18%.drench-glyph
02 ⬩ Downloads

Assets

What you download is what shipped: every file here is the one the site serves. The SVGs carry explicit hex so they hold their colour anywhere, with or without the stylesheet.

Marks

3
civic-mark.svg

Civic mark, light grounds

currentColor in the SVG, ink in the PNGs

civic-mark.svg

Civic mark, dark grounds

currentColor in the SVG, dark-register text in the PNGs

Lockups

2

Hill set

6

App icons and share

4
03 ⬩ Color

Palette D

Color on a Bryn surface means something every time it appears. Warm paper carries the reading in the light register and deep violet-black carries it in the dark, and each accent does exactly one job: purple is the impact, teal is the signal Bryn caught, coral is the cost of waiting. Light is the base; dark applies through data-bryn-theme="dark" on .bryn-site, any band goes dark on its own with data-band="dark", and app figures carry data-scheme="os" to follow the OS colour scheme.

Bryn delivers revenue.

Purple is impact and brand

The outcome is the point, so the delivered word renders brand purple. Buttons, the drench, the hill fill, the noun the hero lands on.

--brand
  • visit/demo
  • resolvedhigh intent
91composite
  1. ingest
  2. resolve
  3. enrich
  4. score

Teal is the caught signal

Resolution, live data, the thing Bryn saw. Teal marks the moment a visitor becomes an account, so it lights the hit in a ledger, the numeral in a kicker, the tick in a progress track.

--signal
watching ⬩ 00:04:35Template

Coral is the cost of waiting

Every minute between the signal and the action costs pipeline. Coral names that cost: the watching clock, the template flag. Sparse by design.

--warn

Accents

The bright values carry fills and marks; the ink values carry text, so an accent stays readable on paper-light ground and steps up to the bright value on dark.

Light ⬩ base
  • Brand--brand#7C3AED
  • Brand hover--brand-hover#6D28D9
  • Brand soft--brand-soft#9993FF
  • Brand shade--brand-shade#3E1973
  • Brand tint--brand-tint#1E1033
  • Brand ink--brand-ink#5B1FA8text ink
  • Signal--signal#2FD9C2
  • Signal soft--signal-soft#7FF0E2
  • Signal ink--signal-ink#0C6D60text ink
  • Warn--warn#FF7E5F
  • Warn ink--warn-ink#A5330Etext ink
Dark ⬩ data-bryn-theme="dark"
  • Brand--brand#7C3AED
  • Brand hover--brand-hover#6D28D9
  • Brand soft--brand-soft#9993FF
  • Brand shade--brand-shade#3E1973
  • Brand tint--brand-tint#1E1033
  • Brand ink--brand-ink#9993FF→ --brand-soft
  • Signal--signal#2FD9C2
  • Signal soft--signal-soft#7FF0E2
  • Signal ink--signal-ink#2FD9C2→ --signal
  • Warn--warn#FF7E5F
  • Warn ink--warn-ink#FF7E5F→ --warn

Ground and ink

The ground is warm rather than white so a page reads like paper, and the ink steps from text to secondary to muted so hierarchy comes from weight of colour before it comes from size.

Light ⬩ base
  • Background--bg#FAF9F5
  • Background alt--bg-alt#F3F1EA
  • Surface--surface#FFFFFF
  • Surface alt--surface-alt#F1EFE7
  • Border--border#E7E4DB
  • Border strong--border-strong#C7C2B3
  • Text--text#211B12
  • Text secondary--text-secondary#5B5541
  • Text muted--text-muted#6A6249
Dark ⬩ data-bryn-theme="dark"
  • Background--bg#07050E
  • Background alt--bg-alt#0C0918
  • Surface--surface#191327
  • Surface alt--surface-alt#120C20
  • Border--border#2C2444
  • Border strong--border-strong#3D3360
  • Text--text#E2E8F0
  • Text secondary--text-secondary#94A3B8
  • Text muted--text-muted#7B8794

On brand

Purple is where a page lands, so everything on it reads white: text at full, secondary lines dimmed to 90%. The drench adds a radial white sheen at 18% from the lower right, which gives the close depth with one colour.

--on-brand
#FFFFFF
--on-brand-dim
rgba(255, 255, 255, 0.90)
04 ⬩ Type

Geist takes stances. Geist Mono speaks for the product.

The split is the point: a reader should always know whether we're talking or Bryn is. Geist carries what we say, headings, ledes, prose, every stance. Geist Mono carries what the product says, readouts, cites, chips, stamps, Play names, log lines, byte-exact. The scale is fluid and ramps again above 90rem, body letter-spacing runs at -0.005em site-wide, and the numbers below are the 1440 landing.

Geist

Buyers send signals. Bryn delivers pipeline.

--font-sansStance, headings, prose
Geist Mono

Run #0001 ⬩ demo.follow-up ⬩ 10:02:11 → 10:06:46 UTC

--font-monoReadouts, stamps, chips, cites

Each stance tightens as it grows: the bigger the line, the heavier the weight and the closer the tracking, so a hero lands like a statement and body copy reads like a page.

  1. Display .t-5
    size
    4.50rem
    weight
    900
    track
    -0.035em
    leading
    1.02

    Bryn.

  2. Hero .t-4
    size
    3.60rem
    weight
    800
    track
    -0.035em
    leading
    1.02

    Buyers send signals.

  3. Headline .t-3
    size
    3.40rem
    weight
    700
    track
    -0.025em
    leading
    1.15

    Bryn watches. You decide.

  4. Title .t-2
    size
    1.90rem
    weight
    600
    track
    -0.025em
    leading
    1.15

    Bryn Watches, Scores, Acts, Logs

  5. Lede .t-1
    size
    1.20rem
    weight
    500
    track
    -0.005em
    leading
    1.45

    Under 10 minutes to your first identified, scored and recorded visitor.

  6. Body .t-0
    size
    1.05rem
    weight
    400
    track
    -0.005em
    leading
    1.60

    A rule set once: when this happens, on an account like this, do that.

  7. Small .t--1
    size
    0.92rem
    weight
    400
    track
    -0.005em
    leading
    1.45

    Bounded writes. Only the channels the Play names.

  8. Stamp .t--2
    size
    0.78rem
    weight
    500
    track
    0.08em
    leading
    1.45

    S3 ⬩ BOUNDED WRITES

05 ⬩ Register

Stamps, hairlines, hills

A Bryn surface should feel like an instrument panel you trust: labelled, seamed, quiet. Mono uppercase stamps at 0.08em tracking name what you're looking at, 1px hairlines seam the bands, and the hill punctuates a section the way a horizon punctuates a view. Elevation is one hairline and a soft shadow, so the evidence carries the weight and the card stays out of its way.

S3 ⬩ Bounded writesscore ⬩ 7d

Mono stamp

A label in the product's own hand, so you know which register you're reading before you read it. Uppercase Geist Mono at step -2, muted ink, a ⬩ separator, and a hairline that runs out to the right. Section ordinals, figure stamps, and metadata rows all wear it.

card-ord ⬩ fig-stamp ⬩ pg-stamp
Anweledig Labsscore ⬩ 7d

Anweledig Labs

anweledig.example
person known

11-50 employees · Software Development · Cardiff, Wales, United Kingdom

Fit100×0.66
Intent60×0.22
Timing100×0.12
91composite
high intent · 14:01:40Z

Hairline and fig panel

The panel frames evidence, so it holds the eye on what's inside it. Surface, 1px border, 20px radius, 24px padding, the small shadow. Adjacent bands seam with a 1px hairline; a dark band swallows the seams around it.

fig ⬩ radius-lg ⬩ shadow-sm
pricing →comparison →repeat (7d)
5Plays ship today

Chip pill and kicker

Chips read the way a Play reads, behavior then window, left to right. Mono at step -2 with a border-strong edge and a teal arrow. The kicker is a sans label whose numeral sets tabular in teal ink: the number is the thing Bryn counted.

chip-pill ⬩ kicker__num
Start the trialSee a live run

Buttons

One action in a row gets the brand; the alternative stands beside it without competing. Semibold at step 0, 12px by 32px padding, 11px radius, 1px press. Primary is the brand fill; ghost is transparent with a border-strong edge.

btn--primary ⬩ btn--ghost

The hill set

The hill is the brand's horizon, and it does a different job in each place it appears: atmosphere behind a hero, a divider between sections, texture across a quiet stretch. Each piece ships in light and dark. The divider is the cheap one and can repeat down a long page; the signal line traces the nearest ridge in teal, the caught signal drawn onto the landscape.

Hero atmospherehill-horizon-hero-light.svg ⬩ hill-horizon-hero-dark.svg
Section dividerhill-divider-light.svg ⬩ hill-divider-dark.svg
Ambient texturehill-texture-light.svg ⬩ hill-texture-dark.svg
06 ⬩ Motion

Short, eased, and once

Motion on a Bryn surface means something arrived; it's a signal, so it plays once and then holds still. Content enters with a 22px rise over 600ms on the rise curve, staggered in four steps, and anything below the fold waits until it's 35% in view before it plays. Under prefers-reduced-motion every duration collapses to zero and the finished frame is the resting state.

Durations

Each duration is sized to what it carries: a state flip is instant, a hover is quick, an entrance takes long enough to register, and the hero ring breathes slowly enough to read as alive rather than busy.

  • --dur-instant80msState flips
  • --dur-fast150msHover, border, color
  • --dur-base220msSegment entrance
  • --dur-slow400msSignal bounce and ping
  • --dur-reveal600msSection reveal
  • --dur-sweep2400msSweep across a panel
  • --dur-hero-ring6500msHero ring, breathing dot

Easings

Things arrive decisively and leave quickly. The rise curve lands content with weight, the ring overshoots because a caught signal has energy, and the fall curve clears the way.

  • --easecubic-bezier(0.4, 0, 0.2, 1)Default
  • --ease-risecubic-bezier(0, 0.55, 0.45, 1)Reveal, ping
  • --ease-ringcubic-bezier(0.34, 1.56, 0.64, 1)Overshoot
  • --ease-fallcubic-bezier(0.55, 0, 1, 0.45)Exit
The reveal contract.reveal ⬩ .seg ⬩ .s1 to .s4
  1. Stamp
  2. Hold
  3. Intersect
  4. Play once
A section earns its entrance by coming into view, then it's done. .reveal rises 22px over --dur-reveal on --ease-rise; .seg rises 10px over --dur-base. .s1 to .s4 add the staggers below.

Staggers

Staggers let a section arrive in reading order, stamp first and evidence last, so the eye is led rather than flooded.

  • --stagger-150ms
  • --stagger-2160ms
  • --stagger-3300ms
  • --stagger-4460ms
07 ⬩ Voice

What we say. What Bryn says.

Every Bryn surface has two speakers, and a reader should always know which one is talking. We write the stance: direct, plain-spoken, outcomes first. Bryn writes the record: Play names, readouts, log lines, byte-exact and in mono.

  • The company is Civic. The product is Bryn, by Civic, then Bryn. The category is signal-based GTM: go-to-market driven by what a buyer actually does on your site and in your product.
  • Builder-native, confident, plain-spoken. Contractions are the rule. Outcomes lead; tools, mechanism, and price appear as proof of an outcome claim.
  • Punctuation is periods, commas, and colons. The ⬩ separator joins stamps and ordinals.
  • Prose takes stances in Geist. The product speaks in Geist Mono, byte-exact: Play names, readouts, log lines, chip grammar. Fit, Intent, Timing, and Composite are the score dimensions; Play is the product noun.
Geist takes stances. Mono speaks.stance ⬩ readout

Identification without action is a dashboard you will stop checking.

Where Bryn sits, as shipped

Run #0001 ⬩demo.follow-up ⬩watched 10:02:11 ⬩logged 10:06:46 UTC

Audit log, Civic's own funnel
The stance is ours and sets in Geist. The readout is Bryn's, set in Geist Mono and quoted byte-exact from the audit log.

Bryn watches. You decide the Play. Bryn runs it.

Product h1, as shipped