npm package: @johnfilipstad/groundwork-tokens
Description: Design tokens (CSS custom properties) — single source of truth for Groundwork vNext.
Author: John Filipstad
Latest version: 2.0.0

# Groundwork Tokens 🏗️

**The foundation of every great design system.**

Groundwork Tokens is the Single Source of Truth (SSOT) for the entire Groundwork vNext ecosystem. Every layer—from base styling to complex components—builds upon these carefully crafted design tokens to create cohesive, accessible, and beautiful web experiences.

[![npm version](https://badge.fury.io/js/%40groundwork%2Ftokens.svg)](https://www.npmjs.com/package/@groundwork/tokens)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

---

## ⚡ Why Groundwork Tokens?

**🎯 Single Source of Truth** — One place to define colors, typography, spacing, and more.<br>
**🎨 Instant Theming** — Change 3 brand colors, get 362 coordinated CSS variables.<br>
**🌍 Universal Foundation** — Powers every layer of the Groundwork ecosystem.<br>
**🔄 Effortless Updates** — Update once, cascade everywhere.<br>
**🌙 Built-in Dark Mode** — Automatic light/dark theming with zero configuration.<br>
**🌐 RTL/LTR Ready** — Logical properties and directional awareness.<br>
**♿ Accessibility First** — WCAG AA contrast ratios and reduced motion support.

---

## 🚀 Quick Start

### Installation

```bash
npm i @johnfilipstad/groundwork-tokens
```

### Basic Usage

**The groundwork must be laid first.** Always import tokens before any other Groundwork layers:

```html
<!-- Tokens MUST come first -->
<link rel="stylesheet" href="/node_modules/@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.css">

<!-- Then other layers (optional) -->
<link rel="stylesheet" href="node_modules/@johnfilipstad/groundwork-harmony/dist/groundwork-harmony.css">
<link rel="stylesheet" href="node_modules/@johnfilipstad/groundwork-flow/dist/groundwork-flow.css">
```

### CDN Usage

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.css">
```

---

## 📦 Multiple Formats

Groundwork Tokens provides design tokens in **multiple formats** to fit any workflow:

| Format | Base Tokens | With Themes | Use Case |
|--------|-------------|-------------|----------|
| **CSS** | ✅ `groundwork-tokens.css` | ✅ *Built-in themes* | Web projects, universal compatibility |
| **SCSS** | ✅ `groundwork-tokens.scss` | ✅ `groundwork-tokens-themes.scss` | Sass/SCSS workflows, theme mixins |
| **JavaScript** | ✅ `groundwork-tokens.js` | ✅ `groundwork-tokens-themes.js` | React/Vue, programmatic theming |
| **TypeScript** | ✅ `groundwork-tokens.d.ts` | ⚠️ *Base types only* | Type definitions |
| **JSON** | ✅ `groundwork-tokens.json` | ✅ `groundwork-tokens-themes.json` | Design tools, documentation |

**🌙 Theme Support**: All theme-aware formats include automatic dark/light mode switching via `prefers-color-scheme` and manual `data-theme` attributes.

### CSS Custom Properties (Default)
Perfect for modern web development with native CSS variables:

```html
<link rel="stylesheet" href="/node_modules/@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.css">
```

```css
.my-component {
  background: var(--color-primary);
  color: var(--color-text);
  padding: var(--spacing-m);
  font-size: var(--font-size-l);
}
```

### SCSS Variables
For Sass/SCSS workflows:

```scss
// Base variables only
@import '~@johnfilipstad/groundwork-tokens/scss';

.my-component {
  background: $color-primary;
  color: $color-text;
  padding: $spacing-m;
  font-size: $font-size-l;
}
```

**Or with automatic dark/light theme support:**

```scss
// Includes theme mixins and media queries
@import '~@johnfilipstad/groundwork-tokens/dist/groundwork-tokens-themes.scss';

// Now automatically supports dark mode via:
// - @media (prefers-color-scheme: dark)
// - :root[data-theme="dark"]
// - Manual @include dark-theme mixin
```

### JavaScript/TypeScript
For component libraries and programmatic access:

```javascript
// Base tokens only
import { ColorPrimary, FontSizeL, SpacingM } from '@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.js';

console.log(ColorPrimary); // "var(--color-primary-600)"
console.log(FontSizeL); // "clamp(1.9rem, 1rem + 2vw, var(--font-size-l-target))"

// CommonJS
const { ColorPrimary } = require('@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.cjs');
```

**Or with theme support and utilities:**

```javascript
// Includes theme objects and utilities
import { ColorPrimary, themes, applyTheme } from '@johnfilipstad/groundwork-tokens/dist/groundwork-tokens-themes.js';

// Theme objects
console.log(themes.dark.colorBody); // "hsl(0deg 0% 8%)"
console.log(themes.light.colorBody); // "hsl(0deg 0% 98%)"

// Programmatic theme switching
applyTheme('dark'); // Applies dark theme to document
applyTheme('light'); // Applies light theme to document
### JSON Design Tokens
For design tools and token management:

```javascript
// Base tokens only - flat format
import tokens from '@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.tokens.json';
console.log(tokens.ColorPrimary); // "var(--color-primary-600)"

// Base tokens only - nested format
import tokens from '@johnfilipstad/groundwork-tokens/dist/groundwork-tokens.json';
console.log(tokens["color-primary"]); // "var(--color-primary-600)"
```

**Or with complete theme data:**

```javascript
// Includes base tokens + theme objects
import tokenData from '@johnfilipstad/groundwork-tokens/dist/groundwork-tokens-themes.json';

console.log(tokenData.base); // All base design tokens
console.log(tokenData.themes.dark); // Dark theme overrides  
console.log(tokenData.themes.light); // Light theme overrides
```

### Framework Integration Examples

#### React/Vue Components
```javascript
import { tokens } from '@johnfilipstad/groundwork-tokens';

const Button = () => (
  <button style={{
    backgroundColor: tokens.color.primary.brand,
    padding: tokens.spacing.m,
    fontSize: tokens.font.size.m
  }}>
    Click me
  </button>
);
```

#### Styled Components
```javascript
import styled from 'styled-components';
import { tokens } from '@johnfilipstad/groundwork-tokens';

const Button = styled.button`
  background: ${tokens.color.primary.brand};
  color: ${tokens.color.text};
  padding: ${tokens.spacing.m};
  font-size: ${tokens.font.size.m};
`;
```

---

## 🏗️ Architecture Power

Groundwork Tokens creates a flexible foundation where each layer can work independently:

### Mix and Match
```html
<!-- Want just variables? -->
<link rel="stylesheet" href="groundwork-tokens.css">

<!-- Beautiful semantic HTML? -->
<link rel="stylesheet" href="groundwork-tokens.css">
<link rel="stylesheet" href="groundwork-harmony.css">

<!-- Flexible layouts? -->
<link rel="stylesheet" href="groundwork-tokens.css">
<link rel="stylesheet" href="groundwork-flow.css">

<!-- Complete foundation? -->
<link rel="stylesheet" href="groundwork-tokens.css">
<link rel="stylesheet" href="groundwork-harmony.css">
<link rel="stylesheet" href="groundwork-flow.css">
```

---

## 🎨 What's Inside

### **Mathematical Typography**
- Responsive font scales using modular ratios
- Perfect fourth (1.333) creates natural hierarchy
- Fluid sizing with `clamp()` for all devices

### **Semantic Color System**
- Auto-generating palettes from brand colors
- Built-in light/dark mode switching
- WCAG AA compliant contrast ratios

### **Consistent Spacing**
- 4px baseline grid for visual rhythm
- Exponential scale for clear hierarchy
- Logical properties for RTL/LTR support

### **Elevation System**
- Theme-aware shadows and depth
- Consistent elevation hierarchy
- Dynamic color integration

---

## 🌙 Theme Switching

### Automatic (OS Preference)
Tokens automatically respect your user's system preference:

```css
/* Automatically switches based on prefers-color-scheme */
:root {
  --color-text: var(--color-text-on-light); /* Light mode */
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-text: var(--color-text-on-dark); /* Dark mode */
  }
}
```

### Manual Override
Let users choose their preference:

```html
<!-- Light mode -->
<html data-theme="light">

<!-- Dark mode -->
<html data-theme="dark">

<!-- Auto (remove attribute) -->
<html>
```

### Add Theme Toggle (Optional)

Want to add dark mode? Just paste this script before the closing `</body>` tag:

```html
<script>
// Theme toggle script from the Dark Mode section above
window.addEventListener("DOMContentLoaded", () => {
  // ... (see full script from Dark Mode section below)
});
</script>
```

### Explore Further

Visit **groundwork.filipstad.dev** for comprehensive documentation, live demos, and advanced examples (coming soon).

---

## 🌓 Dark Mode

Groundwork Tokens supports **`[data-theme="dark" | "light"]` on `<html>`** and respects the user's OS setting via `prefers-color-scheme`.
If you don't set an attribute, Groundwork Tokens will match the OS preference automatically. To provide a user toggle, use this simple approach:

**Copy and paste this complete theme toggle script:**

```html
<script>
window.addEventListener("DOMContentLoaded", () => {
  const styles = `
    .theme-toggle {
      position: fixed;
      top: var(--spacing-s);
      right: var(--spacing-s);
      padding: var(--spacing-s);
      z-index: var(--z-index-toast);
    }
  `;
  const styleSheet = document.createElement("style");
  styleSheet.innerText = styles;
  document.head.appendChild(styleSheet);

  const themeToggleButton = document.createElement("button");
  themeToggleButton.className = "theme-toggle";
  document.body.appendChild(themeToggleButton);

  const html = document.documentElement;

  function toggleTheme() {
    let currentTheme = html.getAttribute("data-theme");
    if (!currentTheme) {
      currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }

    const newTheme = currentTheme === "dark" ? "light" : "dark";
    html.setAttribute("data-theme", newTheme);
    localStorage.setItem("theme", newTheme);
    updateButtonText(newTheme);
  }

  function updateButtonText(theme) {
    themeToggleButton.textContent = theme === "dark" ? "☀️" : "🌙";
  }

  themeToggleButton.addEventListener("click", toggleTheme);

  // Load saved theme or respect OS preference
  const savedTheme = localStorage.getItem("theme");
  if (savedTheme) {
    html.setAttribute("data-theme", savedTheme);
    updateButtonText(savedTheme);
  } else {
    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
    updateButtonText(prefersDark ? 'dark' : 'light');
  }
});
</script>
```

**That's it!** This script creates the button, adds the CSS using design tokens, and handles OS preferences intelligently.

**Notes:**
* Uses Groundwork's design tokens (`--spacing-s`, `--z-index-toast`) for consistent styling
* Respects user's OS preference until they manually toggle
* Saves preference in localStorage for returning users

---

## 💡 Usage Examples

### Custom Properties in CSS
```css
.my-component {
  background-color: var(--color-surface);
  color: var(--color-text);
  padding: var(--spacing-m);
  border-radius: var(--border-radius-s);
  font-size: var(--font-size-l);
}
```

### Brand Customization
Override the foundation to match your brand:

```css
:root {
  /* Change these 3 variables... */
  --color-primary-brand: #your-primary;
  --color-secondary-brand: #your-secondary;
  --color-accent-brand: #your-accent;

  /* ...and get 200+ coordinated variables automatically */
}
```

---

## 📚 Documentation

Complete documentation, examples, and interactive demos:
**[groundwork.filipstad.dev](https://groundwork.filipstad.dev)**

- 🎨 Color system deep dive
- 📏 Typography scale calculator
- 🎛️ Interactive token browser
- 🌙 Theme switching examples
- ♿ Accessibility guidelines

---

## 🏗️ Ecosystem

Groundwork Tokens powers the entire Groundwork vNext family:

| Package | Purpose | Dependencies |
|---------|---------|-------------|
| **@groundwork/tokens** | Design token foundation | *None* |
| [@groundwork/harmony](https://github.com/JohnFilipstad/groundwork-harmony) | Semantic HTML styling | tokens |
| [@groundwork/flow](https://github.com/JohnFilipstad/groundwork-flow) | Layout primitives | tokens |
| [@groundwork/atoms](https://github.com/JohnFilipstad/groundwork-atoms) | Utility classes | tokens |
| [@groundwork/components](https://github.com/JohnFilipstad/groundwork-components) | UI components | tokens + others |

---

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.

### Development Setup
```bash
git clone https://github.com/JohnFilipstad/groundwork-tokens.git
cd groundwork-tokens
npm install
npm run dev
```

---

## 📄 License

MIT © [John Filipstad](https://github.com/JohnFilipstad)

---

## 🔗 Links

- **Documentation**: [groundwork.filipstad.dev](https://groundwork.filipstad.dev)
- **GitHub**: [github.com/JohnFilipstad/groundwork-tokens](https://github.com/JohnFilipstad/groundwork-tokens)
- **NPM**: [@groundwork/tokens](https://www.npmjs.com/package/@johnfilipstad/groundwork-tokens)
- **Issues**: [Report bugs or request features](https://github.com/JohnFilipstad/groundwork-tokens/issues)

---

*The groundwork has been laid. Build something amazing.* 🏗️