npm package: @pantograph/tokens
Description: Design tokens are the visual design atoms of the design system — specifically, they are named entities that store visual design attributes. They're used in place of hard-coded values (such as hex values for color or pixel values for spacing) to maintain a
Author: sedmedgh
Latest version: 1.0.12

# Pantograph Design Tokens

Design tokens are the visual design atoms of the design system — specifically, they are named entities that store visual design attributes. They're used in place of hard-coded values (such as hex values for color or pixel values for spacing) to maintain a scalable and consistent visual system for UI development.

This package contains CSS tokens that synchronize design (Figma) and development, ensuring consistency across all platforms and implementations.

## Token Naming Convention

**All tokens are mapped to use the `--pt-*` prefix** for easy usage, regardless of their original prefix in the JSON files. This provides a consistent and simple API for developers.

- **All tokens**: `--pt-*` (Pantograph Token)
- **No need to remember different prefixes** - everything uses `--pt-*`

## Token Categories

### Colors

#### Alpha Colors
Transparency values for overlays and effects:

| Token Name        | Value     | Description |
|-------------------|-----------|-------------|
| `--pt-alpha-gray-0` | `rgba(0, 0, 0, 0)` | Transparent |
| `--pt-alpha-gray-1` | `rgba(0, 0, 0, 0.04)` | 4% opacity |
| `--pt-alpha-gray-2` | `rgba(0, 0, 0, 0.08)` | 8% opacity |
| `--pt-alpha-gray-3` | `rgba(0, 0, 0, 0.24)` | 24% opacity |
| `--pt-alpha-gray-4` | `rgba(0, 0, 0, 0.4)` | 40% opacity |
| `--pt-alpha-gray-5` | `rgba(0, 0, 0, 0.64)` | 64% opacity |

#### Primitive Colors
Complete primitive color palette with all color families:

**Alpha Colors:**
- `--pt-alpha-gray-0` to `--pt-alpha-gray-5` (transparency values)

**Amber Colors:**
- `--pt-amber-0` to `--pt-amber-9` (lightest to darkest)

**Amethyst Colors:**
- `--pt-amethyst-0` to `--pt-amethyst-9` (lightest to darkest)

**Blue Colors:**
- `--pt-blue-0` to `--pt-blue-9` (lightest to darkest)

**Cyan Colors:**
- `--pt-cyan-0` to `--pt-cyan-9` (lightest to darkest)

**Fuchsia Colors:**
- `--pt-fuchsia-0` to `--pt-fuchsia-9` (lightest to darkest)

**Gray Colors:**
- `--pt-gray-0`, `--pt-gray-05`, `--pt-gray-1` to `--pt-gray-10` (lightest to darkest)

**Green Colors:**
- `--pt-green-0` to `--pt-green-9` (lightest to darkest)

**Lime Colors:**
- `--pt-lime-0` to `--pt-lime-9` (lightest to darkest, note: `--pt-lime-6` is missing)

**Mallard Colors:**
- `--pt-mallard-0` to `--pt-mallard-9` (lightest to darkest)

**Ocean Colors:**
- `--pt-ocean-0` to `--pt-ocean-9` (lightest to darkest)

**Orange Colors:**
- `--pt-orange-0` to `--pt-orange-9` (lightest to darkest)

**Pink Colors:**
- `--pt-pink-0` to `--pt-pink-9` (lightest to darkest)

**Red Colors:**
- `--pt-red-0` to `--pt-red-9` (lightest to darkest)

**Sky Colors:**
- `--pt-sky-0` to `--pt-sky-9` (lightest to darkest)

**Teal Colors:**
- `--pt-teal-0` to `--pt-teal-9` (lightest to darkest)

**Violet Colors:**
- `--pt-violet-0` to `--pt-violet-9` (lightest to darkest)

**Yellow Colors:**
- `--pt-yellow-0` to `--pt-yellow-9` (lightest to darkest)


#### Semantic Color Tokens
Pre-configured semantic color tokens with complete state variants:

