Skip to content

AnglinAI Color System (v2)

The v2 color system lives in @anglinai/ui and provides a WCAG AAA-compliant palette, semantic CSS custom properties, Tailwind utilities, and a dark-mode ThemeProvider. All AnglinAI projects should use it.


Approved Palette

Every production token meets WCAG AAA (7:1 minimum) contrast ratio on the stated background.

TokenHexOnRatioLevel
Primary (deep blue)#054fb9white7.3:1βœ… AAA
Primary hover#0057b0white7.1:1βœ… AAA
Accent / sky blue#8babf1black9.2:1βœ… AAA
Secondary (dark orange)#8b3200white7.2:1βœ… AAA
Vivid orange#f57600black7.4:1βœ… AAA

Aspirational tokens (AA only on white β€” stored as references, not for direct use in UI):

TokenHexRatioNote
#0073e6mid blue4.6:1 AADesign reference only
#c44601orange4.8:1 AADesign reference only

Never use teal or green in any AnglinAI UI β€” see global CLAUDE.md.


CSS Custom Properties

After importing @anglinai/ui/theme.css, these variables are available everywhere.

Semantic tokens (use these in components)

/* Light mode values shown. Dark mode inverts automatically via .dark class. */
/* Primary */
--anglin-color-primary /* #054fb9 light / #8babf1 dark */
--anglin-color-primary-hover /* #0057b0 light / #a5bff5 dark */
--anglin-color-primary-active /* #03368a light / #c0d3f9 dark */
--anglin-color-primary-subtle /* #dde8fb light / #1a2d5a dark */
--anglin-color-on-primary /* #ffffff light / #000000 dark */
/* Secondary */
--anglin-color-secondary /* #8b3200 light / #f57600 dark */
--anglin-color-secondary-hover /* #7a2b00 light / #f78c1f dark */
--anglin-color-secondary-subtle /* #fdebd6 light / #3d1e00 dark */
--anglin-color-on-secondary /* #ffffff light / #000000 dark */
/* Accent */
--anglin-color-accent /* #8babf1 light / #0057b0 dark */
--anglin-color-on-accent /* #000000 light / #ffffff dark */
/* Vivid */
--anglin-color-vivid /* #f57600 both modes */
--anglin-color-on-vivid /* #000000 both modes */
/* Surfaces */
--anglin-color-surface /* #ffffff light / #0f172a dark */
--anglin-color-surface-subtle /* #f8fafc light / #1e293b dark */
--anglin-color-surface-muted /* #eff6ff light / #162044 dark */
--anglin-color-on-surface /* #0f172a light / #f1f5f9 dark */
--anglin-color-on-surface-muted /* #475569 light / #94a3b8 dark */
/* Borders & focus */
--anglin-color-border /* #e2e8f0 light / #334155 dark */
--anglin-color-focus-ring /* #054fb9 light / #8babf1 dark */

Palette reference tokens (raw values β€” not for components)

--anglin-palette-blue-deep /* #054fb9 */
--anglin-palette-blue-hover-aaa /* #0057b0 */
--anglin-palette-blue-sky /* #8babf1 */
--anglin-palette-orange-dark-aaa /* #8b3200 */
--anglin-palette-orange-vivid /* #f57600 */
/* Aspirational (AA only) */
--anglin-palette-blue-mid /* #0073e6 */
--anglin-palette-orange-dark /* #c44601 */

Usage in plain CSS

.my-button {
background-color: var(--anglin-color-primary);
color: var(--anglin-color-on-primary);
}
.my-button:hover {
background-color: var(--anglin-color-primary-hover);
}

Tailwind Utilities

After adding @anglinai/ui as a Tailwind preset, these classes are available.

Setting up the preset

tailwind.config.js
module.exports = {
darkMode: 'class',
presets: [require('@anglinai/ui/tailwind-preset')],
content: [
'./src/**/*.{ts,tsx}',
'./node_modules/@anglinai/ui/dist/**/*.{js,mjs}',
],
};

Available classes

All anglin-* utilities support Tailwind opacity modifiers (e.g. bg-anglin-primary/80).

bg-anglin-primary text-anglin-primary border-anglin-primary
bg-anglin-primary-hover hover:bg-anglin-primary-hover
bg-anglin-primary-subtle text-anglin-primary-subtle
bg-anglin-on-primary text-anglin-on-primary
bg-anglin-secondary text-anglin-secondary
bg-anglin-secondary-hover hover:bg-anglin-secondary-hover
bg-anglin-secondary-subtle
bg-anglin-on-secondary text-anglin-on-secondary
bg-anglin-accent text-anglin-accent
bg-anglin-on-accent text-anglin-on-accent
bg-anglin-vivid text-anglin-vivid
bg-anglin-on-vivid text-anglin-on-vivid
bg-anglin-surface bg-anglin-surface-subtle bg-anglin-surface-muted
text-anglin-on-surface text-anglin-on-surface-muted
border-anglin-border

Static hex classes (for SVG/canvas where CSS vars don’t work)

bg-anglin-static-blue-deep text-anglin-static-blue-deep
bg-anglin-static-blue-hover
bg-anglin-static-blue-sky text-anglin-static-blue-sky
bg-anglin-static-orange-dark
bg-anglin-static-orange-vivid text-anglin-static-orange-vivid

Example component

<button className="bg-anglin-primary text-anglin-on-primary hover:bg-anglin-primary-hover px-4 py-2 rounded-lg">
Save changes
</button>
<div className="bg-anglin-surface-subtle border border-anglin-border rounded-xl p-6">
<p className="text-anglin-on-surface">Content here</p>
<p className="text-anglin-on-surface-muted">Supporting text</p>
</div>

