import plugin from 'tailwindcss/plugin'; import { fontFamily } from 'tailwindcss/defaultTheme'; import type { Config } from 'tailwindcss'; import { BrainfishColors } from './src/colors'; const { blue, dark, green, lime, magenta, orange, pink, primary, purple, red, teal, yellow } = BrainfishColors; const preset: Partial = { darkMode: ['class'], theme: { container: { center: true, padding: '2rem', screens: { '2xl': '1400px', }, }, extend: { fontFamily: { ...fontFamily, sans: ['var(--bfc-font-family)', 'system-ui', 'sans-serif'], fraunces: ['var(--font-fraunces)', 'serif'], inter: ['var(--font-inter)', 'sans-serif'], }, fontWeight: { bold: '700', normal: '400', }, colors: { transparent: 'transparent', primary: 'var(--bfc-primary)', success: { DEFAULT: 'var(--bfc-success-bg)', foreground: 'var(--bfc-success-text)', }, destructive: { DEFAULT: 'var(--bfc-destructive-bg)', foreground: 'var(--bfc-destructive-text)', }, warning: 'var(--bfc-warning-bg)', base: { orange: orange.DEFAULT, yellow: yellow.DEFAULT, primary: primary.DEFAULT, green: green.DEFAULT, blue: blue.DEFAULT, purple: purple.DEFAULT, pink: pink.DEFAULT, red: red.DEFAULT, lime: lime.DEFAULT, teal: teal.DEFAULT, magenta: magenta.DEFAULT, }, dark, orange, yellow, green, blue, purple, pink, red, border: 'var(--bfc-border)', 'border-subtle': 'var(--bfc-border-subtle)', input: 'var(--bfc-input)', ring: 'color-mix(in srgb, var(--bfc-primary) 85%, transparent)', background: 'var(--bfc-background)', foreground: 'var(--bfc-foreground)', feedback: { positive: 'var(--bfc-feedback-positive)', negative: 'var(--bfc-feedback-negative)', }, link: 'var(--bfc-link)', surface: { DEFAULT: 'var(--bfc-surface)', border: 'var(--bfc-surface-border)', }, secondary: { DEFAULT: 'var(--bfc-secondary)', foreground: 'var(--bfc-secondary-foreground)', }, muted: { DEFAULT: 'var(--bfc-muted)', foreground: 'var(--bfc-muted-foreground)', }, accent: { DEFAULT: 'var(--bfc-accent)', foreground: 'var(--bfc-accent-foreground)', }, popover: { DEFAULT: 'var(--bfc-popover)', foreground: 'var(--bfc-foreground)', }, card: { DEFAULT: 'var(--bfc-card)', foreground: 'var(--bfc-card-foreground)', }, }, textColor: { primary: 'var(--bfc-primary-foreground)', 'primary-foreground': 'var(--bfc-primary-foreground)', default: 'var(--bfc-text-default)', subtle: 'var(--bfc-text-subtle)', subtlest: 'var(--bfc-text-subtlest)', success: 'var(--bfc-success-text)', destructive: 'var(--bfc-destructive-text)', warning: 'var(--bfc-warning-text)', }, backgroundColor: { success: 'var(--bfc-success-bg)', destructive: 'var(--bfc-destructive-bg)', warning: 'var(--bfc-warning-bg)', surface: 'var(--bfc-white)', }, borderColor: { success: 'var(--bfc-success-border)', destructive: 'var(--bfc-destructive-border)', warning: 'var(--bfc-warning-border)', }, 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' }, }, sweep: { '0%': { backgroundPosition: '100% center' }, '100%': { backgroundPosition: '-100% center' }, }, }, animation: { 'accordion-down': 'accordion-down 0.2s ease-out', 'accordion-up': 'accordion-up 0.2s ease-out', sweep: 'sweep 1.8s linear infinite', }, maxWidth: { threadWidth: '1400px', }, spacing: { headerHeight: '64px', md: '16px', lg: '24px', xl: '32px', }, backgroundImage: { 'gradient-yellowfin': 'linear-gradient(168deg, rgb(24, 104, 219) 7.35%, rgb(53, 125, 232) 23.69%, rgb(126, 226, 184) 61.42%, rgb(179, 238, 43) 82.59%)', 'sweep-yellowfin': 'linear-gradient(90deg, var(--bfc-v2-color-blue-700) 0%, var(--bfc-v2-color-blue-700) 37%, var(--bfc-v2-color-blue-600) 42%, var(--bfc-v2-color-green-300) 46%, var(--bfc-v2-color-lime-300) 50%, var(--bfc-v2-color-green-300) 54%, var(--bfc-v2-color-blue-600) 58%, var(--bfc-v2-color-blue-700) 63%, var(--bfc-v2-color-blue-700) 100%)', }, zIndex: { 'above-modal': '9999', }, boxShadow: { md: '2px 4px 12px 0 rgba(0,0,0,0.14)', 'md-invert': '2px 4px 12px 0 rgba(255,255,255,0.14)', brand: '2px 2px 0 0 #0A0A0D', 'brand-active': 'inset 2px 2px 0 0 #262626', 'brand-dark': '2px 2px 0 0 #FFF', 'brand-dark-active': 'inset 2px 2px 0 0 #FFF', }, gridTemplateColumns: { 12: 'repeat(12, minmax(0, 1fr))', }, }, }, plugins: [ require('tailwindcss-animate'), require('@tailwindcss/container-queries'), plugin(function ({ addBase }) { addBase({ 'ul': { listStyleType: 'disc' }, 'ol': { listStyleType: 'decimal' }, }); }), plugin(function ({ addUtilities }) { addUtilities({ // Typography - Headings ...Object.entries({ 'xxl': { fontSize: '2rem', lineHeight: '2.25rem', fontFamily: 'var(--bfc-heading-xxl-font-family)' }, 'xl': { fontSize: '1.75rem', lineHeight: '2rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'lg': { fontSize: '1.5rem', lineHeight: '1.75rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'm': { fontSize: '1.25rem', lineHeight: '1.5rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'sm': { fontSize: '1rem', lineHeight: '1.25rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'xs': { fontSize: '0.875rem', lineHeight: '1.25rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'xxs': { fontSize: '0.75rem', lineHeight: '1rem', fontFamily: 'var(--bfc-v2-font-family)' }, 'xxxs': { fontSize: '0.625rem', lineHeight: '0.875rem', fontFamily: 'var(--bfc-v2-font-family)' }, }).reduce( (acc, [size, styles]) => { // outputs `.heading-[size] classes` acc[`.heading-${size}`] = { 'font-family': styles.fontFamily, 'font-size': styles.fontSize, 'font-style': 'normal', 'font-weight': '700', 'line-height': styles.lineHeight, }; return acc; }, {} as Record, ), // Typography - Paragraph ...Object.entries({ 'lg': { fontSize: '1rem', lineHeight: '1.5rem' }, 'md': { fontSize: '0.875rem', lineHeight: '1.25rem' }, 'sm': { fontSize: '0.75rem', lineHeight: '1rem' }, }).reduce( (acc, [size, styles]) => { // outputs `.paragraph-[size] classes` acc[`.paragraph-${size}`] = { 'font-family': 'var(--bfc-v2-font-family)', 'font-size': styles.fontSize, 'font-style': 'normal', 'font-weight': '400', 'line-height': styles.lineHeight, }; return acc; }, {} as Record, ), '.text-subtlest': { fontWeight: '400' }, }); }), plugin(function ({ addUtilities }) { const dashedBorderUtilities: Record = {}; const gradient = (deg: number, color: string) => `repeating-linear-gradient(${deg}deg, ${color}, ${color} 8px, transparent 8px, transparent 16px)`; const createBorderUtility = (colorValue: string, sides: number[], baseName: string) => { const gradients = [0, 90, 180, 270].map((deg) => { const color = sides.includes(deg) ? colorValue : 'transparent'; return gradient(deg, color); }); const className = baseName ? `.custom-dashed-border-${baseName}` : '.custom-dashed-border'; return { [className]: { position: 'relative', border: 'none', }, [`${className}::before`]: { content: '""', position: 'absolute', inset: '0', 'background-image': gradients.join(','), 'background-position': '0 0, 0 0, 100% 0, 0 100%', 'background-size': '1px 100%, 100% 1px, 1px 100%, 100% 1px', 'background-repeat': 'no-repeat', 'pointer-events': 'none', 'border-radius': 'inherit', 'z-index': '0', }, }; }; const generateUtilitiesForColor = (colorValue: string, baseName: string) => { const utilities: Record = {}; Object.assign(utilities, createBorderUtility(colorValue, [0, 90, 180, 270], baseName)); Object.assign(utilities, createBorderUtility(colorValue, [90], baseName ? `t-${baseName}` : 't')); Object.assign(utilities, createBorderUtility(colorValue, [180], baseName ? `r-${baseName}` : 'r')); Object.assign(utilities, createBorderUtility(colorValue, [270], baseName ? `b-${baseName}` : 'b')); Object.assign(utilities, createBorderUtility(colorValue, [0], baseName ? `l-${baseName}` : 'l')); Object.assign(utilities, createBorderUtility(colorValue, [0, 180], baseName ? `x-${baseName}` : 'x')); Object.assign(utilities, createBorderUtility(colorValue, [90, 270], baseName ? `y-${baseName}` : 'y')); return utilities; }; Object.assign(dashedBorderUtilities, generateUtilitiesForColor('var(--bfc-border)', '')); Object.entries(BrainfishColors).forEach(([colorName, colorShades]) => { Object.entries(colorShades).forEach(([shade, colorValue]) => { const baseName = shade === 'DEFAULT' ? colorName : `${colorName}-${shade}`; Object.assign(dashedBorderUtilities, generateUtilitiesForColor(colorValue as string, baseName)); }); }); addUtilities(dashedBorderUtilities); addUtilities({ '.custom-dashed-border-hover': { '&::before': { 'background-image': 'none', 'border': '1px solid var(--bfc-border)', }, 'box-shadow': '4px 4px 0 0 var(--bfc-border)', }, }); const yellowfinBase = { 'border': '1.2px solid transparent', 'background': `linear-gradient(145.85deg, #1868DB 7.35%, #357DE8 23.69%, #7EE2B8 61.42%, #B4EE2B 82.59%), linear-gradient(145.85deg, rgba(180, 238, 43, 0.7) 3.02%, rgba(126, 226, 184, 0.7) 24.19%, rgba(53, 125, 232, 0.7) 61.92%, rgba(24, 104, 219, 0.7) 78.26%)`, 'transition': 'all 0.2s ease-in-out', 'background-origin': 'border-box', 'background-clip': 'content-box, border-box', } as const; addUtilities({ '.bg-yellowfin-gradient': { ...yellowfinBase }, '.bg-yellowfin-gradient-reverse': { ...yellowfinBase, 'filter': 'brightness(1.02) saturate(1.5) hue-rotate(5deg)', 'transform': 'translateY(-1px)', }, }); }), ], }; export default preset;