**Blue Tokens:**
- `--pt-blue-br` - Primary blue border
- `--pt-blue-br-subtle` - Light blue border
- `--pt-blue-br-subtle-target` - Hover state
- `--pt-blue-br-subtle-trigger` - Active state
- `--pt-blue-br-target` - Dark blue border
- `--pt-blue-br-trigger` - Darkest blue border
- `--pt-blue-fg` - Blue foreground
- `--pt-blue-fg-subtle` - Light blue foreground
- `--pt-blue-fill` - Blue fill
- `--pt-blue-fill-subtle` - Light blue fill

**Gray Tokens:**
- `--pt-gray-br` - Gray border
- `--pt-gray-br-subtle` - Light gray border
- `--pt-gray-fg` - Gray foreground
- `--pt-gray-fg-subtle` - Light gray foreground
- `--pt-gray-fill` - Gray fill
- `--pt-gray-fill-subtle` - Light gray fill

**Primary Tokens:**
- `--pt-primary-br` - Primary border
- `--pt-primary-fg` - Primary foreground
- `--pt-primary-fill` - Primary fill
- `--pt-primary-oncolor` - Text color on primary backgrounds

**Status Tokens:**
- `--pt-danger-*` - Error/danger colors
- `--pt-success-*` - Success colors
- `--pt-warning-*` - Warning colors
- `--pt-info-*` - Information colors
- `--pt-disable-*` - Disabled state colors

#### Theme Classes
Themes are applied via CSS classes that change token values:

**Light Theme:**
```css
.pantograph-light {
  /* Light mode color values */
}
```

**Dark Theme:**
```css
.pantograph-dark {
  /* Dark mode color values */
}
```

**Brand Themes:**
```css
.oktuple-theme { /* Ocean blue primary colors */ }
.claytap-theme { /* Sky blue primary colors */ }
.agility-theme { /* Mallard green primary colors */ }
.pantograph-theme { /* Blue primary colors */ }
.bounteco-theme { /* Amethyst purple primary colors */ }
```

**Gray Scale Themes:**
```css
.pantograph-arsenic { /* Arsenic gray scale */ }
.pantograph-cool { /* Cool gray scale */ }
.pantograph-warm { /* Warm gray scale */ }
.pantograph-neutral { /* Neutral gray scale */ }
```

### Spacing & Dimensions

#### Spacing Scale
| Token Name        | Value  | Usage |
|-------------------|--------|-------|
| `--pt-space-0`    | `0px`  | No spacing |
| `--pt-space-100`  | `2px`  | Micro spacing |
| `--pt-space-200`  | `4px`  | Small spacing |
| `--pt-space-300`  | `6px`  | Small-medium spacing |
| `--pt-space-400`  | `8px`  | Medium spacing |
| `--pt-space-600`  | `12px` | Large spacing |
| `--pt-space-800`  | `16px` | Extra large spacing |
| `--pt-space-1000` | `20px` | Huge spacing |
| `--pt-space-1200` | `24px` | Huge spacing |
| `--pt-space-1600` | `32px` | Massive spacing |
| `--pt-space-2000` | `40px` | Massive spacing |
| `--pt-space-2400` | `48px` | Massive spacing |
| `--pt-space-2800` | `56px` | Massive spacing |
| `--pt-space-3200` | `64px` | Massive spacing |
| `--pt-space-4000` | `80px` | Massive spacing |
| `--pt-space-4800` | `96px` | Massive spacing |

#### Size Scale
| Token Name        | Value  | Usage |
|-------------------|--------|-------|
| `--pt-size-3xsm`  | `14px` | Extra small |
| `--pt-size-2xsm`  | `16px` | Very small |
| `--pt-size-xsm`   | `20px` | Small |
| `--pt-size-sm`    | `24px` | Small-medium |
| `--pt-size-md`    | `32px` | Medium |
| `--pt-size-lg`    | `40px` | Large |
| `--pt-size-xlg`   | `48px` | Extra large |
| `--pt-size-2xlg`  | `56px` | Very large |
| `--pt-size-3xlg`  | `80px` | Huge |

