import animate from 'tailwindcss-animate'; /** @type {import('tailwindcss').Config} */ export default { darkMode: ['class', '[data-theme="dark"]'], content: ['./index.html', './src/**/*.{ts,tsx}'], theme: { extend: { colors: { // Every colour resolves through a CSS variable so the user's chosen // accent re-tints the whole interface without a rebuild. bg: 'hsl(var(--bg))', background: 'hsl(var(--bg))', surface: 'hsl(var(--surface))', 'surface-2': 'hsl(var(--surface-2))', border: 'hsl(var(--border))', input: 'hsl(var(--border))', ring: 'hsl(var(--accent))', fg: 'hsl(var(--fg))', foreground: 'hsl(var(--fg))', muted: 'hsl(var(--muted))', 'muted-foreground': 'hsl(var(--muted))', /* * shadcn's `accent` is its SUBTLE hover/selected surface — dropdown * items, command rows, ghost-button hover. It is not the brand colour; * that is `primary`, mapped below. * * Mapping `accent` to --accent (the brand) inverted this, so every * hover state painted a full-strength brand block: in dark mode with * the monochrome "pig" accent that is near-white, which made a selected * command row glare. Aliased to the subtle pair instead, so shadcn * primitives tint the way their authors intended while PIG's own brand * fills use `primary`. */ accent: 'hsl(var(--accent-subtle))', 'accent-foreground': 'hsl(var(--accent-fg))', /** The brand itself, for PIG's own components that need a solid fill. */ brand: 'hsl(var(--accent))', 'accent-fg': 'hsl(var(--accent-fg))', 'accent-on': 'hsl(var(--accent-on))', 'accent-subtle': 'hsl(var(--accent-subtle))', primary: { DEFAULT: 'hsl(var(--accent))', foreground: 'hsl(var(--accent-on))', }, secondary: { DEFAULT: 'hsl(var(--surface-2))', foreground: 'hsl(var(--fg))', }, card: { DEFAULT: 'hsl(var(--surface))', foreground: 'hsl(var(--fg))', }, popover: { DEFAULT: 'hsl(var(--surface))', foreground: 'hsl(var(--fg))', }, destructive: { DEFAULT: 'hsl(var(--danger))', foreground: 'hsl(0 0% 100%)', }, /* * The sidebar primitive's scale. Every one of these resolves, through * the --sidebar-* aliases in index.css, to a variable already defined * above — so this is a naming layer for shadcn's block, not a second * palette that can drift from the first. */ sidebar: { DEFAULT: 'hsl(var(--sidebar-background))', foreground: 'hsl(var(--sidebar-foreground))', primary: 'hsl(var(--sidebar-primary))', 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))', accent: 'hsl(var(--sidebar-accent))', 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))', border: 'hsl(var(--sidebar-border))', ring: 'hsl(var(--sidebar-ring))', }, positive: 'hsl(var(--positive))', warning: 'hsl(var(--warning))', danger: 'hsl(var(--danger))', info: 'hsl(var(--info))', }, fontFamily: { sans: ['Manrope Variable', 'Avenir Next', 'ui-sans-serif', 'system-ui', 'sans-serif'], mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'], }, /* * Three radii by role: 16px surfaces (cards, sheets, dialogs, popovers), * 12px controls (buttons, inputs, selects, chips-that-are-buttons), 8px * inset tiles and raw/code blocks inside a surface. * * `md` is overridden because it was the one nobody chose: 32 call sites * inherited shadcn's 6px, which put a fourth radius in the product doing * the same job as 8px. Naming it here retires 6px without touching them. */ borderRadius: { md: '0.5rem', lg: '0.75rem', xl: '1rem' }, /* * Motion, aliased to the tokens in index.css so there is one definition * of each duration and easing rather than one in CSS and one here. * `duration-1/2/3` and `ease-enter`/`ease-exit` are additions, not * overrides — Tailwind's own `duration-150` and `ease-out` keep their * stock values, so no existing call site changes behaviour. * * tailwindcss-animate reads animationDuration/animationTimingFunction * from these, so the same class names work on `animate-in`/`animate-out`. */ transitionDuration: { 1: 'var(--dur-1)', 2: 'var(--dur-2)', 3: 'var(--dur-3)', }, transitionTimingFunction: { enter: 'var(--ease-out)', exit: 'var(--ease-in)', }, }, }, plugins: [animate], };