/** @type {import('tailwindcss').Config} */ // Every value here resolves to a CSS variable declared in src/index.css, so the // tokens have exactly one source of truth. Components should reach for these // utilities rather than hard-coded hex values or arbitrary shadows. module.exports = { darkMode: ['class'], content: ['./index.html', './src/**/*.{ts,tsx,js,jsx}'], theme: { container: { center: true, padding: 'var(--page-gutter)', screens: { '2xl': 'var(--container-max)' }, }, extend: { borderRadius: { lg: 'var(--radius)', md: 'calc(var(--radius) - 2px)', sm: 'calc(var(--radius) - 4px)', xl: 'calc(var(--radius) + 4px)', '2xl': 'calc(var(--radius) + 8px)', '3xl': 'calc(var(--radius) + 16px)', }, colors: { background: 'hsl(var(--background))', foreground: 'hsl(var(--foreground))', card: { DEFAULT: 'hsl(var(--card))', foreground: 'hsl(var(--card-foreground))', }, popover: { DEFAULT: 'hsl(var(--popover))', foreground: 'hsl(var(--popover-foreground))', }, primary: { DEFAULT: 'hsl(var(--primary))', foreground: 'hsl(var(--primary-foreground))', }, secondary: { DEFAULT: 'hsl(var(--secondary))', foreground: 'hsl(var(--secondary-foreground))', }, muted: { DEFAULT: 'hsl(var(--muted))', foreground: 'hsl(var(--muted-foreground))', }, accent: { DEFAULT: 'hsl(var(--accent))', foreground: 'hsl(var(--accent-foreground))', }, destructive: { DEFAULT: 'hsl(var(--destructive))', foreground: 'hsl(var(--destructive-foreground))', muted: 'hsl(var(--destructive-muted))', }, border: 'hsl(var(--border))', input: 'hsl(var(--input))', ring: 'hsl(var(--ring))', /* KROW brand — named so intent is readable in markup */ krow: { blue: '#0A39DF', 'blue-dark': '#082EB4', 'blue-tint': '#EFF6FF', yellow: '#F9E547', 'yellow-pale': '#F8E08E', navy: '#333F48', mint: '#D1E0D7', }, /* Semantic status */ success: { DEFAULT: 'hsl(var(--success))', foreground: 'hsl(var(--success-foreground))', muted: 'hsl(var(--success-muted))', }, warning: { DEFAULT: 'hsl(var(--warning))', foreground: 'hsl(var(--warning-foreground))', muted: 'hsl(var(--warning-muted))', }, info: { DEFAULT: 'hsl(var(--info))', foreground: 'hsl(var(--info-foreground))', muted: 'hsl(var(--info-muted))', }, neutral: { DEFAULT: 'hsl(var(--neutral))', foreground: 'hsl(var(--neutral-foreground))', muted: 'hsl(var(--neutral-muted))', }, /* Text hierarchy */ ink: { 1: 'hsl(var(--ink-1))', 2: 'hsl(var(--ink-2))', 3: 'hsl(var(--ink-3))', 4: 'hsl(var(--ink-4))', }, /* Surfaces */ surface: { DEFAULT: 'hsl(var(--surface))', subtle: 'hsl(var(--surface-subtle))', sunken: 'hsl(var(--surface-sunken))', }, /* Owliver assistant panel */ panel: { DEFAULT: 'hsl(var(--panel))', raised: 'hsl(var(--panel-raised))', border: 'hsl(var(--panel-border))', foreground: 'hsl(var(--panel-foreground))', muted: 'hsl(var(--panel-muted))', }, chart: { 1: 'hsl(var(--chart-1))', 2: 'hsl(var(--chart-2))', 3: 'hsl(var(--chart-3))', 4: 'hsl(var(--chart-4))', 5: 'hsl(var(--chart-5))', }, 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))', }, }, fontFamily: { heading: ['var(--font-heading)'], body: ['var(--font-body)'], display: ['var(--font-display)'], mono: ['var(--font-mono)'], }, /* Type scale — the sizes the app actually uses, named so pages stop reaching for arbitrary `text-[13px]` values. */ fontSize: { 'display-lg': ['2rem', { lineHeight: '2.375rem', letterSpacing: '-0.02em', fontWeight: '700' }], display: ['1.75rem', { lineHeight: '2.125rem', letterSpacing: '-0.02em', fontWeight: '700' }], 'title-lg': ['1.375rem', { lineHeight: '1.75rem', letterSpacing: '-0.01em', fontWeight: '700' }], title: ['1rem', { lineHeight: '1.375rem', letterSpacing: '-0.01em', fontWeight: '600' }], 'body-lg': ['0.9375rem', { lineHeight: '1.5rem' }], body: ['0.875rem', { lineHeight: '1.375rem' }], 'body-sm': ['0.8125rem', { lineHeight: '1.25rem' }], caption: ['0.75rem', { lineHeight: '1.125rem' }], overline: ['0.6875rem', { lineHeight: '1rem', letterSpacing: '0.06em', fontWeight: '600' }], }, boxShadow: { xs: 'var(--shadow-xs)', sm: 'var(--shadow-sm)', md: 'var(--shadow-md)', lg: 'var(--shadow-lg)', xl: 'var(--shadow-xl)', brand: 'var(--shadow-brand)', panel: 'var(--shadow-panel)', none: 'none', }, transitionTimingFunction: { out: 'var(--ease-out)', 'in-out': 'var(--ease-in-out)', spring: 'var(--ease-spring)', }, transitionDuration: { fast: 'var(--duration-fast)', base: 'var(--duration-base)', slow: 'var(--duration-slow)', }, maxWidth: { container: 'var(--container-max)', /* The shell width. Wide enough that the dashboard keeps roughly its original measure once the 380px assistant column is beside it. */ 'container-wide': 'var(--container-wide)', admin: 'var(--container-admin)', }, keyframes: { 'accordion-down': { from: { height: '0' }, to: { height: 'var(--radix-accordion-content-height)' }, }, 'accordion-up': { from: { height: 'var(--radix-accordion-content-height)' }, to: { height: '0' }, }, shimmer: { '0%': { backgroundPosition: '200% 0' }, '100%': { backgroundPosition: '-200% 0' }, }, 'fade-in': { from: { opacity: '0' }, to: { opacity: '1' }, }, 'slide-up': { from: { opacity: '0', transform: 'translateY(8px)' }, to: { opacity: '1', transform: 'translateY(0)' }, }, 'slide-down': { from: { opacity: '0', transform: 'translateY(-8px)' }, to: { opacity: '1', transform: 'translateY(0)' }, }, 'scale-in': { from: { opacity: '0', transform: 'scale(0.96)' }, to: { opacity: '1', transform: 'scale(1)' }, }, /* Owliver typing indicator */ typing: { '0%, 60%, 100%': { opacity: '0.3', transform: 'translateY(0)' }, '30%': { opacity: '1', transform: 'translateY(-2px)' }, }, /* Live/streaming pulse on the assistant status dot */ 'pulse-ring': { '0%': { boxShadow: '0 0 0 0 rgb(34 197 94 / 0.5)' }, '70%': { boxShadow: '0 0 0 6px rgb(34 197 94 / 0)' }, '100%': { boxShadow: '0 0 0 0 rgb(34 197 94 / 0)' }, }, caret: { '0%, 49%': { opacity: '1' }, '50%, 100%': { opacity: '0' }, }, }, animation: { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', shimmer: 'shimmer 1.6s var(--ease-in-out) infinite', 'fade-in': 'fade-in var(--duration-base) var(--ease-out)', 'slide-up': 'slide-up var(--duration-slow) var(--ease-out)', 'slide-down': 'slide-down var(--duration-slow) var(--ease-out)', 'scale-in': 'scale-in var(--duration-base) var(--ease-out)', typing: 'typing 1.2s var(--ease-in-out) infinite', 'pulse-ring': 'pulse-ring 2s var(--ease-out) infinite', caret: 'caret 1s steps(1) infinite', }, }, }, plugins: [require('tailwindcss-animate')], };