/* Tailwind CSS v4: import the full framework */ @import "tailwindcss"; @import "../styles/tokens.css"; @import "../styles/utilities.css"; @import "../styles/responsive.css"; @custom-variant dark (&:is(.dark *)); :root { --radius: 0.625rem; /* ============= CORE NEUTRALS ============= */ --background: oklch(1 0 0); /* pure white for main content */ --foreground: oklch(0.16 0 0); --card: oklch(1 0 0); /* pure white for cards */ --card-foreground: var(--foreground); --card-muted: oklch(0.98 0.008 234.4); /* subtle brand-tinted gray */ --popover: oklch(1 0 0); --popover-foreground: var(--foreground); /* ============= BRAND COLORS (from logo) ============= */ /* Primary Light Blue - Brand Accent */ --primary: oklch(0.6884 0.1342 234.4); --primary-foreground: oklch(0.99 0 0); --primary-hover: oklch(0.62 0.1342 234.4); --primary-active: oklch(0.56 0.1342 234.4); /* Subtle surfaces & text - tinted with primary brand hue */ --secondary: oklch(0.95 0.015 234.4); --secondary-foreground: oklch(0.29 0 0); --muted: oklch(0.96 0.008 234.4); --muted-foreground: oklch(0.5 0 0); /* Light accent (tinted with brand) */ --accent: oklch(0.95 0.04 234.4); --accent-foreground: var(--foreground); /* ============= SEMANTIC STATUS COLORS ============= */ /* Three-tier system: text (dark readable), bg (almost white), border (subtle accent) */ /* Reserve brand cyan for primary interaction; status colors are secondary */ /* Success - #166534 text, #F0FDF4 bg, #BBF7D0 border */ --success: oklch(0.42 0.1 145); /* dark green for text/icons */ --success-foreground: oklch(0.99 0 0); --success-bg: oklch(0.98 0.02 145); /* very light green bg */ --success-border: oklch(0.93 0.08 150); /* subtle green border */ /* Info - uses primary brand hue */ --info: oklch(0.48 0.1 234.4); --info-foreground: oklch(0.99 0 0); --info-bg: oklch(0.97 0.02 234.4); --info-border: oklch(0.91 0.05 234.4); /* Warning - #92400E text, #FFFBEB bg, #FDE68A border */ --warning: oklch(0.45 0.12 55); /* dark amber for text/icons */ --warning-foreground: oklch(0.99 0 0); --warning-bg: oklch(0.99 0.02 90); /* very light amber bg */ --warning-border: oklch(0.92 0.12 90); /* subtle amber border */ /* Error - #9F1239 text, #FFF1F2 bg, #FECDD3 border (Overdue) */ --error: oklch(0.42 0.16 0); /* dark rose for text/icons */ --error-foreground: oklch(0.99 0 0); --error-bg: oklch(0.98 0.01 0); /* very light rose bg */ --error-border: oklch(0.89 0.06 0); /* subtle rose border */ /* Destructive - #991B1B text, #FEF2F2 bg, #FECACA border (Terminated) */ --destructive: oklch(0.43 0.15 25); /* dark red for text/icons */ --destructive-foreground: oklch(0.99 0 0); --destructive-bg: oklch(0.98 0.01 20); /* very light red bg */ --destructive-border: oklch(0.89 0.06 20); /* subtle red border */ /* Neutral - uses sidebar brand hue */ --neutral: oklch(0.36 0.03 272.34); --neutral-foreground: oklch(0.99 0 0); --neutral-bg: oklch(0.97 0.008 272.34); --neutral-border: oklch(0.87 0.02 272.34); /* ============= GRANULAR STATUS COLORS ============= */ /* Three-tier: text (dark readable), bg (almost white), border (subtle accent) */ /* Active - uses primary brand hue */ --status-active: oklch(0.48 0.1 234.4); --status-active-bg: oklch(0.97 0.02 234.4); --status-active-border: oklch(0.91 0.05 234.4); /* Completed - uses sidebar brand hue */ --status-completed: oklch(0.2754 0.1199 272.34); --status-completed-bg: oklch(0.96 0.02 272.34); --status-completed-border: oklch(0.87 0.07 272.34); /* Paid - #0F766E text, #ECFDF5 bg, #A7F3D0 border (teal, closer to brand) */ --status-paid: oklch(0.48 0.08 175); --status-paid-bg: oklch(0.98 0.02 165); --status-paid-border: oklch(0.92 0.08 160); /* Success - #166534 text, #F0FDF4 bg, #BBF7D0 border */ --status-success: oklch(0.42 0.1 145); --status-success-bg: oklch(0.98 0.02 145); --status-success-border: oklch(0.93 0.08 150); /* Pending - #92400E text, #FFFBEB bg, #FDE68A border */ --status-pending: oklch(0.45 0.12 55); --status-pending-bg: oklch(0.99 0.02 90); --status-pending-border: oklch(0.92 0.12 90); /* Suspended - uses sidebar brand hue */ --status-suspended: oklch(0.36 0.03 272.34); --status-suspended-bg: oklch(0.97 0.008 272.34); --status-suspended-border: oklch(0.87 0.02 272.34); /* Unpaid - #9A3412 text, #FFF7ED bg, #FED7AA border */ --status-unpaid: oklch(0.46 0.13 45); --status-unpaid-bg: oklch(0.98 0.02 70); --status-unpaid-border: oklch(0.9 0.08 65); /* Terminated - #991B1B text, #FEF2F2 bg, #FECACA border */ --status-terminated: oklch(0.43 0.15 25); --status-terminated-bg: oklch(0.98 0.01 20); --status-terminated-border: oklch(0.89 0.06 20); /* Overdue - #9F1239 text, #FFF1F2 bg, #FECDD3 border */ --status-overdue: oklch(0.42 0.16 0); --status-overdue-bg: oklch(0.98 0.01 0); --status-overdue-border: oklch(0.89 0.06 0); /* ============= SOFT COLOR VARIANTS (for badges/pills) ============= */ /* These use the -bg colors for backgrounds with text colors for contrast */ --success-soft: var(--success-bg); --info-soft: var(--info-bg); --warning-soft: var(--warning-bg); --destructive-soft: var(--destructive-bg); --neutral-soft: var(--neutral-bg); /* ============= UI CHROME ============= */ --border: oklch(0.9 0.005 234.4); --border-muted: oklch(0.92 0.003 234.4); --input: oklch(0.88 0.005 234.4); --ring: oklch(0.72 0.12 234.4); --ring-subtle: color-mix(in oklch, var(--ring) 45%, transparent); /* ============= CHARTS ============= */ /* Harmonious palette based on brand and status colors */ --chart-1: oklch(0.6884 0.1342 234.4); /* Primary brand blue */ --chart-2: oklch(0.65 0.12 145); /* Success - green */ --chart-3: oklch(0.75 0.14 85); /* Pending - amber */ --chart-4: oklch(0.55 0.16 38); /* Overdue - orange-red */ --chart-5: oklch(0.2754 0.1199 272.34); /* Sidebar brand navy */ /* ============= SIDEBAR ============= */ /* Primary Dark Blue - Brand Anchor (Logo Color) */ --sidebar: oklch(0.2754 0.1199 272.34); --sidebar-foreground: oklch(1 0 0); --sidebar-primary: oklch(0.6884 0.1342 234.4); /* primary brand blue for accent */ --sidebar-primary-foreground: oklch(1 0 0); --sidebar-accent: oklch(0.36 0.1199 272.34); --sidebar-accent-foreground: oklch(1 0 0); --sidebar-border: oklch(0.36 0.1 272.34); --sidebar-ring: oklch(0.72 0.12 234.4); } .dark { /* ============= CORE NEUTRALS (DARK) ============= */ --background: oklch(0.15 0.01 272.34); --foreground: oklch(0.98 0 0); --card: oklch(0.18 0.01 272.34); --card-foreground: var(--foreground); --card-muted: oklch(0.22 0.01 272.34); --popover: oklch(0.18 0.01 272.34); --popover-foreground: var(--foreground); /* ============= BRAND COLORS (DARK MODE) ============= */ /* Lighter brand blue for dark mode visibility */ --primary: oklch(0.76 0.12 234.4); --primary-foreground: oklch(0.15 0 0); --primary-hover: oklch(0.7 0.12 234.4); --primary-active: oklch(0.65 0.12 234.4); /* Subtle surfaces & text - tinted with sidebar hue */ --secondary: oklch(0.22 0.01 272.34); --secondary-foreground: oklch(0.9 0 0); --muted: oklch(0.25 0.01 272.34); --muted-foreground: oklch(0.74 0 0); /* Accent (tinted with brand) */ --accent: oklch(0.24 0.03 234.4); --accent-foreground: oklch(0.92 0 0); /* ============= SEMANTIC STATUS COLORS (DARK) ============= */ /* Three-tier: text (lighter for dark bg), bg (dark subtle), border (mid accent) */ /* Success - lighter green for dark mode */ --success: oklch(0.72 0.1 145); --success-foreground: oklch(0.15 0 0); --success-bg: oklch(0.24 0.04 145); --success-border: oklch(0.38 0.08 150); /* Info - uses primary brand hue */ --info: oklch(0.72 0.1 234.4); --info-foreground: oklch(0.15 0 0); --info-bg: oklch(0.24 0.04 234.4); --info-border: oklch(0.38 0.07 234.4); /* Warning - lighter amber for dark mode */ --warning: oklch(0.78 0.12 55); --warning-foreground: oklch(0.15 0 0); --warning-bg: oklch(0.26 0.04 90); --warning-border: oklch(0.42 0.1 90); /* Error - lighter rose for dark mode */ --error: oklch(0.72 0.14 0); --error-foreground: oklch(0.15 0 0); --error-bg: oklch(0.24 0.03 0); --error-border: oklch(0.38 0.08 0); /* Destructive - lighter red for dark mode */ --destructive: oklch(0.7 0.14 25); --destructive-foreground: oklch(0.15 0 0); --destructive-bg: oklch(0.24 0.03 20); --destructive-border: oklch(0.38 0.08 20); /* Neutral - uses sidebar brand hue */ --neutral: oklch(0.7 0.03 272.34); --neutral-foreground: oklch(0.15 0 0); --neutral-bg: oklch(0.24 0.02 272.34); --neutral-border: oklch(0.38 0.03 272.34); /* ============= GRANULAR STATUS COLORS (DARK) ============= */ /* Active - uses primary brand hue */ --status-active: oklch(0.72 0.1 234.4); --status-active-bg: oklch(0.24 0.04 234.4); --status-active-border: oklch(0.38 0.07 234.4); /* Completed - uses sidebar brand hue */ --status-completed: oklch(0.55 0.1 272.34); --status-completed-bg: oklch(0.24 0.04 272.34); --status-completed-border: oklch(0.38 0.07 272.34); /* Paid */ --status-paid: oklch(0.7 0.08 175); --status-paid-bg: oklch(0.24 0.04 165); --status-paid-border: oklch(0.4 0.08 160); /* Success */ --status-success: oklch(0.72 0.1 145); --status-success-bg: oklch(0.24 0.04 145); --status-success-border: oklch(0.38 0.08 150); /* Pending */ --status-pending: oklch(0.78 0.12 55); --status-pending-bg: oklch(0.26 0.04 90); --status-pending-border: oklch(0.42 0.1 90); /* Suspended - uses sidebar brand hue */ --status-suspended: oklch(0.7 0.03 272.34); --status-suspended-bg: oklch(0.24 0.02 272.34); --status-suspended-border: oklch(0.38 0.03 272.34); /* Unpaid */ --status-unpaid: oklch(0.76 0.12 45); --status-unpaid-bg: oklch(0.26 0.04 70); --status-unpaid-border: oklch(0.42 0.08 65); /* Terminated */ --status-terminated: oklch(0.7 0.14 25); --status-terminated-bg: oklch(0.24 0.03 20); --status-terminated-border: oklch(0.38 0.08 20); /* Overdue */ --status-overdue: oklch(0.72 0.14 0); --status-overdue-bg: oklch(0.24 0.03 0); --status-overdue-border: oklch(0.38 0.08 0); /* ============= SOFT COLOR VARIANTS (for badges/pills) ============= */ --success-soft: var(--success-bg); --info-soft: var(--info-bg); --warning-soft: var(--warning-bg); --destructive-soft: var(--destructive-bg); --neutral-soft: var(--neutral-bg); /* ============= UI CHROME (DARK) ============= */ --border: oklch(0.32 0.02 272.34); --border-muted: oklch(0.28 0.01 272.34); --input: oklch(0.35 0.02 272.34); --ring: oklch(0.78 0.11 234.4); --ring-subtle: color-mix(in oklch, var(--ring) 40%, transparent); /* ============= CHARTS (DARK) ============= */ --chart-1: oklch(0.76 0.12 234.4); /* Primary brand blue */ --chart-2: oklch(0.72 0.12 145); /* Success - green */ --chart-3: oklch(0.82 0.14 85); /* Pending - amber */ --chart-4: oklch(0.65 0.15 38); /* Overdue - orange-red */ --chart-5: oklch(0.5 0.1 272.34); /* Sidebar brand navy */ /* ============= SIDEBAR (DARK) ============= */ --sidebar: oklch(0.22 0.1199 272.34); --sidebar-foreground: oklch(1 0 0); --sidebar-primary: oklch(0.76 0.12 234.4); /* lighter primary brand blue */ --sidebar-primary-foreground: oklch(0.15 0 0); --sidebar-accent: oklch(0.32 0.1 272.34); --sidebar-accent-foreground: oklch(1 0 0); --sidebar-border: oklch(0.3 0.08 272.34); --sidebar-ring: var(--ring); } /* Tailwind v4 token map */ @theme { /* Core */ --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-card-muted: var(--card-muted); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); /* Brand */ --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-primary-hover: var(--primary-hover); --color-primary-active: var(--primary-active); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); /* Semantic status colors (three-tier: text, bg, border + soft for badges) */ --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-success-bg: var(--success-bg); --color-success-border: var(--success-border); --color-success-soft: var(--success-soft); --color-info: var(--info); --color-info-foreground: var(--info-foreground); --color-info-bg: var(--info-bg); --color-info-border: var(--info-border); --color-info-soft: var(--info-soft); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-warning-bg: var(--warning-bg); --color-warning-border: var(--warning-border); --color-warning-soft: var(--warning-soft); --color-error: var(--error); --color-error-foreground: var(--error-foreground); --color-error-bg: var(--error-bg); --color-error-border: var(--error-border); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-destructive-bg: var(--destructive-bg); --color-destructive-border: var(--destructive-border); --color-destructive-soft: var(--destructive-soft); --color-neutral: var(--neutral); --color-neutral-foreground: var(--neutral-foreground); --color-neutral-bg: var(--neutral-bg); --color-neutral-border: var(--neutral-border); --color-neutral-soft: var(--neutral-soft); /* Granular status colors (three-tier: text, bg, border) */ --color-status-active: var(--status-active); --color-status-active-bg: var(--status-active-bg); --color-status-active-border: var(--status-active-border); --color-status-completed: var(--status-completed); --color-status-completed-bg: var(--status-completed-bg); --color-status-completed-border: var(--status-completed-border); --color-status-paid: var(--status-paid); --color-status-paid-bg: var(--status-paid-bg); --color-status-paid-border: var(--status-paid-border); --color-status-success: var(--status-success); --color-status-success-bg: var(--status-success-bg); --color-status-success-border: var(--status-success-border); --color-status-pending: var(--status-pending); --color-status-pending-bg: var(--status-pending-bg); --color-status-pending-border: var(--status-pending-border); --color-status-suspended: var(--status-suspended); --color-status-suspended-bg: var(--status-suspended-bg); --color-status-suspended-border: var(--status-suspended-border); --color-status-unpaid: var(--status-unpaid); --color-status-unpaid-bg: var(--status-unpaid-bg); --color-status-unpaid-border: var(--status-unpaid-border); --color-status-terminated: var(--status-terminated); --color-status-terminated-bg: var(--status-terminated-bg); --color-status-terminated-border: var(--status-terminated-border); --color-status-overdue: var(--status-overdue); --color-status-overdue-bg: var(--status-overdue-bg); --color-status-overdue-border: var(--status-overdue-border); /* UI chrome */ --color-border: var(--border); --color-border-muted: var(--border-muted); --color-input: var(--input); --color-ring: var(--ring); --color-ring-subtle: var(--ring-subtle); /* Charts */ --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); --color-chart-3: var(--chart-3); --color-chart-4: var(--chart-4); --color-chart-5: var(--chart-5); /* Sidebar */ --color-sidebar: var(--sidebar); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); } @layer base { * { border-color: var(--border); outline-color: var(--ring-subtle); } body { background-color: var(--background); color: var(--foreground); font-family: var(--font-geist-sans), system-ui, sans-serif; } } @theme inline { --animate-aurora: aurora 60s linear infinite; @keyframes aurora { from { backgroundposition: 50% 50%, 50% 50%; } to { backgroundposition: 350% 50%, 350% 50%; } } } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } }