Add shared components (ConfirmDeleteDialog, EditEntryDialog, validation utils), enhance all 12 extension workspaces with edit/delete dialogs, input validation, period comparisons, and new analytics features. Fix critical bugs in ProjectBilling margin calculation and EarningsPerLiter revenue allocation. Add pure calculation modules with 183 new tests across all extensions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
306 lines
7.6 KiB
CSS
306 lines
7.6 KiB
CSS
@import "tailwindcss";
|
|
@plugin "@tailwindcss/typography";
|
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
|
|
:root {
|
|
color-scheme: light;
|
|
/* Clean Slate — Modern ERP Palette */
|
|
|
|
--background: 220 14% 96%; /* Cool off-white #F2F4F7 */
|
|
--foreground: 224 12% 13%; /* Deep slate #1D2029 */
|
|
|
|
--card: 0 0% 100%; /* Pure white */
|
|
--card-foreground: 224 12% 13%;
|
|
|
|
--popover: 0 0% 100%;
|
|
--popover-foreground: 224 12% 13%;
|
|
|
|
/* Primary — Refined navy-blue */
|
|
--primary: 222 47% 35%; /* #304D83 */
|
|
--primary-foreground: 0 0% 100%;
|
|
|
|
/* Secondary — Cool pale gray */
|
|
--secondary: 220 13% 93%; /* #EBEDF1 */
|
|
--secondary-foreground: 224 12% 13%;
|
|
|
|
/* Muted — Neutral gray */
|
|
--muted: 218 12% 91%; /* #E3E6EB */
|
|
--muted-foreground: 218 8% 46%; /* #6B7280 */
|
|
|
|
/* Accent — Clear blue for interactive highlights */
|
|
--accent: 213 72% 50%; /* #2373D8 */
|
|
--accent-foreground: 0 0% 100%;
|
|
|
|
/* Destructive — Clean red */
|
|
--destructive: 0 68% 50%; /* #D63232 */
|
|
--destructive-foreground: 0 0% 100%;
|
|
|
|
/* Borders & Input */
|
|
--border: 218 14% 89%; /* #DEE1E7 */
|
|
--input: 218 14% 89%;
|
|
--ring: 222 47% 35%;
|
|
|
|
/* Radius */
|
|
--radius: 0.5rem;
|
|
|
|
/* Success — Clean green */
|
|
--success: 152 48% 38%; /* #329460 */
|
|
--success-foreground: 0 0% 100%;
|
|
|
|
/* Warning — Clear amber */
|
|
--warning: 38 92% 50%; /* #F59E0B */
|
|
--warning-foreground: 224 12% 13%;
|
|
|
|
/* Custom tokens */
|
|
--font-display: var(--font-fraunces), Georgia, serif;
|
|
--font-body: var(--font-geist-sans), system-ui, sans-serif;
|
|
|
|
/* Shadows — cool-toned */
|
|
--shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.06);
|
|
--shadow-lg: 0 12px 40px rgba(15, 23, 42, 0.08);
|
|
|
|
/* Animation */
|
|
--ease-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
--duration-fast: 150ms;
|
|
--duration-base: 300ms;
|
|
--duration-slow: 500ms;
|
|
}
|
|
|
|
.dark {
|
|
color-scheme: dark;
|
|
|
|
--background: 222 16% 10%;
|
|
--foreground: 216 12% 90%;
|
|
|
|
--card: 222 14% 13%;
|
|
--card-foreground: 216 12% 90%;
|
|
|
|
--popover: 222 14% 13%;
|
|
--popover-foreground: 216 12% 90%;
|
|
|
|
--primary: 222 50% 55%;
|
|
--primary-foreground: 0 0% 100%;
|
|
|
|
--secondary: 220 14% 18%;
|
|
--secondary-foreground: 216 12% 90%;
|
|
|
|
--muted: 220 12% 20%;
|
|
--muted-foreground: 218 8% 55%;
|
|
|
|
--accent: 213 72% 58%;
|
|
--accent-foreground: 0 0% 100%;
|
|
|
|
--destructive: 0 62% 55%;
|
|
--destructive-foreground: 0 0% 100%;
|
|
|
|
--border: 220 12% 22%;
|
|
--input: 220 12% 22%;
|
|
--ring: 222 50% 55%;
|
|
|
|
--success: 152 44% 45%;
|
|
--success-foreground: 0 0% 100%;
|
|
|
|
--warning: 38 85% 55%;
|
|
--warning-foreground: 224 12% 13%;
|
|
|
|
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
|
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35);
|
|
--shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
@theme inline {
|
|
--color-background: hsl(var(--background));
|
|
--color-foreground: hsl(var(--foreground));
|
|
--color-card: hsl(var(--card));
|
|
--color-card-foreground: hsl(var(--card-foreground));
|
|
--color-popover: hsl(var(--popover));
|
|
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
--color-primary: hsl(var(--primary));
|
|
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
--color-secondary: hsl(var(--secondary));
|
|
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
--color-muted: hsl(var(--muted));
|
|
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
--color-accent: hsl(var(--accent));
|
|
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
--color-destructive: hsl(var(--destructive));
|
|
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
--color-border: hsl(var(--border));
|
|
--color-input: hsl(var(--input));
|
|
--color-ring: hsl(var(--ring));
|
|
--color-success: hsl(var(--success));
|
|
--color-success-foreground: hsl(var(--success-foreground));
|
|
--color-warning: hsl(var(--warning));
|
|
--color-warning-foreground: hsl(var(--warning-foreground));
|
|
--radius-lg: var(--radius);
|
|
--radius-md: calc(var(--radius) - 2px);
|
|
--radius-sm: calc(var(--radius) - 4px);
|
|
--font-sans: var(--font-body);
|
|
--font-mono: var(--font-geist-mono), monospace;
|
|
--font-serif: var(--font-display);
|
|
}
|
|
|
|
* {
|
|
border-color: hsl(var(--border));
|
|
}
|
|
|
|
body {
|
|
background-color: hsl(var(--background));
|
|
color: hsl(var(--foreground));
|
|
font-family: var(--font-body);
|
|
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
|
|
/* Display typography - Fraunces */
|
|
.font-display {
|
|
font-family: var(--font-display);
|
|
font-optical-sizing: auto;
|
|
}
|
|
|
|
h1, h2, h3 {
|
|
font-family: var(--font-display);
|
|
font-weight: 500;
|
|
letter-spacing: -0.015em;
|
|
font-optical-sizing: auto;
|
|
}
|
|
|
|
/* Number styling - tabular for alignment */
|
|
.tabular-nums {
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* Text balance for better line wrapping on descriptions */
|
|
.text-balance {
|
|
text-wrap: balance;
|
|
}
|
|
|
|
/* Safe area padding for mobile devices with notch/home indicator */
|
|
.safe-area-bottom {
|
|
padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
|
|
}
|
|
|
|
/* Animation Keyframes */
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(16px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes slideInLeft {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@keyframes scaleIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.96);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes gentlePulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.6; }
|
|
}
|
|
|
|
/* Staggered entrance animation */
|
|
.stagger-enter > * {
|
|
animation: slideUp var(--duration-slow) var(--ease-out) both;
|
|
}
|
|
.stagger-enter > *:nth-child(1) { animation-delay: 0ms; }
|
|
.stagger-enter > *:nth-child(2) { animation-delay: 80ms; }
|
|
.stagger-enter > *:nth-child(3) { animation-delay: 160ms; }
|
|
.stagger-enter > *:nth-child(4) { animation-delay: 240ms; }
|
|
.stagger-enter > *:nth-child(5) { animation-delay: 320ms; }
|
|
.stagger-enter > *:nth-child(6) { animation-delay: 400ms; }
|
|
.stagger-enter > *:nth-child(7) { animation-delay: 480ms; }
|
|
.stagger-enter > *:nth-child(8) { animation-delay: 560ms; }
|
|
.stagger-enter > *:nth-child(9) { animation-delay: 640ms; }
|
|
.stagger-enter > *:nth-child(10) { animation-delay: 720ms; }
|
|
|
|
/* Utility animations */
|
|
.animate-fade-in {
|
|
animation: fadeIn var(--duration-base) var(--ease-out);
|
|
}
|
|
|
|
.animate-slide-up {
|
|
animation: slideUp var(--duration-slow) var(--ease-out);
|
|
}
|
|
|
|
.animate-scale-in {
|
|
animation: scaleIn var(--duration-base) var(--ease-out);
|
|
}
|
|
|
|
/* Refined hover effects */
|
|
.hover-lift {
|
|
transition: transform var(--duration-fast) var(--ease-out),
|
|
box-shadow var(--duration-fast) var(--ease-out);
|
|
}
|
|
|
|
.hover-lift:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-md);
|
|
}
|
|
|
|
/* Soft focus states */
|
|
.focus-ring:focus-visible {
|
|
outline: none;
|
|
box-shadow: 0 0 0 2px hsl(var(--background)),
|
|
0 0 0 4px hsl(var(--primary) / 0.3);
|
|
}
|
|
|
|
/* Custom scrollbar - minimal */
|
|
::-webkit-scrollbar {
|
|
width: 6px;
|
|
height: 6px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: hsl(var(--muted-foreground) / 0.2);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: hsl(var(--muted-foreground) / 0.3);
|
|
}
|
|
|
|
/* Selection color */
|
|
::selection {
|
|
background: hsl(var(--primary) / 0.15);
|
|
color: hsl(var(--foreground));
|
|
}
|
|
|
|
.dark ::selection {
|
|
background: hsl(var(--primary) / 0.3);
|
|
color: hsl(var(--foreground));
|
|
}
|