diff --git a/src/app/(auth)/signup/page.tsx b/src/app/(auth)/signup/page.tsx
index fcbc345..0d21a44 100644
--- a/src/app/(auth)/signup/page.tsx
+++ b/src/app/(auth)/signup/page.tsx
@@ -2,8 +2,8 @@ import { SignupForm } from "@/features/auth/components/signup-form";
export default function Page() {
return (
-
-
+
diff --git a/src/app/(landing-page)/page.tsx b/src/app/(landing-page)/page.tsx
index 5ee532a..a1d3371 100644
--- a/src/app/(landing-page)/page.tsx
+++ b/src/app/(landing-page)/page.tsx
@@ -1,5 +1,4 @@
import {
- RiArrowRightSLine,
RiBankCard2Line,
RiBarChartBoxLine,
RiCalendarLine,
@@ -211,7 +210,6 @@ export default async function Page() {
diff --git a/src/app/globals.css b/src/app/globals.css
index 1d5c829..86e0b68 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -4,53 +4,44 @@
@theme {
--spacing-custom-height-card: 30rem;
- --spacing-8xl: 88rem; /* 1408px */
- --spacing-9xl: 96rem; /* 1536px */
+ --spacing-8xl: 88rem;
+ --spacing-9xl: 96rem;
}
:root {
- /* Base surfaces - warm cream with subtle orange undertone */
- --background: oklch(98.01% 0.00331 67.026);
- --foreground: #201207;
+ --background: oklch(97.036% 0.00276 84.303);
+ --foreground: oklch(27% 0.008 45);
--card: var(--background);
- --card-foreground: #201207;
- --popover: oklch(99.5% 0.004 80);
- --popover-foreground: oklch(18% 0.02 45);
+ --card-foreground: var(--foreground);
+ --popover: oklch(100% 0 0);
+ --popover-foreground: var(--foreground);
- /* Primary - rich terracotta orange */
- --primary: #f17a35;
+ --primary: oklch(72.085% 0.16286 50.705);
--primary-foreground: oklch(98% 0.008 80);
- /* Secondary - warm stone with subtle saturation */
- --secondary: oklch(94% 0.018 70);
- --secondary-foreground: oklch(25% 0.025 45);
+ --secondary: oklch(96.2% 0.005 70);
+ --secondary-foreground: oklch(30% 0.01 45);
- /* Muted - softer background variant */
- --muted: oklch(94.5% 0.014 75);
- --muted-foreground: #44413c;
+ --muted: oklch(95% 0.0035 70);
+ --muted-foreground: oklch(50% 0.007 50);
- /* Accent - complementary warm tone */
- --accent: oklch(94% 0.01 70);
- --accent-foreground: #44413c;
+ --accent: oklch(94.8% 0.009 65);
+ --accent-foreground: var(--foreground);
- /* Semantic states */
- --success: oklch(55.87% 0.12943 157.517);
+ --success: oklch(61.654% 0.14385 157.131);
--success-foreground: oklch(98% 0.01 150);
--warning: oklch(69.913% 0.1798 49.649);
--warning-foreground: oklch(20% 0.04 85);
--info: oklch(55% 0.17 250);
--info-foreground: oklch(98% 0.01 250);
- /* Destructive - accessible red */
--destructive: oklch(55% 0.22 27);
--destructive-foreground: oklch(98% 0.005 30);
- /* Borders and inputs - defined but subtle */
- --border: oklch(82% 0.012 75);
- --input: oklch(82% 0.012 75);
- --ring: oklch(69.18% 0.18855 38.353);
+ --border: oklch(84.567% 0.00583 84.468);
+ --input: oklch(84.567% 0.00583 84.468);
+ --ring: var(--primary);
- /* Charts - 10 harmonious, distinct, accessible colors */
--chart-1: var(--color-emerald-500);
--chart-2: var(--color-orange-500);
--chart-3: var(--color-indigo-500);
@@ -62,20 +53,17 @@
--chart-9: var(--color-cyan-500);
--chart-10: var(--color-lime-500);
- /* Sidebar - slight elevation from background */
- --sidebar: oklch(100% 0 0);
- --sidebar-foreground: oklch(20% 0.02 45);
- --sidebar-primary: oklch(25% 0.025 45);
- --sidebar-primary-foreground: oklch(98% 0.008 80);
- --sidebar-accent: oklch(96.563% 0.00504 67.275);
- --sidebar-accent-foreground: oklch(22% 0.025 45);
- --sidebar-border: oklch(69.18% 0.18855 38.353);
- --sidebar-ring: oklch(69.18% 0.18855 38.353);
+ --sidebar: oklch(99.3% 0.0015 75);
+ --sidebar-foreground: var(--foreground);
+ --sidebar-primary: var(--primary);
+ --sidebar-primary-foreground: var(--primary-foreground);
+ --sidebar-accent: oklch(96.5% 0.004 70);
+ --sidebar-accent-foreground: var(--foreground);
+ --sidebar-border: oklch(91% 0.004 70);
+ --sidebar-ring: var(--primary);
- /* Layout */
--radius: 0.5rem;
- /* Shadows - warm tinted for cohesion */
--shadow-2xs: 0 1px 2px 0px oklch(35% 0.02 45 / 0.04);
--shadow-xs: 0 1px 3px 0px oklch(35% 0.02 45 / 0.06);
--shadow-sm: 0 1px 3px 0px oklch(35% 0.02 45 / 0.08),
@@ -95,31 +83,25 @@
}
.dark {
- /* Base surfaces - warm dark with consistent hue family */
- --background: oklch(18.5% 0.002 70);
- --foreground: oklch(92% 0.015 80);
- --card: var(--background);
- --card-foreground: oklch(92% 0.015 80);
- --popover: oklch(24% 0.003 70);
- --popover-foreground: oklch(92% 0.015 80);
+ --background: oklch(20.5% 0.004 55);
+ --foreground: oklch(93% 0.008 80);
+ --card: oklch(23% 0.004 55);
+ --card-foreground: var(--foreground);
+ --popover: oklch(25% 0.004 55);
+ --popover-foreground: var(--foreground);
- /* Primary - vibrant terracotta stands out on dark */
- --primary: #fa6c26;
- --primary-foreground: oklch(20% 0.002 70);
+ --primary: oklch(72.085% 0.16286 50.705);
+ --primary-foreground: oklch(16% 0.004 60);
- /* Secondary - elevated surface */
- --secondary: oklch(22% 0.004 70);
- --secondary-foreground: oklch(92% 0.015 80);
+ --secondary: oklch(26% 0.004 55);
+ --secondary-foreground: var(--foreground);
- /* Muted - subtle surface variant */
- --muted: oklch(33.5% 0.005 70);
- --muted-foreground: oklch(72% 0.004 70);
+ --muted: oklch(28.5% 0.0035 55);
+ --muted-foreground: oklch(73% 0.006 75);
- /* Accent - subtle highlight */
- --accent: oklch(27% 0.004 70);
- --accent-foreground: oklch(92% 0.015 80);
+ --accent: oklch(30% 0.005 55);
+ --accent-foreground: var(--foreground);
- /* Semantic states */
--success: oklch(65% 0.19 150);
--success-foreground: oklch(15% 0.02 150);
--warning: oklch(69.913% 0.1798 49.649);
@@ -127,16 +109,13 @@
--info: oklch(65% 0.17 250);
--info-foreground: oklch(15% 0.02 250);
- /* Destructive - accessible red for dark */
--destructive: oklch(62% 0.2 28);
--destructive-foreground: oklch(98% 0.005 30);
- /* Borders and inputs - visible but subtle */
- --border: oklch(37% 0.01 70);
- --input: oklch(32% 0.005 70);
- --ring: oklch(69.18% 0.18855 38.353);
+ --border: oklch(33% 0.004 55);
+ --input: oklch(30% 0.004 55);
+ --ring: var(--primary);
- /* Charts - bright and distinct on dark */
--chart-1: var(--color-emerald-500);
--chart-2: var(--color-orange-500);
--chart-3: var(--color-indigo-500);
@@ -148,20 +127,17 @@
--chart-9: var(--color-cyan-500);
--chart-10: var(--color-lime-500);
- /* Sidebar - slight separation from main */
- --sidebar: oklch(24% 0.003 70);
- --sidebar-foreground: oklch(92% 0.015 80);
- --sidebar-primary: oklch(69.18% 0.18855 38.353);
- --sidebar-primary-foreground: oklch(13% 0.006 70);
- --sidebar-accent: oklch(32% 0.004 70);
- --sidebar-accent-foreground: oklch(92% 0.015 80);
- --sidebar-border: oklch(26% 0.004 70);
- --sidebar-ring: oklch(69.18% 0.18855 38.353);
+ --sidebar: oklch(18% 0.004 55);
+ --sidebar-foreground: var(--foreground);
+ --sidebar-primary: var(--primary);
+ --sidebar-primary-foreground: var(--primary-foreground);
+ --sidebar-accent: oklch(27% 0.004 55);
+ --sidebar-accent-foreground: var(--foreground);
+ --sidebar-border: oklch(31% 0.004 55);
+ --sidebar-ring: var(--primary);
- /* Layout */
--radius: 0.5rem;
- /* Shadows - deeper for dark mode */
--shadow-2xs: 0 1px 2px 0px oklch(0% 0 0 / 0.3);
--shadow-xs: 0 1px 3px 0px oklch(0% 0 0 / 0.4);
--shadow-sm: 0 1px 3px 0px oklch(0% 0 0 / 0.45),
@@ -254,7 +230,6 @@
body {
@apply bg-background text-foreground;
- font-family: var(--font-america), sans-serif;
}
*::selection {
@@ -283,7 +258,6 @@
mix-blend-mode: normal;
}
-/* Dialog animations */
@keyframes dialog-in {
from {
opacity: 0;
@@ -332,7 +306,6 @@
animation: dialog-out 0.15s ease-in;
}
-/* Overdue blink: alternates two stacked labels with a smooth crossfade */
@keyframes blink-in {
0%, 40% { opacity: 1; }
50%, 90% { opacity: 0; }
diff --git a/src/features/auth/components/auth-card-shell.tsx b/src/features/auth/components/auth-card-shell.tsx
new file mode 100644
index 0000000..aca8613
--- /dev/null
+++ b/src/features/auth/components/auth-card-shell.tsx
@@ -0,0 +1,27 @@
+import type { PropsWithChildren } from "react";
+import { Card, CardContent } from "@/shared/components/ui/card";
+import { DotPattern } from "@/shared/components/ui/dot-pattern";
+import AuthSidebar from "./auth-sidebar";
+
+export function AuthCardShell({ children }: PropsWithChildren) {
+ return (
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/src/features/auth/components/auth-header.tsx b/src/features/auth/components/auth-header.tsx
index 2164f33..a9fbcb3 100644
--- a/src/features/auth/components/auth-header.tsx
+++ b/src/features/auth/components/auth-header.tsx
@@ -2,14 +2,20 @@ import { cn } from "@/shared/utils/ui";
interface AuthHeaderProps {
title: string;
+ description?: string;
}
-export function AuthHeader({ title }: AuthHeaderProps) {
+export function AuthHeader({ title, description }: AuthHeaderProps) {
return (
-
-
+
+
{title}
+ {description ? (
+
+ {description}
+
+ ) : null}
);
}
diff --git a/src/features/auth/components/auth-sidebar.tsx b/src/features/auth/components/auth-sidebar.tsx
index d154aaa..55176e4 100644
--- a/src/features/auth/components/auth-sidebar.tsx
+++ b/src/features/auth/components/auth-sidebar.tsx
@@ -1,12 +1,32 @@
+import { Logo } from "@/shared/components/logo";
+import { DotPattern } from "@/shared/components/ui/dot-pattern";
+
function AuthSidebar() {
return (
-
-
-
-
+
+
+
+
+
+
+
Controle suas finanças com clareza e foco diário.
-
+
Centralize despesas, organize cartões e acompanhe metas mensais em
um painel inteligente feito para o seu dia a dia.
diff --git a/src/features/auth/components/login-form.tsx b/src/features/auth/components/login-form.tsx
index a55e430..0b33729 100644
--- a/src/features/auth/components/login-form.tsx
+++ b/src/features/auth/components/login-form.tsx
@@ -3,9 +3,7 @@ import { RiFingerprintLine, RiLoader4Line } from "@remixicon/react";
import { useRouter } from "next/navigation";
import { type FormEvent, useEffect, useState } from "react";
import { toast } from "sonner";
-import { Logo } from "@/shared/components/logo";
import { Button } from "@/shared/components/ui/button";
-import { Card, CardContent } from "@/shared/components/ui/card";
import {
Field,
FieldDescription,
@@ -16,13 +14,16 @@ import {
import { Input } from "@/shared/components/ui/input";
import { authClient, googleSignInAvailable } from "@/shared/lib/auth/client";
import { cn } from "@/shared/utils/ui";
+import { AuthCardShell } from "./auth-card-shell";
import { AuthErrorAlert } from "./auth-error-alert";
import { AuthHeader } from "./auth-header";
-import AuthSidebar from "./auth-sidebar";
import { GoogleAuthButton } from "./google-auth-button";
type DivProps = React.ComponentProps<"div">;
+const authLinkClassName =
+ "font-medium text-foreground/88 underline decoration-border underline-offset-4 transition-colors hover:text-foreground hover:decoration-foreground/30 focus-visible:rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
+
export function LoginForm({ className, ...props }: DivProps) {
const router = useRouter();
const isGoogleAvailable = googleSignInAvailable;
@@ -130,119 +131,117 @@ export function LoginForm({ className, ...props }: DivProps) {
}
return (
-