<!
doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expense Tracker</title>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
rel="stylesheet"
/>
<style>
*{
box-sizing: border-box;
margin: 0;
padding: 0;
body {
font-family: "Inter", sans-serif;
background: linear-gradient(135deg, #1f4037, #99f2c8);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
padding: 1rem;
animation: backgroundSlide 10s ease infinite alternate;
@keyframes backgroundSlide {
0% {
background-position: left;
100% {
background-position: right;
.container {
background: white;
padding: 2rem;
border-radius: 1.25rem;
width: 100%;
max-width: 500px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
animation: fadeIn 0.8s ease-in-out;
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.95);
to {
opacity: 1;
transform: scale(1);
h1 {
text-align: center;
font-size: 2.25rem;
margin-bottom: 1.5rem;
color: #2d3748;
animation: slideInTop 0.6s ease-in-out;
@keyframes slideInTop {
from {
transform: translateY(-30px);
opacity: 0;
to {
transform: translateY(0);
opacity: 1;
.form input,
.form select,
.form button {
width: 100%;
padding: 0.75rem 1rem;
margin-top: 0.75rem;
border-radius: 0.625rem;
border: 1px solid #cbd5e0;
font-size: 1rem;
transition: all 0.3s ease;
.form input:focus,
.form select:focus {
outline: none;
border-color: #38b2ac;
box-shadow: 0 0 0 3px rgba(56, 178, 172, 0.3);
.form button {
background-color: #38b2ac;
color: white;
font-weight: 600;
border: none;
cursor: pointer;
}
.form button:hover {
background-color: #319795;
.summary {
text-align: center;
margin-top: 2rem;
.summary h2 {
font-size: 1.75rem;
color: #2d3748;
margin-bottom: 0.75rem;
.summary p {
margin: 0.25rem 0;
font-weight: 600;
font-size: 1.1rem;
.summary .income {
color: #48bb78;
.summary .expense {
color: #f56565;
ul {
list-style: none;
margin-top: 2rem;
max-height: 250px;
overflow-y: auto;
padding: 0;
}
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem 1rem;
margin-bottom: 0.75rem;
border-radius: 0.625rem;
background-color: #f7fafc;
border-left: 5px solid;
transition:
transform 0.2s,
box-shadow 0.2s;
li:hover {
transform: scale(1.02);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
li.income {
border-color: #48bb78;
color: #276749;
li.expense {
border-color: #f56565;
color: #c53030;
li button {
background: none;
border: none;
color: #a0aec0;
font-size: 1.1rem;
cursor: pointer;
transition: color 0.2s;
li button:hover {
color: #e53e3e;
</style>
</head>
<body>
<div class="container">
<h1>Expense Tracker</h1>
<div class="form">
<input type="text" id="desc" placeholder="Description" />
<input type="number" id="amount" placeholder="Amount" />
<input type="number" id="tax" placeholder="Tax % (optional)" />
<select id="type">
<option value="income">Income</option>
<option value="expense">Expense</option>
</select>
<button onclick="addTransaction()">Add Transaction</button>
<button onclick="generateInvoice()">Generate Invoice</button>
<button onclick="shareData()">Share Summary</button>
<button onclick="clearAll()">Clear All</button>
</div>
<div class="summary">
<h2>Balance: ₹<span id="balance">0.00</span></h2>
<p class="income">Income: ₹<span id="income">0.00</span></p>
<p class="expense">Expense: ₹<span id="expense">0.00</span></p>
</div>
<ul id="transactions"></ul>
</div>
<script>
let transactions = JSON.parse(localStorage.getItem("transactions")) || [];
function updateUI() {
const list = document.getElementById("transactions");
list.innerHTML = "";
let income = 0,
expense = 0;
transactions.forEach((t, i) => {
const li = document.createElement("li");
li.className = t.type;
li.innerHTML = `
<span>${t.description} (₹${t.amount.toFixed(2)})</span>
<button onclick="deleteTransaction(${i})">✕</button>
`;
list.appendChild(li);
t.type === "income" ? (income += t.amount) : (expense += t.amount);
});
document.getElementById("income").innerText = income.toFixed(2);
document.getElementById("expense").innerText = expense.toFixed(2);
document.getElementById("balance").innerText = (
income - expense
).toFixed(2);
localStorage.setItem("transactions", JSON.stringify(transactions));
function addTransaction() {
const desc = document.getElementById("desc").value.trim();
const amount = parseFloat(document.getElementById("amount").value);
const tax = parseFloat(document.getElementById("tax").value);
const type = document.getElementById("type").value;
if (!desc || isNaN(amount)) return alert("Fill all fields correctly");
let total = amount;
if (!isNaN(tax) && tax > 0) {
total += amount * (tax / 100);
transactions.push({ description: desc, amount: total, type });
document.getElementById("desc").value = "";
document.getElementById("amount").value = "";
document.getElementById("tax").value = "";
updateUI();
function deleteTransaction(index) {
transactions.splice(index, 1);
updateUI();
function clearAll() {
if (confirm("Are you sure you want to clear all transactions?")) {
transactions = [];
updateUI();
function generateInvoice() {
let invoice = "--- Expense Tracker Invoice ---\n";
transactions.forEach((t) => {
invoice += `${t.description}: ₹${t.amount.toFixed(2)} (${t.type})\n`;
});
invoice += `\nTotal Balance: ₹${document.getElementById("balance").innerText}`;
alert(invoice);
function shareData() {
const summary = `Balance: ₹${document.getElementById("balance").innerText}\nIncome:
₹${document.getElementById("income").innerText}\nExpense:
₹${document.getElementById("expense").innerText}`;
navigator.clipboard.writeText(summary).then(
() => {
alert("Summary copied to clipboard!");
},
() => {
alert("Failed to copy.");
},
);
updateUI();
</script>
</body>
</html>