From d8010bac5667b67464687efb6313ea09125d0d5e Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:59:52 +0530 Subject: [PATCH 01/15] Update money_memory_game.py --- money_memory_game.py | 174 ++++++++++++++++++++++++++++--------------- 1 file changed, 116 insertions(+), 58 deletions(-) diff --git a/money_memory_game.py b/money_memory_game.py index 54fa31924..1ed48c501 100644 --- a/money_memory_game.py +++ b/money_memory_game.py @@ -2,61 +2,119 @@ import tkinter as tk from tkinter import messagebox -# Initialize the main window -window = tk.Tk() -window.title("Money Memory Game") -window.geometry("400x400") - -# List of card values (numbers for simplicity) -cards = list(range(1, 9)) * 2 -random.shuffle(cards) - -# Variables to track the game state -first_card = None -first_button = None -matches_found = 0 -attempts = 0 - -# Function to check for matches between two selected cards -def check_match(btn, idx): - global first_card, first_button, matches_found, attempts - - # Disable the button and show the card value - btn.config(text=str(cards[idx]), state="disabled") - - # First card selection - if first_card is None: - first_card = cards[idx] - first_button = btn - else: - # Second card selection - if first_card == cards[idx]: # If cards match - matches_found += 1 - first_card = None - first_button = None - - # Check if all matches are found - if matches_found == 8: - messagebox.showinfo("Game Over", f"Congratulations! You won in {attempts} attempts!") - else: # If cards don't match - window.after(1000, hide_cards, btn, first_button) - first_card = None - first_button = None - - attempts += 1 - -# Function to hide cards if they don't match -def hide_cards(btn1, btn2): - btn1.config(text="?", state="normal") - btn2.config(text="?", state="normal") - -# Create the buttons for the game board (4x4 grid) -buttons = [] -for i in range(16): - btn = tk.Button(window, text="?", width=10, height=3, - command=lambda i=i: check_match(buttons[i], i)) - btn.grid(row=i // 4, column=i % 4) - buttons.append(btn) - -# Start the game -window.mainloop() +# ------------------------ +# Enhanced Money Memory Game +# ------------------------ + +class MemoryGame: + def __init__(self, master): + self.master = master + master.title("Money Memory Game") + master.geometry("460x500") + master.resizable(False, False) + + self.score = 0 + self.attempts = 0 + self.matches_found = 0 + self.first_card_idx = None + self.locked = False + + # Main frame for padding and flexibility + self.frame = tk.Frame(master, pady=20) + self.frame.pack() + + # Status bar + self.status = tk.Label(master, text='', font=('Arial', 14), fg='green') + self.status.pack(pady=10) + self.update_status() + + # Restart button + restart_btn = tk.Button(master, text="Restart", command=self.restart_game, bg='#ffd700', font=('Arial', 12)) + restart_btn.pack(pady=5) + + # Game board initialization + self.create_board() + + def create_board(self): + self.cards = list(range(1, 9)) * 2 # Money values + random.shuffle(self.cards) + self.button_refs = [] + + # Draw grid + for widget in self.frame.winfo_children(): + widget.destroy() + for i in range(16): + btn = tk.Button(self.frame, text="?", font=('Arial', 18, 'bold'), width=6, height=3, + bg="#336699", fg="white", relief="raised", + command=lambda i=i: self.reveal_card(i)) + btn.grid(row=i // 4, column=i % 4, padx=5, pady=5) + self.button_refs.append(btn) + + def update_status(self): + accuracy = f"{(self.matches_found / self.attempts * 100):.1f}%" if self.attempts else "0%" + self.status.config(text=f"Attempts: {self.attempts} | Matches: {self.matches_found}/8 | Accuracy: {accuracy}") + + def reveal_card(self, idx): + if self.locked or self.button_refs[idx]["state"] == "disabled": + return + + btn = self.button_refs[idx] + btn.config(text=f"₹{self.cards[idx]}", bg="#9ACD32", fg="black", relief="sunken") + btn.update() + + if self.first_card_idx is None: + self.first_card_idx = idx + else: + self.locked = True + self.attempts += 1 + first_btn = self.button_refs[self.first_card_idx] + second_btn = btn + if self.cards[self.first_card_idx] == self.cards[idx]: + # Match + self.matches_found += 1 + first_btn.config(bg="#ffd700", fg="darkgreen", relief="flat") + second_btn.config(bg="#ffd700", fg="darkgreen", relief="flat") + first_btn.config(state="disabled") + second_btn.config(state="disabled") + self.master.after(400, self.after_match) + else: + # No match, flip back after delay + self.master.after(1100, self.hide_cards, self.first_card_idx, idx) + self.first_card_idx = None + self.update_status() + + def hide_cards(self, idx1, idx2): + for idx in [idx1, idx2]: + self.button_refs[idx].config(text="?", bg="#336699", fg="white", relief="raised", state="normal") + self.locked = False + + def after_match(self): + self.locked = False + if self.matches_found == 8: + self.update_status() + messagebox.showinfo("🎉 Game Over", f"Congratulations! You found all matches in {self.attempts} attempts!") + self.play_sound_win() + + def restart_game(self): + self.score = 0 + self.attempts = 0 + self.matches_found = 0 + self.first_card_idx = None + self.locked = False + self.button_refs = [] + self.create_board() + self.update_status() + + def play_sound_win(self): + # Simple sound feedback for successful completion + try: + import winsound + winsound.Beep(600, 250) + winsound.Beep(800, 450) + except Exception: + pass # skip if unsupported (Linux/macOS or no winsound) + +if __name__ == "__main__": + root = tk.Tk() + game = MemoryGame(root) + root.mainloop() From a5d9c60b93a722010f06b7cce55a4b09b577bbff Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 25 Sep 2025 16:43:49 +0530 Subject: [PATCH 02/15] Update money_memory_game.py --- money_memory_game.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/money_memory_game.py b/money_memory_game.py index 1ed48c501..bcf514d32 100644 --- a/money_memory_game.py +++ b/money_memory_game.py @@ -108,11 +108,14 @@ def restart_game(self): def play_sound_win(self): # Simple sound feedback for successful completion try: - import winsound - winsound.Beep(600, 250) - winsound.Beep(800, 450) - except Exception: - pass # skip if unsupported (Linux/macOS or no winsound) + try: + import winsound + winsound.Beep(600, 250) + winsound.Beep(800, 450) +except (ImportError, RuntimeError, AttributeError): + # winsound not available, skip sound + pass + if __name__ == "__main__": root = tk.Tk() From e91f30280a346d8ed02c718a84e5de947e0656d4 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:27:30 +0530 Subject: [PATCH 03/15] Update index.html add fontawesome icons to enhance user experiences --- Basic Contact Form/index.html | 86 +++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/Basic Contact Form/index.html b/Basic Contact Form/index.html index c8e85a124..09bf4de4e 100644 --- a/Basic Contact Form/index.html +++ b/Basic Contact Form/index.html @@ -1,40 +1,60 @@ - - - - - - Contact Form - + + + + + + + + Contact Form + -
-

