# Tailwind preset

> Optional Tailwind (>=4) preset + plugin mirroring the UIKit tokens as utilities. Components do not require Tailwind.

- npm dependencies: `tailwindcss@>=4.0.0`
- Registry dependencies: [theme](https://design.freecodecamp.org/registry/theme.md)
- Files:
  - `preset.ts` → `src/ui/tailwind/preset.ts` (raw: https://design.freecodecamp.org/registry/tailwind/preset.ts)
  - `plugin.ts` → `src/ui/tailwind/plugin.ts` (raw: https://design.freecodecamp.org/registry/tailwind/plugin.ts)

## Install

1. Optional - components are vanilla CSS and do not require Tailwind.
2. Copy `preset.ts` + `plugin.ts` into your Tailwind (>=4) config directory and register them; they mirror UIKit tokens as utilities.
3. You still need the theme installed (https://design.freecodecamp.org/registry/theme.md) - the preset references the same CSS custom properties.

## Source: preset.ts

```ts
import type { Config } from 'tailwindcss';

const fontSans: string[] = [
  'Lato',
  '-apple-system',
  'BlinkMacSystemFont',
  'Segoe UI',
  'sans-serif'
];

const fontMono: string[] = [
  'Hack-ZeroSlash',
  'Fira Mono',
  'Menlo',
  'Consolas',
  'monospace'
];

const preset: Partial<Config> = {
  theme: {
    extend: {
      colors: {
        fg: {
          primary: 'var(--foreground-primary)',
          secondary: 'var(--foreground-secondary)',
          tertiary: 'var(--foreground-tertiary)',
          quaternary: 'var(--foreground-quaternary)',
          muted: 'var(--foreground-muted)'
        },
        bg: {
          primary: 'var(--background-primary)',
          secondary: 'var(--background-secondary)',
          tertiary: 'var(--background-tertiary)',
          quaternary: 'var(--background-quaternary)'
        },
        highlight: {
          color: 'var(--highlight-color)',
          background: 'var(--highlight-background)'
        },
        success: {
          color: 'var(--success-color)',
          background: 'var(--success-background)'
        },
        danger: {
          color: 'var(--danger-color)',
          background: 'var(--danger-background)'
        },
        warning: {
          color: 'var(--warning-color)',
          background: 'var(--warning-background)'
        },
        purple: {
          color: 'var(--purple-color)',
          background: 'var(--purple-background)'
        },
        love: {
          color: 'var(--love-color)'
        },
        cta: {
          background: 'var(--cta-background)',
          foreground: 'var(--cta-foreground)'
        }
      },
      fontFamily: {
        sans: fontSans,
        mono: fontMono
      },
      fontSize: {
        sm: 'var(--fs-sm)',
        md: 'var(--fs-md)',
        lg: 'var(--fs-lg)',
        xl: 'var(--fs-xl)',
        '2xl': 'var(--fs-2xl)',
        '3xl': 'var(--fs-3xl)'
      },
      spacing: {
        '0': 'var(--space-0)',
        '1': 'var(--space-1)',
        '2': 'var(--space-2)',
        '3': 'var(--space-3)',
        '4': 'var(--space-4)',
        '5': 'var(--space-5)',
        '6': 'var(--space-6)',
        '7': 'var(--space-7)',
        '8': 'var(--space-8)'
      },
      borderWidth: {
        hair: 'var(--border-width-hair)',
        DEFAULT: 'var(--border-width-default)',
        thick: 'var(--border-width-thick)'
      },
      borderRadius: {
        none: 'var(--radius-none)',
        sm: 'var(--radius-sm)'
      },
      transitionTimingFunction: {
        snap: 'var(--ease-snap)',
        out: 'var(--ease-out)'
      },
      transitionDuration: {
        fast: 'var(--dur-fast)',
        base: 'var(--dur-base)',
        slow: 'var(--dur-slow)'
      },
      zIndex: {
        breadcrumbs: 'var(--z-breadcrumbs)',
        flash: 'var(--z-flash)',
        siteHeader: 'var(--z-site-header)',
        modal: 'var(--z-modal)'
      }
    }
  }
};

export default preset;
```

## Source: plugin.ts

```ts
import type { Config } from 'tailwindcss';
import plugin from 'tailwindcss/plugin';
import type { PluginCreator } from 'tailwindcss/plugin';

type FccPlugin = {
  handler: PluginCreator;
  config?: Partial<Config>;
};

const fccPlugin: FccPlugin = plugin(({ addUtilities, addVariant }) => {
  addUtilities({
    '.focus-ring': {
      outline: '3px solid var(--blue-mid)',
      outlineOffset: '0'
    }
  });

  addVariant('fcc-dark', '&:is(.dark-palette *)');
  addVariant('fcc-light', '&:is(.light-palette *)');
});

export default fccPlugin;
```

## For coding agents

This library is distributed as copyable source, not an npm package. Start at https://design.freecodecamp.org/registry/starter.md, discover components via https://design.freecodecamp.org/llms.txt, and copy files into the consuming project. Keep token names intact; recolour by editing the copied tokens.css.
