Compaytence · Design Internal · 13 August 2026

Compaytence
Design Guide

Every token, component and rule in the v2 system, shown at working size. Click any swatch to copy its hex.

Version
v2 · guide 1.0
Adopted
3 August 2026
Values measured
13 August 2026
Implementation
assets/system.css
This page is built out of the thing it documents

The stylesheet inlined here is system.css verbatim, copied at build time. Every swatch fill, contrast ratio and OKLCH reading is computed from one hex value by build.py, so a label cannot drift from the color above it. If the system changes, re-run the build rather than editing this file.

Provenance
01

Why the system exists

Not to look good. To be unable to have been installed.

An audit in August 2026 found that 13 of 13 accent and text values in the previous system were Tailwind's literal defaults, and that our own product site had been initialised with shadcn ("style": "new-york"). A competitor in an unrelated industry shared 9 of our 12 signature devices at near-identical values, because both sites were assembled from the same registry.

Every value must trace to a source. If the only answer to “why that number?” is “it looked right,” it is drift.

That test replaced the older one, “could this have been installed?”, because blacklists rot on roughly a twelve-month cycle. The 2024 tell was a purple gradient and Inter. The 2026 tell is warm cream and a serif display, which was the escape route from the 2024 tell, adopted widely enough to become the new one. Derivation does not rot.

Inherited defaults removed in the v2 rebuild
Tailwind palette values13
Vercel house typefaces2
Total 15

Source: design-system.md §0, August 2026 audit.

The corollary, and it is binding

Never write a prohibition without a positive replacement. Told “don't use cream,” a model does not produce variety, it moves to a different fixed palette. Negation relocates an attractor rather than dissolving one. Every rule in this guide names the token, number or face used instead.

The accent
02

One blue ladder, one hue

The wordmark's PAY blue is the seed. Every other blue is that same color made lighter or darker.

Step 50 is the wordmark blue itself, measured at OKLCH hue 245.56. Across all eleven steps the hue holds within 1.6 degrees. Chroma is a different story: it peaks at the seed and falls toward both ends, because sRGB cannot hold saturation at the pale end. The ladder is a lightness ladder with the hue locked, which is the property that matters.

Contrast measured against --paper in each theme. Green clears 4.5:1, gray clears 3:1, red clears neither. Computed 13 August 2026.

The rule that matters more than any other

#33A9FF measures 2.42:1 on the light ground. On a light surface it is a fill only. Never text, never a hairline you need to read. On the dark ground the same hex reaches 7.51:1 and can be set as text. That asymmetry is the entire reason a ladder exists instead of a single hex.

This text is #33A9FF on paper. At 2.42:1 it fails every accessibility floor there is.

Never do this

The same hex as a fill behind white, and as the seed of the whole ladder.

This is its job

Because of that, no one ever hand-picks a step. Six role tokens resolve to the right rung per theme, and the markup only ever names the role.

TokenJobLightRatio DarkRatio
--mark links, emphasis step 70 #0077bd 4.57 step 30 #81c5ff 10.34
--mark-deep heavier emphasis step 80 #005990 7.07 step 20 #b0daff 13.02
--mark-solid FILL on light, text on dark step 50 #33a9ff 2.42 step 50 #33a9ff 7.51
--mark-tint tinted surfaces step 05 #edf6ff 1.04 step 95 #002e4d 1.36
--fig display figures, >=24px only step 60 #0089d9 3.59 step 40 #5fb7ff 8.83
--fig-inline figures in running text step 70 #0077bd 4.57 step 30 #81c5ff 10.34
The figure trap, and the rule that defuses it

--fig is 3.59:1 on the light ground, so it is legal only above about 24px. Making it the default color of a general-purpose figure class means every index numeral and inline stat silently fails AA, which is exactly what happened once. A two-step figure system must default to the safe step and make the display step opt-in.