Please Contact me

-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
- -
-
-
- - +
+

Please Contact me

- +
+
+ +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+
+ + + + From 31016be73ac4a2a1109633ffcdd3e45944549cce Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:29:16 +0530 Subject: [PATCH 04/15] Update style.css icon styles --- Basic Contact Form/style.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Basic Contact Form/style.css b/Basic Contact Form/style.css index 5c9f2e5a1..16de50264 100644 --- a/Basic Contact Form/style.css +++ b/Basic Contact Form/style.css @@ -15,6 +15,8 @@ form h1 { text-align: center; font-size: 22px; } +label .fa-solid { margin-right: 0.5rem; color: #666; } +button .fa-solid { margin-right: 0.4rem; } label { color: rgb(43, 134, 209); From f8a78c3139f89d48f55e4fd5c869c6bb893858fb Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:56:57 +0530 Subject: [PATCH 05/15] Update index.html changes --- AI Quote Generator/index.html | 53 ++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/AI Quote Generator/index.html b/AI Quote Generator/index.html index 5c505851a..9c1150e07 100644 --- a/AI Quote Generator/index.html +++ b/AI Quote Generator/index.html @@ -1,21 +1,48 @@ - - - AI Quotes Generator - + + + AI Quotes Generator + + + + + + + + + + + -
-

AI Quotes Generator

-
-
-
-

-
- +
+

+ + AI Quotes Generator +

+
+ +
+
+ +

Press the button to get an inspirational quote.

+
- + + +
+ + From 4cc58778b9b7b2404ea445375533f63dabdb6e7f Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:57:19 +0530 Subject: [PATCH 06/15] Update script.js --- AI Quote Generator/script.js | 67 +++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/AI Quote Generator/script.js b/AI Quote Generator/script.js index 18672ae5e..4b2f42f17 100644 --- a/AI Quote Generator/script.js +++ b/AI Quote Generator/script.js @@ -1,28 +1,47 @@ -const getQuoteBtn = document.getElementById("getQuoteBtn"); -const quoteText = document.getElementById("quoteText"); +// your code goes here +// script.js -getQuoteBtn.addEventListener("click", () => { - getQuoteBtn.classList.add("loading"); - getQuoteBtn.textContent = "Loading..."; - getQuote(); -}); +const btn = document.getElementById('getQuoteBtn'); +const quoteText = document.getElementById('quoteText'); +const quoteContainer = document.getElementById('quoteContainer'); -// Initially, remove loading state -getQuoteBtn.classList.remove("loading"); -getQuoteBtn.textContent = "Get Quote"; +// Util: set loading state with a spinner icon on the button +function setLoading(isLoading) { + quoteContainer.setAttribute('aria-busy', String(isLoading)); + if (isLoading) { + btn.setAttribute('disabled', 'true'); + // Replace wand icon with spinner + btn.innerHTML = ` Loading...`; + } else { + btn.removeAttribute('disabled'); + btn.innerHTML = ` Get Quote`; + } +} + +// Fetch a random quote from Quotable +async function fetchQuote() { + try { + setLoading(true); + // Quotable: GET https://api.quotable.io/random + const res = await fetch('https://api.quotable.io/random', { cache: 'no-store' }); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + const data = await res.json(); + + // Expecting { content, author } + const content = data.content?.trim() || 'No quote available right now.'; + const author = data.author ? ` — ${data.author}` : ''; -function getQuote() { - fetch("https://api.quotable.io/random") - .then((response) => response.json()) - .then((data) => { - quoteText.innerHTML = `"${data.content}" - ${data.author}`; - getQuoteBtn.classList.remove("loading"); - getQuoteBtn.textContent = "Get Quote"; - }) - .catch((error) => { - console.error("Error fetching quote:", error); - quoteText.innerHTML = "Failed to fetch a quote. Please try again later."; - getQuoteBtn.classList.remove("loading"); - getQuoteBtn.textContent = "Get Quote"; - }); + quoteText.textContent = `${content}${author}`; + } catch (err) { + console.error(err); + quoteText.textContent = 'Could not fetch a quote. Please try again.'; + } finally { + setLoading(false); + } } + +// Events +btn.addEventListener('click', fetchQuote); + +// Initial fetch on page load +window.addEventListener('DOMContentLoaded', fetchQuote); From 3920a0de0ba8a7c044d39b9b2eddaeb9d34e503e Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:57:50 +0530 Subject: [PATCH 07/15] Update styles.css --- AI Quote Generator/styles.css | 122 +++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/AI Quote Generator/styles.css b/AI Quote Generator/styles.css index 9517d8672..ad439e2ef 100644 --- a/AI Quote Generator/styles.css +++ b/AI Quote Generator/styles.css @@ -1,56 +1,98 @@ +/* styles.css */ +:root { + --accent: #3498db; + --bg: #0f172a; + --card: #111827; + --text: #e5e7eb; + --muted: #9ca3af; +} + +* { box-sizing: border-box; } + body { - font-family: Arial, sans-serif; - background-color: #3498db; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - align-items: center; - justify-content: flex-start; /* Adjusted to align header at the top */ - height: 100vh; + margin: 0; + background: + radial-gradient(1200px 600px at 10% -10%, #1e293b, transparent), + radial-gradient(1200px 600px at 90% -20%, #0b3a67, transparent), + var(--bg); + color: var(--text); + font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, "Noto Sans", "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + min-height: 100vh; + display: grid; + place-items: center; } header { - background-color: #2c3e50; - color: #ecf0f1; - text-align: center; - padding: 10px; - width: 100%; + text-align: center; + margin-top: 2rem; +} + +header h1 { + font-family: "Dancing Script", cursive; + font-weight: 700; + font-size: 2.4rem; + letter-spacing: 0.5px; + margin: 0 1rem; +} + +header h1 .fa-robot { + color: var(--accent); + margin-right: 0.5rem; } .container { - text-align: center; - background-color: #fff; - padding: 20px; - margin-left: 2%; - margin-right: 2%; - border-radius: 5px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + width: min(680px, 92vw); + margin: 2rem auto 4rem; + display: grid; + gap: 1rem; } -button { - padding: 10px 20px; - font-size: 18px; - cursor: pointer; /* Set default cursor to pointer */ - background-color: #3498db; /* Default background color */ - color: #fff; - border: none; - border-radius: 5px; - transition: background-color 0.3s, transform 0.3s, filter 0.3s; +#quoteContainer { + background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); + border: 1px solid rgba(255,255,255,0.06); + border-radius: 16px; + padding: 1.5rem 1.25rem; + position: relative; + box-shadow: 0 10px 30px rgba(0,0,0,0.25); } -button.loading { - background-color: #ddd; - cursor: not-allowed; +#quoteContainer .fa-quote-left, +#quoteContainer .fa-quote-right { + color: var(--muted); + font-size: 1rem; + opacity: 0.9; } -button:hover { - background-color: #2980b9; - transform: scale(1.05); /* Zoom in effect on hover */ - filter: brightness(0.9); /* Darken the button on hover */ +#quoteContainer .fa-quote-right { + float: right; } -#quoteContainer { - margin-top: 20px; - font-size: 20px; +#quoteText { + font-family: "Dancing Script", cursive; + font-size: 1.8rem; + line-height: 1.5; + margin: 0.5rem 0; + color: var(--text); + text-wrap: pretty; +} + +#getQuoteBtn { + background-color: var(--accent); + color: white; + border: none; + border-radius: 12px; + padding: 0.9rem 1.1rem; + font-size: 1rem; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 0.6rem; + justify-self: start; + transition: transform 0.05s ease, filter 0.2s ease, opacity 0.2s ease; } + +#getQuoteBtn:hover { filter: brightness(1.05); } +#getQuoteBtn:active { transform: translateY(1px); } +#getQuoteBtn[disabled] { opacity: 0.7; cursor: not-allowed; } + +#getQuoteBtn .fa-wand-magic-sparkles { font-size: 1.05rem; } From 8509f7fb2a3dbe7c643985c38834949f4614a954 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:26:15 +0530 Subject: [PATCH 08/15] Enhance Chuck-Norris-Jokes: Add Google Fonts (Poppins) and FontAwesome icons - Added modern Poppins font family from Google Fonts - Integrated FontAwesome 6.4.0 for icons throughout the UI - Enhanced HTML structure with semantic elements - Added icons to category buttons and UI elements - Improved accessibility with proper ARIA labels - Better semantic markup for improved code quality --- Chuck-Norris-Jokes/index.html | 155 +++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 38 deletions(-) diff --git a/Chuck-Norris-Jokes/index.html b/Chuck-Norris-Jokes/index.html index fe40eed3f..b07d91de4 100644 --- a/Chuck-Norris-Jokes/index.html +++ b/Chuck-Norris-Jokes/index.html @@ -1,48 +1,127 @@ - - - Chuck Norris + Chuck Norris Jokes Generator + + + + + + + + + - - - -

Chuck Norries

-
- - - -
- - - -
- - - -
- - - - -
- - +
+
+ +

Chuck Norris Jokes

+

Get ready to laugh with legendary Chuck Norris jokes!

+
+ +
+
+

Select Category:

+
+ + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + Selected Category: + None +
+ +
+ +

Click a category button to get started!

+ +
+ + +
+
-

Selected Category:

-

-
-

- -
- -
+
+

Powered by Chuck Norris API

+
+
- - - \ No newline at end of file + + + From 21cf2588d75bd63c8d638201caee05bb964fa9f7 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:28:19 +0530 Subject: [PATCH 09/15] Enhance Chuck-Norris-Jokes: Modern CSS with responsive design and animations - Implemented modern gradient backgrounds and card-based layout - Added smooth animations and hover effects for better UX - Enhanced typography using Poppins font throughout - Improved button styling with icons and transitions - Added responsive design for mobile and tablet devices - Better spacing, shadows, and visual hierarchy - Enhanced readability and accessibility --- Chuck-Norris-Jokes/style.css | 370 ++++++++++++++++++++++++++++++----- 1 file changed, 318 insertions(+), 52 deletions(-) diff --git a/Chuck-Norris-Jokes/style.css b/Chuck-Norris-Jokes/style.css index 2e546dc2c..8c4a666f0 100644 --- a/Chuck-Norris-Jokes/style.css +++ b/Chuck-Norris-Jokes/style.css @@ -1,53 +1,319 @@ -*{ - margin-bottom:1rem;; - padding:0; - text-align:center; -} - -div{ - width:22rem; - height:15rem; - text-align:center; - margin:auto; - margin-bottom:1.5rem; - padding:10px; -} -#box1{ - background-color:lightslategrey; - display:flex; - flex-wrap:wrap; - justify-content:space-evenly; -} -#box2{ - background-color:blue; -} - -h3{ - font-size:30px -} -button{ - width:5rem; - height:2rem; - margin:0.2rem; - border:none; - border-radius:5px; - box-shadow:1px 1px rgb(95, 92, 92); - font-size:1rem; -} - -p{ - display:inline-block; - font-size:20px; -} -p#joke{ - color:white; - font-size:1.5rem; - margin:30px; -} -#footer{ - color:blue; - font-size:1rem; -} -hr{ - width:10rem; +/* Enhanced Chuck Norris Jokes - Modern Styling with Poppins Font */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Poppins', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; + line-height: 1.6; +} + +.container { + max-width: 1100px; + width: 100%; + background: rgba(255, 255, 255, 0.95); + border-radius: 20px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + padding: 40px; + animation: fadeIn 0.6s ease-in; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Header Styles */ +header { + text-align: center; + margin-bottom: 40px; + padding-bottom: 30px; + border-bottom: 2px solid #e0e0e0; +} + +.header-icon { + font-size: 3rem; + color: #667eea; + margin-bottom: 15px; + animation: punch 2s ease-in-out infinite; +} + +@keyframes punch { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.1); + } +} + +header h1 { + font-size: 2.5rem; + font-weight: 700; + color: #333; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.subtitle { + font-size: 1.1rem; + color: #666; + font-weight: 300; +} + +/* Category Section */ +.category-section { + margin-bottom: 35px; +} + +.category-section h2 { + font-size: 1.5rem; + color: #333; + margin-bottom: 20px; + font-weight: 600; + display: flex; + align-items: center; + gap: 10px; +} + +.category-section h2 i { + color: #667eea; +} + +.category-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + gap: 12px; + padding: 20px; + background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + border-radius: 15px; +} + +.category-btn { + background: white; + border: 2px solid transparent; + border-radius: 12px; + padding: 15px 10px; + font-size: 0.9rem; + font-weight: 500; + color: #333; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + font-family: 'Poppins', sans-serif; +} + +.category-btn i { + font-size: 1.5rem; + color: #667eea; + transition: transform 0.3s ease; +} + +.category-btn:hover { + transform: translateY(-3px); + box-shadow: 0 6px 12px rgba(102, 126, 234, 0.4); + border-color: #667eea; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +.category-btn:hover i { + color: white; + transform: scale(1.2); +} + +.category-btn:active { + transform: translateY(-1px); +} + +/* Joke Section */ +.joke-section { + margin-top: 30px; +} + +.category-display { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 20px; + padding: 12px 20px; + background: #f8f9fa; + border-radius: 10px; + font-size: 1rem; + color: #555; +} + +.category-display i { + color: #667eea; +} + +.category-display strong { + color: #667eea; + font-weight: 600; +} + +.joke-container { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 40px 30px; + border-radius: 15px; + box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3); + min-height: 200px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; + margin-bottom: 25px; +} + +.quote-icon { + font-size: 2rem; + opacity: 0.3; + position: absolute; +} + +.quote-icon.fa-quote-left { + top: 15px; + left: 20px; +} + +.quote-icon.fa-quote-right { + bottom: 15px; + right: 20px; +} + +.joke-text { + font-size: 1.3rem; + font-weight: 400; + line-height: 1.8; + text-align: center; + z-index: 1; + padding: 0 30px; +} + +.new-joke-btn { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + border-radius: 50px; + padding: 15px 40px; + font-size: 1.1rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); + font-family: 'Poppins', sans-serif; + margin: 0 auto; +} + +.new-joke-btn i { + font-size: 1.2rem; + transition: transform 0.3s ease; +} + +.new-joke-btn:hover { + transform: translateY(-3px); + box-shadow: 0 12px 30px rgba(102, 126, 234, 0.5); +} + +.new-joke-btn:hover i { + transform: rotate(360deg); +} + +.new-joke-btn:active { + transform: translateY(-1px); +} + +/* Footer */ +.page-footer { + text-align: center; + margin-top: 40px; + padding-top: 20px; + border-top: 2px solid #e0e0e0; + color: #666; + font-size: 0.9rem; +} + +.page-footer i { + color: #667eea; + margin-right: 5px; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .container { + padding: 25px; + } + + header h1 { + font-size: 2rem; + } + + .category-grid { + grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); + gap: 10px; + padding: 15px; + } + + .category-btn { + padding: 12px 8px; + font-size: 0.85rem; + } + + .joke-text { + font-size: 1.1rem; + padding: 0 15px; + } + + .new-joke-btn { + padding: 12px 30px; + font-size: 1rem; + } +} + +@media (max-width: 480px) { + header h1 { + font-size: 1.6rem; + } + + .subtitle { + font-size: 0.95rem; + } + + .category-grid { + grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); + } + + .joke-container { + padding: 30px 20px; + min-height: 160px; + } + + .joke-text { + font-size: 1rem; + } } From 12a828c7e441f87d329467dac90024b1ba9a998d Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:30:55 +0530 Subject: [PATCH 10/15] Enhance Age Calculator: Complete upgrade with Google Fonts, FontAwesome, and modern design - Added Inter font family from Google Fonts for modern typography - Integrated FontAwesome 6.4.0 for icons throughout the UI - Enhanced HTML structure with semantic elements and proper sections - Added icons to header, inputs, buttons, and results - Improved accessibility with ARIA labels and better semantics - Better code structure with proper indentation and organization - Ready for CSS and JS enhancements --- Age Calculator/index.html | 78 ++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/Age Calculator/index.html b/Age Calculator/index.html index 0b682201a..b7cef1427 100644 --- a/Age Calculator/index.html +++ b/Age Calculator/index.html @@ -4,20 +4,78 @@ + Age Calculator - Calculate Your Age + + + + + + + + + - Age Calculator
-

-

Enter the DOB badri in format : (MM/DD/YYYY)

- - +
+ +

Age Calculator

+

Calculate your exact age in years, months, and days

+
+ +
+
+
+ +

Loading current date...

+
+
+ +
+ +
+ +
+

+ + Select your date of birth from the calendar +

+
+ +
+ +
+ + +
+ +
+

+ + Made with love to help you calculate your age +

+
-
-

-
- + + From 30cb0945e87531e7f030ef63ded1172fdfd7e3fe Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:32:41 +0530 Subject: [PATCH 11/15] Enhance Age Calculator CSS: Complete modern styling upgrade - Implemented modern gradient backgrounds with purple theme - Added smooth animations (fadeInUp, bounce, shimmer, heartbeat) - Enhanced typography using Inter font throughout - Improved button and input styling with hover effects - Added responsive design for all device sizes - Better visual hierarchy with shadows and spacing - Enhanced result display with animated container - Improved accessibility and readability --- Age Calculator/style.css | 442 ++++++++++++++++++++++++++++++++------- 1 file changed, 368 insertions(+), 74 deletions(-) diff --git a/Age Calculator/style.css b/Age Calculator/style.css index 071e24779..17515684a 100644 --- a/Age Calculator/style.css +++ b/Age Calculator/style.css @@ -1,75 +1,369 @@ -*{ - margin:0; - padding:0; - box-sizing:border-box; - font-family:cursive; -} - -.container{ - display:flex; - width:600px; - margin:auto; - margin-top:10%; - margin-bottom:10%; - align-items:center; - justify-content:center; - flex-direction:column; - background-color:darkslateblue; - box-shadow:8px 8px black; - color:white; - padding:5% 0%; -} - -#currDate{ - font-size:40px; - font-weight:bold; -} - -input{ - font-size:20px; - padding:15px; - margin:20px; - text-align:center; - border-radius:20px; - border:1px solid yellow; - cursor:pointer; -} - -button{ - font-size:20px; - padding:10px 20px; - border-radius:10px; - border:none; - background-color:yellow; - color:black; - margin:20px; - text-transform: uppercase; - font-weight:bold; - cursor:pointer; -} - -button:hover{ - background-color:white; - color:blue; -} - -#displayAge{ - display:flex; - align-items:center; - justify-content:center; - width:620px; - height:480px; - background-color:rgb(228, 91, 91); - border-radius:30px; - position:absolute; - top:19%; - left:30%; - visibility: hidden; -} - -#age{ - color:white; - font-size:50px; - margin:20px; - font-weight:bold; +/* Enhanced Age Calculator - Modern Styling with Inter Font */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Inter', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; + line-height: 1.6; +} + +.container { + max-width: 600px; + width: 100%; + background: rgba(255, 255, 255, 0.98); + border-radius: 25px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + padding: 40px; + animation: fadeInUp 0.6s ease-out; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Header Styles */ +.app-header { + text-align: center; + margin-bottom: 35px; + padding-bottom: 25px; + border-bottom: 2px solid #e0e0e0; +} + +.header-icon { + font-size: 3.5rem; + color: #667eea; + margin-bottom: 15px; + animation: bounce 2s ease-in-out infinite; +} + +@keyframes bounce { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-10px); + } +} + +.app-header h1 { + font-size: 2.5rem; + font-weight: 700; + color: #333; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.subtitle { + font-size: 1rem; + color: #666; + font-weight: 400; +} + +/* Current Date Section */ +.current-date-section { + margin-bottom: 30px; +} + +.date-display { + background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + padding: 20px; + border-radius: 15px; + display: flex; + align-items: center; + gap: 15px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.date-display i { + font-size: 2rem; + color: #667eea; +} + +.current-date { + font-size: 1.3rem; + font-weight: 600; + color: #333; + margin: 0; +} + +/* Input Section */ +.input-section { + margin-bottom: 25px; +} + +.input-label { + display: flex; + align-items: center; + gap: 10px; + font-size: 1.1rem; + font-weight: 600; + color: #333; + margin-bottom: 15px; +} + +.input-label i { + color: #667eea; + font-size: 1.3rem; +} + +.input-wrapper { + margin-bottom: 12px; +} + +.date-input { + width: 100%; + font-size: 1.1rem; + padding: 15px 20px; + border: 2px solid #e0e0e0; + border-radius: 12px; + font-family: 'Inter', sans-serif; + transition: all 0.3s ease; + background: white; + color: #333; + cursor: pointer; +} + +.date-input:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1); +} + +.date-input:hover { + border-color: #667eea; +} + +.input-hint { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.9rem; + color: #666; + margin-top: 8px; +} + +.input-hint i { + color: #667eea; +} + +/* Action Section */ +.action-section { + margin-bottom: 30px; +} + +.calculate-btn { + width: 100%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + border-radius: 50px; + padding: 18px 40px; + font-size: 1.2rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); + font-family: 'Inter', sans-serif; +} + +.calculate-btn i { + font-size: 1.3rem; + transition: transform 0.3s ease; +} + +.calculate-btn:hover { + transform: translateY(-3px); + box-shadow: 0 12px 30px rgba(102, 126, 234, 0.5); +} + +.calculate-btn:hover i { + transform: scale(1.2); +} + +.calculate-btn:active { + transform: translateY(-1px); +} + +.calculate-btn:disabled { + background: #ccc; + cursor: not-allowed; + box-shadow: none; +} + +/* Result Section */ +.result-section { + margin-top: 30px; + animation: slideIn 0.5s ease-out; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.result-container { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 35px; + border-radius: 20px; + text-align: center; + box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3); + position: relative; + overflow: hidden; +} + +.result-container::before { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%); + animation: shimmer 3s infinite; +} + +@keyframes shimmer { + 0% { + transform: translate(-50%, -50%); + } + 50% { + transform: translate(0%, 0%); + } + 100% { + transform: translate(-50%, -50%); + } +} + +.result-icon { + font-size: 3rem; + margin-bottom: 15px; + color: #4ade80; + position: relative; + z-index: 1; +} + +.result-container h2 { + font-size: 1.8rem; + font-weight: 700; + margin-bottom: 15px; + position: relative; + z-index: 1; +} + +.age-result { + font-size: 1.3rem; + font-weight: 500; + line-height: 1.8; + position: relative; + z-index: 1; + margin: 0; +} + +/* Footer */ +.app-footer { + text-align: center; + margin-top: 30px; + padding-top: 25px; + border-top: 2px solid #e0e0e0; + color: #666; + font-size: 0.95rem; +} + +.app-footer i { + color: #e74c3c; + margin-right: 5px; + animation: heartbeat 1.5s ease-in-out infinite; +} + +@keyframes heartbeat { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.1); + } +} + +/* Responsive Design */ +@media (max-width: 768px) { + .container { + padding: 30px 25px; + } + + .app-header h1 { + font-size: 2rem; + } + + .header-icon { + font-size: 2.5rem; + } + + .current-date { + font-size: 1.1rem; + } + + .calculate-btn { + padding: 15px 30px; + font-size: 1.1rem; + } + + .result-container h2 { + font-size: 1.5rem; + } + + .age-result { + font-size: 1.1rem; + } +} + +@media (max-width: 480px) { + .container { + padding: 25px 20px; + } + + .app-header h1 { + font-size: 1.7rem; + } + + .subtitle { + font-size: 0.9rem; + } + + .date-display { + flex-direction: column; + text-align: center; + gap: 10px; + } + + .current-date { + font-size: 1rem; + } } From d6cedfbf56b9d51d29fd29f029df83d061d60e69 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:34:13 +0530 Subject: [PATCH 12/15] Enhance Age Calculator JS: Complete refactoring with modern ES6+ and improved functionality - Refactored to modern ES6+ syntax with proper function organization - Added comprehensive JSDoc comments for all functions - Implemented detailed age calculation (years, months, days, total days) - Added input validation and error handling - Included birthday detection with celebration message - Smooth scrolling to results - Better code structure and readability - Improved accessibility and user experience --- Age Calculator/script.js | 205 +++++++++++++++++++++++++++++++++++---- 1 file changed, 187 insertions(+), 18 deletions(-) diff --git a/Age Calculator/script.js b/Age Calculator/script.js index d6ed6d8e1..59b702c0f 100644 --- a/Age Calculator/script.js +++ b/Age Calculator/script.js @@ -1,19 +1,188 @@ -let currDate= document.getElementById("currDate"); -let dateOfBirth = document.querySelector("#DOB"); -const CalcAge= document.getElementById("CalcAge"); -const displayAge= document.getElementById("displayAge"); -const Age= document.getElementById("age"); -var today = new Date(); -currDate.innerText=`Today's Date is : ${today.toLocaleDateString('en-US')}`; - -CalcAge.addEventListener("click",()=>{ - var birthDate = new Date(dateOfBirth.value); - var age = today.getFullYear() - birthDate.getFullYear(); - var m = today.getMonth() - birthDate.getMonth(); - if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) { - age = age - 1; - } -displayAge.style.visibility="visible"; -Age.innerText=`You are ${age} years old.` -}); +/** + * Enhanced Age Calculator Script + * Calculates age in years, months, and days with improved error handling + */ +// DOM Element References +const currDateElement = document.getElementById('currDate'); +const dateOfBirthInput = document.getElementById('DOB'); +const calculateButton = document.getElementById('CalcAge'); +const displayAgeSection = document.getElementById('displayAge'); +const ageResultElement = document.getElementById('age'); + +// Get current date +const today = new Date(); + +/** + * Initialize the application + */ +function initializeApp() { + // Display current date with formatting + displayCurrentDate(); + + // Set max date to today (prevent future dates) + setMaxDate(); + + // Add event listeners + calculateButton.addEventListener('click', calculateAge); + dateOfBirthInput.addEventListener('keypress', handleEnterKey); +} + +/** + * Display formatted current date + */ +function displayCurrentDate() { + const options = { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }; + const formattedDate = today.toLocaleDateString('en-US', options); + currDateElement.textContent = formattedDate; +} + +/** + * Set maximum date for date input (today) + */ +function setMaxDate() { + const todayString = today.toISOString().split('T')[0]; + dateOfBirthInput.setAttribute('max', todayString); +} + +/** + * Handle Enter key press on date input + */ +function handleEnterKey(event) { + if (event.key === 'Enter') { + calculateAge(); + } +} + +/** + * Calculate age based on date of birth + */ +function calculateAge() { + // Validate input + if (!dateOfBirthInput.value) { + showError('Please select your date of birth'); + return; + } + + const birthDate = new Date(dateOfBirthInput.value); + + // Validate date + if (isNaN(birthDate.getTime())) { + showError('Invalid date. Please select a valid date.'); + return; + } + + // Check if birth date is in the future + if (birthDate > today) { + showError('Birth date cannot be in the future!'); + return; + } + + // Calculate age components + const ageDetails = calculateDetailedAge(birthDate); + + // Display results + displayResults(ageDetails); +} + +/** + * Calculate detailed age (years, months, days) + * @param {Date} birthDate - The birth date + * @returns {Object} Object containing years, months, and days + */ +function calculateDetailedAge(birthDate) { + let years = today.getFullYear() - birthDate.getFullYear(); + let months = today.getMonth() - birthDate.getMonth(); + let days = today.getDate() - birthDate.getDate(); + + // Adjust for negative days + if (days < 0) { + months--; + // Get days in previous month + const lastMonth = new Date(today.getFullYear(), today.getMonth(), 0); + days += lastMonth.getDate(); + } + + // Adjust for negative months + if (months < 0) { + years--; + months += 12; + } + + // Calculate total days lived + const timeDiff = today - birthDate; + const totalDays = Math.floor(timeDiff / (1000 * 60 * 60 * 24)); + + return { years, months, days, totalDays }; +} + +/** + * Display age calculation results + * @param {Object} ageDetails - Object containing age details + */ +function displayResults(ageDetails) { + const { years, months, days, totalDays } = ageDetails; + + // Create result message + let resultHTML = ` + + ${years} ${years === 1 ? 'Year' : 'Years'} + + `; + + // Add months and days if not zero + if (months > 0 || days > 0) { + const parts = []; + if (months > 0) parts.push(`${months} ${months === 1 ? 'Month' : 'Months'}`); + if (days > 0) parts.push(`${days} ${days === 1 ? 'Day' : 'Days'}`); + resultHTML += `
${parts.join(', ')}
`; + } + + // Add total days + resultHTML += `
That's ${totalDays.toLocaleString()} days!
`; + + // Check for birthday + if (months === 0 && days === 0) { + resultHTML += `
🎉 Happy Birthday! 🎂
`; + } + + // Update DOM + ageResultElement.innerHTML = resultHTML; + displayAgeSection.style.display = 'block'; + + // Smooth scroll to results + setTimeout(() => { + displayAgeSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + }, 100); +} + +/** + * Show error message + * @param {string} message - Error message to display + */ +function showError(message) { + ageResultElement.innerHTML = ` +
+ + ${message} +
+ `; + displayAgeSection.style.display = 'block'; + + // Hide error after 3 seconds + setTimeout(() => { + displayAgeSection.style.display = 'none'; + }, 3000); +} + +// Initialize the app when DOM is fully loaded +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initializeApp); +} else { + initializeApp(); +} From de241d5fe2bc3a2666d1dd64411b552d6efe4197 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:36:18 +0530 Subject: [PATCH 13/15] Enhance Password Generator: Complete upgrade with Roboto font, FontAwesome 6.4.0, and modern design - Added Roboto font family from Google Fonts - Upgraded to FontAwesome 6.4.0 for modern icons - Enhanced HTML structure with semantic sections - Added icons to all UI elements (header, buttons, settings) - Improved accessibility with ARIA labels - Better semantic markup and organization - Included Vanilla Tilt library for 3D effect - Ready for CSS and JS enhancements --- Password Generator/index.html | 170 +++++++++++++++++++++++++--------- 1 file changed, 124 insertions(+), 46 deletions(-) diff --git a/Password Generator/index.html b/Password Generator/index.html index 8175245aa..e5267c177 100644 --- a/Password Generator/index.html +++ b/Password Generator/index.html @@ -1,58 +1,136 @@ - - - - - + + + Password Generator - Create Secure Passwords + + + + + + + + + + - Password Generator + + - -
-
-

Password Generator

-
- - -
-
-
- - -
-
- - -
-
- - +
+
+ +

Password Generator

+

Create strong and secure passwords instantly

+
+ +
+
+

+ + Generated Password +

+
+ Click generate to create password +
-
- - +
+ +
+

+ + Settings +

+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
-
- - -
-
-
- - + + +
+ +
+ + +
+

+ + Your passwords are generated locally and never stored +

+
+ - - - From e76caf8806b4f6bed3a15e946599111bfdcf6fca Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:38:06 +0530 Subject: [PATCH 14/15] Enhance Password Generator CSS: Complete modern styling upgrade with Roboto font - Implemented modern gradient backgrounds with purple theme - Added smooth animations (fadeIn, pulse, hover effects) - Enhanced typography using Roboto font throughout - Improved button styling with 3D effects and transitions - Custom checkbox toggle switches - Better visual hierarchy with sections and spacing - Card design with Vanilla Tilt 3D support - Fully responsive for all devices --- Password Generator/style.css | 383 +++++++++++++++++++++++++++++------ 1 file changed, 324 insertions(+), 59 deletions(-) diff --git a/Password Generator/style.css b/Password Generator/style.css index eca06f768..a49353546 100644 --- a/Password Generator/style.css +++ b/Password Generator/style.css @@ -1,84 +1,349 @@ -@import url('https://fonts.googleapis.com/css?family=Muli&display=swap'); +/* Enhanced Password Generator - Modern Styling with Roboto Font */ * { - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } body { - background-color: #3b4498; - color: rgb(255, 255, 255); - font-family: 'Muli'; - font-weight: 500; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100vh; - overflow: hidden; - padding: 10px; - margin: 0; -} - -h2 { - margin: 10px 0 20px; - text-align: center; - font-weight: 1000; + font-family: 'Roboto', sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; + overflow-x: hidden; } +/* Card Container with 3D Tilt Effect */ +.card { + background: rgba(255, 255, 255, 0.98); + border-radius: 25px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + padding: 40px; + width: 100%; + max-width: 550px; + animation: fadeIn 0.6s ease-out; + transform-style: preserve-3d; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Header Styles */ +.app-header { + text-align: center; + margin-bottom: 35px; + padding-bottom: 25px; + border-bottom: 2px solid #e0e0e0; +} + +.header-icon { + font-size: 3.5rem; + color: #667eea; + margin-bottom: 15px; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } +} + +.app-header h1 { + font-size: 2.5rem; + font-weight: 700; + color: #333; + margin-bottom: 10px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +.subtitle { + font-size: 1rem; + color: #666; + font-weight: 400; +} + +/* Container */ .container { - background-color: #7a4fac; - box-shadow: 0px 2px 10px rgba(255, 255, 255, 0.2); - padding: 20px; - width: 350px; - max-width: 100%; + width: 100%; +} + +/* Section Titles */ +.section-title { + display: flex; + align-items: center; + gap: 10px; + font-size: 1.3rem; + font-weight: 600; + color: #333; + margin-bottom: 20px; +} + +.section-title i { + color: #667eea; + font-size: 1.4rem; +} + +/* Result Section */ +.result-section { + margin-bottom: 30px; } .result-container { - background-color: rgba(0, 0, 0, 0.247); - display: flex; - justify-content: flex-start; - align-items: center; - position: relative; - font-size: 18px; - font-weight: bold; - letter-spacing: 1px; - padding: 12px 10px; - height: 50px; - width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + padding: 20px; + border-radius: 12px; + border: 2px solid #e0e0e0; + transition: all 0.3s ease; } -.result-container #result { - word-wrap: break-word; - max-width: calc(100% - 40px); +.result-container:hover { + border-color: #667eea; + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2); } -.result-container .btn { - position: absolute; - top: 5px; - right: 5px; - width: 40px; - height: 40px; - font-size: 20px; +.password-display { + font-size: 1.3rem; + font-weight: 500; + color: #333; + word-break: break-all; + flex: 1; + font-family: 'Courier New', monospace; } +/* Buttons */ .btn { - border: none; - background-color: #2c085c; - color: #fff; - font-size: 16px; - padding: 8px 12px; - cursor: pointer; + border: none; + cursor: pointer; + transition: all 0.3s ease; + font-family: 'Roboto', sans-serif; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; +} + +.btn:active { + transform: scale(0.98); +} + +.btn-copy { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 12px 18px; + border-radius: 10px; + font-size: 1.2rem; + box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3); +} + +.btn-copy:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4); +} + +.btn-generate { + width: 100%; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 18px 40px; + border-radius: 50px; + font-size: 1.2rem; + font-weight: 600; + box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); +} + +.btn-generate i { + font-size: 1.3rem; + transition: transform 0.3s ease; +} + +.btn-generate:hover { + transform: translateY(-3px); + box-shadow: 0 12px 30px rgba(102, 126, 234, 0.5); } -.btn-large { - display: block; - width: 100%; +.btn-generate:hover i { + transform: rotate(360deg); +} + +/* Settings Section */ +.settings-section { + margin-bottom: 25px; +} + +.settings { + background: #f8f9fa; + padding: 25px; + border-radius: 15px; } .setting { - display: flex; - justify-content: space-between; - align-items: center; - margin: 15px 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0; + border-bottom: 1px solid #e0e0e0; +} + +.setting:last-child { + border-bottom: none; +} + +.setting label { + display: flex; + align-items: center; + gap: 10px; + font-size: 1rem; + color: #333; + font-weight: 500; + flex: 1; + cursor: pointer; +} + +.setting label i { + color: #667eea; + font-size: 1.1rem; + width: 20px; + text-align: center; +} + +.setting input[type="number"] { + width: 70px; + padding: 8px 12px; + border: 2px solid #e0e0e0; + border-radius: 8px; + font-size: 1rem; + font-family: 'Roboto', sans-serif; + font-weight: 500; + text-align: center; + transition: all 0.3s ease; +} + +.setting input[type="number"]:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1); +} + +.setting input[type="checkbox"] { + width: 50px; + height: 25px; + position: relative; + appearance: none; + background: #ccc; + border-radius: 25px; + outline: none; + cursor: pointer; + transition: all 0.3s ease; } +.setting input[type="checkbox"]:checked { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +} + +.setting input[type="checkbox"]::before { + content: ''; + position: absolute; + width: 21px; + height: 21px; + border-radius: 50%; + top: 2px; + left: 2px; + background: white; + transition: all 0.3s ease; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} + +.setting input[type="checkbox"]:checked::before { + left: 27px; +} + +/* Action Section */ +.action-section { + margin-top: 25px; +} + +/* Footer */ +.app-footer { + text-align: center; + margin-top: 30px; + padding-top: 25px; + border-top: 2px solid #e0e0e0; + color: #666; + font-size: 0.9rem; +} + +.app-footer i { + color: #667eea; + margin-right: 5px; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .card { + padding: 30px 25px; + } + + .app-header h1 { + font-size: 2rem; + } + + .header-icon { + font-size: 2.5rem; + } + + .password-display { + font-size: 1.1rem; + } + + .btn-generate { + padding: 15px 30px; + font-size: 1.1rem; + } +} + +@media (max-width: 480px) { + .card { + padding: 25px 20px; + } + + .app-header h1 { + font-size: 1.7rem; + } + + .subtitle { + font-size: 0.9rem; + } + + .section-title { + font-size: 1.1rem; + } + + .setting label { + font-size: 0.9rem; + } + + .password-display { + font-size: 1rem; + } +} From 3398c57dab152ece22459c74e0b7c3e08af5a334 Mon Sep 17 00:00:00 2001 From: "MR.NOBODY" <126796695+TacticalReader@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:39:58 +0530 Subject: [PATCH 15/15] Enhance Password Generator JS: Complete refactoring with modern ES6+, notifications, and improved UX - Refactored to modern ES6+ syntax with async/await - Added comprehensive JSDoc comments for all functions - Implemented modern Clipboard API with fallback - Added visual notifications for user feedback - Password shuffling for better randomness - Input validation and error handling - Auto-generate password on load - Better code organization and structure - Improved accessibility and user experience --- Password Generator/script.js | 309 +++++++++++++++++++++++++++++------ 1 file changed, 261 insertions(+), 48 deletions(-) diff --git a/Password Generator/script.js b/Password Generator/script.js index 408e9fb3e..515e9916d 100644 --- a/Password Generator/script.js +++ b/Password Generator/script.js @@ -1,78 +1,291 @@ -const resultEl = document.getElementById('result') -const lengthEl = document.getElementById('length') -const uppercaseEl = document.getElementById('uppercase') -const lowercaseEl = document.getElementById('lowercase') -const numbersEl = document.getElementById('numbers') -const symbolsEl = document.getElementById('symbols') -const generateEl = document.getElementById('generate') -const clipboardEl = document.getElementById('clipboard') - -const randomFunc = { +/** + * Enhanced Password Generator Script + * Generates secure passwords with customizable options + */ + +// DOM Element References +const resultElement = document.getElementById('result'); +const lengthElement = document.getElementById('length'); +const uppercaseElement = document.getElementById('uppercase'); +const lowercaseElement = document.getElementById('lowercase'); +const numbersElement = document.getElementById('numbers'); +const symbolsElement = document.getElementById('symbols'); +const generateButton = document.getElementById('generate'); +const clipboardButton = document.getElementById('clipboard'); + +// Character generation functions mapped to their types +const characterGenerators = { lower: getRandomLower, upper: getRandomUpper, number: getRandomNumber, symbol: getRandomSymbol +}; + +/** + * Initialize the application + */ +function initializeApp() { + // Add event listeners + clipboardButton.addEventListener('click', copyToClipboard); + generateButton.addEventListener('click', handleGeneratePassword); + lengthElement.addEventListener('input', validateLength); + + // Generate initial password + handleGeneratePassword(); } -clipboardEl.addEventListener('click', () => { - const textarea = document.createElement('textarea') - const password = resultEl.innerText +/** + * Validate password length input + */ +function validateLength() { + const length = parseInt(lengthElement.value); + const min = parseInt(lengthElement.min); + const max = parseInt(lengthElement.max); + + if (length < min) lengthElement.value = min; + if (length > max) lengthElement.value = max; +} - if(!password) { return } +/** + * Copy password to clipboard with modern Clipboard API + */ +async function copyToClipboard() { + const password = resultElement.textContent; + + // Validate password exists + if (!password || password === 'Click generate to create password') { + showNotification('Please generate a password first!', 'warning'); + return; + } + + try { + // Try modern Clipboard API first + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(password); + showNotification('Password copied to clipboard!', 'success'); + + // Visual feedback on copy button + const originalIcon = clipboardButton.innerHTML; + clipboardButton.innerHTML = ''; + clipboardButton.style.background = 'linear-gradient(135deg, #10b981 0%, #059669 100%)'; + + setTimeout(() => { + clipboardButton.innerHTML = originalIcon; + clipboardButton.style.background = ''; + }, 2000); + } else { + // Fallback for older browsers + copyToClipboardFallback(password); + } + } catch (error) { + console.error('Copy failed:', error); + copyToClipboardFallback(password); + } +} - textarea.value = password - document.body.appendChild(textarea) - textarea.select() - document.execCommand('copy') - textarea.remove() - alert('Password copied to clipboard!') -}) +/** + * Fallback clipboard copy method for older browsers + * @param {string} text - Text to copy + */ +function copyToClipboardFallback(text) { + const textarea = document.createElement('textarea'); + textarea.value = text; + textarea.style.position = 'fixed'; + textarea.style.left = '-9999px'; + document.body.appendChild(textarea); + textarea.select(); + + try { + document.execCommand('copy'); + showNotification('Password copied to clipboard!', 'success'); + } catch (error) { + console.error('Fallback copy failed:', error); + showNotification('Failed to copy password', 'error'); + } finally { + textarea.remove(); + } +} -generateEl.addEventListener('click', () => { - const length = +lengthEl.value - const hasLower = lowercaseEl.checked - const hasUpper = uppercaseEl.checked - const hasNumber = numbersEl.checked - const hasSymbol = symbolsEl.checked +/** + * Show notification message to user + * @param {string} message - Message to display + * @param {string} type - Notification type (success, error, warning) + */ +function showNotification(message, type = 'info') { + // Create notification element + const notification = document.createElement('div'); + notification.textContent = message; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + padding: 15px 25px; + background: ${type === 'success' ? 'linear-gradient(135deg, #10b981 0%, #059669 100%)' : + type === 'error' ? 'linear-gradient(135deg, #ef4444 0%, #dc2626 100%)' : + 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)'}; + color: white; + border-radius: 10px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); + font-family: 'Roboto', sans-serif; + font-weight: 500; + z-index: 10000; + animation: slideIn 0.3s ease-out; + `; + + document.body.appendChild(notification); + + // Remove after 3 seconds + setTimeout(() => { + notification.style.animation = 'slideOut 0.3s ease-out'; + setTimeout(() => notification.remove(), 300); + }, 3000); +} - resultEl.innerText = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length) -}) +/** + * Handle password generation + */ +function handleGeneratePassword() { + const length = parseInt(lengthElement.value); + const hasLower = lowercaseElement.checked; + const hasUpper = uppercaseElement.checked; + const hasNumber = numbersElement.checked; + const hasSymbol = symbolsElement.checked; + + // Validate at least one option is selected + if (!hasLower && !hasUpper && !hasNumber && !hasSymbol) { + showNotification('Please select at least one character type!', 'warning'); + resultElement.textContent = 'Select at least one option'; + return; + } + + // Generate password + const password = generatePassword(hasLower, hasUpper, hasNumber, hasSymbol, length); + resultElement.textContent = password; + + // Add animation to result + resultElement.style.animation = 'none'; + setTimeout(() => { + resultElement.style.animation = 'fadeIn 0.5s ease-out'; + }, 10); +} +/** + * Generate secure password based on selected criteria + * @param {boolean} lower - Include lowercase letters + * @param {boolean} upper - Include uppercase letters + * @param {boolean} number - Include numbers + * @param {boolean} symbol - Include symbols + * @param {number} length - Password length + * @returns {string} Generated password + */ function generatePassword(lower, upper, number, symbol, length) { - let generatedPassword = '' - const typesCount = lower + upper + number + symbol - const typesArr = [{lower}, {upper}, {number}, {symbol}].filter(item => Object.values(item)[0]) + let generatedPassword = ''; + const typesCount = lower + upper + number + symbol; + + // Create array of selected types + const typesArray = [ + { lower }, + { upper }, + { number }, + { symbol } + ].filter(item => Object.values(item)[0]); - if(typesCount === 0) { - return '' + // Return empty if no types selected + if (typesCount === 0) { + return ''; } - - for(let i = 0; i < length; i += typesCount) { - typesArr.forEach(type => { - const funcName = Object.keys(type)[0] - generatedPassword += randomFunc[funcName]() - }) + + // Generate password by cycling through selected types + for (let i = 0; i < length; i += typesCount) { + typesArray.forEach(type => { + const funcName = Object.keys(type)[0]; + generatedPassword += characterGenerators[funcName](); + }); } + + // Shuffle the password for better randomness + const finalPassword = shuffleString(generatedPassword.slice(0, length)); + + return finalPassword; +} - const finalPassword = generatedPassword.slice(0, length) - - return finalPassword +/** + * Shuffle string characters for better randomness + * @param {string} str - String to shuffle + * @returns {string} Shuffled string + */ +function shuffleString(str) { + const array = str.split(''); + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array.join(''); } +/** + * Generate random lowercase letter + * @returns {string} Random lowercase letter + */ function getRandomLower() { - return String.fromCharCode(Math.floor(Math.random() * 26) + 97) + return String.fromCharCode(Math.floor(Math.random() * 26) + 97); } +/** + * Generate random uppercase letter + * @returns {string} Random uppercase letter + */ function getRandomUpper() { - return String.fromCharCode(Math.floor(Math.random() * 26) + 65) + return String.fromCharCode(Math.floor(Math.random() * 26) + 65); } +/** + * Generate random number + * @returns {string} Random number (0-9) + */ function getRandomNumber() { - return String.fromCharCode(Math.floor(Math.random() * 10) + 48) + return String.fromCharCode(Math.floor(Math.random() * 10) + 48); } +/** + * Generate random symbol + * @returns {string} Random symbol + */ function getRandomSymbol() { - const symbols = '!@#$%^&*(){}[]=<>/,.' - return symbols[Math.floor(Math.random() * symbols.length)] + const symbols = '!@#$%^&*(){}[]=<>/,.'; + return symbols[Math.floor(Math.random() * symbols.length)]; } +// Add CSS animations dynamically +const style = document.createElement('style'); +style.textContent = ` + @keyframes slideIn { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } + } + + @keyframes slideOut { + from { + transform: translateX(0); + opacity: 1; + } + to { + transform: translateX(100%); + opacity: 0; + } + } +`; +document.head.appendChild(style); + +// Initialize the app when DOM is fully loaded +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initializeApp); +} else { + initializeApp(); +}