policyengine-design
PolicyEngine design system — tokens, typography, colors, charts, and branding for all project types. Triggers: "brand colors", "design tokens", "PolicyEngine colors", "typography", "font", "color palette", "CSS variables", "design system", "branding guidelines"
What this skill does
# PolicyEngine design system
Single source of truth for PolicyEngine's visual identity. Design tokens are defined as CSS custom properties in `@policyengine/ui-kit/theme.css`. Every frontend project imports this single CSS file.
**When to use which format:**
| Context | Approach | Example |
|---------|----------|---------|
| **React components** | Tailwind semantic classes | `className="bg-primary text-foreground"` |
| **Brand palette** | Tailwind direct classes | `className="bg-teal-500 text-gray-600"` |
| **Recharts (SVG)** | CSS vars directly in fill/stroke | `fill="var(--chart-1)"` |
| **Inline styles** | CSS vars | `style={{ color: "var(--primary)" }}` |
| **Python (Plotly)** | Hex with CSS var comment | `TEAL = "#319795" # --chart-1` |
| **`<meta>` tags, static HTML** | Hex values with CSS var name in comment | `content="#319795"` |
Python has no CSS runtime, so hex values are acceptable — but always comment with the CSS var name so values stay traceable to the design system.
## The ui-kit theme
**Install:**
```bash
bun install @policyengine/ui-kit
```
**Import the theme CSS in your `globals.css`:**
```css
@import "tailwindcss";
@import "@policyengine/ui-kit/theme.css";
```
The first line enables Tailwind v4 utilities. The second provides all PE design tokens, `@theme` configuration, and base styles. Both are required — see `policyengine-ui-kit-consumer-skill` for details.
**Source:** `PolicyEngine/policyengine-ui-kit/src/theme/tokens.css`
The theme CSS has three layers:
1. **`:root`** — shadcn/ui semantic variables (`--primary`, `--background`, `--chart-1`, etc.)
2. **`@theme inline`** — Bridges `:root` vars to Tailwind utilities (`bg-primary`, `text-foreground`)
3. **`@theme`** — Brand palette (`bg-teal-500`, `text-gray-600`), font sizes, spacing, breakpoints
## Colors
### Primary — teal
| Token | Hex | Tailwind class | Usage |
|-------|-----|---------------|-------|
| `teal-500` | `#319795` | `bg-teal-500` | **Main brand color** — charts, highlights |
| `teal-400` | `#38B2AC` | `bg-teal-400` | Lighter interactive elements |
| `teal-600` | `#2C7A7B` | `bg-teal-600` / `bg-primary` | Hover state, buttons |
| `teal-700` | `#285E61` | `bg-teal-700` | Active/pressed state |
| `teal-50` | `#E6FFFA` | `bg-teal-50` | Tinted backgrounds |
| `teal-800` | `#234E52` | `bg-teal-800` | Dark text on light teal |
### Semantic (shadcn/ui)
| Role | CSS variable | Tailwind class | Hex |
|------|-------------|---------------|-----|
| Primary | `--primary` | `bg-primary` | `#2C7A7B` |
| Background | `--background` | `bg-background` | `#FFFFFF` |
| Foreground | `--foreground` | `text-foreground` | `#000000` |
| Muted | `--muted` | `bg-muted` | `#F2F4F7` |
| Muted foreground | `--muted-foreground` | `text-muted-foreground` | `#6B7280` |
| Border | `--border` | `border-border` | `#E2E8F0` |
| Destructive | `--destructive` | `bg-destructive` | `#DC2626` |
| Card | `--card` | `bg-card` | `#FFFFFF` |
| Ring | `--ring` | `ring-ring` | `#319795` |
### Charts
| CSS variable | Tailwind class | Hex | Usage |
|-------------|---------------|-----|-------|
| `--chart-1` | `fill-chart-1` | `#319795` | Primary series (teal) |
| `--chart-2` | `fill-chart-2` | `#0EA5E9` | Secondary series (blue) |
| `--chart-3` | `fill-chart-3` | `#285E61` | Tertiary series (dark teal) |
| `--chart-4` | `fill-chart-4` | `#026AA2` | Quaternary series (dark blue) |
| `--chart-5` | `fill-chart-5` | `#6B7280` | Quinary series (gray) |
### Additional semantic colors
These are the **brand fill** values — use for status dots, badges, and tinted surfaces. They are *not* WCAG-AA-compliant when set as text on a white background; for text, use the accessible-on-white variants below.
| Color | Hex | Tailwind class |
|-------|-----|---------------|
| Success | `#22C55E` | `text-success` / `bg-success` |
| Error | `#DC2626` | `text-destructive` / `bg-destructive` |
| Warning | `#FEC601` | `text-warning` / `bg-warning` |
| Info | `#1890FF` | `text-info` / `bg-info` |
### Accessible-on-white text variants
Distinct from the brand fills above — these are the values you use when you actually need to render colored text on a white background and want to clear WCAG 2.2 AA (4.5:1 contrast at small text). Available since ui-kit 0.5.0 as `--text-warning` / `--text-error` / `--text-success` and the corresponding Tailwind utilities.
| Token | Hex | Tailwind class | Contrast on white |
|-------|-----|---------------|-------------------|
| `--text-warning` | `#c2410c` (Tailwind orange-700) | `text-warning-foreground` | 5.18:1 ✓ |
| `--text-error` | `#B91C1C` (Tailwind red-700) | `text-error-foreground` | 5.94:1 ✓ |
| `--text-success` | `#285E61` (PE teal-700) | `text-success-foreground` | 7.07:1 ✓ |
The plain `text-warning` / `text-destructive` / `text-success` brand classes are intentionally *not* AA on white — they're meant for soft-tinted backgrounds and badge fills, not paragraph text.
### Dark mode
Available since ui-kit 0.6.0. Activate by adding `class="dark"` to any ancestor element — no JS or media query required. Every shadcn semantic token (`--primary`, `--background`, `--card`, `--border`, etc.) and accessible text variant has a dark-mode value pinned to clear AA on the dark page background `#0B0E14`. Dark-mode values are tested by `tests/theme/contrast.test.ts` in ui-kit and exposed under the `:root.dark` selector in `theme.css`.
```html
<!-- consumer site dark-mode toggle: just toggle the .dark class on <html> -->
<html class="dark">
...
</html>
```
If you're rendering charts, prefer the CSS-var form (`fill="var(--chart-1)"`) over a hex literal — that way the chart picks up dark-mode swaps automatically. For Plotly / Python where there's no CSS runtime, use `chartPalette.light` and `chartPalette.dark` from `@policyengine/ui-kit` and pick by detected theme.
### Gray scale
ui-kit's `palette.gray` is Slate-flavored (matches the dashboard's neutral surfaces and `--border` / `--muted` tokens). The legacy `@policyengine/ui-kit/legacy/tokens` shim still exports the Tailwind-3 grays (`#6B7280` for 500, `#4B5563` for 600) for design-system migration parity, but new code should use the canonical Slate values below.
| Token | Hex | Tailwind class |
|-------|-----|---------------|
| `gray-50` | `#F0F9FF` | `bg-gray-50` |
| `gray-100` | `#F2F4F7` | `bg-gray-100` |
| `gray-200` | `#E2E8F0` | `bg-gray-200` |
| `gray-300` | `#CBD5E1` | `bg-gray-300` |
| `gray-400` | `#94A3B8` | `bg-gray-400` |
| `gray-500` | `#64748B` | `text-gray-500` |
| `gray-600` | `#475569` | `text-gray-600` |
| `gray-700` | `#344054` | `text-gray-700` |
| `gray-800` | `#1E293B` | `text-gray-800` |
| `gray-900` | `#101828` | `text-gray-900` |
## Typography
### Font families
**Two font families only: Inter + JetBrains Mono.** No serif fonts, no Roboto, no Public Sans.
| Context | Font | CSS variable | Tailwind |
|---------|------|-------------|----------|
| **Everything** (UI, charts, blog, tools) | Inter | `--font-sans` | `font-sans` |
| **Code** | JetBrains Mono | `--font-mono` | `font-mono` |
**Loading Inter:**
```html
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
```
### Font sizes
| Tailwind class | Size | Usage |
|---------------|------|-------|
| `text-xs` | 12px | Small labels, captions |
| `text-sm` | 14px | Body text, form labels |
| `text-base` | 16px | Large body text |
| `text-lg` | 18px | Subheadings |
| `text-xl` | 20px | Section titles |
| `text-2xl` | 24px | Page titles |
| `text-3xl` | 28px | Large headings |
### Sentence case
All UI text uses sentence case — capitalize only the first word and proper nouns.
- "Your saved policies" not "Your Saved Policies"
- "Tax liability by income" not "Tax Liability by Income"
- Proper nouns stay capitalized: "Child Tax Credit", "PolicyEngine", "California"
## Spacing
Standard Tailwind spacing classes (`p-4`, `gap-2`, `m-6`) use the default Tailwind scale. Named spacing tokens:
| Token | VRelated in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".