npm package: @reallygoodwork/tailwindcss-modular-scale
Description: TailwindCSS v4 plugin to override spacing utilities with exponential modular scaling
Author: Really Good Work Inc.
Latest version: 1.0.0

# TailwindCSS Modular Scale Plugin

A plugin for TailwindCSS v4 that automatically transforms spacing utilities to use exponential modular scaling instead of linear multiplication.

## Overview

This plugin overrides TailwindCSS v4's default spacing calculations, transforming:

```css
/* Default TailwindCSS output */
.py-4 {
  padding-block: calc(var(--spacing) * 4);
}
```

Into:

```css
/* With modular scale transformation */
.py-4 {
  padding-block: calc(var(--spacing) * pow(var(--modular-scale), 4));
}
```

This enables exponential scaling for all spacing utilities (`py-4`, `px-12`, `w-8`, `m-2`, etc.) while maintaining the same API - you continue using normal TailwindCSS utilities.

## Installation

```bash
npm install tailwindcss-modular-scale
```

## Usage

### 1. Define the Modular Scale Factor

In your CSS file, define the modular scale factor in your `@theme` block:

```css
@theme {
  --spacing: 1px;
  --modular-scale: 1.125; /* Minor third - subtle scaling */
  /* or */
  --modular-scale: 1.4; /* Stronger scaling */
  /* or */
  --modular-scale: 1.618; /* Golden ratio */
}
```

### 2. Add the Plugin

#### For Vite Projects

```ts
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
import modularScale from 'tailwindcss-modular-scale/vite'

export default {
  plugins: [
    tailwindcss(),
    modularScale(), // Must come AFTER tailwindcss()
  ],
}
```

#### For PostCSS Projects

```ts
// postcss.config.js
import tailwindcss from '@tailwindcss/postcss'
import modularScale from 'tailwindcss-modular-scale/postcss'

export default {
  plugins: [
    tailwindcss(),
    modularScale(), // Must come AFTER tailwindcss()
  ],
}
```

### 3. Use Normal TailwindCSS Utilities

That's it! Use TailwindCSS spacing utilities as usual:

```html
<div class="py-4 px-12 w-8 m-2">
  <!-- Automatically uses modular scaling -->
</div>
```

## Configuration Options

```ts
modularScale({
  // Name of the CSS variable that holds the modular scale factor
  scaleFactorVar: '--modular-scale', // default

  // Name of the CSS variable that holds the base spacing value
  spacingVar: '--spacing', // default

  // Enable or disable the transformation
  enabled: true, // default
})
```

### Custom Variable Names

If you're using custom CSS variable names:

```css
@theme {
  --base-spacing: 1px;
  --ratio: 1.125;
}
```

```ts
modularScale({
  scaleFactorVar: '--ratio',
  spacingVar: '--base-spacing',
})
```

## Examples

### Minor Third (1.125)

```css
@theme {
  --modular-scale: 1.125;
}
```

This creates a subtle, harmonious scaling:
- `p-1` → `calc(var(--spacing) * pow(1.125, 1))` ≈ 1.125×
- `p-2` → `calc(var(--spacing) * pow(1.125, 2))` ≈ 1.266×
- `p-4` → `calc(var(--spacing) * pow(1.125, 4))` ≈ 1.602×
- `p-8` → `calc(var(--spacing) * pow(1.125, 8))` ≈ 2.566×

### Major Third (1.25)

```css
@theme {
  --modular-scale: 1.25;
}
```

Stronger scaling:
- `p-1` → `calc(var(--spacing) * pow(1.25, 1))` = 1.25×
- `p-2` → `calc(var(--spacing) * pow(1.25, 2))` = 1.563×
- `p-4` → `calc(var(--spacing) * pow(1.25, 4))` = 2.441×
- `p-8` → `calc(var(--spacing) * pow(1.25, 8))` = 5.960×

### Golden Ratio (1.618)

```css
@theme {
  --modular-scale: 1.618;
}
```

Classic proportional scaling:
- `p-1` → `calc(var(--spacing) * pow(1.618, 1))` ≈ 1.618×
- `p-2` → `calc(var(--spacing) * pow(1.618, 2))` ≈ 2.618×
- `p-4` → `calc(var(--spacing) * pow(1.618, 4))` ≈ 6.854×

## How It Works

1. **TailwindCSS generates** spacing utilities with linear calculations: `calc(var(--spacing) * 4)`
2. **This plugin transforms** them to use exponential scaling: `calc(var(--spacing) * pow(var(--modular-scale), 4))`
3. **CSS evaluates** the `pow()` function at runtime using the value from your `@theme` block

## Browser Compatibility

This plugin uses CSS's native `pow()` function (CSS Values and Units Level 4). Browser support:

- ✅ Chrome 113+
- ✅ Firefox 113+
- ✅ Safari 16.4+
- ⚠️ Not supported in older browsers

For projects requiring older browser support, consider using a CSS polyfill or a different approach.

Reference: [MDN - CSS pow() function](https://developer.mozilla.org/en-US/docs/Web/CSS/pow)

## Supported Utilities

All TailwindCSS spacing utilities are automatically transformed:

- Padding: `p-*`, `px-*`, `py-*`, `pt-*`, `pr-*`, `pb-*`, `pl-*`
- Margin: `m-*`, `mx-*`, `my-*`, `mt-*`, `mr-*`, `mb-*`, `ml-*`
- Width/Height: `w-*`, `h-*`, `min-w-*`, `min-h-*`, `max-w-*`, `max-h-*`
- Gap: `gap-*`, `gap-x-*`, `gap-y-*`
- And any other utility that uses `calc(var(--spacing) * <number>)`

## Edge Cases

- **Decimal values**: `px-2.5` → `calc(var(--spacing) * pow(var(--modular-scale), 2.5))`
- **Negative values**: Handled correctly (though uncommon in TailwindCSS)
- **Multiple calculations**: All instances in a rule are transformed
- **Custom spacing variables**: Supported via the `spacingVar` option

## Plugin Ordering

**Critical**: This plugin must run AFTER TailwindCSS in your build pipeline:

```ts
// ✅ Correct order
plugins: [
  tailwindcss(),      // First
  modularScale(),     // After TailwindCSS
]

// ❌ Wrong order
plugins: [
  modularScale(),     // Won't work - TailwindCSS hasn't generated CSS yet
  tailwindcss(),
]
```

## License

MIT