Never introduce a second accent hue. Brass was tried for figures and rejected, then survived unnoticed in an atmospheric wash at chroma 0.086 for two drafts. If a color is above roughly 0.02 chroma and is not this blue, it is a bug. Two exemptions exist and both must be made auditable rather than left implicit: third-party brand marks keep their owner's color, tagged so the audit whitelists the attribute and never the hex; and a product replica that shows a user what they actually see on login keeps the product's own tokens, asserted in both directions.

The ground
03

Warm paper, cool accent

Both themes are warm. The accent is the only cool thing on the page.

The blue sits at hue 245.56, so its exact complement is 65.56. The neutrals are derived from that number, which means one measurement seeds both halves of the system and the answer to “why that hue” is arithmetic rather than taste. Chroma and lightness carry each neutral's role.

TokenLightDark
--paperthe ground
--paper-2surface tint, carries no text
--washband tint, carries no text
--graphitemuted text
--ink-softbody
--inkheadings
Do not write “hue equals 65.6” as a check

Measured, the twelve neutrals span 62.35 to 75.41 degrees. That is not drift in the colors. At chroma 0.005 to 0.013, 8-bit sRGB cannot address hue: one step on a single channel moves the measured hue by 3.5 to 15.8 degrees, so every value is already within one quantization step of the target, and re-encoding at exactly 65.56 returns the same or an adjacent hex. The checkable form of the rule is chroma at or below 0.013, hue between 55 and 90. Both hold for all twelve, and both are falsifiable.

Route every border through rgba(var(--rule-c), a). The token is not a color but an RGB triplet for compositing: 31,27,22 on light, 233,230,225 on dark, at alpha 0.09 to 0.45. Never hardcode a gray, and never a neutral-black shadow. The light shadow tint is a warm 44,32,21.

Two surfaces that carry no text

--paper-2 and --wash are surface tints only. --graphite, --mark, --risk and --good all fall to roughly 4.3:1 on the first and 3.9:1 on the second, which is below the floor. If you paint a band in either, the text on it steps up to --ink-soft or darker.

Semantics, two of them

There is deliberately no amber warning. Amber sits near hue 70 and collides with the warm ground, which is precisely the mistake the retired brass accent made. Anything that would have been a warning is either a risk or a plain accent note.

Three of these four clear the 4.5:1 floor by 0.04 or less. They have no headroom left. Do not nudge them.

Faces
04

Three typefaces, fixed roles

The roles are not a preference. A face doing another face's job is a defect.

Instrument Serif

Display, section titles, eyebrows, folio, and all figures. Never body, never a UI label.

ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 and its italic

Archivo

Body, UI, card titles, table heads, buttons. Never display, never figures.

ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789

Spline Sans Mono

Technical strings only: code, IDs, lot numbers, swatch labels. Never a label, an eyebrow, or a running head.

ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789

Geist and Geist Mono are retired: they are Vercel's own house typefaces, and wearing the platform's uniform was half the problem. Inter, Roboto, Arial, Poppins, Montserrat, Space Grotesk and any system-font display stack are out for the same reason at a larger scale. They are what a generator reaches for when nobody decided.

Instrument Serif is on that same list, and we use it anyway

It is one of the four most-flagged “AI font” faces, and warm cream plus a serif display is the documented 2026 house style of the frontier models. The defense is not the face, it is the job we give it: figures. A tabular serif figure column in the blue is a device with a population of one. An italic serif word dropped into a headline for flavor is the attractor. Keep the serif's center of gravity on numbers.

The scale: 1.25 off a 17px base

Nine steps, and they are the whole vocabulary. Type is judged comparatively, so a slow ratio works here. Space is judged in isolation and gets a faster one.

