ADD new frontend

This commit is contained in:
Urtzi Alfaro
2025-08-28 10:41:04 +02:00
parent 9c247a5f99
commit 0fd273cfce
492 changed files with 114979 additions and 1632 deletions

View File

@@ -0,0 +1,204 @@
# Centralized Color Palette System
This document describes the unified color system implemented for the Bakery IA frontend application.
## 🎯 Overview
The application now uses a **centralized color configuration** that ensures consistent theming across both light and dark modes while maintaining a professional bakery brand identity.
## 📁 File Structure
```
src/styles/
├── colors.js # 🏛️ Single source of truth for all colors
├── themes/
│ ├── light.css # 🌞 Light theme CSS variables
│ └── dark.css # 🌙 Dark theme CSS variables
├── components.css # 🧩 CSS utility classes
├── globals.css # 🌐 Base styles
└── animations.css # ✨ Animation definitions
```
## 🏛️ Centralized Color Configuration (`colors.js`)
### Base Color Palette
- **Primary**: Warm Orange (#d97706) - Bakery brand color
- **Secondary**: Professional Sage Green (#16a34a) - Complements the brand
- **Semantic Colors**: Success, Warning, Error, Info with full scale support
- **Neutral**: Professional grayscale for text and backgrounds
### Professional Bakery Colors
Special accent colors inspired by bakery products:
- `sourdough`, `wholeWheat`, `brioche`, `rye`, `croissant`
- `danish`, `espresso`, `latte`, `chocolate`, `vanilla`
- And more for specialized use cases
### Chart Colors
Colorblind-safe data visualization palette:
- 8 distinct colors optimized for accessibility
- Different brightness levels for light/dark themes
## 🎨 Theme System
### Light Theme
- Clean, professional appearance
- High contrast for accessibility
- Warm whites and light grays
### Dark Theme
- Rich dark backgrounds (#0f172a, #1e293b)
- Enhanced color brightness for readability
- Maintains brand consistency
## 🔧 Usage
### 1. In CSS (Recommended)
```css
.my-component {
background-color: var(--bg-primary);
color: var(--text-primary);
border: 1px solid var(--border-primary);
}
.primary-button {
background-color: var(--color-primary);
color: var(--text-inverse);
}
```
### 2. Tailwind Classes
```jsx
<div className="bg-primary-600 text-white">
Primary content
</div>
<div className="bg-secondary-500 text-white">
Secondary content
</div>
```
### 3. CSS Utility Classes
```jsx
<div className="bg-bg-primary text-text-primary border-border-primary">
Themed content
</div>
```
## 🏗️ CSS Variable Structure
### Semantic Colors
```css
--color-primary: #d97706 /* Main brand color */
--color-primary-light: #f59e0b /* Lighter variant */
--color-primary-dark: #b45309 /* Darker variant */
--color-primary-50: #fffbeb /* Lightest scale */
--color-primary-900: #78350f /* Darkest scale */
```
### Theme-Specific Colors
```css
--bg-primary: #ffffff /* Main background */
--bg-secondary: #f8fafc /* Secondary background */
--text-primary: #0f172a /* Primary text */
--text-secondary: #475569 /* Secondary text */
--border-primary: #e2e8f0 /* Main borders */
```
### Component Colors
```css
--card-bg: #ffffff /* Card backgrounds */
--input-bg: #ffffff /* Input backgrounds */
--nav-bg: #ffffff /* Navigation background */
```
## 🎪 Available Utility Classes
The system automatically generates utility classes for all color variables:
### Background Classes
- `.bg-bg-primary`, `.bg-bg-secondary`, `.bg-bg-tertiary`
- `.bg-color-primary`, `.bg-color-secondary`, `.bg-color-success`
### Text Classes
- `.text-text-primary`, `.text-text-secondary`, `.text-text-tertiary`
- `.text-color-primary`, `.text-color-error`, `.text-color-success`
### Border Classes
- `.border-border-primary`, `.border-border-secondary`
- `.border-color-primary`, `.border-color-error`
## 🌓 Theme Switching
The application automatically applies the correct color values based on the theme class:
```html
<!-- Light theme -->
<html class="light">
<!-- Colors from light.css applied -->
</html>
<!-- Dark theme -->
<html class="dark">
<!-- Colors from dark.css applied -->
</html>
```
## ✅ Benefits
1. **Single Source of Truth**: All colors defined in one place
2. **Consistent Theming**: Automatic light/dark theme support
3. **Brand Consistency**: Professional bakery color palette
4. **Accessibility**: WCAG 2.1 AA compliant contrast ratios
5. **Developer Experience**: Easy to use utility classes
6. **Maintainability**: Change colors in one place, update everywhere
## 🔄 Migration Guide
### From Hardcoded Colors
```jsx
// ❌ Before
<div className="bg-orange-600 text-white">
// ✅ After
<div className="bg-color-primary text-text-inverse">
```
### From Old CSS Variables
```css
/* ❌ Before */
.component {
background: #d97706;
}
/* ✅ After */
.component {
background: var(--color-primary);
}
```
## 🎯 Best Practices
1. **Always use CSS variables** instead of hardcoded hex values
2. **Prefer semantic classes** like `text-text-primary` over `text-gray-900`
3. **Test in both themes** to ensure proper contrast
4. **Use bakery colors** for brand-specific elements
5. **Use chart colors** for data visualizations
## 🔍 Color Reference
### Primary Palette
- **Primary**: #d97706 (Orange) - Main brand color
- **Secondary**: #16a34a (Sage Green) - Professional complement
- **Success**: #059669 (Green) - Positive actions
- **Warning**: #ea580c (Orange variant) - Caution states
- **Error**: #dc2626 (Red) - Error states
- **Info**: #0284c7 (Blue) - Informational content
### Theme Backgrounds
- **Light**: #ffffff, #f8fafc, #f1f5f9
- **Dark**: #0f172a, #1e293b, #334155
This centralized system ensures consistent, accessible, and maintainable color usage throughout the application while supporting both light and dark themes seamlessly.

View File

@@ -0,0 +1,709 @@
/**
* Animation utilities and keyframes for the bakery management application
*/
/* Keyframe Animations */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
@keyframes bounce {
0%, 20%, 53%, 80%, 100% {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
transform: translateY(0);
}
40%, 43% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translateY(-30px);
}
70% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translateY(-15px);
}
90% {
transform: translateY(-4px);
}
}
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-10px);
}
20%, 40%, 60%, 80% {
transform: translateX(10px);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes slideInUp {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInDown {
from {
transform: translateY(-100%);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOutUp {
from {
transform: translateY(0);
opacity: 1;
}
to {
transform: translateY(-100%);
opacity: 0;
}
}
@keyframes slideOutDown {
from {
transform: translateY(0);
opacity: 1;
}
to {
transform: translateY(100%);
opacity: 0;
}
}
@keyframes slideOutLeft {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(-100%);
opacity: 0;
}
}
@keyframes slideOutRight {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}
@keyframes scaleIn {
from {
transform: scale(0.9);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes scaleOut {
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(0.9);
opacity: 0;
}
}
@keyframes skeleton-loading {
0% {
background-position: -200px 0;
}
100% {
background-position: calc(200px + 100%) 0;
}
}
@keyframes progress-indeterminate {
0% {
left: -35%;
right: 100%;
}
60% {
left: 100%;
right: -90%;
}
100% {
left: 100%;
right: -90%;
}
}
@keyframes ripple {
0% {
transform: scale(0);
opacity: 0.6;
}
100% {
transform: scale(4);
opacity: 0;
}
}
@keyframes glow {
0% {
box-shadow: 0 0 5px currentColor;
}
50% {
box-shadow: 0 0 20px currentColor, 0 0 30px currentColor;
}
100% {
box-shadow: 0 0 5px currentColor;
}
}
@keyframes heartbeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
@keyframes flash {
0%, 50%, 100% {
opacity: 1;
}
25%, 75% {
opacity: 0;
}
}
@keyframes wiggle {
0%, 7% {
transform: rotateZ(0);
}
15% {
transform: rotateZ(-15deg);
}
20% {
transform: rotateZ(10deg);
}
25% {
transform: rotateZ(-10deg);
}
30% {
transform: rotateZ(6deg);
}
35% {
transform: rotateZ(-4deg);
}
40%, 100% {
transform: rotateZ(0);
}
}
/* Animation Utility Classes */
.animate-spin {
animation: spin 1s linear infinite;
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.animate-bounce {
animation: bounce 1s infinite;
}
.animate-shake {
animation: shake 0.5s ease-in-out;
}
.animate-fade-in {
animation: fadeIn var(--transition-normal) ease-out;
}
.animate-fade-out {
animation: fadeOut var(--transition-normal) ease-out;
}
.animate-slide-in-up {
animation: slideInUp var(--transition-normal) ease-out;
}
.animate-slide-in-down {
animation: slideInDown var(--transition-normal) ease-out;
}
.animate-slide-in-left {
animation: slideInLeft var(--transition-normal) ease-out;
}
.animate-slide-in-right {
animation: slideInRight var(--transition-normal) ease-out;
}
.animate-slide-out-up {
animation: slideOutUp var(--transition-normal) ease-in;
}
.animate-slide-out-down {
animation: slideOutDown var(--transition-normal) ease-in;
}
.animate-slide-out-left {
animation: slideOutLeft var(--transition-normal) ease-in;
}
.animate-slide-out-right {
animation: slideOutRight var(--transition-normal) ease-in;
}
.animate-scale-in {
animation: scaleIn var(--transition-normal) ease-out;
}
.animate-scale-out {
animation: scaleOut var(--transition-normal) ease-in;
}
.animate-glow {
animation: glow 2s ease-in-out infinite alternate;
}
.animate-heartbeat {
animation: heartbeat 1.5s ease-in-out infinite;
}
.animate-flash {
animation: flash 1s linear infinite;
}
.animate-wiggle {
animation: wiggle 1s ease-in-out;
}
/* Transition Utilities */
.transition-none {
transition: none;
}
.transition-all {
transition: all var(--transition-fast);
}
.transition-colors {
transition: color var(--transition-fast), background-color var(--transition-fast), border-color var(--transition-fast);
}
.transition-opacity {
transition: opacity var(--transition-fast);
}
.transition-shadow {
transition: box-shadow var(--transition-fast);
}
.transition-transform {
transition: transform var(--transition-fast);
}
/* Transform Utilities */
.transform {
transform: translateX(var(--transform-translate-x, 0)) translateY(var(--transform-translate-y, 0)) rotate(var(--transform-rotate, 0)) skewX(var(--transform-skew-x, 0)) skewY(var(--transform-skew-y, 0)) scaleX(var(--transform-scale-x, 1)) scaleY(var(--transform-scale-y, 1));
}
.rotate-0 {
--transform-rotate: 0deg;
}
.rotate-45 {
--transform-rotate: 45deg;
}
.rotate-90 {
--transform-rotate: 90deg;
}
.rotate-180 {
--transform-rotate: 180deg;
}
.scale-0 {
--transform-scale-x: 0;
--transform-scale-y: 0;
}
.scale-50 {
--transform-scale-x: 0.5;
--transform-scale-y: 0.5;
}
.scale-75 {
--transform-scale-x: 0.75;
--transform-scale-y: 0.75;
}
.scale-90 {
--transform-scale-x: 0.9;
--transform-scale-y: 0.9;
}
.scale-95 {
--transform-scale-x: 0.95;
--transform-scale-y: 0.95;
}
.scale-100 {
--transform-scale-x: 1;
--transform-scale-y: 1;
}
.scale-105 {
--transform-scale-x: 1.05;
--transform-scale-y: 1.05;
}
.scale-110 {
--transform-scale-x: 1.1;
--transform-scale-y: 1.1;
}
.scale-125 {
--transform-scale-x: 1.25;
--transform-scale-y: 1.25;
}
.scale-150 {
--transform-scale-x: 1.5;
--transform-scale-y: 1.5;
}
/* Hover Animations */
.hover-lift {
transition: transform var(--transition-fast);
}
.hover-lift:hover {
transform: translateY(-2px);
}
.hover-scale {
transition: transform var(--transition-fast);
}
.hover-scale:hover {
transform: scale(1.05);
}
.hover-rotate {
transition: transform var(--transition-fast);
}
.hover-rotate:hover {
transform: rotate(5deg);
}
.hover-glow {
transition: box-shadow var(--transition-fast);
}
.hover-glow:hover {
box-shadow: 0 0 20px rgb(217 119 6 / 0.3);
}
/* Loading States */
.loading {
position: relative;
color: transparent !important;
pointer-events: none;
}
.loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 1rem;
height: 1rem;
margin: -0.5rem 0 0 -0.5rem;
border: 2px solid var(--border-secondary);
border-radius: 50%;
border-top: 2px solid var(--color-primary);
animation: spin 1s linear infinite;
}
/* Stagger Animations */
.stagger-item {
opacity: 0;
transform: translateY(20px);
animation: slideInUp var(--transition-normal) ease-out forwards;
}
.stagger-item:nth-child(1) {
animation-delay: 0ms;
}
.stagger-item:nth-child(2) {
animation-delay: 100ms;
}
.stagger-item:nth-child(3) {
animation-delay: 200ms;
}
.stagger-item:nth-child(4) {
animation-delay: 300ms;
}
.stagger-item:nth-child(5) {
animation-delay: 400ms;
}
.stagger-item:nth-child(6) {
animation-delay: 500ms;
}
.stagger-item:nth-child(7) {
animation-delay: 600ms;
}
.stagger-item:nth-child(8) {
animation-delay: 700ms;
}
.stagger-item:nth-child(9) {
animation-delay: 800ms;
}
.stagger-item:nth-child(10) {
animation-delay: 900ms;
}
/* Reduced Motion */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.animate-spin,
.animate-pulse,
.animate-bounce {
animation: none;
}
}
/* Focus Animations */
.focus-ring {
transition: box-shadow var(--transition-fast);
}
.focus-ring:focus {
outline: none;
box-shadow: 0 0 0 3px rgb(217 119 6 / 0.2);
}
.focus-ring:focus-visible {
box-shadow: 0 0 0 3px rgb(217 119 6 / 0.3);
}
/* Entry Animations */
.page-enter {
opacity: 0;
transform: translateY(20px);
}
.page-enter-active {
opacity: 1;
transform: translateY(0);
transition: opacity var(--transition-normal), transform var(--transition-normal);
}
.page-exit {
opacity: 1;
transform: translateY(0);
}
.page-exit-active {
opacity: 0;
transform: translateY(-20px);
transition: opacity var(--transition-normal), transform var(--transition-normal);
}
/* Modal Animations */
.modal-enter {
opacity: 0;
transform: scale(0.95);
}
.modal-enter-active {
opacity: 1;
transform: scale(1);
transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.modal-exit {
opacity: 1;
transform: scale(1);
}
.modal-exit-active {
opacity: 0;
transform: scale(0.95);
transition: opacity var(--transition-fast), transform var(--transition-fast);
}
/* Toast Animations */
.toast-enter {
opacity: 0;
transform: translateX(100%);
}
.toast-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.toast-exit {
opacity: 1;
transform: translateX(0);
}
.toast-exit-active {
opacity: 0;
transform: translateX(100%);
transition: opacity var(--transition-fast), transform var(--transition-fast);
}
/* Bakery Specific Animations */
@keyframes oven-heat {
0%, 100% {
box-shadow: 0 0 10px rgba(255, 165, 0, 0.3);
}
50% {
box-shadow: 0 0 20px rgba(255, 165, 0, 0.6), 0 0 30px rgba(255, 69, 0, 0.4);
}
}
@keyframes mixing {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(90deg) scale(1.1);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(270deg) scale(1.1);
}
100% {
transform: rotate(360deg);
}
}
@keyframes rising {
0% {
transform: scaleY(0.8);
}
50% {
transform: scaleY(1.1);
}
100% {
transform: scaleY(1);
}
}
.animate-oven-heat {
animation: oven-heat 2s ease-in-out infinite;
}
.animate-mixing {
animation: mixing 1s ease-in-out infinite;
}
.animate-rising {
animation: rising 3s ease-in-out infinite;
}

View File

@@ -0,0 +1,321 @@
/**
* Centralized Color Palette Configuration
* Single source of truth for all application colors
*/
// Base Color Palette - Professional Bakery Theme
export const baseColors = {
// Primary Colors - Warm Orange (Bakery Brand)
primary: {
50: '#fffbeb',
100: '#fef3c7',
200: '#fde68a',
300: '#fcd34d',
400: '#fbbf24',
500: '#f59e0b',
600: '#d97706', // Main brand color
700: '#b45309',
800: '#92400e',
900: '#78350f',
},
// Secondary Colors - Professional Sage Green
secondary: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a', // Main secondary color
700: '#15803d',
800: '#166534',
900: '#14532d',
},
// Semantic Colors
success: {
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b',
},
warning: {
50: '#fffbeb',
100: '#fef3c7',
200: '#fde68a',
300: '#fcd34d',
400: '#fbbf24',
500: '#f59e0b',
600: '#ea580c', // Distinct from primary
700: '#c2410c',
800: '#9a3412',
900: '#7c2d12',
},
error: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d',
},
info: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
},
// Neutral Colors (Grayscale)
neutral: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a',
},
};
// Professional Bakery Accent Colors
export const bakeryColors = {
sourdough: '#d4a574',
wholeWheat: '#a67c52',
brioche: '#f4e4bc',
rye: '#8b6f47',
croissant: '#f5d76e',
danish: '#e8b4cb',
espresso: '#3c2415',
latte: '#c8a882',
bread: '#deb887',
wheat: '#f5deb3',
flour: '#faf0e6',
butter: '#fff8dc',
chocolate: '#8b4513',
vanilla: '#f5f5dc',
strawberry: '#ff69b4',
mint: '#98fb98',
caramel: '#d2691e',
cream: '#fffdd0',
};
// Chart Colors (Colorblind-Safe Data Visualization)
export const chartColors = {
primary: '#d97706', // Orange
secondary: '#0369a1', // Blue
tertiary: '#16a34a', // Green
quaternary: '#dc2626', // Red
quinary: '#7c3aed', // Purple
senary: '#0891b2', // Cyan
septenary: '#ea580c', // Orange variant
octonary: '#059669', // Emerald
};
// Light Theme Color Mapping
export const lightTheme = {
// Backgrounds
bg: {
primary: '#ffffff',
secondary: '#f8fafc',
tertiary: '#f1f5f9',
quaternary: '#e2e8f0',
overlay: 'rgba(255, 255, 255, 0.8)',
modalBackdrop: 'rgba(0, 0, 0, 0.5)',
},
// Text Colors
text: {
primary: '#0f172a',
secondary: '#475569',
tertiary: '#64748b',
quaternary: '#94a3b8',
inverse: '#ffffff',
muted: '#64748b',
disabled: '#cbd5e1',
},
// Borders
border: {
primary: '#e2e8f0',
secondary: '#cbd5e1',
tertiary: '#94a3b8',
focus: '#d97706',
error: '#dc2626',
success: '#059669',
},
// Surfaces
surface: {
primary: '#ffffff',
secondary: '#f8fafc',
tertiary: '#f1f5f9',
raised: '#ffffff',
overlay: 'rgba(255, 255, 255, 0.95)',
},
// Component-specific
input: {
bg: '#ffffff',
border: '#d1d5db',
borderFocus: '#d97706',
borderError: '#dc2626',
placeholder: '#9ca3af',
},
nav: {
bg: '#ffffff',
border: '#e5e7eb',
itemHover: '#f9fafb',
itemActive: '#fef3c7',
},
card: {
bg: '#ffffff',
border: '#e5e7eb',
shadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
},
};
// Dark Theme Color Mapping
export const darkTheme = {
// Backgrounds
bg: {
primary: '#0f172a',
secondary: '#1e293b',
tertiary: '#334155',
quaternary: '#475569',
overlay: 'rgba(0, 0, 0, 0.8)',
modalBackdrop: 'rgba(0, 0, 0, 0.75)',
},
// Text Colors
text: {
primary: '#f8fafc',
secondary: '#cbd5e1',
tertiary: '#94a3b8',
quaternary: '#64748b',
inverse: '#0f172a',
muted: '#64748b',
disabled: '#475569',
},
// Borders
border: {
primary: '#334155',
secondary: '#475569',
tertiary: '#64748b',
focus: '#f59e0b',
error: '#ef4444',
success: '#22c55e',
},
// Surfaces
surface: {
primary: '#1e293b',
secondary: '#334155',
tertiary: '#475569',
raised: '#1e293b',
overlay: 'rgba(15, 23, 42, 0.95)',
},
// Component-specific
input: {
bg: '#1e293b',
border: '#475569',
borderFocus: '#f59e0b',
borderError: '#ef4444',
placeholder: '#64748b',
},
nav: {
bg: '#1e293b',
border: '#334155',
itemHover: '#334155',
itemActive: 'rgba(245, 158, 11, 0.2)',
},
card: {
bg: '#1e293b',
border: '#334155',
shadow: '0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4)',
},
};
// Export for Tailwind Config
export const tailwindColorConfig = {
...baseColors,
bakery: bakeryColors,
chart: chartColors,
};
// CSS Custom Properties Generator
export const generateCSSVariables = (theme = 'light') => {
const themeColors = theme === 'light' ? lightTheme : darkTheme;
const semanticColors = baseColors;
const cssVars = {};
// Generate semantic color variables
Object.entries(semanticColors).forEach(([colorName, colorScale]) => {
if (typeof colorScale === 'object') {
Object.entries(colorScale).forEach(([scale, value]) => {
cssVars[`--color-${colorName}-${scale}`] = value;
});
// Main color (600 scale as default)
cssVars[`--color-${colorName}`] = colorScale[600];
}
});
// Generate theme-specific variables
Object.entries(themeColors).forEach(([categoryName, category]) => {
Object.entries(category).forEach(([propertyName, value]) => {
cssVars[`--${categoryName}-${propertyName}`] = value;
});
});
// Generate bakery colors
Object.entries(bakeryColors).forEach(([colorName, value]) => {
cssVars[`--color-${colorName}`] = value;
});
// Generate chart colors
Object.entries(chartColors).forEach(([colorName, value]) => {
cssVars[`--chart-${colorName}`] = value;
});
return cssVars;
};
export default {
baseColors,
bakeryColors,
chartColors,
lightTheme,
darkTheme,
tailwindColorConfig,
generateCSSVariables,
};

