Skip to content
Unbranded 1.0.0
Preset
Color scheme

Design system for pages with no brand

Unbranded covers explainers, small tools, reports, and forms that are not Greenville Triumph or Sean Tippen work. Link three files at a pinned version, pick one of four presets, and build only from the classes and tokens on this page.

Head block

Paste this into the page head, set data-preset on the html element, and fill the brief card before writing any markup. The preloads change with the preset: load that preset's display and body files.

<!doctype html>
<html lang="en" data-preset="standard">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="design-system" content="unbranded 1.0.0">
<title>Literal page title</title>
<link rel="preload" as="font" type="font/woff2" crossorigin href="https://unbranded.seantippen.com/1.0.0/fonts/schibsted-grotesk-latin-wght-normal.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin href="https://unbranded.seantippen.com/1.0.0/fonts/public-sans-latin-wght-normal.woff2">
<link rel="stylesheet" href="https://unbranded.seantippen.com/1.0.0/tokens.css" integrity="sha384-XDeiGpxMH40GoET+QMRWCAR5eq1KmvHub/TMCLGlumygsWgGzX7BB89qEK7gSAF2" crossorigin="anonymous">
<link rel="stylesheet" href="https://unbranded.seantippen.com/1.0.0/components.css" integrity="sha384-SKo2Dp7MntS9/kGGp647kNZZWg7YuCN3WaxZb1oIG+mvmBq+bEnXhadFdj5L+qLP" crossorigin="anonymous">
<script defer src="https://unbranded.seantippen.com/1.0.0/ub.js" integrity="sha384-KBr0JNa28XlPRogXFivF133uGU0fVJDWyEt7mG+uwMHPlPQoJ3DYPmG4iAtD242u" crossorigin="anonymous"></script>
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- ub-brief
purpose: One sentence saying what this page is for.
reader: Who reads it and what they already know.
must-make-clear: The one thing the reader must leave knowing.
preset: standard
starter: argument
signature-move: inverse band
sources: Where every number on the page comes from.
-->
</head>

This release

Version
1.0.0
Released
November 1, 2026
Files
tokens.css, components.css, and ub.js
Presets
4: standard, tool, reading, and report
Schemes
Light by default; dark and auto on request
Contrast
192 color pairs pass WCAG 2.2 and APCA
Contract
SKILL.md
Registry
registry.md and registry.json
Current version
versions.json

Pin the exact version

There is no floating latest URL. Every file lives in an immutable version folder, so a page keeps working when a new version ships.

Presets

A preset sets fonts, accent, neutrals, radii, density, and motion together. Pick the one that matches the job of the page; never mix fonts or accents across presets. Each column below is rendered in its own preset.

Setting standard tool reading report
Heading Permit backlog by district Permit backlog by district Permit backlog by district Permit backlog by district
Body

Open requests rose for six straight weeks, mostly in water billing.

Open requests rose for six straight weeks, mostly in water billing.

Open requests rose for six straight weeks, mostly in water billing.

Open requests rose for six straight weeks, mostly in water billing.

Actions
Input
Status and link Selected Open request Selected Open request Selected Open request Selected Open request
Used for General pages, explainers, demos, light tools Small apps, admin screens, data entry Long reads, essays, documentation Reports, tables, finance and operations summaries
Accent Orange, hue 58, dark label Petrol, hue 218, white label Berry, hue 353, white label Ink, near black
Neutrals Cool steel, hue 235 Warm gray, hue 85 Green gray, hue 160 Warm gray, hue 60
Display face Schibsted Grotesk 700 Funnel Display 600 Literata 650 Source Serif 4 600
Body face Public Sans Public Sans Literata; Public Sans for UI Public Sans
Radius 4, 6, and 8 px 3, 4, and 6 px 4, 4, and 8 px 2, 2, and 4 px
Density Regular Compact Comfortable Regular
Overlay shadow Tinted, light None, border only Tinted, light None, border only
Starter argument and form tool article report

Attributes

AttributeValuesDefaultChanges
data-presetstandard, tool, reading, reportstandardColors, fonts, radii, density, motion, and measure
data-schemelight, dark, autolightLight or dark values of every color
data-densitycompact, regular, comfortableThe preset'sControl heights, UI text size, and spacing
data-contrastmoreOffStronger borders, focus ring, and muted text

Any of the four works on any element, so one section of a page can switch preset or scheme. The Rules section below is an example: it sets data-scheme to the opposite of the page.