Dark Mode Setup

1. Import theme.css

In your root globals.css, import before @tailwind directives:

@import '@anglinai/ui/theme.css';
@tailwind base;
@tailwind components;
@tailwind utilities;

2. Add ThemeScript to prevent FOUC

In your root layout.tsx (Next.js App Router), place ThemeScript inside <head> before the first paint:

import { ThemeScript, ThemeProvider } from '@anglinai/ui';
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<ThemeScript />
</head>
<body>
<ThemeProvider defaultTheme="system">
{children}
</ThemeProvider>
</body>
</html>
);
}

suppressHydrationWarning on <html> is required because ThemeScript modifies the class list before React hydrates.

3. Use the useTheme hook

'use client';
import { useTheme } from '@anglinai/ui';
export function ThemeToggle() {
const { theme, resolvedTheme, setTheme } = useTheme();
return (
<button onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}>
{resolvedTheme === 'dark' ? 'β˜€οΈ Light' : 'πŸŒ™ Dark'}
</button>
);
}

useTheme returns

FieldTypeDescription
theme'light' | 'dark' | 'system'The stored user preference
resolvedTheme'light' | 'dark'What is actually rendered right now
setTheme(t: Theme) => voidPersists to localStorage and applies immediately

The default localStorage key is anglin-theme. Override it via <ThemeScript storageKey="my-key" /> and <ThemeProvider storageKey="my-key">.

How dark mode works

  1. ThemeScript runs as a blocking inline script before paint β€” reads localStorage, falls back to prefers-color-scheme, sets class="dark" and data-theme="dark" on <html>.
  2. Tailwind’s darkMode: 'class' activates the .dark variant for all dark:* utilities.
  3. All --anglin-* CSS variables defined in theme.css swap to their dark-mode values inside .dark {}.
  4. ThemeProvider manages React state and re-syncs on system preference changes when theme === 'system'.

TypeScript: Color Palette Constants

Import raw palette values for non-CSS contexts (e.g. chart libraries, canvas, email templates):

import { COLOR_PALETTE, CONTRAST_TABLE } from '@anglinai/ui';
// Use in a chart config
const chartColors = {
primary: COLOR_PALETTE.blueDeep, // '#054fb9'
secondary: COLOR_PALETTE.orangeVivid, // '#f57600'
};
// Print contrast audit
CONTRAST_TABLE.forEach(({ token, ratio, wcag }) =>
console.log(`${token}: ${ratio} ${wcag}`)
);

COLOR_PALETTE keys

KeyValueWCAG
blueDeep#054fb9AAA
blueHoverAaa#0057b0AAA
blueSky#8babf1AAA
orangeDarkAaa#8b3200AAA
orangeVivid#f57600AAA
blueMid#0073e6AA (reference)
orangeDark#c44601AA (reference)

Installation in a New Project

Terminal window
# Add .npmrc if not present
echo "@anglinai:registry=https://npm.pkg.github.com" >> .npmrc
echo "//npm.pkg.github.com/:_authToken=\${NODE_AUTH_TOKEN}" >> .npmrc
NODE_AUTH_TOKEN=<your-github-pat> npm install @anglinai/ui

Then follow the Dark Mode Setup section above.


Migration: Replacing Old Colors

These search patterns find old primary blues and orange accents to migrate to v2 utilities:

Terminal window
# Old primary blues
grep -rn "#2563eb\|#1d4ed8\|#1e40af\|#0284c7\|#0369a1\|#0ea5e9" src/
# Old orange/accent values
grep -rn "#f97316\|#ea580c\|#1E40AF\|#3B82F6" src/
# Old Tailwind primary-scale classes
grep -rn "bg-primary-\|text-primary-\|border-primary-\|ring-primary-" src/

Known hardcoded values to migrate later

accessible-org-chart:

  • src/utils/versionCheck.ts:33 β€” 'color: #2563eb' β†’ 'color: #054fb9'
  • src/components/templates/org-chart-radial/themes.ts β€” SVG theme colors (use anglin-static-* values)
  • src/app/preview/page.tsx:45 β€” '#1e40af' in color picker preset

Replacement map

Old valueNew CSS varNew Tailwind class
#2563ebvar(--anglin-color-primary)text-anglin-primary
#1d4ed8var(--anglin-color-primary-hover)bg-anglin-primary-hover
#1e40afvar(--anglin-color-primary)bg-anglin-primary
#0284c7var(--anglin-color-primary)bg-anglin-primary
#eff6ffvar(--anglin-color-surface-muted)bg-anglin-surface-muted
#f8fafcvar(--anglin-color-surface-subtle)bg-anglin-surface-subtle
#f97316var(--anglin-color-vivid)bg-anglin-vivid

Files Reference

FilePackage pathPurpose
src/theme.css@anglinai/ui/theme.cssCSS vars only β€” safe to import anywhere
src/globals.css@anglinai/ui/globals.cssCSS vars + @tailwind directives β€” use in the UI package itself
tailwind.config.cjs@anglinai/ui/tailwind-presetTailwind preset with all anglin-* utilities
src/tokens/palette.ts@anglinai/ui (named export)COLOR_PALETTE, CONTRAST_TABLE, PaletteColor
src/components/theme-provider.tsx@anglinai/ui (named export)ThemeProvider, useTheme, Theme type
src/components/theme-script.tsx@anglinai/ui (named export)ThemeScript β€” FOUC prevention

Changelog

VersionDateChanges
v0.2.02026-02-24v2 color system β€” WCAG AAA palette, CSS vars, Tailwind preset, ThemeProvider, ThemeScript
v0.1.12025Initial release with legacy anglin.deep-blue utilities