--t-xs 0.68rem 10.88px labels, table heads, units
Compaytence 2,847
--t-sm 0.85rem 13.60px card body, table cells, points
Compaytence 2,847
--t-base 1.0625rem 17.00px body, the 17px base
Compaytence 2,847
--t-md 1.328rem 21.25px lede, standfirst
Compaytence 2,847
--t-lg 1.66rem 26.56px pull-quote
Compaytence 2,847
--t-xl 2.075rem 33.20px section numeral, row + total figures
Compaytence 2,847
--t-2xl 2.594rem 41.50px section title
Compaytence 2,847
--t-3xl 3.243rem 51.89px stat figure
Compaytence 2,847
--t-4xl 4.05rem 64.80px document title
Compaytence 2,847

Serif italic: a system, or nothing

An oversized serif with one italicised word in it is the universal AI-startup hero, and it is the one place this display face could slide from signature into flourish. The thing that makes it a tell is that it is usually a default, reached for once, for flavor, with no reason behind it.

Banned

An italic serif word dropped into a headline because it looked good there. One-off, unexplainable, decorative.

Not a system
Permitted

An accent device that is traceable to a stated source, applied systematically across a surface, and carried in the content model as data rather than hand-marked per instance.

A system

In documents there is no such system, so four sanctioned italic roles are the whole vocabulary, and there is no fifth: .doc-title em (a whole title line, never a word lifted out), .tag, .note-l, and .quote. Emphasis inside a document heading comes from size, weight, color or position. Gradient fill on text is banned everywhere, including on a sanctioned accent word: the italic already marks it, and the ramp only adds a tell.

The eyebrow, and what replaced the mono label

The eyebrow is Instrument Serif italic, sentence case, graphite, with a 26px hairline prefix. It carries the section's kind; the numeral carries its position. If an eyebrow would only restate the title, leave it out. The old mono-uppercase-tracked eyebrow is dead and must not return in any form.

A retired mono micro-label becomes one of exactly two things
Reserve schedule

.label — Archivo, --t-xs, weight 600, tracking .09em, uppercase, graphite. This is the table th treatment promoted to a class, and it is the only sanctioned uppercase-tracked device left. Use it for a column heading.

Still in underwriting

.tag — serif italic, sentence case, graphite, where the text is a phrase rather than a field name. Reach for this one first.

The signature
05

Figures are the brand

One device with a population of one. It cannot be pattern-matched, because nobody else does it.

Every number is set in the display serif, in the blue, with font-variant-numeric: tabular-nums lining-nums, right-aligned wherever it sits in a column. In running text .fig-inline runs slightly larger than the surrounding Archivo so it catches the eye without going bold.

The same sentence, both ways

Without the treatment: we recovered 20 million dollars across 450 holds for 2,500 businesses, working with 30 processors.

With it: we recovered $20M across 450 holds for 2,500 businesses, working with 30 processors.

Tabular figures are what make a column readable: every digit occupies the same width, so the numbers line up vertically whatever their value. Right-alignment does the rest.

20usd m
Reserves recovered Cumulative, all clients. Source: copy/products/, Aug 2026.
450holds
Holds overturned Cumulative. Source: copy/products/, Aug 2026.
30psps
Processors Active routing relationships. Source: copy/products/, Aug 2026.
A figure without a source is a defect

Same class as a missing logo. A number in a stat card is a claim, so it carries a real value, a denominator where one exists, a date, and where it came from. Round unsourced numbers — “10,000+ merchants”, “99.9% uptime”, “3x faster” — are the most-cited content tell there is. Placeholder figures may exist in a scaffold. They may never ship.

Rhythm
06

Everything derives from 30px

Body is 17px on a 30px baseline, so one line is one unit.

Every spacing value is a fraction or a multiple of that line, and every one is a whole pixel. A geometric ratio was considered and rejected: 1.25 needs fourteen steps to span 4 to 100px and puts 24 next to 30, which reads as an accident, and 1.5 goes fractional at the third step.

The blue rules behind this paragraph are drawn every 30 pixels. The text sits on them because --lh-body is 1.765, and 17 × 1.765 is 30.005. One line of body copy is exactly one unit of the spacing scale, which is why the scale can be stated as fractions of a line rather than as an arbitrary set of numbers somebody liked.

