Platform Foundationsv0.2.0

Tokens

Colors, typography and radius from the Platform styleguide.

Use semantic tokens, never raw hex or pixel values. bg-primary, text-muted-foreground, border, rounded-lg.

Every value on this page is generated from packages/theme/src/theme.css, so it cannot drift from the theme. Click any swatch or token name to copy the token, not the hex.

The three layers

Tokens flow through three layers, and you only work with the middle one:

Primitives (--pc-blue-500) are the raw brand ramp. Rarely referenced directly.

Semantic slots (--primary, --border) map primitives onto roles. Both light and dark values live here, which is why swapping a palette never touches component code.

Tailwind utilities (bg-primary, border-border) are what you write in components.

Semantic tokens

The layer app code consumes. Light and dark side by side, because the dark palette is derived rather than designed and this is where you can review it.

TokenLightDarkResolves to
#ffffff#0d0e0f--pc-neutral-0
#0d0e0f#fafafc--pc-neutral-900
#ffffff#17181b--pc-neutral-0
#2f69ff#2f69ff--pc-blue-500
#f2f3f7#22242a--pc-neutral-100
#f2f3f7#22242a--pc-neutral-100
#6a6f74#8e8f95--pc-neutral-500
#ebf0ff#17244a--pc-blue-100
#0032b2#dce6ff--pc-blue-700
#f33859#f33859--pc-error-500
#3abaaf#3abaaf--pc-success-500
#fbc740#fbc740--pc-warning-500
#00b5f1#00b5f1--pc-info-500
#e9eaf2#2a2c33--pc-neutral-200
#dfe1ec#2a2c33--pc-neutral-300
#2f69ff#5282ff--pc-blue-500

Primitive ramps

Brand blue

Neutral

Functional / Error

Functional / Warning

Functional / Success

Functional / Info

The primary action color is the brand blue #2f69ff. The functional palette (error, warning, success, info) each has a light tint, a solid base, and a dark variant for text on tint.

Data visualization

The shared categorical ramp. Every entry clears 3:1 against --background in both modes, so thin lines and small legend swatches stay visible, and the two blue-family hues sit at opposite ends so adjacent series never collide.

Do not use --accent or another tint token as a series color. They are hover surfaces and disappear against a card. The Special Days, Unit, Area, and Teams palettes are app-specific data-viz sets and live in the app, not in the shared theme.

Typography

The single typeface is Outfit. Load it with next/font/google and expose it as --font-sans.

h1 · Outfit 700 · 20/25

The quick brown fox jumps over the lazy dog

paragraph-l · Outfit 400 · 16/24

The quick brown fox jumps over the lazy dog

paragraph-m · Outfit 400 · 14/24

The quick brown fox jumps over the lazy dog

paragraph-s · Outfit 400 · 12/15

The quick brown fox jumps over the lazy dog

The scale above is what the Figma defines: one heading step plus three paragraph sizes. It is an application UI scale, not a documentation scale, so headings in long-form content are set by the docs site rather than the theme.

Radius

Radius base is 0.375rem (~4-5px, measured from the Figma buttons and cards) with sm/md/lg/xl steps.

Elevation

The design has no shadows. Elevation is a border plus a surface: border-border with bg-card.

The theme enforces this rather than relying on discipline. Tailwind's shadow scale (--shadow-*, --inset-shadow-*, --drop-shadow-*, --text-shadow-*) is overridden to a fully transparent value, so shadow-sm, shadow-lg and friends still compile but paint nothing. That means you can run npx shadcn@latest add and copy upstream component source in unmodified — the shadow-* classes it ships with are inert here, and the component still looks like a Platform app.

Focus rings are unaffected. Tailwind composes rings into the same box-shadow declaration, so the override uses a transparent shadow rather than none, which would be invalid inside a comma-separated list and would take the focus ring down with it.

If you find yourself wanting a shadow to separate two surfaces, the answer is usually a border, a different bg-* token, or more spacing.