View File

@@ -0,0 +1,975 @@
/**
* Component styles for reusable UI components
*/
/* Custom Utility Classes for CSS Variables */
/* Background Color Utilities */
.bg-color-primary {
background-color: var(--color-primary);
}
.bg-color-primary-light {
background-color: var(--color-primary-light);
}
.bg-color-primary-dark {
background-color: var(--color-primary-dark);
}
.bg-color-success {
background-color: var(--color-success);
}
.bg-color-warning {
background-color: var(--color-warning);
}
.bg-color-error {
background-color: var(--color-error);
}
.bg-background-primary {
background-color: var(--background-primary);
}
.bg-background-secondary {
background-color: var(--background-secondary);
}
/* Background CSS Variable Utilities */
.bg-bg-primary {
background-color: var(--bg-primary);
}
.bg-bg-secondary {
background-color: var(--bg-secondary);
}
.bg-bg-tertiary {
background-color: var(--bg-tertiary);
}
.bg-bg-quaternary {
background-color: var(--bg-quaternary);
}
/* Text Color Utilities */
.text-text-primary {
color: var(--text-primary);
}
.text-text-secondary {
color: var(--text-secondary);
}
.text-text-tertiary {
color: var(--text-tertiary);
}
.text-color-primary {
color: var(--color-primary);
}
.text-color-primary-light {
color: var(--color-primary-light);
}
.text-color-primary-dark {
color: var(--color-primary-dark);
}
.text-color-success {
color: var(--color-success);
}
.text-color-warning {
color: var(--color-warning);
}
.text-color-error {
color: var(--color-error);
}
.text-color-info {
color: var(--color-info);
}
.text-color-accent {
color: var(--color-accent);
}
/* Additional background color utilities */
.bg-color-info {
background-color: var(--color-info);
}
.bg-color-accent {
background-color: var(--color-accent);
}
.bg-color-secondary {
background-color: var(--color-secondary);
}
.bg-color-secondary-light {
background-color: var(--color-secondary-light);
}
.bg-color-secondary-dark {
background-color: var(--color-secondary-dark);
}
/* Border color utilities */
.border-color-success {
border-color: var(--color-success);
}
.border-color-warning {
border-color: var(--color-warning);
}
.border-color-error {
border-color: var(--color-error);
}
.border-color-info {
border-color: var(--color-info);
}
.border-color-secondary {
border-color: var(--color-secondary);
}
.border-color-accent {
border-color: var(--color-accent);
}
/* Border Color Utilities */
.border-color-primary {
border-color: var(--color-primary);
}
.border-border-primary {
border-color: var(--border-primary);
}
.border-border-secondary {
border-color: var(--border-secondary);
}
/* Ring Color Utilities */
.ring-color-primary {
--tw-ring-color: var(--color-primary);
}
.ring-color-primary\/20 {
--tw-ring-color: rgba(215, 119, 6, 0.2); /* Fallback for older browsers */
}
/* Additional utility classes matching the component usage */
.bg-color-success\/10 {
background-color: rgba(5, 150, 105, 0.1);
}
.border-color-error\/20 {
border-color: rgba(220, 38, 38, 0.2);
}
.bg-color-error\/10 {
background-color: rgba(220, 38, 38, 0.1);
}
/* Enhanced Bakery-Specific Utility Classes */
.bg-color-sourdough {
background-color: var(--color-sourdough);
}
.bg-color-whole-wheat {
background-color: var(--color-whole-wheat);
}
.bg-color-brioche {
background-color: var(--color-brioche);
}
.text-color-sourdough {
color: var(--color-sourdough);
}
.text-color-croissant {
color: var(--color-croissant);
}
.text-color-danish {
color: var(--color-danish);
}
/* Enhanced Chart Color Utilities */
.bg-chart-primary {
background-color: var(--chart-primary);
}
.bg-chart-secondary {
background-color: var(--chart-secondary);
}
.bg-chart-tertiary {
background-color: var(--chart-tertiary);
}
.text-chart-primary {
color: var(--chart-primary);
}
.text-chart-secondary {
color: var(--chart-secondary);
}
.text-chart-tertiary {
color: var(--chart-tertiary);
}
/* Gradient Background Utilities */
.bg-gradient-primary {
background: var(--gradient-primary);
}
.bg-gradient-secondary {
background: var(--gradient-secondary);
}
.bg-gradient-warm {
background: var(--gradient-warm);
}
.bg-gradient-cool {
background: var(--gradient-cool);
}
/* Map the different variable names used in the app */
:root {
--background-primary: var(--bg-primary, #ffffff);
--background-secondary: var(--bg-secondary, #f8fafc);
}
/* Button Components */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--radius-md);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
line-height: 1;
text-decoration: none;
transition: all var(--transition-fast);
cursor: pointer;
border: 1px solid transparent;
min-height: 2.5rem;
white-space: nowrap;
}
.btn:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
/* Button Variants */
.btn-primary {
background-color: var(--color-primary);
color: var(--text-inverse);
border-color: var(--color-primary);
}
.btn-primary:hover:not(:disabled) {
background-color: var(--color-primary-dark);
border-color: var(--color-primary-dark);
}
.btn-secondary {
background-color: var(--color-secondary);
color: var(--text-inverse);
border-color: var(--color-secondary);
}
.btn-secondary:hover:not(:disabled) {
background-color: var(--color-secondary-dark);
border-color: var(--color-secondary-dark);
}
.btn-outline {
background-color: transparent;
color: var(--color-primary);
border-color: var(--color-primary);
}
.btn-outline:hover:not(:disabled) {
background-color: var(--color-primary);
color: var(--text-inverse);
}
.btn-ghost {
background-color: transparent;
color: var(--text-secondary);
border-color: transparent;
}
.btn-ghost:hover:not(:disabled) {
background-color: var(--bg-tertiary);
color: var(--text-primary);
}
.btn-success {
background-color: var(--color-success);
color: var(--text-inverse);
border-color: var(--color-success);
}
.btn-success:hover:not(:disabled) {
background-color: var(--color-success-dark);
border-color: var(--color-success-dark);
}
.btn-error {
background-color: var(--color-error);
color: var(--text-inverse);
border-color: var(--color-error);
}
.btn-error:hover:not(:disabled) {
background-color: var(--color-error-dark);
border-color: var(--color-error-dark);
}
.btn-warning {
background-color: var(--color-warning);
color: var(--text-inverse);
border-color: var(--color-warning);
}
.btn-warning:hover:not(:disabled) {
background-color: var(--color-warning-dark);
border-color: var(--color-warning-dark);
}
/* Button Sizes */
.btn-sm {
padding: var(--spacing-xs) var(--spacing-sm);
font-size: var(--font-size-xs);
min-height: 2rem;
}
.btn-lg {
padding: var(--spacing-md) var(--spacing-xl);
font-size: var(--font-size-base);
min-height: 3rem;
}
.btn-full {
width: 100%;
}
.btn-icon {
padding: var(--spacing-sm);
min-width: 2.5rem;
min-height: 2.5rem;
}
/* Card Components */
.card {
background-color: var(--bg-primary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
overflow: hidden;
}
.card-header {
padding: var(--spacing-lg);
border-bottom: 1px solid var(--border-primary);
background-color: var(--bg-secondary);
}
.card-body {
padding: var(--spacing-lg);
}
.card-footer {
padding: var(--spacing-lg);
border-top: 1px solid var(--border-primary);
background-color: var(--bg-secondary);
}
.card-compact .card-header,
.card-compact .card-body,
.card-compact .card-footer {
padding: var(--spacing-md);
}
/* Badge Components */
.badge {
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
padding: 0.25rem 0.5rem;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
border-radius: var(--radius-full);
line-height: 1;
}
.badge-primary {
background-color: rgb(217 119 6 / 0.1);
color: var(--color-primary-dark);
}
.badge-secondary {
background-color: rgb(15 118 110 / 0.1);
color: var(--color-secondary-dark);
}
.badge-success {
background-color: rgb(5 150 105 / 0.1);
color: var(--color-success-dark);
}
.badge-error {
background-color: rgb(220 38 38 / 0.1);
color: var(--color-error-dark);
}
.badge-warning {
background-color: rgb(217 119 6 / 0.1);
color: var(--color-warning-dark);
}
.badge-info {
background-color: rgb(37 99 235 / 0.1);
color: var(--color-info-dark);
}
.badge-neutral {
background-color: var(--bg-tertiary);
color: var(--text-secondary);
}
/* Alert Components */
.alert {
padding: var(--spacing-md);
border-radius: var(--radius-md);
border: 1px solid transparent;
margin-bottom: var(--spacing-md);
}
.alert-success {
background-color: rgb(5 150 105 / 0.05);
border-color: rgb(5 150 105 / 0.2);
color: var(--color-success-dark);
}
.alert-error {
background-color: rgb(220 38 38 / 0.05);
border-color: rgb(220 38 38 / 0.2);
color: var(--color-error-dark);
}
.alert-warning {
background-color: rgb(217 119 6 / 0.05);
border-color: rgb(217 119 6 / 0.2);
color: var(--color-warning-dark);
}
.alert-info {
background-color: rgb(37 99 235 / 0.05);
border-color: rgb(37 99 235 / 0.2);
color: var(--color-info-dark);
}
/* Loading Components */
.spinner {
display: inline-block;
width: 1rem;
height: 1rem;
border: 2px solid var(--border-secondary);
border-radius: 50%;
border-top: 2px solid var(--color-primary);
animation: spin 1s linear infinite;
}
.spinner-sm {
width: 0.75rem;
height: 0.75rem;
border-width: 1.5px;
}
.spinner-lg {
width: 1.5rem;
height: 1.5rem;
border-width: 3px;
}
.skeleton {
background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-quaternary) 50%, var(--bg-tertiary) 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
border-radius: var(--radius-md);
}
.skeleton-text {
height: 1rem;
margin-bottom: var(--spacing-xs);
}
.skeleton-text:last-child {
width: 60%;
}
.skeleton-avatar {
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
}
/* Form Components */
.form-group {
margin-bottom: var(--spacing-lg);
}
.form-label {
display: block;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--text-primary);
margin-bottom: var(--spacing-xs);
}
.form-label-required::after {
content: " *";
color: var(--color-error);
}
.form-control {
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border-secondary);
border-radius: var(--radius-md);
background-color: var(--bg-primary);
color: var(--text-primary);
font-size: var(--font-size-sm);
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.form-control:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgb(217 119 6 / 0.1);
}
.form-control:disabled {
background-color: var(--bg-quaternary);
color: var(--text-tertiary);
cursor: not-allowed;
}
.form-control.error {
border-color: var(--color-error);
}
.form-control.error:focus {
box-shadow: 0 0 0 3px rgb(220 38 38 / 0.1);
}
.form-error {
font-size: var(--font-size-xs);
color: var(--color-error);
margin-top: var(--spacing-xs);
}
.form-help {
font-size: var(--font-size-xs);
color: var(--text-tertiary);
margin-top: var(--spacing-xs);
}
/* Table Components */
.table-container {
overflow-x: auto;
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
background-color: var(--bg-primary);
}
.table {
width: 100%;
border-collapse: collapse;
font-size: var(--font-size-sm);
}
.table th {
background-color: var(--bg-secondary);
color: var(--text-secondary);
font-weight: var(--font-weight-semibold);
text-align: left;
padding: var(--spacing-md);
border-bottom: 1px solid var(--border-primary);
}
.table td {
padding: var(--spacing-md);
border-bottom: 1px solid var(--border-primary);
color: var(--text-primary);
}
.table tr:last-child td {
border-bottom: none;
}
.table tr:hover {
background-color: var(--bg-secondary);
}
.table-striped tbody tr:nth-child(odd) {
background-color: var(--bg-secondary);
}
.table-compact th,
.table-compact td {
padding: var(--spacing-sm);
}
/* Modal Components */
.modal-backdrop {
position: fixed;
inset: 0;
background-color: rgb(0 0 0 / 0.5);
z-index: var(--z-modal-backdrop);
display: flex;
align-items: center;
justify-content: center;
padding: var(--spacing-md);
}
.modal {
background-color: var(--bg-primary);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-xl);
max-width: 32rem;
width: 100%;
max-height: 90vh;
overflow: hidden;
z-index: var(--z-modal);
}
.modal-header {
padding: var(--spacing-lg);
border-bottom: 1px solid var(--border-primary);
display: flex;
align-items: center;
justify-content: space-between;
}
.modal-title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
margin: 0;
}
.modal-close {
padding: var(--spacing-xs);
border: none;
background: none;
color: var(--text-tertiary);
cursor: pointer;
border-radius: var(--radius-sm);
transition: all var(--transition-fast);
}
.modal-close:hover {
color: var(--text-primary);
background-color: var(--bg-tertiary);
}
.modal-body {
padding: var(--spacing-lg);
overflow-y: auto;
}
.modal-footer {
padding: var(--spacing-lg);
border-top: 1px solid var(--border-primary);
display: flex;
gap: var(--spacing-sm);
justify-content: flex-end;
}
/* Toast Components */
.toast-container {
position: fixed;
z-index: var(--z-toast);
pointer-events: none;
padding: var(--spacing-md);
}
.toast-container.top-left {
top: 0;
left: 0;
}
.toast-container.top-center {
top: 0;
left: 50%;
transform: translateX(-50%);
}
.toast-container.top-right {
top: 0;
right: 0;
}
.toast-container.bottom-left {
bottom: 0;
left: 0;
}
.toast-container.bottom-center {
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
.toast-container.bottom-right {
bottom: 0;
right: 0;
}
.toast {
background-color: var(--bg-primary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
padding: var(--spacing-md);
margin-bottom: var(--spacing-sm);
pointer-events: auto;
min-width: 20rem;
max-width: 24rem;
display: flex;
align-items: flex-start;
gap: var(--spacing-sm);
}
.toast-success {
border-left: 4px solid var(--color-success);
}
.toast-error {
border-left: 4px solid var(--color-error);
}
.toast-warning {
border-left: 4px solid var(--color-warning);
}
.toast-info {
border-left: 4px solid var(--color-info);
}
.toast-content {
flex: 1;
}
.toast-title {
font-weight: var(--font-weight-medium);
font-size: var(--font-size-sm);
color: var(--text-primary);
margin-bottom: var(--spacing-xs);
}
.toast-message {
font-size: var(--font-size-sm);
color: var(--text-secondary);
line-height: var(--line-height-normal);
}
.toast-close {
padding: var(--spacing-xs);
border: none;
background: none;
color: var(--text-tertiary);
cursor: pointer;
border-radius: var(--radius-sm);
flex-shrink: 0;
}
.toast-close:hover {
color: var(--text-primary);
background-color: var(--bg-tertiary);
}
/* Dropdown Components */
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
min-width: 10rem;
background-color: var(--bg-primary);
border: 1px solid var(--border-primary);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
z-index: var(--z-dropdown);
padding: var(--spacing-xs);
margin-top: var(--spacing-xs);
}
.dropdown-item {
display: block;
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
border: none;
background: none;
color: var(--text-primary);
text-align: left;
border-radius: var(--radius-sm);
cursor: pointer;
transition: background-color var(--transition-fast);
text-decoration: none;
font-size: var(--font-size-sm);
}
.dropdown-item:hover {
background-color: var(--bg-tertiary);
}
.dropdown-item:focus {
outline: none;
background-color: var(--bg-tertiary);
}
.dropdown-divider {
height: 1px;
background-color: var(--border-primary);
margin: var(--spacing-xs) 0;
}
/* Tab Components */
.tabs {
border-bottom: 1px solid var(--border-primary);
margin-bottom: var(--spacing-lg);
}
.tab-list {
display: flex;
gap: var(--spacing-md);
}
.tab-item {
padding: var(--spacing-sm) var(--spacing-md);
border: none;
background: none;
color: var(--text-tertiary);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all var(--transition-fast);
}
.tab-item:hover {
color: var(--text-primary);
}
.tab-item.active {
color: var(--color-primary);
border-bottom-color: var(--color-primary);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
/* Progress Components */
.progress {
width: 100%;
height: 0.5rem;
background-color: var(--bg-tertiary);
border-radius: var(--radius-full);
overflow: hidden;
}
.progress-bar {
height: 100%;
background-color: var(--color-primary);
border-radius: var(--radius-full);
transition: width var(--transition-normal);
}
.progress-bar.success {
background-color: var(--color-success);
}
.progress-bar.error {
background-color: var(--color-error);
}
.progress-bar.warning {
background-color: var(--color-warning);
}
/* Pagination Components */
.pagination {
display: flex;
align-items: center;
gap: var(--spacing-xs);
justify-content: center;
}
.pagination-item {
padding: var(--spacing-sm);
border: 1px solid var(--border-secondary);
background-color: var(--bg-primary);
color: var(--text-primary);
text-decoration: none;
border-radius: var(--radius-md);
min-width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-sm);
transition: all var(--transition-fast);
}
.pagination-item:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
.pagination-item.active {
background-color: var(--color-primary);
border-color: var(--color-primary);
color: var(--text-inverse);
}
.pagination-item:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}

