Skip to content
Back to skills

003 Name Skill 49d571ca

ASecurity

PolicyEngine design system — tokens, typography, colors, charts, and branding for all project types

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 11, 2026
designtypescriptpythongobashreactgitapi

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 003-name-skill_49d571ca --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 003 Name Skill 49d571ca?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 003 Name Skill 49d571ca
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-003-name-skill-49d571ca/badge)](https://www.skillsdirectory.com/skills/tools-only-003-name-skill-49d571ca)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: policyengine-design
description: PolicyEngine design system — tokens, typography, colors, charts, and branding for all project types
---

# PolicyEngine design system

Single source of truth for PolicyEngine's visual identity. All tokens live in `@policyengine/design-system` (npm). Every project — app-v2, standalone tools, charts, Streamlit — should reference these values rather than hardcoding hex codes.

## The design system package

**Install:**
```bash
npm install @policyengine/design-system
```

**Three export formats:**

| Format | Import | Use case |
|--------|--------|----------|
| TypeScript | `import { colors } from '@policyengine/design-system/tokens'` | app-v2, any TS/JS project |
| JSON | `import tokens from '@policyengine/design-system/tokens.json'` | Python scripts, config files |
| CSS | `import '@policyengine/design-system/tokens.css'` | Standalone tools, plain HTML |

**CDN (no install):**
```html
<link rel="stylesheet" href="https://unpkg.com/@policyengine/design-system/dist/tokens.css">
```

**Source:** `PolicyEngine/policyengine-app-v2/packages/design-system/`

## Colors

### Primary — teal

| Token | Hex | Usage |
|-------|-----|-------|
| `primary.500` | `#319795` | **Main brand color** — buttons, links, active states |
| `primary.400` | `#38B2AC` | Lighter interactive elements |
| `primary.600` | `#2C7A7B` | Hover state |
| `primary.700` | `#285E61` | Active/pressed state |
| `primary.50` | `#E6FFFA` | Tinted backgrounds |
| `primary.800` | `#234E52` | Dark text on light teal |

CSS: `var(--pe-color-primary-500)` through `var(--pe-color-primary-900)`

### Gray

| Token | Hex | Usage |
|-------|-----|-------|
| `gray.50` | `#F9FAFB` | Subtle backgrounds |
| `gray.100` | `#F2F4F7` | Card backgrounds |
| `gray.200` | `#E2E8F0` | Borders, dividers |
| `gray.500` | `#6B7280` | Secondary text |
| `gray.600` | `#4B5563` | Chart secondary series |
| `gray.700` | `#344054` | Dark UI text |

### Blue (accent)

| Token | Hex | Usage |
|-------|-----|-------|
| `blue.500` | `#0EA5E9` | Informational highlights |
| `blue.700` | `#026AA2` | Chart secondary series |

### Semantic

| Color | Hex | CSS variable | Usage |
|-------|-----|-------------|-------|
| Success | `#22C55E` | `--pe-color-success` | Positive changes, gains |
| Error | `#EF4444` | `--pe-color-error` | Negative changes, losses |
| Warning | `#FEC601` | `--pe-color-warning` | Cautions, alerts |
| Info | `#1890FF` | `--pe-color-info` | Informational |

### Text

| Token | Hex | CSS variable |
|-------|-----|-------------|
| `text.primary` | `#000000` | `--pe-color-text-primary` |
| `text.secondary` | `#5A5A5A` | `--pe-color-text-secondary` |
| `text.tertiary` | `#9CA3AF` | `--pe-color-text-tertiary` |

### Background

| Token | Hex | CSS variable |
|-------|-----|-------------|
| `background.primary` | `#FFFFFF` | `--pe-color-bg-primary` |
| `background.secondary` | `#F5F9FF` | `--pe-color-bg-secondary` |
| `background.tertiary` | `#F1F5F9` | `--pe-color-bg-tertiary` |

### Legacy colors (deprecated)

These appear in older projects. Migrate to the values above.

| Old | Hex | Replacement |
|-----|-----|-------------|
| `TEAL_ACCENT` | `#39C6C0` | `primary.500` (`#319795`) |
| `BLUE_PRIMARY` | `#2C6496` | `blue.700` (`#026AA2`) |
| `DARK_GRAY` | `#616161` | `text.secondary` (`#5A5A5A`) |

## Typography

### Font families

**Two font families only: Inter + JetBrains Mono.** No serif fonts, no Roboto, no Public Sans.

| Context | Font | CSS variable |
|---------|------|-------------|
| **Everything** (UI, charts, blog, tools) | Inter | `--pe-font-family-primary` |
| **Code** | JetBrains Mono | `--pe-font-family-mono` |

Legacy aliases (`--pe-font-family-chart`, `--pe-font-family-body`, `--pe-font-family-prose`, `--pe-font-family-secondary`) all resolve to Inter for backward compatibility.

**Loading Inter:**
```html
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
```

### Font sizes

| Token | Size | Usage |
|-------|------|-------|
| `xs` | 12px | Small labels, captions |
| `sm` | 14px | Body text, form labels |
| `base` | 16px | Large body text |
| `lg` | 18px | Subheadings |
| `xl` | 20px | Section titles |
| `2xl` | 24px | Page titles |
| `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

| Token | Value | CSS variable |
|-------|-------|-------------|
| `xs` | 4px | `--pe-space-xs` |
| `sm` | 8px | `--pe-space-sm` |
| `md` | 12px | `--pe-space-md` |
| `lg` | 16px | `--pe-space-lg` |
| `xl` | 20px | `--pe-space-xl` |
| `2xl` | 24px | `--pe-space-2xl` |
| `3xl` | 32px | `--pe-space-3xl` |
| `4xl` | 48px | `--pe-space-4xl` |

### Border radius

| Token | Value | CSS variable |
|-------|-------|-------------|
| `sm` | 4px | `--pe-radius-sm` |
| `md` | 6px | `--pe-radius-md` |
| `lg` | 8px | `--pe-radius-lg` |

## Chart branding

### Plotly (Python)

```python
import plotly.graph_objects as go

# Import from tokens.json or hardcode
TEAL = "#319795"
CHART_FONT = "Inter"
LOGO_URL = "https://raw.githubusercontent.com/PolicyEngine/policyengine-app-v2/main/app/public/assets/logos/policyengine/teal.png"

def format_fig(fig):
    fig.update_layout(
        font=dict(family=CHART_FONT, color="black", size=14),
        plot_bgcolor="white",
        paper_bgcolor="white",
        template="plotly_white",
        height=600,
        width=800,
        margin=dict(l=60, r=40, t=40, b=60),
        modebar=dict(bgcolor="rgba(0,0,0,0)", color="rgba(0,0,0,0)"),
    )
    fig.add_layout_image(dict(
        source=LOGO_URL,
        xref="paper", yref="paper",
        x=1.0, y=-0.10,
        sizex=0.10, sizey=0.10,
        xanchor="right", yanchor="bottom",
    ))
    return fig
```

### Recharts (React standalone tools)

```jsx
import { BarChart, Bar, XAxis, YAxis, Tooltip } from "recharts";

<BarChart data={data}>
  <XAxis dataKey="name" style={{ fontFamily: "Inter" }} />
  <YAxis style={{ fontFamily: "Inter" }} />
  <Tooltip />
  <Bar dataKey="value" fill="#319795" />
</BarChart>
```

### Chart color conventions

| Meaning | Color | Hex |
|---------|-------|-----|
| Positive / bonus / gains | Teal | `#319795` |
| Negative / penalty / losses | Gray or red | `#4B5563` or `#EF4444` |
| Neutral / baseline | Light gray | `#E2E8F0` |
| Multi-series | Series array | `#319795`, `#0EA5E9`, `#285E61`, `#026AA2`, `#6B7280` |

**Inverted metrics (taxes):** When a positive delta means bad (higher taxes), use `invertDelta` logic to show "Penalty" label and swap colors.

### Chart typography

- **Axis labels and titles:** Inter, 14px
- **Tick labels:** Inter, 12px
- **Legend:** Inter, horizontal, above chart

## Logos

All logo files in `policyengine-app-v2/app/public/assets/logos/policyengine/`:

| File | Background | Format |
|------|-----------|--------|
| `teal.png` / `teal.svg` | Light | Wide |
| `teal-square.png` / `teal-square.svg` | Light | Square (for chart watermarks) |
| `white.png` / `white.svg` | Dark | Wide |
| `white-square.svg` | Dark | Square |

**Raw URL for charts:**
```
https://raw.githubusercontent.com/PolicyEngine/policyengine-app-v2/main/app/public/assets/logos/policyengine/teal.png
```

## Streamlit apps

```toml
# .streamlit/config.toml
[theme]
base = "light"
primaryColor = "#319795"
backgroundColor = "#FFFFFF"
secondaryBackgroundColor = "#E6FFFA"
textColor = "#000000"

[client]
toolbarMode = "minimal"
```

## Using tokens by project type

| Project type | Token source | Font setup |
|-------------|-------------|------------|
| **app-v2** | `import { colors } from '@/designTokens'` | Built-in (Mantine + Inter) |
| **Standalone tool** | `@import tokens.css` or CDN link | Google Fonts: Inter |
| **Python chart** | Hardcode or load `tokens.json` | Inter for Plotly |
| **Streamlit** | `.streamlit/config.toml` | Default sans-serif |
| **Blog HTML** | Hardcode from token values | Google Fonts: Inter |

## Accessibility

- Teal `#319795` on white passes WCAG AA for large text (3.8:1)
- `text.primary` (`#000000`) on white passes AAA (21:1)
- `text.secondary` (`#5A5A5A`) on white passes AA (7.4:1)
- Never rely on color alone — use labels, patterns, or position to convey meaning
- Ensure chart data series are distinguishable in grayscale

## Related skills

- `policyengine-interactive-tools-skill` — Building standalone tools that use these tokens
- `policyengine-vercel-deployment-skill` — Deploying standalone tools
- `policyengine-app-skill` — app-v2 development
- `policyengine-writing-skill` — Content style (complements visual style)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.