--s1 6 1/5 baseline gap inside a points list
--s2 12 2/5 baseline card title to body, table cell padding
--s3 18 3/5 baseline grid gap, paragraph margin
--s4 24 4/5 baseline card padding, section head margin
--s5 30 1 baseline note margin, one baseline
--s6 45 1 1/2 baseline page padding, masthead margin
--s7 60 2 baseline pull-quote margin
--s8 90 3 baseline between sections
The rule that decides which step to use

Space between text blocks uses whole baselines: 30, 60, 90. Padding inside a component uses the fractions: 6 through 24. Proximity carries meaning, so make the gaps differ where the grouping differs. One spacing value everywhere is a failure to group.

Material
07

Geometry, glass, grain, halos

A two-step shape scale, one hairline weight, and exactly two atmospheric elements.

Corners: two steps, never a third

A control that sits a step tighter than its container reads as considered rather than defaulted. One radius on everything is the soft-blob tell, and the fix costs nothing.

14px
--r-lg
cards, tables, notes, panels
8px
--r-ctl
buttons, inputs, toggles
4px
--r-xs
inline code only

All four corners, always. Elliptical, chamfered, squircle, scaled and asymmetric-keyed corners were each built and rejected, and they stay rejected. --r-sm is retired. Never reach for a raw px value: the two tokens are the whole vocabulary.

One hairline weight

--hair is 1px everywhere, colored rgba(var(--rule-c), .09 to .45). There is no second border thickness in the system.

Glass

A translucent card over the warm ground, with backdrop-filter: blur(16px) saturate(1.25). Held rather than dropped, because grain over it and halos behind it make it a material stack, not a blur applied for gloss.

Grain, over everything

Including over the cards, at z-index 9. Underneath, every card would erase it and the two would visibly fight. Over the top it behaves like film grain and unifies the surface. One grained surface per flat page, and never one grained box nested inside another.

Exactly two halos

That is the entire atmospheric budget. Not a third halo, not an aurora field, not a mesh gradient, and not a glow orb of any edge treatment. “Blurred” does not launder one.

Grain on a multi-band page

Grain must ride the layer that paints the tone, never the section box. In a bridge or bleed system a band's color continues past its own section, so grain scoped to the section ends while its color carries on, and draws a hard line at every boundary: measured at Δ10/255 on paper and Δ22/255 on the dark ground. The page then reads as a stack of slabs rather than one surface.

Containers
08

The card, and when not to use one

The card is the house container. It is not the house default.

A card says “compare me to my siblings.”

Use one when the items genuinely are a set of peers the reader weighs against each other: three plans, three approaches, three outcomes. Anything the reader simply reads in order goes on the ground with no container, as a title, a line, and a hairline rule between rows. A page where every block is a card grid reads as noise no matter how good the cards are. On one four-route service section, applying this took the page from about 24 card surfaces to 9.

The same applies to proof imagery and pull quotes: a screenshot that already ships its own frame and shadow needs no card around it, and a quote reads better as type on a rule than boxed. The four blocks in section 07 above are card-free rows, for exactly this reason.

The four card types

42pct
Stat card Figure-led. The number is the hero, hung large above a hairline.
Row card

Label left, figure right. The ledger row, boxed.

64ch
Total card
Carries the double rule2
Hairlines, 4px apart4
Total 6
The web shape
Feature card

A tag, a title, a line of copy, and a link whose arrow travels with the card.

Back to the top

Hover any card above. At rest it carries a hairline and no shadow. Elevation arrives only on interaction, and it arrives in exactly two layers.

1 · Lift and bloom

The card rises 3px and gains --shadow-lift from nothing. It becomes physically nearer.

2 · Specular sheen

A soft highlight tracks the pointer across the surface, at alpha .035. Expensive materials catch light. This is the layer that sells the material.

Why .035 and not more

