Installation
No build step, no tooling. Add two <link> tags and you're done.
<link rel="stylesheet" href="unc.css">
<link rel="stylesheet" href="unc-extend.css">Load unc-extend.css after unc.css so your overrides take effect.
Colors
Semantic color tokens with built-in state variants. Override any token in unc-extend.css to retheme the entire library.
/* In :root — unc.css */
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
--color-primary-focus: #1d4ed8;
--color-primary-active: #1e40af;
/* Override an existing color in unc-extend.css */
:root {
--color-primary: #e11d48;
--color-primary-hover: #be123c;
--color-primary-focus: #9f1239;
--color-primary-active: #881337;
}
/* Add a custom color in unc-extend.css */
:root {
--color-brand: #f97316;
--color-brand-hover: #ea6c0a;
--color-brand-focus: #c2540a;
--color-brand-active: #9a3e06;
}
.bg-brand { background-color: var(--color-brand); }
.text-brand { color: var(--color-brand); }
.bg-brand-hover:hover { background-color: var(--color-brand-hover); }
.bg-brand-focus:focus { background-color: var(--color-brand-focus); }
.bg-brand-active:active { background-color: var(--color-brand-active); }
Spacing
A 0–10 spacing scale used across margin, padding, and gap utilities.
--space-0: 0;
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-4: 1rem; /* 16px */
--space-8: 2rem; /* 32px */
--space-10: 2.5rem; /* 40px */
Typography Tokens
Font Sizes
xs
The quick brown fox
sm
The quick brown fox
base
The quick brown fox
lg
The quick brown fox
xl
The quick brown fox
2xl
The quick brown fox
3xl
The quick brown fox
4xl
The quick brown fox
5xl
The quick brown fox
6xl
The quick brown fox
7xl
The quick brown fox
Font Weights
normal
Grumpy wizards
medium
Grumpy wizards
semibold
Grumpy wizards
bold
Grumpy wizards
black
Grumpy wizards
--text-xs: 0.75rem; --font-normal: 400;
--text-sm: 0.875rem; --font-medium: 500;
--text-base: 1rem; --font-semibold: 600;
--text-lg: 1.125rem; --font-bold: 700;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 1.875rem;
--text-4xl: 2.25rem;
--text-5xl: 3rem;
--text-6xl: 3.75rem;
--text-7xl: 4.5rem;
Radius
sm
md
lg
full
--radius-sm: 0.125rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-full: 9999px;
Shadows
sm
md
lg
xl
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
Display
<div class="block">...</div>
<span class="inline-block">...</span>
<div class="flex">...</div>
<div class="grid">...</div>
<div class="hidden">not rendered</div>Position
<div class="relative">
<div class="absolute top-0 right-0">pinned top-right</div>
</div>Available: .static .relative .absolute .fixed .sticky
Inset helpers: .inset-0 .top-0 .right-0 .bottom-0 .left-0
Overflow
<div class="overflow-hidden">...</div>
<div class="overflow-auto">...</div>
<div class="overflow-x-auto">...</div>Flex Direction
.flex .flex-row
.flex .flex-col
<div class="flex flex-row gap-4">...</div>
<div class="flex flex-col gap-2">...</div>Flex Justify
.justify-start
.justify-center
.justify-end
.justify-between
<div class="flex justify-start gap-2">...</div>
<div class="flex justify-center gap-2">...</div>
<div class="flex justify-end gap-2">...</div>
<div class="flex justify-between">...</div>
<div class="flex justify-around">...</div>
<div class="flex justify-evenly">...</div>Flex Align
.items-start
.items-center
.items-end
.items-stretch
<div class="flex items-start">...</div>
<div class="flex items-center">...</div>
<div class="flex items-end">...</div>
<div class="flex items-stretch">...</div>Flex Grow & Shrink
<div class="flex gap-2">
<div class="flex-none">fixed width</div>
<div class="flex-1">grows to fill remaining space</div>
<div class="flex-none">fixed width</div>
</div>Grid Columns
.grid .grid-cols-2
.grid .grid-cols-3
.grid .grid-cols-4
<div class="grid grid-cols-2 gap-4">...</div>
<div class="grid grid-cols-3 gap-4">...</div>
<div class="grid grid-cols-4 gap-4">...</div>Column Spanning
<div class="grid grid-cols-4 gap-4">
<div class="col-span-2">spans 2</div>
<div>1</div>
<div>1</div>
<div class="col-span-full">full width</div>
</div>Gap
.gap-1
.gap-2
.gap-4
.gap-6
.gap-8
<div class="flex gap-2">...</div>
<div class="flex gap-4">...</div>
<div class="grid grid-cols-3 gap-6">...</div>
<div class="grid grid-cols-2 gap-x-4 gap-y-2">...</div>Padding
.p-1
.p-2
.p-3
.p-4
.p-6
.p-8
<div class="p-4">padding all sides</div>
<div class="px-6 py-3">horizontal + vertical</div>
<div class="pt-4 pb-2">top + bottom individually</div>
<div class="pl-4">left only</div>Margin
<div class="mx-auto max-w-md">centered block</div>
<div class="mt-4 mb-8">vertical margin</div>
<div class="ml-auto">push right</div>Width
.w-full
.w-auto
<div class="w-full">...</div>
<div class="w-auto">...</div>
<div class="w-fit">...</div>
<div class="w-screen">...</div>Max Width
max-w-xs
max-w-sm
max-w-md
max-w-lg
max-w-xl
max-w-2xl
max-w-4xl
<div class="max-w-md mx-auto">centered, max 28rem wide</div>
<div class="container">max 80rem, auto margins, padded</div>Text Size
text-xs
The quick brown fox jumps
text-sm
The quick brown fox jumps
text-base
The quick brown fox jumps
text-lg
The quick brown fox jumps
text-xl
The quick brown fox jumps
text-2xl
The quick brown fox jumps
text-3xl
The quick brown fox jumps
text-4xl
The quick brown fox jumps
text-5xl
The quick brown fox jumps
text-6xl
The quick brown fox jumps
text-7xl
The quick brown fox jumps
<p class="text-xs">Extra small</p>
<p class="text-sm">Small</p>
<p class="text-base">Base (default)</p>
<p class="text-lg">Large</p>
<p class="text-xl">X-Large</p>
<p class="text-2xl">2X-Large</p>
<p class="text-3xl">3X-Large</p>
<p class="text-4xl">4X-Large</p>
<p class="text-5xl">5X-Large</p>
<p class="text-6xl">6X-Large</p>
<p class="text-7xl">7X-Large</p>Font Weight
font-normal
Grumpy wizards make toxic brew
font-medium
Grumpy wizards make toxic brew
font-semibold
Grumpy wizards make toxic brew
font-bold
Grumpy wizards make toxic brew
font-black
Grumpy wizards make toxic brew
<p class="font-normal">Normal 400</p>
<p class="font-medium">Medium 500</p>
<p class="font-semibold">Semibold 600</p>
<p class="font-bold">Bold 700</p>
<p class="font-black">Black 900</p>Text Alignment
<p class="text-left">Left aligned</p>
<p class="text-center">Centered</p>
<p class="text-right">Right aligned</p>Style & Transform
.italic Italic text.uppercase uppercase text.capitalize capitalized text.underline Underlined text.line-through Strikethrough text.truncate This text will be truncated when too long<p class="italic">Italic</p>
<p class="uppercase">uppercase</p>
<p class="capitalize">capitalize every word</p>
<p class="underline">underlined</p>
<p class="line-through">strikethrough</p>
<p class="truncate">truncated with ellipsis...</p>Line Height
.leading-tight
The quick brown fox jumps over the lazy dog near the riverbank.
.leading-normal
The quick brown fox jumps over the lazy dog near the riverbank.
.leading-relaxed
The quick brown fox jumps over the lazy dog near the riverbank.
.leading-loose
The quick brown fox jumps over the lazy dog near the riverbank.
<p class="leading-tight">tight 1.25</p>
<p class="leading-normal">normal 1.5</p>
<p class="leading-relaxed">relaxed 1.625</p>
<p class="leading-loose">loose 2</p>Text Color
<p class="text-primary">Primary text</p>
<p class="text-secondary">Secondary text</p>
<p class="text-muted">Muted text</p>
<p class="text-success">Success text</p>
<p class="text-danger">Error message</p>
<p class="text-warning">Warning message</p>Background Color
<div class="bg-primary text-white">...</div>
<div class="bg-surface">...</div>
<div class="bg-success text-white">...</div>
<div class="bg-danger text-white">...</div>Border Color
<div class="border border-primary">...</div>
<div class="border border-danger">...</div>
<div class="border-2 border-success">...</div>Borders
<div class="border">all sides</div>
<div class="border-t">top only</div>
<div class="border border-dashed">dashed</div>
<div class="border border-2 border-primary">thick + colored</div>Border Radius
<div class="rounded-sm">slightly rounded</div>
<div class="rounded-md">medium rounded</div>
<div class="rounded-lg">large rounded</div>
<div class="rounded-full">pill / circle</div>Shadows
<div class="shadow-sm rounded-md p-4">subtle shadow</div>
<div class="shadow-md rounded-md p-4">medium shadow</div>
<div class="shadow-lg rounded-md p-4">large shadow</div>
<div class="shadow-xl rounded-md p-4">extra large shadow</div>Opacity
<div class="opacity-100">fully visible</div>
<div class="opacity-75">75%</div>
<div class="opacity-50">50%</div>
<div class="opacity-25">25%</div>
<div class="opacity-0">invisible</div>Transitions
Smooth state changes. Combine with hover/focus/active variants.
<button class="bg-primary bg-primary-hover transition-colors">
Smooth color change
</button>
<div class="shadow-sm shadow-md-hover transition">
Smooth shadow change on hover
</div>Available: .transition .transition-fast .transition-slow .transition-colors .transition-opacity .transition-transform
Cursor
<button class="cursor-pointer">clickable</button>
<span class="cursor-not-allowed opacity-50">disabled</span>Hover Variants
Apply styles only on hover using the -hover suffix. Each color has a dedicated --color-*-hover variable so the shade is independently customizable.
<!-- Background changes on hover -->
<button class="bg-primary bg-primary-hover transition-colors">Button</button>
<!-- Border highlights on hover -->
<div class="border border-primary-hover transition-colors">Card</div>
<!-- Text color changes on hover -->
<a class="text-muted text-primary-hover transition-colors">Link</a>
<!-- Shadow lifts on hover -->
<div class="shadow-sm shadow-md-hover transition">Card</div>
<!-- Opacity dims on hover -->
<img class="opacity-100 opacity-75-hover transition-opacity">Focus Variants
Apply styles on keyboard focus using the -focus suffix. Essential for accessible form inputs.
<input class="border outline-none-focus border-primary-focus transition-colors">
<input class="border border-danger-focus ring-danger-focus">
<!-- ring-focus adds a 2px outline using --color-primary-focus -->
<button class="ring-focus">Keyboard accessible button</button>Active Variants
Apply styles while an element is being pressed using the -active suffix.
<!-- Full interactive state stack -->
<button class="
bg-primary
bg-primary-hover
bg-primary-active
text-white
transition-colors
">
Button
</button>Responsive Variants
Breakpoint variants use a -{breakpoint} suffix and are mobile-first (min-width). Consistent with all other variant naming.
Breakpoints
-sm
640px+
-md
768px+
-lg
1024px+
Column 1
Column 2
...
Extending
Customize tokens or add new utilities in unc-extend.css — loaded after unc.css so everything cascades correctly.
/* unc-extend.css */
/* Override design tokens to retheme the whole library */
:root {
--color-primary: #e11d48;
--color-primary-hover: #be123c;
--color-primary-focus: #9f1239;
--color-primary-active: #881337;
}
/* Add custom component classes built on top of tokens */
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-5);
background: var(--color-primary);
color: #fff;
font-weight: var(--font-medium);
border-radius: var(--radius-md);
border: none;
cursor: pointer;
transition: background var(--transition-fast);
}
.btn:hover { background: var(--color-primary-hover); }
.btn:active { background: var(--color-primary-active); }
.btn-outline {
background: transparent;
color: var(--color-primary);
border: 1px solid var(--color-primary);
}
.btn-outline:hover {
background: var(--color-primary);
color: #fff;
}