<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel><title>Raju's Web tools</title><description>Raju's Web Tools- your one-stop destination for all things web and AI! Here, you'll find blog posts packed with practical web tools, ready-to-use HTML code snippets, and innovative AI resources that you can easily integrate into your projects. Whether you're a developer, tech enthusiast, or simply curious about the digital world, this blog is designed to help you unlock creative solutions and elevate your online presence. Join us as we explore the latest trends and tools that make technology fun</description><managingEditor>noreply@blogger.com (Raju Alankar)</managingEditor><pubDate>Tue, 16 Dec 2025 18:34:54 -0800</pubDate><generator>Blogger http://www.blogger.com</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">505</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">25</openSearch:itemsPerPage><link>http://rajclick.blogspot.com/</link><language>en-us</language><itunes:explicit>no</itunes:explicit><copyright>Copyrighted</copyright><itunes:keywords>civil,e,c,automobile,Mech,engineer,matlab,c,language,facebook,bing</itunes:keywords><itunes:subtitle>Study Engineering</itunes:subtitle><itunes:category text="Education"><itunes:category text="Educational Technology"/></itunes:category><itunes:author>Raju</itunes:author><itunes:owner><itunes:email>rajualankar2@gmail.com</itunes:email><itunes:name>Raju</itunes:name></itunes:owner><item><title>Multi‑Timezone Clock</title><link>http://rajclick.blogspot.com/2025/04/multitimezone-clock.html</link><pubDate>Fri, 18 Apr 2025 06:23:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-3364110731970472365</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
  &lt;title&gt;Multi Timezone Clock&lt;/title&gt;
  &lt;style&gt;
    body {
      background: #121212;
      color: #e0e0e0;
      font-family: 'Segoe UI', Tahoma, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      margin: 0;
    }
    h1 {
      margin-bottom: 20px;
      font-size: 1.8rem;
    }
    .clock-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 20px;
      width: 90%;
      max-width: 1200px;
    }
    .clock {
      background: #1e1e1e;
      border-radius: 12px;
      padding: 20px;
      text-align: center;
      box-shadow: 0 4px 10px rgba(0,0,0,0.5);
      cursor: move;
    }
    .clock.drag-over {
      border: 2px dashed #ffcc00;
    }
    .label {
      font-size: 1.1rem;
      margin-bottom: 10px;
      text-transform: uppercase;
      color: #ffcc00;
    }
    .time {
      font-size: 2rem;
      font-weight: bold;
    }
    .date {
      margin-top: 8px;
      font-size: 1rem;
      color: #aaaaaa;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;Current Time Across Timezones&lt;/h1&gt;
  &lt;div class="clock-container"&gt;
    &lt;!-- IST --&gt;
    &lt;div class="clock" data-zone="IST" id="item-IST" draggable="true"&gt;
      &lt;div class="label"&gt;India (IST)&lt;/div&gt;
      &lt;div class="time" id="clock-IST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-IST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Eastern --&gt;
    &lt;div class="clock" data-zone="EST" id="item-EST" draggable="true"&gt;
      &lt;div class="label"&gt;US Eastern (EST/EDT)&lt;/div&gt;
      &lt;div class="time" id="clock-EST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-EST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Central --&gt;
    &lt;div class="clock" data-zone="CST" id="item-CST" draggable="true"&gt;
      &lt;div class="label"&gt;US Central (CST/CDT)&lt;/div&gt;
      &lt;div class="time" id="clock-CST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-CST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Mountain --&gt;
    &lt;div class="clock" data-zone="MST" id="item-MST" draggable="true"&gt;
      &lt;div class="label"&gt;US Mountain (MST/MDT)&lt;/div&gt;
      &lt;div class="time" id="clock-MST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-MST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Pacific --&gt;
    &lt;div class="clock" data-zone="PST" id="item-PST" draggable="true"&gt;
      &lt;div class="label"&gt;US Pacific (PST/PDT)&lt;/div&gt;
      &lt;div class="time" id="clock-PST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-PST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Alaska --&gt;
    &lt;div class="clock" data-zone="AKST" id="item-AKST" draggable="true"&gt;
      &lt;div class="label"&gt;US Alaska (AKST/AKDT)&lt;/div&gt;
      &lt;div class="time" id="clock-AKST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-AKST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- US Hawaii --&gt;
    &lt;div class="clock" data-zone="HST" id="item-HST" draggable="true"&gt;
      &lt;div class="label"&gt;US Hawaii (HST)&lt;/div&gt;
      &lt;div class="time" id="clock-HST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-HST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Germany --&gt;
    &lt;div class="clock" data-zone="CET" id="item-CET" draggable="true"&gt;
      &lt;div class="label"&gt;Germany (CET/CEST)&lt;/div&gt;
      &lt;div class="time" id="clock-CET"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-CET"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Western Europe --&gt;
    &lt;div class="clock" data-zone="WET" id="item-WET" draggable="true"&gt;
      &lt;div class="label"&gt;Western Europe (WET/BST)&lt;/div&gt;
      &lt;div class="time" id="clock-WET"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-WET"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Eastern Europe --&gt;
    &lt;div class="clock" data-zone="EET" id="item-EET" draggable="true"&gt;
      &lt;div class="label"&gt;Eastern Europe (EET/EEST)&lt;/div&gt;
      &lt;div class="time" id="clock-EET"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-EET"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- UAE Gulf Standard --&gt;
    &lt;div class="clock" data-zone="GST" id="item-GST" draggable="true"&gt;
      &lt;div class="label"&gt;UAE (GST)&lt;/div&gt;
      &lt;div class="time" id="clock-GST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-GST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Saudi Arabia Standard --&gt;
    &lt;div class="clock" data-zone="AST" id="item-AST" draggable="true"&gt;
      &lt;div class="label"&gt;Saudi Arabia (AST)&lt;/div&gt;
      &lt;div class="time" id="clock-AST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-AST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- China --&gt;
    &lt;div class="clock" data-zone="CN" id="item-CN" draggable="true"&gt;
      &lt;div class="label"&gt;China (CST)&lt;/div&gt;
      &lt;div class="time" id="clock-CN"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-CN"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Japan --&gt;
    &lt;div class="clock" data-zone="JST" id="item-JST" draggable="true"&gt;
      &lt;div class="label"&gt;Japan (JST)&lt;/div&gt;
      &lt;div class="time" id="clock-JST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-JST"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;!-- Australia Eastern --&gt;
    &lt;div class="clock" data-zone="AEST" id="item-AEST" draggable="true"&gt;
      &lt;div class="label"&gt;Australia (AEST/AEDT)&lt;/div&gt;
      &lt;div class="time" id="clock-AEST"&gt;&lt;/div&gt;
      &lt;div class="date" id="date-AEST"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const zones = {
      'IST': 'Asia/Kolkata',
      'EST': 'America/New_York',
      'CST': 'America/Chicago',
      'MST': 'America/Denver',
      'PST': 'America/Los_Angeles',
      'AKST': 'America/Anchorage',
      'HST': 'Pacific/Honolulu',
      'CET': 'Europe/Berlin',
      'WET': 'Europe/Lisbon',
      'EET': 'Europe/Helsinki',
      'GST': 'Asia/Dubai',
      'AST': 'Asia/Riyadh',
      'CN': 'Asia/Shanghai',
      'JST': 'Asia/Tokyo',
      'AEST': 'Australia/Sydney'
    };

    function updateClocks() {
      const now = new Date();
      Object.entries(zones).forEach(([id, zone]) =&gt; {
        const timeOptions = { timeZone: zone, hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' };
        const dateOptions = { timeZone: zone, weekday: 'short', day: '2-digit', month: 'short', year: 'numeric' };
        document.getElementById(`clock-${id}`).textContent = now.toLocaleTimeString('en-GB', timeOptions);
        document.getElementById(`date-${id}`).textContent = now.toLocaleDateString('en-GB', dateOptions);
      });
    }

    // Drag and drop reordering
    let dragged;
    document.querySelectorAll('.clock').forEach(card =&gt; {
      card.addEventListener('dragstart', () =&gt; dragged = card);
      card.addEventListener('dragover', e =&gt; { e.preventDefault(); card.classList.add('drag-over'); });
      card.addEventListener('dragleave', () =&gt; card.classList.remove('drag-over'));
      card.addEventListener('drop', e =&gt; {
        e.preventDefault();
        card.classList.remove('drag-over');
        const container = document.querySelector('.clock-container');
        const items = Array.from(container.children);
        const draggedIndex = items.indexOf(dragged);
        const targetIndex = items.indexOf(card);
        container.removeChild(dragged);
        if (draggedIndex &lt; targetIndex) container.insertBefore(dragged, card.nextSibling);
        else container.insertBefore(dragged, card);
      });
    });

    setInterval(updateClocks, 1000);
    updateClocks();
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Youtube Player: Cyber punk style</title><link>http://rajclick.blogspot.com/2025/04/youtube-player-cyber-punk-style.html</link><pubDate>Fri, 4 Apr 2025 09:44:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-7360639403575234690</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Cyberpunk YouTube Player&lt;/title&gt;
    &lt;!-- Using a tech-style font --&gt;
    &lt;link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&amp;display=swap" rel="stylesheet"&gt;
    &lt;style&gt;
        :root {
            --primary-glow: #00ffff; /* Cyan */
            --secondary-glow: #ff00ff; /* Magenta */
            --accent-orange: #ff8c00; /* Orange for Submit button, closer to mockup */
            --background-dark: #0a0a1a; /* Very dark blue/black */
            --border-dark: #1a1a2e; /* Darker element background */
            --text-color: #e0e0e0; /* Light grey/white text */
            --accent-red: #ff3333; /* YouTube Red for title */
            --error-red: #ff4444; /* Specific red for errors */
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: var(--background-dark);
            font-family: 'Orbitron', sans-serif; /* Techy font */
            color: var(--text-color);
            padding: 20px; /* Add padding to body for smaller screens */
        }

        /* Main container with cyberpunk border */
        .cyber-container {
            width: 100%; /* Take full width available */
            max-width: 850px; /* Max width */
            background-color: var(--border-dark);
            /* Complex border simulation using box-shadow and border */
            border: 1px solid var(--primary-glow);
            padding: 25px; /* Generous padding */
            position: relative;
            box-shadow:
                0 0 5px var(--primary-glow),
                0 0 10px var(--primary-glow),
                0 0 15px var(--primary-glow),
                0 0 3px var(--secondary-glow) inset, /* Subtle inner magenta */
                0 0 8px var(--secondary-glow) inset;
            border-radius: 8px; /* Slightly more rounded corners */
            overflow: hidden; /* Ensures pseudo-elements stay contained */
            /* Simulate circuit lines with pseudo-elements */
            background-image:
                linear-gradient(rgba(0, 255, 255, 0.05) 1px, transparent 1px),
                linear-gradient(90deg, rgba(0, 255, 255, 0.05) 1px, transparent 1px);
            background-size: 20px 20px;
        }

        /* --- Decorative Corner Elements --- */
        .cyber-container::before,
        .cyber-container::after {
            content: '';
            position: absolute;
            width: 20px;
            height: 20px;
            border-style: solid;
            border-color: var(--secondary-glow); /* Magenta corners */
            opacity: 0.8;
            box-shadow: 0 0 5px var(--secondary-glow);
        }
        .cyber-container::before {
            top: 5px;
            left: 5px;
            border-width: 2px 0 0 2px; /* Top-left */
        }
        .cyber-container::after {
            bottom: 5px;
            right: 5px;
            border-width: 0 2px 2px 0; /* Bottom-right */
        }
        /* Additional corners */
        .cyber-corner-tr, .cyber-corner-bl {
             content: '';
            position: absolute;
            width: 20px;
            height: 20px;
            border-style: solid;
            border-color: var(--primary-glow); /* Cyan corners */
            opacity: 0.8;
            box-shadow: 0 0 5px var(--primary-glow);
        }
        .cyber-corner-tr {
            top: 5px;
            right: 5px;
            border-width: 2px 2px 0 0; /* Top-right */
        }
         .cyber-corner-bl {
            bottom: 5px;
            left: 5px;
            border-width: 0 0 2px 2px; /* Bottom-left */
        }


        /* Screen base styles */
        .screen {
            display: none; /* Hide screens by default */
            flex-direction: column;
            align-items: center;
            padding: 20px; /* Padding inside the screen */
            background-color: rgba(10, 10, 26, 0.85); /* Slightly transparent inner bg */
            position: relative; /* Needed for z-index stacking */
            z-index: 1; /* Ensure content is above pseudo-elements */
            border: 1px solid rgba(0, 255, 255, 0.1); /* Faint inner border */
            min-height: 450px; /* Give screens some minimum height */
            justify-content: center; /* Center content vertically */
            border-radius: 5px;
        }

        .screen.active {
            display: flex; /* Show the active screen */
        }

        /* Title styling */
        .title {
            font-size: 2.2rem;
            font-weight: 700;
            color: var(--accent-red);
            text-shadow: 0 0 4px var(--accent-red), 0 0 8px var(--accent-red), 0 0 2px #fff; /* Stronger glow */
            margin-bottom: 35px;
            text-transform: uppercase;
            letter-spacing: 3px;
            z-index: 2;
            position: relative;
            text-align: center;
        }

        /* --- Input Screen Styles --- */
        #input-screen label {
            font-size: 1.3rem;
            color: var(--primary-glow);
            margin-bottom: 15px;
            text-shadow: 0 0 3px var(--primary-glow);
            text-align: center;
            display: block; /* Make label take full width */
        }

        #input-screen input[type="text"] {
            width: 100%;
            max-width: 550px;
            padding: 14px 18px;
            background-color: rgba(10, 10, 26, 0.9);
            border: 1px solid var(--primary-glow);
            border-radius: 4px;
            font-family: 'Orbitron', sans-serif;
            color: var(--text-color);
            font-size: 1rem;
            margin-bottom: 10px; /* Space before error message */
            box-shadow: 0 0 6px var(--primary-glow) inset;
            transition: border-color 0.3s, box-shadow 0.3s;
            display: block; /* Make input block level */
            margin-left: auto;
            margin-right: auto; /* Center input */
            text-align: center; /* Center placeholder text */
        }

        #input-screen input[type="text"]:focus {
            outline: none;
            border-color: var(--secondary-glow);
            box-shadow: 0 0 8px var(--secondary-glow) inset, 0 0 5px var(--secondary-glow);
        }

        /* Error message styling */
        .error {
            color: var(--error-red);
            text-shadow: 0 0 3px var(--error-red);
            min-height: 1.2em; /* Reserve space to prevent layout shift */
            margin-bottom: 15px;
            font-size: 0.9rem;
            text-align: center; /* Center error message */
            font-weight: bold;
        }

        /* Shared button base styles */
        .cyber-button {
            padding: 12px 35px;
            background-color: transparent;
            border: 2px solid; /* Border color set below */
            color: var(--text-color); /* Text color set below */
            font-family: 'Orbitron', sans-serif;
            font-size: 1.1rem;
            font-weight: bold;
            cursor: pointer;
            border-radius: 4px;
            text-transform: uppercase;
            transition: background-color 0.3s, color 0.3s, box-shadow 0.3s, transform 0.1s;
            box-shadow: 0 0 5px; /* Shadow color set below */
            margin-top: 20px;
            display: block; /* Make buttons block level */
            margin-left: auto;
            margin-right: auto; /* Center buttons */
            letter-spacing: 1px;
        }
        .cyber-button:active {
             transform: scale(0.98); /* Slight press effect */
        }

        /* Submit Button Styling (Orange Glow) */
        #submit-btn {
            border-color: var(--accent-orange);
            color: var(--accent-orange);
            box-shadow: 0 0 6px var(--accent-orange), 0 0 10px var(--accent-orange);
        }
        #submit-btn:hover {
            background-color: var(--accent-orange);
            color: var(--background-dark);
            box-shadow: 0 0 10px var(--accent-orange), 0 0 15px var(--accent-orange), 0 0 20px var(--accent-orange);
        }

        /* --- Player Screen Styles --- */
        #player-wrapper {
            width: 100%;
            /* Maintain 16:9 aspect ratio */
            position: relative;
            padding-bottom: 56.25%; /* 16:9 Aspect Ratio */
            height: 0;
            background-color: #000; /* Black background while loading/for iframe */
            margin-bottom: 25px; /* Space below player */
            border: 1px solid var(--primary-glow); /* Border around player */
            box-shadow: 0 0 8px var(--primary-glow);
            overflow: hidden; /* Ensure iframe fits */
            border-radius: 4px;
        }

        #youtube-player {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        #youtube-player iframe {
            display: block; /* Prevents potential bottom space */
            width: 100%;
            height: 100%;
            border: none; /* Remove iframe default border */
        }

        /* Static Control Simulation (Visual only) */
        .static-controls {
            display: flex;
            align-items: center;
            justify-content: space-between; /* Space out elements */
            width: 100%;
            max-width: 650px; /* Limit width of controls */
            margin-left: auto;
            margin-right: auto;
            padding: 12px 15px;
            background-color: rgba(30, 30, 50, 0.7);
            border: 1px solid var(--primary-glow);
            border-radius: 4px;
            margin-bottom: 20px; /* Space before back button */
            box-shadow: 0 0 4px rgba(0, 255, 255, 0.5);
        }

        /* Simulated Play Button */
        .control-button-play {
            width: 28px;
            height: 28px;
            background-color: var(--primary-glow);
            clip-path: polygon(0 0, 100% 50%, 0 100%); /* Triangle */
            margin-right: 15px;
            flex-shrink: 0;
            box-shadow: 0 0 5px var(--primary-glow);
            cursor: default; /* Not interactive */
        }

        /* Simulated Progress Bar */
        .progress-bar-container {
            flex-grow: 1;
            height: 10px;
            background-color: rgba(0, 0, 0, 0.6);
            border-radius: 5px;
            overflow: hidden;
            margin: 0 15px; /* Space around bar */
             border: 1px solid rgba(0, 255, 255, 0.2);
        }

        .progress-bar {
            width: 10%; /* Static representation of start */
            height: 100%;
            background: linear-gradient(90deg, var(--secondary-glow), var(--primary-glow));
            border-radius: 5px;
            box-shadow: 0 0 5px var(--primary-glow);
        }

        /* Simulated Time/Icons (basic placeholders) */
        .time-codes, .control-icons {
            font-size: 0.85rem;
            color: var(--text-color);
            opacity: 0.8;
            flex-shrink: 0;
             letter-spacing: 1px;
        }
        .time-codes {
             min-width: 70px; /* Ensure space */
             text-align: right;
        }
        .control-icons span {
            margin-left: 10px;
            cursor: default; /* Not interactive */
            opacity: 0.7;
        }

        /* Back Button Styling (Cyan Glow) */
        #back-btn {
            border-color: var(--primary-glow);
            color: var(--primary-glow);
            box-shadow: 0 0 6px var(--primary-glow), 0 0 10px var(--primary-glow);
        }
        #back-btn:hover {
            background-color: var(--primary-glow);
            color: var(--background-dark);
            box-shadow: 0 0 10px var(--primary-glow), 0 0 15px var(--primary-glow), 0 0 20px var(--primary-glow);
        }


        /* --- Responsiveness --- */
        @media (max-width: 768px) {
             .cyber-container {
                padding: 20px;
                max-width: 95%;
            }
            .title {
                font-size: 1.8rem;
                margin-bottom: 30px;
            }
             .screen {
                min-height: 400px;
            }
            #input-screen input[type="text"] {
                 max-width: 90%;
            }
            .static-controls {
                 max-width: 95%;
                 padding: 10px;
            }
             .control-button-play {
                 width: 24px;
                 height: 24px;
            }
            .progress-bar-container {
                height: 8px;
            }
            .time-codes, .control-icons {
                font-size: 0.8rem;
            }
        }

        @media (max-width: 480px) {
             body {
                 padding: 10px;
             }
             .cyber-container {
                padding: 15px;
                 /* Hide corners on very small screens if they overlap too much */
                 /* &amp;::before, &amp;::after, .cyber-corner-tr, .cyber-corner-bl { display: none; } */
            }
             .screen {
                padding: 15px;
                min-height: 350px; /* Adjust min height */
            }
            .title {
                font-size: 1.5rem;
                margin-bottom: 25px;
                letter-spacing: 2px;
            }
            #input-screen label {
                font-size: 1.1rem;
            }
            #input-screen input[type="text"] {
                padding: 12px 15px;
                font-size: 0.9rem;
            }
            .cyber-button { /* Affects both buttons */
                font-size: 1rem;
                padding: 10px 25px;
            }
            .static-controls {
                padding: 8px;
                flex-wrap: wrap; /* Allow wrapping if needed */
                justify-content: center;
            }
             .control-button-play {
                width: 20px;
                height: 20px;
                margin-right: 10px;
            }
            .progress-bar-container {
                 margin: 5px 0; /* Add vertical margin if wrapped */
                 width: 100%; /* Take full width if wrapped */
            }
             .time-codes, .control-icons {
                 font-size: 0.75rem;
                 margin-top: 5px; /* Space if wrapped */
             }
             .time-codes { text-align: left; min-width: auto; margin-right: 10px;}
             .control-icons span { margin-left: 8px;}
        }

    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="cyber-container"&gt;
        &lt;!-- Decorative Corner Elements --&gt;
        &lt;div class="cyber-corner-tr"&gt;&lt;/div&gt;
        &lt;div class="cyber-corner-bl"&gt;&lt;/div&gt;

        &lt;!-- Screen 1: URL Input --&gt;
        &lt;div id="input-screen" class="screen active"&gt;
            &lt;h1 class="title"&gt;YOUTUBE&lt;/h1&gt;
            &lt;label for="youtube-url"&gt;Enter YouTube URL&lt;/label&gt;
            &lt;input type="text" id="youtube-url" placeholder="e.g., https://www.youtube.com/watch?v=..."&gt;
            &lt;p id="error-message" class="error"&gt;&lt;/p&gt;
            &lt;button id="submit-btn" class="cyber-button"&gt;SUBMIT&lt;/button&gt;
        &lt;/div&gt;

        &lt;!-- Screen 2: Video Player --&gt;
        &lt;div id="player-screen" class="screen"&gt;
            &lt;h1 class="title"&gt;YOUTUBE&lt;/h1&gt;
            &lt;div id="player-wrapper"&gt;
                &lt;!-- YouTube IFrame will be embedded here --&gt;
                &lt;div id="youtube-player"&gt;&lt;/div&gt;
            &lt;/div&gt;
            &lt;!-- Static representation of controls --&gt;
            &lt;div class="static-controls"&gt;
                 &lt;div class="control-button-play"&gt;&lt;/div&gt; &lt;!-- Play Icon --&gt;
                 &lt;span class="time-codes"&gt;0:03&lt;/span&gt; &lt;!-- Start Time --&gt;
                 &lt;div class="progress-bar-container"&gt;
                    &lt;div class="progress-bar"&gt;&lt;/div&gt; &lt;!-- Progress Fill --&gt;
                 &lt;/div&gt;
                 &lt;span class="time-codes"&gt;0:42&lt;/span&gt; &lt;!-- End Time --&gt;
                 &lt;div class="control-icons"&gt; &lt;!-- Icons --&gt;
                     &lt;span&gt;&lt;svg fill="#e0e0e0" height="18px" width="18px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 192.767 192.767" xml:space="preserve"&gt;&lt;g&gt;&lt;path d="M179.061,13.974c-7.467-3.794-16.108-2.198-22.013,4.195L93.333,81.972V24.51c0-9.115-7.394-16.51-16.51-16.51H16.51 C7.394,8.001,0,15.395,0,24.51v143.748c0,9.115,7.394,16.51,16.51,16.51h60.313c9.115,0,16.51-7.394,16.51-16.51v-57.462 l63.715,63.803c3.466,3.466,7.911,5.13,12.32,5.13c3.28,0,6.542-0.932,9.379-2.774c7.468-4.886,11.033-13.869,8.806-22.501 L166.38,70.227c-0.18-0.707-0.404-1.402-0.678-2.081l-11.186-28.337C159.57,27.165,186.527,17.768,179.061,13.974z"/&gt;&lt;/g&gt;&lt;/svg&gt; CC&lt;/span&gt; &lt;!-- CC Icon Placeholder --&gt;
                     &lt;span&gt;&lt;svg fill="#e0e0e0" height="18px" width="18px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 384.97 384.97" xml:space="preserve"&gt;&lt;g&gt;&lt;g&gt;&lt;path d="M372.939,216.545c-6.123,0-12.03,2.346-16.584,6.9c-4.554,4.553-6.9,10.461-6.9,16.584v89.122h-327.91V55.818h89.122 c6.123,0,12.03-2.346,16.584-6.9c4.554-4.554,6.9-10.461,6.9-16.584S101.7,15.435,97.145,10.88c-4.554-4.554-10.461-6.9-16.584-6.9H12.03 C5.388,3.979,0,9.367,0,16.009v352.952c0,6.642,5.388,12.03,12.03,12.03h360.909c6.642,0,12.03-5.388,12.03-12.03V240.029 C384.97,228.986,379.061,216.545,372.939,216.545z"/&gt;&lt;path d="M372.939,3.979c-6.642,0-12.03,5.388-12.03,12.03v104.86L230.054,0.015c-4.211-2.429-9.453-2.429-13.662,0.002 c-4.211,2.43-6.82,6.907-6.82,11.81v130.889c0,4.903,2.609,9.38,6.82,11.81c2.105,1.215,4.482,1.822,6.858,1.822 c2.377,0,4.754-0.607,6.858-1.823l130.854-75.546v104.86c0,6.642,5.388,12.03,12.03,12.03s12.03-5.388,12.03-12.03V16.009 C384.97,9.367,379.581,3.979,372.939,3.979z"/&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/span&gt; &lt;!-- Fullscreen Icon Placeholder --&gt;
                 &lt;/div&gt;
            &lt;/div&gt;
             &lt;!-- Button to go back to input screen --&gt;
            &lt;button id="back-btn" class="cyber-button"&gt;Enter New URL&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Get references to DOM elements
        const inputScreen = document.getElementById('input-screen');
        const playerScreen = document.getElementById('player-screen');
        const urlInput = document.getElementById('youtube-url');
        const submitBtn = document.getElementById('submit-btn');
        const backBtn = document.getElementById('back-btn');
        const playerDiv = document.getElementById('youtube-player');
        const errorMessage = document.getElementById('error-message');
        const progressBarFill = playerScreen.querySelector('.progress-bar'); // Get progress bar fill element

        // Variable to hold the iframe reference
        let currentIframe = null;

        // Function to extract YouTube Video ID from various URL formats
        function getYouTubeVideoId(url) {
            let videoId = null;
            // Regex to capture video ID from standard, short, embed, and channel URLs
             const patterns = [
                /(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/,        // Standard URL
                /(?:https?:\/\/)?(?:www\.)?youtu\.be\/([a-zA-Z0-9_-]{11})/,                  // Shortened URL
                /(?:https?:\/\/)?(?:www\.)?youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/,       // Embed URL
                /(?:https?:\/\/)?(?:www\.)?youtube\.com\/v\/([a-zA-Z0-9_-]{11})/,            // V URL
                /(?:https?:\/\/)?(?:www\.)?youtube\.com\/.*[&amp;?]v=([a-zA-Z0-9_-]{11})/       // URL with other params
            ];

            for (const pattern of patterns) {
                const match = url.match(pattern);
                if (match &amp;&amp; match[1]) {
                    videoId = match[1];
                    break; // Found ID, exit loop
                }
            }
            console.log("Attempting URL:", url, "Extracted Video ID:", videoId); // Debugging
            return videoId;
        }

        // Function to switch between screens
        function showScreen(screenToShow) {
            inputScreen.classList.remove('active');
            playerScreen.classList.remove('active');
            screenToShow.classList.add('active');
        }

        // Function to create and load the YouTube IFrame Player
        function loadVideo(videoId) {
            // Clear previous player if exists and reset progress bar
            playerDiv.innerHTML = '';
            progressBarFill.style.width = '0%'; // Reset progress bar visually
            errorMessage.textContent = ''; // Clear previous errors

            // Create the iframe element
            const iframe = document.createElement('iframe');

            // Set attributes for the iframe
            // Width/Height are controlled by CSS aspect ratio wrapper, but set defaults
            iframe.width = "100%";
            iframe.height = "100%";
            // Construct the embed URL with recommended parameters:
            // - autoplay=1: Start playing automatically
            // - modestbranding=1: Reduce YouTube logo
            // - rel=0: Don't show related videos from other channels
            // - iv_load_policy=3: Don't show video annotations by default
            // - controls=1: Show native YouTube controls (important for usability)
            // - enablejsapi=1: Needed if you want to control via JS API later
            iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&amp;modestbranding=1&amp;rel=0&amp;iv_load_policy=3&amp;controls=1&amp;enablejsapi=1`;
            iframe.title = "YouTube video player";
            iframe.frameborder = "0";
            // Define permissions needed for features like fullscreen and autoplay
            iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
            iframe.allowfullscreen = true; // Allow fullscreen mode

            // Store reference to the new iframe
            currentIframe = iframe;

            // Append the created iframe to the player container div
            playerDiv.appendChild(iframe);

            // Simulate progress bar moving slightly after load (visual flair)
            setTimeout(() =&gt; {
                progressBarFill.style.transition = 'width 0.5s ease-in-out'; // Add transition
                progressBarFill.style.width = '10%'; // Match static mockup start time
            }, 500); // Wait half a second


            // Switch to the player screen
            showScreen(playerScreen);
        }

        // --- Event Listeners ---

        // Listener for the SUBMIT button
        submitBtn.addEventListener('click', () =&gt; {
            const url = urlInput.value.trim(); // Get URL and remove whitespace
            if (!url) {
                errorMessage.textContent = 'Please paste a YouTube URL.';
                urlInput.style.borderColor = 'var(--error-red)'; // Highlight input border in red
                urlInput.focus(); // Set focus back to input
                return; // Stop if URL is empty
            }

            const videoId = getYouTubeVideoId(url); // Extract video ID

            if (videoId) {
                errorMessage.textContent = ''; // Clear any previous error message
                urlInput.style.borderColor = ''; // Reset input border color
                loadVideo(videoId); // Load the video
            } else {
                errorMessage.textContent = 'Invalid or unsupported YouTube URL format.';
                urlInput.style.borderColor = 'var(--error-red)'; // Highlight input border
                urlInput.select(); // Select the text for easy correction
            }
        });

        // Allow submitting with Enter key in the input field
        urlInput.addEventListener('keypress', (event) =&gt; {
            if (event.key === 'Enter') {
                event.preventDefault(); // Prevent default form submission
                submitBtn.click(); // Trigger the submit button click
            }
             // Clear error styling on input change
             if(urlInput.style.borderColor) {
                 urlInput.style.borderColor = '';
                 errorMessage.textContent = '';
             }
        });
        // Also clear error on focus
         urlInput.addEventListener('focus', () =&gt; {
             if(urlInput.style.borderColor) {
                 urlInput.style.borderColor = '';
                 errorMessage.textContent = '';
             }
        });


        // Listener for the 'Enter New URL' (Back) button
        backBtn.addEventListener('click', () =&gt; {
            // Remove the iframe to stop playback and clear the container
             playerDiv.innerHTML = '';
             currentIframe = null; // Clear the reference

            // Reset UI elements
            urlInput.value = ''; // Clear the input field
            errorMessage.textContent = ''; // Clear any errors
            urlInput.style.borderColor = ''; // Reset border highlight
            progressBarFill.style.transition = 'none'; // Remove transition for instant reset
            progressBarFill.style.width = '0%'; // Reset progress bar visually

            showScreen(inputScreen); // Switch back to the input screen
        });

        // Initialize: Show the input screen first when the page loads
        showScreen(inputScreen);

    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Top 12 Karnataka Destinations - 3D Interactive Map</title><link>http://rajclick.blogspot.com/2025/04/top-12-karnataka-destinations-3d.html</link><pubDate>Tue, 1 Apr 2025 06:58:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-4606467673478061250</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Interactive 3D Map of Karnataka&lt;/title&gt;
    &lt;!-- Mapbox GL JS --&gt;
    &lt;script src='https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js'&gt;&lt;/script&gt;
    &lt;link href='https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css' rel='stylesheet' /&gt;
    &lt;!-- Three.js --&gt;
    &lt;script src='https://unpkg.com/three@0.158.0/build/three.min.js'&gt;&lt;/script&gt;
    &lt;!-- Threebox --&gt;
    &lt;script src='https://unpkg.com/threebox-plugin@2.2.7/dist/threebox.min.js'&gt;&lt;/script&gt;

    &lt;style&gt;
        /* Basic Reset */
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        /* IMPORTANT: Ensure the map container itself doesn't affect overall page flow unnecessarily */
        /* You might need to adjust this based on how Blogger embeds */
        html, body {
             /* Avoid setting 100% height on html/body if it conflicts with Blogger */
             /* Let the container below define its size */
            overflow: auto; /* Allow normal page scrolling */
            font-family: sans-serif;
        }

        #app-container {
            display: flex;
            /* --- CHANGE HERE --- */
            /* Instead of 100vh, use a fixed height appropriate for your blog layout */
            /* Adjust this value (e.g., 500px, 600px, 700px) as needed */
            height: 650px;
            /* --- END CHANGE --- */
            width: 100%; /* Take full width available in the post content area */
            max-width: 900px; /* Optional: Limit max width */
            margin: 10px auto; /* Optional: Center the container */
            border: 1px solid #ccc; /* Optional: Add border to see container bounds */
        }

        #sidebar {
            width: 250px; /* Fixed width for the sidebar */
            height: 100%; /* Takes 100% height of its PARENT (#app-container) */
            background-color: #f4f4f4;
            border-right: 1px solid #ccc;
            padding: 15px;
            overflow-y: auto; /* THIS SHOULD NOW WORK if content exceeds the fixed parent height */
            flex-shrink: 0; /* Prevent sidebar from shrinking */
        }

        #sidebar h2 {
            margin-bottom: 15px;
            font-size: 1.2em;
            color: #333;
            border-bottom: 1px solid #ddd;
            padding-bottom: 5px;
        }

        #destination-list {
            list-style: none;
        }

        #destination-list li {
            padding: 8px 5px;
            cursor: pointer;
            border-bottom: 1px dotted #eee;
            transition: background-color 0.2s ease;
            font-size: 0.9em;
        }

        #destination-list li:hover {
            background-color: #e0e0e0;
        }

        #map {
            flex-grow: 1; /* Map takes remaining width */
            height: 100%; /* Takes 100% height of its PARENT (#app-container) */
        }

         /* Mapbox popup customization if needed */
        .mapboxgl-popup-content {
            font-family: sans-serif;
            padding: 10px;
        }

    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!-- Ensure this container is directly within your Blogger post HTML view --&gt;
    &lt;div id="app-container"&gt;
        &lt;div id="sidebar"&gt;
            &lt;h2&gt;Karnataka Destinations&lt;/h2&gt;
            &lt;ul id="destination-list"&gt;
                &lt;!-- Destinations will be added here by JavaScript --&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
        &lt;div id="map"&gt;&lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // --- Configuration ---
        mapboxgl.accessToken = 'pk.eyJ1IjoiaWFtcmFqdWFsYW5rYXIiLCJhIjoiY204eWp1bjFiMDFtcjJ3cnl1M2RsODViMSJ9.h9Gpwe6YXBT29-TQtPOLvQ'; // &lt;-- PASTE YOUR TOKEN HERE

        const destinations = [
            { name: "Bengaluru (Vidhana Soudha)", coords: [77.5913, 12.9797] },
            { name: "Mysuru (Mysore Palace)", coords: [76.6552, 12.3052] },
            { name: "Hampi (Virupaksha Temple)", coords: [76.4626, 15.3350] },
            { name: "Coorg (Madikeri)", coords: [75.7399, 12.4244] },
            { name: "Gokarna (Om Beach)", coords: [74.3169, 14.5194] },
            { name: "Chikmagalur (Mullayanagiri)", coords: [75.7897, 13.3919] },
            { name: "Badami Caves", coords: [75.6834, 15.9198] },
            { name: "Jog Falls", coords: [74.8117, 14.2292] },
            { name: "Udupi (Sri Krishna Matha)", coords: [74.7479, 13.3418] },
            { name: "Belur (Chennakeshava Temple)", coords: [75.8654, 13.1631] },
            { name: "Shravanabelagola (Gomateshwara)", coords: [76.4831, 12.8556] },
            { name: "Dandeli Wildlife Sanctuary", coords: [74.6230, 15.2497] }
        ];

        // --- Initialization ---
        document.addEventListener('DOMContentLoaded', () =&gt; {
            if (mapboxgl.accessToken === 'YOUR_MAPBOX_ACCESS_TOKEN' || !mapboxgl.accessToken || mapboxgl.accessToken.length &lt; 10) { // Basic check
                 // Avoid alert in production, maybe show message in div
                 console.error('Mapbox Access Token missing or invalid.');
                 document.getElementById('map').innerHTML = '&lt;p style="padding:20px; text-align:center; color: red;"&gt;Map configuration error. Requires a valid Mapbox Access Token.&lt;/p&gt;';
                 if(document.getElementById('sidebar')) document.getElementById('sidebar').style.display = 'none';
                 return; // Stop execution
            }

            // Initialize Mapbox Map
            const map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/satellite-streets-v12',
                center: [76.5, 14.5],
                zoom: 6.5,
                pitch: 55,
                bearing: -15,
                antialias: true
            });

            // Initialize Destination List
            const listElement = document.getElementById('destination-list');
            if (!listElement) {
                console.error("Destination list element not found!");
                return;
            }
            destinations.forEach(dest =&gt; {
                const li = document.createElement('li');
                li.textContent = dest.name;
                li.setAttribute('data-lng', dest.coords[0]);
                li.setAttribute('data-lat', dest.coords[1]);
                listElement.appendChild(li);
            });

            // Add Click Listener to the List
            listElement.addEventListener('click', (event) =&gt; {
                if (event.target &amp;&amp; event.target.tagName === 'LI') {
                    const lng = parseFloat(event.target.getAttribute('data-lng'));
                    const lat = parseFloat(event.target.getAttribute('data-lat'));

                    map.flyTo({
                        center: [lng, lat],
                        zoom: 15,
                        pitch: 60,
                        bearing: 0,
                        speed: 1.2,
                        curve: 1.4,
                        essential: true
                    });
                }
            });

            // Initialize Threebox when the map style has loaded
            map.on('style.load', () =&gt; {
                map.addSource('mapbox-dem', {
                    'type': 'raster-dem',
                    'url': 'mapbox://mapbox.mapbox-terrain-dem-v1',
                    'tileSize': 512,
                    'maxzoom': 14
                });
                map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 });

                 map.setFog({ /* ... fog settings ... */ }); // Keep fog settings as before

                window.tb = new Threebox(
                    map,
                    map.getCanvas().getContext('webgl'),
                    {
                        defaultLights: true,
                        enableSelectingFeatures: true
                    }
                );

                let currentPopup = null; // Keep track of the popup

                destinations.forEach(dest =&gt; {
                    const geometry = new THREE.SphereGeometry( 150, 32, 16 );
                    const material = new THREE.MeshPhongMaterial( { color: 0xff8800, emissive: 0x331100 } );
                    const sphere = new THREE.Mesh( geometry, material );

                    let marker3D = window.tb.Object3D({
                        obj: sphere,
                        units: 'meters',
                        anchor: 'center',
                        rotation: { x: 0, y: 0, z: 0 },
                        tooltip: dest.name
                    })
                    .setCoords(dest.coords);

                    window.tb.add(marker3D);

                    marker3D.addEventListener('SelectedChange', function(e){
                         if (currentPopup) {
                            currentPopup.remove();
                            currentPopup = null;
                         }
                         if (e.detail.selected) {
                            currentPopup = new mapboxgl.Popup({ closeButton: false, offset: [0, -50] })
                                .setLngLat(dest.coords)
                                .setHTML(`&lt;strong&gt;${dest.name}&lt;/strong&gt;`)
                                .addTo(map);
                         }
                     }, false);
                });

                map.triggerRepaint();
            }); // End map.on('style.load')

            // Add Map Controls
            map.addControl(new mapboxgl.NavigationControl());
            map.addControl(new mapboxgl.FullscreenControl());

            // Error Handling for Mapbox
            map.on('error', (e) =&gt; {
                console.error('Mapbox GL Error:', e.error);
                // Optionally display a user-friendly message on the map container
                 if (e.error?.message.includes('token')) {
                     document.getElementById('map').innerHTML = '&lt;p style="padding:20px; text-align:center; color: red;"&gt;Error: Invalid Mapbox Access Token or URL restrictions preventing access.&lt;/p&gt;';
                 } else {
                     document.getElementById('map').innerHTML = '&lt;p style="padding:20px; text-align:center; color: orange;"&gt;Map loading error. Please try again later.&lt;/p&gt;';
                 }
            });


        }); // End DOMContentLoaded
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Tic tac toe game</title><link>http://rajclick.blogspot.com/2025/03/tic-tac-toe-game.html</link><category>Game</category><pubDate>Mon, 31 Mar 2025 00:34:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-3317896675172023936</guid><description>&lt;!-- START: Complete Self-Contained Cyber Grid Combat (Tic-Tac-Toe) Block --&gt;

&lt;!-- Main container for the game --&gt;
&lt;div id="post-cyber-ttt"&gt;

    &lt;!-- START: Game-Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles */
        #post-cyber-ttt {
            /* --- CSS Variables (Default: Dark Cyberpunk) --- */
            --ttt-bg-color: #0d0d1a;
            --ttt-text-color: #e0e0ff;
            --ttt-heading-color: #00ffff; /* Cyan */
            --ttt-border-color: #6a0dad; /* Purple */
            --ttt-grid-line-color: rgba(0, 255, 255, 0.3);
            --ttt-cell-bg: rgba(20, 20, 40, 0.7);
            --ttt-cell-hover-bg: rgba(0, 255, 255, 0.1);
            --ttt-x-color: #ff00ff; /* Magenta */
            --ttt-o-color: #00ff00; /* Neon Green */
            --ttt-blocked-color: #ff4500; /* Orange-Red for blocked */
            --ttt-win-bg: rgba(0, 255, 0, 0.2);
            --ttt-button-bg: #331a3f;
            --ttt-button-border: #8e2de2; /* Lighter Purple */
            --ttt-button-text: #00ffff;
            --ttt-button-hover-bg: #4a00e0;
            --ttt-button-hover-text: #ffffff;
            --ttt-ability-button-bg: #2a004f;
            --ttt-ability-button-border: #ff00ff;
            --ttt-ability-button-text: #ff00ff;
            --ttt-ability-active-bg: #ff00ff;
            --ttt-ability-active-text: #0d0d1a;
            --ttt-ability-disabled-opacity: 0.5;
            --ttt-status-text: #00ffcc;
            --ttt-shadow-color: rgba(0, 255, 255, 0.25);
            --ttt-explanation-text: #a0a0c0;

            /* Base styles */
            font-family: 'Consolas', 'Courier New', monospace;
            background-color: var(--ttt-bg-color);
            color: var(--ttt-text-color);
            padding: 25px 30px; border-radius: 5px;
            box-shadow: 0 0 18px var(--ttt-shadow-color), inset 0 0 12px rgba(13, 13, 26, 0.6);
            width: 100%; max-width: 600px; /* Slightly wider for controls */
            margin: 25px auto; border: 2px solid var(--ttt-border-color);
            transition: all 0.3s; box-sizing: border-box; text-align: center;
        }
        #post-cyber-ttt *, #post-cyber-ttt *::before, #post-cyber-ttt *::after { box-sizing: border-box; }

        /* --- Light Mode Overrides --- */
        #post-cyber-ttt.ttt-light-mode {
            --ttt-bg-color: #f0f2f5;
            --ttt-text-color: #333;
            --ttt-heading-color: #0a6ed1;
            --ttt-border-color: #a0a0c0;
            --ttt-grid-line-color: #cccccc;
            --ttt-cell-bg: #ffffff;
            --ttt-cell-hover-bg: #e8f0fe;
            --ttt-x-color: #d9006c;
            --ttt-o-color: #008a00;
            --ttt-blocked-color: #cc0000;
            --ttt-win-bg: rgba(76, 175, 80, 0.15);
            --ttt-button-bg: #e9ecef;
            --ttt-button-border: #adb5bd;
            --ttt-button-text: #333;
            --ttt-button-hover-bg: #ced4da;
            --ttt-button-hover-text: #000;
            --ttt-ability-button-bg: #f8f9fa;
            --ttt-ability-button-border: #0a6ed1;
            --ttt-ability-button-text: #0a6ed1;
            --ttt-ability-active-bg: #0a6ed1;
            --ttt-ability-active-text: #ffffff;
            --ttt-status-text: #0056b3;
            --ttt-shadow-color: rgba(0, 0, 0, 0.15);
            --ttt-explanation-text: #555;
        }

        /* --- Element Styles (Scoped) --- */
        #post-cyber-ttt h2.game-title { /* More specific selector */
            margin-top: 0; margin-bottom: 10px; color: var(--ttt-heading-color);
            font-size: 2rem; text-shadow: 0 0 6px var(--ttt-heading-color);
        }

        /* Theme &amp; Mode Selection */
        #post-cyber-ttt .controls-top {
            display: flex; justify-content: space-between; align-items: center;
            margin-bottom: 15px; flex-wrap: wrap; gap: 10px;
        }
        #post-cyber-ttt .mode-selection button,
        #post-cyber-ttt #tttThemeSwitch {
            padding: 6px 12px; cursor: pointer; border-radius: 3px;
            border: 1px solid var(--ttt-button-border);
            background-color: var(--ttt-button-bg); color: var(--ttt-button-text);
            font-weight: bold; font-size: 0.85em; transition: all 0.2s;
            font-family: inherit;
        }
         #post-cyber-ttt .mode-selection button:hover,
         #post-cyber-ttt #tttThemeSwitch:hover {
             background-color: var(--ttt-button-hover-bg);
             color: var(--ttt-button-hover-text);
         }
          #post-cyber-ttt .mode-selection button.active {
             background-color: var(--ttt-heading-color); /* Use heading color */
             color: var(--ttt-bg-color); /* Use bg color for text */
             border-color: var(--ttt-heading-color);
             box-shadow: 0 0 5px var(--ttt-heading-color);
          }


        /* Status Display */
        #post-cyber-ttt #ttt-status {
            margin-bottom: 15px; font-size: 1.2rem; color: var(--ttt-status-text);
            font-weight: bold; min-height: 1.5em; text-shadow: 0 0 4px var(--ttt-status-text);
        }

        /* Game Board */
        #post-cyber-ttt #ttt-board {
            display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
            width: 90%; max-width: 330px; /* Slightly smaller board */
            aspect-ratio: 1 / 1; margin: 0 auto 20px auto;
            border: 2px solid var(--ttt-grid-line-color);
             background-image:
                linear-gradient(var(--ttt-grid-line-color) 1px, transparent 1px),
                linear-gradient(90deg, var(--ttt-grid-line-color) 1px, transparent 1px);
             background-size: calc(100% / 3) calc(100% / 3); /* Explicit grid lines */
              background-color: var(--ttt-cell-bg); /* BG behind lines */
        }
        #post-cyber-ttt .ttt-cell {
             /* Remove internal borders, use background grid lines */
            background-color: transparent; /* Cells are transparent over grid BG */
            display: flex; justify-content: center; align-items: center;
            font-size: 3.2rem; font-weight: bold; cursor: pointer;
            transition: background-color 0.2s ease-in-out; user-select: none;
        }
        #post-cyber-ttt .ttt-cell:hover:not(.x):not(.o):not(.blocked) {
            background-color: var(--ttt-cell-hover-bg);
        }

        /* Player Marks &amp; Blocked Cells */
        #post-cyber-ttt .ttt-cell.x,
        #post-cyber-ttt .ttt-cell.o,
        #post-cyber-ttt .ttt-cell.blocked { cursor: not-allowed; }

        #post-cyber-ttt .ttt-cell.x { color: var(--ttt-x-color); text-shadow: 0 0 10px var(--ttt-x-color); }
        #post-cyber-ttt .ttt-cell.o { color: var(--ttt-o-color); text-shadow: 0 0 10px var(--ttt-o-color); }
        #post-cyber-ttt .ttt-cell.blocked {
             color: var(--ttt-blocked-color);
             /* Use a content character or SVG for blocked */
             content: '⛝'; /* Example symbol */
             font-size: 2.5rem; /* Adjust size */
              text-shadow: 0 0 5px var(--ttt-blocked-color);
              opacity: 0.7;
         }
          /* Ensure empty cells clear content */
         #post-cyber-ttt .ttt-cell:not(.x):not(.o):not(.blocked)::before {
             content: ''; /* Clear pseudo-elements if any */
         }


         /* Winning Cells Highlight */
         #post-cyber-ttt .ttt-cell.win {
             background-color: var(--ttt-win-bg) !important;
             animation: pulseWin 0.8s infinite alternate;
         }
         @keyframes pulseWin {
             from { box-shadow: 0 0 5px var(--ttt-o-color); }
             to { box-shadow: 0 0 15px var(--ttt-o-color), 0 0 8px var(--ttt-o-color); }
         }
          #post-cyber-ttt .ttt-cell.win.x { animation-name: pulseWinX; } /* Different pulse for X */
          @keyframes pulseWinX {
             from { box-shadow: 0 0 5px var(--ttt-x-color); }
             to { box-shadow: 0 0 15px var(--ttt-x-color), 0 0 8px var(--ttt-x-color); }
         }


        /* Ability Controls */
        #post-cyber-ttt #ability-controls {
             margin: 20px auto;
             padding: 15px;
             border: 1px dashed var(--ttt-border-color);
             border-radius: 5px;
             max-width: 450px;
        }
         #post-cyber-ttt #ability-controls.hidden { display: none; }
         #post-cyber-ttt #ability-title {
             font-size: 1rem; margin-bottom: 10px; font-weight: bold;
             color: var(--ttt-status-text);
         }
         #post-cyber-ttt .ability-buttons {
             display: flex; justify-content: center; gap: 15px; flex-wrap: wrap;
         }
         #post-cyber-ttt button.ability-btn {
             padding: 8px 15px; font-size: 0.9rem; cursor: pointer;
             background: var(--ttt-ability-button-bg); color: var(--ttt-ability-button-text);
             border: 1px solid var(--ttt-ability-button-border); border-radius: 3px;
             transition: all 0.2s; font-family: inherit; font-weight: bold;
         }
          #post-cyber-ttt button.ability-btn:hover:not(:disabled) {
             box-shadow: 0 0 8px var(--ttt-ability-button-text);
             transform: translateY(-2px);
          }
          #post-cyber-ttt button.ability-btn:disabled {
             opacity: var(--ttt-ability-disabled-opacity);
             cursor: not-allowed;
              box-shadow: none; transform: none;
          }
          #post-cyber-ttt button.ability-btn.active-ability {
             background-color: var(--ttt-ability-active-bg);
             color: var(--ttt-ability-active-text);
             box-shadow: 0 0 10px var(--ttt-ability-active-bg);
          }

        /* Restart Button */
        #post-cyber-ttt #ttt-restart-btn {
            padding: 10px 25px; font-size: 1rem; cursor: pointer;
            background: var(--ttt-button-bg); color: var(--ttt-button-text);
            border: 1px solid var(--ttt-button-border); border-radius: 3px;
            transition: all 0.3s; font-family: inherit; font-weight: bold;
            margin-top: 15px; /* Space above restart */
        }
        #post-cyber-ttt #ttt-restart-btn:hover {
            background: var(--ttt-button-hover-bg); color: var(--ttt-button-hover-text);
        }

         /* Explanation Section */
        #post-cyber-ttt .ttt-explanation {
            margin-top: 30px; padding-top: 20px;
            border-top: 1px solid var(--ttt-border-color);
            font-size: 0.9rem; line-height: 1.6;
            color: var(--ttt-explanation-text); text-align: left;
        }
        #post-cyber-ttt .ttt-explanation h4 { margin-bottom: 10px; color: var(--ttt-text-color); font-size: 1.1rem; }
        #post-cyber-ttt .ttt-explanation p { margin-bottom: 10px; }
        #post-cyber-ttt .ttt-explanation ul { margin-left: 20px; margin-bottom: 10px; }

    &lt;/style&gt;
    &lt;!-- END: Game-Specific Styles --&gt;


    &lt;!-- START: Game HTML --&gt;
    &lt;h2 class="game-title"&gt;CYBER GRID COMBAT&lt;/h2&gt;

    &lt;!-- Top Controls: Mode &amp; Theme --&gt;
    &lt;div class="controls-top"&gt;
        &lt;div class="mode-selection"&gt;
            &lt;button type="button" id="mode-pva" class="active"&gt;vs AI&lt;/button&gt;
            &lt;button type="button" id="mode-pvp"&gt;vs Player&lt;/button&gt;
        &lt;/div&gt;
        &lt;div class="theme-switch-wrapper"&gt;
            &lt;button id="tttThemeSwitch"&gt;Switch Theme&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Status Display --&gt;
    &lt;div id="ttt-status"&gt;Player X's Turn&lt;/div&gt;

    &lt;!-- Game Board --&gt;
    &lt;div id="ttt-board"&gt;
        &lt;!-- Cells are generated by JS or hardcoded like this --&gt;
        &lt;div class="ttt-cell" data-cell-index="0"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="1"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="2"&gt;&lt;/div&gt;
        &lt;div class="ttt-cell" data-cell-index="3"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="4"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="5"&gt;&lt;/div&gt;
        &lt;div class="ttt-cell" data-cell-index="6"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="7"&gt;&lt;/div&gt; &lt;div class="ttt-cell" data-cell-index="8"&gt;&lt;/div&gt;
    &lt;/div&gt;

     &lt;!-- Ability Controls Section (Initially Hidden for PvP unless enabled) --&gt;
     &lt;div id="ability-controls" class="hidden"&gt;
        &lt;div id="ability-title"&gt;Player X Abilities:&lt;/div&gt;
        &lt;div class="ability-buttons"&gt;
            &lt;button type="button" class="ability-btn" id="ability-bomb" data-ability="bomb"&gt;EMP Blast (1)&lt;/button&gt;
            &lt;button type="button" class="ability-btn" id="ability-block" data-ability="block"&gt;Glitch Field (1)&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Restart Button --&gt;
    &lt;button id="ttt-restart-btn" type="button"&gt;Restart Game&lt;/button&gt;

     &lt;!-- SEO Explanation Section --&gt;
    &lt;div class="ttt-explanation"&gt;
        &lt;h4&gt;About Cyber Grid Combat&lt;/h4&gt;
        &lt;p&gt;
            Experience Tic-Tac-Toe reimagined in a cyberpunk future! Outwit your opponent – human or AI – on the digital grid. This version includes special abilities to turn the tide of battle.
        &lt;/p&gt;
        &lt;h4&gt;How to Play:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;Select your mode: Play against a basic AI or a local friend.&lt;/li&gt;
            &lt;li&gt;Players take turns placing their mark (X or O) on an empty cell.&lt;/li&gt;
            &lt;li&gt;The first to get three marks in a row (horizontally, vertically, or diagonally) wins.&lt;/li&gt;
            &lt;li&gt;If the grid is full with no winner, the game is a draw.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Special Abilities (1 use per game):&lt;/strong&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;strong&gt;EMP Blast:&lt;/strong&gt; Activate, then click an *opponent's* mark to remove it. Consumes your turn.&lt;/li&gt;
                    &lt;li&gt;&lt;strong&gt;Glitch Field:&lt;/strong&gt; Activate, then click an *empty* cell to permanently block it. Consumes your turn.&lt;/li&gt;
                &lt;/ul&gt;
             &lt;/li&gt;
            &lt;li&gt;Click "Restart Game" to start a new match in the current mode.&lt;/li&gt;
            &lt;li&gt;Toggle between dark and light themes using the switch.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;
    &lt;!-- END: Game HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-cyber-ttt Container --&gt;

&lt;!-- START: Game Script (Scoped, Themed, AI, Abilities - FIXED AI TURN INTERACTION) --&gt;
&lt;script&gt;
    // Wrap in IIFE
    (function() {
        const gameContainer = document.getElementById('post-cyber-ttt');
        if (!gameContainer) { console.error("Cyber TTT container not found!"); return; }

        // Scoped DOM selectors
        const $ = (selector) =&gt; gameContainer.querySelector(selector);
        const $$ = (selector) =&gt; gameContainer.querySelectorAll(selector);

        const statusDisplay = $('#ttt-status');
        const boardElement = $('#ttt-board');
        const cells = $$('.ttt-cell');
        const restartButton = $('#ttt-restart-btn');
        const themeSwitchBtn = $('#tttThemeSwitch');
        const modePvaBtn = $('#mode-pva');
        const modePvpBtn = $('#mode-pvp');
        const abilityControls = $('#ability-controls');
        const abilityTitle = $('#ability-title');
        const abilityButtons = $$('.ability-btn');

        const localStorageThemeKey = 'cyberTttTheme';

        // --- Game State ---
        let board = ['', '', '', '', '', '', '', '', ''];
        let currentPlayer = 'X';
        let gameActive = true;
        let gameMode = 'pva'; // Default to PvA
        const aiPlayer = 'O';
        let activeAbility = null;
        let playerAbilities = { X: { bomb: 1, block: 1 }, O: { bomb: 1, block: 1 } };

        const winningConditions = [
            [0, 1, 2], [3, 4, 5], [6, 7, 8],
            [0, 3, 6], [1, 4, 7], [2, 5, 8],
            [0, 4, 8], [2, 4, 6]
        ];
        const playerClasses = { 'X': 'x', 'O': 'o', 'B': 'blocked' };

        // --- Theme Switching ---
        function applyTheme(theme) {
            if (theme === 'light') { gameContainer.classList.add('ttt-light-mode'); }
            else { gameContainer.classList.remove('ttt-light-mode'); }
            if (themeSwitchBtn) { themeSwitchBtn.textContent = theme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'; }
            localStorage.setItem(localStorageThemeKey, theme);
        }
        if (themeSwitchBtn) {
            themeSwitchBtn.addEventListener('click', () =&gt; {
                const currentThemeIsLight = gameContainer.classList.contains('ttt-light-mode');
                applyTheme(currentThemeIsLight ? 'dark' : 'light');
            });
        }

        // --- Mode Switching ---
         function setGameMode(mode) {
             gameMode = mode;
             if (modePvaBtn &amp;&amp; modePvpBtn) { // Check if buttons exist
                modePvaBtn.classList.toggle('active', mode === 'pva');
                modePvpBtn.classList.toggle('active', mode === 'pvp');
             }
             restartGame(); // Restart when mode changes
         }
          if (modePvaBtn) modePvaBtn.addEventListener('click', () =&gt; setGameMode('pva'));
          if (modePvpBtn) modePvpBtn.addEventListener('click', () =&gt; setGameMode('pvp'));

        // --- Game Logic ---
        function updateStatusDisplay(message) { if (statusDisplay) statusDisplay.textContent = message; }
        function updateAbilityDisplay() {
            if (!abilityControls || !gameActive) {
                if (abilityControls) abilityControls.classList.add('hidden');
                return;
            }
             // Hide if it's AI's turn in PvA mode
             if (gameMode === 'pva' &amp;&amp; currentPlayer === aiPlayer) {
                 abilityControls.classList.add('hidden');
                 return;
             }

            abilityControls.classList.remove('hidden');
            if (abilityTitle) abilityTitle.textContent = `Player ${currentPlayer} Abilities:`;
            abilityButtons.forEach(btn =&gt; {
                 const ability = btn.dataset.ability;
                 const usesLeft = playerAbilities[currentPlayer]?.[ability] ?? 0;
                 btn.textContent = `${btn.id === 'ability-bomb' ? 'EMP Blast' : 'Glitch Field'} (${usesLeft})`;
                 btn.disabled = usesLeft &lt;= 0 || activeAbility !== null;
                 btn.classList.toggle('active-ability', activeAbility === ability); // Simplified toggle
            });
        }

        // --- Ability Handling ---
        function activateAbility(abilityName) {
             if (!gameActive || playerAbilities[currentPlayer]?.[abilityName] &lt;= 0 || activeAbility || (gameMode === 'pva' &amp;&amp; currentPlayer === aiPlayer)) return; // Prevent activating during AI turn

             activeAbility = abilityName;
             updateStatusDisplay(`Ability Active: ${abilityName === 'bomb' ? 'EMP Blast' : 'Glitch Field'} - Target a cell!`);
             updateAbilityDisplay(); // Update buttons state (highlight active, disable others)
         }

         function handleAbilityUse(targetCell, targetIndex) {
             if (!activeAbility || !gameActive) return;

             let abilityUsedSuccessfully = false;
             const abilityName = activeAbility;
             const opponent = currentPlayer === 'X' ? 'O' : 'X';

             if (abilityName === 'bomb' &amp;&amp; board[targetIndex] === opponent) {
                 board[targetIndex] = '';
                 targetCell.textContent = '';
                 targetCell.classList.remove(playerClasses[opponent]);
                 playerAbilities[currentPlayer].bomb--;
                 abilityUsedSuccessfully = true;
             } else if (abilityName === 'block' &amp;&amp; board[targetIndex] === '') {
                 board[targetIndex] = 'B';
                 targetCell.textContent = ''; // Clear any text
                 targetCell.classList.add(playerClasses['B']);
                 targetCell.innerHTML = 'ɭ D;'; // Blocked symbol ⛝
                 playerAbilities[currentPlayer].block--;
                 abilityUsedSuccessfully = true;
             } else {
                 // Invalid target for the selected ability
                 const requiredTarget = abilityName === 'bomb' ? "opponent's mark" : "an empty cell";
                 updateStatusDisplay(`Invalid Target! ${abilityName === 'bomb' ? 'EMP Blast' : 'Glitch Field'} requires ${requiredTarget}.`);
                 // Don't consume turn or ability, just reset the active state
                 resetAbilityState();
                 return; // Exit without proceeding further
             }

             // Reset active ability state *after* successful or failed use attempt that required action
              resetAbilityState(); // Clear active ability visual state first

             if (abilityUsedSuccessfully) {
                 // Ability use consumes the turn. Check game result immediately.
                 if (!handleResultValidation()) { // If game didn't end
                      // Switch player *immediately* after successful ability use
                      switchPlayer();
                      // If now AI's turn in PvA mode, trigger AI
                      if (gameMode === 'pva' &amp;&amp; currentPlayer === aiPlayer &amp;&amp; gameActive) {
                          triggerAiMove();
                      }
                 }
             }
              updateAbilityDisplay(); // Update counts/disabled state after everything
         }

          function resetAbilityState() {
               activeAbility = null;
               // Status update handled after use or by next turn logic
               updateAbilityDisplay(); // Update button states
          }

        // --- Player Move &amp; AI ---
        function handleCellPlayed(clickedCell, clickedCellIndex) {
            if (!gameActive || board[clickedCellIndex] !== '' || board[clickedCellIndex] === 'B') return false; // Prevent playing on non-empty or blocked

            board[clickedCellIndex] = currentPlayer;
            clickedCell.textContent = currentPlayer;
            clickedCell.classList.add(playerClasses[currentPlayer]);
            // Ensure blocked class is removed if cell was somehow cleared by EMP? (edge case)
            clickedCell.classList.remove(playerClasses['B']);
            clickedCell.innerHTML = currentPlayer; // Ensure symbol overrides blocked symbol HTML

            return true;
        }

        function handlePlayerMove(clickedCell, clickedCellIndex) {
             if (handleCellPlayed(clickedCell, clickedCellIndex)) { // If move was valid
                  if (!handleResultValidation()) { // If game didn't end
                      // If PvA mode, trigger AI turn (AFTER validation and player switch)
                      if (gameMode === 'pva' &amp;&amp; currentPlayer === aiPlayer &amp;&amp; gameActive) {
                          triggerAiMove();
                      }
                  }
             }
        }

        function triggerAiMove() {
             if (!gameActive || currentPlayer !== aiPlayer || gameMode !== 'pva') return; // Extra guards

             updateStatusDisplay('AI is thinking...');
             if (boardElement) boardElement.style.pointerEvents = 'none'; // Disable board clicks
             if (abilityControls) abilityControls.classList.add('hidden'); // Hide abilities

             setTimeout(() =&gt; {
                 if (gameActive &amp;&amp; currentPlayer === aiPlayer) { // Check state again after delay
                     makeAiMove();
                 }
                 // Re-enable ONLY IF it's now the human's turn and game is active
                 if (gameActive &amp;&amp; currentPlayer !== aiPlayer) {
                      if (boardElement) boardElement.style.pointerEvents = 'auto';
                 } else if (!gameActive) {
                     // If game ended, keep it disabled until restart
                      if (boardElement) boardElement.style.pointerEvents = 'none';
                 }
                 updateAbilityDisplay(); // Update ability display for human (will be hidden if still AI turn somehow)
             }, 800); // Slightly longer thinking time
        }


        function makeAiMove() {
            if (!gameActive || currentPlayer !== aiPlayer) return;

             let moveIndex = -1;
             const humanPlayer = aiPlayer === 'X' ? 'O' : 'X';
             const emptyCellsIndices = board.map((cell, index) =&gt; cell === '' ? index : null).filter(index =&gt; index !== null);

             // --- AI Strategy ---
             // 1. Check for AI winning move
             for (const condition of winningConditions) {
                const [a, b, c] = condition;
                if (board[a] === aiPlayer &amp;&amp; board[b] === aiPlayer &amp;&amp; board[c] === '') { moveIndex = c; break; }
                if (board[a] === aiPlayer &amp;&amp; board[c] === aiPlayer &amp;&amp; board[b] === '') { moveIndex = b; break; }
                if (board[b] === aiPlayer &amp;&amp; board[c] === aiPlayer &amp;&amp; board[a] === '') { moveIndex = a; break; }
             }
             // 2. Check for Player winning move to block
             if (moveIndex === -1) {
                 for (const condition of winningConditions) {
                     const [a, b, c] = condition;
                     if (board[a] === humanPlayer &amp;&amp; board[b] === humanPlayer &amp;&amp; board[c] === '') { moveIndex = c; break; }
                     if (board[a] === humanPlayer &amp;&amp; board[c] === humanPlayer &amp;&amp; board[b] === '') { moveIndex = b; break; }
                     if (board[b] === humanPlayer &amp;&amp; board[c] === humanPlayer &amp;&amp; board[a] === '') { moveIndex = a; break; }
                 }
             }
             // 3. Prioritize center if empty
             if (moveIndex === -1 &amp;&amp; board[4] === '') {
                  moveIndex = 4;
             }
              // 4. Prioritize corners if empty
             if (moveIndex === -1) {
                 const corners = [0, 2, 6, 8].filter(index =&gt; board[index] === '');
                 if (corners.length &gt; 0) {
                     moveIndex = corners[Math.floor(Math.random() * corners.length)];
                 }
             }
             // 5. Choose random available cell as last resort
             if (moveIndex === -1 &amp;&amp; emptyCellsIndices.length &gt; 0) {
                 moveIndex = emptyCellsIndices[Math.floor(Math.random() * emptyCellsIndices.length)];
             }
             // --- End AI Strategy ---

             if (moveIndex !== -1) {
                 const cellElement = $(`[data-cell-index="${moveIndex}"]`);
                 if (cellElement &amp;&amp; board[moveIndex] === '') { // Final check if cell is still empty
                      handleCellPlayed(cellElement, moveIndex);
                      handleResultValidation(); // Check result *after* AI move
                 } else {
                      console.warn("AI attempted invalid move to index:", moveIndex);
                      // If AI failed, try another random move immediately? (Optional fallback)
                      if (emptyCellsIndices.length &gt; 0) {
                          const fallbackIndex = emptyCellsIndices[Math.floor(Math.random() * emptyCellsIndices.length)];
                           const fallbackCell = $(`[data-cell-index="${fallbackIndex}"]`);
                           if (fallbackCell &amp;&amp; board[fallbackIndex] === '') {
                                handleCellPlayed(fallbackCell, fallbackIndex);
                                handleResultValidation();
                           } else {
                               handleResultValidation(); // Just re-validate if fallback fails too
                           }
                      } else {
                          handleResultValidation(); // Re-validate if no empty cells
                      }
                 }
             } else {
                  console.log("AI couldn't find a move (board likely full or blocked).");
                   handleResultValidation(); // Check for draw again
             }
        }


        function handleResultValidation() {
            let roundWon = false;
            let winningCombo = [];

            for (let i = 0; i &lt; winningConditions.length; i++) {
                const winCondition = winningConditions[i];
                const a = board[winCondition[0]]; const b = board[winCondition[1]]; const c = board[winCondition[2]];
                if (a === '' || b === '' || c === '' || a === 'B' || b === 'B' || c === 'B') continue;
                if (a === b &amp;&amp; b === c) { roundWon = true; winningCombo = winCondition; break; }
            }

            if (roundWon) {
                updateStatusDisplay(`Player ${currentPlayer} Wins!`); gameActive = false;
                winningCombo.forEach(index =&gt; $(`[data-cell-index="${index}"]`)?.classList.add('win', playerClasses[currentPlayer]));
                if (abilityControls) abilityControls.classList.add('hidden');
                if (boardElement) boardElement.style.pointerEvents = 'none'; // Disable board on win
                return true; // Game ended
            }

            const playableCellsLeft = board.filter(cell =&gt; cell === '').length;
            if (playableCellsLeft === 0) {
                 updateStatusDisplay('Gridlocked! It\'s a Draw!'); gameActive = false;
                 if (abilityControls) abilityControls.classList.add('hidden');
                 if (boardElement) boardElement.style.pointerEvents = 'none'; // Disable board on draw
                 return true; // Game ended
            }

            // **FIX:** If game continues, switch player *here* before potentially triggering AI
             switchPlayer();

            return false; // Game continues
        }

        // Switch player state and update UI accordingly
         function switchPlayer() {
             currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
             // Update status *after* switching
             updateStatusDisplay(`Player ${currentPlayer}'s Turn`);
             // Update ability display for the new player
             updateAbilityDisplay();
         }


        function handleCellClick(event) {
            // Prevent clicks if game inactive or during AI turn (via pointer-events CSS)
             if (!gameActive || (gameMode === 'pva' &amp;&amp; currentPlayer === aiPlayer)) return;

            const clickedCell = event.target.closest('.ttt-cell'); // Get the cell itself
            if (!clickedCell) return; // Click wasn't on a cell

            const clickedCellIndex = parseInt(clickedCell.getAttribute('data-cell-index'), 10);

            if (activeAbility) {
                 handleAbilityUse(clickedCell, clickedCellIndex);
                 // Note: handleAbilityUse now handles the turn progression/AI trigger
            } else if (board[clickedCellIndex] === '' &amp;&amp; board[clickedCellIndex] !== 'B') {
                 // Normal player move
                 handlePlayerMove(clickedCell, clickedCellIndex);
                 // Note: handlePlayerMove now handles the result check and AI trigger
            }
        }

        function restartGame() {
            board = ['', '', '', '', '', '', '', '', ''];
            currentPlayer = 'X'; gameActive = true;
            playerAbilities = { X: { bomb: 1, block: 1 }, O: { bomb: 1, block: 1 } };
            activeAbility = null;

            updateStatusDisplay(`Player ${currentPlayer}'s Turn`);
            cells.forEach(cell =&gt; {
                cell.textContent = ''; cell.innerHTML = ''; // Clear both text and potential symbol HTML
                cell.className = 'ttt-cell'; // Reset classes completely
            });
            updateAbilityDisplay();
            if (boardElement) boardElement.style.pointerEvents = 'auto'; // Ensure board is clickable
        }


        // --- Initialization ---
        function initializeGame() {
            const savedTheme = localStorage.getItem(localStorageThemeKey) || 'dark';
            applyTheme(savedTheme);

            if (boardElement) boardElement.addEventListener('click', handleCellClick);
            if (restartButton) restartButton.addEventListener('click', restartGame);
             abilityButtons.forEach(btn =&gt; btn.addEventListener('click', () =&gt; activateAbility(btn.dataset.ability)));

            setGameMode('pva'); // Set default mode &amp; trigger initial restart
        }

        // Run initialization
        if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeGame); }
        else { initializeGame(); }

    })(); // End IIFE
&lt;/script&gt;
&lt;!-- END: Game Script --&gt;

&lt;!-- END: Complete Self-Contained Cyberpunk Tic-Tac-Toe Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Word Scramble Game</title><link>http://rajclick.blogspot.com/2025/03/word-scramble-game.html</link><category>Game</category><pubDate>Sun, 30 Mar 2025 13:23:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-5209149233094744325</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
  &lt;meta charset="UTF-8" /&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"/&gt;
  &lt;title&gt;Word Scramble Game&lt;/title&gt;
  &lt;style&gt;
    body {
      margin: 0;
      font-family: Arial, sans-serif;
      background-color: #121212;
      color: #fff;
      display: flex;
      justify-content: center;
    }
    .widget-container {
      max-width: 1000px;
      width: 100%;
      padding: 20px;
      text-align: center;
    }
    .toggle-mode {
      position: absolute;
      top: 20px;
      right: 20px;
      cursor: pointer;
      font-size: 24px;
    }
    .scramble-box {
      font-size: 2em;
      margin: 20px 0;
    }
    input[type="text"] {
      padding: 10px;
      font-size: 1em;
      width: 250px;
      max-width: 100%;
    }
    button {
      padding: 10px 20px;
      font-size: 1em;
      margin-top: 10px;
      cursor: pointer;
    }
    #timer {
      font-size: 1.2em;
      margin: 10px 0;
    }
    .light-mode {
      background-color: #f9f9f9;
      color: #000;
    }
    .light-mode input, .light-mode button {
      background-color: #fff;
      color: #000;
    }
    .dark-mode input, .dark-mode button {
      background-color: #333;
      color: #fff;
    }
    .seo-content {
      margin-top: 30px;
      font-size: 0.9em;
      opacity: 0.8;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body class="dark-mode"&gt;
  &lt;div class="widget-container"&gt;
    &lt;div class="toggle-mode" id="modeToggle"&gt;&#127769;&lt;/div&gt;
    &lt;h1&gt;Word Scramble Game&lt;/h1&gt;
    &lt;div class="scramble-box" id="scrambledWord"&gt;Loading...&lt;/div&gt;
    &lt;input type="text" id="userInput" placeholder="Guess the word" /&gt;
    &lt;div id="timer"&gt;Time left: 30s&lt;/div&gt;
    &lt;button onclick="checkAnswer()"&gt;Submit&lt;/button&gt;
    &lt;button onclick="startGame()"&gt;Restart&lt;/button&gt;
    &lt;div id="result"&gt;&lt;/div&gt;

    &lt;div class="seo-content"&gt;
      &lt;p&gt;&lt;strong&gt;Word Scramble Game:&lt;/strong&gt; Sharpen your brain with our free online word scramble challenge. Improve vocabulary and spelling while having fun. Ideal for kids and adults. Play anywhere, anytime!&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const words = ["javascript", "function", "variable", "element", "document", "object", "browser", "scramble", "internet", "widget"];
    let currentWord = "";
    let timer;
    let timeLeft = 30;

    function shuffleWord(word) {
      return word.split('').sort(() =&gt; Math.random() - 0.5).join('');
    }

    function startGame() {
      document.getElementById("result").innerText = "";
      timeLeft = 30;
      currentWord = words[Math.floor(Math.random() * words.length)];
      document.getElementById("scrambledWord").innerText = shuffleWord(currentWord);
      document.getElementById("userInput").value = "";
      document.getElementById("timer").innerText = `Time left: ${timeLeft}s`;

      if (timer) clearInterval(timer);
      timer = setInterval(() =&gt; {
        timeLeft--;
        document.getElementById("timer").innerText = `Time left: ${timeLeft}s`;
        if (timeLeft &lt;= 0) {
          clearInterval(timer);
          document.getElementById("result").innerText = `Time's up! The word was "${currentWord}".`;
        }
      }, 1000);
    }

    function checkAnswer() {
      const guess = document.getElementById("userInput").value.toLowerCase();
      if (guess === currentWord) {
        clearInterval(timer);
        document.getElementById("result").innerText = "&#127881; Correct! You guessed it!";
      } else {
        document.getElementById("result").innerText = "❌ Try again!";
      }
    }

    document.getElementById("modeToggle").addEventListener("click", () =&gt; {
      document.body.classList.toggle("light-mode");
      document.body.classList.toggle("dark-mode");
      const isLight = document.body.classList.contains("light-mode");
      document.getElementById("modeToggle").innerText = isLight ? "☀️" : "&#127769;";
    });

    startGame();
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Number Guessing Game</title><link>http://rajclick.blogspot.com/2025/03/number-guessing-game.html</link><category>Game</category><pubDate>Sun, 30 Mar 2025 13:14:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-231332633801137535</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
  &lt;meta charset="UTF-8" /&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&gt;
  &lt;title&gt;Number Guessing Game Widget&lt;/title&gt;
  &lt;style&gt;
    body {
      margin: 0;
      font-family: Arial, sans-serif;
      background-color: #121212;
      color: #f0f0f0;
      transition: all 0.3s ease;
    }

    .light-mode {
      background-color: #ffffff;
      color: #121212;
    }

    .container {
      max-width: 1000px;
      margin: auto;
      padding: 40px 20px;
      text-align: center;
      position: relative;
    }

    .widget-box {
      background-color: #1e1e1e;
      border-radius: 16px;
      padding: 30px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    }

    .light-mode .widget-box {
      background-color: #f5f5f5;
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    }

    input[type="number"] {
      padding: 10px;
      border-radius: 8px;
      border: none;
      font-size: 16px;
      margin-right: 10px;
      width: 120px;
    }

    button {
      padding: 10px 16px;
      border: none;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      margin-top: 10px;
      margin-right: 8px;
      background-color: #4caf50;
      color: white;
      transition: background 0.3s;
    }

    button:hover {
      background-color: #45a049;
    }

    .restart-btn {
      background-color: #f44336;
    }

    .restart-btn:hover {
      background-color: #e53935;
    }

    .toggle-btn {
      position: absolute;
      top: 10px;
      right: 10px;
      background-color: transparent;
      border: none;
      font-size: 24px;
      cursor: pointer;
      color: #f0f0f0;
    }

    .light-mode .toggle-btn {
      color: #000;
    }

    .result {
      margin-top: 20px;
      font-size: 18px;
      font-weight: bold;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div class="container"&gt;
    &lt;button class="toggle-btn" onclick="toggleMode()" title="Toggle Light/Dark Mode"&gt;&#127767;&lt;/button&gt;
    &lt;div class="widget-box"&gt;
      &lt;h2&gt;&#127919; Number Guessing Game&lt;/h2&gt;
      &lt;p&gt;Guess a number between 1 and 100&lt;/p&gt;
      &lt;input type="number" id="guessInput" placeholder="Enter your guess" min="1" max="100" /&gt;
      &lt;br /&gt;
      &lt;button onclick="checkGuess()"&gt;Guess&lt;/button&gt;
      &lt;button class="restart-btn" onclick="restartGame()"&gt;Restart&lt;/button&gt;
      &lt;p class="result" id="resultText"&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;script&gt;
    let secretNumber = Math.floor(Math.random() * 100) + 1;
    let attempt = 0;

    function checkGuess() {
      const guess = parseInt(document.getElementById("guessInput").value);
      const resultText = document.getElementById("resultText");
      attempt++;

      if (isNaN(guess) || guess &lt; 1 || guess &gt; 100) {
        resultText.textContent = "Please enter a number between 1 and 100.";
      } else if (guess === secretNumber) {
        resultText.textContent = `&#127881; Correct! You guessed it in ${attempt} attempts.`;
      } else if (guess &lt; secretNumber) {
        resultText.textContent = "Too low! Try again.";
      } else {
        resultText.textContent = "Too high! Try again.";
      }
    }

    function restartGame() {
      secretNumber = Math.floor(Math.random() * 100) + 1;
      attempt = 0;
      document.getElementById("guessInput").value = "";
      document.getElementById("resultText").textContent = "";
    }

    function toggleMode() {
      document.body.classList.toggle("light-mode");
    }
  &lt;/script&gt;

  &lt;!-- SEO Content --&gt;
  &lt;div style="display:none"&gt;
    &lt;h1&gt;Number Guessing Game Widget&lt;/h1&gt;
    &lt;p&gt;Try this interactive Number Guessing Game! Guess the number between 1 and 100 and get instant feedback. Includes light/dark mode, restart option, and works perfectly on Google Blogs.&lt;/p&gt;
    &lt;p&gt;Tags: Number Game, Guess Game, Blog Widget, Interactive JavaScript Game, Fun Widget, Dark Mode Toggle, Restart Feature&lt;/p&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Cyber Pong game</title><link>http://rajclick.blogspot.com/2025/03/cyber-pong-game.html</link><category>Game</category><pubDate>Sun, 30 Mar 2025 09:21:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-3122523387701733290</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"&gt;
    &lt;!-- Updated Title --&gt;
    &lt;title&gt;Cyber Pong Explosion - Level Challenge&lt;/title&gt;
    &lt;meta name="description" content="Challenge the AI in Cyber Pong Explosion! Progress through levels of increasing difficulty in this fast-paced HTML5 Pong game with neon visuals, explosions, automatic fullscreen, and on-screen controls."&gt;
    &lt;meta name="keywords" content="HTML5 game, JavaScript game, Pong game, Cyber Pong, Neon game, Particle explosion game, Browser game, Single player game, AI opponent, Level based game, Increasing difficulty, Online game, Fullscreen game, Mobile game, Touch controls, Auto fullscreen"&gt;

    &lt;style&gt;
        /* CSS remains largely the same */
        html { scroll-behavior: smooth; }
        body {
            background-color: #0a0a1f; color: #e0e0e0; font-family: 'Consolas', 'Courier New', monospace;
            display: flex; flex-direction: column; align-items: center; margin: 0; padding: 20px;
        }
        h1 {
            color: #00ffff; text-shadow: 0 0 5px #00ffff, 0 0 10px #00ffff; margin-bottom: 10px; text-align: center;
        }
        #gameContainer {
            position: relative; border: 3px solid #ff00ff; box-shadow: 0 0 15px #ff00ff, inset 0 0 10px #ff00ff;
            margin-bottom: 15px; background-color: #000; width: 800px; height: 500px; overflow: hidden; touch-action: none;
        }
        canvas { display: block; width: 100%; height: 100%; }
        #controls { display: flex; justify-content: center; gap: 15px; margin-bottom: 20px; flex-wrap: wrap; }
        /* Removed Fullscreen button, only Play/Restart remains */
        #controls button, #gameMessage button {
            font-family: 'Consolas', 'Courier New', monospace; font-size: 1em; padding: 10px 20px; background-color: #00ff00;
            color: #0a0a1f; border: none; border-radius: 5px; cursor: pointer;
            box-shadow: 0 0 5px #00ff00, 0 0 10px #ffffff; transition: background-color 0.3s, box-shadow 0.3s, transform 0.1s;
            text-transform: uppercase; font-weight: bold;
        }
        #controls button:hover, #gameMessage button:hover { background-color: #ffffff; box-shadow: 0 0 10px #00ff00, 0 0 15px #ffffff; }
        #controls button:active, #gameMessage button:active { transform: scale(0.95); }
        .paddle-controls {
            position: absolute; left: 10px; top: 50%; transform: translateY(-50%); display: flex;
            flex-direction: column; gap: 60px; z-index: 5;
        }
        .paddle-controls button {
            width: 60px; height: 60px; font-size: 1.5em; font-weight: bold; background-color: rgba(0, 255, 255, 0.5);
            color: #0a0a1f; border: 2px solid #00ffff; border-radius: 50%; cursor: pointer; box-shadow: 0 0 8px #00ffff;
            transition: background-color 0.2s, box-shadow 0.2s; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
        }
        .paddle-controls button:hover { background-color: rgba(0, 255, 255, 0.8); box-shadow: 0 0 12px #ffffff; }
        .paddle-controls button:active { background-color: #00ffff; transform: scale(0.95); }
        #gameInfo {
            max-width: 800px; text-align: left; background-color: rgba(20, 20, 40, 0.8); padding: 15px;
            border-radius: 8px; border: 1px solid #3333ff; box-shadow: 0 0 10px #3333ff; margin-top: 10px;
        }
        #gameInfo h2 { color: #ff00ff; text-shadow: 0 0 3px #ff00ff; border-bottom: 1px solid #ff00ff; padding-bottom: 5px; }
        #gameInfo h3 { color: #00ff00; text-shadow: 0 0 3px #00ff00; margin-top: 15px; }
        #gameInfo p, #gameInfo ul { color: #c0c0ff; line-height: 1.6; }
        #gameInfo li { margin-bottom: 5px; }
        #gameInfo strong { color: #ffff00; }
        #gameMessage {
            position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #ffff00;
            font-size: 2.2em; font-weight: bold; text-shadow: 0 0 10px #ffff00, 0 0 20px #ff8800;
            text-align: center; display: none; z-index: 10; background-color: rgba(0, 0, 0, 0.85);
            padding: 25px; border-radius: 10px; border: 2px solid #ffff00; width: 70%;
        }
        #gameMessage button { margin-top: 20px; }
        /* Fullscreen specific styling (applied automatically now) */
        #gameContainer:-webkit-full-screen { width: 100%; height: 100%; border: none; box-shadow: none; }
        #gameContainer:-moz-full-screen { width: 100%; height: 100%; border: none; }
        #gameContainer:-ms-fullscreen { width: 100%; height: 100%; border: none; }
        #gameContainer:fullscreen { width: 100%; height: 100%; border: none; }
        #gameContainer:fullscreen .paddle-controls { left: 20px; }

        #levelDisplay {
            position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
            color: #00ff00; font-size: 20px; text-shadow: 0 0 3px #00ff00; z-index: 5;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;h1&gt;Cyber Pong Explosion&lt;/h1&gt;

    &lt;div id="gameContainer"&gt;
        &lt;canvas id="gameCanvas" width="800" height="500"&gt;&lt;/canvas&gt;
        &lt;div id="levelDisplay"&gt;Level: 1&lt;/div&gt;
        &lt;div class="paddle-controls"&gt;
            &lt;button id="paddleUpBtn"&gt;▲&lt;/button&gt;
            &lt;button id="paddleDownBtn"&gt;▼&lt;/button&gt;
        &lt;/div&gt;
        &lt;div id="gameMessage"&gt;
            &lt;span id="messageText"&gt;&lt;/span&gt;&lt;br&gt;
            &lt;button id="restartButton" style="display: none;"&gt;Play Again (Level 1)&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id="controls"&gt;
        &lt;button id="playButton"&gt;Play&lt;/button&gt;
        &lt;!-- Fullscreen button removed --&gt;
    &lt;/div&gt;

    &lt;div id="gameInfo"&gt;
        &lt;h2&gt;Game Rules &amp; How to Play&lt;/h2&gt;

        &lt;h3&gt;Objective&lt;/h3&gt;
        &lt;p&gt;Defeat the AI opponent in multiple rounds. Win a round by scoring &lt;strong&gt;5 points&lt;/strong&gt; against the AI. Complete all levels to win the game!&lt;/p&gt;

        &lt;h3&gt;Levels &amp; Difficulty&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;The game has multiple levels (starting at Level 1).&lt;/li&gt;
            &lt;li&gt;Each time you win a round, you advance to the next level.&lt;/li&gt;
            &lt;li&gt;The AI opponent (right paddle) and the ball speed will get **faster** with each level.&lt;/li&gt;
            &lt;li&gt;If the AI scores 5 points against you in any round, the game is over, and you'll need to restart from Level 1.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Controls&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Your Paddle (Left):&lt;/strong&gt;
                &lt;ul&gt;
                    &lt;li&gt;Use the &lt;strong&gt;W&lt;/strong&gt; key or the on-screen &lt;strong&gt;▲&lt;/strong&gt; button to move up.&lt;/li&gt;
                    &lt;li&gt;Use the &lt;strong&gt;S&lt;/strong&gt; key or the on-screen &lt;strong&gt;▼&lt;/strong&gt; button to move down.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;AI Opponent (Right):&lt;/strong&gt; Controlled automatically by the computer.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Game Controls:&lt;/strong&gt; Click the &lt;strong&gt;Play / Restart&lt;/strong&gt; button to start or restart the game (always from Level 1). The game will automatically enter fullscreen mode when started. Press &lt;strong&gt;ESC&lt;/strong&gt; to exit fullscreen.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Gameplay&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;Press the &lt;strong&gt;Play&lt;/strong&gt; button to begin at Level 1 (this will also enter fullscreen).&lt;/li&gt;
            &lt;li&gt;The ball starts in the center. Use your paddle to hit the ball past the AI.&lt;/li&gt;
            &lt;li&gt;Score 5 points to complete the level and advance.&lt;/li&gt;
            &lt;li&gt;If the AI scores 5 points first, the game ends.&lt;/li&gt;
            &lt;li&gt;A neon particle &lt;strong&gt;EXPLOSION&lt;/strong&gt; occurs when any point is scored.&lt;/li&gt;
            &lt;li&gt;The ball resets after each point.&lt;/li&gt;
        &lt;/ul&gt;

         &lt;h3&gt;Tips&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;Anticipate the AI's faster reactions at higher levels.&lt;/li&gt;
            &lt;li&gt;Use paddle angles effectively by hitting the ball near the top or bottom of your paddle.&lt;/li&gt;
            &lt;li&gt;Stay focused as the ball speed increases.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;hr style="border-color: #3333ff; margin: 20px 0;"&gt;

        &lt;!-- SEO Content Section --&gt;
        &lt;h2&gt;About Cyber Pong Explosion: Level Challenge&lt;/h2&gt;
        &lt;p&gt;Challenge yourself against an increasingly intelligent AI in &lt;strong&gt;Cyber Pong Explosion: Level Challenge&lt;/strong&gt;! This single-player HTML5 Pong game features vibrant cyber-neon visuals, explosive particle effects, automatic fullscreen, and a progressive difficulty curve across multiple levels. Built with HTML5, CSS, and JavaScript, it offers smooth gameplay and mobile-friendly on-screen controls.&lt;/p&gt;
        &lt;p&gt;Start at Level 1 and see how many levels you can conquer as the AI opponent gets faster and the ball speeds up. Can you beat the final level? Test your reflexes and strategy in this modern take on a classic arcade hit, playable directly in your browser with no downloads needed.&lt;/p&gt;
        &lt;h3&gt;Features:&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;Classic Pong gameplay vs. AI opponent.&lt;/li&gt;
            &lt;li&gt;Multi-level progression with increasing difficulty.&lt;/li&gt;
            &lt;li&gt;AI speed and ball speed scale with levels.&lt;/li&gt;
            &lt;li&gt;Stunning cyber/neon visuals and particle explosions.&lt;/li&gt;
            &lt;li&gt;Single-player focus.&lt;/li&gt;
             &lt;li&gt;**NEW:** Automatic fullscreen on play start.&lt;/li&gt;
            &lt;li&gt;On-screen movement buttons for Player 1 (Mobile Friendly).&lt;/li&gt;
            &lt;li&gt;Play/Restart controls (restarts from Level 1).&lt;/li&gt;
            &lt;li&gt;Built with pure HTML5 Canvas and JavaScript.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Keywords: &lt;em&gt;HTML5 game, JavaScript game, Pong game, Cyber Pong, Neon game, Particle explosion game, Browser game, Single player game, AI opponent, Level based game, Increasing difficulty, Online game, Fullscreen game, Mobile game, Touch controls, Auto fullscreen, Arcade game clone, Web game, Canvas game, Play Pong online, Pong AI challenge&lt;/em&gt;.&lt;/p&gt;
        &lt;!-- End SEO Content Section --&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // --- DOM Elements ---
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const gameContainer = document.getElementById('gameContainer');
        const levelDisplay = document.getElementById('levelDisplay');
        const gameMessage = document.getElementById('gameMessage');
        const messageText = document.getElementById('messageText');
        const restartButton = document.getElementById('restartButton');
        const playButton = document.getElementById('playButton');
        // fullscreenButton element and variable removed
        const paddleUpBtn = document.getElementById('paddleUpBtn');
        const paddleDownBtn = document.getElementById('paddleDownBtn');

        // --- Game Constants --- (Same as before)
        const PADDLE_WIDTH = 15; const PADDLE_HEIGHT = 100; const BALL_RADIUS = 8;
        const PADDLE_SPEED = 8; const WINNING_SCORE = 5; const MAX_LEVEL = 5;
        const BASE_AI_FACTOR = 0.04; const AI_FACTOR_INCREMENT = 0.015; const MAX_AI_FACTOR = 0.15;
        const BASE_BALL_SPEED = 4.5; const BALL_SPEED_INCREMENT = 0.75; const MAX_BALL_SPEED = 10;
        const PADDLE_1_COLOR = '#00ffff'; const PADDLE_2_COLOR = '#ff00ff';
        const BALL_COLOR = '#ffff00'; const NET_COLOR = '#ffffff'; const TEXT_COLOR = '#00ff00';
        const PARTICLE_COLORS = ['#00ffff', '#ff00ff', '#ffff00', '#00ff00', '#ffffff'];

        // --- Game State --- (Same as before)
        let paddle1 = { x: 10, y: canvas.height / 2 - PADDLE_HEIGHT / 2, width: PADDLE_WIDTH, height: PADDLE_HEIGHT, dy: 0, score: 0 };
        let paddle2 = { x: canvas.width - 10 - PADDLE_WIDTH, y: canvas.height / 2 - PADDLE_HEIGHT / 2, width: PADDLE_WIDTH, height: PADDLE_HEIGHT, score: 0 };
        let ball = { x: canvas.width / 2, y: canvas.height / 2, radius: BALL_RADIUS, speed: BASE_BALL_SPEED, dx: BASE_BALL_SPEED, dy: BASE_BALL_SPEED };
        let currentLevel = 1; let currentAiSpeedFactor = BASE_AI_FACTOR; let currentBallSpeed = BASE_BALL_SPEED;
        let keysPressed = {}; let particles = []; let gameOver = false; let roundOver = false;
        let isPaused = true; let gameStarted = false; let paddle1BtnUp = false; let paddle1BtnDown = false;
        let animationFrameId = null; let messageTimeoutId = null;

        // --- Helper Functions for Difficulty --- (Same as before)
        function getAISpeedFactor(level) { const factor = BASE_AI_FACTOR + (level - 1) * AI_FACTOR_INCREMENT; return Math.min(factor, MAX_AI_FACTOR); }
        function getBaseBallSpeed(level) { const speed = BASE_BALL_SPEED + (level - 1) * BALL_SPEED_INCREMENT; return Math.min(speed, MAX_BALL_SPEED); }

        // --- Drawing Functions --- (Identical)
        function drawRect(x, y, w, h, color, glowColor = color) { ctx.fillStyle = color; ctx.shadowColor = glowColor; ctx.shadowBlur = 10; ctx.fillRect(x, y, w, h); ctx.shadowBlur = 0; }
        function drawCircle(x, y, r, color, glowColor = color) { ctx.fillStyle = color; ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2, false); ctx.closePath(); ctx.shadowColor = glowColor; ctx.shadowBlur = 15; ctx.fill(); ctx.shadowBlur = 0; }
        function drawText(text, x, y, color, size = "50px", align = 'center') { ctx.fillStyle = color; ctx.font = `${size} 'Consolas', 'Courier New', monospace`; ctx.shadowColor = color; ctx.shadowBlur = 5; ctx.textAlign = align; ctx.fillText(text, x, y); ctx.shadowBlur = 0; }
        function drawNet() { for (let i = 0; i &lt;= canvas.height; i += 15) { drawRect(canvas.width / 2 - 1, i, 2, 10, NET_COLOR, '#aaaaaa'); } }
        function drawParticles() { for (let i = particles.length - 1; i &gt;= 0; i--) { const p = particles[i]; ctx.save(); ctx.globalAlpha = p.life; drawCircle(p.x, p.y, p.size, p.color); ctx.restore(); } }

        // --- Update Functions ---
        function movePaddle1() {
            if (keysPressed['w'] || keysPressed['W'] || paddle1BtnUp) { paddle1.y -= PADDLE_SPEED; }
            if (keysPressed['s'] || keysPressed['S'] || paddle1BtnDown) { paddle1.y += PADDLE_SPEED; }
            paddle1.y = Math.max(0, Math.min(canvas.height - paddle1.height, paddle1.y));
        }

        function movePaddleAI() {
            const paddleCenter = paddle2.y + paddle2.height / 2;
            let predictionFactor = 0.1 + currentLevel * 0.05;
            let predictedY = ball.y + ball.dy * predictionFactor * (canvas.width / Math.abs(ball.dx));
            predictedY = Math.max(ball.radius, Math.min(canvas.height - ball.radius, predictedY));
            const targetY = predictedY;
            const dy = targetY - paddleCenter;
            let speedAdjust = Math.abs(dy) &gt; paddle2.height * 0.5 ? 1.5 : 1;
            paddle2.y += dy * currentAiSpeedFactor * speedAdjust;
            paddle2.y = Math.max(0, Math.min(canvas.height - paddle2.height, paddle2.y));
        }

        function moveBall() {
            ball.x += ball.dx;
            ball.y += ball.dy;

            // Wall collision (top/bottom)
            if (ball.y + ball.radius &gt; canvas.height || ball.y - ball.radius &lt; 0) {
                ball.dy *= -1; playSound('wallHit');
            }

            // Paddle collision detection
            let hitPaddle = null;
            // Player 1 Collision Check
            if (ball.dx &lt; 0 &amp;&amp; // Moving left
                ball.x - ball.radius &lt; paddle1.x + paddle1.width &amp;&amp; // Left edge of ball passed right edge of paddle
                ball.x + ball.radius &gt; paddle1.x) // Right edge of ball passed left edge of paddle
            {
                 if (ball.y + ball.radius &gt; paddle1.y &amp;&amp; ball.y - ball.radius &lt; paddle1.y + paddle1.height) { // Vertical overlap
                     hitPaddle = paddle1;
                 }
            }
            // Player 2 (AI) Collision Check
            else if (ball.dx &gt; 0 &amp;&amp; // Moving right
                 ball.x + ball.radius &gt; paddle2.x &amp;&amp; // Right edge of ball passed left edge of paddle
                 ball.x - ball.radius &lt; paddle2.x + paddle2.width) // Left edge of ball passed right edge of paddle
             {
                 if (ball.y + ball.radius &gt; paddle2.y &amp;&amp; ball.y - ball.radius &lt; paddle2.y + paddle2.height) { // Vertical overlap
                    hitPaddle = paddle2;
                }
            }

            if (hitPaddle) {
                 // Calculate bounce angle based on hit position
                 let hitPos = (ball.y - (hitPaddle.y + hitPaddle.height / 2)) / (hitPaddle.height / 2);
                 let bounceAngle = hitPos * (Math.PI / 4); // Max 45 degrees +/-

                 // Determine speed magnitude (use current level's base speed)
                 let speedMagnitude = currentBallSpeed;

                 // Calculate new velocities based on angle and speed
                 // Flip horizontal direction based on which paddle was hit
                 ball.dx = speedMagnitude * Math.cos(bounceAngle) * (hitPaddle === paddle1 ? 1 : -1);
                 ball.dy = speedMagnitude * Math.sin(bounceAngle);

                 // *** PHYSICS FIX: Explicitly reposition ball outside paddle ***
                 if (hitPaddle === paddle1) {
                     ball.x = paddle1.x + paddle1.width + ball.radius + 1; // Move just right of paddle 1
                 } else { // hitPaddle === paddle2
                     ball.x = paddle2.x - ball.radius - 1; // Move just left of paddle 2
                 }

                 playSound('paddleHit');
            }

            // --- Score Checking ---
             // Check AFTER collision resolution
             if (ball.x + ball.radius &lt; 0) { // AI scores
                paddle2.score++;
                createExplosion(0, ball.y);
                checkRoundOver();
                if (!gameOver &amp;&amp; !roundOver) resetBall(1);
            } else if (ball.x - ball.radius &gt; canvas.width) { // Player scores
                paddle1.score++;
                createExplosion(canvas.width, ball.y);
                checkRoundOver();
                if (!gameOver &amp;&amp; !roundOver) resetBall(-1);
            }
        }

        // --- Game State Management Functions --- (resetBall, checkRoundOver, resetForNextRound, endGame are largely the same)
         function resetBall(direction) {
             playSound('score');
             ball.x = canvas.width / 2; ball.y = canvas.height / 2;
             ball.speed = currentBallSpeed;
             ball.dx = ball.speed * direction;
             let dyMagnitude = (Math.random() * ball.speed * 0.5 + ball.speed * 0.3);
             ball.dy = (Math.random() &gt; 0.5 ? 1 : -1) * dyMagnitude;
             let maxDy = ball.speed * 0.8; ball.dy = Math.max(-maxDy, Math.min(maxDy, ball.dy));
         }

         function checkRoundOver() {
            roundOver = false;
            if (paddle2.score &gt;= WINNING_SCORE) {
                endGame(`AI Wins on Level ${currentLevel}!`, true);
            } else if (paddle1.score &gt;= WINNING_SCORE) {
                roundOver = true;
                if (currentLevel &gt;= MAX_LEVEL) {
                    endGame("CONGRATULATIONS! You beat all levels!", true);
                } else {
                    endGame(`Level ${currentLevel} Complete!`, false);
                }
            }
         }

         function resetForNextRound() {
             if (gameOver) return;
             currentLevel++;
             paddle1.score = 0; paddle2.score = 0;
             currentAiSpeedFactor = getAISpeedFactor(currentLevel);
             currentBallSpeed = getBaseBallSpeed(currentLevel);
             levelDisplay.textContent = `Level: ${currentLevel}`;
             resetBall(1);
             roundOver = false; isPaused = false;
             if (!animationFrameId) gameLoop();
         }

         function endGame(message, isFinalGameOver) {
            isPaused = true; gameOver = isFinalGameOver;
            cancelAnimationFrame(animationFrameId); animationFrameId = null;
            clearTimeout(messageTimeoutId);
            messageText.textContent = message;
            restartButton.style.display = isFinalGameOver ? 'inline-block' : 'none';
            gameMessage.style.display = 'block';
            playButton.textContent = "Restart";
            if (isFinalGameOver) { playSound('gameOver'); }
            else {
                playSound('levelComplete');
                messageTimeoutId = setTimeout(() =&gt; {
                    gameMessage.style.display = 'none';
                    resetForNextRound();
                }, 2000);
            }
         }

         // --- Fullscreen Function (modified to just enter) ---
         function enterFullScreenIfNeeded() {
             // Check if already in fullscreen
            if (!document.fullscreenElement &amp;&amp;
                !document.mozFullScreenElement &amp;&amp;
                !document.webkitFullscreenElement &amp;&amp;
                !document.msFullscreenElement )
            {
                // Attempt to enter fullscreen
                if (gameContainer.requestFullscreen) { gameContainer.requestFullscreen(); }
                else if (gameContainer.mozRequestFullScreen) { gameContainer.mozRequestFullScreen(); }
                else if (gameContainer.webkitRequestFullscreen) { gameContainer.webkitRequestFullscreen(); }
                else if (gameContainer.msRequestFullscreen) { gameContainer.msRequestFullscreen(); }
            }
         }

        function startGame() {
             // Request fullscreen when starting/restarting
             enterFullScreenIfNeeded();

             if (animationFrameId) cancelAnimationFrame(animationFrameId);
             clearTimeout(messageTimeoutId);
             currentLevel = 1; gameOver = false; roundOver = false; isPaused = false; gameStarted = true;
             paddle1.score = 0; paddle2.score = 0;
             paddle1.y = canvas.height / 2 - PADDLE_HEIGHT / 2; paddle2.y = canvas.height / 2 - PADDLE_HEIGHT / 2;
             particles = [];
             currentAiSpeedFactor = getAISpeedFactor(currentLevel); currentBallSpeed = getBaseBallSpeed(currentLevel);
             levelDisplay.textContent = `Level: ${currentLevel}`;
             gameMessage.style.display = 'none';
             playButton.textContent = "Restart";
             resetBall(Math.random() &gt; 0.5 ? 1 : -1);
             gameLoop();
        }

        // --- Particle System &amp; Sound --- (Identical)
        function createExplosion(x, y) { playSound('explosion'); const particleCount = 50; const maxLife = 1.0; const maxSpeed = 5; for (let i = 0; i &lt; particleCount; i++) { const angle = Math.random() * Math.PI * 2; const speed = Math.random() * maxSpeed + 1; particles.push({ x: x, y: y, dx: Math.cos(angle) * speed, dy: Math.sin(angle) * speed, size: Math.random() * 5 + 2, color: PARTICLE_COLORS[Math.floor(Math.random() * PARTICLE_COLORS.length)], life: maxLife, fadeSpeed: Math.random() * 0.02 + 0.01 }); } }
        function updateParticles() { for (let i = particles.length - 1; i &gt;= 0; i--) { const p = particles[i]; p.x += p.dx; p.y += p.dy; p.life -= p.fadeSpeed; if (p.life &lt;= 0) particles.splice(i, 1); } }
        function playSound(type) { /* console.log(`Sound: ${type}`); */ }

        // --- Game Loop --- (Identical structure)
        function update() { movePaddle1(); movePaddleAI(); moveBall(); updateParticles(); }
        function draw() {
            ctx.fillStyle = 'rgba(0, 0, 0, 0.25)'; ctx.fillRect(0, 0, canvas.width, canvas.height);
            drawNet();
            drawRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height, PADDLE_1_COLOR);
            drawRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height, PADDLE_2_COLOR);
            drawCircle(ball.x, ball.y, ball.radius, BALL_COLOR);
            drawParticles();
            drawText(paddle1.score.toString(), canvas.width / 4, 60, TEXT_COLOR);
            drawText(paddle2.score.toString(), 3 * canvas.width / 4, 60, TEXT_COLOR);
            if (!gameStarted &amp;&amp; isPaused) { drawText("Press Play", canvas.width / 2, canvas.height / 2, '#ffff00', "40px"); }
        }
        function gameLoop() {
            if (isPaused || roundOver) {
                 if(isPaused &amp;&amp; !gameOver) draw();
                 if (gameOver &amp;&amp; isPaused) draw();
                 return;
            }
            update(); draw();
            animationFrameId = requestAnimationFrame(gameLoop);
        }

        // --- Event Listeners ---
        document.addEventListener('keydown', (e) =&gt; { keysPressed[e.key.toLowerCase()] = true; });
        document.addEventListener('keyup', (e) =&gt; { keysPressed[e.key.toLowerCase()] = false; });

        // On-Screen Button Listeners (Identical)
        function handleBtnDown(e, isUpButton) { e.preventDefault(); if(isUpButton) paddle1BtnUp = true; else paddle1BtnDown = true; }
        function handleBtnUp(e, isUpButton) { e.preventDefault(); if(isUpButton) paddle1BtnUp = false; else paddle1BtnDown = false; }
        paddleUpBtn.addEventListener('mousedown', (e) =&gt; handleBtnDown(e, true)); paddleUpBtn.addEventListener('mouseup', (e) =&gt; handleBtnUp(e, true)); paddleUpBtn.addEventListener('mouseleave', (e) =&gt; paddle1BtnUp = false); paddleUpBtn.addEventListener('touchstart', (e) =&gt; handleBtnDown(e, true), { passive: false }); paddleUpBtn.addEventListener('touchend', (e) =&gt; handleBtnUp(e, true), { passive: false });
        paddleDownBtn.addEventListener('mousedown', (e) =&gt; handleBtnDown(e, false)); paddleDownBtn.addEventListener('mouseup', (e) =&gt; handleBtnUp(e, false)); paddleDownBtn.addEventListener('mouseleave', (e) =&gt; paddle1BtnDown = false); paddleDownBtn.addEventListener('touchstart', (e) =&gt; handleBtnDown(e, false), { passive: false }); paddleDownBtn.addEventListener('touchend', (e) =&gt; handleBtnUp(e, false), { passive: false });

        // Control Buttons
        playButton.addEventListener('click', startGame);
        restartButton.addEventListener('click', startGame);
        // Fullscreen button listener removed

        // Fullscreen change listeners removed as button is gone

        // --- Initial Draw ---
        paddle1.y = canvas.height / 2 - PADDLE_HEIGHT / 2; paddle2.y = canvas.height / 2 - PADDLE_HEIGHT / 2;
        ball.x = canvas.width / 2; ball.y = canvas.height / 2;
        levelDisplay.textContent = `Level: ${currentLevel}`;
        draw();

    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Snake Game</title><link>http://rajclick.blogspot.com/2025/03/snake-game.html</link><category>Game</category><pubDate>Sat, 29 Mar 2025 08:56:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-7869119445631303464</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Snake Evolved - Play Online!&lt;/title&gt; &lt;!-- SEO Title --&gt;
    &lt;meta name="description" content="Play Snake Evolved, a modern twist on the classic snake game with neon visuals, increasing levels, obstacles, and fast-paced action. Built with HTML5 and JavaScript."&gt; &lt;!-- SEO Meta Description --&gt;
    &lt;style&gt;
        /* --- Global Styles --- */
        :root {
            --neon-cyan: #00ffea;
            --neon-red: #ff4444; /* Slightly less intense red */
            --neon-green-light: #33ff33;
            --neon-green-dark: #00cc00;
            --obstacle-color: #666699; /* Muted purple/grey for obstacles */
            --obstacle-border: #4d4d80;
            --dark-bg: #1a1a1a;
            --dark-grey: #1f1f1f; /* Canvas BG */
            --wrapper-bg: #282828; /* Wrapper BG */
            --medium-grey: #444;
            --light-grey: #f0f0f0;
            --text-shadow-cyan: 0 0 8px rgba(0, 255, 234, 0.7);
            --box-shadow-cyan: 0 0 20px rgba(0, 255, 234, 0.25);
            --box-shadow-wrapper: 0 4px 15px rgba(0, 0, 0, 0.3);
        }

        body {
            margin: 0;
            padding: 20px; /* Allow space around content */
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--dark-bg);
            color: var(--light-grey);
            /* Removed flex centering and overflow:hidden to allow scrolling */
        }

        /* --- Game Wrapper for Centering --- */
        .game-wrapper {
            display: flex;
            flex-direction: column;
            align-items: center; /* Center items inside the wrapper */
            max-width: 550px; /* Adjust max-width as needed for your blog layout */
            margin: 20px auto; /* Center the wrapper horizontally, add vertical margin */
            padding: 20px;
            background-color: var(--wrapper-bg);
            border-radius: 8px;
            box-shadow: var(--box-shadow-wrapper);
        }

        /* --- Game Title --- */
        .game-wrapper h1 {
            color: #ffffff;
            text-transform: uppercase;
            letter-spacing: 2px;
            font-weight: 600;
            margin-bottom: 15px; /* Increased margin */
            margin-top: 0; /* Reset top margin */
            text-shadow: 0 0 5px rgba(255, 255, 255, 0.3);
            text-align: center;
            width: 100%;
        }

         /* --- Controls Container --- */
        #controlsContainer {
            display: flex;
            justify-content: center; /* Center buttons */
            align-items: center;
            gap: 20px; /* Space between buttons */
            width: 100%; /* Take full width of wrapper */
            max-width: 500px; /* Constrain button area */
            margin-bottom: 20px; /* Increased margin */
            height: 40px; /* Reserve space */
        }

        /* --- Info Bar --- */
        #infoBar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%; /* Take full width of wrapper */
            max-width: 410px; /* Match canvas width + borders */
            margin-bottom: 10px;
            visibility: hidden; /* Start hidden */
        }

        #scoreDisplay, #levelDisplay {
            font-size: 1.4em;
            font-weight: bold;
            color: var(--neon-cyan);
            text-shadow: var(--text-shadow-cyan);
        }
         #levelDisplay {
             color: #ffae00; /* Orange for level */
             text-shadow: 0 0 8px rgba(255, 174, 0, 0.7);
         }

        /* --- General Button Style --- */
        button {
            background-color: var(--medium-grey);
            color: var(--light-grey);
            border: 1px solid var(--neon-cyan);
            padding: 8px 15px;
            font-size: 0.9em;
            font-weight: bold;
            text-transform: uppercase;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
            box-shadow: 0 0 5px rgba(0, 255, 234, 0.3);
        }
        button:hover, button:focus {
            background-color: var(--dark-grey);
            color: var(--neon-cyan);
            box-shadow: var(--text-shadow-cyan);
            outline: none;
        }
        button:active { background-color: #555; }

        /* Specific Buttons */
        #startButton {}
        #fullscreenButton {
             /* Removed margin-left: auto; centering is handled by flex container */
        }
        #playAgainButton {
            margin-top: 20px;
            background-color: var(--neon-red);
            color: var(--dark-bg);
            border: 1px solid var(--neon-red);
            box-shadow: 0 0 8px rgba(255, 68, 68, 0.5);
        }
         #playAgainButton:hover, #playAgainButton:focus {
            background-color: #ff6666;
            color: #fff;
            box-shadow: 0 0 15px rgba(255, 68, 68, 0.8);
         }

        /* --- Game Area Container --- */
        #gameContainer {
            position: relative; /* Needed for absolute positioning of gameOverMessage */
            transition: filter 0.3s ease-in-out;
            display: flex; /* Use flex to easily center canvas if needed */
            justify-content: center;
            align-items: center;
            flex-direction: column;
            width: 100%; /* Take full width of wrapper */
        }

        /* --- Game Canvas --- */
        #gameCanvas {
            border: 3px solid var(--medium-grey);
            box-shadow: var(--box-shadow-cyan);
            display: block;
            visibility: hidden; /* Start hidden */
            background-color: var(--dark-grey); /* Set bg here */
            max-width: 100%; /* Ensure canvas doesn't overflow wrapper on small screens */
            height: auto; /* Maintain aspect ratio if width shrinks */
        }

        /* --- Game Over Message --- */
        #gameOverMessage {
            position: absolute;
            top: 50%; left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.9);
            color: white;
            padding: 30px 50px;
            border-radius: 8px;
            border: 1px solid #555;
            font-size: 2.2em;
            text-align: center;
            display: none; /* Hidden by default */
            z-index: 10;
            text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
             width: 80%; /* Prevent it becoming too wide */
             box-sizing: border-box;
        }
         #gameOverMessage small { font-size: 0.5em; color: #aaa; display: block; margin-top: 15px; }
         #finalScore { color: var(--neon-red); font-weight: bold; }

        /* --- Blur Effect for Game Over --- */
        .game-blurred #gameCanvas,
        .game-blurred #infoBar { /* Blur info bar too */
           filter: blur(5px);
        }

        /* --- SEO Content Styling --- */
        .seo-content {
            max-width: 750px; /* Can be wider than game for readability */
            margin: 40px auto; /* Center and add space below game */
            padding: 25px;
            background-color: var(--wrapper-bg); /* Match wrapper or use different */
            border-radius: 5px;
            line-height: 1.7;
            color: var(--light-grey);
             box-shadow: var(--box-shadow-wrapper);
        }
        .seo-content h2, .seo-content h3 {
            color: var(--neon-cyan);
            margin-top: 1.5em;
            margin-bottom: 0.7em;
            border-bottom: 1px solid var(--medium-grey);
            padding-bottom: 5px;
        }
        .seo-content h2:first-child {
            margin-top: 0;
        }
        .seo-content p {
            margin-bottom: 1.2em;
        }
        .seo-content a {
             color: var(--neon-green-light);
             text-decoration: none;
             font-weight: bold;
        }
        .seo-content a:hover {
             text-decoration: underline;
             color: var(--neon-cyan);
        }
        .seo-content ul {
            list-style: disc;
            margin-left: 20px;
            margin-bottom: 1.2em;
        }
         .seo-content code {
             background-color: var(--dark-grey);
             padding: 2px 5px;
             border-radius: 3px;
             font-family: Consolas, monospace;
         }

    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;!-- Game Wrapper: Centers the game content on the page --&gt;
    &lt;div class="game-wrapper"&gt;

        &lt;h1&gt;Snake Evolved&lt;/h1&gt;

         &lt;div id="controlsContainer"&gt;
             &lt;button id="startButton"&gt;Play Game&lt;/button&gt;
             &lt;button id="fullscreenButton"&gt;Fullscreen&lt;/button&gt;
        &lt;/div&gt;

        &lt;!-- Container for elements that get blurred (Info Bar and Canvas) --&gt;
        &lt;div id="gameContainer"&gt;
            &lt;!-- Info Bar: Score and Level --&gt;
            &lt;div id="infoBar"&gt; &lt;!-- Initially hidden via CSS --&gt;
                &lt;div id="scoreDisplay"&gt;Score: 0&lt;/div&gt;
                &lt;div id="levelDisplay"&gt;Level: 1&lt;/div&gt;
            &lt;/div&gt;

            &lt;!-- The Game Canvas --&gt;
            &lt;canvas id="gameCanvas" width="400" height="400"&gt;&lt;/canvas&gt;

             &lt;!-- Game Over message (positioned absolutely within gameContainer) --&gt;
             &lt;div id="gameOverMessage"&gt;
                WASTED&lt;br&gt;
                &lt;span id="finalScore"&gt;&lt;/span&gt;&lt;br&gt;
                &lt;button id="playAgainButton"&gt;Play Again&lt;/button&gt;&lt;br&gt;
                &lt;small&gt;(Refresh to Respawn)&lt;/small&gt;
            &lt;/div&gt;
        &lt;/div&gt;

    &lt;/div&gt; &lt;!-- End of game-wrapper --&gt;


    &lt;!-- ========================= --&gt;
    &lt;!--      SEO Content Area     --&gt;
    &lt;!-- ========================= --&gt;
    &lt;section class="seo-content"&gt;
        &lt;h2&gt;About Snake Evolved: A Modern Neon Snake Game&lt;/h2&gt;
        &lt;p&gt;
            Welcome to &lt;strong&gt;Snake Evolved&lt;/strong&gt;! This isn't just your classic retro snake game; it's a vibrant, challenging twist built with modern web technologies like HTML5 Canvas and JavaScript. Guide your glowing neon snake through an increasingly hazardous environment, gobbling up food to grow longer while dodging pesky obstacles that appear as you level up.
        &lt;/p&gt;
        &lt;p&gt;
            Experience the nostalgia of snake gameplay combined with a fresh neon aesthetic, smooth animations, and escalating difficulty. Can you reach the highest level and achieve a top score?
        &lt;/p&gt;

        &lt;h3&gt;How to Play&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;Use the &lt;strong&gt;Arrow Keys&lt;/strong&gt; (Up, Down, Left, Right) on your keyboard to control the snake's direction.&lt;/li&gt;
            &lt;li&gt;Eat the &lt;strong style="color: var(--neon-red);"&gt;red squares&lt;/strong&gt; (food) to grow longer and increase your score.&lt;/li&gt;
            &lt;li&gt;Avoid running into the walls, your own tail, or the &lt;strong style="color: var(--obstacle-color);"&gt;purple obstacles&lt;/strong&gt;.&lt;/li&gt;
            &lt;li&gt;Eating a set amount of food advances you to the next level, increasing the snake's speed and adding more obstacles!&lt;/li&gt;
            &lt;li&gt;Use the &lt;strong&gt;Fullscreen&lt;/strong&gt; button for a more immersive experience.&lt;/li&gt;
            &lt;li&gt;If you crash, hit &lt;strong&gt;Play Again&lt;/strong&gt; or refresh the page to restart.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Features of Snake Evolved&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Classic Gameplay, Modern Look:&lt;/strong&gt; Enjoy the simple yet addictive mechanics of snake with a cool neon visual style.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Increasing Difficulty:&lt;/strong&gt; The game gets faster and more challenging as you progress through levels.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Obstacle Challenge:&lt;/strong&gt; Static obstacles appear, adding a layer of strategy and difficulty beyond the classic game.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Responsive Controls:&lt;/strong&gt; Smooth and immediate snake movement based on your key presses.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Score &amp; Level Tracking:&lt;/strong&gt; Monitor your progress and challenge yourself to beat your high score.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Built with Web Tech:&lt;/strong&gt; A fun example of what can be done with HTML5 &lt;code&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Tips for a High Score&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Plan Ahead:&lt;/strong&gt; As the snake gets longer and faster, think a few moves ahead, especially near obstacles and corners.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Use the Space:&lt;/strong&gt; Don't always hug the walls; use the open areas to maneuver, especially when the snake is long.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Controlled Turns:&lt;/strong&gt; Avoid rapidly changing direction back and forth, which can easily lead to crashing into yourself.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Stay Calm:&lt;/strong&gt; Panic leads to mistakes! Keep a steady hand, especially at higher speeds.&lt;/li&gt;
        &lt;/ul&gt;
         &lt;p&gt;
             This online snake game is perfect for a quick break or a longer session trying to beat your personal best. Share your high score in the comments below! If you enjoy retro games with a modern flair, &lt;a href="#"&gt;check out other games on our blog&lt;/a&gt;!.
         &lt;/p&gt;
    &lt;/section&gt;


    &lt;script&gt;
        // --- Design &amp; Look Constants ---
        const CANVAS_BACKGROUND_COLOR = '#1f1f1f'; // Matches CSS --dark-grey
        const BORDER_COLOR = '#333333'; // Unused in current draw, but kept for reference
        const SNAKE_COLOR_LIGHT = '#33ff33'; // Neon Green Light
        const SNAKE_COLOR_DARK = '#00cc00';  // Neon Green Dark
        const FOOD_COLOR = '#ff4444';       // Neon Red
        const FOOD_BORDER_COLOR = '#cc0000';
        const OBSTACLE_COLOR = '#666699';   // Muted Purple/Grey
        const OBSTACLE_BORDER_COLOR = '#4d4d80';
        const USE_GRADIENT_SNAKE = true; // Toggle for snake appearance
        const SEGMENT_ROUNDING = 0.3; // 0 = square, 0.5 = circle

        // --- Game Constants ---
        const BOX_SIZE = 20;
        const BASE_GAME_SPEED = 120; // Start speed (milliseconds)
        const MIN_GAME_SPEED = 45;   // Fastest speed
        const SPEED_DECREASE_PER_LEVEL = 7; // How much faster each level (ms)
        const FOOD_PER_LEVEL = 5;     // Food needed to level up
        const MAX_OBSTACLES = 15;     // Max obstacles on screen

        // --- Game State Variables ---
        let snake;
        let food;
        let obstacles = [];
        let dx;
        let dy;
        let score;
        let currentLevel;
        let foodEatenThisLevel;
        let currentSpeed;
        let changingDirection;
        let gameOver;
        let gameInterval = null;
        let gameActive = false;

        // --- HTML Elements ---
        const gameCanvas = document.getElementById('gameCanvas');
        const ctx = gameCanvas.getContext('2d');
        const scoreDisplay = document.getElementById('scoreDisplay');
        const levelDisplay = document.getElementById('levelDisplay');
        const gameOverMessage = document.getElementById('gameOverMessage');
        const finalScoreDisplay = document.getElementById('finalScore');
        const gameContainer = document.getElementById('gameContainer'); // Container for canvas/overlay
        const startButton = document.getElementById('startButton');
        const playAgainButton = document.getElementById('playAgainButton');
        const fullscreenButton = document.getElementById('fullscreenButton');
        const controlsContainer = document.getElementById('controlsContainer');
        const infoBar = document.getElementById('infoBar');

        // --- Initialization ---
        document.addEventListener('DOMContentLoaded', () =&gt; {
             startButton.addEventListener('click', handleStartGame);
             playAgainButton.addEventListener('click', startGame); // Restart the game
             fullscreenButton.addEventListener('click', toggleFullscreen);
             document.addEventListener('keydown', handleKeyDown);

             // Set initial canvas background (optional, CSS handles it too)
             clearCanvas();
        });

        function handleStartGame() {
            startButton.style.display = 'none'; // Hide Start button
             // Adjust layout if needed - though flex centering in CSS handles it now
             // fullscreenButton.style.marginLeft = 'auto'; // Not needed with justify-content: center
            infoBar.style.visibility = 'visible'; // Show score/level bar
            gameCanvas.style.visibility = 'visible'; // Show canvas
            startGame();
        }

        /**
         * Initializes/Resets the game state and starts the game loop.
         */
        function startGame() {
            // Reset game state
            currentLevel = 1;
            score = 0;
            foodEatenThisLevel = 0;
            gameOver = false;
            gameActive = true;
            changingDirection = false;
            obstacles = [];

            // Initial snake position (center)
            const startX = Math.floor(gameCanvas.width / 2 / BOX_SIZE) * BOX_SIZE;
            const startY = Math.floor(gameCanvas.height / 2 / BOX_SIZE) * BOX_SIZE;
             // Ensure start position isn't right on edge if canvas isn't perfectly divisible
            const gridWidth = Math.floor(gameCanvas.width / BOX_SIZE);
            const gridHeight = Math.floor(gameCanvas.height / BOX_SIZE);
            const centerGridX = Math.floor(gridWidth / 2);
            const centerGridY = Math.floor(gridHeight / 2);

            snake = [
                { x: centerGridX * BOX_SIZE, y: centerGridY * BOX_SIZE },
                { x: (centerGridX - 1) * BOX_SIZE, y: centerGridY * BOX_SIZE },
                { x: (centerGridX - 2) * BOX_SIZE, y: centerGridY * BOX_SIZE },
            ];
            dx = BOX_SIZE; // Start moving right
            dy = 0;

            // Ensure UI state is correct for restart
            startButton.style.display = 'none'; // Keep start button hidden
            infoBar.style.visibility = 'visible';
            gameCanvas.style.visibility = 'visible';
            gameOverMessage.style.display = 'none';
            gameContainer.classList.remove('game-blurred');

            // Update displays
            scoreDisplay.textContent = `Score: ${score}`;
            levelDisplay.textContent = `Level: ${currentLevel}`;

            // Generate initial food (obstacles added per level)
            createFood(); // Create first food item BEFORE adding obstacles
            addObstaclesForLevel(currentLevel); // Add obstacles AFTER food/snake placed


            // Calculate initial speed and start loop
            calculateAndSetSpeed(); // Sets currentSpeed and starts interval

            // Focus the body or game container to ensure keydown events are captured
            // Sometimes needed if buttons were clicked
            document.body.focus();
        }

        /**
         * Calculates speed based on level and starts/restarts the game interval.
         */
        function calculateAndSetSpeed() {
            currentSpeed = Math.max(MIN_GAME_SPEED, BASE_GAME_SPEED - (currentLevel - 1) * SPEED_DECREASE_PER_LEVEL);
            // console.log(`Level ${currentLevel} - Speed: ${currentSpeed}ms`); // Keep for debugging if needed

            if (gameInterval) {
                clearInterval(gameInterval);
            }
            // Ensure game loop doesn't start if game ended immediately (unlikely here)
            if(gameActive &amp;&amp; !gameOver) {
                gameInterval = setInterval(mainGameLoop, currentSpeed);
            }
        }

        /**
         * Main game loop function.
         */
        function mainGameLoop() {
             if (gameOver) { // Check if game ended in the previous tick or collision check
                 showGameOver();
                 if (gameInterval) clearInterval(gameInterval);
                 gameActive = false; // Explicitly stop activity
                 return;
             }
              if (!gameActive) { // Check if game was stopped for other reasons
                 if (gameInterval) clearInterval(gameInterval);
                 return;
              }

            changingDirection = false; // Allow next direction change
            clearCanvas();
            drawObstacles(); // Draw static elements first
            drawFood();
            moveSnake();     // Calculate next position, check food eat/level up
            drawSnake();     // Draw snake in new position
            checkCollision(); // Check if the new position is valid AFTER drawing
                               // This prevents checking collision before moveSnake sets gameOver
        }

        // --- Drawing Functions ---

        function clearCanvas() {
            ctx.fillStyle = CANVAS_BACKGROUND_COLOR;
            ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
            // Optional Grid - uncomment to draw grid lines
            // drawGrid();
        }

        /* // Optional Grid Drawing Function
        function drawGrid() {
            ctx.strokeStyle = '#444'; // Grid line color
            ctx.lineWidth = 0.5;
            for (let x = 0; x &lt;= gameCanvas.width; x += BOX_SIZE) {
                ctx.beginPath();
                ctx.moveTo(x, 0);
                ctx.lineTo(x, gameCanvas.height);
                ctx.stroke();
            }
            for (let y = 0; y &lt;= gameCanvas.height; y += BOX_SIZE) {
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(gameCanvas.width, y);
                ctx.stroke();
            }
             ctx.lineWidth = 1; // Reset line width
        }
        */


        function drawObstacles() {
            ctx.fillStyle = OBSTACLE_COLOR;
            ctx.strokeStyle = OBSTACLE_BORDER_COLOR;
            ctx.lineWidth = 1; // Ensure border width is standard
            obstacles.forEach(obs =&gt; {
                // Simple square obstacles
                ctx.fillRect(obs.x, obs.y, BOX_SIZE, BOX_SIZE);
                ctx.strokeRect(obs.x, obs.y, BOX_SIZE, BOX_SIZE);
            });
        }

        function drawFood() {
            ctx.fillStyle = FOOD_COLOR;
            ctx.strokeStyle = FOOD_BORDER_COLOR;
            ctx.lineWidth = 1; // Ensure border width is standard

            // Draw slightly rounded food
            const radius = BOX_SIZE * 0.2;
            ctx.beginPath();
            ctx.moveTo(food.x + radius, food.y);
            ctx.lineTo(food.x + BOX_SIZE - radius, food.y);
            ctx.quadraticCurveTo(food.x + BOX_SIZE, food.y, food.x + BOX_SIZE, food.y + radius);
            ctx.lineTo(food.x + BOX_SIZE, food.y + BOX_SIZE - radius);
            ctx.quadraticCurveTo(food.x + BOX_SIZE, food.y + BOX_SIZE, food.x + BOX_SIZE - radius, food.y + BOX_SIZE);
            ctx.lineTo(food.x + radius, food.y + BOX_SIZE);
            ctx.quadraticCurveTo(food.x, food.y + BOX_SIZE, food.x, food.y + BOX_SIZE - radius);
            ctx.lineTo(food.x, food.y + radius);
            ctx.quadraticCurveTo(food.x, food.y, food.x + radius, food.y);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        }

        function drawSnake() {
            snake.forEach((segment, index) =&gt; {
                drawSnakePart(segment, index === 0); // Pass true if it's the head
            });
        }

        /**
         * Draws a single snake segment (potentially rounded and with gradient).
         * @param {object} segment - The {x, y} coordinates of the segment.
         * @param {boolean} isHead - True if this is the snake's head.
         */
        function drawSnakePart(segment, isHead) {
            const radius = BOX_SIZE * SEGMENT_ROUNDING; // Adjust rounding

            if (USE_GRADIENT_SNAKE) {
                // Create gradient
                const gradient = ctx.createLinearGradient(segment.x, segment.y, segment.x, segment.y + BOX_SIZE);
                gradient.addColorStop(0, SNAKE_COLOR_LIGHT);
                gradient.addColorStop(1, SNAKE_COLOR_DARK);
                ctx.fillStyle = gradient;
            } else {
                ctx.fillStyle = SNAKE_COLOR_DARK; // Fallback solid color
            }
            ctx.strokeStyle = SNAKE_COLOR_DARK; // Border color matching darker gradient end
            ctx.lineWidth = 1; // Standard line width

            // Draw rounded rectangle
            ctx.beginPath();
            ctx.moveTo(segment.x + radius, segment.y);
            ctx.lineTo(segment.x + BOX_SIZE - radius, segment.y);
            ctx.quadraticCurveTo(segment.x + BOX_SIZE, segment.y, segment.x + BOX_SIZE, segment.y + radius);
            ctx.lineTo(segment.x + BOX_SIZE, segment.y + BOX_SIZE - radius);
            ctx.quadraticCurveTo(segment.x + BOX_SIZE, segment.y + BOX_SIZE, segment.x + BOX_SIZE - radius, segment.y + BOX_SIZE);
            ctx.lineTo(segment.x + radius, segment.y + BOX_SIZE);
            ctx.quadraticCurveTo(segment.x, segment.y + BOX_SIZE, segment.x, segment.y + BOX_SIZE - radius);
            ctx.lineTo(segment.x, segment.y + radius);
            ctx.quadraticCurveTo(segment.x, segment.y, segment.x + radius, segment.y);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            // Draw eyes on the head
            if (isHead) {
                ctx.fillStyle = '#FFFFFF'; // White eyes
                ctx.strokeStyle = '#000000'; // Black outline
                ctx.lineWidth = 1; // Reset just in case

                // Determine eye position based on direction
                let eye1X, eye1Y, eye2X, eye2Y;
                const eyeSize = Math.max(2, BOX_SIZE / 6); // Ensure minimum size
                const offset = BOX_SIZE / 4; // Offset from edge

                // Calculate base positions (centers of eyes)
                if (dx &gt; 0) { // Moving Right
                    eye1X = segment.x + BOX_SIZE - offset - eyeSize; // X is further right
                    eye1Y = segment.y + offset;                      // Y is top offset
                    eye2X = eye1X;
                    eye2Y = segment.y + BOX_SIZE - offset - eyeSize; // Y is bottom offset
                } else if (dx &lt; 0) { // Moving Left
                    eye1X = segment.x + offset;                      // X is further left
                    eye1Y = segment.y + offset;
                    eye2X = eye1X;
                    eye2Y = segment.y + BOX_SIZE - offset - eyeSize;
                } else if (dy &gt; 0) { // Moving Down
                    eye1X = segment.x + offset;                      // X is left offset
                    eye1Y = segment.y + BOX_SIZE - offset - eyeSize; // Y is further down
                    eye2X = segment.x + BOX_SIZE - offset - eyeSize; // X is right offset
                    eye2Y = eye1Y;
                } else { // Moving Up (or stationary initially)
                    eye1X = segment.x + offset;
                    eye1Y = segment.y + offset;                      // Y is further up
                    eye2X = segment.x + BOX_SIZE - offset - eyeSize;
                    eye2Y = eye1Y;
                }

                // Draw circles for eyes
                ctx.beginPath();
                ctx.arc(eye1X + eyeSize / 2, eye1Y + eyeSize / 2, eyeSize / 2, 0, Math.PI * 2);
                ctx.fill();
                ctx.stroke();

                ctx.beginPath();
                ctx.arc(eye2X + eyeSize / 2, eye2Y + eyeSize / 2, eyeSize / 2, 0, Math.PI * 2);
                ctx.fill();
                ctx.stroke();
            }
        }


        // --- Game Logic Functions ---

        function moveSnake() {
            // Calculate the new head position
            const head = { x: snake[0].x + dx, y: snake[0].y + dy };
            snake.unshift(head); // Add the new head to the beginning

            // Check for food collision *before* potentially removing the tail
            const didEatFood = snake[0].x === food.x &amp;&amp; snake[0].y === food.y;

            if (didEatFood) {
                score += 10; // Base score per food
                foodEatenThisLevel++;
                scoreDisplay.textContent = `Score: ${score}`;

                // Check for level up
                if (foodEatenThisLevel &gt;= FOOD_PER_LEVEL) {
                    currentLevel++;
                    foodEatenThisLevel = 0; // Reset counter for the new level
                    levelDisplay.textContent = `Level: ${currentLevel}`;
                    addObstaclesForLevel(currentLevel); // Add more obstacles for the new level
                    calculateAndSetSpeed(); // Increase speed (restarts the interval)
                }

                createFood(); // Generate new food in a safe spot
                // Don't pop the tail - the snake grows
            } else {
                snake.pop(); // Didn't eat food, remove the last segment of the tail
            }
        }

        /**
         * Adds obstacles based on the current level, avoiding snake, food, and existing obstacles.
         * @param {number} level - The current game level.
         */
        function addObstaclesForLevel(level) {
            // Target number of obstacles based on level (e.g., level-1, capped at MAX_OBSTACLES)
            const targetObstacles = Math.min(MAX_OBSTACLES, Math.max(0, level - 1));
            let attempts = 0; // Safety counter to prevent infinite loops

            // Add obstacles until the target number is reached or it's too hard to place more
            while (obstacles.length &lt; targetObstacles &amp;&amp; attempts &lt; 100) {
                 attempts++;
                 // Generate random coordinates aligned to the grid
                 let obsX = randomCoord(0, gameCanvas.width - BOX_SIZE);
                 let obsY = randomCoord(0, gameCanvas.height - BOX_SIZE);

                 let collision = false;

                 // 1. Check collision vs Snake
                 for (const part of snake) {
                     if (part.x === obsX &amp;&amp; part.y === obsY) {
                         collision = true;
                         break;
                     }
                 }
                 if (collision) continue; // Try new coordinates

                 // 2. Check collision vs Food
                 // Ensure food exists before checking (it should, but good practice)
                 if (food &amp;&amp; food.x === obsX &amp;&amp; food.y === obsY) {
                     collision = true;
                     continue; // Try new coordinates
                 }

                 // 3. Check collision vs Existing Obstacles
                 for (const obs of obstacles) {
                     if (obs.x === obsX &amp;&amp; obs.y === obsY) {
                         collision = true;
                         break;
                     }
                 }
                 if (collision) continue; // Try new coordinates

                 // 4. (Optional) Avoid spawning too close to the center on early levels
                 const centerX = Math.floor(gameCanvas.width / 2 / BOX_SIZE) * BOX_SIZE;
                 const centerY = Math.floor(gameCanvas.height / 2 / BOX_SIZE) * BOX_SIZE;
                 const proximityLimit = BOX_SIZE * 3; // Don't spawn within 3 boxes of center
                 if (level &lt;= 2 &amp;&amp; Math.abs(obsX - centerX) &lt; proximityLimit &amp;&amp; Math.abs(obsY - centerY) &lt; proximityLimit) {
                     continue; // Too close to start area, try again
                 }

                 // If no collisions, add the obstacle
                 obstacles.push({ x: obsX, y: obsY });
                 // Reset attempts counter for the next obstacle if needed, or just let it run per obstacle
            }

            // if (attempts &gt;= 100 &amp;&amp; obstacles.length &lt; targetObstacles) {
            //     console.warn("Could not place all required obstacles for level", level);
            // }
            // console.log("Obstacles:", obstacles.length, obstacles); // For debugging
        }


        /** Creates food at a random location, avoiding snake and obstacles. */
        function createFood() {
            let foodX, foodY;
            let collision;
            let attempts = 0; // Prevent infinite loop if board is somehow full

            do {
                collision = false;
                attempts++;
                // Generate random coordinates aligned to grid
                foodX = randomCoord(0, gameCanvas.width - BOX_SIZE);
                foodY = randomCoord(0, gameCanvas.height - BOX_SIZE);

                // Check collision with snake
                for (const part of snake) {
                    if (part.x === foodX &amp;&amp; part.y === foodY) {
                        collision = true;
                        break;
                    }
                }
                if (collision) continue; // Try again

                // Check collision with obstacles
                for (const obs of obstacles) {
                    if (obs.x === foodX &amp;&amp; obs.y === foodY) {
                        collision = true;
                        break;
                    }
                }
            } while (collision &amp;&amp; attempts &lt; 500); // Keep trying until a valid spot is found or max attempts reached

            if (attempts &gt;= 500) {
                console.error("Could not place food - board might be too full or RNG unlucky.");
                // Handle this case? Maybe try placing at 0,0 if free? For now, log error.
                // The game might behave strangely if food overlaps snake/obstacle.
                // As a fallback, place it at a known safe(ish) corner if possible
                if (!isOccupied(0,0)) { foodX = 0; foodY = 0;}
                else { gameOver = true; console.error("Game Over - Cannot place food.");} // Critical failure
            }

            food = { x: foodX, y: foodY };
        }

        /** Helper function to check if a coordinate is occupied by snake or obstacles */
        function isOccupied(x, y) {
             for (const part of snake) if (part.x === x &amp;&amp; part.y === y) return true;
             for (const obs of obstacles) if (obs.x === x &amp;&amp; obs.y === y) return true;
             return false;
        }


        /** Generates a random coordinate aligned to the grid. */
        function randomCoord(min, max) {
            // Calculate number of possible grid cells
            const cells = (max - min) / BOX_SIZE;
            // Generate random cell index, add min offset, multiply by box size
            return Math.floor(Math.random() * (cells + 1)) * BOX_SIZE + min;
        }

        /** Checks for collisions with walls, self, and obstacles. Sets gameOver flag. */
        function checkCollision() {
             // No need to check if game is already over
             if (gameOver) return;

            const head = snake[0];

            // 1. Wall collision
            const hitLeftWall = head.x &lt; 0;
            const hitRightWall = head.x &gt;= gameCanvas.width;
            const hitTopWall = head.y &lt; 0;
            const hitBottomWall = head.y &gt;= gameCanvas.height;

            if (hitLeftWall || hitRightWall || hitTopWall || hitBottomWall) {
                // console.log("Collision: Wall"); // Debug log
                gameOver = true;
                return; // Stop checking further
            }

            // 2. Self collision (check head against rest of the body)
            for (let i = 1; i &lt; snake.length; i++) {
                if (head.x === snake[i].x &amp;&amp; head.y === snake[i].y) {
                     // console.log("Collision: Self"); // Debug log
                     gameOver = true;
                     return; // Stop checking further
                }
            }

            // 3. Obstacle collision
             for (const obs of obstacles) {
                 if (head.x === obs.x &amp;&amp; head.y === obs.y) {
                     // console.log("Collision: Obstacle"); // Debug log
                     gameOver = true;
                     return; // Stop checking further
                 }
             }
        }

        // --- Input Handling &amp; Fullscreen ---

         function handleKeyDown(event) {
             // Only handle direction changes if game is active and not over
             if (gameActive &amp;&amp; !gameOver) {
                 changeDirection(event);
             }
             // Allow Esc to exit fullscreen anytime
             if (event.key === "Escape" || event.keyCode === 27) { // 27 is Escape keycode
                if (document.fullscreenElement || document.webkitFullscreenElement) {
                    exitFullscreen();
                }
             }
             // Prevent arrow keys from scrolling the page when game is active
             if (gameActive &amp;&amp; ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
                 event.preventDefault();
             }
         }

        function changeDirection(event) {
            const LEFT_KEY = 37; const ARROW_LEFT = "ArrowLeft";
            const RIGHT_KEY = 39; const ARROW_RIGHT = "ArrowRight";
            const UP_KEY = 38; const ARROW_UP = "ArrowUp";
            const DOWN_KEY = 40; const ARROW_DOWN = "ArrowDown";

            // Prevent changing direction twice in the same game tick
            if (changingDirection) return;

            const keyPressed = event.key || event.keyCode; // Use event.key for modern browsers, fallback to keyCode

            const goingUp = dy === -BOX_SIZE;
            const goingDown = dy === BOX_SIZE;
            const goingRight = dx === BOX_SIZE;
            const goingLeft = dx === -BOX_SIZE;

            let directionChanged = false;

            // Check key and ensure snake is not trying to reverse direction
            if ((keyPressed === LEFT_KEY || keyPressed === ARROW_LEFT) &amp;&amp; !goingRight) {
                dx = -BOX_SIZE; dy = 0; directionChanged = true;
            } else if ((keyPressed === UP_KEY || keyPressed === ARROW_UP) &amp;&amp; !goingDown) {
                dx = 0; dy = -BOX_SIZE; directionChanged = true;
            } else if ((keyPressed === RIGHT_KEY || keyPressed === ARROW_RIGHT) &amp;&amp; !goingLeft) {
                dx = BOX_SIZE; dy = 0; directionChanged = true;
            } else if ((keyPressed === DOWN_KEY || keyPressed === ARROW_DOWN) &amp;&amp; !goingUp) {
                dx = 0; dy = BOX_SIZE; directionChanged = true;
            }

            // Set the flag if a valid direction change occurred
            if (directionChanged) {
                changingDirection = true;
            }
        }

        function showGameOver() {
            gameActive = false; // Ensure game loop stops trying to run
             if (gameInterval) {
                 clearInterval(gameInterval); // Clear the interval explicitly
                 gameInterval = null;
             }
            finalScoreDisplay.textContent = `Final Score: ${score}`;
            gameOverMessage.style.display = 'block'; // Show the message
            gameContainer.classList.add('game-blurred'); // Apply blur effect
        }

        // --- Fullscreen Functions ---
        function toggleFullscreen() {
            const docEl = document.documentElement; // Target the whole page
             // More robust check for fullscreen capability
            const requestFS = docEl.requestFullscreen || docEl.webkitRequestFullscreen || docEl.mozRequestFullScreen || docEl.msRequestFullscreen;
            // Check if currently in fullscreen
            const isInFullscreen = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;

            if (!isInFullscreen) {
                if (requestFS) {
                    requestFS.call(docEl).then(() =&gt; {
                         fullscreenButton.textContent = "Exit FS";
                    }).catch(err =&gt; {
                        // Inform user if fullscreen failed
                        console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                        alert(`Could not enter fullscreen mode. Browser might not support it or permission denied.`);
                    });
                } else {
                     alert("Fullscreen API is not supported by your browser.");
                }
            } else {
                exitFullscreen(); // Call separate function to exit
            }
        }

        function exitFullscreen() {
            const exitFS = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;
            if (exitFS) {
                exitFS.call(document).then(() =&gt; {
                    fullscreenButton.textContent = "Fullscreen";
                }).catch(err =&gt; {
                    console.error(`Error attempting to exit full-screen mode: ${err.message} (${err.name})`);
                });
            }
        }

        // Event listeners to update button text if fullscreen is exited via Esc key etc.
        document.addEventListener('fullscreenchange', () =&gt; { if (!document.fullscreenElement) fullscreenButton.textContent = "Fullscreen"; });
        document.addEventListener('webkitfullscreenchange', () =&gt; { if (!document.webkitFullscreenElement) fullscreenButton.textContent = "Fullscreen"; });
        document.addEventListener('mozfullscreenchange', () =&gt; { if (!document.mozFullScreenElement) fullscreenButton.textContent = "Fullscreen"; });
        document.addEventListener('MSFullscreenChange', () =&gt; { if (!document.msFullscreenElement) fullscreenButton.textContent = "Fullscreen"; });

    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Generative AI Bookmarks Hub</title><link>http://rajclick.blogspot.com/2025/03/generative-ai-bookmarks-hub.html</link><pubDate>Wed, 26 Mar 2025 07:22:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-3659117411619496062</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en" data-theme="dark"&gt; &lt;!-- Default to dark theme --&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;AI Bookmarks Hub&lt;/title&gt;
    &lt;meta name="description" content="Your one-stop hub for accessing popular AI tools and platforms. Bookmark ChatGPT, DeepSeek, Claude, and more with this convenient and stylish bookmark page."&gt;
    &lt;meta name="keywords" content="AI bookmarks, ChatGPT bookmark, DeepSeek bookmark, Claude bookmark, AI tools, productivity, dark mode"&gt;
    &lt;style&gt;
        :root {
            /* Base variables (can be overridden by themes) */
            --border-radius: 12px;
            --shadow-light: 0 4px 6px rgba(0, 0, 0, 0.1);
            --shadow-dark: 0 4px 8px rgba(0, 0, 0, 0.3);
            --transition-speed: 0.2s;

            /* Light Theme Colors */
            --light-bg: #f0f4f8;
            --light-card-bg: #ffffff;
            --light-text: #2c3e50;
            --light-accent: #3498db;
            --light-footer-text: #666;
            --light-switch-bg: #ccc;
            --light-switch-knob: #fff;
            --light-switch-icon: "☀️"; /* Sun icon */

             /* Dark Theme Colors */
            --dark-bg: #1a1a2e;
            --dark-card-bg: #2a2a4a;
            --dark-text: #e0e0ff;
            --dark-accent: #5a7dcf; /* Adjusted accent for dark */
            --dark-footer-text: #aaa;
            --dark-switch-bg: #555;
            --dark-switch-knob: #333;
            --dark-switch-icon: "&#127769;"; /* Moon icon */
        }

        /* Apply theme variables */
        [data-theme="light"] {
            --primary-bg: var(--light-bg);
            --card-bg: var(--light-card-bg);
            --text-color: var(--light-text);
            --accent-color: var(--light-accent);
            --footer-text-color: var(--light-footer-text);
            --shadow: var(--shadow-light);
            --switch-bg: var(--light-switch-bg);
            --switch-knob: var(--light-switch-knob);
            --switch-icon: var(--light-switch-icon);
        }

        [data-theme="dark"] {
            --primary-bg: var(--dark-bg);
            --card-bg: var(--dark-card-bg);
            --text-color: var(--dark-text);
            --accent-color: var(--dark-accent);
            --footer-text-color: var(--dark-footer-text);
            --shadow: var(--shadow-dark);
            --switch-bg: var(--dark-switch-bg);
            --switch-knob: var(--dark-switch-knob);
            --switch-icon: var(--dark-switch-icon);
        }

        /* General Styles */
        *, *::before, *::after {
            box-sizing: border-box;
        }

        body {
            margin: 0;
            padding: 20px;
            font-family: 'Arial', sans-serif;
            background-color: var(--primary-bg);
            color: var(--text-color);
            transition: background-color var(--transition-speed) ease, color var(--transition-speed) ease;
        }

        header {
            display: flex; /* Use flexbox for alignment */
            justify-content: space-between; /* Space out title and switch */
            align-items: center;
            text-align: center;
            margin-bottom: 30px;
            padding: 0 10px; /* Add some padding */
        }

        /* Center the title - take remaining space */
        header h1 {
            flex-grow: 1; /* Allow title to take available space */
            margin: 0; /* Remove default margin */
            color: var(--accent-color);
            font-size: 2.5em;
            transition: color var(--transition-speed) ease;
        }

        /* Theme Switch Styles */
        .theme-switch-wrapper {
            display: flex;
            align-items: center;
            /* position: absolute; /* Or absolute position if preferred */
            /* top: 20px; */
            /* right: 20px; */
            z-index: 10; /* Ensure it's above other content */
        }

        .theme-switch {
            display: inline-block;
            height: 26px;
            position: relative;
            width: 50px;
            margin-left: 10px; /* Space from title */
        }

        .theme-switch input {
            display:none;
        }

        .slider {
            background-color: var(--switch-bg);
            bottom: 0;
            cursor: pointer;
            left: 0;
            position: absolute;
            right: 0;
            top: 0;
            transition: var(--transition-speed);
            border-radius: 26px;
        }

        .slider:before {
            background-color: var(--switch-knob);
            bottom: 3px;
            content: var(--switch-icon); /* Display sun/moon */
            height: 20px;
            left: 3px;
            position: absolute;
            transition: var(--transition-speed);
            width: 20px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px; /* Adjust icon size */
            line-height: 20px; /* Center icon vertically */
        }

        input:checked + .slider {
            background-color: var(--accent-color); /* Optional: use accent color when light */
        }

        /* Move knob (icon) when checked (light mode) */
        input:checked + .slider:before {
            transform: translateX(24px);
        }

        /* Bookmark Grid Styles */
        .bookmark-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); /* More responsive */
            gap: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }

        .bookmark-card {
            background: var(--card-bg);
            padding: 20px;
            border-radius: var(--border-radius);
            box-shadow: var(--shadow);
            text-align: center;
            text-decoration: none;
            color: var(--text-color);
            transition: transform var(--transition-speed) ease,
                        box-shadow var(--transition-speed) ease,
                        background-color var(--transition-speed) ease,
                        color var(--transition-speed) ease;
            display: flex; /* Use flex for better internal alignment */
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 150px; /* Ensure cards have some height */
        }

        .bookmark-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); /* Consistent shadow hover */
        }

        .icon-container { /* Wrap icon/fallback for consistent spacing */
            width: 48px;
            height: 48px;
            margin-bottom: 10px;
            position: relative; /* Needed for absolute positioning of children if required */
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .favicon {
            width: 100%;
            height: 100%;
            border-radius: 8px; /* Slightly less round? Personal preference */
            object-fit: contain; /* Use contain to avoid cropping */
            display: block; /* Default display */
        }

        .fallback-icon {
            width: 100%;
            height: 100%;
            background: var(--accent-color);
            color: var(--primary-bg); /* Contrast against accent */
            border-radius: 8px;
            display: flex; /* Centering */
            align-items: center;
            justify-content: center;
            font-size: 24px;
            font-weight: bold;
            text-transform: uppercase;
            transition: background-color var(--transition-speed) ease, color var(--transition-speed) ease;
            display: none; /* Hide by default */
        }

        .bookmark-name {
             margin-top: 5px; /* Space between icon and name */
             font-size: 0.9em;
             font-weight: bold;
        }


        footer {
            text-align: center;
            margin-top: 40px;
            padding: 20px;
            font-size: 0.9em;
            color: var(--footer-text-color);
            transition: color var(--transition-speed) ease;
        }

        /* Responsive adjustments (kept from original) */
        @media (max-width: 768px) {
            /* grid-template-columns already handles responsiveness well with auto-fit */
            header h1 {
                 font-size: 2em;
            }
        }

        @media (max-width: 480px) {
             body {
                 padding: 15px;
             }
             .bookmark-grid {
                 gap: 15px;
             }
             .bookmark-card {
                 padding: 15px;
                 min-height: 120px;
             }
             header {
                 flex-direction: column; /* Stack title and switch on small screens */
                 gap: 15px;
             }
             .theme-switch-wrapper {
                 /* Adjust if needed when stacked */
             }
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;header&gt;
        &lt;h1&gt;AI Bookmarks Hub&lt;/h1&gt;
        &lt;!-- Theme Switch --&gt;
        &lt;div class="theme-switch-wrapper"&gt;
            &lt;label class="theme-switch" for="themeToggleCheckbox"&gt;
                &lt;input type="checkbox" id="themeToggleCheckbox" aria-label="Toggle theme between light and dark"&gt;
                &lt;span class="slider"&gt;&lt;/span&gt;
            &lt;/label&gt;
        &lt;/div&gt;
    &lt;/header&gt;

    &lt;div class="bookmark-grid" id="bookmarkGrid"&gt;
        &lt;!-- Bookmarks will be inserted here by JavaScript --&gt;
    &lt;/div&gt;

    &lt;footer&gt;
        &lt;p&gt;Access your favorite AI tools quickly and easily. Your go-to bookmark page for ChatGPT, DeepSeek, Claude, and more AI platforms. Optimized for productivity and convenience.&lt;/p&gt;
    &lt;/footer&gt;

    &lt;script&gt;
        const bookmarks = [
            { name: "ChatGPT", url: "https://chat.openai.com" },
            { name: "DeepSeek", url: "https://chat.deepseek.com" }, // Corrected URL
            { name: "Claude", url: "https://claude.ai" },
            { name: "Gemini", url: "https://gemini.google.com" },
            { name: "Google AI Studio", url: "https://aistudio.google.com" },
            { name: "Perplexity AI", url: "https://www.perplexity.ai" },
            { name: "Qwen Tongyi", url: "https://tongyi.aliyun.com/qianwen/" }, // Updated Qwen
            { name: "Gamma AI", url: "https://gamma.app" },
            { name: "Grok (XAI)", url: "https://x.ai/grok" }, // Corrected URL if possible, else remove if paywalled only
            { name: "Microsoft Copilot", url: "https://copilot.microsoft.com" },
            { name: "Phind", url: "https://www.phind.com" }, // Added another popular one
            { name: "Hugging Face", url: "https://huggingface.co/chat/" } // Added HuggingChat
        ];

        // Sort bookmarks alphabetically by name
        bookmarks.sort((a, b) =&gt; a.name.localeCompare(b.name));

        const grid = document.getElementById('bookmarkGrid');
        const themeToggle = document.getElementById('themeToggleCheckbox');
        const currentHtml = document.documentElement; // Target &lt;html&gt; tag

        function createBookmarkCard(bookmark) {
            const card = document.createElement('a');
            card.className = 'bookmark-card';
            card.href = bookmark.url;
            card.target = '_blank';
            card.rel = 'noopener noreferrer'; // Add security attribute

            const iconContainer = document.createElement('div');
            iconContainer.className = 'icon-container';

            const img = document.createElement('img');
            img.className = 'favicon';
            // Use Google's favicon service for better reliability (optional, fallback still works)
            // Using sz=64 for potentially higher res icon
             img.src = `https://www.google.com/s2/favicons?domain=${encodeURIComponent(bookmark.url)}&amp;sz=64`;
            // img.src = `https://t1.gstatic.com/faviconV2?client=SOCIAL&amp;type=FAVICON&amp;fallback_opts=TYPE,SIZE,URL&amp;url=${encodeURIComponent(bookmark.url)}&amp;size=64`; // Alternative Google Service
            // img.src = `${bookmark.url}/favicon.ico`; // Original method (less reliable)

            img.alt = `${bookmark.name} icon`;

            const fallback = document.createElement('div');
            fallback.className = 'fallback-icon';
            // Use first two letters if available, otherwise one
            fallback.textContent = bookmark.name.length &gt; 1 ? bookmark.name.substring(0, 2) : bookmark.name.charAt(0);


            const name = document.createElement('div');
            name.className = 'bookmark-name';
            name.textContent = bookmark.name;

            // Improved fallback logic
            img.onerror = () =&gt; {
                img.style.display = 'none';
                fallback.style.display = 'flex'; // Show fallback
                // console.warn(`Favicon failed to load for: ${bookmark.name} (${img.src})`);
            };
            // Handle cases where the image loads but is empty (e.g., 1x1 pixel transparent)
             img.onload = () =&gt; {
                 if (img.naturalWidth &lt;= 1 || img.naturalHeight &lt;= 1) {
                    img.onerror(); // Trigger the error handler if image is tiny/invalid
                 } else {
                    // Image loaded successfully, ensure fallback is hidden
                    fallback.style.display = 'none';
                    img.style.display = 'block';
                 }
             }


            iconContainer.appendChild(img);
            iconContainer.appendChild(fallback);
            card.appendChild(iconContainer);
            card.appendChild(name);
            return card;
        }

        // Populate bookmarks
        bookmarks.forEach(bookmark =&gt; {
            const card = createBookmarkCard(bookmark);
            grid.appendChild(card);
        });

        // --- Theme Handling ---

        function setTheme(themeName) {
            localStorage.setItem('theme', themeName);
            currentHtml.setAttribute('data-theme', themeName);
            // Update checkbox state based on theme ('light' means checked)
            themeToggle.checked = (themeName === 'light');
        }

        function toggleTheme() {
            const currentTheme = currentHtml.getAttribute('data-theme');
            const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
            setTheme(newTheme);
        }

        // Add event listener for the toggle switch
        themeToggle.addEventListener('change', toggleTheme);

        // Determine initial theme on load
        function initializeTheme() {
            const savedTheme = localStorage.getItem('theme');
            const prefersDark = window.matchMedia &amp;&amp; window.matchMedia('(prefers-color-scheme: dark)').matches;

            if (savedTheme) {
                // Use saved theme
                setTheme(savedTheme);
            } else if (prefersDark) {
                // Use OS preference if no saved theme
                setTheme('dark');
            } else {
                // Default to dark (as per initial HTML, but reinforces JS state)
                setTheme('dark'); // Or 'light' if you wanted light as fallback default
                 // Ensure checkbox matches initial state if defaulting and not checked
                if (currentHtml.getAttribute('data-theme') === 'dark') {
                    themeToggle.checked = false;
                } else {
                     themeToggle.checked = true;
                }
            }
             // Ensure the toggle is visually correct even if the theme was set via HTML attribute initially
            themeToggle.checked = (currentHtml.getAttribute('data-theme') === 'light');
        }

        // Initialize theme when the script runs
        initializeTheme();

    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Simple Calculator App</title><link>http://rajclick.blogspot.com/2025/03/simple-calculator-app.html</link><category>Calculator App</category><pubDate>Wed, 26 Mar 2025 03:21:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-4421924486981547252</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Enhanced Fun Calculator (Dark/Light Mode)&lt;/title&gt;
    &lt;!-- Google Font --&gt;
    &lt;link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&amp;display=swap" rel="stylesheet"&gt;

    &lt;!-- CSS Styles --&gt;
    &lt;style&gt;
        /* Basic Reset */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        /* --- THEME VARIABLES --- */
        :root { /* Default: Dark Mode */
            --bg-gradient-start: #232526;
            --bg-gradient-end: #414345;
            --body-text: #e0e0e0;
            --calc-bg: #3a3a3a;
            --calc-shadow: rgba(0, 0, 0, 0.4);
            --display-bg: #2a2a2a;
            --display-text: #f0f0f0;
            --button-grid-gap-bg: #555;
            --button-default-bg: #505050;
            --button-default-text: #f5f5f5;
            --button-default-hover-bg: #6a6a6a;
            --button-default-active-bg: #808080;
            --button-number-bg: #6e6e6e;
            --button-number-hover-bg: #858585;
            --button-number-active-bg: #9c9c9c;
            --button-operator-bg: #ff9f0a;
            --button-operator-text: white;
            --button-operator-hover-bg: #e89005;
            --button-operator-active-bg: #d18004;
            --button-equals-bg: #4cd964;
            --button-equals-text: white;
            --button-equals-hover-bg: #45cc5a;
            --button-equals-active-bg: #3dbb50;
            --button-clear-bg: #ff3b30;
            --button-clear-text: white;
            --button-clear-hover-bg: #e63025;
            --button-clear-active-bg: #c92a20;
            --history-bg: #4a4a4a;
            --history-shadow: rgba(0, 0, 0, 0.2);
            --history-header-text: #ccc;
            --history-text: #bbb;
            --history-border: #666;
            /* Theme Toggle specific styling (icon set by JS now) */
            --theme-toggle-color: #f0e68c; /* Light yellow for sun */
            --theme-toggle-border: #aaa;
            --theme-toggle-hover-bg: rgba(255, 255, 255, 0.1);
        }

        body.light-mode { /* Light Mode Overrides */
            --bg-gradient-start: #f5f7fa;
            --bg-gradient-end: #c3cfe2;
            --body-text: #333;
            --calc-bg: #ffffff;
            --calc-shadow: rgba(0, 0, 0, 0.1);
            --display-bg: #e9eef2;
            --display-text: #333;
            --button-grid-gap-bg: #ccc;
            --button-default-bg: #f9f9f9;
            --button-default-text: #333;
            --button-default-hover-bg: #eee;
            --button-default-active-bg: #ddd;
            --button-number-bg: #e0e0e0;
            --button-number-hover-bg: #d5d5d5;
            --button-number-active-bg: #cccccc;
            --history-bg: #f0f0f0;
            --history-shadow: rgba(0, 0, 0, 0.08);
            --history-header-text: #555;
            --history-text: #666;
            --history-border: #ccc;
             /* Theme Toggle specific styling (icon set by JS now) */
            --theme-toggle-color: #4a4a6a; /* Dark blue/purple for moon */
            --theme-toggle-border: #555;
            --theme-toggle-hover-bg: rgba(0, 0, 0, 0.05);
        }

        /* --- General Styles --- */
        body {
            font-family: 'Poppins', sans-serif;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 60px 0 20px; /* Add more padding top for toggle */
            background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
            color: var(--body-text);
            transition: background 0.3s ease, color 0.3s ease; /* Smooth theme transition */
            position: relative; /* Needed for absolute positioning of toggle */
        }

        /* Theme Toggle Button */
        #theme-toggle {
            position: absolute;
            top: 15px;
            right: 15px;
            background: none;
            border: 1px solid var(--theme-toggle-border);
            border-radius: 50%;
            width: 40px;
            height: 40px;
            font-size: 1.5em; /* Adjust icon size */
            cursor: pointer;
            transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
            color: var(--theme-toggle-color); /* Color is themed */
            display: flex;
            justify-content: center;
            align-items: center;
            -webkit-tap-highlight-color: transparent;
             outline: none;
             padding: 0; /* Remove padding */
             line-height: 1; /* Consistent line height */
        }
         #theme-toggle:hover {
            background-color: var(--theme-toggle-hover-bg);
        }
         #theme-toggle:active {
            transform: scale(0.95);
         }

        /* Calculator Container */
        .calculator {
            width: 90%;
            max-width: 360px;
            background-color: var(--calc-bg);
            border-radius: 15px;
            overflow: hidden;
            box-shadow: 0 10px 30px var(--calc-shadow);
            margin-bottom: 20px;
            transition: background-color 0.3s ease, box-shadow 0.3s ease;
        }

        /* Display Screen Styling */
        #display {
            width: 100%;
            padding: 25px 20px;
            font-size: 2.5em;
            text-align: right;
            border: none;
            background-color: var(--display-bg);
            color: var(--display-text);
            -webkit-tap-highlight-color: transparent;
            outline: none;
            min-height: 75px;
            transition: background-color 0.3s ease, color 0.3s ease;
        }

        /* Button Grid Layout */
        .buttons {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(5, auto);
            gap: 1px;
            background-color: var(--button-grid-gap-bg); /* Separator color */
             transition: background-color 0.3s ease;
        }

        /* General Button Styling */
        .button {
            padding: 18px;
            font-size: 1.4em;
            border: none;
            background-color: var(--button-default-bg); /* Use default var */
            color: var(--button-default-text); /* Use default var */
            cursor: pointer;
            transition: background-color 0.2s ease, transform 0.1s ease, color 0.2s ease;
            -webkit-tap-highlight-color: transparent;
            outline: none;
            font-weight: 500;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* Grid Item Placement */
        .btn-clear { grid-column: 1 / 3; }
        .btn-equals { grid-row: 4 / 6; grid-column: 4 / 5; height: auto; }
        .button.zero { grid-column: 1 / 3; }

        /* Hover effect */
        .button:hover { background-color: var(--button-default-hover-bg); }
        .button:active, .button.active-key { background-color: var(--button-default-active-bg) !important; transform: scale(0.97); }

        /* Operator buttons */
        .btn-operator { background-color: var(--button-operator-bg); color: var(--button-operator-text); }
        .btn-operator:hover { background-color: var(--button-operator-hover-bg); }
        .btn-operator:active, .btn-operator.active-key { background-color: var(--button-operator-active-bg) !important; }

        /* Equals button */
        .btn-equals { background-color: var(--button-equals-bg); color: var(--button-equals-text); }
        .btn-equals:hover { background-color: var(--button-equals-hover-bg); }
        .btn-equals:active, .btn-equals.active-key { background-color: var(--button-equals-active-bg) !important; }

        /* Clear button */
        .btn-clear { background-color: var(--button-clear-bg); color: var(--button-clear-text); }
        .btn-clear:hover { background-color: var(--button-clear-hover-bg); }
        .btn-clear:active, .btn-clear.active-key { background-color: var(--button-clear-active-bg) !important; }

        /* Number buttons */
        .btn-number { background-color: var(--button-number-bg); }
        .btn-number:hover { background-color: var(--button-number-hover-bg); }
        .btn-number:active, .btn-number.active-key { background-color: var(--button-number-active-bg) !important; }

        /* --- History Section Styling --- */
        .history-container {
            width: 90%; max-width: 360px; background-color: var(--history-bg); border-radius: 8px; padding: 15px;
            box-shadow: 0 4px 15px var(--history-shadow); transition: background-color 0.3s ease, box-shadow 0.3s ease;
        }
        .history-container h3 { text-align: center; margin-bottom: 10px; color: var(--history-header-text); font-weight: 500; transition: color 0.3s ease; }
        #historyLog { list-style: none; padding: 0; margin: 0; max-height: 150px; overflow-y: auto; font-size: 0.9em; color: var(--history-text); transition: color 0.3s ease; }
        #historyLog li { padding: 5px 8px; border-bottom: 1px dashed var(--history-border); text-align: right; transition: border-color 0.3s ease; }
        #historyLog li:last-child { border-bottom: none; }
        #historyLog::-webkit-scrollbar { width: 6px; }
        #historyLog::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); border-radius: 3px; }
        #historyLog::-webkit-scrollbar-thumb { background: var(--history-border); border-radius: 3px; }
        #historyLog::-webkit-scrollbar-thumb:hover { background: var(--history-text); }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;!-- Theme Toggle Button --&gt;
    &lt;button id="theme-toggle" aria-label="Switch theme"&gt;&lt;/button&gt; &lt;!-- Icon will be set by JS --&gt;

    &lt;!-- HTML Structure (Calculator) --&gt;
    &lt;div class="calculator"&gt;
        &lt;input type="text" id="display" value="0" readonly&gt;
        &lt;div class="buttons"&gt;
            &lt;button class="button btn-clear" id="clear" data-key="Escape"&gt;AC&lt;/button&gt;
            &lt;button class="button btn-operator" data-operator="/" data-key="/"&gt;÷&lt;/button&gt;
            &lt;button class="button btn-operator" data-operator="*" data-key="*"&gt;×&lt;/button&gt;
            &lt;button class="button btn-number" data-num="7" data-key="7"&gt;7&lt;/button&gt;
            &lt;button class="button btn-number" data-num="8" data-key="8"&gt;8&lt;/button&gt;
            &lt;button class="button btn-number" data-num="9" data-key="9"&gt;9&lt;/button&gt;
            &lt;button class="button btn-operator" data-operator="-" data-key="-"&gt;−&lt;/button&gt;
            &lt;button class="button btn-number" data-num="4" data-key="4"&gt;4&lt;/button&gt;
            &lt;button class="button btn-number" data-num="5" data-key="5"&gt;5&lt;/button&gt;
            &lt;button class="button btn-number" data-num="6" data-key="6"&gt;6&lt;/button&gt;
            &lt;button class="button btn-operator" data-operator="+" data-key="+"&gt;+&lt;/button&gt;
            &lt;button class="button btn-number" data-num="1" data-key="1"&gt;1&lt;/button&gt;
            &lt;button class="button btn-number" data-num="2" data-key="2"&gt;2&lt;/button&gt;
            &lt;button class="button btn-number" data-num="3" data-key="3"&gt;3&lt;/button&gt;
            &lt;button class="button btn-equals" id="equals" data-key="Enter"&gt;=&lt;/button&gt;
            &lt;button class="button btn-number zero" data-num="0" data-key="0"&gt;0&lt;/button&gt;
            &lt;button class="button btn-number" data-num="." data-key="."&gt;.&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- History Section --&gt;
    &lt;div class="history-container"&gt;
        &lt;h3&gt;History&lt;/h3&gt;
        &lt;ul id="historyLog"&gt;&lt;/ul&gt;
    &lt;/div&gt;

    &lt;!-- JavaScript Logic --&gt;
    &lt;script&gt;
        document.addEventListener('DOMContentLoaded', () =&gt; {

            // --- DOM Elements ---
            const display = document.getElementById('display');
            const buttons = document.querySelectorAll('.button');
            const historyLog = document.getElementById('historyLog');
            const themeToggle = document.getElementById('theme-toggle');
            const body = document.body;

            // --- State variables ---
            let currentInput = '0';
            let firstOperand = null;
            let operator = null;
            let shouldResetDisplay = false;
            let history = [];
            const MAX_HISTORY_LENGTH = 15;
            const THEME_KEY = 'calculatorTheme'; // Key for localStorage

            // --- Theme Switching Logic ---

            // Function to apply theme based on class, save preference, and update button icon
            function applyTheme(theme) {
                 const toggleButton = document.getElementById('theme-toggle'); // Get button ref
                 if (theme === 'light') {
                    body.classList.add('light-mode');
                    localStorage.setItem(THEME_KEY, 'light');
                    toggleButton.innerHTML = ''; // Set Moon icon (HTML entity) - shows what you switch TO
                 } else {
                    body.classList.remove('light-mode');
                    localStorage.setItem(THEME_KEY, 'dark');
                    toggleButton.innerHTML = '☀'; // Set Sun icon (HTML entity) - shows what you switch TO
                 }
            }

            // Event listener for the theme toggle button
            themeToggle.addEventListener('click', () =&gt; {
                const isLightMode = body.classList.contains('light-mode');
                applyTheme(isLightMode ? 'dark' : 'light'); // Toggle the theme
            });

            // Apply saved theme AND set initial button icon on load
            const savedTheme = localStorage.getItem(THEME_KEY);
            if (savedTheme === 'light') {
                 applyTheme('light'); // Applies theme AND sets icon
            } else {
                 applyTheme('dark'); // Applies theme AND sets icon (default)
            }

            // --- Display &amp; History Update Functions ---
            function updateDisplay() {
                 if (currentInput.length &gt; 16 &amp;&amp; !currentInput.toLowerCase().includes('error')) {
                    try { display.value = parseFloat(currentInput).toExponential(9); }
                    catch { display.value = "Error"; }
                 } else { display.value = currentInput; }
            }
            function updateHistoryDisplay() {
                 historyLog.innerHTML = '';
                 const reversedHistory = history.slice().reverse();
                 reversedHistory.forEach(entry =&gt; {
                    const li = document.createElement('li'); li.textContent = entry; historyLog.appendChild(li);
                 });
                 historyLog.scrollTop = 0;
            }
            function addToHistory(calcString) {
                 history.push(calcString);
                 if (history.length &gt; MAX_HISTORY_LENGTH) { history.shift(); }
                 updateHistoryDisplay();
            }

             // --- Core Calculator Logic ---
             function resetCalculator() {
                 currentInput = '0'; firstOperand = null; operator = null; shouldResetDisplay = false; updateDisplay();
             }
             function calculate() {
                 if (operator === null || firstOperand === null || shouldResetDisplay) { return; }
                 const first = parseFloat(firstOperand); const second = parseFloat(currentInput);
                 if (isNaN(first) || isNaN(second)) {
                    currentInput = "Error"; updateDisplay(); operator = null; firstOperand = null; shouldResetDisplay = true; return;
                 }
                 let result = 0; let calculationString = `${firstOperand} ${getDisplayOperator(operator)} ${currentInput}`;
                 switch (operator) {
                    case '+': result = first + second; break;
                    case '-': result = first - second; break;
                    case '*': result = first * second; break;
                    case '/':
                        if (second === 0) {
                            currentInput = "Error: Div by 0"; updateDisplay(); operator = null; firstOperand = null; shouldResetDisplay = true; return;
                        }
                        result = first / second; break;
                    default: return;
                 }
                 result = parseFloat(result.toPrecision(12));
                 calculationString += ` = ${result}`; addToHistory(calculationString);
                 currentInput = result.toString(); operator = null; firstOperand = null; shouldResetDisplay = true; updateDisplay();
             }
             function getDisplayOperator(op) { switch(op) { case '/': return '÷'; case '*': return '×'; default: return op; } }
             function handleNumber(num) {
                 if (shouldResetDisplay || currentInput.toLowerCase().includes("error")) {
                    currentInput = (num === '.') ? '0.' : num; shouldResetDisplay = false;
                 } else {
                    if (num === '.' &amp;&amp; currentInput.includes('.')) return; if (currentInput.length &gt;= 16) return;
                    currentInput = (currentInput === '0' &amp;&amp; num !== '.') ? num : currentInput + num;
                 }
                 updateDisplay();
             }
             function handleOperator(op) {
                 if (currentInput.toLowerCase().includes("error")) { return; }
                 if (operator !== null &amp;&amp; !shouldResetDisplay) {
                    calculate(); if (currentInput.toLowerCase().includes("error")) { return; }
                 }
                 if (!isNaN(parseFloat(currentInput))) { firstOperand = currentInput; }
                 else if (firstOperand === null) { return; }
                 operator = op; shouldResetDisplay = true;
             }
             function handleBackspace() {
                 if (shouldResetDisplay || currentInput.toLowerCase().includes("error")) return;
                 if (currentInput.length &gt; 1) { currentInput = currentInput.slice(0, -1); }
                 else if (currentInput !== '0') { currentInput = '0'; }
                 updateDisplay();
             }

            // --- Event Listeners (Buttons &amp; Keyboard) ---
            buttons.forEach(button =&gt; {
                button.addEventListener('click', () =&gt; {
                    const btn = button;
                    if (btn.classList.contains('btn-number')) { handleNumber(btn.dataset.num); }
                    else if (btn.classList.contains('btn-operator')) { handleOperator(btn.dataset.operator); }
                    else if (btn.id === 'equals') { calculate(); }
                    else if (btn.id === 'clear') { resetCalculator(); }
                });
            });
            document.addEventListener('keydown', (event) =&gt; {
                const key = event.key;
                let targetButton = document.querySelector(`.button[data-key="${key}"]`);
                if (key === 'Enter' &amp;&amp; !targetButton) targetButton = document.getElementById('equals');
                if (key === 'Escape' &amp;&amp; !targetButton) targetButton = document.getElementById('clear');
                if (key === '*' &amp;&amp; !targetButton) targetButton = document.querySelector('.button[data-key="*"]');
                if (key === '/' &amp;&amp; !targetButton) targetButton = document.querySelector('.button[data-key="/"]');

                if (!isNaN(parseInt(key)) &amp;&amp; key.length === 1) { handleNumber(key); }
                else if (key === '.') { handleNumber('.'); }
                else if (['+', '-', '*', '/'].includes(key)) { handleOperator(key); }
                else if (key === 'Enter' || key === '=') { event.preventDefault(); calculate(); targetButton = document.getElementById('equals'); }
                else if (key === 'Escape') { resetCalculator(); }
                else if (key === 'Backspace') { event.preventDefault(); handleBackspace(); }

                if (targetButton) {
                    targetButton.classList.add('active-key');
                    setTimeout(() =&gt; { targetButton.classList.remove('active-key'); }, 150);
                }
            });

            // --- Initialize ---
            updateDisplay(); // Show initial '0'
            updateHistoryDisplay(); // Show empty history initially
            // Initial theme/icon is set by the logic near the top now

        });
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Coin Toss - HEAD or TAIL</title><link>http://rajclick.blogspot.com/2025/03/coin-toss-head-or-tail.html</link><pubDate>Mon, 24 Mar 2025 01:25:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-2031748611019823168</guid><description>&lt;!-- START: Coin Toss Widget Code for Blogger --&gt;
&lt;div id="coinTossFeature" class="dark-mode"&gt;

  &lt;!-- Coin Toss Widget Container (Centered) --&gt;
  &lt;div class="widget-container"&gt;

    &lt;!-- Theme Switch Button --&gt;
    &lt;button id="themeToggleBtn" class="theme-button"&gt;Switch to Light Mode&lt;/button&gt;

    &lt;!-- Coin --&gt;
    &lt;div class="coin" id="coin"&gt;
      &lt;div class="coin-face coin-head"&gt;&lt;/div&gt;
      &lt;div class="coin-face coin-tail"&gt;&lt;/div&gt;
      &lt;div class="coin-overlay" id="coin-overlay"&gt;TOSS&lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Result Display --&gt;
    &lt;div class="result" id="result"&gt;Tap the coin to toss!&lt;/div&gt;

    &lt;!-- SEO Content --&gt;
    &lt;div class="seo-content"&gt;
      &lt;h2&gt;Realistic Silver Coin Toss Widget&lt;/h2&gt;
      &lt;p&gt;
        Add a touch of realism to your blog with this polished silver coin toss widget.
        Simply tap the coin to see it flip in 3D and land on HEAD or TAIL. This interactive
        feature is sure to engage your audience and add a bit of fun to any page.
      &lt;/p&gt;
      &lt;p&gt;
        Keywords: coin toss, silver coin, realistic coin flip, animated widget,
        interactive blog widget, decision maker, 3D flip, dark mode widget.
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;!-- End Coin Toss Widget Container --&gt;

  &lt;style&gt;
    /* Scoped styles for the coin toss feature */
    #coinTossFeature {
      /* Define CSS Variables for theming */
      --feature-bg: #222; /* Dark background */
      --widget-bg: #333;
      --text-color: #eee;
      --heading-color: #f0f0f0;
      --secondary-text-color: #bbb;
      --widget-shadow: rgba(255, 255, 255, 0.1);
      --coin-gradient-start: #555;
      --coin-gradient-mid: #777;
      --coin-gradient-end: #444;
      --coin-border: #666;
      --coin-shadow: rgba(0, 0, 0, 0.4);
      --coin-inset-shadow: rgba(0, 0, 0, 0.5);
      --coin-edge-gradient-start: #666;
      --coin-edge-gradient-mid: #888;
      --coin-edge-gradient-end: #666;
      --result-color: #66ff66; /* Light green for dark bg */
      --overlay-bg: rgba(0, 0, 0, 0.6);
      --overlay-text: #ffdd55; /* Brighter yellow */
      --button-bg: #555;
      --button-text: #eee;
      --button-border: #777;
      --button-hover-bg: #666;

      background-color: var(--feature-bg);
      color: var(--text-color);
      padding: 15px;
      border-radius: 8px;
      margin: 1em 0; /* Add some space around the feature */
      box-sizing: border-box;
      font-family: Arial, sans-serif;
      user-select: none; /* Prevent text selection */
    }

    /* Light Mode Variable Overrides */
    #coinTossFeature:not(.dark-mode) {
      --feature-bg: #f4f4f4; /* Light background */
      --widget-bg: #fff;
      --text-color: #333;
      --heading-color: #333;
      --secondary-text-color: #555;
      --widget-shadow: rgba(0, 0, 0, 0.15);
      --coin-gradient-start: #e7e7e7;
      --coin-gradient-mid: #bdbdbd;
      --coin-gradient-end: #888;
      --coin-border: #ccc;
      --coin-shadow: rgba(0, 0, 0, 0.1);
      --coin-inset-shadow: rgba(0, 0, 0, 0.2);
      --coin-edge-gradient-start: #999;
      --coin-edge-gradient-mid: #ccc;
      --coin-edge-gradient-end: #999;
      --result-color: #4caf50; /* Original green */
      --overlay-bg: rgba(0, 0, 0, 0.4);
      --overlay-text: #ffcc00; /* Original yellow */
      --button-bg: #eee;
      --button-text: #333;
      --button-border: #ccc;
      --button-hover-bg: #ddd;
    }

    /* Center the widget container */
    #coinTossFeature .widget-container {
      background: var(--widget-bg);
      padding: 20px; /* Reduced padding slightly */
      border-radius: 10px;
      box-shadow: 0 3px 10px var(--widget-shadow);
      text-align: center;
      max-width: 400px; /* Max width */
      width: 90%; /* Responsive width */
      margin: 20px auto; /* Center horizontally, add vertical spacing */
      perspective: 1000px; /* 3D flip effect */
      box-sizing: border-box;
    }

    /* Coin Styles */
    #coinTossFeature .coin {
      width: 140px;
      height: 140px;
      margin: 15px auto; /* Center coin and add spacing */
      position: relative;
      transform-style: preserve-3d;
      transition: transform 3s cubic-bezier(0.25, 1, 0.5, 1); /* Smoother easing */
      cursor: pointer;
    }

    #coinTossFeature .coin-face {
      position: absolute;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      backface-visibility: hidden;
      background: radial-gradient(circle at 30% 30%, var(--coin-gradient-start) 0%, var(--coin-gradient-mid) 40%, var(--coin-gradient-end) 100%);
      border: 2px solid var(--coin-border);
      box-shadow: 0 0 8px var(--coin-shadow), inset 0 0 5px var(--coin-inset-shadow);
      font-size: 1.8em; /* Make HEAD/TAIL text slightly larger if needed */
      font-weight: bold;
      color: var(--text-color); /* Text color based on theme */
    }

    /* Optional: Add explicit text if desired */
    /* #coinTossFeature .coin-head::after { content: "H"; } */
    /* #coinTossFeature .coin-tail::after { content: "T"; } */

    #coinTossFeature .coin-head { transform: rotateY(0deg); }
    #coinTossFeature .coin-tail { transform: rotateY(180deg); }

    /* Coin Edge Effect */
    #coinTossFeature .coin::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background: linear-gradient(90deg, var(--coin-edge-gradient-start), var(--coin-edge-gradient-mid), var(--coin-edge-gradient-end));
      transform: translateZ(-5px); /* Adjust thickness */
      z-index: -1;
    }

    /* Overlay Text */
    #coinTossFeature .coin-overlay {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 1.4rem;
      font-weight: bold;
      color: var(--overlay-text);
      background: var(--overlay-bg);
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
      pointer-events: none; /* Allows clicks to pass through to the coin */
      z-index: 5; /* Ensure it's above coin faces */
    }

    /* Result Display */
    #coinTossFeature .result {
      margin-top: 15px;
      font-size: 1.3rem;
      font-weight: bold;
      color: var(--result-color);
      min-height: 1.5em;
      transition: color 0.3s ease;
    }

    /* SEO Content */
    #coinTossFeature .seo-content {
      margin-top: 30px;
      font-size: 0.9rem;
      color: var(--secondary-text-color);
      text-align: left; /* Keep text left-aligned */
      max-width: 100%; /* Allow it to fill container width */
    }

    #coinTossFeature .seo-content h2 {
      margin-bottom: 10px;
      font-size: 1.2rem;
      color: var(--heading-color);
    }

    /* Theme Toggle Button */
    #coinTossFeature .theme-button {
      background-color: var(--button-bg);
      color: var(--button-text);
      border: 1px solid var(--button-border);
      padding: 8px 15px;
      border-radius: 5px;
      cursor: pointer;
      font-size: 0.9rem;
      transition: background-color 0.3s ease, color 0.3s ease;
      display: inline-block; /* Allows centering via text-align */
      margin-bottom: 15px; /* Space below button */
    }

    #coinTossFeature .theme-button:hover {
      background-color: var(--button-hover-bg);
    }

  &lt;/style&gt;

  &lt;script&gt;
    // Wrap script in a function to avoid global scope pollution
    (function() {
      // Select elements within the specific feature container
      const featureContainer = document.getElementById('coinTossFeature');
      if (!featureContainer) return; // Exit if container not found

      const coin = featureContainer.querySelector('#coin');
      const overlay = featureContainer.querySelector('#coin-overlay');
      const resultText = featureContainer.querySelector('#result');
      const themeToggleBtn = featureContainer.querySelector('#themeToggleBtn');

      let isAnimating = false;
      let currentRotation = 0;

      // Coin Toss Logic
      if (coin &amp;&amp; overlay &amp;&amp; resultText) {
        coin.addEventListener('click', () =&gt; {
          if (isAnimating) return;
          isAnimating = true;

          // Hide overlay smoothly (optional)
           if(overlay) overlay.style.opacity = '0';


          // Random outcome
          const isHead = Math.random() &lt; 0.5;
          // More spins for better visual effect
          const spins = Math.floor(Math.random() * 4) + 5; // Random spins between 5 and 8
          // Ensure landing is exactly on 0 or 180 degrees relative to spins
          const landingAngle = isHead ? 0 : 180;
          const totalRotation = (spins * 360) + landingAngle;

          // Update the current rotation state - important for subsequent flips
          currentRotation = totalRotation;

          // Animate coin flip
          // Use requestAnimationFrame for smoother rendering if possible,
          // but direct style change works fine here too.
          coin.style.transform = `rotateY(${currentRotation}deg)`;

          // Clear previous result immediately
          resultText.textContent = 'Flipping...';
           resultText.style.color = 'var(--secondary-text-color)'; // Use secondary color while flipping


          // Update result text after animation completes
          setTimeout(() =&gt; {
            resultText.textContent = isHead ? 'Result: HEAD' : 'Result: TAIL';
            resultText.style.color = 'var(--result-color)'; // Restore result color
            isAnimating = false;
             // Optionally hide overlay permanently after first toss
             if(overlay) overlay.style.display = 'none';
          }, 3000); // Match CSS transition duration (3s)
        });
      } else {
        console.error("Coin toss elements not found within #coinTossFeature");
      }

      // Theme Toggle Logic
      if (themeToggleBtn &amp;&amp; featureContainer) {
        // Set initial button text based on default mode (dark)
        themeToggleBtn.textContent = 'Switch to Light Mode';

        themeToggleBtn.addEventListener('click', () =&gt; {
          featureContainer.classList.toggle('dark-mode');
          const isDarkMode = featureContainer.classList.contains('dark-mode');
          themeToggleBtn.textContent = isDarkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode';
        });
      } else {
         console.error("Theme toggle button or feature container not found.");
      }

    })(); // Immediately invoke the function
  &lt;/script&gt;

&lt;/div&gt;
&lt;!-- END: Coin Toss Widget Code for Blogger --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Mileage Calculator</title><link>http://rajclick.blogspot.com/2025/03/mileage-calculator.html</link><category>Calculator App</category><pubDate>Sun, 23 Mar 2025 23:31:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-1635163810376764414</guid><description>&lt;!-- Start of Mileage Calculator Code for Blogger --&gt;
&lt;div id="mileageCalculatorWrapper"&gt;

  &lt;!-- ====== CSS STYLES ====== --&gt;
  &lt;style&gt;
    /* Apply base styles to the wrapper */
    #mileageCalculatorWrapper {
      --bg-dark: #1e1e1e; /* Slightly lighter than pure black for container */
      --text-dark: #e0e0e0;
      --container-bg-dark: #2a2a2a; /* Different shade for inner container */
      --border-dark: #555;
      --input-bg-dark: #333;
      --shadow-dark: rgba(255, 255, 255, 0.1);
      --placeholder-dark: #888;

      --bg-light: #ffffff; /* White background for wrapper in light mode */
      --text-light: #333;
      --container-bg-light: #f8f9fa; /* Light grey for inner container */
      --border-light: #ccc;
      --input-bg-light: #fff;
      --shadow-light: rgba(0, 0, 0, 0.1);
      --placeholder-light: #999;

      --accent-green: #28a745;
      --accent-red: #dc3545;
      --text-on-accent: white;

      /* Default to Dark Mode Styles */
      background-color: var(--bg-dark);
      color: var(--text-dark);
      padding: 20px 10px; /* Padding for the whole wrapper */
      font-family: Arial, sans-serif;
      border-radius: 8px;
      margin: 20px 0; /* Add some space above/below the widget */
      transition: background-color 0.3s, color 0.3s;
      text-align: center; /* Center inline/block elements like the image */
    }

    /* Light Mode Styles for the Wrapper */
    #mileageCalculatorWrapper.light-mode {
      background: var(--bg-light);
      color: var(--text-light);
    }

    /* Image Container */
    #mileageCalculatorWrapper .image-container {
      display: block;
      padding: 1em 0;
      margin-bottom: 20px;
      max-width: 320px; /* Limit image container width */
      margin-left: auto; /* Center block */
      margin-right: auto; /* Center block */
    }

    #mileageCalculatorWrapper .image-container img {
      max-width: 100%;
      height: auto;
      border: 0;
      display: inline-block; /* Allows text-align center to work */
    }

    /* Calculator Container */
    #mileageCalculatorWrapper .calculator-container {
      background: var(--container-bg-dark);
      border-radius: 8px;
      padding: 20px;
      box-shadow: 0 2px 5px var(--shadow-dark);
      width: 90%;
      max-width: 320px;
      margin: 20px auto 0 auto; /* Center horizontally, add top margin */
      text-align: left; /* Reset text align for form elements */
      transition: background-color 0.3s, box-shadow 0.3s;
    }
    #mileageCalculatorWrapper.light-mode .calculator-container {
      background: var(--container-bg-light);
      box-shadow: 0 2px 5px var(--shadow-light);
    }

    #mileageCalculatorWrapper h2 {
      text-align: center;
      color: inherit;
      margin-bottom: 20px;
      font-size: 1.4em;
    }

    #mileageCalculatorWrapper label {
      display: block;
      margin-top: 10px;
      color: inherit;
      font-size: 0.9em;
      font-weight: bold;
    }

    #mileageCalculatorWrapper input[type="number"] {
      width: calc(100% - 18px);
      padding: 8px;
      margin-top: 5px;
      border: 1px solid var(--border-dark);
      border-radius: 4px;
      background: var(--input-bg-dark);
      color: var(--text-dark);
      transition: background-color 0.3s, color 0.3s, border-color 0.3s;
      box-sizing: border-box;
    }
    #mileageCalculatorWrapper input[type="number"]::placeholder {
        color: var(--placeholder-dark);
        opacity: 0.7;
    }
    #mileageCalculatorWrapper.light-mode input[type="number"] {
      border: 1px solid var(--border-light);
      background: var(--input-bg-light);
      color: var(--text-light);
    }
    #mileageCalculatorWrapper.light-mode input[type="number"]::placeholder {
        color: var(--placeholder-light);
         opacity: 0.7;
    }

    #mileageCalculatorWrapper button {
      width: 48%;
      padding: 10px;
      margin-top: 20px; /* More space above buttons */
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-weight: bold;
      color: var(--text-on-accent);
      transition: background-color 0.2s, opacity 0.2s;
    }

    #mileageCalculatorWrapper #calculateBtn {
      background: var(--accent-green);
      float: left;
    }
    #mileageCalculatorWrapper #calculateBtn:hover {
        opacity: 0.9;
    }

    #mileageCalculatorWrapper #resetBtn {
      background: var(--accent-red);
      float: right;
    }
    #mileageCalculatorWrapper #resetBtn:hover {
        opacity: 0.9;
    }

    /* Result Area */
    #mileageCalculatorWrapper .result {
      margin-top: 70px; /* Increased space needed due to floated buttons */
      text-align: center;
      font-size: 1em; /* Adjusted size */
      font-weight: bold;
      color: inherit;
      clear: both;
      padding-top: 15px;
      min-height: 45px; /* Ensure space */
      line-height: 1.5;
    }

    /* SEO Content Area */
    #mileageCalculatorWrapper .seo-content {
      max-width: 600px;
      margin: 40px auto 20px auto;
      padding: 0 15px 10px 15px; /* Adjusted padding */
      font-size: 0.9em; /* Slightly smaller */
      line-height: 1.6;
      color: inherit;
      text-align: justify;
      width: 90%;
    }

    #mileageCalculatorWrapper .seo-content h3 {
      text-align: center;
      color: inherit;
      margin-bottom: 15px;
    }
    #mileageCalculatorWrapper .seo-content p {
        margin-bottom: 10px; /* Space between paragraphs */
    }

    /* Theme Toggle Button Styling */
    #mileageCalculatorWrapper #themeToggleBtn {
      display: inline-block; /* Allows centering via text-align */
      margin: 0 auto 20px auto; /* Center and add space below */
      padding: 8px 15px;
      background-color: #444; /* Consistent button style */
      color: white;
      border: 1px solid #666;
      border-radius: 20px;
      cursor: pointer;
      font-size: 0.85em;
      font-weight: normal; /* Override default button bold */
      transition: background-color 0.3s, color 0.3s, border-color 0.3s;
      float: none; /* Ensure it's not floated */
      width: auto; /* Fit content */
    }
    #mileageCalculatorWrapper.light-mode #themeToggleBtn {
      background-color: #eee;
      color: #333;
      border: 1px solid #ccc;
    }
    #mileageCalculatorWrapper #themeToggleBtn:hover {
      opacity: 0.8;
    }

    /* Clearfix for button container if needed, though result clear should handle it */
    #mileageCalculatorWrapper .calculator-container::after {
      content: "";
      display: table;
      clear: both;
    }
  &lt;/style&gt;
  &lt;!-- ====== END CSS STYLES ====== --&gt;


  &lt;!-- ====== HTML CONTENT ====== --&gt;

  &lt;!-- Theme Toggle Button (Static placement) --&gt;
  &lt;button id="themeToggleBtn"&gt;Switch Theme&lt;/button&gt;

  &lt;!-- Calculator Form --&gt;
  &lt;div class="calculator-container"&gt;
    &lt;h2&gt;Mileage Calculator&lt;/h2&gt;
    &lt;label for="distance"&gt;Total Travelled Distance (km):&lt;/label&gt;
    &lt;input type="number" id="distance" placeholder="e.g., 350" step="any" inputmode="decimal" /&gt;

    &lt;label for="petrolPrice"&gt;Petrol Price per Liter:&lt;/label&gt;
    &lt;input type="number" id="petrolPrice" placeholder="e.g., 1.50" step="any" inputmode="decimal" /&gt;

    &lt;label for="mileage"&gt;Mileage of Car (km/l):&lt;/label&gt;
    &lt;input type="number" id="mileage" placeholder="e.g., 15" step="any" inputmode="decimal" /&gt;

    &lt;button id="calculateBtn"&gt;Calculate&lt;/button&gt;
    &lt;button id="resetBtn"&gt;Reset&lt;/button&gt;

    &lt;div class="result" id="result"&gt;&lt;/div&gt;
  &lt;/div&gt;

  &lt;!-- SEO Content Section --&gt;
  &lt;div class="seo-content"&gt;
    &lt;h3&gt;About Our Mileage Calculator&lt;/h3&gt;
    &lt;p&gt;
      This mileage calculator helps you easily estimate the fuel required for your trip and its cost. Enter the total distance, current petrol price per liter, and your vehicle's fuel efficiency (mileage in km/l) for instant results.
    &lt;/p&gt;
    &lt;p&gt;
      Keywords: Mileage Calculator, Fuel Calculator, Fuel Cost, Car Mileage, Travel Expenses, Petrol Price India, Bike Mileage Calculator, Fuel Consumption.
    &lt;/p&gt;
  &lt;/div&gt;
  &lt;!-- ====== END HTML CONTENT ====== --&gt;


  &lt;!-- ====== JAVASCRIPT ====== --&gt;
  &lt;script&gt;
    // Wrap script logic in a function to avoid global scope pollution
    (function() {
      // Select elements *within* the wrapper
      const wrapper = document.getElementById('mileageCalculatorWrapper');
      if (!wrapper) return; // Exit if wrapper not found

      const themeToggleBtn = wrapper.querySelector('#themeToggleBtn');
      const calculateBtn = wrapper.querySelector('#calculateBtn');
      const resetBtn = wrapper.querySelector('#resetBtn');
      const distanceInput = wrapper.querySelector('#distance');
      const petrolPriceInput = wrapper.querySelector('#petrolPrice');
      const mileageInput = wrapper.querySelector('#mileage');
      const resultDiv = wrapper.querySelector('#result');

      // Function to set the theme
      function setTheme(theme) {
        if (theme === 'light') {
          wrapper.classList.add('light-mode');
          themeToggleBtn.textContent = 'Switch to Dark Mode';
        } else {
          wrapper.classList.remove('light-mode');
          themeToggleBtn.textContent = 'Switch to Light Mode';
        }
        // Use localStorage to remember the theme preference
        try {
           localStorage.setItem('mileageCalcTheme', theme);
        } catch (e) {
           console.warn("LocalStorage is not available. Theme preference won't be saved.");
        }
      }

      // --- Event Listeners ---

      // Theme Toggle Button Click
      if (themeToggleBtn) {
          themeToggleBtn.addEventListener('click', () =&gt; {
            const isLight = wrapper.classList.contains('light-mode');
            setTheme(isLight ? 'dark' : 'light');
          });
      }

      // Calculate Button Click
      if (calculateBtn) {
          calculateBtn.addEventListener('click', function() {
            const distance = parseFloat(distanceInput.value);
            const petrolPrice = parseFloat(petrolPriceInput.value);
            const mileage = parseFloat(mileageInput.value);

            // Input validation
            if(isNaN(distance) || distance &lt;= 0 || isNaN(petrolPrice) || petrolPrice &lt;= 0 || isNaN(mileage) || mileage &lt;= 0) {
              resultDiv.innerHTML = "Please enter valid positive numbers for all fields.";
              return;
            }

            // Calculation
            const fuelNeeded = distance / mileage;
            const totalCost = fuelNeeded * petrolPrice;

            // Display result (using template literals for cleaner formatting)
            resultDiv.innerHTML = `Fuel Needed: ${fuelNeeded.toFixed(2)} liters&lt;br&gt;Total Cost: ${totalCost.toFixed(2)}`;
          });
      }

      // Reset Button Click
      if (resetBtn) {
          resetBtn.addEventListener('click', function() {
            distanceInput.value = "";
            petrolPriceInput.value = "";
            mileageInput.value = "";
            resultDiv.innerHTML = ""; // Clear result display
          });
      }

      // --- Initial Setup ---

      // Apply saved theme on load or default to dark
      let savedTheme = 'dark'; // Default theme
      try {
          savedTheme = localStorage.getItem('mileageCalcTheme') || 'dark';
      } catch (e) {
          // LocalStorage might be disabled or unavailable
          console.warn("LocalStorage is not available. Defaulting to dark theme.");
      }
      setTheme(savedTheme);

    })(); // Immediately invoke the function expression
  &lt;/script&gt;
  &lt;!-- ====== END JAVASCRIPT ====== --&gt;

&lt;/div&gt;
&lt;!-- End of Mileage Calculator Code for Blogger --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Days, Months, Weeks, Years Calculator</title><link>http://rajclick.blogspot.com/2025/03/days-months-weeks-years-calculator.html</link><category>Calculator App</category><pubDate>Mon, 17 Mar 2025 11:26:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-4667331844818785231</guid><description>&lt;!-- Start: Date Duration Calculator Widget --&gt;
&lt;style&gt;
/* Encapsulated styles for the Date Calculator Widget */
#date-calculator-widget {
  /* --- Base Styles &amp; Light Theme Variables --- */
  --dc-primary-color: #1976d2;
  --dc-primary-light: #e3f2fd;
  --dc-primary-dark: #0d47a1;
  --dc-text-color: #333;
  --dc-light-text-color: #555;
  --dc-container-bg: #ffffff;
  --dc-border-color: #bdbdbd;
  --dc-input-bg: #ffffff;
  --dc-input-border: #bdbdbd;
  --dc-focus-ring-color: rgba(25, 118, 210, 0.2);
  --dc-error-color: #d32f2f;
  --dc-hr-color: #e0e0e0;
  --dc-button-bg: #f0f0f0;
  --dc-button-text: #333;
  --dc-button-hover-bg: #d5d5d5;
  --dc-invert-value: 0;

  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background: var(--dc-container-bg);
  color: var(--dc-text-color);
  padding: 1.5rem 1rem;
  border-radius: 8px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 450px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  line-height: 1.6;
  box-sizing: border-box;
  transition: background-color 0.3s ease, color 0.3s ease;
}

/* --- Dark Theme Variable Overrides --- */
#date-calculator-widget[data-theme="dark"] {
  --dc-primary-color: #64b5f6;
  --dc-primary-light: #2a3b47;
  --dc-primary-dark: #bbdefb;
  --dc-text-color: #e0e0e0;
  --dc-light-text-color: #bdbdbd;
  --dc-container-bg: #212121;
  --dc-border-color: #424242;
  --dc-input-bg: #333333;
  --dc-input-border: #555555;
  --dc-focus-ring-color: rgba(100, 181, 246, 0.2);
  --dc-error-color: #ef9a9a;
  --dc-hr-color: #424242;
  --dc-button-bg: #424242; /* Dark mode button bg */
  --dc-button-text: #e0e0e0; /* Dark mode button text (emoji) color */
  --dc-button-hover-bg: #555555;
  --dc-invert-value: 1;
}

#date-calculator-widget *,
#date-calculator-widget *::before,
#date-calculator-widget *::after {
  box-sizing: inherit; margin: 0; padding: 0;
  transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

/* Widget Header Area */
#date-calculator-widget .widget-header {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 1.5rem; padding: 0 0.5rem;
}

/* Heading */
#date-calculator-widget h2 {
  color: var(--dc-primary-color); font-size: 1.3rem; padding: 0; margin: 0;
  text-align: left; flex-grow: 1;
}

/* Theme Toggle Button */
#date-calculator-widget .theme-toggle {
  width: 36px; height: 36px; font-size: 1.2rem; border-radius: 50%; cursor: pointer;
  display: inline-flex; justify-content: center; align-items: center;
  padding: 0; line-height: 1;
  background-color: var(--dc-button-bg, #f0f0f0);
  color: var(--dc-button-text, #333);
  border: 1px solid var(--dc-border-color, #bdbdbd);
  flex-shrink: 0; margin-left: 0.75rem;
  transition: background-color 0.3s ease, transform 0.2s ease, border-color 0.3s ease;
  opacity: 1; visibility: visible;
}
#date-calculator-widget .theme-toggle:hover,
#date-calculator-widget .theme-toggle:focus {
  background-color: var(--dc-button-hover-bg, #d5d5d5);
  outline: none; transform: scale(1.1);
}

/* FORCE DARK MODE BUTTON COLORS - NEW */
#date-calculator-widget[data-theme="dark"] .theme-toggle {
    background-color: var(--dc-button-bg) !important;
    color: var(--dc-button-text) !important;
    border-color: var(--dc-border-color) !important;
}


/* Form, Input, Result, Footer Styles (Keep as before) */
#date-calculator-widget .date-form { display: grid; gap: 1rem 0.5rem; margin-bottom: 1.5rem; text-align: left; }
#date-calculator-widget label { font-weight: 600; color: var(--dc-text-color); display: block; margin-bottom: 0.25rem; }
#date-calculator-widget input[type="date"] { width: 100%; padding: 0.6rem; border: 1px solid var(--dc-input-border); border-radius: 4px; font-size: 1rem; text-align: center; appearance: none; background-color: var(--dc-input-bg); color: var(--dc-text-color); color-scheme: dark light; }
#date-calculator-widget input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(var(--dc-invert-value)); cursor: pointer; }
#date-calculator-widget input[type="date"]:focus { outline: none; border-color: var(--dc-primary-color); box-shadow: 0 0 0 3px var(--dc-focus-ring-color); }
#date-calculator-widget .result { margin-top: 1rem; padding: 1rem; background-color: var(--dc-primary-light); border-radius: 4px; border-left: 5px solid var(--dc-primary-color); text-align: left; min-height: 50px; font-size: 1rem; color: var(--dc-primary-dark); }
#date-calculator-widget .result p { margin-bottom: 0.5rem; color: var(--dc-text-color); }
#date-calculator-widget .result p:first-child { color: var(--dc-primary-dark); font-weight: bold; }
#date-calculator-widget .result p:last-child { margin-bottom: 0; }
#date-calculator-widget .result strong { display: inline-block; min-width: 60px; color: var(--dc-text-color); font-weight: bold; }
#date-calculator-widget .result p strong:first-child { font-weight: normal; color: var(--dc-light-text-color); }
#date-calculator-widget .result p:first-child strong { min-width: auto; font-weight: bold; color: var(--dc-primary-dark); }
#date-calculator-widget .result .error { color: var(--dc-error-color); font-weight: bold; background-color: transparent; }
#date-calculator-widget .result hr { border: none; border-top: 1px solid var(--dc-hr-color); margin: 10px 0; }
#date-calculator-widget footer { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--dc-border-color); font-size: 0.875rem; color: var(--dc-light-text-color); text-align: center; }
#date-calculator-widget footer p { margin-bottom: 0.5rem; }
#date-calculator-widget footer strong { color: var(--dc-text-color); }

&lt;/style&gt;

&lt;!-- HTML Structure (Unchanged) --&gt;
&lt;div id="date-calculator-widget"&gt;
    &lt;div class="widget-header"&gt;
        &lt;h2&gt;Date Duration Calculator&lt;/h2&gt;
        &lt;button id="dc-theme-toggle" class="theme-toggle" aria-label="Switch Theme"&gt;&lt;/button&gt;
    &lt;/div&gt;
    &lt;form class="date-form" onsubmit="return false;"&gt;
        &lt;div&gt;&lt;label for="dc-fromDate"&gt;From Date:&lt;/label&gt;&lt;input type="date" id="dc-fromDate"&gt;&lt;/div&gt;
        &lt;div&gt;&lt;label for="dc-toDate"&gt;To Date:&lt;/label&gt;&lt;input type="date" id="dc-toDate"&gt;&lt;/div&gt;
    &lt;/form&gt;
    &lt;div class="result" id="dc-result" aria-live="polite"&gt;Select both dates to see the duration.&lt;/div&gt;
    &lt;footer&gt;
        &lt;p&gt;&lt;strong&gt;Why Use This Calculator?&lt;/strong&gt;&lt;/p&gt;
        &lt;p&gt;Easily find the exact duration between two dates, broken down into years, months, days, and total days/weeks.&lt;/p&gt;
    &lt;/footer&gt;
&lt;/div&gt;

&lt;!-- JavaScript (MODIFIED EMOJIS TO TEXT) --&gt;
&lt;script&gt;
(function() {
    // console.log("DC Widget Script: Starting execution.");
    const widget = document.getElementById("date-calculator-widget");
    if (!widget || widget.dataset.initialized) { return; }
    widget.dataset.initialized = "true";
    // console.log("DC Widget Script: Widget container found and marked as initialized.");

    const fromDateInput = document.getElementById("dc-fromDate");
    const toDateInput = document.getElementById("dc-toDate");
    const resultDiv = document.getElementById("dc-result");
    const themeToggleButton = document.getElementById("dc-theme-toggle");

    if (!themeToggleButton) { console.error("DC Widget Script: Theme toggle button (#dc-theme-toggle) NOT FOUND!"); }
    // else { console.log("DC Widget Script: Theme toggle button (#dc-theme-toggle) FOUND."); }

    // --- Theme Switching ---
    function setTheme(theme) {
        if(!widget) return;
        // console.log("DC Widget Script: Setting theme to:", theme);
        widget.setAttribute('data-theme', theme);
        localStorage.setItem('dc-theme', theme);

        if (themeToggleButton) {
            if (theme === 'dark') {
                themeToggleButton.textContent = 'L'; // Use 'L' for Light mode switch (visible in dark)
                themeToggleButton.setAttribute('aria-label', 'Switch to Light Mode');
            } else {
                themeToggleButton.textContent = 'D'; // Use 'D' for Dark mode switch (visible in light)
                themeToggleButton.setAttribute('aria-label', 'Switch to Dark Mode');
            }
            // console.log("DC Widget Script: Theme button icon/label updated.");
        }
        // else { console.warn("DC Widget Script: Cannot update theme button icon - button not found."); }
    }

    if (themeToggleButton) {
       // console.log("DC Widget Script: Adding click listener to theme button.");
       themeToggleButton.addEventListener('click', () =&gt; {
          // console.log("DC Widget Script: Theme button clicked!");
          const currentTheme = widget.getAttribute('data-theme') || 'dark';
          const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
          setTheme(newTheme);
       });
    }
    // else { console.warn("DC Widget Script: Cannot add click listener - theme button not found."); }

    // --- Date Calculation Logic (Unchanged) ---
    function daysInMonth(year, month) { return new Date(year, month + 1, 0).getDate(); }
    function calculateDuration() { /* ... same calculation logic as before ... */ if (!fromDateInput || !toDateInput || !resultDiv) return; const fromDateValue = fromDateInput.value; const toDateValue = toDateInput.value; resultDiv.classList.remove('error'); const existingError = resultDiv.querySelector('p.error'); if (existingError) resultDiv.innerHTML = 'Select both dates to see the duration.'; if (!fromDateValue || !toDateValue) { resultDiv.textContent = "Please select both a 'From' and 'To' date."; return; } const fromDate = new Date(fromDateValue + 'T00:00:00Z'); const toDate = new Date(toDateValue + 'T00:00:00Z'); if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) { resultDiv.innerHTML = '&lt;p class="error"&gt;Invalid date format selected.&lt;/p&gt;'; resultDiv.classList.add('error'); return; } if (toDate &lt; fromDate) { resultDiv.innerHTML = '&lt;p class="error"&gt;"To" date cannot be earlier than "From" date.&lt;/p&gt;'; resultDiv.classList.add('error'); return; } const timeDifference = toDate.getTime() - fromDate.getTime(); const totalDays = Math.round(timeDifference / (1000 * 60 * 60 * 24)); const totalWeeks = Math.floor(totalDays / 7); const remainingDaysAfterWeeks = totalDays % 7; let years = toDate.getUTCFullYear() - fromDate.getUTCFullYear(); let months = toDate.getUTCMonth() - fromDate.getUTCMonth(); let days = toDate.getUTCDate() - fromDate.getUTCDate(); if (days &lt; 0) { months--; const prevMonth = toDate.getUTCMonth() === 0 ? 11 : toDate.getUTCMonth() - 1; const yearOfPrevMonth = prevMonth === 11 ? toDate.getUTCFullYear() - 1 : toDate.getUTCFullYear(); days += daysInMonth(yearOfPrevMonth, prevMonth); } if (months &lt; 0) { years--; months += 12; } let resultHTML = `&lt;p&gt;&lt;strong&gt;Duration:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;${years} year${years !== 1 ? 's' : ''}, ${months} month${months !== 1 ? 's' : ''}, ${days} day${days !== 1 ? 's' : ''}&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;strong&gt;Total Days:&lt;/strong&gt; &lt;strong&gt;${totalDays}&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Total Weeks:&lt;/strong&gt; &lt;strong&gt;${totalWeeks}&lt;/strong&gt; weeks and &lt;strong&gt;${remainingDaysAfterWeeks}&lt;/strong&gt; day${remainingDaysAfterWeeks !== 1 ? 's' : ''}&lt;/p&gt;`; resultDiv.innerHTML = resultHTML; }

    if (fromDateInput) { /* console.log("DC Widget Script: Adding input listener to From date."); */ fromDateInput.addEventListener("input", calculateDuration); }
    if (toDateInput) { /* console.log("DC Widget Script: Adding input listener to To date."); */ toDateInput.addEventListener("input", calculateDuration); }

    // --- Initialization ---
    // console.log("DC Widget Script: Performing initial theme setup.");
    const savedTheme = localStorage.getItem('dc-theme') || 'dark';
    setTheme(savedTheme);
    // console.log("DC Widget Script: Initialization complete.");
})();
&lt;/script&gt;
&lt;!-- End: Date Duration Calculator Widget --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Random Password Generator</title><link>http://rajclick.blogspot.com/2025/03/random-password-generator.html</link><category>Calculator App</category><pubDate>Mon, 17 Mar 2025 11:13:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-1484483848568844139</guid><description>&lt;!-- START: Complete Self-Contained Password Generator Block --&gt;

&lt;!-- Main container for the tool with a unique ID for scoping --&gt;
&lt;div id="post-password-generator"&gt;

    &lt;!-- START: Generator-Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles to this container */
        #post-password-generator {
            /* --- CSS Variables for Theming (Default: Dark) --- */
            --pg-bg-color: #2a2a2a;
            --pg-text-color: #e0e0e0;
            --pg-heading-color: #79baff;
            --pg-border-color: #444;
            --pg-input-bg: #333;
            --pg-input-border: #555;
            --pg-input-text: #e0e0e0;
            --pg-output-bg: #1e1e1e; /* Darker background for output */
            --pg-output-text: #a6d1ff; /* Light blue for password */
            --pg-button-primary-bg: #00796b; /* Green generate */
            --pg-button-primary-hover: #005a4f;
            --pg-button-secondary-bg: #4f5b62; /* Grey copy/options */
            --pg-button-secondary-hover: #3b444a;
            --pg-button-text: #ffffff;
            --pg-label-color: #b0b0b0; /* Lighter label color */
            --pg-copy-success-color: #2e7d32; /* Success green */
            --pg-shadow-color: rgba(0, 0, 0, 0.3);
            --pg-explanation-text: #b0b0b0;

            /* Base styles */
            font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--pg-bg-color);
            color: var(--pg-text-color);
            padding: 25px 30px; /* Adjusted padding */
            border-radius: 10px;
            box-shadow: 0 5px 15px var(--pg-shadow-color);
            width: 100%;
            max-width: 650px; /* Wider for options */
            margin: 25px auto; /* Center block */
            border: 1px solid var(--pg-border-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            box-sizing: border-box;
            text-align: center;
        }
        #post-password-generator *,
        #post-password-generator *::before,
        #post-password-generator *::after {
            box-sizing: border-box;
        }

        /* --- Light Mode Overrides --- */
        #post-password-generator.pg-light-mode {
            --pg-bg-color: #ffffff;
            --pg-text-color: #333;
            --pg-heading-color: #0a6ed1;
            --pg-border-color: #ddd;
            --pg-input-bg: #f8f9fa;
            --pg-input-border: #ccc;
            --pg-input-text: #333;
            --pg-output-bg: #e9ecef; /* Light grey output bg */
            --pg-output-text: #0b7dda; /* Blue password */
            --pg-button-primary-bg: #28a745;
            --pg-button-primary-hover: #218838;
            --pg-button-secondary-bg: #6c757d;
            --pg-button-secondary-hover: #5a6268;
            --pg-label-color: #555;
            --pg-copy-success-color: #198754;
            --pg-shadow-color: rgba(0, 0, 0, 0.1);
            --pg-explanation-text: #555;
        }

        /* --- Element Styles (Scoped) --- */
        #post-password-generator h2 {
            margin-top: 0;
            margin-bottom: 15px;
            color: var(--pg-heading-color);
            font-size: 1.8rem;
        }

        /* Theme Switch */
         #post-password-generator .theme-switch-wrapper {
            text-align: right; margin-bottom: 20px; padding-right: 5px;
         }
         #post-password-generator #pgThemeSwitch {
            padding: 6px 12px; cursor: pointer; border-radius: 5px;
            border: 1px solid var(--pg-input-border);
            background-color: var(--pg-input-bg); color: var(--pg-text-color);
            font-weight: bold; font-size: 0.85em; transition: all 0.2s;
         }
         #post-password-generator #pgThemeSwitch:hover { opacity: 0.85; }

        /* Password Output Area */
        #post-password-generator .password-display-area {
            position: relative; /* For copy button positioning */
            margin-bottom: 20px;
        }
        #post-password-generator input#passwordOutput {
            width: 100%;
            padding: 15px 55px 15px 15px; /* Pad right for button */
            font-size: 1.4rem; /* Larger password font */
            font-family: 'Courier New', Courier, monospace;
            border: 1px solid var(--pg-border-color);
            background-color: var(--pg-output-bg);
            color: var(--pg-output-text);
            border-radius: 8px;
            text-align: center;
            letter-spacing: 1px;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            /* Prevent user selection, copying done via button/JS */
            user-select: none;
            cursor: default; /* Indicate it's not directly editable */
        }
        #post-password-generator input#passwordOutput::placeholder {
             color: var(--pg-label-color);
             font-size: 1.1rem;
             font-style: italic;
             opacity: 0.7;
        }

        /* Copy Button */
        #post-password-generator button#copyBtn {
            position: absolute;
            right: 8px;
            top: 50%;
            transform: translateY(-50%);
            padding: 8px 10px;
            font-size: 0.9rem;
            background-color: var(--pg-button-secondary-bg);
            color: var(--pg-button-text);
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        #post-password-generator button#copyBtn:hover {
            background-color: var(--pg-button-secondary-hover);
        }
         /* Style for copy success message */
        #post-password-generator #copyMessage {
             display: block; /* Reserve space */
             height: 1.2em; /* Reserve space */
             margin-top: -10px; /* Pull up slightly */
             margin-bottom: 10px; /* Space below */
             font-size: 0.9em;
             color: var(--pg-copy-success-color);
             font-weight: bold;
             opacity: 0; /* Hidden by default */
             transition: opacity 0.3s ease-in-out;
        }
        #post-password-generator #copyMessage.visible {
             opacity: 1;
        }

        /* Options Area */
        #post-password-generator .options {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Responsive columns */
            gap: 15px 20px;
            margin-bottom: 25px;
            text-align: left;
             padding: 15px;
             border: 1px solid var(--pg-border-color);
             background-color: var(--pg-input-bg); /* Options background */
             border-radius: 8px;
        }
        #post-password-generator .option {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        #post-password-generator .option label {
            flex-grow: 1;
            color: var(--pg-label-color);
            font-size: 0.95rem;
            cursor: pointer; /* Make label clickable for checkbox */
        }
        #post-password-generator .option input[type="number"] {
            width: 60px;
            padding: 8px;
            text-align: center;
            border: 1px solid var(--pg-input-border);
            background-color: var(--pg-bg-color); /* Use main bg for input */
            color: var(--pg-input-text);
            border-radius: 4px;
            font-size: 0.95rem;
        }
         #post-password-generator .option input[type="number"]:focus {
            outline: none;
            border-color: var(--pg-heading-color);
         }

        #post-password-generator .option input[type="checkbox"] {
            transform: scale(1.2);
            cursor: pointer;
             accent-color: var(--pg-button-primary-bg); /* Checkbox color */
             flex-shrink: 0; /* Prevent shrinking */
        }

        /* Generate Button */
        #post-password-generator button#generateBtn {
            padding: 12px 30px;
            font-size: 1.1rem; /* Larger generate button */
            cursor: pointer;
            background: var(--pg-button-primary-bg);
            color: var(--pg-button-text);
            border: none;
            border-radius: 8px;
            transition: background-color 0.3s, transform 0.2s;
            display: block; /* Full width */
            width: 100%;
             margin-top: 10px; /* Space above */
        }
        #post-password-generator button#generateBtn:hover {
            background: var(--pg-button-primary-hover);
            transform: scale(1.02); /* Subtle grow effect */
        }

         /* Explanation Section */
        #post-password-generator .pg-explanation {
            margin-top: 30px; padding-top: 20px;
            border-top: 1px solid var(--pg-border-color);
            font-size: 0.9rem; line-height: 1.6;
            color: var(--pg-explanation-text); text-align: left;
        }
        #post-password-generator .pg-explanation h4 { margin-bottom: 10px; color: var(--pg-text-color); font-size: 1.1rem; }
        #post-password-generator .pg-explanation p { margin-bottom: 10px; }
        #post-password-generator .pg-explanation ul { margin-left: 20px; margin-bottom: 10px; }

    &lt;/style&gt;
    &lt;!-- END: Generator-Specific Styles --&gt;


    &lt;!-- START: Generator HTML --&gt;
    &lt;h2&gt;Password Generator&lt;/h2&gt;

    &lt;!-- Local Theme Switch --&gt;
     &lt;div class="theme-switch-wrapper"&gt;
        &lt;button id="pgThemeSwitch"&gt;Switch Theme&lt;/button&gt;
    &lt;/div&gt;

    &lt;!-- Password Display &amp; Copy --&gt;
    &lt;div class="password-display-area"&gt;
        &lt;input type="text" id="passwordOutput" placeholder="Generated password appears here..." readonly aria-label="Generated Password"&gt;
        &lt;button type="button" id="copyBtn" title="Copy Password"&gt;Copy&lt;/button&gt;
    &lt;/div&gt;
     &lt;span id="copyMessage"&gt;Copied!&lt;/span&gt; &lt;!-- Initially hidden via CSS opacity --&gt;

    &lt;!-- Options --&gt;
    &lt;div class="options"&gt;
        &lt;div class="option"&gt;
            &lt;label for="length"&gt;Password Length:&lt;/label&gt;
            &lt;input type="number" id="length" value="16" min="8" max="128"&gt;
        &lt;/div&gt;
        &lt;div class="option"&gt;
            &lt;input type="checkbox" id="includeUppercase" checked&gt;
            &lt;label for="includeUppercase"&gt;Include Uppercase (A-Z)&lt;/label&gt;
        &lt;/div&gt;
        &lt;div class="option"&gt;
            &lt;input type="checkbox" id="includeLowercase" checked&gt;
            &lt;label for="includeLowercase"&gt;Include Lowercase (a-z)&lt;/label&gt;
        &lt;/div&gt;
        &lt;div class="option"&gt;
            &lt;input type="checkbox" id="includeNumbers" checked&gt;
            &lt;label for="includeNumbers"&gt;Include Numbers (0-9)&lt;/label&gt;
        &lt;/div&gt;
        &lt;div class="option"&gt;
            &lt;input type="checkbox" id="includeSymbols" checked&gt;
            &lt;label for="includeSymbols"&gt;Include Symbols (!@#...)&lt;/label&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Generate Button --&gt;
    &lt;button type="button" id="generateBtn"&gt;Generate Password&lt;/button&gt;

     &lt;!-- SEO Explanation Section --&gt;
    &lt;div class="pg-explanation"&gt;
        &lt;h4&gt;About This Password Generator&lt;/h4&gt;
        &lt;p&gt;
            Create strong, secure, and random passwords instantly with this generator. Customize the length and character types to meet your specific security requirements.
        &lt;/p&gt;
        &lt;h4&gt;Features:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Customizable Length:&lt;/strong&gt; Choose a password length between 8 and 128 characters.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Character Sets:&lt;/strong&gt; Select whether to include uppercase letters, lowercase letters, numbers, and symbols.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Instant Generation:&lt;/strong&gt; Click "Generate Password" to create a new random password based on your criteria.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Auto-Copy:&lt;/strong&gt; The generated password is automatically copied to your clipboard for convenience.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Manual Copy:&lt;/strong&gt; A "Copy" button is also available next to the password display.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Visual Feedback:&lt;/strong&gt; A "Copied!" message appears briefly after generation or manual copy.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Theme Switch:&lt;/strong&gt; Toggle between dark and light modes.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;
            Using strong, unique passwords for different accounts is crucial for online security. This tool helps you generate complex passwords that are difficult to guess or crack.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;!-- END: Generator HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-password-generator Container --&gt;


&lt;!-- START: Generator Script (Scoped, Themed, Copy Functionality) --&gt;
&lt;script&gt;
    // Wrap in IIFE
    (function() {
        const generatorContainer = document.getElementById('post-password-generator');
        if (!generatorContainer) { console.error("Password Generator container not found!"); return; }

        // Scoped DOM selectors
        const $ = (selector) =&gt; generatorContainer.querySelector(selector);

        const passwordOutput = $('#passwordOutput');
        const generateBtn = $('#generateBtn');
        const copyBtn = $('#copyBtn');
        const copyMessage = $('#copyMessage');
        const lengthInput = $('#length');
        const includeUppercase = $('#includeUppercase');
        const includeLowercase = $('#includeLowercase');
        const includeNumbers = $('#includeNumbers');
        const includeSymbols = $('#includeSymbols');
        const themeSwitchBtn = $('#pgThemeSwitch');
        const localStorageThemeKey = 'passwordGenTheme'; // Unique key

        const uppercaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        const lowercaseChars = 'abcdefghijklmnopqrstuvwxyz';
        const numberChars = '0123456789';
        const symbolChars = '!@#$%^&amp;*()_+-=[]{}|;:,.&lt;&gt;/?';

        let copyTimeout; // Variable to store the timeout for hiding the copy message

        // --- Theme Switching ---
        function applyTheme(theme) {
            if (theme === 'light') {
                generatorContainer.classList.add('pg-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Dark Mode';
            } else {
                generatorContainer.classList.remove('pg-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Light Mode';
            }
            localStorage.setItem(localStorageThemeKey, theme);
        }

        if (themeSwitchBtn) {
            themeSwitchBtn.addEventListener('click', () =&gt; {
                const currentThemeIsLight = generatorContainer.classList.contains('pg-light-mode');
                applyTheme(currentThemeIsLight ? 'dark' : 'light');
            });
        }

        // --- Password Generation ---
        function generatePassword() {
            const length = parseInt(lengthInput.value);
            let characterPool = '';
            let password = '';

            if (includeUppercase.checked) characterPool += uppercaseChars;
            if (includeLowercase.checked) characterPool += lowercaseChars;
            if (includeNumbers.checked) characterPool += numberChars;
            if (includeSymbols.checked) characterPool += symbolChars;

            if (characterPool === '') {
                alert('Please select at least one character type!');
                passwordOutput.value = ''; // Clear output if no types selected
                passwordOutput.placeholder = 'Select character types below...';
                return; // Stop generation
            }
             if (length &lt; 8 || length &gt; 128 || isNaN(length)) {
                 alert('Please enter a valid length between 8 and 128.');
                 lengthInput.value = Math.max(8, Math.min(128, length || 16)); // Correct invalid length
                 return; // Stop generation until length is valid
             }

            // Ensure password contains at least one of each selected type (simple approach)
            let guaranteedChars = '';
            if (includeUppercase.checked) guaranteedChars += uppercaseChars[Math.floor(Math.random() * uppercaseChars.length)];
            if (includeLowercase.checked) guaranteedChars += lowercaseChars[Math.floor(Math.random() * lowercaseChars.length)];
            if (includeNumbers.checked) guaranteedChars += numberChars[Math.floor(Math.random() * numberChars.length)];
            if (includeSymbols.checked) guaranteedChars += symbolChars[Math.floor(Math.random() * symbolChars.length)];

             // Adjust length to ensure space for guaranteed chars if needed
            const remainingLength = length - guaranteedChars.length;
            if (remainingLength &lt; 0) {
                 // This should only happen if length is very small and many types are selected
                 // We'll just use the guaranteed chars truncated to the desired length
                 password = guaranteedChars.substring(0, length);
            } else {
                 // Generate remaining characters
                 for (let i = 0; i &lt; remainingLength; i++) {
                      password += characterPool[Math.floor(Math.random() * characterPool.length)];
                 }
                 // Add guaranteed characters and shuffle the result
                 password = shuffleString(password + guaranteedChars);
            }


            passwordOutput.value = password;
            passwordOutput.placeholder = 'Generated password appears here...'; // Reset placeholder

            // Auto-copy the generated password
            copyPassword();
        }

         // Helper function to shuffle a string (Fisher-Yates algorithm)
         function shuffleString(str) {
             let arr = str.split('');
             for (let i = arr.length - 1; i &gt; 0; i--) {
                 const j = Math.floor(Math.random() * (i + 1));
                 [arr[i], arr[j]] = [arr[j], arr[i]]; // Swap elements
             }
             return arr.join('');
         }

        // --- Copy Functionality ---
        function copyPassword() {
            const password = passwordOutput.value;

            if (!password) {
                // Optionally show a message or just do nothing if empty
                // console.log("Nothing to copy.");
                return;
            }

            if (navigator.clipboard &amp;&amp; navigator.clipboard.writeText) {
                navigator.clipboard.writeText(password).then(() =&gt; {
                    // Success! Show confirmation message
                    showCopyMessage();
                }).catch(err =&gt; {
                    // Error! Inform user (could be permissions, HTTP, etc.)
                    console.error('Failed to copy password: ', err);
                    alert('Could not copy password automatically. Please copy it manually.');
                    // Fallback: Select text for manual copying
                     selectPasswordText();
                });
            } else {
                // Fallback for older browsers (less reliable)
                try {
                    selectPasswordText();
                    document.execCommand('copy');
                    window.getSelection()?.removeAllRanges(); // Deselect
                    showCopyMessage();
                } catch (err) {
                    console.error('Fallback copy failed: ', err);
                    alert('Could not copy password. Please copy it manually.');
                     selectPasswordText(); // Still select for manual copy
                }
            }
        }

         // Helper to select text in the input
         function selectPasswordText() {
             if(passwordOutput) {
                 passwordOutput.focus(); // Focus needed for execCommand sometimes
                 passwordOutput.select();
             }
         }

        function showCopyMessage() {
            if (!copyMessage) return;
            clearTimeout(copyTimeout); // Clear any existing timeout
            copyMessage.classList.add('visible');
            copyTimeout = setTimeout(() =&gt; {
                copyMessage.classList.remove('visible');
            }, 2000); // Show message for 2 seconds
        }

        // --- Event Listeners ---
        if (generateBtn) generateBtn.addEventListener('click', generatePassword);
        if (copyBtn) copyBtn.addEventListener('click', copyPassword);
        // Update password on option change? Maybe not, usually generate is explicit
        // $$('.options input').forEach(input =&gt; input.addEventListener('change', generatePassword));

        // --- Initialization ---
        function initialize() {
            const savedTheme = localStorage.getItem(localStorageThemeKey) || 'dark';
            applyTheme(savedTheme);
            // Optionally generate a password on load?
            // generatePassword();
        }

        if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); }
        else { initialize(); }

    })(); // End IIFE
&lt;/script&gt;
&lt;!-- END: Generator Script --&gt;

&lt;!-- END: Complete Self-Contained Password Generator Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Percentage Calculator</title><link>http://rajclick.blogspot.com/2025/03/percentage-calculator.html</link><category>Calculator App</category><pubDate>Mon, 10 Mar 2025 10:23:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-7329657993438712158</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Instant Percentage Calculator&lt;/title&gt;
    &lt;style&gt;
        /* Define color variables for themes */
        :root {
            /* Light Mode Colors */
            --lm-bg: #f0f4f8;
            --lm-text: #333;
            --lm-container-bg: #fff;
            --lm-container-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            --lm-header-color: #0a6ed1;
            --lm-input-border: #0a6ed1;
            --lm-input-bg: #fff;
            --lm-input-text: #333;
            --lm-result-bg: #e7f3ff;
            --lm-result-text: #0a6ed1;
            --lm-button-bg: #0a6ed1;
            --lm-button-text: #fff;
            --lm-button-hover-bg: #085ab8;

            /* Dark Mode Colors */
            --dm-bg: #121212;
            --dm-text: #e0e0e0;
            --dm-container-bg: #1e1e1e;
            --dm-container-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
            --dm-header-color: #7bb0e8; /* Lighter blue for dark mode */
            --dm-input-border: #555;
            --dm-input-bg: #333;
            --dm-input-text: #e0e0e0;
            --dm-result-bg: #2a2a2a;
            --dm-result-text: #7bb0e8;
            --dm-button-bg: #333;
            --dm-button-text: #e0e0e0;
            --dm-button-hover-bg: #444;
        }

        body {
            font-family: Arial, sans-serif;
            margin: 0; /* Remove default margin */
            padding: 20px; /* Add some padding around the container */
            box-sizing: border-box;
            /* --- Center Alignment --- */
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            /* --- Default to Dark Mode via class --- */
            transition: background-color 0.3s, color 0.3s; /* Smooth theme transition */
        }

        /* --- Light Mode Styles --- */
        body.light-mode {
            background-color: var(--lm-bg);
            color: var(--lm-text);
        }
        body.light-mode .calculator-container {
            background-color: var(--lm-container-bg);
            box-shadow: var(--lm-container-shadow);
        }
        body.light-mode h2 {
            color: var(--lm-header-color);
        }
         body.light-mode label {
             color: var(--lm-text); /* Ensure label color is set */
         }
        body.light-mode input[type=number] {
            border: 1px solid var(--lm-input-border);
            background-color: var(--lm-input-bg);
            color: var(--lm-input-text);
        }
        body.light-mode input[type=number]::placeholder {
             color: #999; /* Placeholder color for light mode */
        }
        body.light-mode .result {
            background-color: var(--lm-result-bg);
            color: var(--lm-result-text);
        }
        body.light-mode #theme-toggle {
            background-color: var(--lm-button-bg);
            color: var(--lm-button-text);
            border: 1px solid var(--lm-button-bg);
        }
         body.light-mode #theme-toggle:hover {
            background-color: var(--lm-button-hover-bg);
         }

        /* --- Dark Mode Styles --- */
        body.dark-mode {
            background-color: var(--dm-bg);
            color: var(--dm-text);
        }
        body.dark-mode .calculator-container {
            background-color: var(--dm-container-bg);
            box-shadow: var(--dm-container-shadow);
        }
        body.dark-mode h2 {
            color: var(--dm-header-color);
        }
         body.dark-mode label {
             color: var(--dm-text); /* Ensure label color is set */
         }
        body.dark-mode input[type=number] {
            border: 1px solid var(--dm-input-border);
            background-color: var(--dm-input-bg);
            color: var(--dm-input-text);
        }
         body.dark-mode input[type=number]::placeholder {
             color: #777; /* Placeholder color for dark mode */
         }
        body.dark-mode .result {
            background-color: var(--dm-result-bg);
            color: var(--dm-result-text);
        }
        body.dark-mode #theme-toggle {
            background-color: var(--dm-button-bg);
            color: var(--dm-button-text);
            border: 1px solid var(--dm-input-border); /* Match input border */
        }
         body.dark-mode #theme-toggle:hover {
             background-color: var(--dm-button-hover-bg);
         }

        /* --- Common Styles --- */
        .calculator-container {
            max-width: 500px;
            width: 90%; /* Responsive width */
            margin: 20px; /* Add margin for spacing */
            padding: 30px; /* Increased padding */
            border-radius: 10px;
            transition: background-color 0.3s, box-shadow 0.3s; /* Smooth transition for container */
        }

        h2 {
            text-align: center;
            margin-top: 0;
            margin-bottom: 25px; /* More space below header */
        }

        label {
            display: block; /* Make labels block elements */
            margin-bottom: 8px; /* Space below label */
            font-weight: bold;
            font-size: 0.9em;
        }

        input[type=number] {
            width: 100%;
            padding: 12px; /* Slightly larger padding */
            margin-top: 5px;
            margin-bottom: 20px; /* More space below inputs */
            border-radius: 5px;
            box-sizing: border-box; /* Include padding and border in element's total width/height */
            font-size: 1em;
             transition: background-color 0.3s, color 0.3s, border-color 0.3s;
        }
         /* Remove arrows from number inputs (optional) */
        input[type=number]::-webkit-outer-spin-button,
        input[type=number]::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        input[type=number] {
            -moz-appearance: textfield; /* Firefox */
        }


        .result {
            margin-top: 10px;
            margin-bottom: 25px; /* Space below result */
            padding: 12px;
            border-radius: 5px;
            font-weight: bold;
            text-align: center;
            min-height: 1.5em; /* Prevent layout shift when empty */
             transition: background-color 0.3s, color 0.3s;
        }

        #theme-toggle {
            display: block; /* Make button block */
            margin: 0 auto 25px auto; /* Center button and add space below */
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
        }

        p.description { /* Style the description paragraph */
            text-align: center;
            margin-top: 20px;
            font-size: 0.9em;
            line-height: 1.5;
            opacity: 0.8; /* Slightly less prominent */
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;!-- Default to dark mode --&gt;
&lt;body class="dark-mode"&gt;

&lt;div class="calculator-container"&gt;
    &lt;h2&gt;Instant Percentage Calculator&lt;/h2&gt;

    &lt;!-- Theme Toggle Button --&gt;
    &lt;button id="theme-toggle"&gt;Switch to Light Mode&lt;/button&gt;

    &lt;label for="oldValue"&gt;Calculate Percentage Increase/Decrease&lt;/label&gt;
    &lt;input type="number" id="oldValue" placeholder="Old Value"&gt;
    &lt;input type="number" id="newValue" placeholder="New Value"&gt;
    &lt;div class="result" id="changeResult"&gt;&lt;/div&gt;

    &lt;label for="percent"&gt;Find Percentage of a Number&lt;/label&gt;
    &lt;input type="number" id="percent" placeholder="Percentage (%)"&gt;
    &lt;input type="number" id="ofNumber" placeholder="Number"&gt;
    &lt;div class="result" id="percentOfResult"&gt;&lt;/div&gt;

    &lt;label for="firstNumber"&gt;What Percent One Number Is of Another&lt;/label&gt;
    &lt;input type="number" id="firstNumber" placeholder="Part Number"&gt;
    &lt;input type="number" id="secondNumber" placeholder="Whole Number"&gt;
    &lt;div class="result" id="whatPercentResult"&gt;&lt;/div&gt;

    &lt;p class="description"&gt;
        Instantly calculate percentage increases, decreases, percentages of numbers, and determine what percent one number is of another. Ideal for students, professionals, and everyday tasks.
    &lt;/p&gt;
&lt;/div&gt;

&lt;script&gt;
    // --- Calculator Logic ---
    function calculate() {
        // Use parseFloat or return NaN if empty/invalid
        const parseOrDefault = (id) =&gt; parseFloat(document.getElementById(id).value) || NaN;

        const oldVal = parseOrDefault('oldValue');
        const newVal = parseOrDefault('newValue');
        const percent = parseOrDefault('percent');
        const ofNum = parseOrDefault('ofNumber');
        const firstNum = parseOrDefault('firstNumber');
        const secondNum = parseOrDefault('secondNumber');

        const changeResultDiv = document.getElementById('changeResult');
        const percentOfResultDiv = document.getElementById('percentOfResult');
        const whatPercentResultDiv = document.getElementById('whatPercentResult');

        // Calculate Percentage Change
        if (!isNaN(oldVal) &amp;&amp; !isNaN(newVal)) {
             if (oldVal === 0 &amp;&amp; newVal === 0) {
                changeResultDiv.innerText = 'Change: 0.00%';
             } else if (oldVal === 0) {
                changeResultDiv.innerText = 'Change: Infinite % (from zero)';
             } else {
                const change = ((newVal - oldVal) / Math.abs(oldVal)) * 100;
                changeResultDiv.innerText = `Change: ${change.toFixed(2)}% ${change &gt;= 0 ? '(Increase)' : '(Decrease)'}`;
             }
        } else {
            changeResultDiv.innerText = '';
        }

        // Calculate Percentage Of a Number
        if (!isNaN(percent) &amp;&amp; !isNaN(ofNum)) {
            percentOfResultDiv.innerText = `${percent}% of ${ofNum} is ${((percent / 100) * ofNum).toFixed(2)}`;
        } else {
            percentOfResultDiv.innerText = '';
        }

        // Calculate What Percent One Number Is of Another
        if (!isNaN(firstNum) &amp;&amp; !isNaN(secondNum)) {
             if (secondNum === 0) {
                 whatPercentResultDiv.innerText = 'Cannot divide by zero';
             } else {
                 whatPercentResultDiv.innerText = `${firstNum} is ${((firstNum / secondNum) * 100).toFixed(2)}% of ${secondNum}`;
             }
        } else {
            whatPercentResultDiv.innerText = '';
        }
    }

    // Add event listeners to all number inputs
    document.querySelectorAll('input[type=number]').forEach(input =&gt; {
        input.addEventListener('input', calculate);
    });

    // --- Theme Toggle Logic ---
    const themeToggle = document.getElementById('theme-toggle');
    const body = document.body;

    // Function to apply theme based on class and update button
    function applyTheme(isDarkMode) {
        if (isDarkMode) {
            body.classList.add('dark-mode');
            body.classList.remove('light-mode');
            themeToggle.textContent = 'Switch to Light Mode';
            localStorage.setItem('theme', 'dark'); // Save preference
        } else {
            body.classList.add('light-mode');
            body.classList.remove('dark-mode');
            themeToggle.textContent = 'Switch to Dark Mode';
            localStorage.setItem('theme', 'light'); // Save preference
        }
    }

    // Event listener for the toggle button
    themeToggle.addEventListener('click', () =&gt; {
        const isCurrentlyDark = body.classList.contains('dark-mode');
        applyTheme(!isCurrentlyDark); // Toggle the theme
    });

    // Check for saved theme preference on load
    document.addEventListener('DOMContentLoaded', () =&gt; {
        const savedTheme = localStorage.getItem('theme');
        // Default is dark (set in HTML class), only switch if 'light' is saved
        if (savedTheme === 'light') {
            applyTheme(false);
        } else {
             // Ensure button text is correct for default dark mode if no preference saved
             applyTheme(true);
        }
        // Initial calculation run in case of pre-filled values (less common)
        calculate();
    });

&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Age &amp; Date Difference Calculator</title><link>http://rajclick.blogspot.com/2025/03/age-date-difference-calculator.html</link><category>Calculator App</category><pubDate>Mon, 10 Mar 2025 10:06:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-8603821285978396190</guid><description>&lt;!-- START: Complete Self-Contained Age/Date Calculator Block --&gt;

&lt;!-- Main container for the calculator with a unique ID for scoping --&gt;
&lt;div id="post-age-date-calculator"&gt;

    &lt;!-- START: Calculator-Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles to this container */
        #post-age-date-calculator {
            /* --- CSS Variables for Theming (Default: Dark) --- */
            --adc-bg-color: #2a2a2a;         /* Dark card background */
            --adc-text-color: #e0e0e0;       /* Light text */
            --adc-heading-color: #79baff;    /* Lighter blue for headings */
            --adc-border-color: #444;        /* Dark border */
            --adc-input-bg: #333;           /* Dark input bg */
            --adc-input-border: #555;       /* Dark input border */
            --adc-input-text: #e0e0e0;      /* Light input text */
            --adc-button-bg: #3a7bf0;       /* Button blue */
            --adc-button-hover-bg: #2a68d0; /* Darker button blue */
            --adc-button-text: #ffffff;
            --adc-result-bg: #333d47;     /* Darker result bg */
            --adc-result-text: #a6d1ff;     /* Lighter blue result text */
            --adc-shadow-color: rgba(0, 0, 0, 0.3);
            --adc-explanation-text: #b0b0b0; /* Color for explanation text */

            /* Base styles */
            font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--adc-bg-color);
            color: var(--adc-text-color);
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 4px 12px var(--adc-shadow-color);
            width: 100%;
            max-width: 600px; /* Limit width */
            margin: 25px auto; /* Center block and add vertical space */
            border: 1px solid var(--adc-border-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            box-sizing: border-box;
            /* Removed position: relative; - Not needed now */
        }
        /* Apply box-sizing to all elements within */
        #post-age-date-calculator *,
        #post-age-date-calculator *::before,
        #post-age-date-calculator *::after {
            box-sizing: border-box;
        }

        /* --- Light Mode Overrides --- */
        #post-age-date-calculator.adc-light-mode {
            --adc-bg-color: #ffffff;
            --adc-text-color: #333;
            --adc-heading-color: #0a6ed1;
            --adc-border-color: #e0e0e0;
            --adc-input-bg: #ffffff;
            --adc-input-border: #cfd8dc;
            --adc-input-text: #333;
            --adc-button-bg: #0a6ed1;
            --adc-button-hover-bg: #0866b3;
            --adc-button-text: #ffffff;
            --adc-result-bg: #f1f8ff;
            --adc-result-text: #0a6ed1;
            --adc-shadow-color: rgba(0, 0, 0, 0.1);
            --adc-explanation-text: #555;
        }

        /* --- Element Styles (Scoped) --- */
        #post-age-date-calculator h2 {
            margin-top: 0;
            margin-bottom: 15px; /* Reduced margin below main title */
            color: var(--adc-heading-color);
            text-align: center;
            font-size: 1.8rem;
        }

         /* Theme Switch Styling */
         #post-age-date-calculator .theme-switch-wrapper {
            /* Removed position: absolute; */
            text-align: right; /* Align button to the right */
            margin-bottom: 25px; /* Space below switch */
         }
         /* Responsive adjustments */
         @media (max-width: 600px) {
              #post-age-date-calculator .theme-switch-wrapper {
                   text-align: center; /* Center on small screens */
              }
              #post-age-date-calculator { padding: 20px; }
              #post-age-date-calculator h2 { font-size: 1.6rem; margin-bottom: 10px;}
              #post-age-date-calculator h3 { font-size: 1.3rem; }
         }
         #post-age-date-calculator #adcThemeSwitch {
            padding: 6px 12px;
            cursor: pointer;
            border-radius: 5px;
            border: 1px solid var(--adc-input-border);
            background-color: var(--adc-input-bg); /* Use input bg for button */
            color: var(--adc-text-color);
            font-weight: bold;
            font-size: 0.85em;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s, opacity 0.2s;
         }
          #post-age-date-calculator #adcThemeSwitch:hover {
              opacity: 0.85;
          }

        #post-age-date-calculator h3 {
            margin-top: 0; /* Reset margin if needed */
            margin-bottom: 20px;
            color: var(--adc-heading-color);
            font-size: 1.4rem;
            border-bottom: 2px solid var(--adc-border-color);
            padding-bottom: 8px;
            transition: border-color 0.3s;
        }

        #post-age-date-calculator .calculator-section {
            margin-bottom: 30px;
        }
         /* Remove margin from last section */
         #post-age-date-calculator .calculator-section:last-of-type {
              margin-bottom: 15px;
         }

        #post-age-date-calculator .form-group {
            display: flex;
            flex-direction: column;
            margin-bottom: 20px;
        }

        #post-age-date-calculator label {
            margin-bottom: 8px;
            font-weight: bold;
            color: var(--adc-text-color);
            opacity: 0.9;
            font-size: 0.95rem;
        }

        #post-age-date-calculator input[type="date"] {
            padding: 10px;
            border: 1px solid var(--adc-input-border);
            border-radius: 5px;
            font-size: 1rem;
            background-color: var(--adc-input-bg);
            color: var(--adc-input-text);
            transition: border-color 0.3s, background-color 0.3s, color 0.3s, box-shadow 0.3s;
            color-scheme: dark; /* Hint for dark mode picker */
        }
        #post-age-date-calculator.adc-light-mode input[type="date"] {
             color-scheme: light; /* Hint for light mode picker */
        }

        #post-age-date-calculator input[type="date"]:focus {
            outline: none;
            border-color: var(--adc-heading-color);
            box-shadow: 0 0 5px rgba(10, 110, 209, 0.3);
        }
         #post-age-date-calculator.adc-light-mode input[type="date"]:focus {
             box-shadow: 0 0 5px rgba(10, 110, 209, 0.3);
         }

        #post-age-date-calculator .btn {
            padding: 10px 20px;
            background-color: var(--adc-button-bg);
            color: var(--adc-button-text);
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 0.95rem;
            transition: background-color 0.3s;
            align-self: flex-start;
            margin-top: 10px;
        }

        #post-age-date-calculator .btn:hover {
            background-color: var(--adc-button-hover-bg);
        }

        #post-age-date-calculator .result {
            background-color: var(--adc-result-bg);
            padding: 15px;
            border-radius: 5px;
            margin-top: 10px;
            font-weight: 500;
            color: var(--adc-result-text);
            border: 1px solid var(--adc-border-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            line-height: 1.5;
             min-height: 50px;
             word-wrap: break-word;
        }

        /* Explanation Section Styling */
        #post-age-date-calculator .calculator-explanation {
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid var(--adc-border-color);
            font-size: 0.9rem;
            line-height: 1.6;
            color: var(--adc-explanation-text);
             text-align: left; /* Align text left for readability */
        }
        #post-age-date-calculator .calculator-explanation h4 {
             margin-bottom: 10px;
             color: var(--adc-text-color); /* Use main text color */
             font-size: 1.1rem;
        }
         #post-age-date-calculator .calculator-explanation p {
             margin-bottom: 10px;
         }
          #post-age-date-calculator .calculator-explanation ul {
              margin-left: 20px;
              margin-bottom: 10px;
          }


    &lt;/style&gt;
    &lt;!-- END: Calculator-Specific Styles --&gt;


    &lt;!-- START: Calculator HTML --&gt;
    &lt;h2&gt;Age &amp; Date Difference Calculator&lt;/h2&gt;

    &lt;!-- Local Theme Switch - Moved Here --&gt;
    &lt;div class="theme-switch-wrapper"&gt;
        &lt;button id="adcThemeSwitch"&gt;Switch Theme&lt;/button&gt; &lt;!-- Text set by JS --&gt;
    &lt;/div&gt;

    &lt;!-- Age Calculator Section --&gt;
    &lt;div class="calculator-section" id="ageCalculator"&gt;
      &lt;h3&gt;Age Calculator&lt;/h3&gt;
      &lt;div class="form-group"&gt;
        &lt;label for="birthdate"&gt;Birth Date:&lt;/label&gt;
        &lt;input type="date" id="birthdate" /&gt;
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
        &lt;label for="referenceDate"&gt;Reference Date:&lt;/label&gt;
        &lt;input type="date" id="referenceDate" /&gt;
        &lt;button class="btn" type="button" id="setCurrent"&gt;Set to Current Date&lt;/button&gt;
      &lt;/div&gt;
      &lt;div class="result" id="ageResult"&gt;Enter dates to see the age.&lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Date Difference Calculator Section --&gt;
    &lt;div class="calculator-section" id="dateDifference"&gt;
      &lt;h3&gt;Date Difference Calculator&lt;/h3&gt;
      &lt;div class="form-group"&gt;
        &lt;label for="date1"&gt;Start Date:&lt;/label&gt;
        &lt;input type="date" id="date1" /&gt;
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
        &lt;label for="date2"&gt;End Date:&lt;/label&gt;
        &lt;input type="date" id="date2" /&gt;
      &lt;/div&gt;
      &lt;div class="result" id="diffResult"&gt;Enter dates to see the difference.&lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- SEO Explanation Section --&gt;
    &lt;div class="calculator-explanation"&gt;
        &lt;h4&gt;About This Calculator&lt;/h4&gt;
        &lt;p&gt;
            This tool provides two useful date-related calculations: determining your exact age based on your birth date and a reference date, and finding the precise difference between any two given dates.
        &lt;/p&gt;
        &lt;h4&gt;How to Use:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Age Calculator:&lt;/strong&gt; Enter your date of birth and a reference date (or use the "Set to Current Date" button). The tool will display your age in years, months, weeks, and days. This is helpful for tracking milestones or simply knowing your precise age.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Date Difference Calculator:&lt;/strong&gt; Input any two dates (Start Date and End Date). The calculator will show the duration between them, broken down into years, months, weeks, and days, along with the total number of days. This is useful for project planning, calculating time between events, or historical analysis.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;
            The calculations account for leap years and varying month lengths to provide accurate results. Dates are processed using UTC to avoid timezone inconsistencies.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;!-- END: Calculator HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-age-date-calculator Container --&gt;


&lt;!-- START: Calculator Script (Scoped &amp; Themed) --&gt;
&lt;script&gt;
    // Wrap in IIFE
    (function() {
        const calculatorContainer = document.getElementById('post-age-date-calculator');
        if (!calculatorContainer) { console.error("Calculator container not found."); return; }

        // DOM Elements (scoped)
        const $ = (selector) =&gt; calculatorContainer.querySelector(selector);
        const birthdateInput = $('#birthdate');
        const referenceDateInput = $('#referenceDate');
        const setCurrentBtn = $('#setCurrent');
        const ageResultDiv = $('#ageResult');
        const date1Input = $('#date1');
        const date2Input = $('#date2');
        const diffResultDiv = $('#diffResult');
        const themeSwitchBtn = $('#adcThemeSwitch');
        const localStorageThemeKey = 'ageDateCalcTheme';

        // --- Theme Switching ---
        function applyTheme(theme) {
            if (theme === 'light') {
                calculatorContainer.classList.add('adc-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Dark Mode';
            } else {
                calculatorContainer.classList.remove('adc-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Light Mode';
            }
            localStorage.setItem(localStorageThemeKey, theme);
        }

        if (themeSwitchBtn) {
            themeSwitchBtn.addEventListener('click', () =&gt; {
                const currentThemeIsLight = calculatorContainer.classList.contains('adc-light-mode');
                applyTheme(currentThemeIsLight ? 'dark' : 'light');
            });
        }

        // --- Date Calculation Logic ---
        function calculateDifference(start, end) {
          if (!(start instanceof Date) || !(end instanceof Date) || isNaN(start) || isNaN(end)) return null;
          if (start &gt; end) [start, end] = [end, start];

          let startYear = start.getFullYear(), startMonth = start.getMonth(), startDay = start.getDate();
          let endYear = end.getFullYear(), endMonth = end.getMonth(), endDay = end.getDate();
          let years = endYear - startYear, months = endMonth - startMonth, days = endDay - startDay;

          if (days &lt; 0) { months--; days += new Date(endYear, endMonth, 0).getDate(); }
          if (months &lt; 0) { years--; months += 12; }

          const timeDiff = end.getTime() - start.getTime();
          const totalDays = Math.max(0, Math.floor(timeDiff / (1000 * 60 * 60 * 24))); // Ensure non-negative
          let weeks = Math.floor(totalDays / 7);
          let remainingDaysAfterWeeks = totalDays % 7;

          return { years, months, weeks, days: remainingDaysAfterWeeks, totalDays };
        }

        // --- UI Update Functions ---
        function updateAge() {
          if (!birthdateInput || !referenceDateInput || !ageResultDiv) return;
          const birthInput = birthdateInput.value; const refInput = referenceDateInput.value;
          if (!birthInput || !refInput) { ageResultDiv.textContent = 'Please select both dates.'; return; }

          const birthDate = new Date(birthInput + 'T00:00:00Z'); const refDate = new Date(refInput + 'T00:00:00Z');
          if (isNaN(birthDate.getTime()) || isNaN(refDate.getTime())) { ageResultDiv.textContent = 'Invalid date selected.'; return; }
          if (birthDate &gt; refDate) { ageResultDiv.textContent = 'Birth date cannot be after reference date.'; return; }

          const diff = calculateDifference(birthDate, refDate);
          if (!diff) { ageResultDiv.textContent = 'Could not calculate age.'; return; }

          let ageString = 'Age: ';
          if (diff.years &gt; 0) ageString += `${diff.years} year${diff.years &gt; 1 ? 's' : ''}`;
          if (diff.months &gt; 0) ageString += `${diff.years &gt; 0 ? ', ' : ''}${diff.months} month${diff.months &gt; 1 ? 's' : ''}`;
          // Show weeks only if years/months are zero OR if you always want weeks
           if (diff.years === 0 &amp;&amp; diff.months === 0 &amp;&amp; diff.weeks &gt; 0) ageString += `${diff.weeks} week${diff.weeks &gt; 1 ? 's' : ''}`;
          if (diff.days &gt; 0) ageString += `${(diff.years &gt; 0 || diff.months &gt; 0 || (diff.years === 0 &amp;&amp; diff.months === 0 &amp;&amp; diff.weeks &gt; 0)) ? ', ' : ''}${diff.days} day${diff.days &gt; 1 ? 's' : ''}`;

           if (ageString === 'Age: ') { ageString = diff.totalDays === 0 ? 'Age: Same day' : 'Age: Less than a day'; }

          ageResultDiv.textContent = ageString + '.';
        }

        function updateDifference() {
            if (!date1Input || !date2Input || !diffResultDiv) return;
            const date1InputVal = date1Input.value; const date2InputVal = date2Input.value;
            if (!date1InputVal || !date2InputVal) { diffResultDiv.textContent = 'Please select both dates.'; return; }

            const date1 = new Date(date1InputVal + 'T00:00:00Z'); const date2 = new Date(date2InputVal + 'T00:00:00Z');
            if (isNaN(date1.getTime()) || isNaN(date2.getTime())) { diffResultDiv.textContent = 'Invalid date selected.'; return; }

            const diff = calculateDifference(date1, date2);
             if (!diff) { diffResultDiv.textContent = 'Could not calculate difference.'; return; }

            let diffString = 'Difference: ';
            if (diff.years &gt; 0) diffString += `${diff.years} year${diff.years &gt; 1 ? 's' : ''}`;
            if (diff.months &gt; 0) diffString += `${diff.years &gt; 0 ? ', ' : ''}${diff.months} month${diff.months &gt; 1 ? 's' : ''}`;
            // Show weeks if significant or if years/months are zero
            if (diff.weeks &gt; 0 &amp;&amp; (diff.years &gt; 0 || diff.months &gt; 0 || diff.days &gt; 0)) diffString += `${(diff.years &gt; 0 || diff.months &gt; 0) ? ', ' : ''}${diff.weeks} week${diff.weeks &gt; 1 ? 's' : ''}`;
             else if (diff.years === 0 &amp;&amp; diff.months === 0 &amp;&amp; diff.weeks &gt; 0) diffString += `${diff.weeks} week${diff.weeks &gt; 1 ? 's' : ''}`; // Weeks only case
            if (diff.days &gt; 0) diffString += `${(diff.years &gt; 0 || diff.months &gt; 0 || diff.weeks &gt; 0) ? ', ' : ''}${diff.days} day${diff.days &gt; 1 ? 's' : ''}`;

            if (diffString === 'Difference: ') { diffString = diff.totalDays === 0 ? 'Difference: Same day' : 'Difference: Less than a day'; }
             else { diffString += ` (Total: ${diff.totalDays} day${diff.totalDays !== 1 ? 's' : ''}).`; } // Add total days

            diffResultDiv.textContent = diffString;
        }

        // --- Event Listeners ---
        if (birthdateInput) birthdateInput.addEventListener('change', updateAge);
        if (referenceDateInput) referenceDateInput.addEventListener('change', updateAge);
        if (date1Input) date1Input.addEventListener('change', updateDifference);
        if (date2Input) date2Input.addEventListener('change', updateDifference);

        if (setCurrentBtn) {
            setCurrentBtn.addEventListener('click', function() {
                const today = new Date();
                // Format YYYY-MM-DD for input type="date"
                const formattedDate = today.toISOString().split('T')[0];
                if (referenceDateInput) {
                    referenceDateInput.value = formattedDate;
                    updateAge();
                }
            });
        }

        // --- Initial Setup ---
        function initialize() {
            const savedTheme = localStorage.getItem(localStorageThemeKey) || 'dark';
            applyTheme(savedTheme);

            const today = new Date();
            const formattedDate = today.toISOString().split('T')[0];
            if (referenceDateInput) { referenceDateInput.value = formattedDate; }
            // Optionally trigger initial calculation on load if desired
             // updateAge();
             // updateDifference();
        }

        if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); }
        else { initialize(); }

    })(); // End IIFE
&lt;/script&gt;
&lt;!-- END: Calculator Script --&gt;

&lt;!-- END: Complete Self-Contained Age/Date Calculator Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Task Tracker</title><link>http://rajclick.blogspot.com/2025/03/task-tracker.html</link><category>Tracker app</category><pubDate>Mon, 10 Mar 2025 09:12:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-6552004626779214560</guid><description>&lt;!-- START: Complete Self-Contained Task Tracker Block --&gt;

&lt;!-- Main container for the tracker --&gt;
&lt;div id="post-task-tracker"&gt;

    &lt;!-- START: Tracker-Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles to the tracker container */
        #post-task-tracker {
            /* --- CSS Variables for Theming (Default: Dark) --- */
            --tracker-bg-color: #1e1e1e;
            --tracker-text-color: #e0e0e0;
            --tracker-card-bg: #2a2a2a;
            --tracker-table-header-bg: #004d40; /* Darker Green */
            --tracker-table-border-color: #444;
            --tracker-input-bg: #333;
            --tracker-input-border: #555;
            --tracker-input-text-color: #e0e0e0;
            --tracker-progress-bar-bg: #444;
            --tracker-progress-fill-bg: #00796b; /* Tealish Green */
            --tracker-button-primary-bg: #00796b;
            --tracker-button-primary-text: #ffffff;
            --tracker-button-danger-bg: #c62828; /* Darker Red */
            --tracker-button-danger-text: #ffffff;
            --tracker-priority-high-bg: #c62828;
            --tracker-priority-medium-bg: #ff8f00; /* Darker Orange */
            --tracker-priority-low-bg: #2e7d32;  /* Darker Green */
            --tracker-link-color: #64b5f6;
            --tracker-select-arrow-color: #e0e0e0; /* Default arrow color (dark mode) */
            --tracker-error-border-color: #c62828; /* Error highlight color */
            --tracker-hover-bg: rgba(128, 128, 128, 0.1); /* Dark hover */

            /* Base styles */
            background-color: var(--tracker-bg-color);
            color: var(--tracker-text-color);
            padding: 20px;
            border-radius: 8px;
            margin: 25px auto; /* Center block and add space */
            font-family: 'Roboto', Arial, sans-serif;
            line-height: 1.6;
            border: 1px solid var(--tracker-table-border-color); /* Match border */
            box-shadow: 0 3px 7px rgba(0,0,0,0.2);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            width: 100%; /* Use available width */
            max-width: 950px; /* Limit max width */
            box-sizing: border-box;
            position: relative; /* Needed for absolute positioning of theme switch */
        }
         /* Apply box-sizing to all elements within */
        #post-task-tracker *, #post-task-tracker *::before, #post-task-tracker *::after {
            box-sizing: border-box;
        }

        /* --- Light Mode Overrides --- */
        #post-task-tracker.tracker-light-mode {
            --tracker-bg-color: #ffffff;
            --tracker-text-color: #333333;
            --tracker-card-bg: #f4f4f4;
            --tracker-table-header-bg: #4CAF50;
            --tracker-table-border-color: #ddd;
            --tracker-input-bg: #ffffff;
            --tracker-input-border: #ccc;
            --tracker-input-text-color: #333333;
            --tracker-progress-bar-bg: #e0e0e0;
            --tracker-progress-fill-bg: #4CAF50;
            --tracker-button-primary-bg: #4CAF50;
            --tracker-button-primary-text: #ffffff;
            --tracker-button-danger-bg: #ef5350; /* Lighter red */
            --tracker-button-danger-text: #ffffff;
            --tracker-priority-high-bg: #ef5350;
            --tracker-priority-medium-bg: #ffca28; /* Lighter orange */
            --tracker-priority-low-bg: #66bb6a;  /* Lighter green */
            --tracker-link-color: #0b7dda;
            --tracker-select-arrow-color: #333333; /* Arrow color for light mode */
            --tracker-error-border-color: #ef5350;
            --tracker-hover-bg: rgba(0, 0, 0, 0.04); /* Light hover */
        }

        /* --- Element Styles (Scoped) --- */
        #post-task-tracker header {
            text-align: center;
            margin-bottom: 30px;
            border-bottom: 1px solid var(--tracker-table-border-color);
            padding-bottom: 15px;
        }
        #post-task-tracker header h1 {
            margin-bottom: 5px;
            font-size: 2.2em; /* Adjusted title size */
             color: var(--tracker-text-color);
        }
        #post-task-tracker header p {
            color: var(--tracker-text-color);
            opacity: 0.8;
            margin-top: 0;
            font-size: 0.95em;
        }

        /* Theme Switch Styling */
        #post-task-tracker .theme-switch-wrapper {
            text-align: right;
            position: absolute; /* Position relative to main container */
            top: 15px; /* Adjust positioning */
            right: 20px;
        }
        /* Responsive adjustments for theme switch */
        @media (max-width: 600px) {
             #post-task-tracker .theme-switch-wrapper {
                  position: relative; /* Back to relative */
                  top: auto;
                  right: auto;
                  text-align: center;
                  margin-bottom: 20px; /* Space below switch */
                  margin-top: -15px; /* Pull up slightly */
             }
              #post-task-tracker header {
                 margin-bottom: 15px; /* Reduce header margin */
             }
        }

        #post-task-tracker #themeSwitch {
            padding: 8px 15px;
            cursor: pointer;
            border-radius: 5px;
            border: 1px solid var(--tracker-input-border);
            background-color: var(--tracker-card-bg);
            color: var(--tracker-text-color);
            font-weight: bold;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s, opacity 0.2s;
            box-shadow: 0 1px 3px rgba(0,0,0,0.2);
            font-size: 0.9em;
        }
         #post-task-tracker #themeSwitch:hover {
             opacity: 0.85;
         }

        /* Form Styling */
        #post-task-tracker .task-form {
            background: var(--tracker-card-bg);
            padding: 25px;
            border-radius: 8px;
            margin-bottom: 30px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
             transition: background-color 0.3s;
        }
         #post-task-tracker .task-form h2 {
            margin-top: 0;
            color: var(--tracker-text-color);
             border-bottom: 1px solid var(--tracker-table-border-color);
             padding-bottom: 10px;
             margin-bottom: 20px;
             font-size: 1.5em;
         }

        #post-task-tracker .form-group {
            margin-bottom: 15px;
        }
        #post-task-tracker .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: var(--tracker-text-color);
             opacity: 0.9;
             font-size: 0.9em;
        }
        #post-task-tracker .form-group input,
        #post-task-tracker .form-group select,
        #post-task-tracker .form-group textarea {
            width: 100%;
            padding: 10px;
            border: 1px solid var(--tracker-input-border);
            border-radius: 4px;
            background-color: var(--tracker-input-bg);
            color: var(--tracker-input-text-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
             font-size: 1em;
        }
        #post-task-tracker .form-group select {
            appearance: none;
            background-repeat: no-repeat;
            background-position: right 10px center;
            padding-right: 30px;
            cursor: pointer;
            /* Arrow set by JS */
        }
        /* Error highlighting */
        #post-task-tracker .form-group input.error,
        #post-task-tracker .form-group select.error,
        #post-task-tracker .form-group textarea.error {
            border: 2px solid var(--tracker-error-border-color); /* Thicker border for error */
        }

        /* Buttons */
        #post-task-tracker #submitBtn,
        #post-task-tracker .edit-btn,
        #post-task-tracker .delete-btn {
             padding: 10px 20px;
             border: none;
             border-radius: 5px;
             cursor: pointer;
             font-weight: bold;
             transition: background-color 0.2s, opacity 0.2s;
             font-size: 0.95em;
        }
        #post-task-tracker #submitBtn {
            background-color: var(--tracker-button-primary-bg);
            color: var(--tracker-button-primary-text);
             display: block;
             width: 100%;
             margin-top: 10px;
        }
         #post-task-tracker #submitBtn:hover { opacity: 0.9; }

        /* Table Styling */
        #post-task-tracker .task-table-container {
             overflow-x: auto;
        }
        #post-task-tracker .task-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            border-radius: 8px; /* Apply radius to table */
             border: 1px solid var(--tracker-table-border-color); /* Border around table */
            background-color: var(--tracker-card-bg);
             min-width: 700px; /* Ensure minimum width */
             table-layout: fixed; /* More predictable column widths */
        }
        #post-task-tracker .task-table th {
            background: var(--tracker-table-header-bg);
            color: var(--tracker-button-primary-text);
            padding: 12px 10px; /* Adjusted padding */
            text-align: left;
            font-weight: bold;
            text-transform: uppercase;
            letter-spacing: 0.5px;
             transition: background-color 0.3s;
             font-size: 0.8em;
             border-bottom: 2px solid var(--tracker-table-border-color); /* Stronger header bottom border */
        }
         /* Set column widths */
         #post-task-tracker .task-table th:nth-child(1) { width: 20%; } /* Task */
         #post-task-tracker .task-table th:nth-child(2) { width: 10%; } /* Priority */
         #post-task-tracker .task-table th:nth-child(3) { width: 15%; } /* Progress */
         #post-task-tracker .task-table th:nth-child(4) { width: 12%; } /* Start Date */
         #post-task-tracker .task-table th:nth-child(5) { width: 12%; } /* Due Date */
         #post-task-tracker .task-table th:nth-child(6) { width: 21%; } /* Remarks */
         #post-task-tracker .task-table th:nth-child(7) { width: 10%; text-align: center; } /* Action */


        #post-task-tracker .task-table td {
            border-bottom: 1px solid var(--tracker-table-border-color);
            padding: 10px 10px; /* Adjusted padding */
            color: var(--tracker-text-color);
            transition: border-color 0.3s, color 0.3s;
            font-size: 0.9em;
            vertical-align: middle;
             word-wrap: break-word; /* Use word-wrap instead of break-word */
             overflow-wrap: break-word; /* Better word breaking */
        }
        #post-task-tracker .task-table tr:last-child td {
            border-bottom: none;
        }
        #post-task-tracker .task-table tbody tr:hover {
             background-color: var(--tracker-hover-bg);
        }
         /* Style for empty table message */
         #post-task-tracker .empty-message td {
             text-align: center;
             padding: 30px;
             font-style: italic;
             color: var(--tracker-text-color);
             opacity: 0.7;
             background-color: transparent !important; /* Override hover */
         }
         #post-task-tracker .task-table td:nth-child(7) { /* Action column centered */
            text-align: center;
         }

        /* Progress Bar */
        #post-task-tracker .progress-bar-container { /* Add container for layout */
             display: flex;
             align-items: center;
             gap: 5px; /* Space between bar and text */
        }
        #post-task-tracker .progress-bar {
            flex-grow: 1; /* Allow bar to take available space */
            height: 10px;
            background: var(--tracker-progress-bar-bg);
            border-radius: 5px;
            overflow: hidden;
             transition: background-color 0.3s;
        }
        #post-task-tracker .progress-fill {
            height: 100%;
            background: var(--tracker-progress-fill-bg);
            transition: width 0.4s ease-out, background-color 0.3s;
            border-radius: 5px;
        }
        #post-task-tracker .progress-text {
            font-size: 0.9em;
            color: var(--tracker-text-color);
             min-width: 35px; /* Minimum width for text */
             text-align: right;
             flex-shrink: 0; /* Prevent text from shrinking */
        }

        /* Priority Badges */
        #post-task-tracker .priority {
            padding: 5px 10px;
            border-radius: 12px;
            color: white;
            text-align: center;
            font-size: 0.85em;
            font-weight: bold;
            display: inline-block;
            text-transform: capitalize;
             transition: background-color 0.3s;
        }
        #post-task-tracker .high { background: var(--tracker-priority-high-bg); }
        #post-task-tracker .medium { background: var(--tracker-priority-medium-bg); }
        #post-task-tracker .low { background: var(--tracker-priority-low-bg); }

        /* Action Buttons in Table */
         #post-task-tracker .action-buttons {
              white-space: nowrap;
         }
        #post-task-tracker .edit-btn {
            background: var(--tracker-button-primary-bg);
            color: var(--tracker-button-primary-text);
            padding: 6px 12px;
             margin-right: 5px;
        }
         #post-task-tracker .edit-btn:hover { opacity: 0.9; }

        #post-task-tracker .delete-btn {
            background: var(--tracker-button-danger-bg);
            color: var(--tracker-button-danger-text);
             padding: 6px 12px;
        }
         #post-task-tracker .delete-btn:hover { opacity: 0.9; }

         /* Footer (Optional) */
         #post-task-tracker footer {
             text-align: center;
             margin-top: 40px;
             padding-top: 20px;
             font-size: 0.85em;
             color: var(--tracker-text-color);
             opacity: 0.6;
             border-top: 1px solid var(--tracker-table-border-color);
         }
        /* Utility class for hiding elements */
        #post-task-tracker .hidden {
            display: none !important; /* Use important to override potential conflicts */
        }

    &lt;/style&gt;
    &lt;!-- END: Tracker-Specific Styles --&gt;


    &lt;!-- START: Tracker HTML --&gt;
    &lt;!-- Header --&gt;
    &lt;header&gt;
        &lt;h1&gt;Task Tracker&lt;/h1&gt;
        &lt;p id="currentDate"&gt;&lt;!-- Date will be inserted here --&gt;&lt;/p&gt;
    &lt;/header&gt;

    &lt;!-- Theme Switch Button --&gt;
    &lt;div class="theme-switch-wrapper"&gt;
        &lt;button id="themeSwitch"&gt;Switch Theme&lt;/button&gt; &lt;!-- Text updated by JS --&gt;
    &lt;/div&gt;

    &lt;!-- Add/Edit Form --&gt;
    &lt;div class="task-form"&gt;
        &lt;h2&gt;Add / Edit Task&lt;/h2&gt;
        &lt;input type="hidden" id="taskId"&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="taskName"&gt;Task Name&lt;/label&gt;
            &lt;input type="text" id="taskName" required&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="priority"&gt;Priority&lt;/label&gt;
            &lt;select id="priority" required&gt;
                &lt;option value="high"&gt;High&lt;/option&gt;
                &lt;option value="medium" selected&gt;Medium&lt;/option&gt;
                &lt;option value="low"&gt;Low&lt;/option&gt;
            &lt;/select&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="progress"&gt;Progress (%)&lt;/label&gt;
            &lt;input type="number" id="progress" min="0" max="100" value="0" required&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="startDate"&gt;Start Date&lt;/label&gt;
            &lt;input type="date" id="startDate" required&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="dueDate"&gt;Due Date&lt;/label&gt;
            &lt;input type="date" id="dueDate" required&gt;
        &lt;/div&gt;
        &lt;div class="form-group"&gt;
            &lt;label for="remarks"&gt;Remarks&lt;/label&gt;
            &lt;textarea id="remarks" rows="3"&gt;&lt;/textarea&gt;
        &lt;/div&gt;
        &lt;button type="button" id="submitBtn"&gt;Add Task&lt;/button&gt;
    &lt;/div&gt;

    &lt;!-- Task Table --&gt;
    &lt;div class="task-table-container"&gt;
        &lt;table class="task-table"&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;Task&lt;/th&gt;
                    &lt;th&gt;Priority&lt;/th&gt;
                    &lt;th&gt;Progress&lt;/th&gt;
                    &lt;th&gt;Start Date&lt;/th&gt;
                    &lt;th&gt;Due Date&lt;/th&gt;
                    &lt;th&gt;Remarks&lt;/th&gt;
                    &lt;th&gt;Action&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody id="taskList"&gt;
                &lt;!-- Template row for empty state --&gt;
                &lt;tr id="emptyMessageRow" class="empty-message hidden"&gt;
                     &lt;td colspan="7"&gt;No tasks yet. Add one above!&lt;/td&gt;
                &lt;/tr&gt;
                &lt;!-- Task rows injected by JS --&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/div&gt;

    &lt;!-- Footer --&gt;
    &lt;footer&gt;
        Task Tracker © &lt;span id="currentYear"&gt;&lt;!-- Year inserted by JS --&gt;&lt;/span&gt;
    &lt;/footer&gt;
    &lt;!-- END: Tracker HTML --&gt;


&lt;/div&gt;&lt;!-- END: #post-task-tracker Container --&gt;


&lt;!-- START: Tracker Script (Scoped &amp; Fixed) --&gt;
&lt;script&gt;
    // Wrap everything in a function to avoid global scope pollution
    (function() {
        // Use the container ID for scoping selectors
        const trackerContainerId = 'post-task-tracker';
        const trackerContainer = document.getElementById(trackerContainerId);

        if (!trackerContainer) {
            console.error('Task tracker container "#' + trackerContainerId + '" not found!');
            return; // Stop if the container doesn't exist
        }

        // --- DOM Elements (Scoped within the container) ---
        // Helper function to query within the specific container
        const $ = (selector) =&gt; trackerContainer.querySelector(selector);
        const $$ = (selector) =&gt; trackerContainer.querySelectorAll(selector);

        const taskList = $('#taskList');
        const submitBtn = $('#submitBtn');
        const themeSwitchBtn = $('#themeSwitch');
        const taskNameInput = $('#taskName');
        const priorityInput = $('#priority');
        const progressInput = $('#progress');
        const startDateInput = $('#startDate');
        const dueDateInput = $('#dueDate');
        const remarksInput = $('#remarks');
        const taskIdInput = $('#taskId');
        const currentDateEl = $('#currentDate');
        const currentYearEl = $('#currentYear');
        const selectElements = $$('.form-group select');
        const emptyMessageRow = $('#emptyMessageRow');
        const formInputs = $$('.task-form input, .task-form select, .task-form textarea'); // For error clearing

        // --- Utility Functions ---
        function escapeHtml(unsafe) {
            if (typeof unsafe !== 'string') return String(unsafe);
            return unsafe.replace(/&amp;/g, "&amp;").replace(/&lt;/g, "&lt;").replace(/&gt;/g, "&gt;").replace(/"/g, "\"").replace(/'/g, "'");
        }

        function formatDate(dateString) {
            if (!dateString || typeof dateString !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
                return 'N/A';
            }
            const options = { year: 'numeric', month: 'short', day: 'numeric', timeZone: 'UTC' };
             try {
                 const date = new Date(dateString + 'T00:00:00Z');
                 if (isNaN(date.getTime())) { return 'Invalid Date'; }
                 return date.toLocaleDateString('en-US', options);
             } catch (e) {
                 console.error("Error formatting date:", dateString, e);
                 return dateString;
             }
        }

        function clearInputErrors() {
             formInputs.forEach(input =&gt; input.classList.remove('error'));
        }

        function highlightInputError(inputElement) {
            if (inputElement) { inputElement.classList.add('error'); }
        }

        // --- Theme Switching Logic ---
        function updateSelectArrowColor() {
            try {
                // Get variable value *relative to the container* in case styles are nested
                const arrowColorVar = getComputedStyle(trackerContainer).getPropertyValue('--tracker-select-arrow-color').trim();
                // Basic hex check - adjust if using other formats
                const arrowColor = arrowColorVar &amp;&amp; /^#[0-9A-Fa-f]{3,6}$/.test(arrowColorVar) ? arrowColorVar.substring(1) : 'e0e0e0';
                // URL Encode the color for the SVG string
                const encodedColor = encodeURIComponent('#' + arrowColor);
                const svgArrow = `&lt;svg fill="${encodedColor}" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"&gt;&lt;path d="M7 10l5 5 5-5z"/&gt;&lt;path d="M0 0h24v24H0z" fill="none"/&gt;&lt;/svg&gt;`;
                selectElements.forEach(select =&gt; {
                    select.style.backgroundImage = `url('data:image/svg+xml;utf8,${svgArrow}')`;
                });
             } catch (e) {
                 console.error("Error updating select arrow color:", e);
             }
        }

        function applyTheme(theme) {
             // Use the scoped container for class toggling
            if (theme === 'light') {
                trackerContainer.classList.add('tracker-light-mode');
                if (themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Dark Mode';
            } else {
                trackerContainer.classList.remove('tracker-light-mode');
                if (themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Light Mode';
            }
            // Use a unique local storage key for this instance
            localStorage.setItem('trackerTheme', theme);
            updateSelectArrowColor(); // Update arrows after theme change
        }

        // --- Task Logic ---
        let tasks = [];
        const localStorageKey = 'trackerTasks'; // Unique key for tasks

        function loadTasks() {
            const storedTasks = localStorage.getItem(localStorageKey);
            try {
                tasks = storedTasks ? JSON.parse(storedTasks) : [];
                if (!Array.isArray(tasks)) { tasks = []; }
            } catch (e) { tasks = []; console.error("Error loading tasks:", e); }
        }

        function saveTasks() {
            try { localStorage.setItem(localStorageKey, JSON.stringify(tasks)); }
            catch (e) { console.error("Error saving tasks:", e); }
        }

        function renderTasks() {
            if (!taskList || !emptyMessageRow) { return; } // Exit if elements missing
            taskList.innerHTML = ''; // Clear previous task rows

            if (tasks.length === 0) {
                emptyMessageRow.classList.remove('hidden');
                taskList.appendChild(emptyMessageRow); // Ensure it's appended if table was emptied
            } else {
                emptyMessageRow.classList.add('hidden');
                tasks.forEach((task, index) =&gt; {
                    if (typeof task !== 'object' || task === null) return;

                    const row = document.createElement('tr');
                    const taskName = task.taskName ?? 'N/A';
                    const priority = task.priority ?? 'medium';
                    const progress = Math.max(0, Math.min(100, task.progress ?? 0)); // Clamp progress 0-100
                    const startDate = task.startDate ?? '';
                    const dueDate = task.dueDate ?? '';
                    const remarks = task.remarks ?? '';

                    row.innerHTML = `
                        &lt;td&gt;${escapeHtml(taskName)}&lt;/td&gt;
                        &lt;td&gt;&lt;span class="priority ${escapeHtml(priority)}"&gt;${escapeHtml(priority)}&lt;/span&gt;&lt;/td&gt;
                        &lt;td&gt;
                            &lt;div class="progress-bar-container"&gt;
                                &lt;div class="progress-bar"&gt;
                                    &lt;div class="progress-fill" style="width: ${progress}%"&gt;&lt;/div&gt;
                                &lt;/div&gt;
                                &lt;span class="progress-text"&gt;${progress}%&lt;/span&gt;
                            &lt;/div&gt;
                        &lt;/td&gt;
                        &lt;td&gt;${formatDate(startDate)}&lt;/td&gt;
                        &lt;td&gt;${formatDate(dueDate)}&lt;/td&gt;
                        &lt;td&gt;${escapeHtml(remarks) || '-'}&lt;/td&gt;
                        &lt;td&gt;
                            &lt;div class="action-buttons"&gt;
                                 &lt;button type="button" class="edit-btn" data-index="${index}"&gt;Edit&lt;/button&gt;
                                 &lt;button type="button" class="delete-btn" data-index="${index}"&gt;Delete&lt;/button&gt;
                            &lt;/div&gt;
                        &lt;/td&gt;
                    `;
                    taskList.appendChild(row);
                });
            }
        }

        function addOrUpdateTask() {
            clearInputErrors();
            let isValid = true;
            const errors = [];

            const taskName = taskNameInput.value.trim();
            const priority = priorityInput.value;
            const progressString = progressInput.value;
            const startDate = startDateInput.value;
            const dueDate = dueDateInput.value;
            const remarks = remarksInput.value.trim();
            const editingIndex = taskIdInput.value;

            // Validation...
            if (!taskName) { isValid = false; highlightInputError(taskNameInput); errors.push("Task Name"); }
            const progress = parseInt(progressString, 10);
            if (progressString === '' || isNaN(progress) || progress &lt; 0 || progress &gt; 100) { isValid = false; highlightInputError(progressInput); errors.push("Progress (0-100)"); }
            if (!startDate) { isValid = false; highlightInputError(startDateInput); errors.push("Start Date"); }
            if (!dueDate) { isValid = false; highlightInputError(dueDateInput); errors.push("Due Date"); }

            if (isValid &amp;&amp; startDate &amp;&amp; dueDate) {
                const start = new Date(startDate); const due = new Date(dueDate);
                if (start &gt; due) { isValid = false; highlightInputError(startDateInput); highlightInputError(dueDateInput); errors.push("Start Date &gt; Due Date"); }
            }

            if (!isValid) {
                alert("Please correct the highlighted fields: " + errors.join(', '));
                return;
            }

            const newTaskData = { taskName, priority, progress, startDate, dueDate, remarks };

            try {
                if (editingIndex !== "") { // Update
                    const index = parseInt(editingIndex, 10);
                    if (!isNaN(index) &amp;&amp; index &gt;= 0 &amp;&amp; index &lt; tasks.length) { tasks[index] = newTaskData; }
                    else { throw new Error("Invalid index for update"); }
                } else { // Add
                    tasks.push(newTaskData);
                }
            } catch (e) {
                alert("Error saving task: " + e.message); return;
            }

            saveTasks();
            clearForm();
            renderTasks();
        }

        function handleTableClick(event) {
            const target = event.target;
            const editButton = target.closest('.edit-btn');
            const deleteButton = target.closest('.delete-btn');

            if (editButton &amp;&amp; editButton.dataset.index !== undefined) {
                editTask(parseInt(editButton.dataset.index, 10));
            } else if (deleteButton &amp;&amp; deleteButton.dataset.index !== undefined) {
                deleteTask(parseInt(deleteButton.dataset.index, 10));
            }
        }

        function editTask(index) {
            if (isNaN(index) || index &lt; 0 || index &gt;= tasks.length) return;
            const task = tasks[index];
            if (!task) return;

            clearInputErrors();
            taskNameInput.value = task.taskName ?? '';
            priorityInput.value = task.priority ?? 'medium';
            progressInput.value = task.progress ?? 0;
            startDateInput.value = task.startDate ?? '';
            dueDateInput.value = task.dueDate ?? '';
            remarksInput.value = task.remarks ?? '';
            taskIdInput.value = index;

            submitBtn.textContent = 'Update Task';
            taskNameInput.focus();
            // Scroll form into view gently
            const formElement = $('.task-form');
            if (formElement) formElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }

        function deleteTask(index) {
            if (isNaN(index) || index &lt; 0 || index &gt;= tasks.length) return;
            const taskNameToDelete = tasks[index]?.taskName || `task ${index+1}`;
            if (confirm(`Delete task: "${taskNameToDelete}"?`)) {
                tasks.splice(index, 1);
                saveTasks();
                renderTasks();
                if (taskIdInput.value === String(index)) clearForm(); // Clear form if deleted task was being edited
            }
        }

        function clearForm() {
            // Use querySelector within the container to get form elements
            const form = $('form'); // Assuming form elements are within a form tag is safer if true
            // if (form) form.reset(); // If using a &lt;form&gt; tag, reset() is easier
            // else { // Manual reset if no form tag
                taskNameInput.value = '';
                priorityInput.value = 'medium';
                progressInput.value = 0;
                startDateInput.value = '';
                dueDateInput.value = '';
                remarksInput.value = '';
                taskIdInput.value = '';
            // }
            submitBtn.textContent = 'Add Task';
            clearInputErrors();
        }

         function initializeApp() {
             if (!trackerContainer) return; // Stop if container wasn't found earlier

             // Set date/year
             const today = new Date();
             if (currentDateEl) currentDateEl.textContent = today.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
             if (currentYearEl) currentYearEl.textContent = today.getFullYear();

             loadTasks();

             // Load saved theme or default to dark for THIS INSTANCE
             const savedTheme = localStorage.getItem('trackerTheme') || 'dark'; // Use unique key
             applyTheme(savedTheme); // Apply theme and update arrows

             // --- Add Event Listeners (Check elements exist) ---
             if(themeSwitchBtn) {
                 themeSwitchBtn.addEventListener('click', () =&gt; {
                     const currentThemeIsLight = trackerContainer.classList.contains('tracker-light-mode');
                     applyTheme(currentThemeIsLight ? 'dark' : 'light');
                 });
             } else console.error("Theme switch button not found inside tracker container!");

             if (submitBtn) {
                 submitBtn.addEventListener('click', addOrUpdateTask);
             } else console.error("Submit button not found inside tracker container!");

             if (taskList) {
                 taskList.addEventListener('click', handleTableClick);
             } else console.error("Task list container not found inside tracker container!");

             // Initial render
             renderTasks();
         }

        // --- Run Initialization ---
         // Use DOMContentLoaded specific to this script block might be safer
         // if the script is placed before the HTML in the post.
         // However, running directly might work if script is after HTML.
         // Let's stick to DOMContentLoaded for robustness.
         if (document.readyState === 'loading') { // Loading hasn't finished yet
             document.addEventListener('DOMContentLoaded', initializeApp);
         } else { // `DOMContentLoaded` has already fired
             initializeApp();
         }

    })(); // IIFE to contain scope
&lt;/script&gt;
&lt;!-- END: Tracker Script --&gt;

&lt;!-- END: Complete Self-Contained Task Tracker Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Expense Tracker</title><link>http://rajclick.blogspot.com/2025/03/expense-tracker.html</link><category>Tracker app</category><pubDate>Mon, 10 Mar 2025 08:44:00 -0700</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-7371444752166367953</guid><description>&lt;!-- PASTE EVERYTHING BELOW THIS LINE INTO BLOGGER'S *HTML VIEW* EDITOR --&gt;

&lt;style&gt;
  /* --- Styles specifically for the expense tracker app within Blogger --- */

  /* Define color variables for themes (within the app wrapper) */
  #expense-tracker-blogger-app { /* Using the wrapper ID */
    /* Default: Dark Mode */
    --et-bg-color: #121212;
    --et-text-color: #e0e0e0;
    --et-card-bg-color: #1e1e1e;
    --et-card-shadow-color: rgba(255, 255, 255, 0.1);
    --et-icon-color: #e0e0e0;
    --et-border-color: #333;
    --et-primary-color: #4CAF50;
    --et-primary-text-color: #ffffff;
    --et-danger-color: #f44336;
    --et-danger-text-color: #ffffff;
    --et-export-color: #2196F3;
    --et-export-text-color: #ffffff;
    --et-input-bg-color: #333;
    --et-input-text-color: #e0e0e0;
    --et-input-border-color: #555;
    --et-modal-bg-overlay: rgba(0, 0, 0, 0.7);
    --et-modal-content-bg: #2a2a2a;
    --et-switch-bg: #555;
    --et-switch-slider-bg: #ccc;
    --et-switch-slider-checked-bg: var(--et-primary-color);

    /* Apply base styles directly to the wrapper */
    font-family: Arial, sans-serif;
    background-color: var(--et-bg-color);
    color: var(--et-text-color);
    padding: 20px 5%; /* Add some padding */
    box-sizing: border-box;
    transition: background-color 0.3s, color 0.3s;
    /* Remove body-specific styles like display:flex, min-height */
  }

  /* Light Mode overrides (applied to the wrapper) */
  #expense-tracker-blogger-app.light-mode {
    --et-bg-color: #f9f9f9;
    --et-text-color: #333333;
    --et-card-bg-color: #ffffff;
    --et-card-shadow-color: rgba(0, 0, 0, 0.1);
    --et-icon-color: #000000;
    --et-border-color: #ddd;
    --et-input-bg-color: #ffffff;
    --et-input-text-color: #333333;
    --et-input-border-color: #ccc;
    --et-modal-bg-overlay: rgba(0, 0, 0, 0.5);
    --et-modal-content-bg: #ffffff;
    --et-switch-bg: #ccc;
    --et-switch-slider-bg: #fff;
  }

  /* --- Prefixed Styles --- */
  /* Add #expense-tracker-blogger-app prefix to ALL selectors */

  #expense-tracker-blogger-app .container {
    width: 100%; /* Let it fill the wrapper */
    max-width: 1200px;
    margin: 0 auto; /* Center container within the wrapper */
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  #expense-tracker-blogger-app h1,
  #expense-tracker-blogger-app h2 {
    text-align: center;
    padding: 15px;
    color: var(--et-text-color); /* Use app variables */
  }
  #expense-tracker-blogger-app h2 {
      margin-top: 20px;
  }

  /* Theme Switch Styles (Position relative to the wrapper) */
  #expense-tracker-blogger-app .theme-switch-wrapper {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-bottom: 15px;
    width: 100%;
    max-width: 1200px; /* Match container max-width */
    margin-left: auto; /* Push to the right */
    margin-right: auto; /* Center the max-width block */
    padding: 0 5%; /* Align with container padding if needed */
    box-sizing: border-box;
    color: var(--et-text-color); /* Ensure label uses theme color */
  }
  #expense-tracker-blogger-app .theme-switch {
    display: inline-block;
    height: 24px;
    position: relative;
    width: 50px;
    margin-left: 10px;
  }
  #expense-tracker-blogger-app .theme-switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }
  #expense-tracker-blogger-app .slider {
    background-color: var(--et-switch-bg);
    bottom: 0;
    cursor: pointer;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    transition: .4s;
    border-radius: 24px;
  }
  #expense-tracker-blogger-app .slider:before {
    background-color: var(--et-switch-slider-bg);
    bottom: 3px;
    content: "";
    height: 18px;
    left: 4px;
    position: absolute;
    transition: .4s;
    width: 18px;
    border-radius: 50%;
  }
  #expense-tracker-blogger-app input:checked + .slider {
    background-color: var(--et-switch-slider-checked-bg);
  }
  #expense-tracker-blogger-app input:checked + .slider:before {
    transform: translateX(26px);
  }


  /* Categories grid */
  #expense-tracker-blogger-app .categories-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    grid-gap: 15px;
    margin-bottom: 25px;
    width: 100%;
  }
  #expense-tracker-blogger-app .category {
    background: var(--et-card-bg-color);
    border-radius: 8px;
    box-shadow: 0 2px 5px var(--et-card-shadow-color);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 15px;
    transition: background-color 0.3s, box-shadow 0.3s, transform 0.2s;
    text-align: center;
    color: var(--et-text-color);
  }
  #expense-tracker-blogger-app .category:hover {
     transform: translateY(-2px);
     box-shadow: 0 4px 8px var(--et-card-shadow-color);
  }
  #expense-tracker-blogger-app .category i {
    font-size: 40px;
    color: var(--et-icon-color);
    margin-bottom: 8px;
  }
  #expense-tracker-blogger-app .category span {
    font-weight: bold;
    font-size: 0.9em;
  }

  /* Summary section */
  #expense-tracker-blogger-app .summary {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 20px 0;
    width: 100%;
  }
  #expense-tracker-blogger-app .summary div {
    background: var(--et-card-bg-color);
    padding: 12px 18px;
    border-radius: 8px;
    box-shadow: 0 2px 5px var(--et-card-shadow-color);
    text-align: center;
    color: var(--et-text-color);
    transition: background-color 0.3s, box-shadow 0.3s;
  }

  /* Buttons Container */
  #expense-tracker-blogger-app .button-container {
      text-align: center;
      margin-bottom: 25px;
      width: 100%;
  }

  /* Buttons */
  #expense-tracker-blogger-app button {
    padding: 10px 20px;
    margin: 5px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-weight: bold;
    transition: background-color 0.3s, opacity 0.3s;
  }
  #expense-tracker-blogger-app button:hover {
      opacity: 0.9;
  }
  #expense-tracker-blogger-app .btn-primary {
    background-color: var(--et-primary-color);
    color: var(--et-primary-text-color);
  }
  #expense-tracker-blogger-app .btn-danger {
    background-color: var(--et-danger-color);
    color: var(--et-danger-text-color);
  }
  #expense-tracker-blogger-app .btn-export {
    background-color: var(--et-export-color);
    color: var(--et-export-text-color);
  }

  /* Expense List */
  #expense-tracker-blogger-app #expenseList {
      width: 100%;
      max-width: 600px;
      margin: 0 auto;
  }
  #expense-tracker-blogger-app #expenseList div { /* Style list item container */
      background: var(--et-card-bg-color);
      margin: 8px 0;
      padding: 15px;
      border-radius: 8px;
      box-shadow: 0 2px 5px var(--et-card-shadow-color);
      color: var(--et-text-color);
      transition: background-color 0.3s, box-shadow 0.3s;
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
  }
   #expense-tracker-blogger-app #expenseList div &gt; div { /* Target the inner content div */
      flex-grow: 1;
      padding: 0;
      margin: 0 10px 0 0; /* Add right margin */
      box-shadow: none;
      background: transparent;
      /* Reset inherited styles if needed */
      border-radius: 0;
      display: block; /* Ensure it behaves like a block */
   }
  #expense-tracker-blogger-app #expenseList strong {
      color: var(--et-primary-color);
      display: inline; /* Ensure strong and span are inline */
  }
   #expense-tracker-blogger-app #expenseList span { /* Target amount span specifically if needed */
       display: inline;
       /* Add other styles if needed */
   }
  #expense-tracker-blogger-app #expenseList small {
      display: block;
      margin: 3px 0;
      color: var(--et-text-color);
      opacity: 0.8;
  }
  #expense-tracker-blogger-app #expenseList em {
      display: block;
      color: var(--et-text-color);
      opacity: 0.9;
      font-style: normal;
      margin-top: 3px;
  }
  #expense-tracker-blogger-app #expenseList p { /* Style for 'No expenses' message */
      text-align: center;
      padding: 20px;
      color: var(--et-text-color);
      opacity: 0.7;
      background: transparent; /* Ensure no card background */
      box-shadow: none;
  }
  #expense-tracker-blogger-app #expenseList button { /* Style delete button */
      padding: 6px 12px;
      margin: 5px 0 5px 10px;
      flex-shrink: 0;
  }

  /* Modal styles */
  /* Modal needs to be outside the main flow, position fixed relative to viewport */
  .et-modal { /* Use a class for the modal itself */
    display: none;
    position: fixed; /* Relative to viewport */
    z-index: 10000; /* High z-index for Blogger */
    left: 0; top: 0;
    width: 100%; height: 100%;
    background-color: var(--et-modal-bg-overlay, rgba(0, 0, 0, 0.7)); /* Default fallback */
    transition: background-color 0.3s;
    overflow-y: auto;
  }
  .et-modal-content { /* Use a class */
    background: var(--et-modal-content-bg, #2a2a2a);
    color: var(--et-text-color, #e0e0e0);
    margin: 10% auto;
    padding: 25px;
    border-radius: 8px;
    width: 90%;
    max-width: 400px;
    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
    position: relative;
    transition: background-color 0.3s;
  }
  .et-modal .et-close { /* Use classes */
    position: absolute;
    top: 10px;
    right: 15px;
    color: var(--et-text-color, #e0e0e0);
    font-size: 32px;
    font-weight: bold;
    cursor: pointer;
    line-height: 1;
    text-decoration: none; /* Remove underline if it appears */
  }
   .et-modal .et-close:hover {
      opacity: 0.7;
  }
   .et-modal h3 {
      margin-top: 0;
      margin-bottom: 15px;
      color: var(--et-text-color, #e0e0e0);
  }
   .et-modal label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
      color: var(--et-text-color, #e0e0e0);
  }

   .et-modal input[type="number"],
   .et-modal input[type="text"] {
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    box-sizing: border-box;
    background-color: var(--et-input-bg-color, #333);
    color: var(--et-input-text-color, #e0e0e0);
    border: 1px solid var(--et-input-border-color, #555);
    border-radius: 4px;
    transition: background-color 0.3s, border-color 0.3s;
  }
   .et-modal input[type="number"]:focus,
   .et-modal input[type="text"]:focus {
      outline: none;
      border-color: var(--et-primary-color, #4CAF50);
  }

  /* Ensure modal button uses app styles */
   .et-modal .btn-primary {
      display: block;
      width: 100%;
      margin-top: 10px;
      background-color: var(--et-primary-color);
      color: var(--et-primary-text-color);
   }
   .et-modal .btn-primary:hover {
       opacity: 0.9;
   }

  /* SEO Content Styling */
  #expense-tracker-blogger-app #seo-content {
    padding: 20px;
    background: var(--et-card-bg-color);
    border-radius: 8px;
    margin-bottom: 25px;
    box-shadow: 0 2px 5px var(--et-card-shadow-color);
    width: 100%;
    max-width: 800px;
    text-align: left;
    color: var(--et-text-color);
    transition: background-color 0.3s, box-shadow 0.3s;
  }
  #expense-tracker-blogger-app #seo-content h2 {
      text-align: left;
      margin-top: 0;
      padding: 0 0 10px 0;
      color: var(--et-primary-color);
  }
  #expense-tracker-blogger-app #seo-content p {
      line-height: 1.6;
      margin-bottom: 10px;
      color: var(--et-text-color); /* Ensure p tag color */
  }

&lt;/style&gt;

&lt;!-- Unique ID Wrapper for the entire App --&gt;
&lt;div id="expense-tracker-blogger-app"&gt;

  &lt;!-- Theme Switch (place it where you want it within the wrapper) --&gt;
  &lt;div class="theme-switch-wrapper"&gt;
      &lt;span id="et-theme-label"&gt;Light Mode&lt;/span&gt; &lt;!-- Added ID for JS --&gt;
      &lt;label class="theme-switch" for="et-checkbox"&gt; &lt;!-- Changed ID --&gt;
          &lt;input type="checkbox" id="et-checkbox" /&gt;
          &lt;div class="slider round"&gt;&lt;/div&gt;
      &lt;/label&gt;
  &lt;/div&gt;

  &lt;!-- Main App Container --&gt;
  &lt;div class="container"&gt;
    &lt;h1&gt;Expense Tracker&lt;/h1&gt;

    &lt;!-- SEO Content Start --&gt;
    &lt;section id="seo-content"&gt;
      &lt;h2&gt;About This Expense Tracker&lt;/h2&gt;
      &lt;p&gt;
        This Expense Tracker is a simple yet powerful tool designed to help you
        manage your day-to-day finances... [rest of your SEO content] ...Use the switch to toggle between dark (default) and light modes.
      &lt;/p&gt;
    &lt;/section&gt;
    &lt;!-- SEO Content End --&gt;

    &lt;div class="categories-grid" id="categoriesGrid"&gt;
      &lt;!-- Categories will be inserted here by JS --&gt;
    &lt;/div&gt;

    &lt;div class="summary" id="summaryStats"&gt;
      &lt;div id="todaySummary"&gt;Today: ₹0&lt;/div&gt;
      &lt;div id="weekSummary"&gt;This Week: ₹0&lt;/div&gt;
      &lt;div id="monthSummary"&gt;This Month: ₹0&lt;/div&gt;
      &lt;div id="allTimeSummary"&gt;All Time: ₹0&lt;/div&gt;
    &lt;/div&gt;

    &lt;div class="button-container"&gt;
      &lt;button class="btn-export" onclick="etApp.exportCSV()"&gt;Export to CSV&lt;/button&gt; &lt;!-- Prefixed JS Call --&gt;
      &lt;button class="btn-danger" onclick="etApp.clearAllData()"&gt;Clear All Data&lt;/button&gt; &lt;!-- Prefixed JS Call --&gt;
    &lt;/div&gt;

    &lt;h2&gt;Expense List&lt;/h2&gt;
    &lt;div id="expenseList"&gt;
        &lt;!-- Expense items will be inserted here --&gt;
    &lt;/div&gt;
  &lt;/div&gt; &lt;!-- End .container --&gt;

&lt;/div&gt; &lt;!-- End #expense-tracker-blogger-app --&gt;


&lt;!-- Modal for adding an expense (Outside the main wrapper for fixed positioning) --&gt;
&lt;!-- Note: The modal background/text colors depend on the theme applied to the wrapper --&gt;
&lt;div id="expenseModal" class="et-modal"&gt; &lt;!-- Use class for styling --&gt;
  &lt;div class="et-modal-content"&gt; &lt;!-- Use class for styling --&gt;
    &lt;span class="et-close" onclick="etApp.closeModal()" title="Close"&gt;×&lt;/span&gt; &lt;!-- Prefixed JS Call --&gt;
    &lt;h3&gt;Add Expense - &lt;span id="modalCategory"&gt;&lt;/span&gt;&lt;/h3&gt;
    &lt;label for="expenseAmount"&gt;Amount (₹):&lt;/label&gt;
    &lt;input type="number" id="expenseAmount" placeholder="Enter amount" required&gt;
    &lt;label for="expenseNotes"&gt;Notes:&lt;/label&gt;
    &lt;input type="text" id="expenseNotes" placeholder="Enter details (optional)"&gt;
    &lt;button class="btn-primary" onclick="etApp.saveExpense()"&gt;Save Expense&lt;/button&gt; &lt;!-- Prefixed JS Call --&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;script&gt;
// Wrap all JS in an IIFE and expose functions via a namespace
(function() {
    'use strict'; // Enable strict mode

    // Get the main app wrapper element
    const appWrapper = document.getElementById('expense-tracker-blogger-app');
    if (!appWrapper) {
        console.error("Expense Tracker Error: Cannot find main wrapper #expense-tracker-blogger-app");
        return; // Stop if the main container isn't found
    }

    // Define categories (same as before)
    const categories = [
        { name: "Groceries", icon: "local_grocery_store" }, { name: "Electricity", icon: "flash_on" },
        { name: "Rent", icon: "home" }, { name: "Water Bill", icon: "opacity" },
        { name: "Internet", icon: "wifi" }, { name: "Mobile Recharge", icon: "smartphone" },
        { name: "LPG/Gas", icon: "local_fire_department" },
        { name: "Education", icon: "school" }, { name: "Transport", icon: "directions_bus" },
        { name: "Metro/Train", icon: "train" }, { name: "Auto/Rickshaw", icon: "local_taxi" },
        { name: "Fuel", icon: "local_gas_station" }, { name: "Dining Out", icon: "restaurant" },
        { name: "Healthcare", icon: "local_hospital" }, { name: "Medicines", icon: "medical_services" },
        { name: "Entertainment", icon: "theaters" }, { name: "Shopping", icon: "shopping_bag" },
        { name: "Clothing", icon: "checkroom" }, { name: "Gifts", icon: "card_giftcard" },
        { name: "Domestic Help", icon: "cleaning_services" }, { name: "Home Repairs", icon: "build" },
        { name: "Insurance", icon: "verified_user" }, { name: "Investments", icon: "trending_up" },
        { name: "EMI/Loan", icon: "account_balance" }, { name: "Savings", icon: "savings" },
        { name: "Childcare", icon: "child_friendly" }, { name: "Fitness/Gym", icon: "fitness_center" },
        { name: "Travel", icon: "flight" }, { name: "Festival", icon: "celebration" },
        { name: "Miscellaneous", icon: "more_horiz" }
    ];

    let selectedCategory = "";

    // --- THEME SWITCH LOGIC (Targets the wrapper) ---
    const themeToggle = document.getElementById('et-checkbox'); // Use updated ID
    const themeLabel = document.getElementById('et-theme-label'); // Get label
    const currentTheme = localStorage.getItem('et_theme'); // Use prefixed storage key

    // Function to set the theme on the wrapper
    function setTheme(theme) {
        if (!appWrapper || !themeToggle || !themeLabel) return; // Safety check

        if (theme === 'light') {
            appWrapper.classList.add('light-mode');
            themeToggle.checked = true;
            themeLabel.textContent = 'Dark Mode'; // Update label text
            localStorage.setItem('et_theme', 'light'); // Use prefixed key
            // Apply theme vars to modal if needed (optional, CSS vars should cascade)
            updateModalTheme('light');
        } else {
            appWrapper.classList.remove('light-mode');
            themeToggle.checked = false;
            themeLabel.textContent = 'Light Mode'; // Update label text
            localStorage.setItem('et_theme', 'dark'); // Use prefixed key
            updateModalTheme('dark');
        }
    }
     // Function to explicitly update modal theme vars if CSS cascade isn't enough
    function updateModalTheme(theme) {
        const modal = document.getElementById('expenseModal');
        if (!modal) return;
        const styles = getComputedStyle(appWrapper); // Get computed styles from the themed wrapper
        modal.style.setProperty('--et-modal-bg-overlay', styles.getPropertyValue('--et-modal-bg-overlay'));
        // Update modal content styles (optional, usually inherits via CSS vars)
         const modalContent = modal.querySelector('.et-modal-content');
         if(modalContent) {
             modalContent.style.setProperty('--et-modal-content-bg', styles.getPropertyValue('--et-modal-content-bg'));
             modalContent.style.setProperty('--et-text-color', styles.getPropertyValue('--et-text-color'));
             // Update input styles if necessary
             modalContent.querySelectorAll('input').forEach(input =&gt; {
                 input.style.setProperty('--et-input-bg-color', styles.getPropertyValue('--et-input-bg-color'));
                 input.style.setProperty('--et-input-text-color', styles.getPropertyValue('--et-input-text-color'));
                 input.style.setProperty('--et-input-border-color', styles.getPropertyValue('--et-input-border-color'));
             });
         }

    }

    // Apply saved theme or default dark
    setTheme(currentTheme || 'dark');

    // Listener for theme toggle
    if (themeToggle) {
        themeToggle.addEventListener('change', function() {
            setTheme(this.checked ? 'light' : 'dark');
        });
    }
    // --- END THEME SWITCH LOGIC ---

    // --- Core App Functions --- (Keep these largely the same)
    function renderCategories() {
      const grid = document.getElementById('categoriesGrid');
      if (!grid) return;
      grid.innerHTML = '';
      categories.forEach(cat =&gt; {
        const div = document.createElement('div');
        div.className = 'category';
        // Use Material Icons class directly if needed
        div.innerHTML = `&lt;i class="material-icons"&gt;${cat.icon}&lt;/i&gt;&lt;span&gt;&lt;/span&gt;`;
        div.querySelector('span').textContent = cat.name;
        // Call namespaced function
        div.onclick = () =&gt; etApp.openModal(cat.name);
        grid.appendChild(div);
      });
    }

    function openModal(category) {
      selectedCategory = category;
      const modal = document.getElementById('expenseModal');
      const categorySpan = document.getElementById('modalCategory');
      const amountInput = document.getElementById('expenseAmount');
      const notesInput = document.getElementById('expenseNotes');

      if (!modal || !categorySpan || !amountInput || !notesInput) return;

      categorySpan.textContent = category;
      amountInput.value = '';
      notesInput.value = '';
      modal.style.display = 'block';
       // Ensure modal colors match current theme when opened
       updateModalTheme(localStorage.getItem('et_theme') || 'dark');
      amountInput.focus();
    }

    function closeModal() {
      const modal = document.getElementById('expenseModal');
      if (modal) modal.style.display = 'none';
    }

    function saveExpense() {
      const amountInput = document.getElementById('expenseAmount');
      const notesInput = document.getElementById('expenseNotes');
      if (!amountInput || !notesInput) return;

      const amount = parseFloat(amountInput.value);
      if (isNaN(amount) || amount &lt;= 0) {
        alert('Please enter a valid positive amount.');
        amountInput.focus();
        return;
      }
      const notes = notesInput.value.trim();
      const expense = {
        id: Date.now(),
        category: selectedCategory,
        amount: amount,
        notes: notes,
        date: new Date().toISOString()
      };

      let expenses = JSON.parse(localStorage.getItem('et_expenses')) || []; // Prefixed storage
      expenses.push(expense);
      localStorage.setItem('et_expenses', JSON.stringify(expenses)); // Prefixed storage

      closeModal();
      updateExpenseList();
      updateSummary();
    }

    function updateExpenseList() {
      const listDiv = document.getElementById('expenseList');
      if (!listDiv) return;
      listDiv.innerHTML = '';
      let expenses = JSON.parse(localStorage.getItem('et_expenses')) || []; // Prefixed storage

      if (expenses.length === 0) {
        listDiv.innerHTML = '&lt;p&gt;No expenses recorded yet. Tap a category to add one!&lt;/p&gt;';
        return;
      }
      expenses.sort((a, b) =&gt; new Date(b.date) - new Date(a.date));

      expenses.forEach(exp =&gt; {
        const itemDiv = document.createElement('div');
        const contentDiv = document.createElement('div');
        // ... (rest of element creation is the same as before) ...
         const categoryStrong = document.createElement('strong');
        categoryStrong.textContent = exp.category;
        const amountSpan = document.createElement('span');
        amountSpan.textContent = ` - ₹${exp.amount.toFixed(2)}`;
        const dateSmall = document.createElement('small');
        dateSmall.textContent = new Date(exp.date).toLocaleString();

        contentDiv.appendChild(categoryStrong);
        contentDiv.appendChild(amountSpan);
        contentDiv.appendChild(dateSmall);

        if (exp.notes) {
          const notesEm = document.createElement('em');
          notesEm.textContent = exp.notes;
          contentDiv.appendChild(notesEm);
        }

        const deleteButton = document.createElement('button');
        deleteButton.textContent = 'Delete';
        deleteButton.className = 'btn-danger';
        // Call namespaced function
        deleteButton.onclick = () =&gt; etApp.deleteExpense(exp.id);

        itemDiv.appendChild(contentDiv);
        itemDiv.appendChild(deleteButton);
        listDiv.appendChild(itemDiv);
      });
    }

    function deleteExpense(id) {
        if (confirm(`Are you sure you want to delete this expense?`)) {
            let expenses = JSON.parse(localStorage.getItem('et_expenses')) || []; // Prefixed storage
            expenses = expenses.filter(exp =&gt; exp.id !== id);
            localStorage.setItem('et_expenses', JSON.stringify(expenses)); // Prefixed storage
            updateExpenseList();
            updateSummary();
        }
    }

    function updateSummary() {
      let expenses = JSON.parse(localStorage.getItem('et_expenses')) || []; // Prefixed storage
      const today = new Date();
      const todayStart = new Date(today.setHours(0, 0, 0, 0));
      const weekStart = new Date(todayStart);
      weekStart.setDate(todayStart.getDate() - today.getDay() + (today.getDay() === 0 ? -6 : 1)); // Assuming week starts Monday
      const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);

      let sumToday = 0, sumWeek = 0, sumMonth = 0, sumAll = 0;
      expenses.forEach(exp =&gt; {
        const expAmount = exp.amount;
        const expDate = new Date(exp.date);
        sumAll += expAmount;
        if (expDate &gt;= todayStart) sumToday += expAmount;
        if (expDate &gt;= weekStart) sumWeek += expAmount;
        if (expDate &gt;= monthStart) sumMonth += expAmount;
      });

      const todayEl = document.getElementById('todaySummary');
      const weekEl = document.getElementById('weekSummary');
      const monthEl = document.getElementById('monthSummary');
      const allTimeEl = document.getElementById('allTimeSummary');

      if(todayEl) todayEl.textContent = `Today: \u20B9${sumToday.toFixed(2)}`;
  if(weekEl) weekEl.textContent = `This Week: \u20B9${sumWeek.toFixed(2)}`;
  if(monthEl) monthEl.textContent = `This Month: \u20B9${sumMonth.toFixed(2)}`;
  if(allTimeEl) allTimeEl.textContent = `All Time: \u20B9${sumAll.toFixed(2)}`;
    }

    function exportCSV() {
      let expenses = JSON.parse(localStorage.getItem('et_expenses')) || []; // Prefixed storage
      if (expenses.length === 0) {
        alert("No expenses to export!");
        return;
      }
      let csvContent = "data:text/csv;charset=utf-8,";
      csvContent += "Category,Amount,Notes,Date\n";
      expenses.forEach(exp =&gt; {
        const notesEscaped = `"${exp.notes.replace(/"/g, '""')}"`;
        let row = [
          exp.category, exp.amount.toFixed(2), notesEscaped, `"${new Date(exp.date).toLocaleString()}"`
        ].join(",");
        csvContent += row + "\n";
      });
      const encodedUri = encodeURI(csvContent);
      const link = document.createElement("a");
      link.setAttribute("href", encodedUri);
      link.setAttribute("download", "expenses.csv");
      // Append to the app wrapper instead of body
      appWrapper.appendChild(link);
      link.click();
      appWrapper.removeChild(link);
    }

    function clearAllData() {
      if (confirm("WARNING: This will permanently delete all expense data for this tracker. Are you sure?")) {
        localStorage.removeItem('et_expenses'); // Prefixed storage
        updateExpenseList();
        updateSummary();
        alert("All expense data has been cleared.");
      }
    }

    // --- Initialization ---
    // Check if elements exist before running updates
    function initializeApp() {
        if (document.getElementById('categoriesGrid') &amp;&amp; document.getElementById('expenseList')) {
             renderCategories();
             updateExpenseList();
             updateSummary();
             console.log("Expense Tracker Initialized.");
        } else {
            console.error("Expense Tracker Error: Missing essential elements (categoriesGrid or expenseList).");
        }
    }

    // Use DOMContentLoaded for safety, even within Blogger post
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initializeApp);
    } else {
        initializeApp(); // Already loaded
    }


    // --- Event Listeners for Modal ---
    // Close modal on outside click
    const modalElement = document.getElementById('expenseModal');
    if (modalElement) {
        modalElement.addEventListener('click', function(event) {
            if (event.target === modalElement) {
                closeModal();
            }
        });
    }

    // Close modal on Escape key press (attach to document)
    document.addEventListener('keydown', function(event) {
        const modal = document.getElementById('expenseModal');
        // Check if modal exists and is visible
        if (event.key === "Escape" &amp;&amp; modal &amp;&amp; modal.style.display === 'block') {
            closeModal();
        }
    });

    // --- Expose necessary functions to the global scope via a namespace ---
    window.etApp = {
        openModal: openModal,
        closeModal: closeModal,
        saveExpense: saveExpense,
        deleteExpense: deleteExpense,
        exportCSV: exportCSV,
        clearAllData: clearAllData
    };

})(); // End IIFE
&lt;/script&gt;

&lt;!-- END OF CODE TO PASTE --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Voice to Text</title><link>http://rajclick.blogspot.com/2025/03/voice-to-text.html</link><pubDate>Sun, 2 Mar 2025 04:15:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-6595089364910569258</guid><description>&lt;div class="voice-container"&gt;
    &lt;div class="theme-toggle" id="themeToggle"&gt;Toggle Theme&lt;/div&gt;
    &lt;div class="voice-input-group"&gt;
        &lt;input type="text" id="voiceInput" placeholder="Speak or type here..."&gt;
        &lt;button id="voiceButton" aria-label="Start voice input"&gt;
            &lt;svg width="24" height="24" viewBox="0 0 24 24"&gt;
                &lt;path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm-1 1.93c-3.94-.49-7-3.85-7-7.93h2c0 3.31 2.69 6 6 6s6-2.69 6-6h2c0 4.08-3.06 7.44-7 7.93V19h4v2H8v-2h4v-3.07z"/&gt;
            &lt;/svg&gt;
        &lt;/button&gt;
        &lt;div id="voiceStatus" class="status-message"&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="google-logo"&gt;
        &lt;svg viewBox="0 0 48 48" width="24" height="24" fill="currentColor"&gt;
            &lt;path d="M43.57 12.17C43.57 12.17 42.2 10.68 40.31 10.07C40.77 9.87 41.37 9.89 41.98 10.15C42.16 9.84 42.39 9.53 42.63 9.23C43.08 9.23 43.64 9.48 43.83 9.92C45.19 9.49 46.19 8.63 46.19 7.73C46.19 6.83 45.19 5.88 43.83 6.19C43.83 5.88 43.08 5.68 42.63 5.68C42.39 5.68 42.16 5.97 42.16 6.19C40.31 5.53 40.53 5.5 40.53 5.5C19.2 5.09 8.59 16.34 8.59 27.67C8.59 28.6 8.9 29.55 9.51 30.38C8.59 30.38 7.75 31.85 7.75 33.5C7.75 34.92 8.59 36.21 9.74 36.21C9.75 36.21 14.37 31.7 27.67 31.7C27.68 31.7 27.69 31.7 27.7 31.7C27.69 31.7 27.68 31.7 27.67 31.7C12.1 31.7 14.71 30.85 15.1 30.85C14.71 30.85 15.55 30.2 15.55 30.2C14.48 32.56 13.24 35.06 13.24 37.67C13.24 37.87 13.28 38.09 13.35 38.28C13.9 39.09 15.03 39.36 15.5 39.36C15.37 39.36 15.24 39.36 15.11 39.36C15.5 39.36 16.0 39.37 16.0 39.37C16.0 39.83 16.22 40.27 16.53 40.53C16.53 40.53 21.34 38.95 25.09 45.97C22.94 45.03 21.44 43.4 21.07 41.65C21.07 41.65 20.35 40.6 18.51 40.6C17.93 40.6 16.82 40.95 16.82 41.33C16.82 41.71 17.93 42 18.51 42C20.35 42 21.07 40.98 21.07 40.56C21.44 42.51 22.94 44.15 25.09 44.77C25.77 45.67 26.61 46.22 27.77 46.22C28.92 46.22 29.77 45.66 30.5 44.78C31.79 45.16 33.18 45.57 34.57 45.57C34.71 45.57 35.87 45.44 36.08 45.14C35.34 45.33 35.09 45.48 35.09 45.48C35.09 45.48 34.58 44.48 34.58 43.24C34.58 43.24 35.27 40.97 34.87 39.08C34.87 39.08 36.42 39.95 37.99 39.3C37.99 39.3 39.59 35.7 37.69 33.38C39.64 33.38 40.92 34.18 41.56 35.25C41.56 35.25 39.95 36.35 38.71 36.77C38.71 36.77 37.22 36.8 36.02 36.8C36.02 36.8 36.02 36.8 36.02 36.8C36.02 36.8 37.14 37.16 38.41 37.16C38.41 37.16 40.34 37.16 40.34 37.16C40.34 37.16 39.53 37.67 38.61 37.67C38.61 37.67 38.72 38.95 37.96 39.42C37.96 39.42 36.01 38.77 36.01 38.77C36.01 38.77 37.43 40.57 35.17 41.87C35.17 41.87 2.17 45.17 43.57 12.17Z"/&gt;
        &lt;/svg&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;style&gt;
.voice-container {
    max-width: 600px;
    margin: 20px auto;
    padding: 20px;
    background: rgba(0, 0, 0, 0.1);
    backdrop-filter: blur(10px);
    border-radius: 12px;
    position: relative;
}

.theme-toggle {
    position: absolute;
    top: 20px;
    right: 20px;
    cursor: pointer;
    font-size: 0.875rem;
    padding: 5px 12px;
    border: 1px solid #999;
    border-radius: 20px;
    transition: all 0.3s ease;
}

.theme-toggle:hover {
    background: #999;
    color: white;
}

.voice-input-group {
    position: relative;
    background: transparent;
}

#voiceInput {
    width: 100%;
    padding: 12px 50px 12px 20px;
    font-size: 1rem;
    border: 2px solid #ddd;
    border-radius: 8px;
    outline: none;
    transition: border-color 0.3s;
    background: #fff;
    color: #1a1a1a;
}

#voiceInput:focus {
    border-color: #1a73e8;
}

#voiceButton {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    padding: 5px;
}

#voiceButton:hover path {
    fill: #1a73e8;
}

#voiceButton path {
    fill: #5f6368;
    transition: fill 0.3s;
}

.status-message {
    margin-top: 8px;
    font-size: 0.875rem;
    color: #5f6368;
    min-height: 20px;
}

.google-logo {
    position: absolute;
    top: 20px;
    left: 20px;
    color: #4285f4;
}
&lt;/style&gt;

&lt;script&gt;
document.addEventListener('DOMContentLoaded', function() {
    const themeToggle = document.getElementById('themeToggle');
    const container = document.querySelector('.voice-container');

    function toggleTheme() {
        if (container.getAttribute('data-theme') === 'dark') {
            container.setAttribute('data-theme', 'light');
            container.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
        } else {
            container.setAttribute('data-theme', 'dark');
            container.style.backgroundColor = 'rgba(0, 0, 0, 0.1)';
        }
        themeToggle.textContent = 
            (container.getAttribute('data-theme') === 'dark' ? 'Light' : 'Dark') + ' Mode';
    }

    themeToggle.addEventListener('click', toggleTheme);
});

// Speech recognition code remains the same as the previous implementation
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Text Case Converter</title><link>http://rajclick.blogspot.com/2025/03/text-case-converter.html</link><pubDate>Sun, 2 Mar 2025 03:53:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-6538839541147145517</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Text Case Converter Tool&lt;/title&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Arial', sans-serif;
        }

        body {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 800px;
            margin: 40px auto;
            background: white;
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
        }

        h1 {
            text-align: center;
            color: #2d3748;
            margin-bottom: 30px;
            font-size: 2.5em;
        }

        .converter-box {
            display: grid;
            gap: 20px;
        }

        textarea {
            width: 100%;
            height: 150px;
            padding: 15px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            resize: vertical;
            font-size: 16px;
            transition: border-color 0.3s ease;
        }

        textarea:focus {
            outline: none;
            border-color: #667eea;
        }

        .button-group {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 10px;
            margin: 15px 0;
        }

        button {
            padding: 12px 20px;
            background: #4a5568;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            transition: transform 0.2s ease, background 0.3s ease;
        }

        button:hover {
            background: #2d3748;
            transform: translateY(-2px);
        }

        .copy-btn {
            background: #48bb78;
        }

        .reset-btn {
            background: #f56565;
        }

        .result-box {
            position: relative;
            margin-top: 20px;
        }

        .char-count {
            text-align: right;
            color: #4a5568;
            margin-top: 10px;
            font-size: 0.9em;
        }

        @media (max-width: 600px) {
            .container {
                margin: 20px;
                padding: 20px;
            }
            
            h1 {
                font-size: 1.8em;
            }
        }
    &lt;/style&gt;
    
    &lt;!-- Google Analytics Code --&gt;
    &lt;script type="text/javascript"&gt;
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-26277044-1']);
        _gaq.push(['_trackPageview']);

        (function() {
            var ga = document.createElement('script');
            ga.type = 'text/javascript';
            ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0];
            s.parentNode.insertBefore(ga, s);
        })();
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="container"&gt;
        &lt;h1&gt;Text Case Converter&lt;/h1&gt;
        &lt;div class="converter-box"&gt;
            &lt;textarea id="input-text" placeholder="Enter your text here..." autofocus&gt;&lt;/textarea&gt;
            &lt;div class="button-group"&gt;
                &lt;button onclick="convertCase('upper')"&gt;UPPERCASE&lt;/button&gt;
                &lt;button onclick="convertCase('lower')"&gt;lowercase&lt;/button&gt;
                &lt;button onclick="convertCase('title')"&gt;Title Case&lt;/button&gt;
                &lt;button onclick="convertCase('kebab')"&gt;kebab-case&lt;/button&gt;
                &lt;button onclick="convertCase('sentence')"&gt;Sentence case&lt;/button&gt;
            &lt;/div&gt;
            &lt;textarea id="output-text" readonly placeholder="Converted text will appear here..."&gt;&lt;/textarea&gt;
            &lt;div class="char-count" id="char-count"&gt;Characters: 0&lt;/div&gt;
            &lt;div class="button-group"&gt;
                &lt;button class="copy-btn" onclick="copyText()"&gt;Copy Result&lt;/button&gt;
                &lt;button class="reset-btn" onclick="resetAll()"&gt;Reset All&lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        function convertCase(type) {
            const input = document.getElementById('input-text').value;
            let output = '';

            switch(type) {
                case 'upper':
                    output = input.toUpperCase();
                    break;
                case 'lower':
                    output = input.toLowerCase();
                    break;
                case 'title':
                    output = input.toLowerCase().split(' ')
                            .map(word =&gt; word.charAt(0).toUpperCase() + word.slice(1))
                            .join(' ');
                    break;
                case 'kebab':
                    output = input.toLowerCase().replace(/\s+/g, '-');
                    break;
                case 'sentence':
                    output = input.toLowerCase().replace(/^\w|\.\s\w/g, 
                        match =&gt; match.toUpperCase());
                    break;
                default:
                    output = input;
            }

            document.getElementById('output-text').value = output;
            updateCharCount();
        }

        function copyText() {
            const output = document.getElementById('output-text');
            output.select();
            document.execCommand('copy');
        }

        function resetAll() {
            document.getElementById('input-text').value = '';
            document.getElementById('output-text').value = '';
            document.getElementById('char-count').textContent = 'Characters: 0';
        }

        function updateCharCount() {
            const text = document.getElementById('input-text').value;
            document.getElementById('char-count').textContent = `Characters: ${text.length}`;
        }

        // Update character count on input
        document.getElementById('input-text').addEventListener('input', updateCharCount);
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Stopwatch &amp; Timer</title><link>http://rajclick.blogspot.com/2025/03/stopwatch-timer.html</link><category>Tracker app</category><pubDate>Sun, 2 Mar 2025 03:47:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-1894458178273299402</guid><description>&lt;!-- START: Complete Self-Contained Stopwatch &amp; Timer Block --&gt;

&lt;!-- Main container for the tool with a unique ID for scoping --&gt;
&lt;div id="post-stopwatch-timer"&gt;

    &lt;!-- START: Tool-Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles to this container */
        #post-stopwatch-timer {
            /* --- CSS Variables for Theming (Default: Dark) --- */
            --swt-bg-color: #2a2a2a;         /* Dark card background */
            --swt-text-color: #e0e0e0;       /* Light text */
            --swt-heading-color: #79baff;    /* Lighter blue for headings */
            --swt-border-color: #444;        /* Dark border */
            --swt-tab-bg: #333;             /* Dark inactive tab */
            --swt-tab-active-bg: #00796b;    /* Active tab green */
            --swt-tab-active-text: #ffffff;
            --swt-tab-text: #b0b0b0;        /* Inactive tab text */
            --swt-display-text: #f0f0f0;     /* Display text color */
            --swt-input-bg: #383838;         /* Dark input bg */
            --swt-input-border: #555;       /* Dark input border */
            --swt-input-text: #e0e0e0;      /* Light input text */
            --swt-button-primary-bg: #00796b; /* Green start */
            --swt-button-primary-text: #ffffff;
            --swt-button-stop-bg: #c62828;   /* Red stop */
            --swt-button-reset-bg: #ff8f00;  /* Orange reset */
            --swt-button-text: #ffffff;
            --swt-shadow-color: rgba(0, 0, 0, 0.3);
            --swt-explanation-text: #b0b0b0; /* Explanation text */

            /* Base styles */
            font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--swt-bg-color);
            color: var(--swt-text-color);
            padding: 25px; /* Adjusted padding */
            border-radius: 15px; /* Slightly less rounded */
            box-shadow: 0 6px 20px var(--swt-shadow-color);
            width: 100%;
            max-width: 700px; /* Allow slightly wider */
            margin: 25px auto; /* Center block */
            border: 1px solid var(--swt-border-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            box-sizing: border-box;
            text-align: center; /* Center most content */
        }
        /* Apply box-sizing to all elements within */
        #post-stopwatch-timer *,
        #post-stopwatch-timer *::before,
        #post-stopwatch-timer *::after {
            box-sizing: border-box;
        }

        /* --- Light Mode Overrides --- */
        #post-stopwatch-timer.swt-light-mode {
            --swt-bg-color: #ffffff;
            --swt-text-color: #333;
            --swt-heading-color: #0a6ed1;
            --swt-border-color: #e0e0e0;
            --swt-tab-bg: #f0f0f0;          /* Light inactive tab */
            --swt-tab-active-bg: #4CAF50;   /* Light active tab green */
            --swt-tab-active-text: #ffffff;
            --swt-tab-text: #555;
            --swt-display-text: #212121;    /* Darker display text */
            --swt-input-bg: #ffffff;
            --swt-input-border: #ccc;
            --swt-input-text: #333;
            --swt-button-primary-bg: #4CAF50;
            --swt-button-stop-bg: #f44336;
            --swt-button-reset-bg: #ff9800;
            --swt-button-text: #ffffff;
            --swt-shadow-color: rgba(0, 0, 0, 0.1);
            --swt-explanation-text: #555;
        }

        /* --- Element Styles (Scoped) --- */
        #post-stopwatch-timer .tool-title { /* Optional overall title */
             font-size: 1.8rem;
             margin-bottom: 15px;
             color: var(--swt-heading-color);
        }

         /* Theme Switch Styling */
         #post-stopwatch-timer .theme-switch-wrapper {
            text-align: right;
            margin-bottom: 20px; /* Space below switch */
            /* Position adjustment if needed, but inline flow might be better */
            padding-right: 5px; /* Ensure some spacing from edge */
         }
         #post-stopwatch-timer #swtThemeSwitch {
            padding: 6px 12px;
            cursor: pointer;
            border-radius: 5px;
            border: 1px solid var(--swt-input-border);
            background-color: var(--swt-input-bg);
            color: var(--swt-text-color);
            font-weight: bold;
            font-size: 0.85em;
            transition: background-color 0.3s, color 0.3s, border-color 0.3s, opacity 0.2s;
         }
          #post-stopwatch-timer #swtThemeSwitch:hover { opacity: 0.85; }

        /* Tabs */
        #post-stopwatch-timer .tabs {
            display: flex;
            margin-bottom: 25px;
            border-radius: 8px; /* Rounded tabs container */
            overflow: hidden; /* Clip corners */
            border: 1px solid var(--swt-border-color);
        }
        #post-stopwatch-timer .tab {
            flex: 1;
            padding: 14px; /* Slightly more padding */
            text-align: center;
            cursor: pointer;
            background: var(--swt-tab-bg);
            color: var(--swt-tab-text);
            border: none;
            font-size: 1rem; /* Adjusted font size */
            font-weight: 600;
            transition: all 0.3s ease;
            border-left: 1px solid var(--swt-border-color); /* Separator */
        }
        #post-stopwatch-timer .tab:first-child {
             border-left: none; /* No border on first tab */
        }
        #post-stopwatch-timer .tab.active {
            background: var(--swt-tab-active-bg);
            color: var(--swt-tab-active-text);
            font-weight: bold;
        }
         #post-stopwatch-timer .tab:hover:not(.active) {
            opacity: 0.8;
         }

        /* Display Area */
        #post-stopwatch-timer .display {
            font-size: 3.5rem; /* Larger display */
            text-align: center;
            margin: 30px 0; /* More vertical margin */
            font-family: 'Courier New', Courier, monospace; /* Monospaced font */
            color: var(--swt-display-text);
            letter-spacing: 2px; /* Add some spacing */
            background-color: var(--swt-input-bg); /* Display bg */
            padding: 15px 10px;
            border-radius: 8px;
            border: 1px solid var(--swt-border-color);
        }

        /* Controls (Buttons) */
        #post-stopwatch-timer .controls {
            display: flex;
            justify-content: center;
            gap: 15px; /* More gap */
            margin-top: 25px;
        }
        #post-stopwatch-timer button.control-btn { /* Base button style */
            padding: 12px 25px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: bold;
            transition: transform 0.2s ease, background-color 0.2s ease;
            color: var(--swt-button-text);
            min-width: 100px; /* Minimum width for buttons */
        }
        #post-stopwatch-timer button.control-btn:hover { transform: scale(1.05); }
        #post-stopwatch-timer button.start-btn { background-color: var(--swt-button-primary-bg); }
        #post-stopwatch-timer button.stop-btn { background-color: var(--swt-button-stop-bg); }
        #post-stopwatch-timer button.reset-btn { background-color: var(--swt-button-reset-bg); }

        /* Timer Inputs */
        #post-stopwatch-timer .timer-inputs {
            display: flex;
            justify-content: center;
            align-items: center; /* Align items vertically */
            gap: 8px; /* Reduced gap slightly */
            margin: 25px 0 20px 0; /* Adjusted margins */
            font-size: 1.5rem; /* Make colons larger */
            color: var(--swt-text-color);
        }
        #post-stopwatch-timer .timer-inputs input {
            width: 70px; /* Slightly wider */
            padding: 10px; /* More padding */
            text-align: center;
            border: 1px solid var(--swt-input-border);
            background-color: var(--swt-input-bg);
            color: var(--swt-input-text);
            border-radius: 5px;
            font-size: 1.4rem; /* Larger font in inputs */
             font-family: 'Courier New', Courier, monospace;
        }
         #post-stopwatch-timer .timer-inputs input:focus {
            outline: none;
            border-color: var(--swt-heading-color);
         }
        #post-stopwatch-timer .timer-inputs input::placeholder {
            color: var(--swt-text-muted-color);
             opacity: 0.6;
             font-size: 1.1rem;
        }

        /* Hidden class */
        #post-stopwatch-timer .hidden {
            display: none !important;
        }

        /* Explanation Section Styling */
        #post-stopwatch-timer .swt-explanation {
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid var(--swt-border-color);
            font-size: 0.9rem;
            line-height: 1.6;
            color: var(--swt-explanation-text);
            text-align: left;
        }
        #post-stopwatch-timer .swt-explanation h4 {
             margin-bottom: 10px;
             color: var(--swt-text-color);
             font-size: 1.1rem;
        }
         #post-stopwatch-timer .swt-explanation p { margin-bottom: 10px; }
          #post-stopwatch-timer .swt-explanation ul { margin-left: 20px; margin-bottom: 10px; }

    &lt;/style&gt;
    &lt;!-- END: Tool-Specific Styles --&gt;


    &lt;!-- START: Tool HTML --&gt;
    &lt;h2 class="tool-title"&gt;Stopwatch &amp; Timer&lt;/h2&gt;

    &lt;!-- Local Theme Switch --&gt;
    &lt;div class="theme-switch-wrapper"&gt;
        &lt;button id="swtThemeSwitch"&gt;Switch Theme&lt;/button&gt; &lt;!-- Text set by JS --&gt;
    &lt;/div&gt;

    &lt;div class="tabs"&gt;
        &lt;button class="tab active" type="button" onclick="swtShowTab('stopwatch')"&gt;Stopwatch&lt;/button&gt;
        &lt;button class="tab" type="button" onclick="swtShowTab('timer')"&gt;Timer&lt;/button&gt;
    &lt;/div&gt;

    &lt;!-- Stopwatch Section --&gt;
    &lt;div id="stopwatchSection"&gt;
        &lt;div class="display" id="stopwatchDisplay"&gt;00:00:00.00&lt;/div&gt; &lt;!-- Added milliseconds --&gt;
        &lt;div class="controls"&gt;
            &lt;button class="control-btn start-btn" type="button" onclick="swtStartStopwatch()"&gt;Start&lt;/button&gt;
            &lt;button class="control-btn stop-btn" type="button" onclick="swtStopStopwatch()"&gt;Stop&lt;/button&gt;
            &lt;button class="control-btn reset-btn" type="button" onclick="swtResetStopwatch()"&gt;Reset&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Timer Section --&gt;
    &lt;div id="timerSection" class="hidden"&gt;
        &lt;div class="timer-inputs"&gt;
            &lt;input type="number" id="timerHours" min="0" placeholder="HH" aria-label="Hours"&gt;&lt;span&gt;:&lt;/span&gt;
            &lt;input type="number" id="timerMinutes" min="0" max="59" placeholder="MM" aria-label="Minutes"&gt;&lt;span&gt;:&lt;/span&gt;
            &lt;input type="number" id="timerSeconds" min="0" max="59" placeholder="SS" aria-label="Seconds"&gt;
        &lt;/div&gt;
        &lt;div class="display" id="timerDisplay"&gt;00:00:00&lt;/div&gt;
        &lt;div class="controls"&gt;
            &lt;button class="control-btn start-btn" type="button" onclick="swtStartTimer()"&gt;Start&lt;/button&gt;
            &lt;button class="control-btn reset-btn" type="button" onclick="swtResetTimer()"&gt;Reset&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- SEO Explanation Section --&gt;
    &lt;div class="swt-explanation"&gt;
        &lt;h4&gt;About This Stopwatch &amp; Timer&lt;/h4&gt;
        &lt;p&gt;
            This versatile tool provides both a precise stopwatch for measuring elapsed time and a countdown timer for managing your activities. Easily switch between modes using the tabs.
        &lt;/p&gt;
        &lt;h4&gt;How to Use:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Stopwatch:&lt;/strong&gt; Click "Start" to begin timing. "Stop" pauses the counter, and "Start" resumes it. "Reset" clears the time back to zero. It displays time down to hundredths of a second.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Timer:&lt;/strong&gt; Enter the desired hours, minutes, and seconds in the input fields. Click "Start" to begin the countdown. An alert will notify you when time is up. "Reset" clears the inputs and stops the timer.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;
            Useful for workouts, cooking, study sessions, meetings, or any situation where accurate time tracking or countdowns are needed.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;!-- END: Tool HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-stopwatch-timer Container --&gt;


&lt;!-- START: Tool Script (Scoped &amp; Themed) --&gt;
&lt;script&gt;
    // Wrap in IIFE
    (function() {
        const toolContainer = document.getElementById('post-stopwatch-timer');
        if (!toolContainer) { console.error("Stopwatch/Timer container not found."); return; }

        // Scoped DOM selectors
        const $ = (selector) =&gt; toolContainer.querySelector(selector);
        const $$ = (selector) =&gt; toolContainer.querySelectorAll(selector);

        // Theme Elements
        const themeSwitchBtn = $('#swtThemeSwitch');
        const localStorageThemeKey = 'stopwatchTimerTheme';

        // Stopwatch Elements
        const stopwatchDisplay = $('#stopwatchDisplay');
        const stopwatchSection = $('#stopwatchSection');

        // Timer Elements
        const timerDisplay = $('#timerDisplay');
        const timerSection = $('#timerSection');
        const hoursInput = $('#timerHours');
        const minutesInput = $('#timerMinutes');
        const secondsInput = $('#timerSeconds');

        // Tab Elements
        const tabs = $$('.tab');

        // Stopwatch State
        let stopwatchRunning = false;
        let stopwatchInterval;
        let stopwatchTime = 0; // Time in milliseconds
        let stopwatchStartTime = 0;

        // Timer State
        let timerRunning = false;
        let timerInterval;
        let timerTotalSetTime = 0; // Initial time set by user in ms
        let timerEndTime = 0; // Timestamp when timer should end

        // --- Theme Switching ---
        function applyTheme(theme) {
            if (theme === 'light') {
                toolContainer.classList.add('swt-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Dark Mode';
            } else {
                toolContainer.classList.remove('swt-light-mode');
                if(themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Light Mode';
            }
            localStorage.setItem(localStorageThemeKey, theme);
        }

        if (themeSwitchBtn) {
            themeSwitchBtn.addEventListener('click', () =&gt; {
                const currentThemeIsLight = toolContainer.classList.contains('swt-light-mode');
                applyTheme(currentThemeIsLight ? 'dark' : 'light');
            });
        }

        // --- Stopwatch Functions ---
        window.swtStartStopwatch = function() { // Make function global within IIFE scope for onclick
            if (!stopwatchRunning) {
                stopwatchRunning = true;
                stopwatchStartTime = Date.now() - stopwatchTime; // Adjust start time if resuming
                // Use requestAnimationFrame for smoother updates if available, fallback to setInterval
                 function tick() {
                    if (!stopwatchRunning) return;
                    stopwatchTime = Date.now() - stopwatchStartTime;
                    updateStopwatchDisplay();
                    stopwatchInterval = requestAnimationFrame(tick);
                }
                stopwatchInterval = requestAnimationFrame(tick);
                // Fallback (kept simple for blogger embed):
                // stopwatchInterval = setInterval(() =&gt; {
                //     if (!stopwatchRunning) return; // Check inside interval too
                //     stopwatchTime = Date.now() - stopwatchStartTime;
                //     updateStopwatchDisplay();
                // }, 10); // Update frequently for ms
            }
        }

        window.swtStopStopwatch = function() {
            if (stopwatchRunning) {
                stopwatchRunning = false;
                // Use cancelAnimationFrame if using it, else clearInterval
                 cancelAnimationFrame(stopwatchInterval);
                // clearInterval(stopwatchInterval);
            }
        }

        window.swtResetStopwatch = function() {
            swtStopStopwatch(); // Stop first
            stopwatchTime = 0;
            updateStopwatchDisplay(); // Update display to 0
        }

        function updateStopwatchDisplay() {
            if (!stopwatchDisplay) return;
            const totalMilliseconds = stopwatchTime;
            const milliseconds = String(Math.floor((totalMilliseconds % 1000) / 10)).padStart(2, '0'); // Get hundredths
            const totalSeconds = Math.floor(totalMilliseconds / 1000);
            const seconds = String(totalSeconds % 60).padStart(2, '0');
            const totalMinutes = Math.floor(totalSeconds / 60);
            const minutes = String(totalMinutes % 60).padStart(2, '0');
            const hours = String(Math.floor(totalMinutes / 60)).padStart(2, '0');

            stopwatchDisplay.textContent = `${hours}:${minutes}:${seconds}.${milliseconds}`;
        }


        // --- Timer Functions ---
        window.swtStartTimer = function() {
            if (timerRunning) return; // Don't restart if already running

            const hours = parseInt(hoursInput.value) || 0;
            const minutes = parseInt(minutesInput.value) || 0;
            const seconds = parseInt(secondsInput.value) || 0;

            timerTotalSetTime = (hours * 3600 + minutes * 60 + seconds) * 1000;

            if (timerTotalSetTime &lt;= 0) {
                alert('Please set a valid timer duration.');
                return;
            }

            timerRunning = true;
            timerEndTime = Date.now() + timerTotalSetTime; // Calculate end timestamp

             function tick() {
                 if (!timerRunning) return;

                 const remaining = Math.max(0, timerEndTime - Date.now()); // Calculate remaining ms

                 updateTimerDisplay(remaining);

                 if (remaining &lt;= 0) {
                     swtResetTimer(); // Reset automatically
                     // Optional: Play a sound or show a more prominent notification
                     alert('Time is up!');
                     // Maybe flash the display or change background?
                     if(timerDisplay) timerDisplay.style.animation = 'flash 1s infinite alternate';
                 } else {
                     // Continue the timer loop
                    timerInterval = requestAnimationFrame(tick);
                 }
             }
              timerInterval = requestAnimationFrame(tick);
             // Fallback:
             // timerInterval = setInterval(() =&gt; {
             //    if (!timerRunning) return;
             //     const remaining = Math.max(0, timerEndTime - Date.now());
             //     updateTimerDisplay(remaining);
             //     if (remaining &lt;= 0) {
             //         swtResetTimer();
             //         alert('Time is up!');
             //     }
             // }, 50); // Update less frequently for timer is usually fine
        }

        window.swtResetTimer = function() {
            timerRunning = false;
            // Use cancelAnimationFrame if using it, else clearInterval
             cancelAnimationFrame(timerInterval);
            // clearInterval(timerInterval);
            timerTotalSetTime = 0;
            timerEndTime = 0;
            if (hoursInput) hoursInput.value = '';
            if (minutesInput) minutesInput.value = '';
            if (secondsInput) secondsInput.value = '';
            updateTimerDisplay(0); // Reset display to 00:00:00
             if (timerDisplay) timerDisplay.style.animation = 'none'; // Stop flashing if any
        }

        function updateTimerDisplay(ms) {
            if (!timerDisplay) return;
            const totalSeconds = Math.max(0, Math.ceil(ms / 1000)); // Use ceil to show 00:01 before hitting 0
            const seconds = String(totalSeconds % 60).padStart(2, '0');
            const totalMinutes = Math.floor(totalSeconds / 60);
            const minutes = String(totalMinutes % 60).padStart(2, '0');
            const hours = String(Math.floor(totalMinutes / 60)).padStart(2, '0');

            timerDisplay.textContent = `${hours}:${minutes}:${seconds}`;
        }

        // --- Tab Switching ---
        window.swtShowTab = function(tabName) {
            tabs.forEach(tab =&gt; tab.classList.remove('active'));
            const activeTabButton = toolContainer.querySelector(`.tab[onclick="swtShowTab('${tabName}')"]`);
            if (activeTabButton) activeTabButton.classList.add('active');

            if (stopwatchSection) stopwatchSection.classList.toggle('hidden', tabName !== 'stopwatch');
            if (timerSection) timerSection.classList.toggle('hidden', tabName !== 'timer');

            // Optional: Stop the timer/stopwatch when switching tabs
             if (tabName !== 'stopwatch') swtStopStopwatch();
             // Resetting timer on switch might be annoying, maybe just stop?
             // if (tabName !== 'timer') swtResetTimer(); // Or just stop it?
             if (tabName !== 'timer' &amp;&amp; timerRunning) {
                  timerRunning = false;
                  cancelAnimationFrame(timerInterval);
                 // clearInterval(timerInterval);
                  // Keep display showing remaining time? Or reset? Let's keep it.
             }
        }

        // --- Input Validation ---
        $$('input[type="number"]').forEach(input =&gt; {
            input.addEventListener('input', function() {
                // Remove non-digit characters except potential leading negative (though min=0 handles this)
                this.value = this.value.replace(/[^0-9]/g, '');

                if (this.value === '') return; // Allow empty input temporarily

                let numValue = parseInt(this.value, 10);
                if (isNaN(numValue)) numValue = 0; // Handle NaN

                if (numValue &lt; 0) this.value = 0; // Enforce min 0

                if (this.id === 'timerMinutes' || this.id === 'timerSeconds') {
                    if (numValue &gt; 59) this.value = 59; // Enforce max 59
                }
                // Add max for hours if desired, e.g., if (this.id === 'timerHours' &amp;&amp; numValue &gt; 99) this.value = 99;
            });
             input.addEventListener('blur', function() {
                 // Optional: Pad with zero on blur if needed, e.g., for MM/SS format
                 // if ((this.id === 'timerMinutes' || this.id === 'timerSeconds') &amp;&amp; this.value.length === 1) {
                 //     this.value = this.value.padStart(2, '0');
                 // }
                 if (this.value === '') {
                      // Handle empty value on blur if needed (e.g., set to 0)
                      // this.value = '00'; // Example for MM/SS
                 }
             });
        });

        // --- Initialization ---
        function initialize() {
            if (!toolContainer) return; // Guard clause

            const savedTheme = localStorage.getItem(localStorageThemeKey) || 'dark';
            applyTheme(savedTheme);

            // Initial display states
            updateStopwatchDisplay();
            updateTimerDisplay(0);
            swtShowTab('stopwatch'); // Show stopwatch by default
        }

        // Run initialization
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initialize);
        } else {
            initialize();
        }

    })(); // End IIFE
&lt;/script&gt;
&lt;!-- END: Tool Script --&gt;

&lt;!-- Google Analytics removed - add back if specifically needed for this tool --&gt;

&lt;!-- END: Complete Self-Contained Stopwatch &amp; Timer Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>To - Do list</title><link>http://rajclick.blogspot.com/2025/03/to-do-list.html</link><category>Tracker app</category><pubDate>Sun, 2 Mar 2025 03:21:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-6839953290093483657</guid><description>&lt;!-- START: Complete Self-Contained To-Do List Block --&gt;

&lt;!-- Main container for the To-Do List with a unique ID --&gt;
&lt;div id="post-todo-list"&gt;

    &lt;!-- START: To-Do List Specific Styles (Scoped) --&gt;
    &lt;style&gt;
        /* Scope all styles to this container */
        #post-todo-list {
            /* --- CSS Variables for Theming (Default: Dark) --- */
            --todo-bg-color: #2a2a2a;         /* Dark container background */
            --todo-text-color: #e0e0e0;       /* Light text */
            --todo-heading-color: #79baff;    /* Lighter blue for headings */
            --todo-border-color: #444;        /* Dark border */
            --todo-input-bg: #333;           /* Dark input bg */
            --todo-input-border: #555;       /* Dark input border */
            --todo-input-text: #e0e0e0;      /* Light input text */
            --todo-button-primary-bg: #00796b; /* Green add button */
            --todo-button-primary-hover: #005a4f;
            --todo-button-secondary-bg: #4f5b62; /* Grey action buttons */
            --todo-button-secondary-hover: #3b444a;
            --todo-button-text: #ffffff;
            --todo-list-item-bg: #333d47;    /* Darker list item bg */
            --todo-list-item-shadow: rgba(0, 0, 0, 0.2);
            --todo-delete-color: #ff6b6b;      /* Red delete button */
            --todo-completed-text: #888;
            --todo-checkbox-accent: #00796b;
            --todo-shadow-color: rgba(0, 0, 0, 0.3);
            --todo-explanation-text: #b0b0b0;

            /* Base styles */
            font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--todo-bg-color);
            color: var(--todo-text-color);
            padding: 25px;
            border-radius: 10px;
            box-shadow: 0 5px 15px var(--todo-shadow-color);
            width: 100%;
            max-width: 700px; /* Use more space */
            margin: 25px auto; /* Center block */
            border: 1px solid var(--todo-border-color);
            transition: background-color 0.3s, color 0.3s, border-color 0.3s;
            box-sizing: border-box;
        }
        #post-todo-list *,
        #post-todo-list *::before,
        #post-todo-list *::after {
            box-sizing: border-box;
        }

        /* --- Light Mode Overrides --- */
        #post-todo-list.todo-light-mode {
            --todo-bg-color: #ffffff;
            --todo-text-color: #333;
            --todo-heading-color: #0a6ed1;
            --todo-border-color: #ddd;
            --todo-input-bg: #ffffff;
            --todo-input-border: #ccc;
            --todo-input-text: #333;
            --todo-button-primary-bg: #28a745;
            --todo-button-primary-hover: #218838;
            --todo-button-secondary-bg: #6c757d;
            --todo-button-secondary-hover: #5a6268;
            --todo-list-item-bg: #f9f9f9;
            --todo-list-item-shadow: rgba(0, 0, 0, 0.1);
            --todo-delete-color: #dc3545;
            --todo-completed-text: #6c757d;
            --todo-checkbox-accent: #28a745;
            --todo-shadow-color: rgba(0, 0, 0, 0.1);
            --todo-explanation-text: #555;
        }

        /* --- Element Styles (Scoped) --- */
        #post-todo-list h2 {
            text-align: center;
            margin-top: 0;
            margin-bottom: 15px;
            color: var(--todo-heading-color);
            font-size: 1.8rem;
        }

         /* Theme Switch */
        #post-todo-list .theme-switch-wrapper {
            text-align: right;
            margin-bottom: 20px;
         }
         #post-todo-list #todoThemeSwitch {
            padding: 6px 12px; cursor: pointer; border-radius: 5px;
            border: 1px solid var(--todo-input-border);
            background-color: var(--todo-input-bg); color: var(--todo-text-color);
            font-weight: bold; font-size: 0.85em; transition: all 0.2s;
         }
         #post-todo-list #todoThemeSwitch:hover { opacity: 0.85; }

        #post-todo-list .input-container {
            display: flex;
            gap: 10px;
            margin-bottom: 20px; /* Space before list starts */
        }

        #post-todo-list input[type="text"] {
            flex-grow: 1;
            padding: 12px;
            font-size: 1rem; /* Standardize font size */
            border: 1px solid var(--todo-input-border);
            background-color: var(--todo-input-bg);
            color: var(--todo-input-text);
            border-radius: 5px;
            transition: border-color 0.3s, background-color 0.3s, color 0.3s;
        }
         #post-todo-list input[type="text"]:focus {
            outline: none;
            border-color: var(--todo-heading-color);
         }

        #post-todo-list button.add-btn {
            padding: 12px 20px;
            font-size: 1rem;
            cursor: pointer;
            background: var(--todo-button-primary-bg);
            color: var(--todo-button-text);
            border: none;
            border-radius: 5px;
            transition: background-color 0.3s;
            flex-shrink: 0; /* Prevent button from shrinking */
        }
        #post-todo-list button.add-btn:hover {
            background: var(--todo-button-primary-hover);
        }

        #post-todo-list ul#taskList {
            list-style-type: none;
            padding: 0;
            margin: 0; /* Remove default margin */
        }

        #post-todo-list li.task-item {
            background: var(--todo-list-item-bg);
            padding: 12px 15px; /* Adjusted padding */
            margin-bottom: 8px; /* Space between items */
            display: flex;
            align-items: center;
            border-radius: 5px;
            box-shadow: 0 2px 5px var(--todo-list-item-shadow);
            font-size: 1rem;
            gap: 12px; /* Consistent gap */
            transition: background-color 0.3s;
             border: 1px solid var(--todo-border-color);
             word-break: break-word; /* Allow long words to break */
        }

        #post-todo-list li.task-item input[type="checkbox"] {
            transform: scale(1.3);
            flex-shrink: 0; /* Prevent checkbox shrinking */
            cursor: pointer;
             accent-color: var(--todo-checkbox-accent); /* Modern checkbox color */
        }

        #post-todo-list li.task-item .task-text {
            flex-grow: 1; /* Allow text to take available space */
             transition: color 0.3s, text-decoration 0.3s;
        }

        #post-todo-list li.task-item .task-text.completed {
            text-decoration: line-through;
            color: var(--todo-completed-text);
            font-style: italic;
        }

        #post-todo-list .delete-btn {
            cursor: pointer;
            color: var(--todo-delete-color);
            font-weight: bold;
            font-size: 1.2rem; /* Slightly larger delete X */
            padding: 0 5px; /* Add padding for easier clicking */
            flex-shrink: 0;
            transition: color 0.3s;
            user-select: none; /* Prevent text selection */
        }
         #post-todo-list .delete-btn:hover {
             opacity: 0.7;
         }

        #post-todo-list .actions {
            display: flex;
            justify-content: center;
            flex-wrap: wrap; /* Allow buttons to wrap on smaller screens */
            gap: 10px;
            margin-top: 25px;
            padding-top: 15px;
            border-top: 1px solid var(--todo-border-color);
        }
         #post-todo-list button.action-btn {
            padding: 10px 15px;
            font-size: 0.9rem;
            cursor: pointer;
            background: var(--todo-button-secondary-bg);
            color: var(--todo-button-text);
            border: none;
            border-radius: 5px;
            transition: background-color 0.3s;
         }
          #post-todo-list button.action-btn:hover {
              background: var(--todo-button-secondary-hover);
          }

         /* Hide actions initially or when no tasks */
         #post-todo-list .actions.hidden {
             display: none;
         }

         /* Explanation Section */
        #post-todo-list .todo-explanation {
            margin-top: 30px; padding-top: 20px;
            border-top: 1px solid var(--todo-border-color);
            font-size: 0.9rem; line-height: 1.6;
            color: var(--todo-explanation-text); text-align: left;
        }
        #post-todo-list .todo-explanation h4 { margin-bottom: 10px; color: var(--todo-text-color); font-size: 1.1rem; }
        #post-todo-list .todo-explanation p { margin-bottom: 10px; }
        #post-todo-list .todo-explanation ul { margin-left: 20px; margin-bottom: 10px; }

    &lt;/style&gt;
    &lt;!-- END: To-Do List Specific Styles --&gt;


    &lt;!-- START: To-Do List HTML --&gt;
    &lt;h2&gt;To-Do List&lt;/h2&gt;

     &lt;!-- Local Theme Switch --&gt;
     &lt;div class="theme-switch-wrapper"&gt;
        &lt;button id="todoThemeSwitch"&gt;Switch Theme&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class="input-container"&gt;
      &lt;input type="text" id="taskInput" placeholder="Enter a new task" /&gt;
      &lt;button class="add-btn" type="button" id="addTaskBtn"&gt;Add Task&lt;/button&gt;
    &lt;/div&gt;

    &lt;ul id="taskList"&gt;
        &lt;!-- Task items added by JS --&gt;
    &lt;/ul&gt;

    &lt;!-- Actions container --&gt;
    &lt;div class="actions hidden" id="taskListActions"&gt;
      &lt;button class="action-btn" type="button" id="downloadBtn"&gt;Download List&lt;/button&gt;
      &lt;button class="action-btn" type="button" id="closeAllBtn"&gt;Close All Tasks&lt;/button&gt;
      &lt;button class="action-btn" type="button" id="reopenAllBtn"&gt;Re-open All Tasks&lt;/button&gt;
    &lt;/div&gt;

     &lt;!-- SEO Explanation Section --&gt;
    &lt;div class="todo-explanation"&gt;
        &lt;h4&gt;About This To-Do List&lt;/h4&gt;
        &lt;p&gt;
            Keep track of your tasks efficiently with this simple and interactive To-Do List. Easily add, manage, and organize your daily or long-term goals.
        &lt;/p&gt;
        &lt;h4&gt;Features:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Add Tasks:&lt;/strong&gt; Quickly enter tasks using the input field and "Add Task" button or by pressing Enter.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Mark Complete:&lt;/strong&gt; Check the box next to a task to mark it as completed (strikethrough). Uncheck to mark it pending again.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Delete Tasks:&lt;/strong&gt; Remove individual tasks by clicking the "X" icon next to them.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Bulk Actions:&lt;/strong&gt; Use the "Close All" button to mark all tasks as complete, or "Re-open All" to mark them all as pending.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Download List:&lt;/strong&gt; Generate a simple text file (.txt) of your current task list with their status (Pending/Completed).&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Theme Switch:&lt;/strong&gt; Toggle between dark and light modes for comfortable viewing.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;
            This tool is perfect for personal task management, shopping lists, project steps, or any scenario where you need a quick and easy way to list and track items. Your list is saved locally in your browser.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;!-- END: To-Do List HTML --&gt;


&lt;/div&gt;&lt;!-- END: #post-todo-list Container --&gt;


&lt;!-- START: To-Do List Script (Scoped &amp; Themed - Fixed Delete Icon) --&gt;
&lt;script&gt;
    // Wrap in IIFE
    (function() {
        const todoContainer = document.getElementById('post-todo-list');
        if (!todoContainer) { console.error("To-Do List container not found!"); return; }

        // Scoped DOM selectors
        const $ = (selector) =&gt; todoContainer.querySelector(selector);
        const $$ = (selector) =&gt; todoContainer.querySelectorAll(selector);

        const taskInput = $('#taskInput');
        const addTaskBtn = $('#addTaskBtn');
        const taskList = $('#taskList');
        const taskListActions = $('#taskListActions');
        const downloadBtn = $('#downloadBtn');
        const closeAllBtn = $('#closeAllBtn');
        const reopenAllBtn = $('#reopenAllBtn');
        const themeSwitchBtn = $('#todoThemeSwitch');
        const localStorageThemeKey = 'todoListTheme';
        const localStorageTasksKey = 'todoListTasks';

        // --- Theme Switching ---
        function applyTheme(theme) {
            if (theme === 'light') {
                todoContainer.classList.add('todo-light-mode');
                if (themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Dark Mode';
            } else {
                todoContainer.classList.remove('todo-light-mode');
                if (themeSwitchBtn) themeSwitchBtn.textContent = 'Switch to Light Mode';
            }
            localStorage.setItem(localStorageThemeKey, theme);
        }

        if (themeSwitchBtn) {
            themeSwitchBtn.addEventListener('click', () =&gt; {
                const currentThemeIsLight = todoContainer.classList.contains('todo-light-mode');
                applyTheme(currentThemeIsLight ? 'dark' : 'light');
            });
        }

        // --- Task Management ---
        function loadTasks() {
            const tasks = JSON.parse(localStorage.getItem(localStorageTasksKey) || '[]');
            if (Array.isArray(tasks)) {
                tasks.forEach(taskData =&gt; createTaskElement(taskData.text, taskData.completed));
            }
            updateActionsVisibility();
        }

        function saveTasks() {
            const tasks = [];
            $$('#taskList li.task-item').forEach(li =&gt; {
                const checkbox = li.querySelector('input[type="checkbox"]');
                const taskTextSpan = li.querySelector('.task-text');
                if (checkbox &amp;&amp; taskTextSpan) {
                    tasks.push({
                        text: taskTextSpan.textContent,
                        completed: checkbox.checked
                    });
                }
            });
            localStorage.setItem(localStorageTasksKey, JSON.stringify(tasks));
        }

        function updateActionsVisibility() {
            if (!taskListActions) return;
            const taskCount = $$('#taskList li.task-item').length;
            taskListActions.classList.toggle('hidden', taskCount === 0);
        }

        function createTaskElement(taskText, isCompleted = false) {
             if (!taskText) return;

             const li = document.createElement("li");
             li.classList.add('task-item');

             const checkbox = document.createElement("input");
             checkbox.type = "checkbox";
             checkbox.checked = isCompleted;
             checkbox.addEventListener('change', () =&gt; {
                 taskTextSpan.classList.toggle("completed", checkbox.checked);
                 saveTasks();
             });

             const taskTextSpan = document.createElement("span");
             taskTextSpan.classList.add('task-text');
             taskTextSpan.textContent = taskText; // Use textContent for safety here
             if (isCompleted) {
                 taskTextSpan.classList.add("completed");
             }

             const deleteSpan = document.createElement("span");
             deleteSpan.classList.add("delete-btn");
             // *** THE FIX IS HERE: Use innerHTML to render the entity ***
             deleteSpan.innerHTML = "✗"; // Use HTML entity for '✕' or similar cross mark
             // Alternatively, if you prefer the exact symbol from image: deleteSpan.innerHTML = "✕";
             deleteSpan.title = "Delete Task";
             deleteSpan.addEventListener('click', () =&gt; {
                 li.remove();
                 updateActionsVisibility();
                 saveTasks();
             });

             li.appendChild(checkbox);
             li.appendChild(taskTextSpan);
             li.appendChild(deleteSpan);

             if (taskList) {
                 taskList.appendChild(li);
             }
        }

        function handleAddTask() {
            if (!taskInput) return;
            const taskText = taskInput.value.trim();
            if (taskText === "") {
                alert("Please enter a task.");
                return;
            }
            createTaskElement(taskText);
            taskInput.value = "";
            taskInput.focus();
            updateActionsVisibility();
            saveTasks();
        }

        // --- Action Button Functions ---
        function downloadList() {
            const tasks = $$("#taskList li.task-item");
            if (tasks.length === 0) { alert("No tasks to download."); return; }
            let text = "To-Do List:\n==========\n\n";
            tasks.forEach((li, index) =&gt; {
                const checkbox = li.querySelector("input[type='checkbox']");
                const taskTextSpan = li.querySelector(".task-text");
                if (checkbox &amp;&amp; taskTextSpan) {
                    const taskText = taskTextSpan.textContent;
                    const status = checkbox.checked ? "[X] Completed" : "[ ] Pending";
                    text += `${index + 1}. ${status} - ${taskText}\n`;
                }
            });
            const blob = new Blob([text], { type: "text/plain;charset=utf-8" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = url;
            const dateStr = new Date().toISOString().split('T')[0];
            a.download = `todo_list_${dateStr}.txt`;
            document.body.appendChild(a); a.click(); document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        function closeAllTasks() {
            const tasks = $$("#taskList li.task-item");
            if (tasks.length === 0) return; let changed = false;
            tasks.forEach(li =&gt; {
                const checkbox = li.querySelector("input[type='checkbox']");
                const taskTextSpan = li.querySelector(".task-text");
                if (checkbox &amp;&amp; !checkbox.checked &amp;&amp; taskTextSpan) {
                    checkbox.checked = true; taskTextSpan.classList.add("completed"); changed = true;
                }
            });
             if (changed) saveTasks();
        }

        function reopenAllTasks() {
            const tasks = $$("#taskList li.task-item");
             if (tasks.length === 0) return; let changed = false;
            tasks.forEach(li =&gt; {
                const checkbox = li.querySelector("input[type='checkbox']");
                const taskTextSpan = li.querySelector(".task-text");
                 if (checkbox &amp;&amp; checkbox.checked &amp;&amp; taskTextSpan) {
                    checkbox.checked = false; taskTextSpan.classList.remove("completed"); changed = true;
                }
            });
             if (changed) saveTasks();
        }

        // --- Initial Setup ---
        function initialize() {
            const savedTheme = localStorage.getItem(localStorageThemeKey) || 'dark';
            applyTheme(savedTheme);
            loadTasks();

            // Add Event Listeners
            if (addTaskBtn) addTaskBtn.addEventListener('click', handleAddTask);
            if (taskInput) {
                taskInput.addEventListener('keypress', (event) =&gt; {
                    if (event.key === "Enter") { event.preventDefault(); handleAddTask(); }
                });
            }
            if (downloadBtn) downloadBtn.addEventListener('click', downloadList);
            if (closeAllBtn) closeAllBtn.addEventListener('click', closeAllTasks);
            if (reopenAllBtn) reopenAllBtn.addEventListener('click', reopenAllTasks);
        }

        // Run initialization
        if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); }
        else { initialize(); }

    })(); // End IIFE
&lt;/script&gt;
&lt;!-- END: To-Do List Script --&gt;

&lt;!-- Google Analytics removed --&gt;

&lt;!-- END: Complete Self-Contained To-Do List Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>QR Code Generator - Generates a QR code from a text or URL input.</title><link>http://rajclick.blogspot.com/2025/03/qr-code-generator-generates-qr-code.html</link><pubDate>Sun, 2 Mar 2025 03:18:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-6532330301587781985</guid><description>&lt;!-- START: Complete Self-Contained QR Code Generator Block --&gt;

&lt;!-- Container for the QR generator with a unique ID for scoping --&gt;
&lt;div id="post-qr-generator"&gt;

  &lt;!-- START: QR Generator-Specific Styles (Scoped) --&gt;
  &lt;style&gt;
    /* Scope all styles to the generator container */
    #post-qr-generator {
      /* --- Default: Dark Mode Colors --- */
      --qr-primary-color: #5a85f1;    /* Lighter blue for dark bg */
      --qr-secondary-color: #1fdd98;  /* Brighter green */
      --qr-bg-color: #2e343a;         /* Dark background for container */
      --qr-text-color: #f8f9fa;       /* Light text */
      --qr-text-muted-color: #adb5bd;
      --qr-border-color: #5a6168;     /* Darker border */
      --qr-input-bg: #495057;        /* Dark input background */
      --qr-button-bg: #3a7bf0;       /* Button blue */
      --qr-button-text: #ffffff;
      --qr-white: #fff;
      --qr-shadow-color: rgba(0, 0, 0, 0.2); /* Slightly more visible shadow on dark */

      /* Base styles */
      background-color: var(--qr-bg-color);
      color: var(--qr-text-color);
      padding: 25px; /* More padding */
      border-radius: 8px;
      margin: 25px 0; /* Space above/below in post */
      font-family: "Helvetica Neue", Arial, sans-serif;
      line-height: 1.6;
      border: 1px solid var(--qr-border-color);
      box-shadow: 0 3px 7px var(--qr-shadow-color);
      transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
      width: 100%; /* Use available width */
      box-sizing: border-box;
      text-align: center; /* Center inline/block elements */
    }
    #post-qr-generator * {
        box-sizing: border-box;
    }

    /* --- Light Mode Overrides --- */
    #post-qr-generator.qr-light-mode {
      --qr-primary-color: #4e73df;
      --qr-secondary-color: #1cc88a;
      --qr-bg-color: #ffffff;         /* White container bg */
      --qr-text-color: #343a40;       /* Dark text */
      --qr-text-muted-color: #6c757d;
      --qr-border-color: #dee2e6;     /* Light border */
      --qr-input-bg: #ffffff;        /* White input bg */
      --qr-button-bg: #007bff;       /* Standard blue */
      --qr-button-text: #ffffff;
      --qr-shadow-color: rgba(0, 0, 0, 0.1);
    }

    /* --- Element Styles (Scoped) --- */
    #post-qr-generator h2 {
      margin-top: 0;
      margin-bottom: 25px;
      color: var(--qr-text-color); /* Title color matches text */
      font-size: 1.6em;
    }

    /* Local Theme Switch Button Style */
     #post-qr-generator .qr-theme-switch-wrapper {
         text-align: right;
         margin-bottom: 20px;
     }
    #post-qr-generator #qr-theme-toggle {
       padding: 7px 14px;
       background-color: var(--qr-secondary-color);
       color: var(--qr-white);
       border: none;
       border-radius: 4px;
       font-size: 0.85rem;
       cursor: pointer;
       transition: background-color 0.3s ease;
    }
     #post-qr-generator.qr-light-mode #qr-theme-toggle {
          background-color: #6c757d; /* Grey button in light mode */
          color: var(--qr-white);
      }

    #post-qr-generator #qr-theme-toggle:hover {
       opacity: 0.85;
    }

    #post-qr-generator input[type="text"] {
      width: 100%; /* Full width */
      max-width: 500px; /* Limit input width for aesthetics */
      padding: 12px;
      font-size: 16px;
      margin-bottom: 15px;
      border: 1px solid var(--qr-border-color);
      background-color: var(--qr-input-bg);
      color: var(--qr-text-color);
      border-radius: 4px;
      display: block; /* Ensure it takes width */
      margin-left: auto; /* Center the input field */
      margin-right: auto;
    }
    #post-qr-generator input[type="text"]::placeholder {
         color: var(--qr-text-muted-color);
         opacity: 0.7;
    }
    #post-qr-generator input[type="text"]:focus {
      border-color: var(--qr-primary-color);
      outline: none;
    }

    #post-qr-generator button#generateQrBtn {
      padding: 12px 30px;
      font-size: 16px;
      cursor: pointer;
      background-color: var(--qr-button-bg);
      color: var(--qr-button-text);
      border: none;
      border-radius: 4px;
      transition: background-color 0.3s ease;
      display: inline-block; /* Adjust button width to content */
      margin-bottom: 20px; /* Space below button */
    }

    #post-qr-generator button#generateQrBtn:hover {
      opacity: 0.9;
    }

    /* QR Code output area */
    #post-qr-generator #qrcodeResult {
      margin-top: 25px;
      /* Use Flexbox to center the QR code itself */
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 170px; /* Visual space for QR code */
      padding: 10px; /* Padding around the centered QR */
    }

     /* Style the image/canvas generated by qrcode.js */
     #post-qr-generator #qrcodeResult img,
     #post-qr-generator #qrcodeResult canvas {
        padding: 6px; /* Padding inside border */
        border: 1px solid var(--qr-border-color);
        background-color: var(--qr-white); /* Always white background for QR */
        border-radius: 4px; /* Optional rounded corners */
     }
      /* Ensure light mode border is visible */
      #post-qr-generator.qr-light-mode #qrcodeResult img,
      #post-qr-generator.qr-light-mode #qrcodeResult canvas {
          border-color: #ccc;
      }

  &lt;/style&gt;
  &lt;!-- END: QR Generator-Specific Styles --&gt;


  &lt;!-- START: QR Generator HTML --&gt;
  &lt;h2&gt;QR Code Generator&lt;/h2&gt;

  &lt;!-- Local Theme Switch --&gt;
  &lt;div class="qr-theme-switch-wrapper"&gt;
    &lt;button id="qr-theme-toggle"&gt;Switch to Light Mode&lt;/button&gt;
  &lt;/div&gt;

  &lt;input type="text" id="qrText" placeholder="Enter text or URL" /&gt;
  &lt;button type="button" id="generateQrBtn" onclick="generateQR()"&gt;Generate QR Code&lt;/button&gt;

  &lt;!-- This div will hold the generated QR code --&gt;
  &lt;div id="qrcodeResult"&gt;
      &lt;!-- QR Code will appear here --&gt;
  &lt;/div&gt;
  &lt;!-- END: QR Generator HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-qr-generator Container --&gt;


&lt;!-- START: QR Generator Script (with Local Theme Logic) --&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
  // Local Theme Switcher Logic for QR Generator
  const qrThemeToggle = document.getElementById('qr-theme-toggle');
  const qrGeneratorDiv = document.getElementById('post-qr-generator');
  const qrLocalStorageKey = 'qrGeneratorTheme'; // Unique key
  const qrCurrentTheme = localStorage.getItem(qrLocalStorageKey) ? localStorage.getItem(qrLocalStorageKey) : null;

  // Apply saved theme ON LOAD to the generator div
  if (qrCurrentTheme === 'light') {
    qrGeneratorDiv.classList.add('qr-light-mode');
    qrThemeToggle.textContent = 'Switch to Dark Mode';
  } else {
    qrGeneratorDiv.classList.remove('qr-light-mode'); // Default dark
    qrThemeToggle.textContent = 'Switch to Light Mode';
  }

  // Add event listener for the LOCAL button
  qrThemeToggle.addEventListener('click', () =&gt; {
    qrGeneratorDiv.classList.toggle('qr-light-mode');
    let theme = 'dark';
    if (qrGeneratorDiv.classList.contains('qr-light-mode')) {
      theme = 'light';
      qrThemeToggle.textContent = 'Switch to Dark Mode';
    } else {
      qrThemeToggle.textContent = 'Switch to Light Mode';
    }
    // Save the generator's specific theme state
    localStorage.setItem(qrLocalStorageKey, theme);
  });


  // QR Code Generation Logic
  let qrcodeInstance = null; // Variable to hold the QRCode instance

  function generateQR() {
      const text = document.getElementById("qrText").value.trim();
      const qrCodeContainer = document.getElementById("qrcodeResult"); // Target the output div

      // Clear previous QR code
      qrCodeContainer.innerHTML = "";
      qrcodeInstance = null; // Reset the instance

      if (text !== "") {
          try {
              // Generate new QR code
              qrcodeInstance = new QRCode(qrCodeContainer, {
                  text: text,
                  width: 180, // Slightly larger QR code
                  height: 180,
                  colorDark: "#000000", // QR code dark color
                  colorLight: "#ffffff", // QR code light color (background)
                  correctLevel: QRCode.CorrectLevel.H // High error correction
              });
              console.log("Generated QR Code for: " + text);
          } catch (error) {
              console.error("Error generating QR Code:", error);
              qrCodeContainer.innerHTML = '&lt;p style="color: #dc3545;"&gt;Error generating QR code.&lt;/p&gt;'; // Show error message
              alert("Could not generate QR Code. Please check the input or try again.");
          }
      } else {
          alert("Please enter text or a URL to generate a QR Code.");
          qrCodeContainer.innerHTML = ''; // Ensure container is empty if input is empty
      }
  }

  // Optional: Generate QR on Enter key press in the input field
  document.getElementById("qrText").addEventListener("keypress", function(event) {
      if (event.key === "Enter") {
          event.preventDefault();
          generateQR();
      }
  });

&lt;/script&gt;
&lt;!-- END: QR Generator Script --&gt;

&lt;!-- Google Analytics Code (Keep only if needed for the specific tool, often omitted here) --&gt;
&lt;!--
&lt;script type="text/javascript"&gt;
    // GA code removed for brevity unless specifically needed for this tool
&lt;/script&gt;
--&gt;

&lt;!-- END: Complete Self-Contained QR Code Generator Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>Word &amp; Character Counter tool</title><link>http://rajclick.blogspot.com/2025/03/word-character-counter-tool.html</link><category>Tracker app</category><pubDate>Sun, 2 Mar 2025 03:15:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-5660914751843439530</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;Word &amp; Character Counter&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin: 50px;
        }
        textarea {
            width: 100%;
            height: 150px;
            padding: 10px;
            font-size: 16px;
        }
        .stats {
            margin-top: 20px;
            font-size: 18px;
            font-weight: bold;
        }
    &lt;/style&gt;
    &lt;script async src="https://www.googletagmanager.com/gtag/js?id=UA-26277044-1"&gt;&lt;/script&gt;
    &lt;script&gt;
        window.dataLayer = window.dataLayer || [];
        function gtag(){ dataLayer.push(arguments); }
        gtag('js', new Date());
        gtag('config', 'UA-26277044-1');
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h2&gt;Word &amp; Character Counter&lt;/h2&gt;
    &lt;textarea id="textInput" placeholder="Type or paste text here..." oninput="countText()"&gt;&lt;/textarea&gt;
    &lt;div class="stats"&gt;
        &lt;p&gt;Words: &lt;span id="wordCount"&gt;0&lt;/span&gt;&lt;/p&gt;
        &lt;p&gt;Characters: &lt;span id="charCount"&gt;0&lt;/span&gt;&lt;/p&gt;
        &lt;p&gt;Sentences: &lt;span id="sentenceCount"&gt;0&lt;/span&gt;&lt;/p&gt;
        &lt;p&gt;Paragraphs: &lt;span id="paraCount"&gt;0&lt;/span&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;script&gt;
        function countText() {
            let text = document.getElementById("textInput").value;
            
            let words = text.match(/\b\w+\b/g) || [];
            let characters = text.replace(/\s/g, "").length;
            let sentences = text.split(/[.!?]+/).filter(s =&gt; s.trim().length &gt; 0);
            let paragraphs = text.split(/\n+/).filter(p =&gt; p.trim().length &gt; 0);
            
            document.getElementById("wordCount").innerText = words.length;
            document.getElementById("charCount").innerText = characters;
            document.getElementById("sentenceCount").innerText = sentences.length;
            document.getElementById("paraCount").innerText = paragraphs.length;
            
            console.log("Words: " + words.length);
            console.log("Characters: " + characters);
            console.log("Sentences: " + sentences.length);
            console.log("Paragraphs: " + paragraphs.length);
        }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item><item><title>New Regime Income Tax Calculator 2025-2026</title><link>http://rajclick.blogspot.com/2025/03/new-regime-income-tax-calculator-2025.html</link><pubDate>Sun, 2 Mar 2025 01:55:00 -0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-1083521546680529197.post-3013445491007508307</guid><description>&lt;!-- START: Complete Self-Contained Tax Calculator Block --&gt;

&lt;!-- Container for the calculator with a unique ID for scoping --&gt;
&lt;div id="post-tax-calculator"&gt;

  &lt;!-- START: Calculator-Specific Styles (Scoped) --&gt;
  &lt;style&gt;
    /* Scope all styles to the calculator container */
    #post-tax-calculator {
      /* --- Default: Dark Mode Colors --- */
      --calc-primary-color: #5a85f1;
      --calc-secondary-color: #1fdd98;
      --calc-bg-color: #343a40; /* Container background */
      --calc-text-color: #f8f9fa;
      --calc-text-muted-color: #adb5bd;
      --calc-border-color: #6c757d;
      --calc-subtle-bg: #495057;
      --calc-input-bg: #495057;
      --calc-white: #fff;
      --calc-shadow-color: rgba(255, 255, 255, 0.05);

      /* Base styles */
      background-color: var(--calc-bg-color);
      color: var(--calc-text-color);
      padding: 20px;
      border-radius: 8px;
      margin: 20px auto; /* Center block on page if post container allows */
      max-width: 650px; /* Max width for readability */
      font-family: "Helvetica Neue", Arial, sans-serif; /* Define font */
      line-height: 1.5;
      border: 1px solid var(--calc-border-color);
      box-shadow: 0 2px 6px var(--calc-shadow-color);
      transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
      box-sizing: border-box; /* Apply box-sizing to the container */
    }
    #post-tax-calculator * {
        box-sizing: border-box; /* Ensure child elements inherit */
    }


    /* --- Light Mode Overrides --- */
    #post-tax-calculator.calculator-light-mode {
      --calc-primary-color: #4e73df;
      --calc-secondary-color: #1cc88a;
      --calc-bg-color: #ffffff; /* Light container bg */
      --calc-text-color: #343a40;
      --calc-text-muted-color: #6c757d;
      --calc-border-color: #ced4da;
      --calc-subtle-bg: #e9ecef;
      --calc-input-bg: #ffffff;
      --calc-shadow-color: rgba(0, 0, 0, 0.1);
    }

    /* --- Element Styles (Scoped) --- */
    #post-tax-calculator h2 {
      margin-top: 0;
      margin-bottom: 20px;
      color: var(--calc-primary-color);
      text-align: center;
      font-size: 1.5em;
    }

    /* Local Theme Switch Button Style */
     #post-tax-calculator .calc-theme-switch-wrapper {
         text-align: right;
         margin-bottom: 15px;
     }
    #post-tax-calculator #calculator-theme-toggle {
       padding: 8px 15px;
       background-color: var(--calc-secondary-color);
       color: var(--calc-white);
       border: none;
       border-radius: 4px;
       font-size: 0.9rem;
       cursor: pointer;
       transition: background-color 0.3s ease;
    }
    #post-tax-calculator #calculator-theme-toggle:hover {
       opacity: 0.9;
    }


    #post-tax-calculator label {
      display: block;
      margin: 15px 0 5px;
      font-weight: 600;
      color: var(--calc-text-color);
    }

    #post-tax-calculator input[type="number"],
    #post-tax-calculator select {
      width: 100%;
      padding: 10px;
      border: 1px solid var(--calc-border-color);
      background-color: var(--calc-input-bg);
      color: var(--calc-text-color);
      border-radius: 4px;
      outline: none;
      font-size: 14px;
      transition: border-color 0.3s ease, background-color 0.3s ease, color 0.3s ease;
    }

    #post-tax-calculator input[type="number"]:focus,
    #post-tax-calculator select:focus {
      border-color: var(--calc-secondary-color);
    }
     #post-tax-calculator input::placeholder {
         color: var(--calc-text-muted-color);
         opacity: 0.7;
     }

    #post-tax-calculator button#calculateTaxBtn {
      margin-top: 20px;
      padding: 12px 20px;
      background: var(--calc-secondary-color);
      color: var(--calc-white);
      border: none;
      border-radius: 4px;
      font-size: 16px;
      cursor: pointer;
      transition: background 0.3s ease;
      display: block;
      width: 100%;
    }

    #post-tax-calculator button#calculateTaxBtn:hover {
       opacity: 0.9;
    }

    #post-tax-calculator .result {
      margin-top: 25px;
      padding: 15px;
      background: var(--calc-subtle-bg);
      border-radius: 6px;
      border: 1px solid var(--calc-border-color);
      transition: background-color 0.3s ease, border-color 0.3s ease;
    }
     #post-tax-calculator .result h3 {
         margin-top: 0;
         color: var(--calc-primary-color);
     }
     #post-tax-calculator .result p {
         margin: 8px 0;
         word-wrap: break-word; /* Prevent long results overflowing */
     }
     #post-tax-calculator .result strong {
         color: var(--calc-text-color);
     }


    #post-tax-calculator #breakdown {
       margin-top: 25px;
       overflow-x: auto; /* Handle table overflow on small screens */
    }
     #post-tax-calculator #breakdown h3 {
         margin-top: 0;
         margin-bottom: 10px;
         color: var(--calc-primary-color);
     }

    #post-tax-calculator table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 0px; /* Adjusted */
      background-color: transparent; /* Use container bg */
    }

    #post-tax-calculator table,
    #post-tax-calculator th,
    #post-tax-calculator td {
      border: 1px solid var(--calc-border-color);
      transition: border-color 0.3s ease;
    }

    #post-tax-calculator th,
    #post-tax-calculator td {
      padding: 8px 10px; /* Adjust padding for table density */
      text-align: right; /* Align numbers to right */
       color: var(--calc-text-color); /* Ensure text color applies */
       white-space: nowrap; /* Prevent wrapping in table cells */
    }
    /* Center align specific columns if needed */
    #post-tax-calculator th:nth-child(3), /* Rate column */
    #post-tax-calculator td:nth-child(3) {
        text-align: center;
    }
    #post-tax-calculator th {
        text-align: center; /* Center align headers by default */
    }
    /* Align Total/Cess labels right in footer */
     #post-tax-calculator tfoot td[colspan='4'] {
         text-align: right;
         font-weight: bold;
     }
     /* Align footer values right */
     #post-tax-calculator tfoot td:last-child {
        text-align: right;
        font-weight: bold;
     }


    #post-tax-calculator th {
      background: var(--calc-subtle-bg);
      font-weight: 600;
      transition: background-color 0.3s ease;
    }

    #post-tax-calculator .disclaimer {
      margin-top: 25px;
      padding-top: 15px;
      border-top: 1px dashed var(--calc-border-color);
      font-style: italic;
      font-size: 0.9rem;
      color: var(--calc-text-muted-color);
      text-align: center;
      transition: color 0.3s ease, border-color 0.3s ease;
    }
  &lt;/style&gt;
  &lt;!-- END: Calculator-Specific Styles --&gt;


  &lt;!-- START: Calculator HTML --&gt;
  &lt;h2&gt;New Regime Income Tax Calculator (FY 2025-2026)&lt;/h2&gt;

  &lt;!-- Local Theme Switch --&gt;
  &lt;div class="calc-theme-switch-wrapper"&gt;
    &lt;button id="calculator-theme-toggle"&gt;Switch to Light Mode&lt;/button&gt;
  &lt;/div&gt;

  &lt;label for="salary"&gt;Enter Total Salary:&lt;/label&gt;
  &lt;input type="number" id="salary" placeholder="Enter amount" /&gt;

  &lt;label for="salaryType"&gt;Salary Input Type:&lt;/label&gt;
  &lt;select id="salaryType"&gt;
    &lt;option value="annual"&gt;Annual&lt;/option&gt;
    &lt;option value="monthly"&gt;Monthly&lt;/option&gt;
  &lt;/select&gt;

  &lt;button id="calculateTaxBtn" onclick="calculateTax()"&gt;Calculate Tax&lt;/button&gt;

  &lt;div id="output" class="result" style="display: none;"&gt;&lt;/div&gt;
  &lt;div id="breakdown" style="display: none;"&gt;&lt;/div&gt;

  &lt;div class="disclaimer"&gt;
    Disclaimer: This calculator is for informational purposes only. For precise tax calculations, please consult a qualified Chartered Accountant.
  &lt;/div&gt;
  &lt;!-- END: Calculator HTML --&gt;

&lt;/div&gt;&lt;!-- END: #post-tax-calculator Container --&gt;


&lt;!-- START: Calculator Script (with Local Theme Logic &amp; CORRECTED TAX LOGIC) --&gt;
&lt;!-- START: Calculator Script (with Local Theme Logic &amp; CORRECTED TAX LOGIC + Final 'To' Value) --&gt;
&lt;script&gt;
  // Local Theme Switcher Logic for Calculator (remains the same)
  const calcThemeToggle = document.getElementById('calculator-theme-toggle');
  const calculatorDiv = document.getElementById('post-tax-calculator');
  const calcCurrentTheme = localStorage.getItem('calculatorTheme') ? localStorage.getItem('calculatorTheme') : null;

  if (calcCurrentTheme === 'light') {
    calculatorDiv.classList.add('calculator-light-mode');
    calcThemeToggle.textContent = 'Switch to Dark Mode';
  } else {
    calculatorDiv.classList.remove('calculator-light-mode');
    calcThemeToggle.textContent = 'Switch to Light Mode';
  }

  calcThemeToggle.addEventListener('click', () =&gt; {
    calculatorDiv.classList.toggle('calculator-light-mode');
    let theme = 'dark';
    if (calculatorDiv.classList.contains('calculator-light-mode')) {
      theme = 'light';
      calcThemeToggle.textContent = 'Switch to Dark Mode';
    } else {
      calcThemeToggle.textContent = 'Switch to Light Mode';
    }
    localStorage.setItem('calculatorTheme', theme);
  });


  // *** Calculation Logic based on your image (with updated table generation) ***
  function calculateTax() {
    const salaryInput = parseFloat(document.getElementById('salary').value);
    const salaryType = document.getElementById('salaryType').value;
    const outputDiv = document.getElementById('output');
    const breakdownDiv = document.getElementById('breakdown');

    // Clear previous results
    outputDiv.style.display = 'none';
    breakdownDiv.style.display = 'none';
    outputDiv.innerHTML = '';
    breakdownDiv.innerHTML = '';

    if (isNaN(salaryInput) || salaryInput &lt; 0) {
      alert('Please enter a valid positive salary amount.');
      return;
    }

    const annualSalary = (salaryType === 'monthly') ? salaryInput * 12 : salaryInput;

    // Apply Standard Deduction (as requested)
    const standardDeduction = 75000;
    let taxableIncome = annualSalary - standardDeduction;
    if (taxableIncome &lt; 0) taxableIncome = 0;

    let computedTax = 0;
    const breakdownDetails = [];
    let outputHTML = "";
    let breakdownHTML = "";

    // Define tax slabs EXACTLY as per your image
    const slabs = [
      { lower: 0,      upper: 400000,  rate: 0.00 },
      { lower: 400000, upper: 800000,  rate: 0.05 },
      { lower: 800000, upper: 1200000, rate: 0.10 },
      { lower: 1200000,upper: 1600000, rate: 0.15 },
      { lower: 1600000,upper: 2000000, rate: 0.20 },
      { lower: 2000000,upper: 2400000, rate: 0.25 },
      { lower: 2400000,upper: Infinity,rate: 0.30 } // Last slab uses Infinity
    ];

    // --- Slab Calculation ---
    let remainingIncomeToTax = taxableIncome;
    for (const slab of slabs) {
        if (remainingIncomeToTax &lt;= 0 &amp;&amp; slab.rate &gt; 0) break;

        const currentSlabLower = slab.lower;
        const currentSlabUpper = slab.upper;
        const currentSlabRate = slab.rate;
        const maxPossibleAmountInThisSlab = (currentSlabUpper === Infinity) ? Infinity : currentSlabUpper - currentSlabLower;

        const amountTaxedInThisSlab = Math.max(0, Math.min(remainingIncomeToTax, maxPossibleAmountInThisSlab));
        const taxInSlab = amountTaxedInThisSlab * currentSlabRate;
        computedTax += taxInSlab;

         if (taxableIncome &gt;= currentSlabLower || currentSlabLower === 0) {
             breakdownDetails.push({
                 from: currentSlabLower,
                 to: currentSlabUpper, // Still store Infinity here
                 rate: (currentSlabRate * 100).toFixed(0) + "%",
                 taxableAmount: amountTaxedInThisSlab,
                 tax: taxInSlab
             });
         }
        remainingIncomeToTax -= amountTaxedInThisSlab;
         if (taxableIncome &lt;= currentSlabUpper &amp;&amp; currentSlabUpper !== Infinity) break;
         if (currentSlabUpper === Infinity) break;
    }
    // --- End Slab Calculation ---


    // Add Health and Education Cess (4% on computed tax)
    const cessRate = 0.04;
    const cessAmount = computedTax * cessRate;
    const finalTax = computedTax + cessAmount;

    const netAnnual = annualSalary - finalTax;
    const netMonthly = netAnnual / 12;

    // --- Build Output HTML (remains the same) ---
    outputHTML += "&lt;h3&gt;Results:&lt;/h3&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Annual Salary (Input):&lt;/strong&gt; Rs. " + annualSalary.toLocaleString('en-IN') + "&lt;/p&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Standard Deduction:&lt;/strong&gt; Rs. " + standardDeduction.toLocaleString('en-IN') + "&lt;/p&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Taxable Income (After Deduction):&lt;/strong&gt; Rs. " + taxableIncome.toLocaleString('en-IN', {maximumFractionDigits:0}) + "&lt;/p&gt;";
    outputHTML += "&lt;hr style='border-top: 1px dashed var(--calc-border-color); margin: 10px 0;'&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Total Tax (Before Cess):&lt;/strong&gt; Rs. " + computedTax.toLocaleString('en-IN', {maximumFractionDigits:2}) + "&lt;/p&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Cess (" + (cessRate * 100) + "%):&lt;/strong&gt; Rs. " + cessAmount.toLocaleString('en-IN', {maximumFractionDigits:2}) + "&lt;/p&gt;";
    outputHTML += "&lt;p style='font-weight: bold;'&gt;&lt;strong&gt;Total Tax Payable:&lt;/strong&gt; Rs. " + finalTax.toLocaleString('en-IN', {maximumFractionDigits:2}) + "&lt;/p&gt;";
    outputHTML += "&lt;hr style='border-top: 1px dashed var(--calc-border-color); margin: 10px 0;'&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Net Annual Salary (After Tax):&lt;/strong&gt; Rs. " + netAnnual.toLocaleString('en-IN', {maximumFractionDigits:2}) + "&lt;/p&gt;";
    outputHTML += "&lt;p&gt;&lt;strong&gt;Net Monthly Salary (Approx.):&lt;/strong&gt; Rs. " + netMonthly.toLocaleString('en-IN', {maximumFractionDigits:2}) + "&lt;/p&gt;";


    // --- Build Breakdown Table HTML (MODIFIED 'To' Column Logic) ---
    const formatTaxValue = (value) =&gt; {
        // Display '-' for exactly zero tax, otherwise format the number
        return value === 0 ? "-" : value.toLocaleString('en-IN', {minimumFractionDigits: 2, maximumFractionDigits:2});
    };
     const formatBoundary = (value) =&gt; {
         // Formats regular slab boundaries
         return value.toLocaleString('en-IN', {maximumFractionDigits:0});
     };
     const formatFromBoundary = (value) =&gt; {
         return value.toLocaleString('en-IN', {maximumFractionDigits:0});
     }


    breakdownHTML += "&lt;h3&gt;Tax Breakdown by Slabs:&lt;/h3&gt;";
    breakdownHTML += "&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;From (Rs.)&lt;/th&gt;&lt;th&gt;To (Rs.)&lt;/th&gt;&lt;th&gt;Rate&lt;/th&gt;&lt;th&gt;Taxable Amount (Rs.)&lt;/th&gt;&lt;th&gt;Tax (Rs.)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;";
    for (const detail of breakdownDetails) {
      // Only add row if amount taxed in slab is &gt; 0 OR it's the 0% slab and income is non-negative
      if(detail.taxableAmount &gt; 0 || (detail.from === 0 &amp;&amp; taxableIncome &gt;= 0)) {

          // *** MODIFICATION HERE: Check if it's the Infinity slab ***
          const toValueDisplay = (detail.to === Infinity)
                                 ? taxableIncome.toLocaleString('en-IN', {maximumFractionDigits:0}) // Show actual taxable income
                                 : formatBoundary(detail.to); // Show normal upper boundary

          breakdownHTML += "&lt;tr&gt;" +
            "&lt;td&gt;" + formatFromBoundary(detail.from) + "&lt;/td&gt;" +
            "&lt;td&gt;" + toValueDisplay + "&lt;/td&gt;" + // Use the modified 'To' value
            "&lt;td&gt;" + detail.rate + "&lt;/td&gt;" +
            "&lt;td&gt;" + detail.taxableAmount.toLocaleString('en-IN', {maximumFractionDigits:0}) + "&lt;/td&gt;" +
            "&lt;td&gt;" + formatTaxValue(detail.tax) + "&lt;/td&gt;" +
            "&lt;/tr&gt;";
      }
    }
    breakdownHTML += "&lt;/tbody&gt;";

    // Add Footer rows (remains the same)
    breakdownHTML += "&lt;tfoot&gt;";
    breakdownHTML += "&lt;tr&gt;&lt;td colspan='4'&gt;Total Tax (before Cess)&lt;/td&gt;&lt;td&gt;" + computedTax.toLocaleString('en-IN', {minimumFractionDigits: 2, maximumFractionDigits:2}) + "&lt;/td&gt;&lt;/tr&gt;";
    breakdownHTML += "&lt;tr&gt;&lt;td colspan='4'&gt;Cess ("+(cessRate * 100)+"%)&lt;/td&gt;&lt;td&gt;" + cessAmount.toLocaleString('en-IN', {minimumFractionDigits: 2, maximumFractionDigits:2}) + "&lt;/td&gt;&lt;/tr&gt;";
    breakdownHTML += "&lt;tr&gt;&lt;td colspan='4'&gt;Total Tax Payable&lt;/td&gt;&lt;td&gt;" + finalTax.toLocaleString('en-IN', {minimumFractionDigits: 2, maximumFractionDigits:2}) + "&lt;/td&gt;&lt;/tr&gt;";
    breakdownHTML += "&lt;/tfoot&gt;";

    breakdownHTML += "&lt;/table&gt;";


    // Display results
    outputDiv.innerHTML = outputHTML;
    outputDiv.style.display = 'block';

    // Display breakdown logic (remains the same)
    if(computedTax &gt; 0 &amp;&amp; breakdownDetails.length &gt; 0) {
        breakdownDiv.innerHTML = breakdownHTML;
        breakdownDiv.style.display = 'block';
    } else {
         if (taxableIncome &gt;= 0 &amp;&amp; breakdownDetails.length &gt; 0) {
            let zeroTaxBreakdownHTML = "&lt;h3&gt;Tax Breakdown by Slabs:&lt;/h3&gt;";
            zeroTaxBreakdownHTML += "&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;From (Rs.)&lt;/th&gt;&lt;th&gt;To (Rs.)&lt;/th&gt;&lt;th&gt;Rate&lt;/th&gt;&lt;th&gt;Taxable Amount (Rs.)&lt;/th&gt;&lt;th&gt;Tax (Rs.)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;";
             for (const detail of breakdownDetails) {
                if(detail.taxableAmount &gt;= 0 &amp;&amp; detail.from === 0) {
                  const toValueDisplayZero = (detail.to === Infinity)
                                         ? taxableIncome.toLocaleString('en-IN', {maximumFractionDigits:0})
                                         : formatBoundary(detail.to);
                  zeroTaxBreakdownHTML += "&lt;tr&gt;" +
                    "&lt;td&gt;" + formatFromBoundary(detail.from) + "&lt;/td&gt;" +
                    "&lt;td&gt;" + toValueDisplayZero + "&lt;/td&gt;" +
                    "&lt;td&gt;" + detail.rate + "&lt;/td&gt;" +
                    "&lt;td&gt;" + detail.taxableAmount.toLocaleString('en-IN', {maximumFractionDigits:0}) + "&lt;/td&gt;" +
                    "&lt;td&gt;" + formatTaxValue(detail.tax) + "&lt;/td&gt;" +
                    "&lt;/tr&gt;";
                 }
             }
            zeroTaxBreakdownHTML += "&lt;/tbody&gt;&lt;/table&gt;";
            // No footer needed if total tax is zero
            breakdownDiv.innerHTML = zeroTaxBreakdownHTML;
            breakdownDiv.style.display = 'block';
         } else {
            breakdownDiv.style.display = 'none';
         }
    }
  }
&lt;/script&gt;
&lt;!-- END: Calculator Script --&gt;

&lt;!-- END: Complete Self-Contained Tax Calculator Block --&gt;&lt;div class="blogger-post-footer"&gt;Click Above^link to Read full&lt;/div&gt;</description><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><author>rajualankar2@gmail.com (Raju)</author></item></channel></rss>