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-lockup-civic-ink.svg
bryn-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. Use civic-mark.svg as it ships: it's drawn in currentColor, so it takes the ink of its surface.
civic-mark.svg ⬩ currentColor
Use it like this
One glyph, two cuts: in full, with its hill, it's brand purple on light and dark grounds in the header, footer and heroes; as its lines alone, it's border-strong when it fades into a watermark and 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.
xx
mark 96px ⬩ x = 24px
xx
mark 48px ⬩ x = 12px
xxBRYNby 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.
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="site" to read in the site theme wherever they sit.
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
ingest
resolve
enrich
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
See who's on your site. Act while they're still looking.
--font-sansStance, headings, prose
Geist Mono
Run #0001 ⬩ demo.follow-up ⬩ 10:02 AM → 10:06 AM
--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.
Display .t-5
size
4.50rem
weight
900
track
-0.035em
leading
1.02
Bryn.
Hero .t-4
size
3.60rem
weight
800
track
-0.035em
leading
1.02
See who's on your site.
Headline .t-3
size
3.40rem
weight
700
track
-0.025em
leading
1.15
Bryn watches. You decide.
Title .t-2
size
1.90rem
weight
600
track
-0.025em
leading
1.15
Bryn Watches, Scores, Acts, Logs
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.
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.
Small .t--1
size
0.92rem
weight
400
track
-0.005em
leading
1.45
Bounded writes. Only the channels the Play names.
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
AL
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
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)
Chip pill
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.
chip-pill
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.
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.
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 AM ⬩logged 10:06 AM
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.