diff --git a/app/globals.css b/app/globals.css
index 21c90a2..ff31fd9 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -63,6 +63,13 @@
--warning: oklch(0.78 0.2 80);
--warning-foreground: oklch(0.1 0.015 280);
+ /* Additional semantic colors */
+ --green: oklch(0.68 0.2 150);
+ --blue: oklch(0.6 0.2 250);
+ --gray: oklch(0.55 0.01 280);
+ --gray-light: oklch(0.92 0.005 280);
+ --card-column: oklch(0.96 0.006 280);
+
--radius: 1.25rem;
/* Sidebar moderne avec glassmorphism très prononcé */
@@ -77,73 +84,86 @@
}
.dark {
- /* Background sombre fintech avec dégradé vibrant */
- --background: oklch(0.1 0.015 280);
- --foreground: oklch(0.97 0.005 280);
+ /* ═══════════════════════════════════════════════════════════════════
+ THÈME SOMBRE FINTECH - Design moderne avec profondeur et vibrance
+ ═══════════════════════════════════════════════════════════════════ */
- /* Cards avec effet glassmorphism sombre très prononcé */
- --card: oklch(0.15 0.015 280 / 0.5);
- --card-foreground: oklch(0.97 0.005 280);
- --card-hover: oklch(0.18 0.015 280 / 0.65);
+ /* Background avec légère teinte bleutée pour profondeur */
+ --background: oklch(0.12 0.008 260);
+ --foreground: oklch(0.95 0.005 260);
- /* Popover avec backdrop blur très fort */
- --popover: oklch(0.15 0.015 280 / 0.95);
- --popover-foreground: oklch(0.97 0.005 280);
+ /* Cards avec subtile élévation - légèrement plus claires que le fond */
+ --card: oklch(0.15 0.01 260);
+ --card-foreground: oklch(0.95 0.005 260);
+ --card-hover: oklch(0.18 0.012 260);
- /* Primary: Bleu/violet très brillant pour dark mode */
- --primary: oklch(0.72 0.28 270);
- --primary-foreground: oklch(0.1 0.015 280);
+ /* Popover avec fond plus dense pour contraste */
+ --popover: oklch(0.13 0.01 260);
+ --popover-foreground: oklch(0.95 0.005 260);
+
+ /* Primary: Cyan/Bleu électrique très vibrant */
+ --primary: oklch(0.72 0.19 220);
+ --primary-foreground: oklch(0.12 0.008 260);
--primary-gradient: linear-gradient(
135deg,
- oklch(0.72 0.28 270) 0%,
- oklch(0.75 0.25 300) 50%,
- oklch(0.73 0.27 250) 100%
+ oklch(0.72 0.19 220) 0%,
+ oklch(0.65 0.22 240) 50%,
+ oklch(0.58 0.24 260) 100%
);
- --primary-light: oklch(0.78 0.23 270);
+ --primary-light: oklch(0.78 0.16 220);
- /* Secondary avec plus de contraste */
- --secondary: oklch(0.22 0.015 280);
- --secondary-foreground: oklch(0.95 0.005 280);
+ /* Secondary avec teinte subtile */
+ --secondary: oklch(0.2 0.012 260);
+ --secondary-foreground: oklch(0.9 0.005 260);
- /* Muted plus visible */
- --muted: oklch(0.22 0.015 280);
- --muted-foreground: oklch(0.7 0.012 280);
+ /* Muted pour éléments désactivés/secondaires */
+ --muted: oklch(0.18 0.01 260);
+ --muted-foreground: oklch(0.6 0.015 260);
- /* Accent très vibrant */
- --accent: oklch(0.26 0.02 260);
- --accent-foreground: oklch(0.72 0.28 270);
+ /* Accent pour hover et sélections */
+ --accent: oklch(0.22 0.015 260);
+ --accent-foreground: oklch(0.72 0.19 220);
- /* Destructive moderne */
- --destructive: oklch(0.68 0.27 25);
- --destructive-foreground: oklch(0.97 0 0);
+ /* Destructive: Rouge vif mais accessible */
+ --destructive: oklch(0.65 0.22 25);
+ --destructive-foreground: oklch(0.98 0 0);
- /* Bordures subtiles */
- --border: oklch(0.25 0.015 280 / 0.4);
- --input: oklch(0.22 0.015 280);
- --ring: oklch(0.72 0.28 270 / 0.6);
+ /* Bordures avec subtile teinte pour cohérence */
+ --border: oklch(0.25 0.01 260);
+ --input: oklch(0.16 0.01 260);
+ --ring: oklch(0.72 0.19 220 / 0.6);
- /* Chart colors très vibrantes pour dark */
- --chart-1: oklch(0.75 0.27 270);
- --chart-2: oklch(0.8 0.25 180);
- --chart-3: oklch(0.85 0.23 120);
- --chart-4: oklch(0.8 0.27 320);
- --chart-5: oklch(0.75 0.25 40);
+ /* Palette de graphiques vibrante et harmonieuse */
+ --chart-1: oklch(0.72 0.19 220); /* Cyan primaire */
+ --chart-2: oklch(0.72 0.2 165); /* Vert émeraude */
+ --chart-3: oklch(0.8 0.18 85); /* Ambre doré */
+ --chart-4: oklch(0.7 0.22 300); /* Violet */
+ --chart-5: oklch(0.68 0.2 350); /* Rose */
- /* Success et Warning pour fintech dark */
- --success: oklch(0.73 0.22 150);
- --success-foreground: oklch(0.1 0.015 280);
- --warning: oklch(0.8 0.22 80);
- --warning-foreground: oklch(0.1 0.015 280);
+ /* Success: Vert émeraude vibrant */
+ --success: oklch(0.72 0.2 165);
+ --success-foreground: oklch(0.12 0.008 260);
- /* Sidebar dark moderne avec glassmorphism très prononcé */
- --sidebar: oklch(0.12 0.015 280 / 0.5);
- --sidebar-foreground: oklch(0.95 0.005 280);
- --sidebar-primary: oklch(0.72 0.28 270);
- --sidebar-primary-foreground: oklch(0.1 0.015 280);
- --sidebar-accent: oklch(0.26 0.02 260);
- --sidebar-accent-foreground: oklch(0.95 0.005 280);
- --sidebar-border: oklch(0.25 0.015 280 / 0.3);
- --sidebar-ring: oklch(0.72 0.28 270 / 0.5);
+ /* Warning: Ambre chaleureux */
+ --warning: oklch(0.8 0.18 85);
+ --warning-foreground: oklch(0.15 0.01 85);
+
+ /* Couleurs sémantiques additionnelles */
+ --green: oklch(0.72 0.2 165);
+ --blue: oklch(0.72 0.19 220);
+ --gray: oklch(0.55 0.01 260);
+ --gray-light: oklch(0.3 0.008 260);
+ --card-column: oklch(0.14 0.008 260);
+
+ /* Sidebar avec profondeur distincte */
+ --sidebar: oklch(0.1 0.01 260);
+ --sidebar-foreground: oklch(0.9 0.005 260);
+ --sidebar-primary: oklch(0.72 0.19 220);
+ --sidebar-primary-foreground: oklch(0.12 0.008 260);
+ --sidebar-accent: oklch(0.18 0.012 260);
+ --sidebar-accent-foreground: oklch(0.9 0.005 260);
+ --sidebar-border: oklch(0.2 0.01 260);
+ --sidebar-ring: oklch(0.72 0.19 220 / 0.5);
}
@theme inline {
@@ -153,6 +173,7 @@
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
+ --color-card-column: var(--card-column);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
@@ -165,6 +186,14 @@
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
+ --color-success: var(--success);
+ --color-success-foreground: var(--success-foreground);
+ --color-warning: var(--warning);
+ --color-warning-foreground: var(--warning-foreground);
+ --color-green: var(--green);
+ --color-blue: var(--blue);
+ --color-gray: var(--gray);
+ --color-gray-light: var(--gray-light);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
@@ -192,7 +221,8 @@
@apply border-border outline-ring/50;
}
body {
- @apply bg-background text-foreground;
+ @apply bg-background;
+ color: var(--foreground);
font-feature-settings:
"rlig" 1,
"calt" 1;
@@ -201,6 +231,10 @@
-moz-osx-font-smoothing: grayscale;
}
+ .dark body {
+ color: var(--foreground) !important;
+ }
+
h1,
h2,
h3,
@@ -209,6 +243,16 @@
h6 {
letter-spacing: -0.02em;
font-weight: 700;
+ color: var(--foreground);
+ }
+
+ .dark h1,
+ .dark h2,
+ .dark h3,
+ .dark h4,
+ .dark h5,
+ .dark h6 {
+ color: var(--foreground);
}
p {
@@ -345,6 +389,16 @@
inset 0 1px 0 0 color-mix(in srgb, white 20%, transparent);
}
+ .dark .glass {
+ background: oklch(0.12 0.01 260 / 0.9);
+ backdrop-filter: blur(24px) saturate(140%);
+ -webkit-backdrop-filter: blur(24px) saturate(140%);
+ border-color: oklch(1 0 0 / 0.08);
+ box-shadow:
+ 0 8px 32px -8px oklch(0 0 0 / 0.5),
+ inset 0 1px 0 0 oklch(1 0 0 / 0.05);
+ }
+
/* Gradient text effect */
.gradient-text {
background: var(--primary-gradient);
@@ -368,45 +422,142 @@
position: relative;
background: linear-gradient(
135deg,
- oklch(0.98 0.01 280) 0%,
- oklch(0.97 0.012 270) 50%,
- oklch(0.98 0.01 290) 100%
+ oklch(0.99 0 0) 0%,
+ oklch(0.985 0 0) 50%,
+ oklch(0.99 0 0) 100%
);
overflow: hidden;
}
- /* Fonds personnalisables */
+ /* ═══════════════════════════════════════════════════════════════════
+ THÈMES DE FOND - Mode Clair
+ ═══════════════════════════════════════════════════════════════════ */
+
+ /* Neutre - Fond élégant et discret */
.page-background.bg-default {
- background: linear-gradient(
- 135deg,
- oklch(0.98 0.01 280) 0%,
- oklch(0.97 0.012 270) 50%,
- oklch(0.98 0.01 290) 100%
- );
+ background:
+ radial-gradient(
+ ellipse 100% 60% at 50% 0%,
+ oklch(0.97 0.01 260 / 0.5) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.985 0 0) 0%,
+ oklch(0.97 0.005 260) 50%,
+ oklch(0.985 0 0) 100%
+ );
}
+ /* Océan - Bleu apaisant */
.page-background.bg-gradient-blue {
- background: linear-gradient(135deg, #e0f2fe 0%, #bae6fd 50%, #7dd3fc 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 20% 20%,
+ oklch(0.85 0.1 220 / 0.4) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 80% 70%,
+ oklch(0.75 0.12 225 / 0.3) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.95 0.03 230) 0%,
+ oklch(0.88 0.08 225) 50%,
+ oklch(0.78 0.12 220) 100%
+ );
}
+ /* Améthyste - Violet sophistiqué */
.page-background.bg-gradient-purple {
- background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 50%, #d8b4fe 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 30% 20%,
+ oklch(0.82 0.12 300 / 0.4) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 75% 65%,
+ oklch(0.72 0.15 290 / 0.3) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.95 0.04 300) 0%,
+ oklch(0.88 0.1 295) 50%,
+ oklch(0.78 0.15 290) 100%
+ );
}
+ /* Forêt - Vert naturel */
.page-background.bg-gradient-green {
- background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 50%, #86efac 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 25% 25%,
+ oklch(0.82 0.12 160 / 0.4) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 70% 70%,
+ oklch(0.72 0.14 150 / 0.3) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.95 0.04 160) 0%,
+ oklch(0.88 0.1 155) 50%,
+ oklch(0.78 0.14 150) 100%
+ );
}
+ /* Aurore - Orange chaleureux */
.page-background.bg-gradient-orange {
- background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 50%, #fed7aa 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 20% 30%,
+ oklch(0.88 0.1 60 / 0.4) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 80% 60%,
+ oklch(0.8 0.14 45 / 0.3) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.97 0.03 80) 0%,
+ oklch(0.92 0.08 60) 50%,
+ oklch(0.85 0.14 45) 100%
+ );
}
+ /* Lumineux - Blanc épuré avec subtile profondeur */
.page-background.bg-solid-light {
- background: #ffffff;
+ background:
+ radial-gradient(
+ ellipse 100% 60% at 50% 0%,
+ oklch(0.98 0.008 260 / 0.6) 0%,
+ transparent 50%
+ ),
+ linear-gradient(135deg, oklch(1 0 0) 0%, oklch(0.98 0.005 260) 100%);
}
.page-background.bg-solid-dark {
- background: #0f172a !important;
+ /* Fond noir profond avec subtile teinte bleutée */
+ background:
+ radial-gradient(
+ ellipse 120% 80% at 50% 0%,
+ oklch(0.16 0.02 260) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 100% 60% at 100% 100%,
+ oklch(0.13 0.015 220) 0%,
+ transparent 40%
+ ),
+ oklch(0.08 0.012 260) !important;
}
.page-background.bg-custom-image {
@@ -418,11 +569,34 @@
}
.page-background.bg-custom-image::before,
- .page-background.bg-solid-light::before,
- .page-background.bg-solid-dark::before {
+ .page-background.bg-solid-light::before {
display: none;
}
+ .page-background.bg-solid-dark::before {
+ /* Effet de lumière subtil pour profondeur */
+ content: "";
+ position: fixed;
+ top: -50%;
+ left: -50%;
+ right: -50%;
+ bottom: -50%;
+ z-index: 0;
+ background:
+ radial-gradient(
+ ellipse 60% 40% at 30% 20%,
+ oklch(0.72 0.19 220 / 0.04) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 50% 35% at 70% 70%,
+ oklch(0.72 0.2 165 / 0.03) 0%,
+ transparent 50%
+ );
+ pointer-events: none;
+ opacity: 0.6;
+ }
+
.page-background::before {
content: "";
position: fixed;
@@ -463,67 +637,152 @@
opacity: 1;
}
+ /* ═══════════════════════════════════════════════════════════════════
+ THÈMES DE FOND - Mode Sombre (système)
+ ═══════════════════════════════════════════════════════════════════ */
+
+ /* Neutre sombre - Profondeur élégante */
.dark .page-background.bg-default {
- background: linear-gradient(
- 135deg,
- oklch(0.1 0.015 280) 0%,
- oklch(0.11 0.018 270) 50%,
- oklch(0.1 0.015 290) 100%
- );
+ background:
+ radial-gradient(
+ ellipse 120% 80% at 50% 0%,
+ oklch(0.2 0.025 260) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 100% 60% at 100% 100%,
+ oklch(0.16 0.02 220) 0%,
+ transparent 40%
+ ),
+ oklch(0.1 0.012 260);
}
+ /* Océan sombre - Profondeurs marines */
.dark .page-background.bg-gradient-blue {
- background: linear-gradient(135deg, #0c4a6e 0%, #075985 50%, #0369a1 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 20% 20%,
+ oklch(0.35 0.14 225) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 80% 70%,
+ oklch(0.28 0.12 220) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.15 0.05 230) 0%,
+ oklch(0.12 0.04 225) 50%,
+ oklch(0.08 0.03 220) 100%
+ );
}
+ /* Améthyste sombre - Nuit mystique */
.dark .page-background.bg-gradient-purple {
- background: linear-gradient(135deg, #581c87 0%, #6b21a8 50%, #7c3aed 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 30% 20%,
+ oklch(0.38 0.16 300) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 75% 65%,
+ oklch(0.3 0.14 290) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.16 0.07 300) 0%,
+ oklch(0.12 0.06 295) 50%,
+ oklch(0.08 0.04 290) 100%
+ );
}
+ /* Forêt sombre - Canopée nocturne */
.dark .page-background.bg-gradient-green {
- background: linear-gradient(135deg, #14532d 0%, #166534 50%, #16a34a 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 25% 25%,
+ oklch(0.38 0.14 160) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 70% 70%,
+ oklch(0.3 0.12 150) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.15 0.05 160) 0%,
+ oklch(0.12 0.04 155) 50%,
+ oklch(0.08 0.03 150) 100%
+ );
}
+ /* Aurore sombre - Braises crépusculaires */
.dark .page-background.bg-gradient-orange {
- background: linear-gradient(135deg, #7c2d12 0%, #9a3412 50%, #c2410c 100%);
+ background:
+ radial-gradient(
+ ellipse 80% 50% at 20% 30%,
+ oklch(0.42 0.16 50) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ ellipse 60% 40% at 80% 70%,
+ oklch(0.34 0.14 40) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.18 0.07 60) 0%,
+ oklch(0.14 0.05 50) 50%,
+ oklch(0.08 0.03 45) 100%
+ );
}
+ /* Lumineux en mode sombre - Soft glow */
.dark .page-background.bg-solid-light {
- background: #f8fafc;
+ background:
+ radial-gradient(
+ ellipse 100% 60% at 50% 0%,
+ oklch(1 0 0 / 0.03) 0%,
+ transparent 50%
+ ),
+ linear-gradient(
+ 135deg,
+ oklch(0.98 0.005 260) 0%,
+ oklch(0.96 0.008 260) 100%
+ );
}
+ /* Minuit en mode sombre - Identique (déjà sombre) */
.dark .page-background.bg-solid-dark {
- background: #0f172a !important;
+ background: oklch(0.08 0.015 260) !important;
}
.dark .page-background::before {
+ /* Effet de lumière subtil en mode sombre */
+ content: "";
+ position: fixed;
+ top: -50%;
+ left: -50%;
+ right: -50%;
+ bottom: -50%;
+ z-index: 0;
background:
radial-gradient(
- circle 800px at 10% 20%,
- color-mix(in srgb, var(--primary) 22%, transparent) 0%,
+ ellipse 60% 40% at 30% 20%,
+ color-mix(in srgb, var(--primary) 4%, transparent) 0%,
transparent 50%
),
radial-gradient(
- circle 600px at 90% 80%,
- color-mix(in srgb, var(--chart-2) 18%, transparent) 0%,
+ ellipse 50% 35% at 70% 70%,
+ color-mix(in srgb, var(--chart-2) 3%, transparent) 0%,
transparent 50%
- ),
- radial-gradient(
- circle 500px at 50% 50%,
- color-mix(in srgb, var(--chart-3) 15%, transparent) 0%,
- transparent 60%
- ),
- radial-gradient(
- circle 400px at 20% 70%,
- color-mix(in srgb, var(--chart-4) 12%, transparent) 0%,
- transparent 65%
- ),
- radial-gradient(
- circle 300px at 80% 30%,
- color-mix(in srgb, var(--primary-light) 10%, transparent) 0%,
- transparent 70%
);
- opacity: 1;
+ pointer-events: none;
+ opacity: 0.6;
}
.page-content {
@@ -565,12 +824,14 @@
}
.dark .fintech-card::before {
+ /* Subtile texture grain en mode sombre */
background-image: radial-gradient(
circle at 1px 1px,
- color-mix(in srgb, white 3%, transparent) 1px,
+ oklch(1 0 0 / 0.015) 1px,
transparent 0
);
- opacity: 0.1;
+ background-size: 24px 24px;
+ opacity: 0.8;
}
/* Texture plus prononcée pour les cards de statistiques */
@@ -594,18 +855,14 @@
}
.dark .stat-card-textured::before {
- background-image:
- radial-gradient(
- circle at 1px 1px,
- color-mix(in srgb, white 4%, transparent) 1px,
- transparent 0
- ),
- radial-gradient(
- circle at 11px 11px,
- color-mix(in srgb, white 2%, transparent) 1px,
- transparent 0
- );
- opacity: 0.15;
+ /* Texture grain subtile en mode sombre */
+ background-image: radial-gradient(
+ circle at 1px 1px,
+ oklch(1 0 0 / 0.02) 1px,
+ transparent 0
+ );
+ background-size: 20px 20px;
+ opacity: 0.6;
}
/* Effet glass renforcé pour les cards de contenu */
@@ -616,22 +873,22 @@
}
.dark .fintech-card.card-hover {
- background: color-mix(in srgb, var(--card) 55%, transparent);
- backdrop-filter: blur(80px) saturate(220%) brightness(0.92);
- -webkit-backdrop-filter: blur(80px) saturate(220%) brightness(0.92);
+ background: var(--card-hover);
+ backdrop-filter: blur(20px) saturate(120%);
+ -webkit-backdrop-filter: blur(20px) saturate(120%);
+ border-color: color-mix(in srgb, var(--primary) 20%, var(--border));
}
.dark .fintech-card {
- background: color-mix(in srgb, var(--card) 65%, transparent);
- backdrop-filter: blur(60px) saturate(200%) brightness(0.95);
- -webkit-backdrop-filter: blur(60px) saturate(200%) brightness(0.95);
- border: none;
+ background: var(--card) !important;
+ backdrop-filter: blur(16px) saturate(110%) !important;
+ -webkit-backdrop-filter: blur(16px) saturate(110%) !important;
+ border: 1px solid var(--border) !important;
box-shadow:
- 0 2px 8px 0 color-mix(in srgb, var(--foreground) 12%, transparent),
- 0 8px 24px -4px color-mix(in srgb, var(--primary) 12%, transparent),
- 0 16px 48px -8px color-mix(in srgb, black 50%, transparent),
- inset 0 1px 0 0 color-mix(in srgb, white 12%, transparent),
- inset 0 -1px 0 0 color-mix(in srgb, var(--foreground) 4%, transparent);
+ 0 4px 16px -2px oklch(0 0 0 / 0.4),
+ 0 12px 40px -8px oklch(0 0 0 / 0.3),
+ inset 0 1px 0 0 oklch(1 0 0 / 0.03),
+ inset 0 0 0 1px oklch(1 0 0 / 0.02) !important;
}
.fintech-card::after {
@@ -654,15 +911,17 @@
}
.dark .fintech-card::after {
- opacity: 0.25;
+ /* Subtile ligne de lumière sur le bord supérieur */
+ height: 1px;
background: linear-gradient(
90deg,
transparent 0%,
- color-mix(in srgb, white 30%, transparent) 20%,
- color-mix(in srgb, white 40%, transparent) 50%,
- color-mix(in srgb, white 30%, transparent) 80%,
+ oklch(1 0 0 / 0.06) 20%,
+ oklch(1 0 0 / 0.1) 50%,
+ oklch(1 0 0 / 0.06) 80%,
transparent 100%
);
+ opacity: 1;
}
/* Gradient backgrounds for stat cards - design moderne et subtil */
@@ -694,17 +953,23 @@
}
.dark .stat-card-gradient-1 {
- background: linear-gradient(
- 135deg,
- color-mix(in srgb, var(--primary) 12%, var(--card)) 0%,
- color-mix(in srgb, var(--primary-light) 8%, var(--card)) 50%,
- color-mix(in srgb, var(--primary) 6%, var(--card)) 100%
- );
- border-color: color-mix(in srgb, var(--primary) 30%, var(--border));
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--primary) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--primary) 15%, var(--border)) !important;
}
.dark .stat-card-gradient-1::before {
- opacity: 0.25;
+ background: radial-gradient(
+ ellipse 100% 80% at 100% 0%,
+ color-mix(in srgb, var(--primary) 6%, transparent) 0%,
+ transparent 60%
+ );
+ opacity: 1;
}
.stat-card-gradient-2 {
@@ -735,17 +1000,23 @@
}
.dark .stat-card-gradient-2 {
- background: linear-gradient(
- 135deg,
- color-mix(in srgb, var(--success) 12%, var(--card)) 0%,
- color-mix(in srgb, var(--success) 8%, var(--card)) 50%,
- color-mix(in srgb, var(--success) 6%, var(--card)) 100%
- );
- border-color: color-mix(in srgb, var(--success) 30%, var(--border));
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--success) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--success) 15%, var(--border)) !important;
}
.dark .stat-card-gradient-2::before {
- opacity: 0.25;
+ background: radial-gradient(
+ ellipse 100% 80% at 100% 0%,
+ color-mix(in srgb, var(--success) 6%, transparent) 0%,
+ transparent 60%
+ );
+ opacity: 1;
}
.stat-card-gradient-3 {
@@ -776,17 +1047,23 @@
}
.dark .stat-card-gradient-3 {
- background: linear-gradient(
- 135deg,
- color-mix(in srgb, var(--destructive) 12%, var(--card)) 0%,
- color-mix(in srgb, var(--destructive) 8%, var(--card)) 50%,
- color-mix(in srgb, var(--destructive) 6%, var(--card)) 100%
- );
- border-color: color-mix(in srgb, var(--destructive) 30%, var(--border));
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--destructive) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--destructive) 15%, var(--border)) !important;
}
.dark .stat-card-gradient-3::before {
- opacity: 0.25;
+ background: radial-gradient(
+ ellipse 100% 80% at 100% 0%,
+ color-mix(in srgb, var(--destructive) 6%, transparent) 0%,
+ transparent 60%
+ );
+ opacity: 1;
}
.stat-card-gradient-4 {
@@ -817,17 +1094,23 @@
}
.dark .stat-card-gradient-4 {
- background: linear-gradient(
- 135deg,
- color-mix(in srgb, var(--chart-4) 12%, var(--card)) 0%,
- color-mix(in srgb, var(--chart-4) 8%, var(--card)) 50%,
- color-mix(in srgb, var(--chart-4) 6%, var(--card)) 100%
- );
- border-color: color-mix(in srgb, var(--chart-4) 30%, var(--border));
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--chart-4) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--chart-4) 15%, var(--border)) !important;
}
.dark .stat-card-gradient-4::before {
- opacity: 0.25;
+ background: radial-gradient(
+ ellipse 100% 80% at 100% 0%,
+ color-mix(in srgb, var(--chart-4) 6%, transparent) 0%,
+ transparent 60%
+ );
+ opacity: 1;
}
.stat-card-gradient-5 {
@@ -858,16 +1141,193 @@
}
.dark .stat-card-gradient-5 {
- background: linear-gradient(
- 135deg,
- color-mix(in srgb, var(--chart-5) 12%, var(--card)) 0%,
- color-mix(in srgb, var(--chart-5) 8%, var(--card)) 50%,
- color-mix(in srgb, var(--chart-5) 6%, var(--card)) 100%
- );
- border-color: color-mix(in srgb, var(--chart-5) 30%, var(--border));
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--chart-5) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--chart-5) 15%, var(--border)) !important;
}
.dark .stat-card-gradient-5::before {
- opacity: 0.25;
+ background: radial-gradient(
+ ellipse 100% 80% at 100% 0%,
+ color-mix(in srgb, var(--chart-5) 6%, transparent) 0%,
+ transparent 60%
+ );
+ opacity: 1;
+ }
+
+ /* Force la couleur des titres en mode sombre */
+ .dark h1,
+ .dark h2,
+ .dark h3,
+ .dark h4,
+ .dark h5,
+ .dark h6,
+ .dark .text-foreground,
+ html.dark h1,
+ html.dark h2,
+ html.dark h3,
+ html.dark h4,
+ html.dark h5,
+ html.dark h6,
+ html.dark .text-foreground {
+ color: var(--foreground) !important;
+ }
+
+ /* ═══════════════════════════════════════════════════════════════════
+ FOND SOLIDE SOMBRE - Force le thème sombre complet
+ ═══════════════════════════════════════════════════════════════════ */
+ .page-background.bg-solid-dark {
+ /* Forcer toutes les variables du thème sombre */
+ --background: oklch(0.12 0.008 260);
+ --foreground: oklch(0.95 0.005 260);
+ --card: oklch(0.15 0.01 260);
+ --card-foreground: oklch(0.95 0.005 260);
+ --card-hover: oklch(0.18 0.012 260);
+ --popover: oklch(0.13 0.01 260);
+ --popover-foreground: oklch(0.95 0.005 260);
+ --primary: oklch(0.72 0.19 220);
+ --primary-foreground: oklch(0.12 0.008 260);
+ --primary-light: oklch(0.78 0.16 220);
+ --secondary: oklch(0.2 0.012 260);
+ --secondary-foreground: oklch(0.9 0.005 260);
+ --muted: oklch(0.18 0.01 260);
+ --muted-foreground: oklch(0.6 0.015 260);
+ --accent: oklch(0.22 0.015 260);
+ --accent-foreground: oklch(0.72 0.19 220);
+ --destructive: oklch(0.65 0.22 25);
+ --destructive-foreground: oklch(0.98 0 0);
+ --border: oklch(0.25 0.01 260);
+ --input: oklch(0.16 0.01 260);
+ --ring: oklch(0.72 0.19 220 / 0.6);
+ --success: oklch(0.72 0.2 165);
+ --success-foreground: oklch(0.12 0.008 260);
+ --warning: oklch(0.8 0.18 85);
+ --warning-foreground: oklch(0.15 0.01 85);
+ --chart-1: oklch(0.72 0.19 220);
+ --chart-2: oklch(0.72 0.2 165);
+ --chart-3: oklch(0.8 0.18 85);
+ --chart-4: oklch(0.7 0.22 300);
+ --chart-5: oklch(0.68 0.2 350);
+ --green: oklch(0.72 0.2 165);
+ --blue: oklch(0.72 0.19 220);
+ --gray: oklch(0.55 0.01 260);
+ --gray-light: oklch(0.3 0.008 260);
+ --card-column: oklch(0.14 0.008 260);
+ --sidebar: oklch(0.1 0.01 260);
+ --sidebar-foreground: oklch(0.9 0.005 260);
+ --sidebar-primary: oklch(0.72 0.19 220);
+ --sidebar-primary-foreground: oklch(0.12 0.008 260);
+ --sidebar-accent: oklch(0.18 0.012 260);
+ --sidebar-accent-foreground: oklch(0.9 0.005 260);
+ --sidebar-border: oklch(0.2 0.01 260);
+ --sidebar-ring: oklch(0.72 0.19 220 / 0.5);
+ }
+
+ /* Cards avec effet glass subtil en mode solid-dark */
+ .page-background.bg-solid-dark .fintech-card {
+ background: var(--card) !important;
+ backdrop-filter: blur(16px) saturate(110%) !important;
+ -webkit-backdrop-filter: blur(16px) saturate(110%) !important;
+ border: 1px solid var(--border) !important;
+ box-shadow:
+ 0 4px 16px -2px oklch(0 0 0 / 0.4),
+ 0 12px 40px -8px oklch(0 0 0 / 0.3),
+ inset 0 1px 0 0 oklch(1 0 0 / 0.03),
+ inset 0 0 0 1px oklch(1 0 0 / 0.02) !important;
+ }
+
+ .page-background.bg-solid-dark .fintech-card::before {
+ background-image: radial-gradient(
+ circle at 1px 1px,
+ oklch(1 0 0 / 0.015) 1px,
+ transparent 0
+ );
+ background-size: 24px 24px;
+ opacity: 0.8;
+ }
+
+ .page-background.bg-solid-dark .fintech-card::after {
+ height: 1px;
+ background: linear-gradient(
+ 90deg,
+ transparent 0%,
+ oklch(1 0 0 / 0.06) 20%,
+ oklch(1 0 0 / 0.1) 50%,
+ oklch(1 0 0 / 0.06) 80%,
+ transparent 100%
+ );
+ opacity: 1;
+ }
+
+ /* Glass effect en mode solid-dark */
+ .page-background.bg-solid-dark .glass {
+ background: oklch(0.12 0.01 260 / 0.9);
+ backdrop-filter: blur(24px) saturate(140%);
+ -webkit-backdrop-filter: blur(24px) saturate(140%);
+ border-color: oklch(1 0 0 / 0.08);
+ box-shadow:
+ 0 8px 32px -8px oklch(0 0 0 / 0.5),
+ inset 0 1px 0 0 oklch(1 0 0 / 0.05);
+ }
+
+ /* Stat cards avec glow subtil en mode solid-dark */
+ .page-background.bg-solid-dark .stat-card-gradient-1 {
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--primary) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--primary) 15%, var(--border)) !important;
+ }
+
+ .page-background.bg-solid-dark .stat-card-gradient-2 {
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--success) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--success) 15%, var(--border)) !important;
+ }
+
+ .page-background.bg-solid-dark .stat-card-gradient-3 {
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--destructive) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--destructive) 15%, var(--border)) !important;
+ }
+
+ .page-background.bg-solid-dark .stat-card-gradient-4 {
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--chart-4) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--chart-4) 15%, var(--border)) !important;
+ }
+
+ .page-background.bg-solid-dark .stat-card-gradient-5 {
+ background:
+ radial-gradient(
+ ellipse 80% 60% at 85% 20%,
+ color-mix(in srgb, var(--chart-5) 8%, transparent) 0%,
+ transparent 50%
+ ),
+ var(--card) !important;
+ border: 1px solid color-mix(in srgb, var(--chart-5) 15%, var(--border)) !important;
}
}
diff --git a/app/layout.tsx b/app/layout.tsx
index 398513b..68f4072 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -5,6 +5,7 @@ import "./globals.css";
import { AuthSessionProvider } from "@/components/providers/session-provider";
import { QueryProvider } from "@/components/providers/query-provider";
import { BackgroundProvider } from "@/components/providers/background-provider";
+import { ThemeProvider } from "@/components/theme-provider";
const _geist = Geist({ subsets: ["latin"] });
const _geistMono = Geist_Mono({ subsets: ["latin"] });
@@ -22,12 +23,19 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
+
-
-
- {children}
-
+
+
+
+ {children}
+
+
);
diff --git a/components/accounts/account-card.tsx b/components/accounts/account-card.tsx
index 26e155c..f50cdbd 100644
--- a/components/accounts/account-card.tsx
+++ b/components/accounts/account-card.tsx
@@ -188,7 +188,7 @@ export function AccountCard({
? "text-base"
: "text-xl",
!compact && !isMobile && "mb-1.5",
- realBalance >= 0 ? "text-emerald-600" : "text-red-600",
+ realBalance >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(realBalance)}
diff --git a/components/categories/parent-category-row.tsx b/components/categories/parent-category-row.tsx
index 5bffb8b..422edb6 100644
--- a/components/categories/parent-category-row.tsx
+++ b/components/categories/parent-category-row.tsx
@@ -125,7 +125,7 @@ export function ParentCategoryRow({
onDelete(parent.id)}
- className="text-red-600"
+ className="text-destructive"
>
Supprimer
diff --git a/components/dashboard/accounts-summary.tsx b/components/dashboard/accounts-summary.tsx
index a2860ae..ad951cb 100644
--- a/components/dashboard/accounts-summary.tsx
+++ b/components/dashboard/accounts-summary.tsx
@@ -89,7 +89,7 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
= 0 ? "text-emerald-600" : "text-red-600",
+ folderTotal >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(folderTotal)}
@@ -131,8 +131,8 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
className={cn(
"font-bold tabular-nums text-base",
realBalance >= 0
- ? "text-emerald-600 dark:text-emerald-400"
- : "text-red-600 dark:text-red-400",
+ ? "text-success"
+ : "text-destructive",
)}
>
{formatCurrency(realBalance)}
@@ -204,7 +204,7 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
= 0 ? "text-emerald-600" : "text-red-600",
+ orphanTotal >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(orphanTotal)}
@@ -245,8 +245,8 @@ export function AccountsSummary({ data }: AccountsSummaryProps) {
className={cn(
"font-bold tabular-nums text-base",
realBalance >= 0
- ? "text-emerald-600 dark:text-emerald-400"
- : "text-red-600 dark:text-red-400",
+ ? "text-success"
+ : "text-destructive",
)}
>
{formatCurrency(realBalance)}
diff --git a/components/dashboard/overview-cards.tsx b/components/dashboard/overview-cards.tsx
index 50b5a8e..58b9b69 100644
--- a/components/dashboard/overview-cards.tsx
+++ b/components/dashboard/overview-cards.tsx
@@ -60,7 +60,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
{/* Icône en arrière-plan */}
-
+
@@ -73,8 +73,8 @@ export function OverviewCards({ data }: OverviewCardsProps) {
className={cn(
"text-2xl sm:text-3xl md:text-3xl lg:text-2xl xl:text-3xl font-black tracking-tight mb-3 leading-tight break-words",
totalBalance >= 0
- ? "text-emerald-600 dark:text-emerald-400"
- : "text-red-600 dark:text-red-400"
+ ? "text-success"
+ : "text-destructive"
)}
>
{formatCurrency(totalBalance)}
@@ -87,7 +87,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
{/* Icône en arrière-plan */}
-
+
@@ -110,7 +110,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
{/* Icône en arrière-plan */}
-
+
@@ -133,7 +133,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
{/* Icône en arrière-plan */}
-
+
@@ -153,7 +153,7 @@ export function OverviewCards({ data }: OverviewCardsProps) {
{/* Icône en arrière-plan */}
-
+
diff --git a/components/dashboard/recent-transactions.tsx b/components/dashboard/recent-transactions.tsx
index 17d0cd9..3017181 100644
--- a/components/dashboard/recent-transactions.tsx
+++ b/components/dashboard/recent-transactions.tsx
@@ -88,8 +88,8 @@ export function RecentTransactions({ data }: RecentTransactionsProps) {
className={cn(
"font-black tabular-nums text-sm md:text-base shrink-0 md:hidden",
transaction.amount >= 0
- ? "text-emerald-600 dark:text-emerald-400"
- : "text-red-600 dark:text-red-400"
+ ? "text-success"
+ : "text-destructive"
)}
>
{transaction.amount >= 0 ? "+" : ""}
@@ -130,8 +130,8 @@ export function RecentTransactions({ data }: RecentTransactionsProps) {
className={cn(
"font-black tabular-nums text-base md:text-lg shrink-0 hidden md:block leading-tight",
transaction.amount >= 0
- ? "text-emerald-600 dark:text-emerald-400"
- : "text-red-600 dark:text-red-400"
+ ? "text-success"
+ : "text-destructive"
)}
>
{transaction.amount >= 0 ? "+" : ""}
diff --git a/components/dashboard/sidebar.tsx b/components/dashboard/sidebar.tsx
index 05f62d9..a52e869 100644
--- a/components/dashboard/sidebar.tsx
+++ b/components/dashboard/sidebar.tsx
@@ -88,20 +88,17 @@ function SidebarContent({
"w-full justify-start gap-4 h-12 rounded-2xl",
isActive &&
"bg-gradient-to-r from-primary/15 via-primary/10 to-primary/5 border-2 border-primary/30 shadow-lg shadow-primary/10 backdrop-blur-sm",
- collapsed && "justify-center px-2 w-12 mx-auto",
+ collapsed && "justify-center px-2 w-12 mx-auto"
)}
>
{!collapsed && (
{item.label}
@@ -116,7 +113,7 @@ function SidebarContent({
@@ -124,7 +121,7 @@ function SidebarContent({
variant="ghost"
className={cn(
"w-full justify-start gap-4 h-12 rounded-2xl",
- collapsed && "justify-center px-2 w-12 mx-auto",
+ collapsed && "justify-center px-2 w-12 mx-auto"
)}
>
@@ -139,7 +136,7 @@ function SidebarContent({
className={cn(
"w-full justify-start gap-4 h-12 rounded-2xl",
"text-destructive",
- collapsed && "justify-center px-2 w-12 mx-auto",
+ collapsed && "justify-center px-2 w-12 mx-auto"
)}
>
@@ -164,7 +161,10 @@ export function Sidebar({ open, onOpenChange }: SidebarProps) {
if (isMobile) {
return (
-
+
Navigation
{!collapsed && (
@@ -205,10 +205,7 @@ export function Sidebar({ open, onOpenChange }: SidebarProps) {
variant="ghost"
size="icon"
onClick={() => setCollapsed(!collapsed)}
- className={cn(
- "rounded-xl",
- collapsed ? "" : "ml-auto",
- )}
+ className={cn("rounded-xl", collapsed ? "" : "ml-auto")}
>
{collapsed ? (
diff --git a/components/folders/draggable-account-item.tsx b/components/folders/draggable-account-item.tsx
index 4e4182f..7817792 100644
--- a/components/folders/draggable-account-item.tsx
+++ b/components/folders/draggable-account-item.tsx
@@ -74,7 +74,7 @@ export function DraggableAccountItem({
= 0 ? "text-emerald-600" : "text-red-600",
+ realBalance >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(realBalance)}
diff --git a/components/folders/draggable-folder-item.tsx b/components/folders/draggable-folder-item.tsx
index f5c7c0c..6b8c495 100644
--- a/components/folders/draggable-folder-item.tsx
+++ b/components/folders/draggable-folder-item.tsx
@@ -120,7 +120,7 @@ export function DraggableFolderItem({
= 0 ? "text-emerald-600" : "text-red-600",
+ folderTotal >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(folderTotal)}
@@ -145,7 +145,7 @@ export function DraggableFolderItem({
{folder.id !== "folder-root" && (
onDelete(folder.id)}
- className="text-red-600"
+ className="text-destructive"
>
Supprimer
diff --git a/components/import/ofx-import-dialog.tsx b/components/import/ofx-import-dialog.tsx
index 22a7dad..44caa51 100644
--- a/components/import/ofx-import-dialog.tsx
+++ b/components/import/ofx-import-dialog.tsx
@@ -505,9 +505,9 @@ export function OFXImportDialog({
{importResults.map((result, i) => (
{result.error ? (
-
+
) : (
-
+
)}
{result.fileName}
{!result.error && (
@@ -524,16 +524,16 @@ export function OFXImportDialog({
{step === "success" && (
-
+
{importResults.length > 1 && (
{importResults.map((result, i) => (
{result.error ? (
-
+
) : (
-
+
)}
@@ -544,7 +544,7 @@ export function OFXImportDialog({
{result.error ? (
-
+
{result.error}
) : (
@@ -559,7 +559,7 @@ export function OFXImportDialog({
)}
{errorCount > 0 && (
-
+
{errorCount} fichier{errorCount > 1 ? "s" : ""} en erreur
)}
@@ -572,7 +572,7 @@ export function OFXImportDialog({
{step === "error" && (
-
+
)}
diff --git a/components/layout/page-header.tsx b/components/layout/page-header.tsx
index 4bbd1a4..ab313e6 100644
--- a/components/layout/page-header.tsx
+++ b/components/layout/page-header.tsx
@@ -1,6 +1,6 @@
"use client";
-import { ReactNode } from "react";
+import { ReactNode, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Menu } from "lucide-react";
import { useSidebarContext } from "@/components/layout/sidebar-context";
@@ -21,6 +21,30 @@ export function PageHeader({
}: PageHeaderProps) {
const { setOpen } = useSidebarContext();
const isMobile = useIsMobile();
+ const [textColor, setTextColor] = useState("var(--foreground)");
+
+ useEffect(() => {
+ const checkDarkBackground = () => {
+ const pageBackground = document.querySelector(".page-background");
+ if (pageBackground?.classList.contains("bg-solid-dark")) {
+ setTextColor("#f5f5f5");
+ } else {
+ setTextColor("var(--foreground)");
+ }
+ };
+
+ checkDarkBackground();
+ const observer = new MutationObserver(checkDarkBackground);
+ const pageBackground = document.querySelector(".page-background");
+ if (pageBackground) {
+ observer.observe(pageBackground, {
+ attributes: true,
+ attributeFilter: ["class"],
+ });
+ }
+
+ return () => observer.disconnect();
+ }, []);
return (
@@ -37,7 +61,13 @@ export function PageHeader({
)}
-
+
{title}
{rightContent &&
{rightContent}
}
diff --git a/components/rules/rule-create-dialog.tsx b/components/rules/rule-create-dialog.tsx
index 979775c..f5b3395 100644
--- a/components/rules/rule-create-dialog.tsx
+++ b/components/rules/rule-create-dialog.tsx
@@ -133,7 +133,7 @@ export function RuleCreateDialog({
catégorisées.
{existingCategory && (
-
+
Ce mot-clé existe déjà dans "{existingCategory.name}
diff --git a/components/settings/background-card.tsx b/components/settings/background-card.tsx
index 711542f..af0dee7 100644
--- a/components/settings/background-card.tsx
+++ b/components/settings/background-card.tsx
@@ -35,42 +35,49 @@ const DEFAULT_BACKGROUNDS: Array<{
value: BackgroundType;
label: string;
preview: string;
+ description?: string;
}> = [
{
value: "default",
- label: "Par défaut",
- preview:
- "linear-gradient(135deg, oklch(0.98 0.01 280) 0%, oklch(0.97 0.012 270) 50%, oklch(0.98 0.01 290) 100%)",
+ label: "Neutre",
+ preview: "linear-gradient(135deg, oklch(0.985 0 0) 0%, oklch(0.97 0.005 260) 50%, oklch(0.985 0 0) 100%)",
+ description: "Fond neutre et élégant",
},
{
value: "gradient-blue",
- label: "Dégradé bleu",
- preview: "linear-gradient(135deg, #e0f2fe 0%, #bae6fd 50%, #7dd3fc 100%)",
+ label: "Océan",
+ preview: "linear-gradient(135deg, oklch(0.95 0.03 230) 0%, oklch(0.88 0.08 225) 50%, oklch(0.78 0.12 220) 100%)",
+ description: "Dégradé bleu apaisant",
},
{
value: "gradient-purple",
- label: "Dégradé violet",
- preview: "linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 50%, #d8b4fe 100%)",
+ label: "Améthyste",
+ preview: "linear-gradient(135deg, oklch(0.95 0.04 300) 0%, oklch(0.88 0.1 295) 50%, oklch(0.78 0.15 290) 100%)",
+ description: "Dégradé violet sophistiqué",
},
{
value: "gradient-green",
- label: "Dégradé vert",
- preview: "linear-gradient(135deg, #dcfce7 0%, #bbf7d0 50%, #86efac 100%)",
+ label: "Forêt",
+ preview: "linear-gradient(135deg, oklch(0.95 0.04 160) 0%, oklch(0.88 0.1 155) 50%, oklch(0.78 0.14 150) 100%)",
+ description: "Dégradé vert naturel",
},
{
value: "gradient-orange",
- label: "Dégradé orange",
- preview: "linear-gradient(135deg, #fff7ed 0%, #ffedd5 50%, #fed7aa 100%)",
+ label: "Aurore",
+ preview: "linear-gradient(135deg, oklch(0.97 0.03 80) 0%, oklch(0.92 0.08 60) 50%, oklch(0.85 0.14 45) 100%)",
+ description: "Dégradé orange chaleureux",
},
{
value: "solid-light",
- label: "Solide clair",
- preview: "#ffffff",
+ label: "Lumineux",
+ preview: "linear-gradient(135deg, oklch(1 0 0) 0%, oklch(0.98 0.005 260) 100%)",
+ description: "Fond blanc épuré",
},
{
value: "solid-dark",
- label: "Solide sombre",
- preview: "#1e293b",
+ label: "Minuit",
+ preview: "linear-gradient(135deg, oklch(0.18 0.02 260) 0%, oklch(0.08 0.015 250) 100%)",
+ description: "Fond sombre immersif",
},
];
diff --git a/components/settings/danger-zone-card.tsx b/components/settings/danger-zone-card.tsx
index 0f38791..e31dab6 100644
--- a/components/settings/danger-zone-card.tsx
+++ b/components/settings/danger-zone-card.tsx
@@ -46,7 +46,7 @@ export function DangerZoneCard({
const result = await onDeduplicate();
if (result.deletedCount > 0) {
alert(
- `${result.deletedCount} transaction${result.deletedCount > 1 ? "s" : ""} en double supprimée${result.deletedCount > 1 ? "s" : ""}`,
+ `${result.deletedCount} transaction${result.deletedCount > 1 ? "s" : ""} en double supprimée${result.deletedCount > 1 ? "s" : ""}`
);
} else {
alert("Aucun doublon trouvé");
@@ -59,9 +59,9 @@ export function DangerZoneCard({
}
};
return (
-
+
-
+
Zone dangereuse
diff --git a/components/statistics/savings-trend-chart.tsx b/components/statistics/savings-trend-chart.tsx
index d5f2286..9410b5d 100644
--- a/components/statistics/savings-trend-chart.tsx
+++ b/components/statistics/savings-trend-chart.tsx
@@ -36,13 +36,13 @@ export function SavingsTrendChart({
Évolution des économies
{isPositive ? (
-
+
) : (
-
+
)}
{formatCurrency(latestSavings)}
diff --git a/components/statistics/stats-summary-cards.tsx b/components/statistics/stats-summary-cards.tsx
index fa10a7a..19a3457 100644
--- a/components/statistics/stats-summary-cards.tsx
+++ b/components/statistics/stats-summary-cards.tsx
@@ -23,8 +23,8 @@ export function StatsSummaryCards({
{/* Icône en arrière-plan */}
-
-
+
+
@@ -32,7 +32,7 @@ export function StatsSummaryCards({
-
+
{formatCurrency(totalIncome)}
@@ -40,8 +40,8 @@ export function StatsSummaryCards({
{/* Icône en arrière-plan */}
-
-
+
+
@@ -49,7 +49,7 @@ export function StatsSummaryCards({
-
+
{formatCurrency(totalExpenses)}
@@ -57,7 +57,7 @@ export function StatsSummaryCards({
{/* Icône en arrière-plan */}
-
+
@@ -74,12 +74,12 @@ export function StatsSummaryCards({
{/* Icône en arrière-plan */}
-
+
= 0
- ? "border-emerald-600 dark:border-emerald-400"
- : "border-red-600 dark:border-red-400"
+ ? "border-success"
+ : "border-destructive"
)} />
@@ -91,7 +91,7 @@ export function StatsSummaryCards({
= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400",
+ savings >= 0 ? "text-success" : "text-destructive",
)}
>
{formatCurrency(savings)}
diff --git a/components/statistics/top-expenses-list.tsx b/components/statistics/top-expenses-list.tsx
index 15113ed..c921d44 100644
--- a/components/statistics/top-expenses-list.tsx
+++ b/components/statistics/top-expenses-list.tsx
@@ -45,7 +45,7 @@ export function TopExpensesList({
{expense.description}
-
+
{formatCurrency(expense.amount)}
diff --git a/components/transactions/transaction-table.tsx b/components/transactions/transaction-table.tsx
index 501078d..3e946c2 100644
--- a/components/transactions/transaction-table.tsx
+++ b/components/transactions/transaction-table.tsx
@@ -227,7 +227,7 @@ export function TransactionTable({
);
return (
-
+
{transactions.length === 0 ? (
@@ -323,8 +323,8 @@ export function TransactionTable({
className={cn(
"font-semibold tabular-nums text-base md:text-base shrink-0",
transaction.amount >= 0
- ? "text-emerald-600"
- : "text-red-600"
+ ? "text-success"
+ : "text-destructive"
)}
>
{transaction.amount >= 0 ? "+" : ""}
@@ -398,7 +398,7 @@ export function TransactionTable({
onDelete(transaction.id);
}
}}
- className="text-red-600 focus:text-red-600"
+ className="text-destructive focus:text-destructive"
>
Supprimer
@@ -576,8 +576,8 @@ export function TransactionTable({
className={cn(
"p-3 text-right font-semibold tabular-nums",
transaction.amount >= 0
- ? "text-emerald-600"
- : "text-red-600"
+ ? "text-success"
+ : "text-destructive"
)}
>
{transaction.amount >= 0 ? "+" : ""}
@@ -592,7 +592,7 @@ export function TransactionTable({
className="p-1 hover:bg-muted rounded"
>
{transaction.isReconciled ? (
-
+
) : (
)}
@@ -650,7 +650,7 @@ export function TransactionTable({
onDelete(transaction.id);
}
}}
- className="text-red-600 focus:text-red-600"
+ className="text-destructive focus:text-destructive"
>
Supprimer
diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx
index 46f988c..9fd4b82 100644
--- a/components/ui/badge.tsx
+++ b/components/ui/badge.tsx
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
- "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
+ "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/30 aria-invalid:border-destructive overflow-hidden",
{
variants: {
variant: {
@@ -14,7 +14,7 @@ const badgeVariants = cva(
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
destructive:
- "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ "border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/30",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},
@@ -22,7 +22,7 @@ const badgeVariants = cva(
defaultVariants: {
variant: "default",
},
- },
+ }
);
function Badge({
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
index 2716ff9..9d7a577 100644
--- a/components/ui/button.tsx
+++ b/components/ui/button.tsx
@@ -5,16 +5,16 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-semibold disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-semibold disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/30 aria-invalid:border-destructive",
{
variants: {
variant: {
default:
"bg-gradient-to-r from-primary via-primary/95 to-primary/90 text-primary-foreground shadow-xl shadow-primary/30 backdrop-blur-sm border border-primary/20",
destructive:
- "bg-gradient-to-r from-destructive via-destructive/95 to-destructive/90 text-white shadow-xl shadow-destructive/30 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 backdrop-blur-sm border border-destructive/20",
+ "bg-gradient-to-r from-destructive via-destructive/95 to-destructive/90 text-destructive-foreground shadow-xl shadow-destructive/30 focus-visible:ring-destructive/30 backdrop-blur-sm border border-destructive/20",
outline:
- "border-2 bg-background/95 backdrop-blur-md shadow-md dark:bg-input/40 dark:border-input",
+ "border-2 bg-background/95 backdrop-blur-md shadow-md border-border",
secondary:
"bg-gradient-to-r from-secondary via-secondary/95 to-secondary/90 text-secondary-foreground backdrop-blur-sm",
ghost: "backdrop-blur-sm",
diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx
index bf22032..28ea3ed 100644
--- a/components/ui/calendar.tsx
+++ b/components/ui/calendar.tsx
@@ -201,7 +201,7 @@ function CalendarDayButton({
data-range-end={modifiers.range_end}
data-range-middle={modifiers.range_middle}
className={cn(
- "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
+ "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
defaultClassNames.day,
className,
)}
diff --git a/components/ui/checkbox.tsx b/components/ui/checkbox.tsx
index ae02cf5..53646e1 100644
--- a/components/ui/checkbox.tsx
+++ b/components/ui/checkbox.tsx
@@ -14,8 +14,8 @@ function Checkbox({
diff --git a/components/ui/context-menu.tsx b/components/ui/context-menu.tsx
index ab7a5d0..6399d5d 100644
--- a/components/ui/context-menu.tsx
+++ b/components/ui/context-menu.tsx
@@ -126,7 +126,7 @@ function ContextMenuItem({
data-inset={inset}
data-variant={variant}
className={cn(
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/15 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
diff --git a/components/ui/dialog.tsx b/components/ui/dialog.tsx
index 4f877c8..5655ddf 100644
--- a/components/ui/dialog.tsx
+++ b/components/ui/dialog.tsx
@@ -39,7 +39,7 @@ function DialogOverlay({
data-slot="dialog-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
- className,
+ className
)}
{...props}
/>
@@ -60,8 +60,8 @@ function DialogContent({
@@ -96,7 +96,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
data-slot="dialog-footer"
className={cn(
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
- className,
+ className
)}
{...props}
/>
diff --git a/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx
index 8086084..b670e87 100644
--- a/components/ui/dropdown-menu.tsx
+++ b/components/ui/dropdown-menu.tsx
@@ -76,7 +76,7 @@ function DropdownMenuItem({
data-inset={inset}
data-variant={variant}
className={cn(
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/15 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
diff --git a/components/ui/field.tsx b/components/ui/field.tsx
index 9802658..1e01837 100644
--- a/components/ui/field.tsx
+++ b/components/ui/field.tsx
@@ -117,7 +117,7 @@ function FieldLabel({
className={cn(
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
- "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
+ "has-data-[state=checked]:bg-primary/8 has-data-[state=checked]:border-primary",
className,
)}
{...props}
diff --git a/components/ui/input-group.tsx b/components/ui/input-group.tsx
index 0571e0c..9345f11 100644
--- a/components/ui/input-group.tsx
+++ b/components/ui/input-group.tsx
@@ -13,7 +13,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
data-slot="input-group"
role="group"
className={cn(
- "group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none",
+ "group/input-group border-input bg-input relative flex w-full items-center rounded-md border shadow-xs outline-none",
"h-9 has-[>textarea]:h-auto",
// Variants based on alignment.
@@ -26,7 +26,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
// Error state.
- "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
+ "has-[[data-slot][aria-invalid=true]]:ring-destructive/30 has-[[data-slot][aria-invalid=true]]:border-destructive",
className,
)}
@@ -135,7 +135,7 @@ function InputGroupInput({
) {
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground",
- "dark:bg-input/40 border-input h-9 w-full min-w-0 rounded-lg border bg-background/50 backdrop-blur-sm px-3 py-1 text-base",
- "shadow-sm transition-all duration-200 outline-none",
+ "bg-input border-border h-9 w-full min-w-0 rounded-lg border backdrop-blur-sm px-3 py-1 text-base",
+ "shadow-sm outline-none",
"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium",
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-primary/50 focus-visible:ring-primary/20 focus-visible:ring-[3px] focus-visible:shadow-md focus-visible:shadow-primary/10",
"hover:border-primary/30 hover:shadow-sm",
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
- className,
+ "aria-invalid:ring-destructive/30 aria-invalid:border-destructive",
+ className
)}
{...props}
/>
diff --git a/components/ui/kbd.tsx b/components/ui/kbd.tsx
index bde3abb..2c1cac4 100644
--- a/components/ui/kbd.tsx
+++ b/components/ui/kbd.tsx
@@ -7,8 +7,8 @@ function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
className={cn(
"bg-muted w-fit text-muted-foreground pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none",
"[&_svg:not([class*='size-'])]:size-3",
- "[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
- className,
+ "[[data-slot=tooltip-content]_&]:bg-background/15 [[data-slot=tooltip-content]_&]:text-background",
+ className
)}
{...props}
/>
diff --git a/components/ui/menubar.tsx b/components/ui/menubar.tsx
index 803094a..ddee644 100644
--- a/components/ui/menubar.tsx
+++ b/components/ui/menubar.tsx
@@ -103,7 +103,7 @@ function MenubarItem({
data-inset={inset}
data-variant={variant}
className={cn(
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/15 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
diff --git a/components/ui/radio-group.tsx b/components/ui/radio-group.tsx
index bc5495a..032c9b9 100644
--- a/components/ui/radio-group.tsx
+++ b/components/ui/radio-group.tsx
@@ -27,7 +27,7 @@ function RadioGroupItem({
diff --git a/components/ui/tabs.tsx b/components/ui/tabs.tsx
index 469a958..ba37107 100644
--- a/components/ui/tabs.tsx
+++ b/components/ui/tabs.tsx
@@ -42,7 +42,7 @@ function TabsTrigger({
) {
data-slot="textarea"
className={cn(
"border-input placeholder:text-muted-foreground",
- "dark:bg-input/40 flex field-sizing-content min-h-16 w-full rounded-lg border bg-background/50 backdrop-blur-sm px-3 py-2 text-base",
- "shadow-sm transition-all duration-200 outline-none",
+ "bg-input flex field-sizing-content min-h-16 w-full rounded-lg border backdrop-blur-sm px-3 py-2 text-base",
+ "shadow-sm outline-none",
"focus-visible:border-primary/50 focus-visible:ring-primary/20 focus-visible:ring-[3px] focus-visible:shadow-md focus-visible:shadow-primary/10",
"hover:border-primary/30 hover:shadow-sm",
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ "aria-invalid:ring-destructive/30 aria-invalid:border-destructive",
"disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
diff --git a/components/ui/toggle.tsx b/components/ui/toggle.tsx
index 47517bd..d6c6856 100644
--- a/components/ui/toggle.tsx
+++ b/components/ui/toggle.tsx
@@ -7,7 +7,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const toggleVariants = cva(
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none aria-invalid:ring-destructive/30 aria-invalid:border-destructive whitespace-nowrap",
{
variants: {
variant: {
diff --git a/styles/globals.css b/styles/globals.css
deleted file mode 100644
index 840b33f..0000000
--- a/styles/globals.css
+++ /dev/null
@@ -1,125 +0,0 @@
-@import "tailwindcss";
-@import "tw-animate-css";
-
-@custom-variant dark (&:is(.dark *));
-
-:root {
- --background: oklch(1 0 0);
- --foreground: oklch(0.145 0 0);
- --card: oklch(1 0 0);
- --card-foreground: oklch(0.145 0 0);
- --popover: oklch(1 0 0);
- --popover-foreground: oklch(0.145 0 0);
- --primary: oklch(0.205 0 0);
- --primary-foreground: oklch(0.985 0 0);
- --secondary: oklch(0.97 0 0);
- --secondary-foreground: oklch(0.205 0 0);
- --muted: oklch(0.97 0 0);
- --muted-foreground: oklch(0.556 0 0);
- --accent: oklch(0.97 0 0);
- --accent-foreground: oklch(0.205 0 0);
- --destructive: oklch(0.577 0.245 27.325);
- --destructive-foreground: oklch(0.577 0.245 27.325);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
- --ring: oklch(0.708 0 0);
- --chart-1: oklch(0.646 0.222 41.116);
- --chart-2: oklch(0.6 0.118 184.704);
- --chart-3: oklch(0.398 0.07 227.392);
- --chart-4: oklch(0.828 0.189 84.429);
- --chart-5: oklch(0.769 0.188 70.08);
- --radius: 0.625rem;
- --sidebar: oklch(0.985 0 0);
- --sidebar-foreground: oklch(0.145 0 0);
- --sidebar-primary: oklch(0.205 0 0);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.97 0 0);
- --sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
- --sidebar-ring: oklch(0.708 0 0);
-}
-
-.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.145 0 0);
- --card-foreground: oklch(0.985 0 0);
- --popover: oklch(0.145 0 0);
- --popover-foreground: oklch(0.985 0 0);
- --primary: oklch(0.985 0 0);
- --primary-foreground: oklch(0.205 0 0);
- --secondary: oklch(0.269 0 0);
- --secondary-foreground: oklch(0.985 0 0);
- --muted: oklch(0.269 0 0);
- --muted-foreground: oklch(0.708 0 0);
- --accent: oklch(0.269 0 0);
- --accent-foreground: oklch(0.985 0 0);
- --destructive: oklch(0.396 0.141 25.723);
- --destructive-foreground: oklch(0.637 0.237 25.331);
- --border: oklch(0.269 0 0);
- --input: oklch(0.269 0 0);
- --ring: oklch(0.439 0 0);
- --chart-1: oklch(0.488 0.243 264.376);
- --chart-2: oklch(0.696 0.17 162.48);
- --chart-3: oklch(0.769 0.188 70.08);
- --chart-4: oklch(0.627 0.265 303.9);
- --chart-5: oklch(0.645 0.246 16.439);
- --sidebar: oklch(0.205 0 0);
- --sidebar-foreground: oklch(0.985 0 0);
- --sidebar-primary: oklch(0.488 0.243 264.376);
- --sidebar-primary-foreground: oklch(0.985 0 0);
- --sidebar-accent: oklch(0.269 0 0);
- --sidebar-accent-foreground: oklch(0.985 0 0);
- --sidebar-border: oklch(0.269 0 0);
- --sidebar-ring: oklch(0.439 0 0);
-}
-
-@theme inline {
- --font-sans: "Geist", "Geist Fallback";
- --font-mono: "Geist Mono", "Geist Mono Fallback";
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --color-card: var(--card);
- --color-card-foreground: var(--card-foreground);
- --color-popover: var(--popover);
- --color-popover-foreground: var(--popover-foreground);
- --color-primary: var(--primary);
- --color-primary-foreground: var(--primary-foreground);
- --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);
- --color-destructive: var(--destructive);
- --color-destructive-foreground: var(--destructive-foreground);
- --color-border: var(--border);
- --color-input: var(--input);
- --color-ring: var(--ring);
- --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);
- --radius-sm: calc(var(--radius) - 4px);
- --radius-md: calc(var(--radius) - 2px);
- --radius-lg: var(--radius);
- --radius-xl: calc(var(--radius) + 4px);
- --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 {
- * {
- @apply border-border outline-ring/50;
- }
- body {
- @apply bg-background text-foreground;
- }
-}