Color

Pages use role tokens only. Values are generated, then checked against both contrast gates before they ship. The value column shows what the current preset and scheme resolve to; switch either at the top of the page.

Surfaces and text

TokenColorValueUse
--ub-bgPage ground
--ub-surfacePanels
--ub-surface-raisedInputs, popovers, and menus
--ub-surface-sunkenWells, code, and sunken bands
--ub-surface-overlayDialogs and drawers
--ub-fgBody text and headings
--ub-fg-mutedLabels, captions, and metadata
--ub-fg-faintPlaceholders and disabled text
--ub-borderSeparators and panel edges
--ub-border-strongHeader rules and emphasis
--ub-border-controlInput and checkbox edges (3:1)

Accent

TokenColorValueUse
--ub-accentOne primary button per view
--ub-accent-hoverPrimary button on hover
--ub-on-accentLabel on the accent fill
--ub-accent-subtleSelected rows, accent band
--ub-accent-borderEdge of a selected item
--ub-accent-textLinks and selected text
--ub-focusFocus ring

Never use the accent for headings, body text, ordinary borders, decorative icons, a chart series, or a second button in the same view.

Status

StatusSolidSubtleBorderTextOn solidExample
successClosed
warningOverdue
dangerFailed
infoScheduled

Status colors are the same in every preset and appear only in status UI, always with an icon and a word. Warning yellow is never decoration.

Data

Categorical, --ub-chart-1 to -8. Separated for color-vision deficiency; each is 3:1 on the surface. Slot order moves a hue that is close to the accent to the end.

12345678

Sequential, --ub-seq-1 to -7

1234567

Diverging, --ub-div-1 to -9, blue to orange through a neutral midpoint. Red and green are never paired.

123456789

Neutral scale, --ub-neutral-1 to -12. Read-only: components use it, pages use the role tokens.

123456789101112

Accent scale, --ub-accent-1 to -12. Read-only.

123456789101112

Contrast gates

PairWCAG 2.2APCA Lc
Body text on page and surfaces7:190
Muted text, links5.5:172
Faint text, status text4.5:160
Label on a solid fill4.5:160
Control border3:130
Focus ring3:145
Chart color on surface3:1Not used

Type

UI sizes are fixed; content sizes scale between a 320 px and a 1440 px viewport. Fonts are self-hosted with tokens.css, so a page needs no Google Fonts link. The face below follows the preset chosen at the top.

TokenAt 320 pxAt 1440 pxUsed forSample
--ub-text-5xl47.868.7Display, one short lineBacklog
--ub-text-4xl39.854.9DisplayBacklog
--ub-text-3xl33.243.9Page heading (h1), stat valueBacklog
--ub-text-2xl27.635.2Section heading (h2)Backlog
--ub-text-xl23.028.1h3Backlog
--ub-text-lg19.222.5h4, lead, reading bodyBacklog
--ub-text-base16.018.0BodyOpen requests by team
--ub-text-sm14.014.0Dense UI, tables, captionsOpen requests by team
--ub-text-xs12.012.0Badges, source lines (the floor)Open requests by team

Fonts

RolestandardtoolreadingreportToken
DisplaySchibsted GroteskFunnel DisplayLiterataSource Serif 4--ub-font-display
BodyPublic SansPublic SansLiterataPublic Sans--ub-font-body
UI and tablesPublic SansPublic SansPublic SansPublic Sans--ub-font-ui
CodeAtkinson Hyperlegible MonoAtkinson Hyperlegible MonoAtkinson Hyperlegible MonoAtkinson Hyperlegible Mono--ub-font-mono

Body text runs at --ub-measure (62 to 72 characters by preset). Headings balance and stop at 28 characters wide. Space above a heading is three times the space below it. Tables use tabular figures.

Space and layout

Spacing steps are multiples of 4 px with the same numbers Tailwind uses. Breakpoints are two literals, 40rem and 64rem; components use container queries.

TokenpxSize
--ub-space-14
--ub-space-28
--ub-space-312
--ub-space-416
--ub-space-520
--ub-space-624
--ub-space-832
--ub-space-1040
--ub-space-1248
--ub-space-1664
--ub-space-2080
--ub-space-2496
TokenPhoneDesktopUse
--ub-gutter1640Page side padding
--ub-gap1628Grid and sidebar gaps
--ub-block2448Between blocks
--ub-section48112Between sections
--ub-control-md4440Control height (touch is taller)
--ub-page-narrow640640Forms, single columns
--ub-page-default11521152Content and tools
--ub-page-wide15361536Data-heavy pages

