BREAKING: Full rewrite from static HTML to production-grade stack. Features: - React 18 + Vite + Tailwind CSS (mobile-first) - Express + Prisma + PostgreSQL backend - JWT authentication with role-based access - Weekly Mon-Sun timesheets with auto-save - Multiple homeowner entries per day - Submit → Approve/Reject workflow - Server-side PDF generation - SMTP email integration - Admin panel with reporting & filters - Dark mode (system-aware) - Docker Compose one-command deploy - Non-root containers, Helmet, bcrypt, Zod validation
89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
/** @type {import('tailwindcss').Config} */
|
|
export default {
|
|
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
|
darkMode: 'class',
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
ocean: {
|
|
50: '#f0f9ff',
|
|
100: '#e0f2fe',
|
|
200: '#bae6fd',
|
|
300: '#7dd3fc',
|
|
400: '#38bdf8',
|
|
500: '#0ea5e9',
|
|
600: '#0284c7',
|
|
700: '#0369a1',
|
|
800: '#075985',
|
|
900: '#0c4a6e',
|
|
950: '#082f49',
|
|
},
|
|
coastal: {
|
|
50: '#f0fdfa',
|
|
100: '#ccfbf1',
|
|
200: '#99f6e4',
|
|
300: '#5eead4',
|
|
400: '#2dd4bf',
|
|
500: '#14b8a6',
|
|
600: '#0d9488',
|
|
700: '#0f766e',
|
|
800: '#115e59',
|
|
900: '#134e4a',
|
|
},
|
|
},
|
|
fontFamily: {
|
|
sans: [
|
|
'-apple-system',
|
|
'BlinkMacSystemFont',
|
|
'SF Pro Display',
|
|
'SF Pro Text',
|
|
'Segoe UI',
|
|
'Roboto',
|
|
'Helvetica Neue',
|
|
'Arial',
|
|
'sans-serif',
|
|
],
|
|
},
|
|
borderRadius: {
|
|
'2xl': '1rem',
|
|
'3xl': '1.5rem',
|
|
},
|
|
boxShadow: {
|
|
'soft': '0 2px 15px -3px rgba(0, 0, 0, 0.07), 0 10px 20px -2px rgba(0, 0, 0, 0.04)',
|
|
'soft-lg': '0 10px 40px -10px rgba(0, 0, 0, 0.1), 0 2px 10px -2px rgba(0, 0, 0, 0.04)',
|
|
'inner-soft': 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.04)',
|
|
},
|
|
animation: {
|
|
'fade-in': 'fadeIn 0.3s ease-out',
|
|
'slide-up': 'slideUp 0.3s ease-out',
|
|
'slide-down': 'slideDown 0.3s ease-out',
|
|
'scale-in': 'scaleIn 0.2s ease-out',
|
|
'pulse-soft': 'pulseSoft 2s ease-in-out infinite',
|
|
},
|
|
keyframes: {
|
|
fadeIn: {
|
|
'0%': { opacity: '0' },
|
|
'100%': { opacity: '1' },
|
|
},
|
|
slideUp: {
|
|
'0%': { opacity: '0', transform: 'translateY(10px)' },
|
|
'100%': { opacity: '1', transform: 'translateY(0)' },
|
|
},
|
|
slideDown: {
|
|
'0%': { opacity: '0', transform: 'translateY(-10px)' },
|
|
'100%': { opacity: '1', transform: 'translateY(0)' },
|
|
},
|
|
scaleIn: {
|
|
'0%': { opacity: '0', transform: 'scale(0.95)' },
|
|
'100%': { opacity: '1', transform: 'scale(1)' },
|
|
},
|
|
pulseSoft: {
|
|
'0%, 100%': { opacity: '1' },
|
|
'50%': { opacity: '0.5' },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
plugins: [require('@tailwindcss/forms')],
|
|
};
|