#### Border Radius
| Token Name            | Value  | Usage |
|-----------------------|--------|-------|
| `--pt-roundness-zero` | `0px`  | No radius |
| `--pt-roundness-sm`   | `4px`  | Small radius |
| `--pt-roundness-md`   | `6px`  | Medium radius |
| `--pt-roundness-lg`   | `8px`  | Large radius |
| `--pt-roundness-xlg`  | `12px` | Extra large radius |
| `--pt-roundness-full` | `88px` | Full radius (circular) |

#### Stroke Width
| Token Name        | Value  | Usage |
|-------------------|--------|-------|
| `--pt-stroke-0`   | `0px`  | No stroke |
| `--pt-stroke-10`  | `1px`  | Thin stroke |
| `--pt-stroke-15`  | `1.5px`| Thin-medium stroke |
| `--pt-stroke-20`  | `2px`  | Medium stroke |
| `--pt-stroke-30`  | `3px`  | Thick stroke |
| `--pt-stroke-40`  | `4px`  | Very thick stroke |

#### Screen Dimensions
| Token Name              | Value   | Usage |
|-------------------------|---------|-------|
| `--pt-screen-min-height`| `1024px`| Minimum screen height |
| `--pt-screen-min-width` | `1440px`| Minimum screen width |
| `--pt-screen-max-width` | `1920px`| Maximum screen width |

### Typography

#### Font Family
Font families are applied via CSS classes:

**Persian Text:**
```css
.fa, [lang="fa"] {
  --pt-font-family: notocoloremoji, iranyekan, inter, tahoma, serif;
}
```

**English Text:**
```css
.en, [lang="en"] {
  --pt-font-family: notocoloremoji, inter, tahoma, serif;
}
```

#### Font Weights
| Token Name                   | Value    | Usage |
|------------------------------|----------|-------|
| `--pt-font-weight-bold`      | `bold`   | Bold text |
| `--pt-font-weight-medium`    | `medium` | Medium weight |
| `--pt-font-weight-regular`   | `regular`| Regular weight |

#### Line Heights
Line heights are applied via CSS classes:

**Title Line Heights:**
```css
.title, .pantograph-tokens {
  --pt-lineheight-1: 38px;
  --pt-lineheight-2: 28px;
  --pt-lineheight-3: 24px;
  --pt-lineheight-4: 20px;
  --pt-lineheight-5: 18px;
  --pt-lineheight-6: 16px;
  --pt-lineheight-7: 14px;
  --pt-lineheight-8: 12px;
}
```

**Paragraph Line Heights:**
```css
.paragraph {
  --pt-lineheight-1: 48px;
  --pt-lineheight-2: 32px;
  --pt-lineheight-3: 24px;
  --pt-lineheight-4: 24px;
  --pt-lineheight-5: 28px;
  --pt-lineheight-6: 24px;
  --pt-lineheight-7: 20px;
  --pt-lineheight-8: 18px;
}
```

### Levels (Indentation)

#### Level System
The level system provides dynamic indentation based on nesting depth:

| Token Name               | Value  | Usage |
|--------------------------|--------|-------|
| `--pt-level`             | `0`    | Current nesting level |
| `--pt-level-padding-sm`  | `calc(4px + 20px * level)` | Small indentation |
| `--pt-level-padding-md`  | `calc(8px + 24px * level)` | Medium indentation |
| `--pt-level-padding-lg`  | `calc(12px + 28px * level)` | Large indentation |
| `--pt-level-gap-sm`      | `4px`  | Small gap |
| `--pt-level-gap-md`      | `4px`  | Medium gap |
| `--pt-level-gap-lg`      | `8px`  | Large gap |

### Icons

#### Icon Classes
Icons are sized using CSS classes:

| Class Name        | Size  | Stroke | Usage |
|-------------------|-------|--------|-------|
| `.pc_icon--3xsm`  | `14px`| `1px`  | Extra small icons |
| `.pc_icon--2xsm`  | `16px`| `1px`  | Very small icons |
| `.pc_icon--xsm`   | `20px`| `1px`  | Small icons |
| `.pc_icon--sm`    | `24px`| `1.5px`| Small-medium icons |

#### Icon Tokens
| Token Name        | Value  | Usage |
|-------------------|--------|-------|
| `--pt-icon-size`  | `var(--pt-size-*)` | Icon size |
| `--pt-icon-stroke`| `var(--pt-stroke-*)` | Icon stroke width |