Layout primitives

Layout comes from these classes, not from page CSS. Each one takes a few custom properties (knobs) for its sizes.

ClassDoesKnobs
.ub-stackVertical rhythm for controls and panels--ub-stack-space
.ub-flowProse rhythm, more space above headings--ub-flow-space
.ub-centerCentered column with the page gutter--ub-center-max
.ub-clusterWrapping row of buttons, tags, or metadata--ub-cluster-space
.ub-gridTwo tracks, 7 to 5 by default; one column under 40rem--ub-grid-cols, --ub-grid-min
.ub-with-sidebarSidebar that drops under the content when narrow--ub-sidebar-width
.ub-switcherRow that becomes a column below a width--ub-switcher-threshold
.ub-coverFull-height screen with one centered block--ub-cover-min
.ub-frameCrops media to an aspect ratio--ub-frame-ratio
.ub-reelHorizontal scroller for screenshots--ub-reel-item
.ub-bandFull-width section with its own grounddata-ground, data-scheme
7 tracks: the claim, the table, the main content
5 tracks: the evidence or the figure

Components

One root class per component, parts named after it, and closed attributes for variants. States come from the browser (hover, focus, disabled, checked) and ARIA, never from state classes. The figures in this section are sample data generated for this page.

Button

VariantDefaultHoverFocusPressedDisabledBusy
solid
soft
outline
ghost
linkNot used

One solid accent button per view. Neutral and danger tones, sizes, a pressed toggle, icon buttons (each with an aria-label), and a tooltip on hover or focus.

Forms

Receipts and status changes go here.

Backup email must include @.

Shown in its hover state.

Shown in its focus state.

Notify
Priority
Range

Panel, description list, and callout

Request 2213

Overdue

High bill dispute, opened 4 days ago

Team
Water billing
Address
418 Larkin Mill Road, Unit 2
Caller
Mara Okafor
Amount disputed
$186.40
Due
Oct 30, 2026

Billing cycle closes Friday

Disputes opened after Friday move to the November cycle.

Meter re-read scheduled

A technician visits 418 Larkin Mill Road on Nov 3.

2 days past due

Overdue requests go to the team lead each morning.

Stats, table, and chart

657

Open requests

All teams, Nov 1, 2026

546

Opened this week

29 more than last week

528

Closed this week

17 more than last week

3.0

Median days to close

Across 5 teams with closures

Source: sample data generated for this page.

Requests opened and closed per week

All teams, 12 weeks from Aug 10 to Oct 26, 2026

  • Opened
  • Closed

Source: sample data generated for this page.

Open requests by team
Permits214964.5
Water billing1871412.0
Streets and sidewalks162589.5
Parks71443.0
Records23371.5
Code enforcement and property maintenance012No data

Sort any column by its header. Days is the median number of days to close. The selected row shows the selected state.

Badges

Draft Selected Scheduled Closed Overdue Failed 12

Overlays

Teams

Delete 3 requests?

Requests 2207, 2213, and 2219 will be removed from the Permits queue. This cannot be undone.

Request 2219

Team
Permits
Type
Fence permit, residential
Address
77 Ashby Court
Opened
Oct 21, 2026
Status
Scheduled

Tabs and accordion

Opened
546
Closed
528
Can a page change the accent?

No. Pick the preset whose accent fits. A white-label demo overrides the accent through the generator, which checks contrast again.

Does a page work without ub.js?

Yes. The script adds keyboard tabs, sorting, toasts, and the chart bridge. Everything else is CSS and HTML.

How do I update to a new version?

Change the version in the three URLs and the meta tag, then replace the integrity hashes from versions.json.

Empty, loading, and progress

No requests match these filters

Clear the filters to see all 657 open requests.

Loading Loading requests

Navigation, code, and keys

<button class="ub-button" type="button">Save changes</button>
<button class="ub-button" data-variant="outline" data-tone="neutral">Cancel</button>

Press Ctrl K to search. Inline code looks like --ub-accent.

Every class

