diff --git a/package-lock.json b/package-lock.json
index 18fa3fb..8829090 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@hookform/resolvers": "^5.0.1",
+ "@radix-ui/react-accordion": "^1.2.8",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-slot": "^1.2.0",
"@t3-oss/env-nextjs": "^0.12.0",
@@ -883,6 +884,99 @@
"node": ">=12.4.0"
}
},
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz",
+ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-accordion": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.8.tgz",
+ "integrity": "sha512-c7OKBvO36PfQIUGIjj1Wko0hH937pYFU2tR5zbIJDUsmTzHoZVHHt4bmb7OOJbzTaWJtVELKWojBHa7OcnUHmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-collapsible": "1.1.8",
+ "@radix-ui/react-collection": "1.1.4",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.0",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.8.tgz",
+ "integrity": "sha512-hxEsLvK9WxIAPyxdDRULL4hcaSjMZCfP7fHB0Z1uUnDoDBat1Zh46hwYfa69DeZAbJrPckjf0AGAtEZyvDyJbw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-presence": "1.1.4",
+ "@radix-ui/react-primitive": "2.1.0",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.4.tgz",
+ "integrity": "sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.0",
+ "@radix-ui/react-slot": "1.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-compose-refs": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
@@ -898,6 +992,54 @@
}
}
},
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-label": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.4.tgz",
@@ -921,6 +1063,30 @@
}
}
},
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz",
+ "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-primitive": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.0.tgz",
@@ -962,6 +1128,58 @@
}
}
},
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
diff --git a/package.json b/package.json
index 240f75b..1a3789b 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
},
"dependencies": {
"@hookform/resolvers": "^5.0.1",
+ "@radix-ui/react-accordion": "^1.2.8",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-slot": "^1.2.0",
"@t3-oss/env-nextjs": "^0.12.0",
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d2ab6a6..0dac805 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -4,8 +4,10 @@ import { type Metadata } from "next";
import { Geist } from "next/font/google";
export const metadata: Metadata = {
- title: "Create T3 App",
- description: "Generated by create-t3-app",
+ title:
+ "FIRE Calculator - Plan Your Financial Independence & Early Retirement",
+ description:
+ "Calculate your FIRE number, estimate your retirement age, and plan your path to financial independence with this comprehensive FIRE calculator.",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};
@@ -18,7 +20,7 @@ export default function RootLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
-
+
{children}
);
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 6770123..841ac15 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,14 +1,348 @@
import FireCalculatorForm from "./components/FireCalculatorForm";
+import {
+ Accordion,
+ AccordionContent,
+ AccordionItem,
+ AccordionTrigger,
+} from "@/components/ui/accordion";
export default function HomePage() {
return (
-
+
FIRE Calculator
+
+ {/* Added SEO Content Sections */}
+
+
+ What is FIRE?
+
+ FIRE stands for "Financial Independence, Retire Early."
+ It's a movement focused on aggressive saving and investing to
+ build a large enough portfolio that the returns can cover living
+ expenses indefinitely. Achieving FIRE means you are no longer
+ dependent on traditional employment to fund your lifestyle, giving
+ you the freedom to pursue passions, travel, or simply enjoy life
+ without the need for a regular paycheck.
+
+
+ The core principle often involves saving a high percentage of income
+ (sometimes 50% or more) and investing it wisely, typically in
+ low-cost index funds. The target amount, often called the "FIRE
+ number," is usually calculated as 25 times your desired annual
+ spending, based on the 4% safe withdrawal rate rule.
+
+
+
+
+ How This Calculator Works
+
+ This calculator helps you estimate your path to FIRE based on your
+ current financial situation and future projections. Here's a
+ breakdown of the inputs:
+
+
+ -
+ Starting Capital: The total amount you currently
+ have invested.
+
+ -
+ Monthly Savings: The amount you consistently save
+ and invest each month.
+
+ -
+ Current Age: Your current age in years.
+
+ -
+ Expected Annual Growth Rate (%): The average
+ annual return you expect from your investments (after fees, before
+ inflation).
+
+ -
+ Desired Monthly Allowance (Today's Value):{" "}
+ How much you want to be able to spend each month in retirement, in
+ today's money value.
+
+ -
+ Annual Inflation Rate (%): The expected average
+ rate at which the cost of living will increase.
+
+ -
+ Life Expectancy (Age): The age until which you
+ want your funds to last.
+
+
+
+ The calculator simulates your investment growth year by year,
+ factoring in monthly contributions, compound growth, and
+ inflation's effect on your target allowance. It then determines
+ the age at which your accumulated capital is sufficient to sustain
+ your desired, inflation-adjusted monthly allowance throughout your
+ expected retirement years until your specified life expectancy. It
+ estimates your "FIRE Number" (the capital needed at
+ retirement) and the age you might reach it.
+
+
+
+
+
+ Frequently Asked Questions (FAQ)
+
+
+
+
+ What is the 4% rule?
+
+
+ The 4% rule is a guideline suggesting that you can safely
+ withdraw 4% of your investment portfolio's value in your
+ first year of retirement, and then adjust that amount for
+ inflation each subsequent year, with a high probability of your
+ money lasting for at least 30 years. This calculator uses a more
+ dynamic simulation based on your life expectancy but is related
+ to this concept.
+
+
+
+
+
+ Is the Expected Growth Rate realistic?
+
+
+ Historically, diversified stock market investments have returned
+ around 7-10% annually over the long term, before inflation. A
+ rate of 7% (after fees) is often used as a reasonable estimate,
+ but past performance doesn't guarantee future results.
+ It's crucial to choose a rate you feel comfortable with and
+ understand the associated risks.
+
+
+
+
+
+ How does inflation impact my FIRE number?
+
+
+ Inflation erodes the purchasing power of money over time. Your
+ desired monthly allowance needs to increase each year just to
+ maintain the same standard of living. This calculator accounts
+ for this by adjusting your target allowance upwards based on the
+ inflation rate you provide, ensuring the calculated FIRE number
+ supports your desired lifestyle in future dollars.
+
+
+
+
+
+ Can I really retire early?
+
+
+ Retiring significantly earlier than traditional retirement age
+ is possible but requires discipline, a high savings rate, and
+ consistent investment growth. The feasibility depends heavily on
+ your income, expenses, savings habits, and investment returns.
+ Use this calculator as a tool for planning and motivation, but
+ remember it provides estimates based on your inputs.
+
+
+
+
+
+ What does FIRE stand for?
+
+
+ FIRE stands for Financial Independence, Retire Early. It
+ represents a lifestyle movement aimed at maximizing your savings
+ rate through increased income and/or decreased expenses to
+ achieve financial independence and retire much earlier than
+ traditional retirement age.
+
+
+
+
+
+ How much should I save each month?
+
+
+ FIRE enthusiasts typically aim to save 50-70% of their income.
+ The more you can save, the faster you'll reach your FIRE
+ goal. However, the right amount depends on your income,
+ lifestyle, and target retirement age. Use the calculator to
+ experiment with different monthly savings amounts to see their
+ impact on your retirement timeline.
+
+
+
+
+
+ {/* Optional: Add a section for relevant resources/links here */}
+
+
+ Further Reading & Resources
+
+
+ Want to learn more about FIRE and continue your journey to financial
+ independence? Here are some valuable resources to explore:
+
+
+
+
Getting Started with FIRE:
+
+ -
+ Read foundational content like Mr. Money Mustache's simple
+ math article
+
+ -
+ Calculate your personal numbers using this and other FIRE
+ calculators
+
+ -
+ Join communities like r/Fire to ask questions and find support
+
+ - Explore books and podcasts to deepen your understanding
+
+
+
+
+
+
+
+
+
+
+ Additional Calculators & Tools
+
+
+
+
+
+
+ Recent Articles & Trends
+
+
+
+
+
+
);
}
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
new file mode 100644
index 0000000..4ca9fd0
--- /dev/null
+++ b/src/components/ui/accordion.tsx
@@ -0,0 +1,60 @@
+"use client";
+
+import * as React from "react";
+import * as AccordionPrimitive from "@radix-ui/react-accordion";
+import { ChevronDown } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Accordion = AccordionPrimitive.Root;
+
+const AccordionItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AccordionItem.displayName = "AccordionItem";
+
+const AccordionTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ svg]:rotate-180",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+));
+AccordionTrigger.displayName = "AccordionTrigger";
+
+const AccordionContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+));
+AccordionContent.displayName = "AccordionContent";
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };