Better foundations
Pre-made shadcn and tailwind components for semantic and legible interfaces. Built for the Supertype assembly line and open-source.
Install
Install it with three commands: add the package, initialize the CSS, and run the wiring check.
yarn add @supertype.ai/foundations
npx foundations init # adds and reorders the CSS imports, prints the rest
npx foundations doctor # checks the wiringEvery release is tagged and published, so you can pin a specific commit ahead of the next release.
Here is what init writes. This site uses the same block, unchanged:
/* app/global.css */
@import "tailwindcss";
@import "@supertype.ai/foundations/tokens.css";
@import "@supertype.ai/foundations/theme.css";
@import "@supertype.ai/foundations/type.css";
@import "@supertype.ai/foundations/prose.css";
@import "@supertype.ai/foundations/shiki.css";
@source '../node_modules/@supertype.ai/foundations/dist/**/*.js';Do not skip the @source line
Tailwind generates only the classes it finds in the files it scans, and skipsnode_modules by default. Leave this line out and the package’s utility classes get purged from the build. The components render bare, with no error.Fonts are the one part you wire up yourself. next/font runs in your app and hashes its variable names at build time, so the binding belongs in your layout:
// app/layout.tsx
import { Ubuntu_Sans, Ubuntu_Sans_Mono, Average } from "next/font/google";
const sans = Ubuntu_Sans({
variable: "--font-ubuntu-sans",
subsets: ["latin"],
});
const mono = Ubuntu_Sans_Mono({
variable: "--font-ubuntu-sans-mono",
subsets: ["latin"],
});
const serif = Average({
variable: "--font-average",
weight: "400",
subsets: ["latin"],
});
const fonts = `${sans.variable} ${mono.variable} ${serif.variable}`;
<html className={`${fonts} font-sans`}>If you use a coding agent
The package ships an llms.txt alongside its dist/: the public API, the rules, and the common mistakes that leave a build looking fine. One line is enough to point an agent at it, so it stops writing text-sm text-muted-foreground when a primitive already exists.
# CLAUDE.md, AGENTS.md, or your agent's equivalent
@node_modules/@supertype.ai/foundations/llms.txtCoding agents covers what is in the file, how it stays current, and the lint rules and doctor run that catch what it misses.
Contrast you can check
A WCAG ratio scores both polarities alike. Swap the ink and the ground and it reports the same figure, while on screen dark glyphs on a bright field thin out and light glyphs on a dark field bloat. The two specimens below carry the same ratio to a tenth, both clear AA, and read half a ramp apart.
Six weeks after the migration the queue drained on its own, which nobody had predicted and nobody could explain.
Six weeks after the migration the queue drained on its own, which nobody had predicted and nobody could explain.
So the package measures its palette twice. contrast answers the compliance question and lc answers the design one: whether your secondary ink is meaningfully quieter than your primary, and whether it survived the trip to dark. Both read the resolved cascade, so what gets measured is the page a browser paints.
- WCAG ratio, tertiary ink
The dark theme measures nearly twice the light one.
- Lc, the same two inks
Polarity-aware, so it ranks them the other way.
- Floors held in CI
Both themes, every release.
Light
Dark
Light
Dark
Read
Marks
checkLegibility and checkSignals hold those floors across both themes in CI. Every figure above was computed at build time from the stylesheet this site installs, including the two ratios in that row: the same tertiary ink measures 3.44:1 in light and 6.75:1 in dark, and reads 59.5 Lc against 47.8. Two measures has the maths and the call sites.
What is in here
The written reference lives in the repo: the README and docs.
In production
Sites running the package. Both install it from a tag, the way the instructions above describe, so you are seeing these components at full size on real content.