It shipped at .14 and read as a spotlight following the cursor rather than a material catching light. The tell that it is right: you notice it when the pointer moves and cannot quite point at it when it stops. Every surface shares one block, so this single number tunes the whole page. Never re-tune it per component.

A third layer, a blue rule wiping across the top edge, was built and removed. With the sheen already carrying the accent it was one signal too many, and it made the card announce itself rather than respond. Shipping a hairline and a diffuse shadow at rest was dropped for the same class of reason: it is running two elevation systems at once.

The double rule

A ledger never closes a column with a single line. .total-line draws two hairlines 4px apart above a total. It costs one pseudo-element, it is nobody else's, and it means something. Use it only above a genuine total, never as decoration.

The rest of the catalog

MeasureBefore v2After
Tailwind default values130
Vercel typefaces20
Accent hues21
Radius steps12
Reveal durations12

Source: design-system.md changelog, 3 August and 12 August 2026.

Nested cards are out

A card inside a card is visual noise. If content inside a card needs a frame, it wants a rule or a tinted band, not a second card.

Motion
09

Two weights, and nothing under them

Everything arriving identically is decoration. Varying it by importance makes motion carry meaning.

ClassTravelDurationUse on
.rise180.7 Section heads, anything that opens a block
.rise-sub100.5 Cards, grids, tables inside a section
none Points, labels, inline elements, small controls

The lead announces the block; the follower settles under it. Do not add a third duration, and do not put a reveal on something small. An element that arrives on its own for no reason is the same failure as everything arriving identically.

The lead arrives first
and the follower settles under it, 10px in half a second.

The two easing curves

One pair, and no bounce or elastic anywhere. Every hand-picked easing curve in the measured corpus is an ease-out, which is what both of these are.

--ease
cubic-bezier(.2,.7,.2,1)

Color, background and border transitions.

--ease-out
cubic-bezier(.16,1,.3,1)

Reveals, card lift, the travelling arrow.

The card hover is a signature, not a default

The measured corpus norm for a hover is a color change: background 33.8%, color 24.4%, border 12.3%, transform only 6.6%. Our two-layer lift is correct on a card and wrong on a link or a table row, which want color at about 200ms. Per-site median transition is 250ms, so --dur-lead at 0.7s and --dur-sub at 0.5s are top-decile values: right for reveals, wrong anywhere near a hover.

Source: motion-canon.md, 1,199 sites' shipped CSS, 13 August 2026.

Access
10

Both themes, measured

4.5:1 for text, 3:1 for display figures over about 24px. Every value below was computed from the shipped hex, not copied from a note.

TokenJobLightDarkFloor
--ink headings 16.31 17.74 4.5
--ink-soft body 7.93 15.38 4.5
--graphite muted text, eyebrow 4.66 6.12 4.5
--mark links, emphasis 4.57 10.34 4.5
--fig-inline figures in text 4.57 10.34 4.5
--fig display figures >=24px 3.59 8.83 3.0
--mark-solid fill only FILL on light; text on dark 2.42 7.51 4.5
--risk error states 4.54 4.53 4.5
--good confirmations 4.54 5.16 4.5

Ratios against --paper in each theme. WCAG 2.1 relative luminance, computed 13 August 2026. The system's shipped floors are 3.59:1 on light and 4.53:1 on dark.

Do not benchmark focus against the field

78.6% of measured sites write outline:none at least once, and 26.5% do so while never defining :focus-visible. 12.7% have no focus styling at all. Reduced motion is worse: only 39.8% of sites carry the query, and by platform it collapses to 14.4% on Webflow and 2.3% on Framer, two sites out of 87. Any Compaytence surface built on Framer or Webflow needs that query written by hand.

Source: motion-canon.md, 13 August 2026.

The verification gotcha that invalidates a whole audit

In a hidden preview tab, getComputedStyle returns stale values for anything mid-transition, and forcing reflow does not help. Before measuring contrast, inject *,*::before,*::after{transition:none!important}. Otherwise a theme flip reports the previous theme's colors and every reading is wrong.

