diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index e4ff6b0..e3dd25c 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -1,3 +1,5 @@ +import colors from 'tailwindcss/colors'; + /** @type {import('tailwindcss').Config} */ export default { content: [ @@ -27,175 +29,167 @@ export default { "2xl": "1400px", }, }, - extend: { - // Linear-inspired color palette (Charcoal & Bone) - colors: { - // Neutral scale (primary palette) - neutral: { - 50: '#FAFAFA', - 100: '#F5F5F5', - 200: '#E5E5E5', - 300: '#D4D4D4', - 400: '#A3A3A3', - 500: '#737373', - 600: '#525252', - 700: '#404040', - 800: '#262626', - 850: '#1F1F1F', - 900: '#171717', - 950: '#0A0A0A', - }, - // Accent (Linear's desaturated blue-purple) - accent: { - DEFAULT: '#5E6AD2', - hover: '#6E7AE2', - muted: 'rgba(94, 106, 210, 0.15)', - foreground: '#FFFFFF', - }, - // Semantic colors - success: { - DEFAULT: '#22C55E', - muted: 'rgba(34, 197, 94, 0.15)', - foreground: '#FFFFFF', - }, - warning: { - DEFAULT: '#EAB308', - muted: 'rgba(234, 179, 8, 0.15)', - foreground: '#171717', - }, - destructive: { - DEFAULT: '#EF4444', - muted: 'rgba(239, 68, 68, 0.15)', - foreground: '#FFFFFF', - }, - // Legacy support (mapped to neutral) - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "#5E6AD2", // Now accent color - foreground: "#FFFFFF", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, + // Design OS Palette (Stone & Lime) + colors: { + // Neutral scale (Stone = warmth + utility) + neutral: { + ...colors.stone, + // Map legacy specifics if needed, but prefer stone-950 for blacks + 850: '#1c1917', // stone-900ish + 950: '#0c0a09', // stone-950 }, - borderRadius: { - 'xs': '4px', - 'sm': '6px', - 'md': '8px', - 'lg': '12px', - 'xl': '16px', + // Primary Accent (Lime = fresh + technical) + accent: { + ...colors.lime, + DEFAULT: colors.lime[500], // Was Linear Purple + hover: colors.lime[400], + muted: 'rgba(132, 204, 22, 0.15)', // Lime-500 alpha + foreground: colors.stone[950], // Dark text on lime }, - // Touch-friendly spacing - spacing: { - 'touch': '44px', - 'touch-lg': '56px', + // Semantic colors + success: { + DEFAULT: colors.emerald[500], + muted: 'rgba(16, 185, 129, 0.15)', + foreground: '#FFFFFF', }, - // Linear-inspired typography - fontFamily: { - sans: ['Inter', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'], - display: ['Space Grotesk', 'Inter', '-apple-system', 'BlinkMacSystemFont', 'sans-serif'], - mono: ['JetBrains Mono', 'Fira Code', 'Consolas', 'monospace'], + warning: { + DEFAULT: colors.amber[500], + muted: 'rgba(245, 158, 11, 0.15)', + foreground: '#171717', }, - fontSize: { - 'xs': ['11px', { lineHeight: '1.4', letterSpacing: '0.01em' }], - 'sm': ['13px', { lineHeight: '1.5', letterSpacing: '-0.01em' }], - 'base': ['14px', { lineHeight: '1.6', letterSpacing: '-0.01em' }], - 'lg': ['16px', { lineHeight: '1.5', letterSpacing: '-0.02em', fontWeight: '500' }], - 'xl': ['18px', { lineHeight: '1.4', letterSpacing: '-0.02em', fontWeight: '600' }], - '2xl': ['24px', { lineHeight: '1.3', letterSpacing: '-0.02em', fontWeight: '600' }], - '3xl': ['30px', { lineHeight: '1.2', letterSpacing: '-0.02em', fontWeight: '700' }], - '4xl': ['36px', { lineHeight: '1.1', letterSpacing: '-0.02em', fontWeight: '700' }], + destructive: { + DEFAULT: colors.red[500], + muted: 'rgba(239, 68, 68, 0.15)', + foreground: '#FFFFFF', }, - // Animation timing (Linear-style) - transitionTimingFunction: { - 'out-expo': 'cubic-bezier(0.16, 1, 0.3, 1)', - 'in-out-expo': 'cubic-bezier(0.87, 0, 0.13, 1)', - 'spring': 'cubic-bezier(0.34, 1.56, 0.64, 1)', + // Mappings + border: colors.stone[200], + input: colors.stone[200], + ring: colors.lime[500], + background: colors.stone[50], // Slightly warm background + foreground: colors.stone[950], + primary: { + DEFAULT: colors.lime[500], + foreground: colors.stone[950], }, - transitionDuration: { - 'instant': '50ms', - 'fast': '100ms', - 'normal': '150ms', - 'slow': '250ms', - 'slower': '400ms', + secondary: { + DEFAULT: colors.stone[100], + foreground: colors.stone[900], }, - // Keyframe animations - keyframes: { - 'fade-in': { - '0%': { opacity: '0' }, - '100%': { opacity: '1' }, - }, - 'fade-out': { - '0%': { opacity: '1' }, - '100%': { opacity: '0' }, - }, - 'slide-up': { - '0%': { opacity: '0', transform: 'translateY(8px)' }, - '100%': { opacity: '1', transform: 'translateY(0)' }, - }, - 'slide-down': { - '0%': { opacity: '0', transform: 'translateY(-8px)' }, - '100%': { opacity: '1', transform: 'translateY(0)' }, - }, - 'scale-in': { - '0%': { opacity: '0', transform: 'scale(0.95)' }, - '100%': { opacity: '1', transform: 'scale(1)' }, - }, - 'scale-out': { - '0%': { opacity: '1', transform: 'scale(1)' }, - '100%': { opacity: '0', transform: 'scale(0.95)' }, - }, - 'shimmer': { - '0%': { backgroundPosition: '-200% 0' }, - '100%': { backgroundPosition: '200% 0' }, - }, - 'pulse-subtle': { - '0%, 100%': { opacity: '1' }, - '50%': { opacity: '0.7' }, - }, - 'spin-slow': { - '0%': { transform: 'rotate(0deg)' }, - '100%': { transform: 'rotate(360deg)' }, - }, + muted: { + DEFAULT: colors.stone[100], + foreground: colors.stone[500], }, - animation: { - 'fade-in': 'fade-in 150ms ease-out', - 'fade-out': 'fade-out 150ms ease-out', - 'slide-up': 'slide-up 200ms cubic-bezier(0.16, 1, 0.3, 1)', - 'slide-down': 'slide-down 200ms cubic-bezier(0.16, 1, 0.3, 1)', - 'scale-in': 'scale-in 150ms cubic-bezier(0.16, 1, 0.3, 1)', - 'scale-out': 'scale-out 150ms cubic-bezier(0.16, 1, 0.3, 1)', - 'shimmer': 'shimmer 2s linear infinite', - 'pulse-subtle': 'pulse-subtle 2s ease-in-out infinite', - 'spin-slow': 'spin-slow 3s linear infinite', + popover: { + DEFAULT: "#FFFFFF", + foreground: colors.stone[950], }, - // Box shadows (subtle, Linear-style) - boxShadow: { - 'xs': '0 1px 2px 0 rgb(0 0 0 / 0.05)', - 'sm': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', - 'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', - 'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)', - 'focus': '0 0 0 3px rgba(94, 106, 210, 0.25)', - 'focus-destructive': '0 0 0 3px rgba(239, 68, 68, 0.25)', + card: { + DEFAULT: "#FFFFFF", + foreground: colors.stone[950], }, }, + borderRadius: { + 'xs': '4px', + 'sm': '6px', + 'md': '8px', + 'lg': '12px', + 'xl': '16px', + }, + // Touch-friendly spacing + spacing: { + 'touch': '44px', + 'touch-lg': '56px', + }, + // Linear-inspired typography + fontFamily: { + sans: ['Inter', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'], + display: ['Space Grotesk', 'Inter', '-apple-system', 'BlinkMacSystemFont', 'sans-serif'], + mono: ['JetBrains Mono', 'Fira Code', 'Consolas', 'monospace'], + }, + fontSize: { + 'xs': ['11px', { lineHeight: '1.4', letterSpacing: '0.01em' }], + 'sm': ['13px', { lineHeight: '1.5', letterSpacing: '-0.01em' }], + 'base': ['14px', { lineHeight: '1.6', letterSpacing: '-0.01em' }], + 'lg': ['16px', { lineHeight: '1.5', letterSpacing: '-0.02em', fontWeight: '500' }], + 'xl': ['18px', { lineHeight: '1.4', letterSpacing: '-0.02em', fontWeight: '600' }], + '2xl': ['24px', { lineHeight: '1.3', letterSpacing: '-0.02em', fontWeight: '600' }], + '3xl': ['30px', { lineHeight: '1.2', letterSpacing: '-0.02em', fontWeight: '700' }], + '4xl': ['36px', { lineHeight: '1.1', letterSpacing: '-0.02em', fontWeight: '700' }], + }, + // Animation timing (Linear-style) + transitionTimingFunction: { + 'out-expo': 'cubic-bezier(0.16, 1, 0.3, 1)', + 'in-out-expo': 'cubic-bezier(0.87, 0, 0.13, 1)', + 'spring': 'cubic-bezier(0.34, 1.56, 0.64, 1)', + }, + transitionDuration: { + 'instant': '50ms', + 'fast': '100ms', + 'normal': '150ms', + 'slow': '250ms', + 'slower': '400ms', + }, + // Keyframe animations + keyframes: { + 'fade-in': { + '0%': { opacity: '0' }, + '100%': { opacity: '1' }, + }, + 'fade-out': { + '0%': { opacity: '1' }, + '100%': { opacity: '0' }, + }, + 'slide-up': { + '0%': { opacity: '0', transform: 'translateY(8px)' }, + '100%': { opacity: '1', transform: 'translateY(0)' }, + }, + 'slide-down': { + '0%': { opacity: '0', transform: 'translateY(-8px)' }, + '100%': { opacity: '1', transform: 'translateY(0)' }, + }, + 'scale-in': { + '0%': { opacity: '0', transform: 'scale(0.95)' }, + '100%': { opacity: '1', transform: 'scale(1)' }, + }, + 'scale-out': { + '0%': { opacity: '1', transform: 'scale(1)' }, + '100%': { opacity: '0', transform: 'scale(0.95)' }, + }, + 'shimmer': { + '0%': { backgroundPosition: '-200% 0' }, + '100%': { backgroundPosition: '200% 0' }, + }, + 'pulse-subtle': { + '0%, 100%': { opacity: '1' }, + '50%': { opacity: '0.7' }, + }, + 'spin-slow': { + '0%': { transform: 'rotate(0deg)' }, + '100%': { transform: 'rotate(360deg)' }, + }, + }, + animation: { + 'fade-in': 'fade-in 150ms ease-out', + 'fade-out': 'fade-out 150ms ease-out', + 'slide-up': 'slide-up 200ms cubic-bezier(0.16, 1, 0.3, 1)', + 'slide-down': 'slide-down 200ms cubic-bezier(0.16, 1, 0.3, 1)', + 'scale-in': 'scale-in 150ms cubic-bezier(0.16, 1, 0.3, 1)', + 'scale-out': 'scale-out 150ms cubic-bezier(0.16, 1, 0.3, 1)', + 'shimmer': 'shimmer 2s linear infinite', + 'pulse-subtle': 'pulse-subtle 2s ease-in-out infinite', + 'spin-slow': 'spin-slow 3s linear infinite', + }, + // Box shadows (subtle, Linear-style) + boxShadow: { + 'xs': '0 1px 2px 0 rgb(0 0 0 / 0.05)', + 'sm': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', + 'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', + 'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)', + 'focus': '0 0 0 3px rgba(94, 106, 210, 0.25)', + 'focus-destructive': '0 0 0 3px rgba(239, 68, 68, 0.25)', + }, }, - plugins: [], +}, +plugins: [], } diff --git a/product/design-system/colors.json b/product/design-system/colors.json new file mode 100644 index 0000000..54a18f8 --- /dev/null +++ b/product/design-system/colors.json @@ -0,0 +1,13 @@ +{ + "colors": { + "primary": "lime", + "secondary": "stone", + "neutral": "stone", + "background": "white", + "foreground": "stone-950" + }, + "typography": { + "sans": "Inter", + "mono": "JetBrains Mono" + } +} \ No newline at end of file diff --git a/product/product-overview.md b/product/product-overview.md new file mode 100644 index 0000000..0953ae2 --- /dev/null +++ b/product/product-overview.md @@ -0,0 +1,20 @@ +# CA Grow Ops Manager + +## Vision + +The CA Grow Ops Manager is a comprehensive facility management system for cannabis cultivation operations. It unifies environment tracking, plant lifecycle management, task delegation, compliance auditing, and visitor management into a single, intuitive interface. + +## Core Pillars + +1. **Facility Visualization**: 3D Digital Twin of the facility for intuitive navigation and monitoring. +2. **Compliance & Audit**: Rigorous tracking of all actions (SOPs, logs, visitor access) to meet regulatory standards. +3. **Operational Efficiency**: Task management, batch tracking, and automated schedules (IPM, feeding). +4. **Data-Driven Insights**: Real-time environmental metrics and historical reporting. + +## Key Features + +- **3D Facility Viewer**: Interactive "Time Machine" to view plant states at any point in history. +- **Batch Tracking**: From clone to harvest, integrated with METRC. +- **Visitor Kiosk**: Self-service check-in with badge printing. +- **SOP Library**: Document version control and acknowledgement tracking. +- **Audit Log**: Immutable record of all system activities. diff --git a/product/types.ts b/product/types.ts new file mode 100644 index 0000000..e6f3b32 --- /dev/null +++ b/product/types.ts @@ -0,0 +1,7 @@ +export interface DesignToken { + colors: { + primary: string; + secondary: string; + neutral: string; + } +}