Skip to content

Commit 90a3eb8

Browse files
added changes
1 parent e666ff3 commit 90a3eb8

File tree

11 files changed

+2149
-1
lines changed

11 files changed

+2149
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ vanillaverse/
4444
├── projects/ # Individual mini-project folders
4545
│ └── example/
4646
│ ├── index.html
47-
│ └── main.js # Each includes TODOs for contributors
47+
│ └── main.js # Each includes TODOs
4848
└── .github/ # Issue templates and deploy workflow
4949
```
5050

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Tip Calculator</title>
7+
<link rel="stylesheet" href="styles.css" />
8+
</head>
9+
<body>
10+
<button id="themeToggle" class="theme-toggle" aria-label="Toggle theme">
11+
<svg
12+
class="sun-icon"
13+
width="20"
14+
height="20"
15+
viewBox="0 0 24 24"
16+
fill="none"
17+
stroke="currentColor"
18+
stroke-width="2"
19+
>
20+
<circle cx="12" cy="12" r="5" />
21+
<line x1="12" y1="1" x2="12" y2="3" />
22+
<line x1="12" y1="21" x2="12" y2="23" />
23+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
24+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
25+
<line x1="1" y1="12" x2="3" y2="12" />
26+
<line x1="21" y1="12" x2="23" y2="12" />
27+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
28+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
29+
</svg>
30+
<svg
31+
class="moon-icon"
32+
width="20"
33+
height="20"
34+
viewBox="0 0 24 24"
35+
fill="none"
36+
stroke="currentColor"
37+
stroke-width="2"
38+
>
39+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
40+
</svg>
41+
</button>
42+
<h1>Tip Calculator</h1>
43+
44+
<div class="container">
45+
<label for="bill">Enter total amount in ₹:</label>
46+
<input
47+
id="bill"
48+
class="bill"
49+
type="number"
50+
placeholder="e.g. 50"
51+
min="0"
52+
/>
53+
54+
<h3>Select tip percentage:</h3>
55+
<div class="tip-buttons">
56+
<button type="button" class="tip-btn" data-tip="10">10%</button>
57+
<button type="button" class="tip-btn" data-tip="15">15%</button>
58+
<button type="button" class="tip-btn" data-tip="20">20%</button>
59+
</div>
60+
61+
<label for="custom-tip">Or enter custom tip %:</label>
62+
<input id="custom-tip" type="number" placeholder="e.g. 18" min="0" />
63+
64+
<label for="split">Number of people to split bill:</label>
65+
<input
66+
id="split"
67+
class="split"
68+
type="number"
69+
placeholder="e.g. 2"
70+
min="1"
71+
value="1"
72+
/>
73+
74+
<div class="results">
75+
<h3>Tip Amount: <span id="tip-amount">Rs0.00</span></h3>
76+
<h3>Total Bill: <span id="total-bill">Rs0.00</span></h3>
77+
<h3>Total per Person: <span id="per-person">Rs0.00</span></h3>
78+
</div>
79+
</div>
80+
81+
<script src="main.js"></script>
82+
</body>
83+
</html>

projects/Tip Calculator/main 2.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const billInput = document.querySelector(".bill");
2+
const splitInput = document.querySelector(".split");
3+
const tipButtons = document.querySelectorAll(".tip-btn");
4+
const customTipInput = document.getElementById("custom-tip");
5+
const tipAmountDisplay = document.getElementById("tip-amount");
6+
const totalBillDisplay = document.getElementById("total-bill");
7+
const perPersonDisplay = document.getElementById("per-person");
8+
9+
let tipPercentage = 0;
10+
11+
tipButtons.forEach(btn => {
12+
btn.addEventListener("click", () => {
13+
tipPercentage = Number(btn.dataset.tip);
14+
customTipInput.value = ""; // clear custom tip
15+
tipButtons.forEach(b => b.classList.remove("active"));
16+
btn.classList.add("active");
17+
calculateTotals();
18+
});
19+
});
20+
21+
22+
[billInput, splitInput, customTipInput].forEach(input => {
23+
input.addEventListener("input", () => calculateTotals());
24+
});
25+
26+
27+
function calculateTotals() {
28+
const bill = parseFloat(billInput.value);
29+
const people = parseInt(splitInput.value) || 1;
30+
const customTip = parseFloat(customTipInput.value);
31+
32+
// Use custom tip if entered
33+
const tipPercent = customTip > 0 ? customTip : tipPercentage;
34+
35+
// Prevent calculation for empty bill
36+
if (isNaN(bill) || bill <= 0) {
37+
updateDisplay(0, 0, 0);
38+
return;
39+
}
40+
41+
const tipAmount = (bill * tipPercent) / 100;
42+
const totalBill = bill + tipAmount;
43+
const perPerson = totalBill / people;
44+
45+
updateDisplay(tipAmount, totalBill, perPerson);
46+
}
47+
48+
function updateDisplay(tip, total, perPerson) {
49+
tipAmountDisplay.textContent = `Rs${tip.toFixed(2)}`;
50+
totalBillDisplay.textContent = `Rs${total.toFixed(2)}`;
51+
perPersonDisplay.textContent = `Rs${perPerson.toFixed(2)}`;
52+
}
53+
54+
const themeToggle = document.getElementById("themeToggle");
55+
const body = document.body;
56+
57+
const currentTheme = localStorage.getItem("theme") || "light";
58+
if (currentTheme === "dark") {
59+
body.classList.add("dark-mode");
60+
}
61+
62+
themeToggle.addEventListener("click", () => {
63+
body.classList.toggle("dark-mode");
64+
65+
const theme = body.classList.contains("dark-mode") ? "dark" : "light";
66+
localStorage.setItem("theme", theme);
67+
});
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
:root {
2+
/* Light Theme */
3+
--bg: #f9fafb;
4+
--card: #ffffff;
5+
--muted: #6b7280;
6+
--accent: #2563eb;
7+
--text: #111827;
8+
--border: #e5e7eb;
9+
}
10+
11+
body.dark-mode {
12+
/* dark mode */
13+
--bg: #0f172a;
14+
--card: #1e293b;
15+
--muted: #9ca3af;
16+
--accent: #60a5fa;
17+
--text: #f1f5f9;
18+
--border: #334155;
19+
}
20+
21+
22+
html, body {
23+
height: 100%;
24+
margin: 0;
25+
padding: 0;
26+
}
27+
28+
body {
29+
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial;
30+
background: var(--bg);
31+
color: var(--text);
32+
display: flex;
33+
flex-direction: column;
34+
align-items: center;
35+
justify-content: flex-start;
36+
min-height: 100vh;
37+
padding: 2rem;
38+
transition: background 0.4s ease, color 0.4s ease;
39+
}
40+
41+
* {
42+
box-sizing: border-box;
43+
transition: background 0.4s ease, color 0.4s ease, border-color 0.3s ease;
44+
}
45+
46+
47+
.container {
48+
background: var(--card);
49+
padding: 2rem;
50+
border-radius: 16px;
51+
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
52+
53+
54+
width: 32vw;
55+
max-width: 100%;
56+
min-width: 320px;
57+
58+
margin-top: 0.1rem;
59+
}
60+
61+
h1 {
62+
text-align: center;
63+
margin-bottom: 1.6rem;
64+
font-size: 2rem;
65+
font-weight: 600;
66+
color: var(--text);
67+
}
68+
69+
70+
label {
71+
display: block;
72+
margin-top: 1rem;
73+
font-size: 0.95rem;
74+
color: var(--muted);
75+
font-weight: 500;
76+
}
77+
78+
input[type="number"] {
79+
width: 100%;
80+
padding: 0.75rem;
81+
margin-top: 0.5rem;
82+
font-size: 1rem;
83+
border: 1px solid var(--border);
84+
border-radius: 8px;
85+
background: var(--bg);
86+
color: var(--text);
87+
transition: border 0.3s ease, box-shadow 0.3s ease;
88+
}
89+
90+
input[type="number"]:focus {
91+
outline: none;
92+
border-color: var(--accent);
93+
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
94+
}
95+
96+
.tip-buttons {
97+
display: flex;
98+
gap: 0.75rem;
99+
margin-top: 1rem;
100+
flex-wrap: wrap;
101+
}
102+
103+
.tip-btn {
104+
flex: 1 1 30%;
105+
padding: 0.75rem;
106+
font-size: 1rem;
107+
font-weight: 500;
108+
border: 1px solid var(--border);
109+
background: var(--card);
110+
color: var(--text);
111+
border-radius: 8px;
112+
cursor: pointer;
113+
transition: all 0.3s ease;
114+
}
115+
116+
.tip-btn:hover {
117+
background: var(--accent);
118+
color: #ffffff;
119+
border-color: var(--accent);
120+
}
121+
122+
.tip-btn.active {
123+
background: var(--accent);
124+
color: #ffffff;
125+
border-color: var(--accent);
126+
}
127+
128+
129+
.results {
130+
margin-top: 2rem;
131+
background: rgba(0, 0, 0, 0.03);
132+
padding: 1rem 1.25rem;
133+
border-radius: 10px;
134+
border: 1px solid var(--border);
135+
}
136+
137+
body.dark-mode .results {
138+
background: rgba(255, 255, 255, 0.05);
139+
}
140+
141+
.results h3 {
142+
margin-bottom: 0.75rem;
143+
font-size: 1.1rem;
144+
display: flex;
145+
justify-content: space-between;
146+
align-items: center;
147+
color: var(--text);
148+
}
149+
150+
.results span {
151+
font-weight: bold;
152+
color: var(--accent);
153+
}
154+
155+
/* Theme toggle */
156+
.theme-toggle {
157+
background: var(--card);
158+
border: 2px solid var(--border);
159+
border-radius: 50%;
160+
width: 45px;
161+
height: 45px;
162+
cursor: pointer;
163+
display: flex;
164+
align-items: center;
165+
justify-content: center;
166+
transition: all 0.3s ease;
167+
position: fixed;
168+
top: 1rem;
169+
right: 1rem;
170+
z-index: 1000;
171+
color: var(--text);
172+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
173+
}
174+
175+
.theme-toggle:hover {
176+
transform: scale(1.1);
177+
}
178+
179+
.theme-toggle .sun-icon {
180+
display: none;
181+
}
182+
183+
body.dark-mode .theme-toggle .sun-icon {
184+
display: block;
185+
}
186+
187+
body.dark-mode .theme-toggle .moon-icon {
188+
display: none;
189+
}
190+
191+
/* Responsive */
192+
@media (max-width: 768px) {
193+
body {
194+
padding: 1.5rem;
195+
}
196+
197+
.container {
198+
margin-top: 1rem;
199+
padding: 1.5rem;
200+
}
201+
202+
h1 {
203+
font-size: 1.7rem;
204+
}
205+
}
206+
207+
@media (max-width: 480px) {
208+
.tip-buttons {
209+
flex-direction: column;
210+
}
211+
212+
.tip-btn {
213+
flex: 1 1 100%;
214+
}
215+
216+
.container {
217+
padding: 1.25rem;
218+
}
219+
220+
h1 {
221+
font-size: 1.5rem;
222+
}
223+
}
224+
/* Remove (arrows that appear for input type number ( to inc and dec value) */
225+
input[type="number"]::-webkit-outer-spin-button,
226+
input[type="number"]::-webkit-inner-spin-button {
227+
-webkit-appearance: none;
228+
margin: 0;
229+
}

0 commit comments

Comments
 (0)