diff --git a/src/app/components/charts/CoastFireChart.tsx b/src/app/components/charts/CoastFireChart.tsx index ba48253..017a1dc 100644 --- a/src/app/components/charts/CoastFireChart.tsx +++ b/src/app/components/charts/CoastFireChart.tsx @@ -1,7 +1,14 @@ 'use client'; import { Line, LineChart, CartesianGrid, XAxis, YAxis } from 'recharts'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from '@/components/ui/card'; import { ChartContainer, ChartLegend, @@ -45,6 +52,9 @@ const generateData = () => { const data = generateData(); const chartConfig = { + age: { + label: 'Age', + }, Standard: { label: 'Standard Path', color: 'var(--chart-4)', @@ -75,16 +85,22 @@ export function CoastFireChart() { tickLine={false} axisLine={false} tickMargin={8} - tickFormatter={(value: number) => `$${String(value / 1000)}k`} + tickFormatter={(value: number) => { + if (value < 1000) { + return `$${String(value)}`; + } + if (value < 1000000) { + return `$${String(value / 1000)}k`; + } + if (value < 1000000000) { + return `$${String(value / 1000000)}M`; + } + return `$${String(value / 1000000000)}B`; + }} /> `Age ${String(value)}`} - indicator="line" - /> - } + content={} /> } /> + +

+ Simulation assumes 7% returns. Standard: Save $10k/yr (age 25-65). Coast: Save $30k/yr (age + 25-35), then $0. +

+
); diff --git a/src/app/components/charts/FourPercentRuleChart.tsx b/src/app/components/charts/FourPercentRuleChart.tsx index c8114e1..43741d8 100644 --- a/src/app/components/charts/FourPercentRuleChart.tsx +++ b/src/app/components/charts/FourPercentRuleChart.tsx @@ -1,7 +1,14 @@ 'use client'; import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from '@/components/ui/card'; import { ChartContainer, ChartLegend, @@ -96,6 +103,15 @@ export function FourPercentRuleChart() { + +
+

4% balances safety and spending power

+

+ A 5% withdrawal rate risks depleting your portfolio within 30 years, while 3% leaves a large + surplus. The 4% rule is widely considered the safe "sweet spot." +

+
+
); } diff --git a/src/app/learn/coast-fire-vs-lean-fire/page.tsx b/src/app/learn/coast-fire-vs-lean-fire/page.tsx index 0dcecfb..5238161 100644 --- a/src/app/learn/coast-fire-vs-lean-fire/page.tsx +++ b/src/app/learn/coast-fire-vs-lean-fire/page.tsx @@ -147,7 +147,7 @@ export default function CoastVsLeanPage() { discipline.

- +

Run The Numbers

The best way to decide is to see the math. Use our calculator to simulate both scenarios:

diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx index a593bb3..6a7d345 100644 --- a/src/components/ui/chart.tsx +++ b/src/components/ui/chart.tsx @@ -209,7 +209,7 @@ function ChartTooltipContent({ {itemConfig?.label ?? item.name} {item.value && ( - + {item.value.toLocaleString()} )} diff --git a/src/styles/globals.css b/src/styles/globals.css index faaacdb..83805f2 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,12 +1,12 @@ -@import "tailwindcss"; -@import "tw-animate-css"; +@import 'tailwindcss'; +@import 'tw-animate-css'; @custom-variant dark (&:is(.dark *)); @theme { --font-sans: - var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; } @theme inline { @@ -60,9 +60,7 @@ --secondary: oklch(0.49 0.1326 259.29); /* denim */ --secondary-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ --muted: oklch(0.67 0.0763 198.81 / 20%); /* verdigris with opacity */ - --muted-foreground: oklch( - 0.39 0.0215 96.47 / 80% - ); /* black olive with opacity */ + --muted-foreground: oklch(0.39 0.0215 96.47 / 80%); /* black olive with opacity */ --accent: oklch(0.49 0.1326 259.29); /* denim */ --accent-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ --destructive: oklch(0.33 0.1316 336.24); /* palatinate */ @@ -80,9 +78,7 @@ --sidebar-primary-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ --sidebar-accent: oklch(0.49 0.1326 259.29); /* denim */ --sidebar-accent-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ - --sidebar-border: oklch( - 0.67 0.0763 198.81 / 20% - ); /* verdigris with opacity */ + --sidebar-border: oklch(0.67 0.0763 198.81 / 20%); /* verdigris with opacity */ --sidebar-ring: oklch(0.67 0.0763 198.81); /* verdigris */ } @@ -116,9 +112,7 @@ --sidebar-primary-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ --sidebar-accent: oklch(0.49 0.1326 259.29); /* denim */ --sidebar-accent-foreground: oklch(0.97 0.0228 95.96); /* cosmic latte */ - --sidebar-border: oklch( - 0.97 0.0228 95.96 / 10% - ); /* cosmic latte with opacity */ + --sidebar-border: oklch(0.97 0.0228 95.96 / 10%); /* cosmic latte with opacity */ --sidebar-ring: oklch(0.67 0.0763 198.81); /* verdigris */ } @@ -142,7 +136,7 @@ @apply scroll-m-20 text-xl font-semibold tracking-tight; } p { - @apply leading-7 [&:not(:first-child)]:mt-6; + @apply mb-2 leading-7 [&:not(:first-child)]:mt-6; } blockquote { @apply mt-6 border-l-2 pl-6 italic; @@ -151,6 +145,6 @@ @apply my-6 ml-6 list-disc [&>li]:mt-2; } code { - @apply bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold + @apply bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold; } }