From 162e16d90a5a42ba7817738e3e3995b7aea6402c Mon Sep 17 00:00:00 2001
From: "Jai T." <142034117+D15A-Jai-61@users.noreply.github.com>
Date: Sun, 5 Oct 2025 22:15:49 +0530
Subject: [PATCH] Made the webpage prettier, added a reset button and a
light/dark mode button
---
index.html | 90 ++++++++++++++++++++++++++++++++++++-------
script.js | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++---
style.css | 98 ++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 276 insertions(+), 21 deletions(-)
diff --git a/index.html b/index.html
index 8a580ffb3..81091d0fc 100644
--- a/index.html
+++ b/index.html
@@ -1,16 +1,80 @@
-
-
-
-
-
-
- Simple Interest Calculator
+
+
+
+
+
+ Simple Interest Calculator
- Amount
- Rate
- No. of Years
- Interest :
+
+
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/script.js b/script.js
index 7adfb78be..b931119ab 100644
--- a/script.js
+++ b/script.js
@@ -1,6 +1,103 @@
-function compute()
-{
- p = document.getElementById("principal").value;
-
-}
-
\ No newline at end of file
+// script.js
+// Modern, safe code: event-driven, input validation, accessible updates.
+
+document.addEventListener('DOMContentLoaded', () => {
+ const form = document.getElementById('si-form');
+ const principalEl = document.getElementById('principal');
+ const rateEl = document.getElementById('rate');
+ const yearsEl = document.getElementById('years');
+ const resultEl = document.getElementById('result');
+ const resetBtn = document.getElementById('reset');
+ const themeToggle = document.getElementById('theme-toggle');
+
+ // Format numbers to 2 decimal places with locale formatting
+ function formatAmount(n) {
+ return Number(n).toLocaleString(undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2
+ });
+ }
+
+ function showError(message) {
+ resultEl.textContent = message;
+ resultEl.classList.add('error');
+ }
+
+ function clearError() {
+ resultEl.classList.remove('error');
+ }
+
+ function compute() {
+ // parseFloat used to accept decimal input
+ const p = parseFloat(principalEl.value);
+ const r = parseFloat(rateEl.value);
+ const y = parseFloat(yearsEl.value);
+
+ // Validate numbers and non-negative
+ if (Number.isNaN(p) || Number.isNaN(r) || Number.isNaN(y)) {
+ showError('Please enter numeric values for all fields.');
+ return;
+ }
+ if (p < 0 || r < 0 || y < 0) {
+ showError('Please enter non-negative values.');
+ return;
+ }
+
+ clearError();
+
+ // Simple interest formula: interest = (p * r * y) / 100
+ const interest = (p * r * y) / 100;
+ const total = p + interest;
+
+ resultEl.innerHTML = `${formatAmount(interest)} (Interest). Total: ${formatAmount(total)}`;
+ }
+
+ // handle form submit
+ form.addEventListener('submit', (ev) => {
+ ev.preventDefault();
+ compute();
+ });
+
+ // reset handler
+ resetBtn.addEventListener('click', () => {
+ form.reset();
+ resultEl.textContent = '—';
+ resultEl.classList.remove('error');
+ });
+
+ // make compute available globally in case someone expects window.compute()
+ window.compute = compute;
+
+ /* -----------------------
+ Theme toggle (light/dark)
+ - persists selection in localStorage
+ - respects system preference if no saved choice
+ ----------------------- */
+ const THEME_KEY = 'si.theme';
+
+ function applyTheme(theme) {
+ document.documentElement.setAttribute('data-theme', theme);
+ const isDark = theme === 'dark';
+ themeToggle.setAttribute('aria-pressed', String(isDark));
+ themeToggle.textContent = isDark ? '🌙 Dark' : '☀️ Light';
+ localStorage.setItem(THEME_KEY, theme);
+ }
+
+ // Initialize theme
+ (function initTheme() {
+ const stored = localStorage.getItem(THEME_KEY);
+ if (stored === 'dark' || stored === 'light') {
+ applyTheme(stored);
+ return;
+ }
+ // fallback to system preference
+ const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
+ applyTheme(prefersDark ? 'dark' : 'light');
+ })();
+
+ // Toggle handler
+ themeToggle.addEventListener('click', () => {
+ const current = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
+ applyTheme(current === 'dark' ? 'light' : 'dark');
+ });
+});
diff --git a/style.css b/style.css
index 8a6b03574..a8c032f3c 100644
--- a/style.css
+++ b/style.css
@@ -1,4 +1,98 @@
-body {background-color:tan;}
-h1{color:green;}
+/* Themeable variables */
+:root{
+ --bg: #f5efe6;
+ --card: #ffffff;
+ --accent: #2e8b57;
+ --accent-600: #237246;
+ --text: #1f2933;
+ --muted: #505a63;
+ --input-bg: #ffffff;
+ --input-border: #e6e6e6;
+ --input-text: #1f2933;
+ --shadow: 0 10px 30px rgba(18, 24, 28, 0.08);
+ --soft-shadow: 0 6px 18px rgba(18, 24, 28, 0.06);
+ --btn-radius: 10px;
+ --focus-ring: rgba(46,139,87,0.18);
+ --surface: rgba(255,255,255,0.6);
+}
+[data-theme="dark"]{
+ --bg: #071021;
+ --card: #071827;
+ --accent: #60b38a;
+ --accent-600: #4aa073;
+ --text: #e6eef1;
+ --muted: #9fb3b7;
+ --input-bg: #071827;
+ --input-border: #133042;
+ --input-text: #e6eef1;
+ --shadow: 0 8px 24px rgba(2, 8, 15, 0.6);
+ --soft-shadow: 0 6px 18px rgba(2,8,15,0.5);
+ --focus-ring: rgba(96,179,138,0.18);
+ --surface: rgba(255,255,255,0.02);
+}
+/* Reset & base */
+* { box-sizing: border-box; }
+html,body { height: 100%; margin: 0; font-family: Inter, ui-sans-serif, system-ui; color: var(--text); background: var(--bg); }
+
+body { display: flex; align-items: center; justify-content: center; padding: 2rem; min-height: 100vh; }
+
+.container {
+ width: 100%;
+ max-width: 520px;
+ background: var(--card);
+ border-radius: 12px;
+ padding: 1.5rem;
+ box-shadow: var(--shadow);
+}
+
+/* Header */
+.header { display:flex; align-items:center; justify-content:space-between; margin-bottom:1rem; }
+h1 { margin:0; color: var(--accent-600); font-size:1.25rem; }
+
+/* Theme toggle */
+#theme-toggle{
+ padding:0.35rem 0.6rem;
+ border-radius:999px;
+ border:none;
+ cursor:pointer;
+ background: var(--surface);
+ font-weight:600;
+ color: var(--text); /* <- changed: matches page text for light/dark mode */
+ transition: transform 120ms ease, box-shadow 160ms ease, opacity 160ms ease;
+}
+#theme-toggle:active { transform: translateY(1px); }
+#theme-toggle:hover { opacity: 0.95; }
+
+/* Form rows */
+.row { display:flex; gap:0.8rem; align-items:center; margin-bottom:0.85rem; }
+.row label { min-width:130px; font-weight:600; color: var(--muted); font-size:0.95rem; }
+.row input[type="number"]{
+ flex:1; padding:0.65rem 0.75rem; border-radius:10px; border:1px solid var(--input-border);
+ background: var(--input-bg); color: var(--input-text); outline:none; box-shadow: var(--soft-shadow);
+ font-size:1rem; transition: all 0.15s ease;
+}
+.row input:focus { box-shadow: 0 8px 22px var(--focus-ring); border-color: var(--accent-600); }
+
+/* Result row */
+.result-row { align-items: baseline; margin-top: 0.25rem; padding-top: 0.5rem; border-top:1px dashed rgba(0,0,0,0.1); }
+.result-value { margin-left:0.65rem; font-weight:700; font-size:1rem; }
+
+/* Buttons area */
+.buttons { display:flex; gap:0.6rem; margin-top:1.1rem; justify-content:center; }
+button { padding:0.55rem 0.95rem; border-radius:var(--btn-radius); border:none; font-weight:700; font-size:0.95rem; cursor:pointer; transition: all 0.12s ease; }
+button:active { transform: translateY(1px); }
+button.primary { background: linear-gradient(180deg, var(--accent), var(--accent-600)); color:white; }
+button.ghost { background:transparent; border:1px solid rgba(0,0,0,0.1); color: var(--muted); }
+
+/* Error styling */
+.result-value.error { color:#b00020; }
+
+/* Responsive */
+@media (max-width: 420px){
+ .row { flex-direction: column; align-items: stretch; }
+ .row label { min-width: 0; }
+ .header { gap: 0.5rem; }
+ .container { padding: 1rem; border-radius: 10px; }
+}