59 components and primitives in 1.0.0
What it isAlso called
.ub-stackVertical rhythm for components and forms.None
.ub-flowProse rhythm: space between blocks, more above headings than below.None
.ub-boxA bordered padded area.None
.ub-centerCentered content column with the page gutter.None
.ub-clusterWrapping row of items.None
.ub-with-sidebarSidebar beside content that wraps under it when narrow.None
.ub-switcherRow that becomes a column below a container width.None
.ub-coverFills the viewport height with one centered main block.None
.ub-gridTwo-track grid with one dominant track (7/5); equal tracks only with data-fit.None
.ub-frameCrops media to an aspect ratio.None
.ub-reelHorizontal scroller.None
.ub-with-iconIcon aligned to the first line of text.None
.ub-cqMarks a container for container queries.None
.ub-table-wrapScroll container for wide tables.None
.ub-bandFull-width page section that carries its own ground.None
.ub-displayDisplay-size headline for one short phrase (six words at most).None
.ub-leadThe paragraph that says what the page is for.None
.ub-iconInline SVG icon from the page's Lucide sprite.None
.ub-buttonThe action control.btn, cta
.ub-icon-buttonA button that shows only an icon.icon-btn
.ub-fieldA label, a control, help text, and an error message.None
.ub-inputText input, select, or textarea.text-field, textbox
.ub-checkCheckbox or radio with its label.checkbox, radio
.ub-switchOn and off for one setting that applies immediately.toggle
.ub-segmentedA small set of mutually exclusive views or values.segmented-control, toggle-group
.ub-fieldsetGroups related fields under a legend.None
.ub-panelGroups one task's content with a title and optional actions.card, box, tile
.ub-dlLabel and value pairs, value next to its label.description-list, key-value
.ub-calloutA message with a status: full border, tinted ground, icon, and a word.alert, banner, notice
.ub-tableData table sized to its contents, headers on one line, numbers right-aligned.None
.ub-sortThe button inside a sortable column header.None
.ub-statOne sourced figure with a label, an optional change, and its basis.metric, kpi
.ub-statsA row of two to four stats divided by hairlines.None
.ub-figureA figure, diagram, or image with a caption and a required source line.image, diagram
.ub-badgeA short status or count.tag, pill, label, chip
.ub-chartThe frame every chart sits in: title, subtitle with units, plot, legend for two or more series, source line.chart-frame, graph
.ub-mapFrame for a Leaflet map on OpenFreeMap tiles.None
.ub-tipA short CSS tooltip from data-tip.tooltip
.ub-popoverFloating content opened by a button (popovertarget).None
.ub-dialogA modal dialog on the native dialog element.modal
.ub-drawerA dialog attached to one side of the screen.sheet, tray, side-panel
.ub-toastA short confirmation that disappears on its own.snackbar, notification
.ub-tabsPeer views of one dataset.None
.ub-accordionSections that open one at a time, on details name.None
.ub-emptyWhat is missing, what to do, and one button.empty-state, zero-state
.ub-skeletonA static placeholder block while content loads. No shimmer.None
.ub-spinnerThe only infinite animation in the system.None
.ub-progressDeterminate or indeterminate progress, or a meter.None
.ub-appbarThe full-width bar at the top of a page or app.header, navbar, topbar
.ub-navA list of page links.None
.ub-sidenavA vertical list of sections or pages.None
.ub-appApp shell: appbar on top, sidebar beside main.None
.ub-toolbarA row of controls above a table or view.None
.ub-codeA code block with a copy button.None
.ub-skipSkip link to the main content.None
.ub-numRight-aligned tabular figure.None
.ub-nowrapKeeps a value on one line.None
.ub-sr-onlyVisually hidden, still read by screen readers.visually-hidden
.ub-mutedSecondary text color.None

Rules every page follows

These are the checks ub-check runs. Floor rules never have an exception. A Reflex rule can be waived once per page with a written reason.

Floor
IDRule
F01Head block present, files pinned to an exact version
F02No unknown ub- class
F03No unknown --ub- token
F04No other design system on the page
F05No color literal outside tokens.css
F06Fonts only through --ub-font-*
F07No gradients and no gradient text
F08No backdrop blur
F09No scale on hover, press, or focus
F10No panel or box inside another
F11No colored stripe on one side of a box
F12No icon tile above a heading
F13No spaced-out uppercase labels
F14No emoji outside content
F15No em-dashes
F16No placeholder text, names, or image hosts
F17No accent bar under or beside a heading
F18No background image or pattern on the page or a section
Reflex
IDRule
R01Spacing, radius, and z-index from tokens
R02Headings and paragraphs aligned left
R03No row of three or more identical cards
R04No 01, 02, 03 section markers
R05The spinner is the only infinite animation
R06No bounce or elastic easing
R07No !important in page CSS
R08Every CDN file pinned and hashed
R09Charts colored only through the bridge
R10Warning colors only in status UI
R11Brief card in the page head
R12A figure with %, x, or + has a source
R13No numbered scale tokens in page CSS
R14One solid accent button per section

