From c4707e55113aa2e4b4f6268afdda44f871c1d7a6 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Sun, 21 Dec 2025 13:29:43 +0100 Subject: [PATCH] feat: update fintech card styles with modern design enhancements; add subtle texture effects and adjust gradient backgrounds for improved visual appeal in overview and statistics cards --- app/globals.css | 281 ++++++++++++------ components/dashboard/overview-cards.tsx | 85 +++--- components/statistics/stats-summary-cards.tsx | 66 ++-- 3 files changed, 282 insertions(+), 150 deletions(-) diff --git a/app/globals.css b/app/globals.css index ba1d83d..0b1037c 100644 --- a/app/globals.css +++ b/app/globals.css @@ -459,21 +459,50 @@ z-index: 1; } - /* Fintech card styles avec glassmorphism très prononcé */ + /* Fintech card styles avec design moderne et élégant */ .fintech-card { background: var(--card); - backdrop-filter: blur(50px) saturate(200%); - -webkit-backdrop-filter: blur(50px) saturate(200%); - border: 1px solid var(--border); - border-radius: var(--radius); + backdrop-filter: blur(40px) saturate(180%); + -webkit-backdrop-filter: blur(40px) saturate(180%); + border: 1px solid color-mix(in srgb, var(--border) 60%, transparent); + border-radius: calc(var(--radius) + 0.25rem); box-shadow: - 0 8px 32px -8px color-mix(in srgb, var(--primary) 8%, transparent), - 0 2px 8px -2px color-mix(in srgb, var(--foreground) 3%, transparent), - inset 0 1px 0 0 color-mix(in srgb, white 25%, transparent); + 0 1px 3px 0 color-mix(in srgb, var(--foreground) 4%, transparent), + 0 4px 12px -2px color-mix(in srgb, var(--primary) 6%, transparent), + 0 8px 24px -4px color-mix(in srgb, var(--foreground) 2%, transparent), + inset 0 1px 0 0 color-mix(in srgb, white 30%, transparent); position: relative; overflow: hidden; } + /* Texture subtile avec grain/noise */ + .fintech-card::before { + content: ""; + position: absolute; + inset: 0; + background-image: + radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--foreground) 2%, transparent) 1px, transparent 0); + background-size: 20px 20px; + opacity: 0.15; + pointer-events: none; + z-index: 1; + } + + .dark .fintech-card::before { + background-image: + radial-gradient(circle at 1px 1px, color-mix(in srgb, white 3%, transparent) 1px, transparent 0); + opacity: 0.1; + } + + .dark .fintech-card { + border-color: color-mix(in srgb, var(--border) 40%, transparent); + box-shadow: + 0 1px 3px 0 color-mix(in srgb, var(--foreground) 8%, transparent), + 0 4px 12px -2px color-mix(in srgb, var(--primary) 8%, transparent), + 0 8px 24px -4px color-mix(in srgb, black 40%, transparent), + inset 0 1px 0 0 color-mix(in srgb, white 8%, transparent); + } + .fintech-card::after { content: ""; position: absolute; @@ -484,140 +513,220 @@ background: linear-gradient( 90deg, transparent 0%, - color-mix(in srgb, white 40%, transparent) 50%, + color-mix(in srgb, white 50%, transparent) 50%, transparent 100% ); - opacity: 0.5; + opacity: 0.6; + z-index: 2; } - /* Gradient backgrounds for stat cards très vibrants */ + .dark .fintech-card::after { + opacity: 0.2; + } + + /* Gradient backgrounds for stat cards - design moderne et subtil */ .stat-card-gradient-1 { + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--primary) 8%, var(--card)) 0%, + color-mix(in srgb, var(--primary-light) 5%, var(--card)) 50%, + color-mix(in srgb, var(--primary) 4%, var(--card)) 100% + ); + position: relative; + overflow: hidden; + border-color: color-mix(in srgb, var(--primary) 20%, var(--border)); + } + + .stat-card-gradient-1::before { + content: ""; + position: absolute; + top: -30%; + right: -20%; + width: 150%; + height: 150%; + background: radial-gradient( + circle, + color-mix(in srgb, var(--primary) 15%, transparent) 0%, + transparent 60% + ); + opacity: 0.4; + } + + .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% ); - position: relative; - overflow: hidden; + border-color: color-mix(in srgb, var(--primary) 30%, var(--border)); } - .stat-card-gradient-1::before { - content: ""; - position: absolute; - top: -50%; - right: -50%; - width: 200%; - height: 200%; - background: radial-gradient( - circle, - color-mix(in srgb, var(--primary) 20%, transparent) 0%, - transparent 70% - ); - opacity: 0.3; + .dark .stat-card-gradient-1::before { + opacity: 0.25; } .stat-card-gradient-2 { + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--success) 8%, var(--card)) 0%, + color-mix(in srgb, var(--success) 5%, var(--card)) 50%, + color-mix(in srgb, var(--success) 4%, var(--card)) 100% + ); + position: relative; + overflow: hidden; + border-color: color-mix(in srgb, var(--success) 20%, var(--border)); + } + + .stat-card-gradient-2::before { + content: ""; + position: absolute; + top: -30%; + right: -20%; + width: 150%; + height: 150%; + background: radial-gradient( + circle, + color-mix(in srgb, var(--success) 15%, transparent) 0%, + transparent 60% + ); + opacity: 0.4; + } + + .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% ); - position: relative; - overflow: hidden; + border-color: color-mix(in srgb, var(--success) 30%, var(--border)); } - .stat-card-gradient-2::before { - content: ""; - position: absolute; - top: -50%; - right: -50%; - width: 200%; - height: 200%; - background: radial-gradient( - circle, - color-mix(in srgb, var(--success) 20%, transparent) 0%, - transparent 70% - ); - opacity: 0.3; + .dark .stat-card-gradient-2::before { + opacity: 0.25; } .stat-card-gradient-3 { + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--destructive) 8%, var(--card)) 0%, + color-mix(in srgb, var(--destructive) 5%, var(--card)) 50%, + color-mix(in srgb, var(--destructive) 4%, var(--card)) 100% + ); + position: relative; + overflow: hidden; + border-color: color-mix(in srgb, var(--destructive) 20%, var(--border)); + } + + .stat-card-gradient-3::before { + content: ""; + position: absolute; + top: -30%; + right: -20%; + width: 150%; + height: 150%; + background: radial-gradient( + circle, + color-mix(in srgb, var(--destructive) 15%, transparent) 0%, + transparent 60% + ); + opacity: 0.4; + } + + .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% ); - position: relative; - overflow: hidden; + border-color: color-mix(in srgb, var(--destructive) 30%, var(--border)); } - .stat-card-gradient-3::before { - content: ""; - position: absolute; - top: -50%; - right: -50%; - width: 200%; - height: 200%; - background: radial-gradient( - circle, - color-mix(in srgb, var(--destructive) 20%, transparent) 0%, - transparent 70% - ); - opacity: 0.3; + .dark .stat-card-gradient-3::before { + opacity: 0.25; } .stat-card-gradient-4 { + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--chart-4) 8%, var(--card)) 0%, + color-mix(in srgb, var(--chart-4) 5%, var(--card)) 50%, + color-mix(in srgb, var(--chart-4) 4%, var(--card)) 100% + ); + position: relative; + overflow: hidden; + border-color: color-mix(in srgb, var(--chart-4) 20%, var(--border)); + } + + .stat-card-gradient-4::before { + content: ""; + position: absolute; + top: -30%; + right: -20%; + width: 150%; + height: 150%; + background: radial-gradient( + circle, + color-mix(in srgb, var(--chart-4) 15%, transparent) 0%, + transparent 60% + ); + opacity: 0.4; + } + + .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% ); - position: relative; - overflow: hidden; + border-color: color-mix(in srgb, var(--chart-4) 30%, var(--border)); } - .stat-card-gradient-4::before { - content: ""; - position: absolute; - top: -50%; - right: -50%; - width: 200%; - height: 200%; - background: radial-gradient( - circle, - color-mix(in srgb, var(--chart-4) 20%, transparent) 0%, - transparent 70% - ); - opacity: 0.3; + .dark .stat-card-gradient-4::before { + opacity: 0.25; } .stat-card-gradient-5 { + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--chart-5) 8%, var(--card)) 0%, + color-mix(in srgb, var(--chart-5) 5%, var(--card)) 50%, + color-mix(in srgb, var(--chart-5) 4%, var(--card)) 100% + ); + position: relative; + overflow: hidden; + border-color: color-mix(in srgb, var(--chart-5) 20%, var(--border)); + } + + .stat-card-gradient-5::before { + content: ""; + position: absolute; + top: -30%; + right: -20%; + width: 150%; + height: 150%; + background: radial-gradient( + circle, + color-mix(in srgb, var(--chart-5) 15%, transparent) 0%, + transparent 60% + ); + opacity: 0.4; + } + + .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% ); - position: relative; - overflow: hidden; + border-color: color-mix(in srgb, var(--chart-5) 30%, var(--border)); } - .stat-card-gradient-5::before { - content: ""; - position: absolute; - top: -50%; - right: -50%; - width: 200%; - height: 200%; - background: radial-gradient( - circle, - color-mix(in srgb, var(--chart-5) 20%, transparent) 0%, - transparent 70% - ); - opacity: 0.3; + .dark .stat-card-gradient-5::before { + opacity: 0.25; } } diff --git a/components/dashboard/overview-cards.tsx b/components/dashboard/overview-cards.tsx index fb7a1b5..50b5a8e 100644 --- a/components/dashboard/overview-cards.tsx +++ b/components/dashboard/overview-cards.tsx @@ -59,18 +59,19 @@ export function OverviewCards({ data }: OverviewCardsProps) { return (
- - + {/* Icône en arrière-plan */} +
+ +
+ + Solde Total -
- -
- +
= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400" @@ -78,26 +79,27 @@ export function OverviewCards({ data }: OverviewCardsProps) { > {formatCurrency(totalBalance)}
-

+

{data.accounts.length} compte{data.accounts.length > 1 ? "s" : ""}

- - + {/* Icône en arrière-plan */} +
+ +
+ + Revenus du mois -
- -
- -
+ +
{formatCurrency(income)}
-

+

{monthTransactions.filter((t) => t.amount > 0).length} opération {monthTransactions.filter((t) => t.amount > 0).length > 1 ? "s" @@ -107,19 +109,20 @@ export function OverviewCards({ data }: OverviewCardsProps) { - - + {/* Icône en arrière-plan */} +

+ +
+ + Dépenses du mois -
- -
- -
+ +
{formatCurrency(expenses)}
-

+

{monthTransactions.filter((t) => t.amount < 0).length} opération {monthTransactions.filter((t) => t.amount < 0).length > 1 ? "s" @@ -129,38 +132,40 @@ export function OverviewCards({ data }: OverviewCardsProps) { - - + {/* Icône en arrière-plan */} +

+ +
+ + Pointage -
- -
- -
+ +
{reconciledPercent}%
-

+

{reconciled} / {total} opérations pointées

- - + {/* Icône en arrière-plan */} +
+ +
+ + Catégorisation -
- -
- -
+ +
{categorizedPercent}%
-

+

{categorized} / {total} opérations catégorisées

diff --git a/components/statistics/stats-summary-cards.tsx b/components/statistics/stats-summary-cards.tsx index 0edd8bc..e7f9eaa 100644 --- a/components/statistics/stats-summary-cards.tsx +++ b/components/statistics/stats-summary-cards.tsx @@ -21,59 +21,77 @@ export function StatsSummaryCards({ return (
- - - - + + {/* Icône en arrière-plan */} +
+ +
+ + Total Revenus - -
+ +
{formatCurrency(totalIncome)}
- - - - + + {/* Icône en arrière-plan */} +
+ +
+ + Total Dépenses - -
+ +
{formatCurrency(totalExpenses)}
- - - - + + {/* Icône en arrière-plan */} +
+ +
+ + Moyenne mensuelle - -
+ +
{formatCurrency(avgMonthlyExpenses)}
- - - + + {/* Icône en arrière-plan */} +
+
= 0 + ? "border-emerald-600 dark:border-emerald-400" + : "border-red-600 dark:border-red-400" + )} /> +
+ + Économies - +
= 0 ? "text-emerald-600" : "text-red-600", + "text-xl md:text-2xl font-black tracking-tight", + savings >= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400", )} > {formatCurrency(savings)}