<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Web on Vijay Kodam</title><link>https://vijay.eu/tags/web/</link><description>Recent content in Web on Vijay Kodam</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 10 Jun 2026 12:00:00 +0300</lastBuildDate><atom:link href="https://vijay.eu/tags/web/index.xml" rel="self" type="application/rss+xml"/><item><title>Retro Racer</title><link>https://vijay.eu/projects/retro-racer/</link><pubDate>Wed, 10 Jun 2026 12:00:00 +0300</pubDate><guid>https://vijay.eu/projects/retro-racer/</guid><description>&lt;div class="retro-racer"&gt;
&lt;h1 class="racer-title"&gt;Retro Racer&lt;/h1&gt;
&lt;p class="racer-subtitle"&gt;A 3D arcade racer. One lap, against the clock.&lt;/p&gt;
&lt;div class="racer-frame"&gt;
&lt;canvas id="racerCanvas"&gt;&lt;/canvas&gt;
&lt;div class="racer-banner hidden" id="racerBanner" aria-live="polite"&gt;&lt;/div&gt;
&lt;div class="racer-hud" aria-live="off"&gt;
&lt;div class="hud-item"&gt;
&lt;span class="hud-label"&gt;Time&lt;/span&gt;
&lt;span class="hud-value" id="hudTime"&gt;0:00.0&lt;/span&gt;
&lt;/div&gt;
&lt;div class="hud-item hud-item--speed"&gt;
&lt;span class="hud-label"&gt;Speed&lt;/span&gt;
&lt;span class="hud-value" id="hudSpeed"&gt;0 km/h&lt;/span&gt;
&lt;/div&gt;
&lt;div class="hud-item"&gt;
&lt;span class="hud-label"&gt;Progress&lt;/span&gt;
&lt;span class="hud-value" id="hudProgress"&gt;0%&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="racer-overlay" id="racerStart"&gt;
&lt;h2&gt;Retro Racer&lt;/h2&gt;
&lt;p&gt;Complete one lap as fast as you can. Dodge traffic and stay on the road - grass and crashes will slow you down.&lt;/p&gt;
&lt;p&gt;Arrow keys or WASD to drive. On touch devices, hold gas/brake with your left thumb and steer with your right.&lt;/p&gt;
&lt;button class="racer-btn" id="racerStartBtn" type="button" disabled&gt;Start Race&lt;/button&gt;
&lt;p class="racer-loading" id="racerLoading"&gt;Loading 3D assets...&lt;/p&gt;
&lt;p class="racer-best" id="racerStartBest"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="racer-overlay hidden" id="racerResults"&gt;
&lt;h2&gt;Finish!&lt;/h2&gt;
&lt;p class="racer-result-time" id="racerResultTime"&gt;&lt;/p&gt;
&lt;p class="racer-best" id="racerResultBest"&gt;&lt;/p&gt;
&lt;button class="racer-btn" id="racerAgainBtn" type="button"&gt;Race Again&lt;/button&gt;
&lt;/div&gt;
&lt;div class="racer-cinematic hidden" id="racerCinematic" aria-hidden="true"&gt;
&lt;div class="racer-letterbox racer-letterbox--top"&gt;&lt;/div&gt;
&lt;div class="racer-letterbox racer-letterbox--bottom"&gt;&lt;/div&gt;
&lt;div class="racer-flyby-label"&gt;
&lt;span class="racer-flyby-name"&gt;Mazda Miata&lt;/span&gt;
&lt;span class="racer-flyby-sub"&gt;MX-5 NA&lt;/span&gt;
&lt;/div&gt;
&lt;button class="racer-skip-btn" id="racerSkipBtn" type="button"&gt;Skip &amp;rsaquo;&amp;rsaquo;&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="racer-touch"&gt;
&lt;div class="touch-cluster touch-cluster--drive" aria-label="Speed controls (left thumb)"&gt;
&lt;button class="touch-btn touch-btn--gas" id="racerBtnGas" type="button" aria-label="Accelerate"&gt;GAS&lt;/button&gt;
&lt;button class="touch-btn touch-btn--brake" id="racerBtnBrake" type="button" aria-label="Brake"&gt;BRAKE&lt;/button&gt;
&lt;/div&gt;
&lt;div class="touch-cluster touch-cluster--steer" aria-label="Steering controls (right thumb)"&gt;
&lt;button class="touch-btn touch-btn--arrow" id="racerBtnLeft" type="button" aria-label="Steer left"&gt;&amp;larr;&lt;/button&gt;
&lt;button class="touch-btn touch-btn--arrow" id="racerBtnRight" type="button" aria-label="Steer right"&gt;&amp;rarr;&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class="racer-note"&gt;Built with vanilla JavaScript and &lt;a href="https://threejs.org/" rel="noopener"&gt;three.js&lt;/a&gt;. Car models "&lt;a href="https://sketchfab.com/3d-models/mazda-miata-mx-5-na-d51fcd44b74f4daf8012c41e0400c041" rel="noopener"&gt;Mazda Miata MX-5 NA&lt;/a&gt;" and "&lt;a href="https://sketchfab.com/3d-models/toyota-ae86-trueno-fe02fba6302e450ea8424591493341ea" rel="noopener"&gt;Toyota AE86 Trueno&lt;/a&gt;" by Lexyc16 on Sketchfab (CC-BY 4.0). Textures and lighting from &lt;a href="https://polyhaven.com/" rel="noopener"&gt;Poly Haven&lt;/a&gt; (CC0). Your best lap time is stored locally in your browser.&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>Tesla Wrap Maker</title><link>https://vijay.eu/projects/tesla-wrap/</link><pubDate>Sat, 09 May 2026 00:00:00 +0300</pubDate><guid>https://vijay.eu/projects/tesla-wrap/</guid><description>&lt;p&gt;Design custom Tesla wraps in the browser, download the PNG for Paint Shop, and preview supported models in 3D.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://vijay.eu/tesla-wrap/" class="button"&gt;Open Tesla Wrap Maker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://vijay.eu/images/tesla_wrap_screenshot.png" alt="Tesla Wrap Maker screenshot"&gt;&lt;/p&gt;</description></item><item><title>Note Quest</title><link>https://vijay.eu/projects/note-quest/</link><pubDate>Thu, 26 Feb 2026 00:00:00 +0200</pubDate><guid>https://vijay.eu/projects/note-quest/</guid><description>&lt;p&gt;Learn to read music notes on the grand staff! Pick the correct note name for each question.&lt;/p&gt;
&lt;p&gt;Created using Claude Code CLI on 26th Feb 2026. V2 released on 8th Mar 2026.
&lt;link rel="stylesheet" href="https://vijay.eu/css/note-quest.css"&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/vexflow/build/cjs/vexflow.js"&gt;&lt;/script&gt;
&lt;div class="note-quest-wrapper"&gt;
&lt;div class="nq-screen start-screen active" id="nqStartScreen"&gt;
&lt;label class="nq-helper-toggle"&gt;
&lt;input type="checkbox" id="nqShowNoteNames"&gt; Show note names on staff
&lt;small class="nq-helper-hint"&gt;Auto for Levels 1–2, 4 · Ignored for 8–10&lt;/small&gt;
&lt;/label&gt;
&lt;div class="level-grid"&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label easy"&gt;Easy&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box easy" data-level="1"&gt;
&lt;span class="level-num"&gt;1&lt;/span&gt;
&lt;span class="level-detail"&gt;First Notes · Both clefs · F3,C4 / C4,G4&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box easy" data-level="2"&gt;
&lt;span class="level-num"&gt;2&lt;/span&gt;
&lt;span class="level-detail"&gt;Staff Basics · Both clefs · F3–G4&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box easy" data-level="3"&gt;
&lt;span class="level-num"&gt;3&lt;/span&gt;
&lt;span class="level-detail"&gt;Getting Comfortable · Both clefs · C3–C5&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label medium"&gt;Medium&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box medium" data-level="4"&gt;
&lt;span class="level-num"&gt;4&lt;/span&gt;
&lt;span class="level-detail"&gt;Wider Range · Both clefs · A2–E5&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="5"&gt;
&lt;span class="level-num"&gt;5&lt;/span&gt;
&lt;span class="level-detail"&gt;Grand Staff · Both clefs · C2–C6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="6"&gt;
&lt;span class="level-num"&gt;6&lt;/span&gt;
&lt;span class="level-detail"&gt;Expanding Range · Both clefs · A1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box medium" data-level="7"&gt;
&lt;span class="level-num"&gt;7&lt;/span&gt;
&lt;span class="level-detail"&gt;Full Staff · Both clefs · E2–C6&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="level-row"&gt;
&lt;span class="row-label hard"&gt;Hard&lt;/span&gt;
&lt;div class="level-boxes"&gt;
&lt;button class="level-box hard" data-level="8"&gt;
&lt;span class="level-num"&gt;8&lt;/span&gt;
&lt;span class="level-detail"&gt;Ledger Lines · Both clefs · C2–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box hard" data-level="9"&gt;
&lt;span class="level-num"&gt;9&lt;/span&gt;
&lt;span class="level-detail"&gt;Extended Range · Both clefs · B1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;button class="level-box hard" data-level="10"&gt;
&lt;span class="level-num"&gt;10&lt;/span&gt;
&lt;span class="level-detail"&gt;Note Master · Both clefs · A1–E6&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-version"&gt;v2.1&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-screen" id="nqGameScreen"&gt;
&lt;div class="nq-header"&gt;
&lt;div class="nq-logo"&gt;Note Quest&lt;/div&gt;
&lt;div class="nq-progress" id="nqProgress"&gt;1 / 10&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-container"&gt;
&lt;div class="staff-card" id="nqStaffCard"&gt;&lt;/div&gt;
&lt;div class="choices" id="nqChoices"&gt;
&lt;button class="choice-btn" data-note="C"&gt;C&lt;/button&gt;
&lt;button class="choice-btn" data-note="D"&gt;D&lt;/button&gt;
&lt;button class="choice-btn" data-note="E"&gt;E&lt;/button&gt;
&lt;button class="choice-btn" data-note="F"&gt;F&lt;/button&gt;
&lt;button class="choice-btn" data-note="G"&gt;G&lt;/button&gt;
&lt;button class="choice-btn" data-note="A"&gt;A&lt;/button&gt;
&lt;button class="choice-btn" data-note="B"&gt;B&lt;/button&gt;
&lt;/div&gt;
&lt;div class="stats-bar"&gt;
&lt;span&gt;Streak: &lt;strong id="nqStreakDisplay"&gt;0&lt;/strong&gt;&lt;/span&gt;
&lt;span&gt;Score: &lt;strong id="nqScoreDisplay"&gt;0&lt;/strong&gt;&lt;/span&gt;
&lt;span id="nqTimerDisplay"&gt;0:00&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="nq-screen results-screen" id="nqResultsScreen"&gt;
&lt;h2&gt;Round Complete!&lt;/h2&gt;
&lt;div class="stars" id="nqStarsDisplay"&gt;&lt;/div&gt;
&lt;div class="results-stats" id="nqResultsStats"&gt;&lt;/div&gt;
&lt;button class="play-again-btn"&gt;Play Again&lt;/button&gt;
&lt;/div&gt;
&lt;canvas id="nqConfetti"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/note-quest.js"&gt;&lt;/script&gt;
&lt;/p&gt;</description></item><item><title>Hand-Gesture 3D Car Viewer</title><link>https://vijay.eu/projects/car-concept/</link><pubDate>Sun, 11 Jan 2026 00:00:00 +0300</pubDate><guid>https://vijay.eu/projects/car-concept/</guid><description>&lt;div class="car-concept-container"&gt;
&lt;header class="car-header"&gt;
&lt;div class="car-header__content"&gt;
&lt;h1 class="car-header__title"&gt;Hand-Gesture 3D Car Viewer&lt;/h1&gt;
&lt;p class="car-header__subtitle"&gt;&lt;strong&gt;Uses your camera to detect hand gestures&lt;/strong&gt; - Open hand to rotate, make a fist and move to zoom&lt;/p&gt;
&lt;/div&gt;
&lt;div class="car-header__status"&gt;
&lt;span class="status-badge" id="statusHand"&gt;Hand: Not detected&lt;/span&gt;
&lt;span class="status-badge status-badge--muted" id="statusGesture"&gt;Use mouse or enable hand tracking&lt;/span&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;div class="viewer-container"&gt;
&lt;canvas id="threeCanvas"&gt;&lt;/canvas&gt;
&lt;div class="loading-overlay" id="loadingOverlay"&gt;
&lt;div class="loading-spinner"&gt;&lt;/div&gt;
&lt;p&gt;Loading 3D model...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="webcam-preview" id="webcamPreview"&gt;
&lt;div class="webcam-preview__stack"&gt;
&lt;video id="webcam" playsinline autoplay muted&gt;&lt;/video&gt;
&lt;canvas id="overlay2d"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;button class="webcam-btn" id="btnWebcam" type="button"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="16" height="16"&gt;
&lt;path stroke-linecap="round" stroke-linejoin="round" d="M6.827 6.175A2.31 2.31 0 015.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 00-1.134-.175 2.31 2.31 0 01-1.64-1.055l-.822-1.316a2.192 2.192 0 00-1.736-1.039 48.774 48.774 0 00-5.232 0 2.192 2.192 0 00-1.736 1.039l-.821 1.316z" /&gt;
&lt;path stroke-linecap="round" stroke-linejoin="round" d="M16.5 12.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5z" /&gt;
&lt;/svg&gt;
Enable Hand Tracking
&lt;/button&gt;
&lt;div class="webcam-error hidden" id="webcamError"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="instructions" id="instructions"&gt;
&lt;div class="instructions__item"&gt;
&lt;span class="instructions__icon"&gt;🖱️&lt;/span&gt;
&lt;span&gt;Drag to rotate, scroll to zoom&lt;/span&gt;
&lt;/div&gt;
&lt;div class="instructions__item"&gt;
&lt;span class="instructions__icon"&gt;✋&lt;/span&gt;
&lt;span&gt;Open hand: rotate car&lt;/span&gt;
&lt;/div&gt;
&lt;div class="instructions__item"&gt;
&lt;span class="instructions__icon"&gt;✊&lt;/span&gt;
&lt;span&gt;Fist + move: zoom in/out&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Hand-Gesture Cricket</title><link>https://vijay.eu/projects/cricket-bowling/</link><pubDate>Sat, 10 Jan 2026 10:00:00 +0300</pubDate><guid>https://vijay.eu/projects/cricket-bowling/</guid><description>&lt;div class="cricket-bowling-container"&gt;
&lt;header class="cricket-header"&gt;
&lt;div class="brand"&gt;
&lt;div class="brand__title"&gt;Hand-Gesture Cricket&lt;/div&gt;
&lt;div class="brand__subtitle"&gt;&lt;strong&gt;Uses your camera to detect hand gestures&lt;/strong&gt; - Grip, bowl, and hit the wickets with real hand motions!&lt;/div&gt;
&lt;/div&gt;
&lt;div class="status" aria-live="polite"&gt;
&lt;span class="badge badge--phase" id="statusPhase"&gt;Ready&lt;/span&gt;
&lt;span class="badge" id="statusSpeed"&gt;Speed: --&lt;/span&gt;
&lt;span class="badge" id="statusBallType"&gt;--&lt;/span&gt;
&lt;span class="badge badge--score" id="statusScore"&gt;Wickets: 0/0&lt;/span&gt;
&lt;span class="badge badge--muted" id="statusFps"&gt;FPS: --&lt;/span&gt;
&lt;/div&gt;
&lt;/header&gt;
&lt;main class="cricket-layout"&gt;
&lt;section class="panel"&gt;
&lt;div class="panel__header"&gt;
&lt;h2 class="panel__title"&gt;Camera&lt;/h2&gt;
&lt;div class="panel__actions"&gt;
&lt;button class="btn btn--primary" id="btnWebcam" type="button"&gt;Enable webcam&lt;/button&gt;
&lt;button class="btn" id="btnOverlay" type="button" aria-pressed="true"&gt;Overlay: On&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="media"&gt;
&lt;div class="media__stack"&gt;
&lt;video id="webcam" playsinline autoplay muted&gt;&lt;/video&gt;
&lt;canvas id="overlay2d" class="overlay2d" aria-hidden="true"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;div class="hint" id="gameHint"&gt;
&lt;strong&gt;How to play:&lt;/strong&gt;&lt;br&gt;
1. Show your hand to the camera&lt;br&gt;
2. Make a bowling motion (arm forward/down)&lt;br&gt;
3. Release naturally at the end&lt;br&gt;
4. Try to hit the wickets!
&lt;/div&gt;
&lt;div class="result-display hidden" id="resultDisplay"&gt;
&lt;div class="result-icon" id="resultIcon"&gt;&lt;/div&gt;
&lt;div class="result-text" id="resultText"&gt;&lt;/div&gt;
&lt;div class="result-details" id="resultDetails"&gt;&lt;/div&gt;
&lt;div class="result-hint"&gt;Show hand to bowl again&lt;/div&gt;
&lt;/div&gt;
&lt;div class="error hidden" id="cameraError" role="alert"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="game-stats"&gt;
&lt;div class="stat-row"&gt;
&lt;span class="stat-label"&gt;Fast balls:&lt;/span&gt;
&lt;span class="stat-value" id="statFast"&gt;0&lt;/span&gt;
&lt;/div&gt;
&lt;div class="stat-row"&gt;
&lt;span class="stat-label"&gt;Spin balls:&lt;/span&gt;
&lt;span class="stat-value" id="statSpin"&gt;0&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="debug-panel hidden" id="debugPanel"&gt;
&lt;div class="debug-header"&gt;
&lt;strong&gt;DEBUG MODE&lt;/strong&gt;
&lt;div&gt;
&lt;button class="btn btn--small" id="btnDebugClear" type="button"&gt;Clear Recording&lt;/button&gt;
&lt;button class="btn btn--small" id="btnDebugClose" type="button"&gt;X&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id="debugOutput" style="font-size: 11px; margin: 0; white-space: pre-wrap;"&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;button class="btn btn--small" id="btnDebug" type="button" style="margin-top: 8px;"&gt;Show Debug&lt;/button&gt;
&lt;/section&gt;
&lt;section class="panel"&gt;
&lt;div class="panel__header"&gt;
&lt;h2 class="panel__title"&gt;3D Scene&lt;/h2&gt;
&lt;div class="panel__actions"&gt;
&lt;button class="btn" id="btnReset" type="button"&gt;Reset Game&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="scene"&gt;
&lt;canvas id="threeCanvas"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;footer class="cricket-footer"&gt;
&lt;span class="muted"&gt;Tip: Good lighting helps hand tracking. Works best on Chrome/Safari.&lt;/span&gt;
&lt;/footer&gt;
&lt;/section&gt;
&lt;/main&gt;
&lt;/div&gt;</description></item><item><title>Tic Tac Toe</title><link>https://vijay.eu/projects/tic-tac-toe/</link><pubDate>Wed, 02 Jul 2025 15:20:07 +0300</pubDate><guid>https://vijay.eu/projects/tic-tac-toe/</guid><description>&lt;p&gt;Created it using Google Gemini CLI on 2nd Jul 2025
&lt;link rel="stylesheet" href="https://vijay.eu/css/tic-tac-toe.css"&gt;
&lt;div class="tic-tac-toe-container"&gt;
&lt;div id="game-setup"&gt;
&lt;div class="setup-section"&gt;
&lt;p class="setup-title"&gt;Game Mode&lt;/p&gt;
&lt;div class="button-group" id="game-mode-selector"&gt;
&lt;button class="btn-toggle active" data-mode="pvc"&gt;Player vs. Computer&lt;/button&gt;
&lt;button class="btn-toggle" data-mode="pvp"&gt;Player vs. Player&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="setup-section" id="first-move-container"&gt;
&lt;p class="setup-title"&gt;Who Goes First?&lt;/p&gt;
&lt;div class="button-group" id="first-move-selector"&gt;
&lt;button class="btn-toggle active" data-first-move="player"&gt;Player (X)&lt;/button&gt;
&lt;button class="btn-toggle" data-first-move="computer"&gt;Computer (O)&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;button id="start-game"&gt;Start Game&lt;/button&gt;
&lt;/div&gt;
&lt;div id="game-board" class="hidden"&gt;
&lt;div class="cell" data-index="0"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="1"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="2"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="3"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="4"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="5"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="6"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="7"&gt;&lt;/div&gt;
&lt;div class="cell" data-index="8"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id="message" class="hidden"&gt;&lt;/div&gt;
&lt;button id="restart-game" class="hidden"&gt;Restart Game&lt;/button&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/tic-tac-toe.js"&gt;&lt;/script&gt;
&lt;/p&gt;</description></item><item><title>Decibel Meter</title><link>https://vijay.eu/projects/decibel-meter/</link><pubDate>Wed, 12 Mar 2025 23:28:14 +0200</pubDate><guid>https://vijay.eu/projects/decibel-meter/</guid><description>&lt;p&gt;Built using Anthropic Claude Code CLI.&lt;/p&gt;
&lt;div class="decibel-meter-wrapper"&gt;
&lt;div class="speedometer-container"&gt;
&lt;div class="needle-container"&gt;
&lt;div class="needle" id="needle"&gt;&lt;/div&gt;
&lt;div class="needle-center"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="reading" id="reading"&gt;0 dB&lt;/div&gt;
&lt;div class="description" id="description"&gt;Please enable microphone&lt;/div&gt;
&lt;button id="startButton"&gt;Start Measuring&lt;/button&gt;
&lt;div class="sensitivity-control"&gt;
&lt;label for="sensitivity"&gt;Microphone Sensitivity: &lt;span id="sensitivityValue"&gt;&lt;/span&gt;&lt;/label&gt;
&lt;input type="range" id="sensitivity" min="1" max="5" step="0.5" value="2.0"&gt;
&lt;/div&gt;
&lt;div class="error" id="errorMessage"&gt;&lt;/div&gt;
&lt;div class="child-voice-legend"&gt;
&lt;div class="child-voice-title"&gt;Voice Level Guide for Kids&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #4CAF50;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Whisper to Library Voice (0-40 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #7CB342;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Indoor Voice (40-60 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FFC107;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Classroom Voice (60-70 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FF9800;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Playground Voice (70-80 dB)&lt;/span&gt;
&lt;/div&gt;
&lt;div class="voice-level-item"&gt;
&lt;div class="voice-level-color" style="background: #FF5722;"&gt;&lt;/div&gt;
&lt;span class="voice-level-text"&gt;Too Loud! (80+ dB)&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script src="https://vijay.eu/js/decibel-meter.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="https://vijay.eu/css/decibel-meter.css"&gt;
&lt;ul&gt;
&lt;li&gt;No data is stored or transmitted - all processing happens locally in your browser.&lt;/li&gt;
&lt;li&gt;dB values are approximate. Calibration has not been done.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Markdown Editor</title><link>https://vijay.eu/projects/markdown-editor/</link><pubDate>Sun, 09 Mar 2025 23:44:00 +0300</pubDate><guid>https://vijay.eu/projects/markdown-editor/</guid><description>&lt;p&gt;Generated using Claude Code agentic tool.&lt;/p&gt;
&lt;div class="markdown-editor-container"&gt;
&lt;div class="editor-toolbar"&gt;
&lt;div class="toolbar-dropdown"&gt;
&lt;button class="toolbar-btn dropdown-toggle" title="Headings"&gt;H&lt;/button&gt;
&lt;div class="dropdown-menu"&gt;
&lt;button class="toolbar-btn" data-action="heading1" title="Heading 1 (# text)" data-tag="# "&gt;H1&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="heading2" title="Heading 2 (## text)" data-tag="## "&gt;H2&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="heading3" title="Heading 3 (### text)" data-tag="### "&gt;H3&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="heading4" title="Heading 4 (#### text)" data-tag="#### "&gt;H4&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="heading5" title="Heading 5 (##### text)" data-tag="##### "&gt;H5&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="heading6" title="Heading 6 (###### text)" data-tag="###### "&gt;H6&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;button class="toolbar-btn" data-action="bold" title="Bold (**text**)" data-tag="**"&gt;B&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="italic" title="Italic (*text*)" data-tag="*"&gt;I&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="strikethrough" title="Strikethrough (~~text~~)" data-tag="~~"&gt;S&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="link" title="Link ([text](url))" data-tag="[](url)"&gt;🔗&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="image" title="Image (![alt](url))" data-tag="![alt](url)"&gt;🖼️&lt;/button&gt;
&lt;div class="toolbar-dropdown"&gt;
&lt;button class="toolbar-btn dropdown-toggle" title="Code"&gt;📝&lt;/button&gt;
&lt;div class="dropdown-menu"&gt;
&lt;button class="toolbar-btn" data-action="code" title="Inline Code (`code`)" data-tag="`"&gt;Inline&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="codeblock-js" title="JavaScript Code Block" data-tag="```javascript"&gt;JavaScript&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="codeblock-html" title="HTML Code Block" data-tag="```html"&gt;HTML&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="codeblock-css" title="CSS Code Block" data-tag="```css"&gt;CSS&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="codeblock-python" title="Python Code Block" data-tag="```python"&gt;Python&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="codeblock" title="Code Block" data-tag="```"&gt;No Language&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;button class="toolbar-btn" data-action="blockquote" title="Blockquote (&gt; text)" data-tag="&gt; "&gt;❝&lt;/button&gt;
&lt;div class="toolbar-dropdown"&gt;
&lt;button class="toolbar-btn dropdown-toggle" title="Lists"&gt;•&lt;/button&gt;
&lt;div class="dropdown-menu"&gt;
&lt;button class="toolbar-btn" data-action="unordered-list" title="Unordered List (- item)" data-tag="- "&gt;Bullet List&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="ordered-list" title="Ordered List (1. item)" data-tag="1. "&gt;Numbered List&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="task-list" title="Task List (- [ ] task)" data-tag="- [ ] "&gt;Task List&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;button class="toolbar-btn" data-action="hr" title="Horizontal Rule (---)" data-tag="---"&gt;―&lt;/button&gt;
&lt;button class="toolbar-btn" data-action="table" title="Table (| header | header |)"&gt;📊&lt;/button&gt;
&lt;/div&gt;
&lt;div class="editor-panels"&gt;
&lt;div class="editor-panel"&gt;
&lt;h3&gt;Markdown&lt;/h3&gt;
&lt;textarea id="markdown-input" placeholder="Type your markdown here..."&gt;&lt;/textarea&gt;
&lt;div class="editor-status"&gt;
&lt;span id="word-count"&gt;0 words&lt;/span&gt;
&lt;span id="char-count"&gt;0 characters&lt;/span&gt;
&lt;span id="cursor-position"&gt;Line: 1, Column: 1&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="editor-panel"&gt;
&lt;h3&gt;Preview&lt;/h3&gt;
&lt;div id="markdown-preview"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here is the cost and time it took to create this working code and testing it.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;gt; /cost
⎿ Total cost: $1.01
Total duration (API): 5m 8.1s
Total duration (wall): 31m 43.5s
Total code changes: 713 lines added, 43 lines removed
⎿ Set editor mode to vim
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You just have to have clear requirements and what you want and LLMs are there to make it happen.&lt;/p&gt;</description></item><item><title>Your Public IP Address</title><link>https://vijay.eu/projects/my-ip/</link><pubDate>Sat, 10 Aug 2024 12:05:32 +0300</pubDate><guid>https://vijay.eu/projects/my-ip/</guid><description>&lt;div style="text-align: left; margin-top: 20vh;"&gt;
&lt;div id="ip-address" style="font-size: 2em; color: #007bff; margin-top: 20px;"&gt;
Fetching IP address...
&lt;/div&gt;
&lt;script type="application/javascript"&gt;
function getIP(json) {
document.getElementById('ip-address').textContent = json.ip;
}
&lt;/script&gt;
&lt;script type="application/javascript" src="https://api.ipify.org?format=jsonp&amp;callback=getIP"&gt;&lt;/script&gt;
&lt;/div&gt;</description></item><item><title>Fitness Calculator</title><link>https://vijay.eu/projects/fitness-calculator/</link><pubDate>Fri, 09 Aug 2024 18:55:00 +0300</pubDate><guid>https://vijay.eu/projects/fitness-calculator/</guid><description>&lt;div class="container"&gt;
&lt;div id="intro-text"&gt;
&lt;p&gt;
The 2 Km Walk Test is a reliable way to estimate your maximal aerobic power (VO2max) and assess your fitness level.
&lt;/p&gt;
&lt;p&gt;
To ensure accurate results, please follow these steps before filling in the details below:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Preparation:&lt;/strong&gt; Ensure you are in good health and fit to undertake the test. Wear comfortable clothing and shoes suitable for walking.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Walk 2 Kilometers:&lt;/strong&gt; Find a flat, measured course (e.g., a track or a known distance on a path). Walk a total distance of 2 kilometers at a brisk, steady pace.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collect Your Data:&lt;/strong&gt; As soon as you finish the 2 km walk, immediately measure your heart rate (beats per minute) and note the total time taken to complete the walk (in minutes and seconds).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter Your Details:&lt;/strong&gt; Once you have completed the walk and collected the necessary data, fill in the information below to calculate your fitness index.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;form id="fitness-form"&gt;
&lt;div&gt;
&lt;label for="age"&gt;Age (years):&lt;/label&gt;
&lt;input type="number" id="age" name="age" required&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="gender"&gt;Gender:&lt;/label&gt;
&lt;select id="gender" name="gender" required&gt;
&lt;option value="male"&gt;Male&lt;/option&gt;
&lt;option value="female"&gt;Female&lt;/option&gt;
&lt;/select&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="weight"&gt;Weight (kg):&lt;/label&gt;
&lt;input type="number" id="weight" name="weight" step="0.1" required&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="height"&gt;Height (cm):&lt;/label&gt;
&lt;input type="number" id="height" name="height" required&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="time-minutes"&gt;Time to complete 2 km (minutes):&lt;/label&gt;
&lt;input type="number" id="time-minutes" name="time-minutes" required&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="time-seconds"&gt;Time to complete 2 km (seconds):&lt;/label&gt;
&lt;input type="number" id="time-seconds" name="time-seconds" required&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;label for="heart-rate"&gt;Heart rate at the end of the walk (bpm):&lt;/label&gt;
&lt;input type="number" id="heart-rate" name="heart-rate" required&gt;
&lt;/div&gt;
&lt;button type="submit"&gt;Calculate Fitness&lt;/button&gt;
&lt;p class="disclaimer"&gt;
&lt;strong&gt;Disclaimer:&lt;/strong&gt; This tool is for informational purposes only and is not a substitute for professional medical advice, diagnosis, or treatment. Always consult your doctor or a qualified health professional before making any changes to your exercise routine or lifestyle.
&lt;/p&gt;
&lt;/form&gt;
&lt;div id="results" style="display:none;"&gt;
&lt;h3&gt;Your Fitness Results&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Maximal Aerobic Power (VO2max):&lt;/strong&gt; &lt;span id="vo2max-result"&gt;&lt;/span&gt; ml·min⁻¹·kg⁻¹&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BMI:&lt;/strong&gt; &lt;span id="bmi-result"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fitness Index:&lt;/strong&gt; &lt;span id="fitness-index-result"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fitness Class:&lt;/strong&gt; &lt;span id="fitness-class-result"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div id="calculation-details" style="margin-top: 40px;"&gt;
&lt;/div&gt;
&lt;button id="new-calculation"&gt;New Calculation&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Flag Game</title><link>https://vijay.eu/projects/flag-game/</link><pubDate>Thu, 08 Aug 2024 07:00:32 +0300</pubDate><guid>https://vijay.eu/projects/flag-game/</guid><description>&lt;div class="container"&gt;
&lt;div class="status"&gt;
&lt;div class="counter"&gt;&lt;strong id="quiz-mini-counter"&gt;1&lt;/strong&gt; / 10&lt;/div&gt;
&lt;div class="correct"&gt;&lt;strong id="quiz-mini-correct"&gt;0&lt;/strong&gt; correctly&lt;/div&gt;
&lt;div class="wrong"&gt;&lt;strong id="quiz-mini-wrong"&gt;0&lt;/strong&gt; wrong&lt;/div&gt;
&lt;/div&gt;
&lt;div id="quiz-mini-image" class="image"&gt;&lt;/div&gt;
&lt;div id="quiz-mini-options" class="options"&gt;&lt;/div&gt;
&lt;div id="quiz-mini-result" class="result" style="display: none;"&gt;
&lt;small&gt;
&lt;strong&gt;&lt;span id="quiz-mini-result-correct"&gt;Well done!&lt;/span&gt;&lt;/strong&gt;
&lt;span id="quiz-mini-result-wrong"&gt;False, it is &lt;strong id="quiz-mini-result-wrong-name"&gt;*&lt;/strong&gt;&lt;/span&gt;
&lt;/small&gt;
&lt;button id="quiz-mini-refresh" style="display: none;"&gt;Restart Game&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Paris 2024 Olympics Medal Tally</title><link>https://vijay.eu/projects/medal-tally/</link><pubDate>Thu, 01 Aug 2024 16:49:32 +0300</pubDate><guid>https://vijay.eu/projects/medal-tally/</guid><description>&lt;p&gt;Final medal tally for Finland and India from the Paris 2024 Olympics.&lt;/p&gt;
&lt;div class="medal-tally-container"&gt;
&lt;div class="medal-box"&gt;
&lt;h2&gt;Finland&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Gold&lt;/th&gt;
&lt;th&gt;Silver&lt;/th&gt;
&lt;th&gt;Bronze&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="medal-box"&gt;
&lt;h2&gt;India&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Gold&lt;/th&gt;
&lt;th&gt;Silver&lt;/th&gt;
&lt;th&gt;Bronze&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;71&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.medal-tally-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin: 20px 0;
}
.medal-box {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 20px;
flex: 1 1 300px;
max-width: 300px;
text-align: center;
}
.medal-box h2 {
margin-top: 0;
margin-bottom: 15px;
}
.medal-box table {
width: 100%;
border-collapse: collapse;
}
.medal-box th, .medal-box td {
border: 1px solid #ddd;
padding: 8px;
text-align: center;
}
.medal-box th {
background-color: #f2f2f2;
}
&lt;/style&gt;</description></item></channel></rss>