Copy

Plain, literal, and short. Name the thing; say what happened; say what to do.

ElementRuleExample
Page headlineWhat the page is or does, under 10 wordsOpen requests by team
Section headingName the contents in one to three wordsOverdue requests
ButtonVerb and object, sentence case, three words or fewerExport CSV
Never on a buttonSubmit, OK, Click here, Get started, Learn moreRead the fee schedule
Empty stateWhat is missing, what to do, one buttonNo invoices yet. Add one to start tracking.
ErrorField, problem, fix; no apology or blameEmail address must include @.
SuccessPast tense, names the object, no exclamationRequest 2213 assigned to Permits.
Destructive confirmTitle names the object; the button repeats the actionDelete 3 requests?
LoadingSay what is loadingLoading requests
NumbersUnits in headers, one date format, a source for every figureRevenue (USD); $15/match
TermsOne noun per thing across a productRequest everywhere, never ticket or case

Also banned: em-dashes, buzzwords (seamless, supercharge, world-class, unlock, elevate, streamline, empower), aphorism cadence such as "Less X. More Y.", invented numbers, a subtitle that repeats the title, lorem ipsum, and the brand claiming feelings. Serial lists take the Oxford comma.

Starters

Five page structures, so pages built on the system do not all share one shape. Copy the starter that fits, then replace the sample content. None has a hero, a card row, testimonials, pricing, or an FAQ block.

StarterPresetStructure
argumentstandardHeadline that states the claim, evidence beside it in a 7 to 5 split, sections on alternating grounds, sourced figures
articlereadingOne column at the prose measure, contents list, notes in the margin on wide screens
tooltoolApp shell: top bar, sidebar, toolbar, table, and a detail drawer
reportreportTitle block with as-of date and source, up to four stats, tables sized to content, a chart, and notes
formstandardNarrow page, fieldsets, inline validation, an error summary, and a confirmation state

Examples

Three finished pages built from the starters. The explainer and the report use real public data with citations; the tool uses sample data.

ExamplePresetData
How to tell three penguin species apartstandardPalmer Penguins, CC0
Freezer samplestoolSample data
Renewable share of electricity, 2000 to 2025reportOur World in Data, CC BY 4.0

Signature moves

Every page picks one and records it in its brief card: an oversized sourced figure, an inverse band, an accent band, a side-by-side comparison table, a margin column, a large index list used as navigation, an annotated diagram of the page's own mechanism, or a real screenshot at native size.

Files

Every file in a version folder is immutable and served with Access-Control-Allow-Origin: *, so pages on any domain can link it. Client demos copy the folder into their own deploy instead of linking this host.

FilePinned URLIntegrity
tokens.csshttps://unbranded.seantippen.com/1.0.0/tokens.csssha384-XDeiGpxMH40GoET+QMRWCAR5eq1KmvHub/TMCLGlumygsWgGzX7BB89qEK7gSAF2
components.csshttps://unbranded.seantippen.com/1.0.0/components.csssha384-SKo2Dp7MntS9/kGGp647kNZZWg7YuCN3WaxZb1oIG+mvmBq+bEnXhadFdj5L+qLP
ub.jshttps://unbranded.seantippen.com/1.0.0/ub.jssha384-KBr0JNa28XlPRogXFivF133uGU0fVJDWyEt7mG+uwMHPlPQoJ3DYPmG4iAtD242u
FileHolds
SKILL.mdThe contract for agents: the build loop, hard rules, head block, decision tables, and snippets
registry.mdEvery component with its use, classes, variants, states, and knobs
registry.jsonThe same, plus every token name, for tools
versions.jsonThe current version and the integrity hash of each file
adapters/shadcn.cssMaps shadcn/ui variables and slots to Unbranded tokens for React apps
adapters/tailwind-theme.cssTailwind v4 theme that replaces the default palette with tokens
favicon/The default icon set for unbranded pages