View File

@@ -1,96 +1,425 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
/**
* Global styles for the bakery management application
*/
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700&display=swap');
/* Tailwind CSS directives */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Base styles */
* {
/* CSS Reset and Base Styles */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Root Variables */
:root {
/* Colors - Light Theme */
--color-primary: #d97706;
--color-primary-light: #f59e0b;
--color-primary-dark: #b45309;
--color-secondary: #0f766e;
--color-secondary-light: #14b8a6;
--color-secondary-dark: #0d5d56;
--color-accent: #dc2626;
--color-accent-light: #ef4444;
--color-accent-dark: #b91c1c;
--color-success: #059669;
--color-success-light: #10b981;
--color-success-dark: #047857;
--color-warning: #d97706;
--color-warning-light: #f59e0b;
--color-warning-dark: #b45309;
--color-error: #dc2626;
--color-error-light: #ef4444;
--color-error-dark: #b91c1c;
--color-info: #2563eb;
--color-info-light: #3b82f6;
--color-info-dark: #1d4ed8;
/* Background Colors - Default fallbacks, overridden by theme files */
--bg-primary: #ffffff;
--bg-secondary: #f8fafc;
--bg-tertiary: #f1f5f9;
--bg-quaternary: #e2e8f0;
/* Text Colors - Default fallbacks, overridden by theme files */
--text-primary: #0f172a;
--text-secondary: #475569;
--text-tertiary: #64748b;
--text-inverse: #ffffff;
/* Border Colors - Default fallbacks, overridden by theme files */
--border-primary: #e2e8f0;
--border-secondary: #cbd5e1;
--border-tertiary: #94a3b8;
/* Shadow Colors */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
/* Typography */
--font-family-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
--font-family-mono: 'JetBrains Mono', 'Fira Code', 'Monaco', 'Consolas', monospace;
--font-size-xs: 0.75rem; /* 12px */
--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 1rem; /* 16px */
--font-size-lg: 1.125rem; /* 18px */
--font-size-xl: 1.25rem; /* 20px */
--font-size-2xl: 1.5rem; /* 24px */
--font-size-3xl: 1.875rem; /* 30px */
--font-size-4xl: 2.25rem; /* 36px */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
/* Spacing */
--spacing-xs: 0.25rem; /* 4px */
--spacing-sm: 0.5rem; /* 8px */
--spacing-md: 1rem; /* 16px */
--spacing-lg: 1.5rem; /* 24px */
--spacing-xl: 2rem; /* 32px */
--spacing-2xl: 3rem; /* 48px */
--spacing-3xl: 4rem; /* 64px */
/* Border Radius */
--radius-sm: 0.25rem; /* 4px */
--radius-md: 0.375rem; /* 6px */
--radius-lg: 0.5rem; /* 8px */
--radius-xl: 0.75rem; /* 12px */
--radius-2xl: 1rem; /* 16px */
--radius-full: 9999px;
/* Z-Index */
--z-dropdown: 1000;
--z-sticky: 1020;
--z-fixed: 1030;
--z-modal-backdrop: 1040;
--z-modal: 1050;
--z-popover: 1060;
--z-tooltip: 1070;
--z-toast: 1080;
/* Transition */
--transition-fast: 150ms ease-in-out;
--transition-normal: 300ms ease-in-out;
--transition-slow: 500ms ease-in-out;
/* Layout */
--container-max-width: 1280px;
--sidebar-width: 280px;
--header-height: 64px;
--footer-height: 56px;
}
/* Base HTML Elements */
html {
font-size: 16px;
line-height: 1.5;
-webkit-text-size-adjust: 100%;
-moz-tab-size: 4;
tab-size: 4;
font-feature-settings: normal;
font-variation-settings: normal;
}
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
line-height: 1.5;
font-family: var(--font-family-sans);
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: var(--line-height-normal);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
/* Custom scrollbar */
/* Typography */
h1, h2, h3, h4, h5, h6 {
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
margin-bottom: var(--spacing-md);
}
h1 { font-size: var(--font-size-4xl); }
h2 { font-size: var(--font-size-3xl); }
h3 { font-size: var(--font-size-2xl); }
h4 { font-size: var(--font-size-xl); }
h5 { font-size: var(--font-size-lg); }
h6 { font-size: var(--font-size-base); }
p {
margin-bottom: var(--spacing-md);
line-height: var(--line-height-relaxed);
}
a {
color: var(--color-primary);
text-decoration: none;
transition: color var(--transition-fast);
}
a:hover {
color: var(--color-primary-dark);
text-decoration: underline;
}
/* Lists */
ul, ol {
margin-bottom: var(--spacing-md);
padding-left: var(--spacing-lg);
}
li {
margin-bottom: var(--spacing-xs);
}
/* Code */
code {
font-family: var(--font-family-mono);
font-size: 0.875em;
background-color: var(--bg-tertiary);
padding: 0.125rem 0.25rem;
border-radius: var(--radius-sm);
color: var(--color-accent);
}
pre {
font-family: var(--font-family-mono);
background-color: var(--bg-tertiary);
padding: var(--spacing-md);
border-radius: var(--radius-lg);
overflow-x: auto;
margin-bottom: var(--spacing-md);
}
pre code {
background: none;
padding: 0;
color: inherit;
}
/* Tables */
table {
width: 100%;
border-collapse: collapse;
margin-bottom: var(--spacing-md);
}
th, td {
padding: var(--spacing-sm) var(--spacing-md);
text-align: left;
border-bottom: 1px solid var(--border-primary);
}
th {
font-weight: var(--font-weight-semibold);
background-color: var(--bg-secondary);
color: var(--text-secondary);
}
/* Form Elements */
input,
textarea,
select,
button {
font-family: inherit;
font-size: inherit;
line-height: inherit;
color: inherit;
}
input,
textarea,
select {
background-color: var(--bg-primary);
border: 1px solid var(--border-secondary);
border-radius: var(--radius-md);
padding: var(--spacing-sm) var(--spacing-md);
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
input:focus,
textarea:focus,
select:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgb(217 119 6 / 0.1);
}
input:disabled,
textarea:disabled,
select:disabled {
background-color: var(--bg-quaternary);
color: var(--text-tertiary);
cursor: not-allowed;
}
button {
cursor: pointer;
background: none;
border: none;
padding: 0;
font: inherit;
color: inherit;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all var(--transition-fast);
}
button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
/* Images */
img {
max-width: 100%;
height: auto;
display: block;
}
/* Utility Classes */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.container {
width: 100%;
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 var(--spacing-md);
}
.flex {
display: flex;
}
.inline-flex {
display: inline-flex;
}
.grid {
display: grid;
}
.hidden {
display: none;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
.sticky {
position: sticky;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-auto {
overflow: auto;
}
.text-center {
text-align: center;
}
.text-right {
text-align: right;
}
.text-left {
text-align: left;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pointer-events-none {
pointer-events: none;
}
/* Focus Management */
.focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 6px;
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f1f5f9;
background: var(--bg-secondary);
border-radius: var(--radius-full);
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
background: var(--border-tertiary);
border-radius: var(--radius-full);
transition: background-color var(--transition-fast);
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
background: var(--text-tertiary);
}
/* Focus styles */
.focus-ring:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.1);
border-color: #f97316;
}
/* Animation classes */
.animate-fade-in {
animation: fadeIn 0.5s ease-in-out;
}
.animate-slide-up {
animation: slideUp 0.3s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Custom components */
.bakery-card {
@apply bg-white rounded-xl shadow-soft p-6 hover:shadow-medium transition-all duration-200;
}
.confidence-high {
@apply bg-green-100 text-green-800 border-green-200;
}
.confidence-medium {
@apply bg-yellow-100 text-yellow-800 border-yellow-200;
}
.confidence-low {
@apply bg-red-100 text-red-800 border-red-200;
}
/* Mobile-first responsive design helpers */
@media (max-width: 640px) {
.mobile-padding {
padding-left: 1rem;
padding-right: 1rem;
/* Print Styles */
@media print {
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
.mobile-text-sm {
font-size: 0.875rem;
body {
font-size: 12pt;
line-height: 1.4;
}
.no-print {
display: none !important;
}
}

View File

@@ -0,0 +1,263 @@
/**
* Dark theme variables for the bakery management application
* Generated from centralized color configuration
*/
.dark,
[data-theme="dark"] {
/* === SEMANTIC COLORS === */
/* Primary Colors - Warm Orange (Bakery Brand) - Adjusted for dark theme */
--color-primary-50: #fffbeb;
--color-primary-100: #fef3c7;
--color-primary-200: #fde68a;
--color-primary-300: #fcd34d;
--color-primary-400: #fbbf24;
--color-primary-500: #f59e0b;
--color-primary-600: #d97706;
--color-primary-700: #b45309;
--color-primary-800: #92400e;
--color-primary-900: #78350f;
--color-primary: #f59e0b; /* Brighter for dark theme */
--color-primary-light: #fbbf24;
--color-primary-dark: #d97706;
/* Secondary Colors - Professional Sage Green - Adjusted for dark theme */
--color-secondary-50: #f0fdf4;
--color-secondary-100: #dcfce7;
--color-secondary-200: #bbf7d0;
--color-secondary-300: #86efac;
--color-secondary-400: #4ade80;
--color-secondary-500: #22c55e;
--color-secondary-600: #16a34a;
--color-secondary-700: #15803d;
--color-secondary-800: #166534;
--color-secondary-900: #14532d;
--color-secondary: #22c55e; /* Brighter for dark theme */
--color-secondary-light: #4ade80;
--color-secondary-dark: #16a34a;
/* Success Colors */
--color-success-50: #ecfdf5;
--color-success-100: #d1fae5;
--color-success-200: #a7f3d0;
--color-success-300: #6ee7b7;
--color-success-400: #34d399;
--color-success-500: #10b981;
--color-success-600: #059669;
--color-success-700: #047857;
--color-success-800: #065f46;
--color-success-900: #064e3b;
--color-success: #22c55e; /* Brighter for dark theme */
--color-success-light: #4ade80;
--color-success-dark: #16a34a;
/* Warning Colors */
--color-warning-50: #fffbeb;
--color-warning-100: #fef3c7;
--color-warning-200: #fde68a;
--color-warning-300: #fcd34d;
--color-warning-400: #fbbf24;
--color-warning-500: #f59e0b;
--color-warning-600: #ea580c;
--color-warning-700: #c2410c;
--color-warning-800: #9a3412;
--color-warning-900: #7c2d12;
--color-warning: #fb923c; /* Brighter for dark theme */
--color-warning-light: #fdba74;
--color-warning-dark: #ea580c;
/* Error Colors */
--color-error-50: #fef2f2;
--color-error-100: #fee2e2;
--color-error-200: #fecaca;
--color-error-300: #fca5a5;
--color-error-400: #f87171;
--color-error-500: #ef4444;
--color-error-600: #dc2626;
--color-error-700: #b91c1c;
--color-error-800: #991b1b;
--color-error-900: #7f1d1d;
--color-error: #ef4444; /* Brighter for dark theme */
--color-error-light: #f87171;
--color-error-dark: #dc2626;
/* Info Colors */
--color-info-50: #eff6ff;
--color-info-100: #dbeafe;
--color-info-200: #bfdbfe;
--color-info-300: #93c5fd;
--color-info-400: #60a5fa;
--color-info-500: #3b82f6;
--color-info-600: #0284c7;
--color-info-700: #0369a1;
--color-info-800: #075985;
--color-info-900: #0c4a6e;
--color-info: #0ea5e9; /* Brighter for dark theme */
--color-info-light: #0ea5e9;
--color-info-dark: #0369a1;
/* === THEME-SPECIFIC COLORS === */
/* Background Colors */
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-tertiary: #334155;
--bg-quaternary: #475569;
--bg-overlay: rgba(0, 0, 0, 0.8);
--bg-modal-backdrop: rgba(0, 0, 0, 0.75);
/* Text Colors */
--text-primary: #f8fafc;
--text-secondary: #cbd5e1;
--text-tertiary: #94a3b8;
--text-quaternary: #64748b;
--text-inverse: #0f172a;
--text-muted: #64748b;
--text-disabled: #475569;
/* Border Colors */
--border-primary: #334155;
--border-secondary: #475569;
--border-tertiary: #64748b;
--border-focus: #f59e0b;
--border-error: #ef4444;
--border-success: #22c55e;
/* Surface Colors */
--surface-primary: #1e293b;
--surface-secondary: #334155;
--surface-tertiary: #475569;
--surface-raised: #1e293b;
--surface-overlay: rgba(15, 23, 42, 0.95);
/* Input Colors */
--input-bg: #1e293b;
--input-border: #475569;
--input-border-focus: #f59e0b;
--input-border-error: #ef4444;
--input-placeholder: #64748b;
/* Navigation Colors */
--nav-bg: #1e293b;
--nav-border: #334155;
--nav-item-hover: #334155;
--nav-item-active: rgba(245, 158, 11, 0.2);
/* Card Colors */
--card-bg: #1e293b;
--card-border: #334155;
--card-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
/* === BAKERY COLORS - Adjusted for dark theme === */
--color-sourdough: #d4a574;
--color-wholeWheat: #a67c52;
--color-brioche: #f4e4bc;
--color-rye: #8b6f47;
--color-croissant: #f5d76e;
--color-danish: #e8b4cb;
--color-espresso: #8b7355; /* Lighter for dark mode */
--color-latte: #c8a882;
--color-bread: #a0845c; /* Adjusted for dark backgrounds */
--color-wheat: #c4a876;
--color-flour: #d4c4b0;
--color-butter: #e6d8a3;
--color-chocolate: #6b3410;
--color-vanilla: #d4c8a6;
--color-strawberry: #d1477a;
--color-mint: #7bc97b;
--color-caramel: #a85a1a;
--color-cream: #ede6a3;
/* === CHART COLORS - Dark Mode Optimized === */
--chart-primary: #fbbf24; /* Lighter orange for dark backgrounds */
--chart-secondary: #0ea5e9; /* Bright blue */
--chart-tertiary: #4ade80; /* Success green */
--chart-quaternary: #f87171; /* Error red */
--chart-quinary: #a78bfa; /* Purple accent */
--chart-senary: #22d3ee; /* Cyan accent */
--chart-septenary: #fb923c; /* Warning orange */
--chart-octonary: #34d399; /* Deep emerald */
/* === SHADOWS - Enhanced for dark theme === */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 8px 10px -6px rgba(0, 0, 0, 0.6);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.8);
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.3);
/* === INTERACTIVE STATES === */
--hover-opacity: 0.8;
--active-opacity: 0.9;
--disabled-opacity: 0.5;
}
/* Dark theme specific overrides */
.dark {
color-scheme: dark;
}
/* Component-specific dark theme styles */
.dark .bg-pattern {
background-image:
radial-gradient(circle at 25% 25%, rgba(245, 158, 11, 0.05) 0%, transparent 50%),
radial-gradient(circle at 75% 75%, rgba(34, 197, 94, 0.05) 0%, transparent 50%);
}
.dark .glass-effect {
background: rgba(30, 41, 59, 0.8);
backdrop-filter: blur(10px);
border: 1px solid rgba(51, 65, 85, 0.3);
}
.dark .focus-ring:focus {
box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.3);
}
.dark .focus-ring:focus-visible {
box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.4);
}
/* Form elements in dark theme */
.dark input[type="checkbox"]:checked {
background-color: var(--color-primary);
border-color: var(--color-primary);
}
.dark input[type="radio"]:checked {
background-color: var(--color-primary);
border-color: var(--color-primary);
}
/* Scrollbar in dark theme */
.dark ::-webkit-scrollbar-track {
background-color: #334155;
}
.dark ::-webkit-scrollbar-thumb {
background-color: #64748b;
}
.dark ::-webkit-scrollbar-thumb:hover {
background-color: #94a3b8;
}
/* Interactive states */
.dark .glow-effect {
box-shadow: 0 0 20px rgba(245, 158, 11, 0.3);
}
.dark .border-glow {
border: 1px solid rgba(245, 158, 11, 0.5);
box-shadow: 0 0 10px rgba(245, 158, 11, 0.2);
}
/* Dark theme image adjustments */
.dark img {
filter: brightness(0.9) contrast(1.1);
}
.dark .logo {
filter: invert(1) brightness(0.9);
}

View File

@@ -0,0 +1,244 @@
/**
* Light theme variables for the bakery management application
* Generated from centralized color configuration
*/
.light,
[data-theme="light"] {
/* === SEMANTIC COLORS === */
/* Primary Colors - Warm Orange (Bakery Brand) */
--color-primary-50: #fffbeb;
--color-primary-100: #fef3c7;
--color-primary-200: #fde68a;
--color-primary-300: #fcd34d;
--color-primary-400: #fbbf24;
--color-primary-500: #f59e0b;
--color-primary-600: #d97706;
--color-primary-700: #b45309;
--color-primary-800: #92400e;
--color-primary-900: #78350f;
--color-primary: #d97706;
--color-primary-light: #f59e0b;
--color-primary-dark: #b45309;
/* Secondary Colors - Professional Sage Green */
--color-secondary-50: #f0fdf4;
--color-secondary-100: #dcfce7;
--color-secondary-200: #bbf7d0;
--color-secondary-300: #86efac;
--color-secondary-400: #4ade80;
--color-secondary-500: #22c55e;
--color-secondary-600: #16a34a;
--color-secondary-700: #15803d;
--color-secondary-800: #166534;
--color-secondary-900: #14532d;
--color-secondary: #16a34a;
--color-secondary-light: #22c55e;
--color-secondary-dark: #15803d;
/* Success Colors */
--color-success-50: #ecfdf5;
--color-success-100: #d1fae5;
--color-success-200: #a7f3d0;
--color-success-300: #6ee7b7;
--color-success-400: #34d399;
--color-success-500: #10b981;
--color-success-600: #059669;
--color-success-700: #047857;
--color-success-800: #065f46;
--color-success-900: #064e3b;
--color-success: #059669;
--color-success-light: #10b981;
--color-success-dark: #047857;
/* Warning Colors */
--color-warning-50: #fffbeb;
--color-warning-100: #fef3c7;
--color-warning-200: #fde68a;
--color-warning-300: #fcd34d;
--color-warning-400: #fbbf24;
--color-warning-500: #f59e0b;
--color-warning-600: #ea580c;
--color-warning-700: #c2410c;
--color-warning-800: #9a3412;
--color-warning-900: #7c2d12;
--color-warning: #ea580c;
--color-warning-light: #f59e0b;
--color-warning-dark: #c2410c;
/* Error Colors */
--color-error-50: #fef2f2;
--color-error-100: #fee2e2;
--color-error-200: #fecaca;
--color-error-300: #fca5a5;
--color-error-400: #f87171;
--color-error-500: #ef4444;
--color-error-600: #dc2626;
--color-error-700: #b91c1c;
--color-error-800: #991b1b;
--color-error-900: #7f1d1d;
--color-error: #dc2626;
--color-error-light: #ef4444;
--color-error-dark: #b91c1c;
/* Info Colors */
--color-info-50: #eff6ff;
--color-info-100: #dbeafe;
--color-info-200: #bfdbfe;
--color-info-300: #93c5fd;
--color-info-400: #60a5fa;
--color-info-500: #3b82f6;
--color-info-600: #0284c7;
--color-info-700: #0369a1;
--color-info-800: #075985;
--color-info-900: #0c4a6e;
--color-info: #0284c7;
--color-info-light: #3b82f6;
--color-info-dark: #0369a1;
/* === THEME-SPECIFIC COLORS === */
/* Background Colors */
--bg-primary: #ffffff;
--bg-secondary: #f8fafc;
--bg-tertiary: #f1f5f9;
--bg-quaternary: #e2e8f0;
--bg-overlay: rgba(255, 255, 255, 0.8);
--bg-modal-backdrop: rgba(0, 0, 0, 0.5);
/* Text Colors */
--text-primary: #0f172a;
--text-secondary: #475569;
--text-tertiary: #64748b;
--text-quaternary: #94a3b8;
--text-inverse: #ffffff;
--text-muted: #64748b;
--text-disabled: #cbd5e1;
/* Border Colors */
--border-primary: #e2e8f0;
--border-secondary: #cbd5e1;
--border-tertiary: #94a3b8;
--border-focus: #d97706;
--border-error: #dc2626;
--border-success: #059669;
/* Surface Colors */
--surface-primary: #ffffff;
--surface-secondary: #f8fafc;
--surface-tertiary: #f1f5f9;
--surface-raised: #ffffff;
--surface-overlay: rgba(255, 255, 255, 0.95);
/* Input Colors */
--input-bg: #ffffff;
--input-border: #d1d5db;
--input-border-focus: #d97706;
--input-border-error: #dc2626;
--input-placeholder: #9ca3af;
/* Navigation Colors */
--nav-bg: #ffffff;
--nav-border: #e5e7eb;
--nav-item-hover: #f9fafb;
--nav-item-active: #fef3c7;
/* Card Colors */
--card-bg: #ffffff;
--card-border: #e5e7eb;
--card-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
/* === BAKERY COLORS === */
--color-sourdough: #d4a574;
--color-wholeWheat: #a67c52;
--color-brioche: #f4e4bc;
--color-rye: #8b6f47;
--color-croissant: #f5d76e;
--color-danish: #e8b4cb;
--color-espresso: #3c2415;
--color-latte: #c8a882;
--color-bread: #deb887;
--color-wheat: #f5deb3;
--color-flour: #faf0e6;
--color-butter: #fff8dc;
--color-chocolate: #8b4513;
--color-vanilla: #f5f5dc;
--color-strawberry: #ff69b4;
--color-mint: #98fb98;
--color-caramel: #d2691e;
--color-cream: #fffdd0;
/* === CHART COLORS === */
--chart-primary: #d97706;
--chart-secondary: #0369a1;
--chart-tertiary: #16a34a;
--chart-quaternary: #dc2626;
--chart-quinary: #7c3aed;
--chart-senary: #0891b2;
--chart-septenary: #ea580c;
--chart-octonary: #059669;
/* === SHADOWS === */
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
--shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
--shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);
/* === INTERACTIVE STATES === */
--hover-opacity: 0.8;
--active-opacity: 0.9;
--disabled-opacity: 0.5;
}
/* Light theme specific overrides */
.light {
color-scheme: light;
}
/* Component-specific light theme styles */
.light .bg-pattern {
background-image:
radial-gradient(circle at 25% 25%, rgba(217, 119, 6, 0.03) 0%, transparent 50%),
radial-gradient(circle at 75% 75%, rgba(22, 163, 74, 0.03) 0%, transparent 50%);
}
.light .glass-effect {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.light .focus-ring:focus {
box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.2);
}
.light .focus-ring:focus-visible {
box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.3);
}
/* Form elements in light theme */
.light input[type="checkbox"]:checked {
background-color: var(--color-primary);
border-color: var(--color-primary);
}
.light input[type="radio"]:checked {
background-color: var(--color-primary);
border-color: var(--color-primary);
}
/* Scrollbar in light theme */
.light ::-webkit-scrollbar-track {
background-color: #f1f5f9;
}
.light ::-webkit-scrollbar-thumb {
background-color: #cbd5e1;
}
.light ::-webkit-scrollbar-thumb:hover {
background-color: #94a3b8;
}