Evidence
11

Why this reads as ours

On 13 August 2026, 1,290 shipped design systems were machine-measured from applied CSS. The numbers below are what came back.

2.6pct
Warm paper with a cool-only accent Among corpus sites on a warm canvas carrying any chromatic accent, 77.3% pair it with a warm accent. Ours is the other kind: a 37× rarity gap, and the single most defensible property of this ground.
0.9pct
Sites carrying the full generated fingerprint Generic sans, everything rounded 8 to 16px, shadows and gradients: 12 of 1,290, every one a dev-tool or SaaS product. The genre uniform is not the norm. It is the most-represented thing in training data.
59.5pct
Define zero box-shadows 78% state a flat or hairline-only rule outright. Stripe, Mercury, Anthropic, Notion, Intercom, Wealthsimple and Retool all ship zero. Our hairline-at-rest card is the majority position, not a compromise.
47.4pct
Use exactly two radius steps Only 14.6% round every surface into the 8 to 16px band. 0px is the single most common card radius at 21.2%, ahead of both 8 and 16.

Source: styles.refero.design, 1,290 systems measured from applied CSS; anti-patterns.md §9 and website-builder/references/design-canon.md, 13 August 2026.

Two more that sharpened the system rather than confirming it. Bold is a bigger tell than radius: 46.2% of these sites never exceed weight 600, and 36.6% state an anti-bold rule. Hierarchy is size, space and color, so a 700-weight heading is a more reliable marker of an unconsidered system than any palette choice. And negative tracking is not hygiene: roughly half the corpus applies none, even on display. Track by size band with a stated reason, or not at all.

The one rule this evidence added

Never let a warm accent onto the warm paper. Not in an illustration, not in a chart series, not in a hover tint, not in an atmospheric wash. It is the one move that collapses a 2.6% position into a 77.3% one, and it is exactly the failure mode already on record: brass survived unnoticed in a wash at chroma 0.086 for two drafts. --risk is the sanctioned exception, scoped to error states only.

Two honest caveats, so this is used as a self-audit and not a weapon

Most of these tells were 2022 to 2024 human design trends with named exemplars before the generators were any good. What changed is not the vocabulary, it is that the average became free to produce. The real diagnosis is “nobody decided,” not “a machine made it”: a human shipping stock shadcn produces the identical artifact. Point this list at our own work.

Prohibitions
12

The kill list

Permanently out. If one appears, it is a regression, not an option.

The retired v1 system is archived and must never be rendered: no cream #fafaf7 canvas, no Geist, no #3b82f6, no mono eyebrows, no glow orbs, no grid overlays, no dark navigation rail.

Process
13

The audit, before you present

Six questions. Any “no” is a defect, not a preference.

One
Logo swap

Replace the wordmark with a competitor's. Does anything else have to change?

Two
Provenance

Pick five rendered values at random: a color, a radius, a gap, a size, a duration. Can each be traced to a token or a stated derivation without saying “it looked right”?

Three
Ranking

Does the page show what matters most, or is every block the same weight? Identical word counts across sibling cards mean the copy was trimmed to fill the boxes.

Four
Proof

Does every figure and quote carry a real source, a date and an attribution?

Five
The unhappy path

Do the empty, loading, error and 404 states exist, and does each say something specific?

Six
The scroll

Does it hold up scrolled to the bottom at 375px and at 1440px, in both themes? A page verified only from its first viewport is verified the way a generator would verify it.

If the build is being matched against a reference site, add a seventh: put our page, the reference, and the closest generic template side by side. Distinctiveness is only visible in a lineup.

Where the machine-readable version lives

This page is the human one. The gradeable version, with every rule carrying an ID, a measured value, a test and a source line, is .claude/skills/compaytence/references/design-system-spec.md. It is what the design-loop skill's system critic resolves to, and its §15 is a pre-built twenty-line checklist ready to fork into a run.