## Usage

### Installation

```bash
npm install @pantograph/tokens
```

### CSS Custom Properties

Import the font faces CSS file in your project:

```css
@import '@pantograph/tokens/style/index.css';
```

Then use the tokens in your CSS:

```css
.my-component {
  background-color: rgba(var(--pt-blue-5));
  padding: var(--pt-space-400);
  border-radius: var(--pt-roundness-lg);
  color: rgba(var(--pt-gray-8));
  border: var(--pt-stroke-10) solid rgba(var(--pt-gray-2));
}
```

### Theme Application

Apply themes using CSS classes on your root element:

```html
<!-- Light theme with Pantograph brand -->
<div class="pantograph-tokens pantograph-light pantograph-theme">
  <div class="pantograph-neutral">
    <p>Content with light theme and neutral gray scale</p>
  </div>
</div>

<!-- Dark theme with OKTUPLE brand -->
<div class="pantograph-tokens pantograph-dark oktuple-theme">
  <div class="pantograph-arsenic">
    <p>Content with dark theme and arsenic gray scale</p>
  </div>
</div>
```

### Language Support

Apply language-specific font families:

```html
<!-- Persian text -->
<div class="fa" lang="fa">
  <p>Persian text with Iran Yekan font</p>
</div>

<!-- English text -->
<div class="en" lang="en">
  <p>English text with Inter font</p>
</div>
```

### Icon Usage

Use icon classes for consistent icon sizing:

```html
<!-- Small icon -->
<i class="pc_icon--3xsm">icon</i>

<!-- Medium icon -->
<i class="pc_icon--sm">icon</i>
```

### Level System

Use the level system for dynamic indentation. You can either use raw variables or the new class-based presets:

```css
.nested-item {
  padding-left: var(--pt-level-padding-md);
  margin-bottom: var(--pt-level-gap-md);
}

/* Increase level for deeper nesting */
.nested-item.level-1 {
  --pt-level: 1;
}

.nested-item.level-2 {
  --pt-level: 2;
}
/* Or wrap with a level preset class */
/* available presets follow Levels.json modes, e.g., pantograph-tokens-level-default, ... */
<div class="pantograph-tokens pantograph-light pantograph-theme pantograph-tokens-level-default">
  <div class="nested-item">Item</div>
  <div class="nested-item level-1">Nested Item</div>
  <div class="nested-item level-2">Nested Deeper</div>
  <!-- you can override --pt-level per element or rely on preset variables -->
</div>
```

### Typography Classes

Apply typography styles using CSS classes:

```html
<!-- Title with title line heights -->
<h1 class="title">Main Title</h1>

<!-- Paragraph with paragraph line heights -->
<p class="paragraph">Body text content</p>
```

### JavaScript/TypeScript

Import the token values directly in your JavaScript or TypeScript files:

```javascript
import { 
  init, 
  getThemeInfo, 
  addCssToHead, 
  removeCssFromHead,
  getCoreHexColor,
  getCoreRgbColor 
} from '@pantograph/tokens';

// Initialize token system
init({
  element: '#app',
  dark: false,
  theme: 'pantograph',
  grayScale: 'neutral'
});

// Get theme information
const themeInfo = getThemeInfo({
  dark: true,
  theme: 'oktuple',
  grayScale: 'arsenic'
});
console.log(themeInfo.classes); // 'pantograph-tokens pantograph-dark oktuple-theme pantograph-arsenic'

// Manage CSS dynamically
addCssToHead('custom-styles', '.custom { color: red; }');
removeCssFromHead('custom-styles');

// Access color values
const primaryColor = getCoreHexColor('primary-5'); // '#0ea5e9'
const primaryRgb = getCoreRgbColor('primary-5'); // 'rgb(14, 165, 233)'
```

### UnoCSS Integration

The tokens package provides a UnoCSS preset for seamless integration:

```javascript
// uno.config.js
import { presetPantographVue } from '@pantograph/tokens'

export default {
  presets: [
    presetPantographVue()
  ]
}
```

### Vue Integration

