diff --git a/frontend-v2/src/app.css b/frontend-v2/src/app.css index 809cc72..da5f984 100644 --- a/frontend-v2/src/app.css +++ b/frontend-v2/src/app.css @@ -16,7 +16,7 @@ body { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); } :root { /* ── Fonts ── */ - --font: 'DM Sans', -apple-system, system-ui, sans-serif; + --font: 'Outfit', -apple-system, system-ui, sans-serif; --mono: 'JetBrains Mono', ui-monospace, monospace; --transition: 150ms ease; @@ -56,8 +56,8 @@ --radius-xs: 4px; --radius-sm: 6px; --radius-md: 8px; - --radius: 12px; - --radius-lg: 16px; + --radius: 16px; + --radius-lg: 20px; --radius-full: 9999px; /* ── Elevation scale ── @@ -67,11 +67,12 @@ * lg: elevated (dropdowns, popovers, hero cards) * xl: overlay (modals, slide-out panels) */ - --shadow-xs: 0 1px 2px rgba(0,0,0,0.03); - --shadow-sm: 0 1px 3px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.04); - --shadow-md: 0 2px 6px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06); - --shadow-lg: 0 4px 12px rgba(0,0,0,0.06), 0 16px 40px rgba(0,0,0,0.1); - --shadow-xl: 0 8px 24px rgba(0,0,0,0.08), 0 24px 60px rgba(0,0,0,0.15); + /* Zinc-tinted shadows */ + --shadow-xs: 0 1px 2px rgba(24,24,27,0.04); + --shadow-sm: 0 1px 2px rgba(24,24,27,0.04), 0 4px 8px rgba(24,24,27,0.02); + --shadow-md: 0 2px 8px rgba(24,24,27,0.05), 0 12px 24px rgba(24,24,27,0.04); + --shadow-lg: 0 4px 16px rgba(24,24,27,0.06), 0 24px 48px rgba(24,24,27,0.06); + --shadow-xl: 0 8px 24px rgba(24,24,27,0.08), 0 32px 64px rgba(24,24,27,0.1); /* Legacy aliases */ --card-shadow: var(--shadow-md); --card-shadow-sm: var(--shadow-sm); @@ -103,75 +104,68 @@ --leading-loose: 1.8; } - /* ── LIGHT MODE ── */ + /* ── LIGHT MODE — Zinc + Emerald ── */ :root { - /* Surface hierarchy: canvas (page bg) → surface (sidebars, panels) → card (content containers) */ - --canvas: #F3F4F6; + --canvas: #FAFAFA; --surface: #FFFFFF; - --surface-secondary: #F7F8FA; + --surface-secondary: #F4F4F5; --card: #FFFFFF; - --card-secondary: #F7F8FA; - --card-hover: #EDEEF2; + --card-secondary: #F4F4F5; + --card-hover: #F0F0F2; - /* Borders */ --border: rgba(0,0,0,0.06); --border-strong: rgba(0,0,0,0.10); - /* Text hierarchy: 1 (headings/names) → 2 (body) → 3 (labels/meta) → 4 (placeholder/disabled) */ - --text-1: #111118; - --text-2: #3d3d4a; - --text-3: #6b6b78; - --text-4: #a8a8b3; + --text-1: #18181B; + --text-2: #3F3F46; + --text-3: #71717A; + --text-4: #A1A1AA; - /* Accent — deep indigo */ - --accent: #4338CA; - --accent-bg: #EEF2FF; - --accent-dim: rgba(67,56,202,0.06); - --accent-border: rgba(67,56,202,0.12); - --accent-focus: rgba(67,56,202,0.14); + /* Accent — Emerald (single, desaturated) */ + --accent: #059669; + --accent-bg: #ECFDF5; + --accent-dim: rgba(5,150,105,0.07); + --accent-border: rgba(5,150,105,0.14); + --accent-focus: rgba(5,150,105,0.16); - /* Semantic: success */ --success: #059669; --success-bg: #ECFDF5; --success-dim: rgba(5,150,105,0.07); - /* Semantic: error */ --error: #DC2626; --error-bg: #FEF2F2; --error-dim: rgba(220,38,38,0.06); - /* Semantic: warning */ --warning: #D97706; --warning-bg: rgba(217,119,6,0.07); - /* Overlay */ - --overlay: rgba(0,0,0,0.25); - --overlay-strong: rgba(0,0,0,0.45); - --nav-bg: rgba(255,255,255,0.92); + --overlay: rgba(0,0,0,0.2); + --overlay-strong: rgba(0,0,0,0.4); + --nav-bg: rgba(250,250,250,0.8); } - /* ── DARK MODE ── */ + /* ── DARK MODE — Zinc + Emerald ── */ .dark { - --canvas: #0a0a0c; - --surface: #111114; - --surface-secondary: #141417; - --card: #18181c; - --card-secondary: #141417; - --card-hover: #1f1f24; + --canvas: #09090B; + --surface: #111113; + --surface-secondary: #18181B; + --card: #1C1C1F; + --card-secondary: #18181B; + --card-hover: #232326; --border: rgba(255,255,255,0.07); --border-strong: rgba(255,255,255,0.12); - --text-1: #f4f4f5; - --text-2: #a1a1aa; - --text-3: #71717a; - --text-4: #3f3f46; + --text-1: #FAFAFA; + --text-2: #A1A1AA; + --text-3: #71717A; + --text-4: #3F3F46; - --accent: #6366F1; - --accent-bg: rgba(99,102,241,0.1); - --accent-dim: rgba(99,102,241,0.08); - --accent-border: rgba(99,102,241,0.14); - --accent-focus: rgba(99,102,241,0.16); + --accent: #34D399; + --accent-bg: rgba(52,211,153,0.1); + --accent-dim: rgba(52,211,153,0.08); + --accent-border: rgba(52,211,153,0.14); + --accent-focus: rgba(52,211,153,0.16); --success: #22c55e; --success-bg: rgba(34,197,94,0.1); @@ -487,7 +481,7 @@ /* ── App surface (centered container) ── */ .app-surface { - max-width: 1200px; + max-width: 1280px; width: 100%; margin: 0 auto; padding: 0 var(--sp-6); diff --git a/frontend-v2/src/app.html b/frontend-v2/src/app.html index 6b07520..bd524fe 100644 --- a/frontend-v2/src/app.html +++ b/frontend-v2/src/app.html @@ -5,7 +5,7 @@ - + %sveltekit.head%
diff --git a/frontend-v2/src/lib/components/dashboard/BudgetModule.svelte b/frontend-v2/src/lib/components/dashboard/BudgetModule.svelte index 2067a15..60bde42 100644 --- a/frontend-v2/src/lib/components/dashboard/BudgetModule.svelte +++ b/frontend-v2/src/lib/components/dashboard/BudgetModule.svelte @@ -61,17 +61,18 @@ } .budget-amount { - font-size: var(--text-3xl); - font-weight: 500; + font-size: 36px; + font-weight: 800; font-family: var(--mono); + letter-spacing: -0.04em; color: var(--text-1); line-height: 1; } .budget-label { - font-size: var(--text-base); - color: var(--text-3); - margin-top: var(--sp-1.5); + font-size: 12px; + color: var(--text-4); + margin-top: 4px; } .budget-rows { @@ -92,18 +93,19 @@ } .budget-row-name { - font-size: var(--text-base); - color: var(--text-2); + font-size: 13px; + color: var(--text-3); } .budget-row-amount { - font-size: var(--text-base); + font-size: 12px; font-family: var(--mono); - color: var(--text-1); + font-weight: 500; + color: var(--text-2); } .budget-row-amount.income { - color: var(--success); + color: var(--accent); } @media (max-width: 768px) { diff --git a/frontend-v2/src/lib/components/dashboard/DashboardActionCard.svelte b/frontend-v2/src/lib/components/dashboard/DashboardActionCard.svelte index ade52d5..6c39b5c 100644 --- a/frontend-v2/src/lib/components/dashboard/DashboardActionCard.svelte +++ b/frontend-v2/src/lib/components/dashboard/DashboardActionCard.svelte @@ -14,147 +14,139 @@ size?: 'primary' | 'secondary'; href: string; } = $props(); + + // Extract the number from title (e.g. "78 uncategorized..." → "78") + function extractNumber(t: string): { num: string; rest: string } { + const match = t.match(/^([\d,\.]+)\s+(.*)$/); + if (match) return { num: match[1], rest: match[2] }; + return { num: '', rest: t }; + } + + const parsed = $derived(extractNumber(title)); - -