For Vue 3 applications, use the ConfigProvider component:

```vue
<template>
  <ConfigProvider :theme="themeConfig">
    <App />
  </ConfigProvider>
</template>

<script setup lang="ts">
import { ConfigProvider } from '@pantograph/vue'
import { ref } from 'vue'

const themeConfig = ref({
  init: true,
  theme: 'pantograph',
  grayScale: 'neutral',
  dark: false,
  element: '#app'
})
</script>
```

### Custom Theme Override

Override theme tokens for custom branding:

```css
.custom-brand {
  /* Override primary colors */
  --pt-primary-0: var(--pt-pink-0);
  --pt-primary-1: var(--pt-pink-1);
  --pt-primary-2: var(--pt-pink-2);
  --pt-primary-3: var(--pt-pink-3);
  --pt-primary-4: var(--pt-pink-4);
  --pt-primary-5: var(--pt-pink-5);
  --pt-primary-6: var(--pt-pink-6);
  --pt-primary-7: var(--pt-pink-7);
  --pt-primary-8: var(--pt-pink-8);
  --pt-primary-9: var(--pt-pink-9);
  --pt-primary-oncolor: var(--pt-grayscale-light-0);
}
```

## Package Structure

```
shared/tokens/
├── dist/                    # Built output
│   ├── index.js            # Main JavaScript export
│   ├── index.cjs           # CommonJS export
│   ├── index.d.ts          # TypeScript definitions
│   └── style/
│       └── index.css       # CSS custom properties
├── src/                    # Source code
│   ├── const/              # Token constants
│   ├── rules/              # UnoCSS rules
│   ├── style/              # Font files and CSS
│   └── utils/              # Utility functions
├── tokens/                 # JSON token definitions
│   ├── Colors.json         # Color tokens
│   ├── PrimitiveColors.json# Primitive color palette
│   ├── BrandColors.json    # Brand-specific colors
│   ├── GrayScale.json      # Grayscale colors
│   ├── Sizes.json          # Size and spacing tokens
│   ├── Typography.json     # Typography tokens
│   ├── Levels.json         # Indentation tokens
│   ├── Icon.json           # Icon tokens
│   └── generatedTokens.css # Generated CSS tokens
└── scripts/                # Build scripts
```

## How It Works

### Token Generation Process

1. **JSON Definitions**: Token values are defined in JSON files in the `tokens/` directory
2. **Build Process**: The build system processes these JSON files and generates:
   - CSS custom properties with `--pt-*` prefix
   - Theme classes (`.pantograph-light`, `.pantograph-dark`, etc.)
   - Brand theme classes (`.oktuple-theme`, `.claytap-theme`, etc.)
   - Gray scale classes (`.pantograph-arsenic`, `.pantograph-cool`, etc.)
   - Language classes (`.fa`, `.en`)
   - Icon classes (`.pc_icon--*`)
   - Typography classes (`.title`, `.paragraph`)

3. **Final Output**: The `generatedTokens.css` file contains all the mapped tokens with consistent `--pt-*` naming

### Key Features

- **Consistent Naming**: All tokens use `--pt-*` prefix regardless of source
- **Theme Switching**: Colors change via CSS classes, not JavaScript
- **RGB Values**: Colors are stored as RGB values for `rgba()` usage
- **Dynamic Theming**: Multiple themes can coexist on the same page
- **Language Support**: Automatic font family switching based on language classes
- **Level System**: Dynamic indentation based on nesting depth

## Contributing

Design tokens are generated from our Figma design system. Changes to token values should be made in Figma and then exported to this package using our internal tooling.

### Development

To build the tokens package:

```bash
npm run build
```

This will generate the CSS custom properties and JavaScript exports from the JSON token definitions.

### Token Updates

1. Update token values in the JSON files in `tokens/` directory
2. Run `npm run build` to regenerate the CSS and JS exports
3. Test the changes in the Vue component library
4. Update documentation as needed


### Important Notes

- **All tokens are mapped to `--pt-*` prefix** - no need to remember different prefixes
- **Colors use RGB values** - wrap with `rgba()` for opacity control
- **Themes are applied via CSS classes** - not JavaScript variables