22 Free Exercises · Voice-Guided · Live Timer · Global Leaderboard · No Equipment · No Login · India

Free Guided Wellness Exercises – Brain Training, Pranayama & More | Wellness Clinic

India's only free Ayurvedic wellness exercise platform. 22 voice-guided activities: Nadi Shodhana Pranayama, Bhramari, Kapalabhati, Trataka (Candle Focus), Vajrasana, eye yoga, brain games & more. Each activity explains every step in plain language with a live timer. No app download, no login — works on any phone.

🧪 Take the Wellness Lab for personalised exercise recommendations →
22Free Exercises
6Categories
1–5Min Each
FreeAlways
🌿
Welcome back!
Your streak continues. Start today's routine to keep it going.
🔥 Loading streak…
🎯 Recommended for You — Based on Your Wellness Lab Results
Your test results show areas that need attention. Tap any category below to see the activities that will help you most.
Activities marked ★ Recommended on the cards below are matched to your results.
22 Guided Activities

Choose Your Activity

Filter by category or see all. Each activity guides you step by step — read the instructions, then press Start when you're ready.

Build Your Habit

Daily Wellness Routine

Two short routines — morning and night — that build healthy habits over time. Tap any activity to begin, or start the full routine at once.

🌅 Morning Routine
10 minutes · Energise & activate your mind and body
🏃
Full Body Wake-Up Movement
⏱ 3 min
Begin
🌬️
Alternate Nostril Breathing
⏱ 5 min
Begin
🐝
Humming Breath (Bhramari)
⏱ 2 min
Begin
🌙 Night Routine
8 minutes · Calm your body & support digestion
🧘
After-Meal Sitting Pose
⏱ 5 min
Begin
🕯️
Candle Focus Exercise
⏱ 3 min
Begin
💤
4-7-8 Relaxation Breathing
⏱ 4 min
Begin
Exercises by Health Goal

What Are You Working On?

Select a health goal to instantly filter activities most relevant to you.

🧠
Brain & Memory
Humming Breath
Candle Focus
Memory Match
🧘
Stress Relief
Box Breathing
Alternate Nostril
4-7-8 Breathing
🍃
Digestion
After-Meal Sitting
Knee-to-Chest
Digestive Routine
🦴
Joint Pain
Cross-Body Movement
Neck & Shoulder
Wrist Relief
👁️
Eye Strain
Eye Movement
20-20-20 Rule
Eye Massage
Ayurvedic Support

Boost Your Practice with Herbal Support

Pair your exercises with the right Ayurvedic supplement for faster, more lasting results.

Your Progress

Daily Wellness Dashboard

Track your exercises, scores and streaks. Your data is saved on this device — no login needed.

🏆 Daily Wellness Score
Complete exercises to build your score
Brain
Breathing
Body
Focus
🔥 Practice Streak
0Current Days
0Best Streak
📅 This Week
🏅 Personal Bests
Fastest Reaction
Best Memory
Best Math
📊 Today's Progress
🧠 Brain
0%
🌬️ Breathing
0%
🤸 Body
0%
👁️ Eyes
0%
✅ Today's Routine
Morning
Evening
💡 Daily Tip Practicing breathing exercises for just 5 minutes daily may support focus and reduce feelings of stress.
About Shah Hayaat Wellness Clinic

India's Best Free Guided Wellness Exercises – 2026

🧠 Free Brain Training Exercises with Global Leaderboard

Shah Hayaat offers 6 free brain training exercises: Reaction Speed Test (15-second tap challenge with live global leaderboard), Math Speed Challenge (60-second mental maths), Memory Match Game (flip card pairs), Candle Focus (Ayurvedic Trataka concentration practice), Number Sequence (tap 1–25 in order), and Typing Speed Test (WPM with global ranking). All voice-guided with live timers. No app download, no login — completely free.

🌬️ Free Pranayama & Breathing Exercises Online India

5 free guided pranayama exercises: Alternate Nostril Breathing (Nadi Shodhana — balances nervous system, reduces cortisol), Bhramari Pranayama (Humming Breath — proven to lower blood pressure and reduce anxiety), Box Breathing (Navy SEAL stress control technique), 4-7-8 Relaxation Breathing (activates parasympathetic response for sleep), and Quick Energy Breath (floods brain with oxygen for instant alertness). Each has step-by-step voice guidance and breathing ring animation.

👁️ Free Eye Yoga & Digital Eye Strain Relief Exercises

3 free guided eye exercises: Eye Movement Exercise (exercises all 6 eye muscles — up/down, left/right, diagonal circles, palming — reverses strain from screen use), 20-20-20 Eye Rest Rule (the optometrist gold standard for digital eye strain prevention — look 20 feet away for 20 seconds every 20 minutes), and Ayurvedic Eye Massage (acupressure points along brow bone, under-eye ridge, temples and nose bridge to relieve headaches and eye fatigue).

🍃 Free Ayurvedic Digestion Exercises After Meals

3 free guided Ayurvedic digestion exercises: Vajrasana After-Meal Sitting (classical Ayurvedic post-meal practice — compresses the digestive tract for better enzyme activity), Digestive Activation Routine (gentle post-meal walking + clockwise abdominal massage + belly breathing — proven to reduce blood sugar spike by up to 30%), and Agni Breath — Kapalabhati (pumping exhales that massage the stomach, awaken digestive fire and relieve bloating and gas).

🤸 Free Body Movement & Posture Exercises No Equipment

4 free guided body exercises: Neck & Shoulder Release (2-minute cervical decompression for desk workers — tilts, circles, shoulder shrugs), Wrist & Hand Relief (prevents repetitive strain injury from typing — finger stretches, wrist circles, prayer stretch), Cross-Body Movement (activates both brain hemispheres simultaneously — used in brain rehabilitation worldwide), and Stand & Full Body Stretch (reverses effects of prolonged sitting in under 2 minutes).

Why Shah Hayaat Wellness Clinic is India\'s Best Free Exercise Platform

Unlike most wellness apps that require a subscription, account or app download, Shah Hayaat Wellness Clinic is 100% free, forever — accessible on any phone or computer instantly. Features include: voice guidance that walks you through every step, live countdown timers so you always know where you are, global leaderboards for brain games, daily streak tracking saved automatically on your device, personalised exercise recommendations from the free Wellness Lab assessment, and Ayurvedic product pairing suggestions for each exercise category. This is Shah Hayaat\'s gift to India\'s health.

About Shah Hayaat Wellness Clinic

India's Best Free Ayurvedic Wellness Exercise Platform

22 Free Voice-Guided Exercises — No App, No Login, No Equipment

Shah Hayaat Wellness Clinic is India's most complete free guided wellness exercise platform. All 22 activities are 100% free, require no app download, no login and no equipment — just a phone or computer and a few minutes per day. Voice guidance in clear English walks you through every step, and a live countdown timer keeps you on track.

Each exercise includes a "How to Do This" step-by-step guide before you start, an optional voice companion during the exercise, and a completion summary at the end. You can do exercises individually, follow the morning or night routine, or start all activities in sequence. Your streak, scores and progress are automatically saved on your device — no account needed.

Pranayama Breathing Exercises — Nadi Shodhana, Bhramari, Box Breathing & More

The breathing category includes five evidence-backed Pranayama techniques used in Ayurveda and modern clinical settings. Nadi Shodhana (Alternate Nostril Breathing) balances the left and right hemispheres of the brain and reduces cortisol — 5 minutes of guided practice with phase-by-phase voice instruction. Bhramari (Humming Bee Breath) creates calming cranial vibrations proven to lower blood pressure and reduce anxiety. Box Breathing — used by military personnel and athletes worldwide — uses four equal counts to rebalance the autonomic nervous system in under 5 minutes. 4-7-8 Breathing activates the parasympathetic "rest and digest" system for deep relaxation. Quick Energy Breath (Kapalabhati-inspired) provides an immediate oxygen surge for energy and alertness without caffeine.

Brain Training Exercises — Reaction Test, Memory Match, Math Challenge & Trataka

Six free brain training exercises with global leaderboards. The Reaction Speed Test measures and trains your fastest possible tap response — users compete on a live global leaderboard. Math Speed Challenge activates the prefrontal cortex with 60 seconds of rapid mental arithmetic. Memory Match Game trains short-term visual memory — find all 8 emoji pairs in the fewest attempts. Candle Focus (Trataka) is the classical Ayurvedic concentration practice: fix your gaze on a candle flame shown on screen to develop single-pointed attention and reduce mind wandering. Number Sequence tests visual search speed and sustained attention — tap 1 to 25 in order as fast as possible. Typing Speed Test with Shah Hayaat\'s unique 100 wellness passage library trains finger agility, focus and hand-brain coordination.

Eye Yoga & Screen Relief — Trataka, 20-20-20 Rule & Ayurvedic Eye Massage

Three dedicated eye exercises for India's screen-dependent workforce and students. The Eye Movement Exercise trains all 6 eye muscles through up-down, left-right, diagonal and circular movements — recommended for everyone who spends more than 2 hours daily on screens. The 20-20-20 Rule is the optometrist-recommended approach to digital eye strain: every 20 minutes, look 20 feet away for 20 seconds. Shah Hayaat\'s guided version adds slow blinks, near-far focus switching and eye palming. The Ayurvedic Eye Massage stimulates acupressure points around the eyes — brow bone, under-eye bone, nose bridge, temples — to relieve eye fatigue and tension headaches. All three exercises are free, guided and take under 3 minutes each.

Digestive Exercises — Vajrasana After-Meal Pose, Agni Breath & Digestive Routine

Three Ayurvedic digestive exercises address India's most common health complaint. Vajrasana (After-Meal Sitting Pose) — sitting on your knees for 5 minutes after eating — compresses the digestive tract in the way Ayurveda has prescribed for centuries. Modern studies confirm it significantly reduces post-meal bloating. Digestive Activation Routine combines slow walking, clockwise abdominal massage and belly breathing — research shows post-meal walking can reduce blood sugar spikes by up to 30%. Agni Breath (Kapalabhati Pranayama) uses rapid pumping exhales to massage the stomach from inside — Ayurveda\'s primary technique for awakening digestive fire and clearing metabolic toxins (Ama).

Pair Exercises with Ayurvedic Herbal Support

Shah Hayaat's exercises are designed to complement its WHO-GMP certified Ayurvedic product range. Brain training exercises are most effective alongside Brain Champ (Brahmi, Shankhpushpi, Ashwagandha — ₹175). Breathing and immunity exercises pair with Fevodol (Giloy, Tulsi — ₹165). Digestive exercises work alongside Shah Zyme digestive enzyme syrup (₹165). Joint and mobility exercises pair with Ortho Hayaat (Shallaki, Guggul — ₹649). Exercise and herbal support together produce results faster than either alone.

Frequently Asked Questions

Are all exercises completely free?

Yes. All 22 exercises on Shah Hayaat Wellness Clinic are permanently free. No subscription, no premium tier, no in-app purchases. The free tools are a social initiative — Shah Hayaat\'s way of giving back to the community.

What equipment do I need for these exercises?

No equipment at all. Every exercise is designed for anywhere — at your desk, bedroom floor, or immediately after a meal. You only need a phone or computer. Pranayama exercises only need a quiet place to sit.

What is the best free brain training exercise online in India?

Shah Hayaat offers 6 free brain training exercises with live leaderboards: Reaction Speed Test, Math Speed Challenge, Memory Match Game, Candle Focus (Trataka), Number Sequence (1 to 25), and Typing Speed Test — all in one place, free, with no download required.

Which Pranayama is best for beginners in India?

For complete beginners, start with Box Breathing (4 counts in, hold, 4 out, hold). It is the simplest structured breathing technique and shows immediate stress relief results. After 1–2 weeks, try Nadi Shodhana (Alternate Nostril) for deeper nervous system benefits. Shah Hayaat\'s guided versions walk you through every breath, so no prior experience is needed.

Can these exercises help with digestion problems?

Yes. Vajrasana after meals, Kapalabhati (Agni Breath) and post-meal walking are all Ayurvedic practices with clinical evidence for digestive support. For comprehensive digestive care, pair these exercises with Shah Zyme digestive syrup. Most people with chronic bloating notice significant improvement within 2–3 weeks of consistent daily practice.

🔗 Related Health Guides & Products
→ Ayurvedic Memory Booster Guide (Brahmi) → Ayurvedic Immunity Booster – Giloy & Tulsi → Ayurvedic Joint Pain Treatment Guide → Ayurvedic Digestion Treatment Guide → Ayurvedic Acidity & Heartburn Guide → Ayurvedic Liver Detox & Fatty Liver Guide → Brain Champ – Memory Booster ₹175 → Free Wellness Lab – Personalised Assessment → Ayurvedic Wellness Blog
💬
🎉
Great job!
You completed this exercise.
🌿
⭐⭐⭐⭐⭐
You\'re doing amazing
could you do us one favour?
Shah Hayaat has been quietly changing lives for generations — but we need your voice to reach the people who need us most.

A 5-star review takes 30 seconds and means the world to our small team. Share what you love — even one honest line makes a huge difference. 🙏
⭐ Leave a 5-Star Review
🏆
You scored taps!
Enter your name to save your score on the global leaderboard, or skip to save as Anonymous.
📊 Your Stats
🏆 Your Global Ranks
🔥 Streak
🏅
Achievement Unlocked!
🏅 Achievements
Loading…
/* ════════════════════════════════════════════════════════════ GAME LEADERBOARD — Math, Memory, Number Sequence Each game saves {name, score, game, metric} via POST and shows rank on the done screen via #gameGlobalRank ════════════════════════════════════════════════════════════ */ var _gameLbPendingData = null; // {game, score, metric, wpm, acc} set by each game finish /* Show the game name modal (reuses #tyExNameModal styling) */ /* ═══════════════════════════════════════════════════════ GAME LEADERBOARDS — Math, Memory, Number Sequence Each uses its own POST type and its own sheet in GAS ═══════════════════════════════════════════════════════ */ var _gameLbPendingData = null; function _gameShowBox(html, bg, border) { var gameIds = ['math-challenge','memory-match','number-sequence']; if (!_ex || gameIds.indexOf(_ex.id) === -1) return; var el = document.getElementById('gameGlobalRank'); if (!el) return; el.innerHTML = html; _rankBoxShow(el, '', bg || '', border || ''); } function gameLbShowModal(postType, label, extraData) { // extraData = extra fields beyond name (correct, wrong, attempts, time, elapsed) _gameLbPendingData = { postType:postType, label:label, extra:extraData }; var m = document.getElementById('tyExNameModal'); var sv = document.getElementById('tyExModalScore'); if (sv) sv.textContent = label; var ttl = document.querySelector('#tyExNameModal h3'); if (ttl) ttl.textContent = 'Save your score to the leaderboard'; if (m) m.style.display = 'flex'; setTimeout(function(){ var inp=document.getElementById('tyExNameInput'); if(inp){inp.value='';inp.focus();} },300); } function _gameDoSave(name, data) { var displayName = (name && name.length >= 2) ? name : 'Anonymous'; var payload = Object.assign({ type: data.postType, name: displayName }, data.extra); var savedExId = _ex ? _ex.id : null; // capture at call time — guard stale async responses var el2 = document.getElementById('gameGlobalRank'); if (el2) { el2.innerHTML = '
⏳ Saving…
'; _rankBoxShow(el2, '', '', ''); } fetch(GAME_LB_API, { method:'POST', redirect:'follow', headers:{'Content-Type':'text/plain'}, body: JSON.stringify(payload) }) .then(function(r){ return r.json(); }) .then(function(json){ if (json.ok && json.rank >= 1) { var rank=json.rank, savedExId2=savedExId; // Guard removed — rank shows even at queue "All Done" screen _showAnimatedRank(rank, json.score, '', 0, savedExId2, 'gameGlobalRank'); } else { // No rank returned — show local estimate var savedExId3 = savedExId; var metricVal = data.extra ? (data.extra.score || data.extra.wpm || data.extra.taps || 0) : 0; var estRank = _estimateLocalRank(metricVal, savedExId3 || ''); _showAnimatedRank(estRank, json.score || metricVal, '', 0, savedExId3, 'gameGlobalRank'); } setTimeout(function(){ gameLbLoad(data.postType.replace('_score','')); }, 800); }) .catch(function(){ // Network error — show local estimate var metricVal = data.extra ? (data.extra.score || data.extra.wpm || data.extra.taps || 0) : 0; var estRank = _estimateLocalRank(metricVal, savedExId || ''); _showAnimatedRank(estRank, metricVal, '', 0, savedExId, 'gameGlobalRank'); }); } function gameLbLoad(gameKey) { // gameKey = 'math' | 'memory' | 'sequence' var typeMap = {'math':'math_scores','memory':'memory_scores','sequence':'sequence_scores', 'math-challenge':'math_scores','memory-match':'memory_scores','number-sequence':'sequence_scores', 'speed-reading':'speed_reading_scores','speed_reading_score':'speed_reading_scores','speed_reading':'speed_reading_scores',}; var listMap = {'math':'gameLbList_math_challenge','memory':'gameLbList_memory_match','sequence':'gameLbList_number_sequence', 'math-challenge':'gameLbList_math_challenge','memory-match':'gameLbList_memory_match','number-sequence':'gameLbList_number_sequence', 'speed-reading':'gameLbList_speed_reading','speed_reading_score':'gameLbList_speed_reading','speed_reading':'gameLbList_speed_reading',}; var scoreType = typeMap[gameKey]; var listId = listMap[gameKey]; if (!scoreType || !listId) return; fetch(GAME_LB_API + '?type=' + scoreType, {method:'GET', redirect:'follow', mode:'cors'}) .then(function(r){ return r.json(); }) .then(function(json){ var list = document.getElementById(listId); if (!list) return; var rows = (json.ok && json.data) ? json.data.filter(function(r){ return r.name && !r.name.startsWith('__auto__'); }) : []; if (!rows.length) { list.innerHTML='
No scores yet. Be the first!
'; return; } var metricFn = { math_scores: function(r){ return (r.correct||r.score)+' correct'; }, memory_scores: function(r){ return (r.attempts||'')+' attempts'; }, sequence_scores: function(r){ return (r.elapsed||'')?r.elapsed+'s':r.score+' pts'; } }[scoreType] || function(r){ return r.score+' pts'; }; list.innerHTML = rows.slice(0,500).map(function(r,i){ var medal=i===0?'🥇':i===1?'🥈':i===2?'🥉':('#'+(i+1)); return '
' + ''+medal+''+ ''+_esc(r.name)+''+ ''+metricFn(r)+'
'; }).join(''); }).catch(function(){}); } /* ════════════════════════════════════════════════════════════ TYPING SCORE FLOW — name first, then single POST 1. Game finishes → show name modal immediately (nothing saved yet) 2a. User enters name → POST {name, wpm, acc} → show rank from response 2b. User skips → POST {name:'Anonymous', wpm, acc} → silent save ════════════════════════════════════════════════════════════ */ var _tyExPendingWPM = 0; var _tyExPendingAcc = 0; function tyShowNameModal(wpm, acc) { _tyExPendingWPM = wpm; _tyExPendingAcc = acc; var m = document.getElementById('tyExNameModal'); var sv = document.getElementById('tyExModalScore'); if (sv) sv.textContent = wpm + ' WPM, ' + acc + '% accuracy'; if (m) m.style.display = 'flex'; setTimeout(function() { var inp = document.getElementById('tyExNameInput'); if (inp) { inp.value = ''; inp.focus(); } }, 400); } /* POST score with name, show rank from GAS response */ function tySaveScore(name, wpm, acc) { var displayName = (name && name.length >= 2) ? name : 'Anonymous'; function showOnDone(html, extraCls) { var el = document.getElementById('tyGlobalRank'); if (!el) return; el.innerHTML = html; _rankBoxShow(el, extraCls, '', ''); } showOnDone('
⏳ Saving score…
', ''); fetch(TY_LB_API, { method: 'POST', redirect: 'follow', headers: { 'Content-Type': 'text/plain' }, body: JSON.stringify({ type: 'typing_score', name: displayName, wpm: wpm, acc: acc }) }) .then(function(r) { return r.json(); }) .then(function(json) { if (json.ok && json.rank >= 1) { _tyShowRank(json.rank, json.score); } else { // No rank from API — estimate locally var pts = json.score || Math.round(wpm * (acc / 100) * 10); var estRank = _estimateLocalRank(wpm, 'typing-speed'); _showAnimatedRank(estRank, pts, '', 0, 'typing-speed', 'tyGlobalRank'); } setTimeout(tyLbLoad, 1000); }) .catch(function() { // Network error — show local estimate var pts = Math.round(wpm * (acc / 100) * 10); var estRank = _estimateLocalRank(wpm, 'typing-speed'); _showAnimatedRank(estRank, pts, '', 0, 'typing-speed', 'tyGlobalRank'); }); } function _tyShowRank(rank, score) { /* Typing panel bar */ var medal = rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : '🏅'; var bar = document.getElementById('tyOvRank'); if (bar) { bar.innerHTML = '' + medal + ' Rank #' + rank + ''; bar.style.display = 'block'; } /* Done screen animated reveal — guard removed so rank shows at queue "All Done" too */ _showAnimatedRank(rank, score, '', 0, 'typing-speed', 'tyGlobalRank'); } window._tyExSubmitName = function() { var inp = document.getElementById('tyExNameInput'); var raw = inp ? inp.value.trim() : ''; var name = raw.replace(/[^a-zA-Z0-9 ]/g, '').trim(); var warn = document.getElementById('tyExNameWarn'); if (name && name.length < 2) { if(warn) warn.textContent='Min 2 characters'; return; } if (warn) warn.textContent = ''; var m = document.getElementById('tyExNameModal'); if (m) m.style.display = 'none'; if (_gameLbPendingData) { _gameDoSave(name, _gameLbPendingData); _gameLbPendingData = null; } else { tySaveScore(name || 'Anonymous', _tyExPendingWPM, _tyExPendingAcc); } }; window._tyExSkipName = function() { var m = document.getElementById('tyExNameModal'); if (m) m.style.display = 'none'; // Re-show PDF button if speed reading was just completed var _pb=document.getElementById('ovSrPdfBtn'); if(_pb && _srPassage) _pb.style.display=''; if (_gameLbPendingData) { _gameDoSave('Anonymous', _gameLbPendingData); _gameLbPendingData = null; } else { tySaveScore('Anonymous', _tyExPendingWPM, _tyExPendingAcc); } }; /* Game state */ var _tyPassage = ''; var _tyStarted = false, _tyFinished = false, _tyStartTime = 0; var _tyTimerInt = null, _tyRemSecs = TY_DURATION; /* Called when isTypingGame overlay opens */ function tyInit() { _tyPassage = tyPickPassage(); _tyStarted = false; _tyFinished = false; _tyStartTime = 0; _tyRemSecs = TY_DURATION; clearInterval(_tyTimerInt); /* Reset UI */ var wEl=document.getElementById('tyOvWPM'); if(wEl) wEl.textContent='0'; var aEl=document.getElementById('tyOvAcc'); if(aEl) aEl.textContent='—'; var tEl=document.getElementById('tyOvTimer'); if(tEl){tEl.textContent=TY_DURATION;tEl.style.color='#D4A017';} var bEl=document.getElementById('tyOvBar'); if(bEl) bEl.style.width='0%'; var rEl=document.getElementById('tyOvRank'); if(rEl){rEl.style.display='none';rEl.innerHTML='';} var grEl=document.getElementById('tyGlobalRank'); if(grEl){grEl.className='rank-box';grEl.innerHTML='';} var inp=document.getElementById('tyOvInput'); if(inp){inp.value='';inp.disabled=false;inp.style.borderColor='rgba(255,255,255,.15)';} var startBtn=document.getElementById('tyOvStartBtn'); if(startBtn) startBtn.style.display=''; tyRenderPassage(''); tyLbLoad(); /* Wire up textarea immediately so it\'s ready — timer only starts on first keystroke */ setTimeout(function() { var inp = document.getElementById('tyOvInput'); if (!inp) return; inp.disabled = false; /* Block copy-paste and all clipboard shortcuts */ ['copy','cut','paste','contextmenu'].forEach(function(ev) { inp.addEventListener(ev, function(e){ e.preventDefault(); e.stopPropagation(); return false; }); }); inp.addEventListener('keydown', function(e) { if ((e.ctrlKey||e.metaKey) && 'vcxa'.indexOf(e.key.toLowerCase()) !== -1) { e.preventDefault(); e.stopPropagation(); return false; } }); inp.addEventListener('input', tyHandleInput); }, 150); } function tyRenderPassage(typed) { var el = document.getElementById('tyOvPassage'); if (!el) return; // Split into word/space tokens so words never break mid-character var tokens = _tyPassage.split(/(\s+)/); var html = ''; var gi = 0; // global char index for (var t = 0; t < tokens.length; t++) { var token = tokens[t]; if (!token) continue; if (/^\s+$/.test(token)) { // Spaces: render individually, allow line-break opportunity here for (var s = 0; s < token.length; s++) { var si = gi + s; if (si < typed.length) { var sok = typed[si] === _tyPassage[si]; html += ' '; } else if (si === typed.length) { html += ' '; } else { html += ' '; } } gi += token.length; } else { // Word: wrap in inline-block so it never splits across lines var wordHtml = ''; for (var c = 0; c < token.length; c++) { var ci = gi + c; var ch = token[c]; if (ci < typed.length) { var ok = typed[ci] === _tyPassage[ci]; wordHtml += '' + ch + ''; } else if (ci === typed.length) { wordHtml += '' + ch + ''; } else { wordHtml += '' + ch + ''; } } html += '' + wordHtml + ''; gi += token.length; } } el.innerHTML = html; } function tyStart() { var startBtn = document.getElementById('tyOvStartBtn'); if (startBtn) startBtn.style.display = 'none'; var inp = document.getElementById('tyOvInput'); if (inp) { inp.disabled = false; inp.focus(); } speak('Go! Type the passage as fast and accurately as you can. Timer starts on your first keystroke.'); } function tyHandleInput() { if (_tyFinished) return; var inp = document.getElementById('tyOvInput'); if (!inp) return; var typed = inp.value; if (!_tyStarted && typed.length > 0) { _tyStarted = true; _tyStartTime = Date.now(); _tyTimerInt = setInterval(function(){ if (!document.getElementById('tyOvTimer')) { clearInterval(_tyTimerInt); return; } /* FIX: always read the CURRENT textarea value — never use the stale closure */ var currentInp = document.getElementById('tyOvInput'); var currentTyped = currentInp ? currentInp.value : ''; var elapsed = (Date.now() - _tyStartTime) / 1000; _tyRemSecs = Math.max(0, TY_DURATION - elapsed); var pct = (elapsed / TY_DURATION) * 100; var tEl = document.getElementById('tyOvTimer'); var bEl = document.getElementById('tyOvBar'); if (tEl) { tEl.textContent = Math.ceil(_tyRemSecs); tEl.style.color = _tyRemSecs < 8 ? '#F87171' : '#D4A017'; } if (bEl) bEl.style.width = pct + '%'; /* Count words from live current value */ var words = currentTyped.trim().split(/\s+/).filter(function(w){ return w; }).length; var liveWPM = elapsed > 0.5 ? Math.round((words / elapsed) * 60) : 0; var wEl = document.getElementById('tyOvWPM'); if(wEl) wEl.textContent = liveWPM; if (_tyRemSecs <= 0) { clearInterval(_tyTimerInt); tyFinish(currentTyped); } }, 250); } if (!_tyStarted) return; tyRenderPassage(typed); var correct=0; for(var i=0;i0 ? Math.round((correct/typed.length)*100) : 0; var aEl=document.getElementById('tyOvAcc'); if(aEl) aEl.textContent=acc+'%'; /* Also auto-finish when passage fully typed */ if (typed.length >= _tyPassage.length && _tyStarted) { clearInterval(_tyTimerInt); setTimeout(function(){ tyFinish(typed); }, 300); } } function tyFinish(typed) { if (_tyFinished) return; _tyFinished = true; var inp = document.getElementById('tyOvInput'); if(inp) inp.disabled = true; var elapsed = Math.max(1, (Date.now()-_tyStartTime)/1000); var words = typed.trim().split(/\s+/).filter(function(w){ return w; }).length; var wpm = Math.round((words/elapsed)*60); var correct=0; for(var i=0;i0 ? Math.round((correct/typed.length)*100) : 0; if (wpm > tyGetPB()) tySetPB(wpm); var rating = wpm>=65?'Lightning fast!':wpm>=50?'Excellent speed!':wpm>=35?'Good pace!':'Keep practising!'; var scoreHTML = '
'+wpm+'WPM
' + '
'+acc+'%ACCURACY
' + '
'+rating+'RATING
'; saveScore('brain', Math.min(100, Math.round(wpm * (acc/100) / 0.7))); checkAchievements('typing', wpm); speak(wpm + ' words per minute at ' + acc + ' percent accuracy. ' + rating); _lastChallengeScore = wpm; _lastChallengeName = 'WPM typing speed'; _lastChallengeExId = 'typing-speed'; // FIX: Do NOT pre-save as Anonymous. _showDone calls _resetAllRankBoxes which wipes // tyGlobalRank before the async POST resolves. Rank is shown correctly AFTER the // user submits or skips in tyShowNameModal (tySaveScore -> _showAnimatedRank). setTimeout(function(){ _showDone(scoreHTML); tyShowNameModal(wpm, acc); }, 600); } /* ── BOOST GRID — product cross-links per exercise goal ── */ (function(){ var BOOSTS = [ {icon:'🧠',goal:'Brain & Memory',text:'Pair brain exercises with Brain Champ — Brahmi, Shankhpushpi & Ashwagandha to support focus and recall.',name:'Brain Champ',price:'₹175',url:'brain-champ-ayurvedic-memory-booster.html',wa:'Hi Shah Hayaat! I want to order Brain Champ (₹175). Please guide me.'}, {icon:'🌬️',goal:'Breathing & Stress',text:'Support pranayama with Fevodol — Giloy & Tulsi to strengthen respiratory immunity.',name:'Fevodol',price:'₹165',url:'fevodol-ayurvedic-immunity-booster-giloy-tulsi.html',wa:'Hi Shah Hayaat! I want to order Fevodol (₹165). Please guide me.'}, {icon:'🍃',goal:'Digestion',text:'Enhance digestive exercises with Shah Zyme — herbal enzymes for gas, bloating and absorption.',name:'Shah Zyme',price:'₹165',url:'shah-zyme-ayurvedic-digestive-syrup.html',wa:'Hi Shah Hayaat! I want to order Shah Zyme (₹165). Please guide me.'}, {icon:'🦴',goal:'Joint & Body',text:'Pair mobility exercises with Ortho Hayaat — Shallaki & Guggul to reduce inflammation.',name:'Ortho Hayaat',price:'₹649',url:'ortho-hayaat-ayurvedic-joint-pain-relief.html',wa:'Hi Shah Hayaat! I want to order Ortho Hayaat (₹649). Please guide me.'}, {icon:'👁️',goal:'Eye Care',text:'Support eye yoga with Brain Champ — antioxidant herbs that help protect vision and reduce eye fatigue.',name:'Brain Champ',price:'₹175',url:'brain-champ-ayurvedic-memory-booster.html',wa:'Hi Shah Hayaat! I want to order Brain Champ (₹175). Please guide me.'}, {icon:'⚡',goal:'Energy & Wake-Up',text:'Fuel morning routines with Blood Storm — iron and Ashwagandha to combat fatigue and boost vitality.',name:'Blood Storm',price:'₹165',url:'blood-storm-ayurvedic-iron-tonic.html',wa:'Hi Shah Hayaat! I want to order Blood Storm (₹165). Please guide me.'} ]; var grid = document.getElementById('boostGrid'); if (!grid) return; grid.innerHTML = BOOSTS.map(function(b){ return '
' + '
'+b.icon+''+b.goal+'
' + '

'+b.text+'

' + '
' + ''+b.price+'' + '
' + 'Details' + 'Order' + '
' + '
' + '
'; }).join(''); function encodeURIComponent_safe(s){ try{ return encodeURIComponent(s); }catch(e){ return s; } } })(); /* ═══════════════════════════════════════════════════════════ SOUND ENGINE — Web Audio API, no files needed ═══════════════════════════════════════════════════════════ */ var _soundEnabled = true; var _audioCtx = null; function _getAudioCtx() { if (!_audioCtx) { try { _audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } catch(e) {} } return _audioCtx; } function _playTone(freq, type, duration, vol, startDelay) { if (!_soundEnabled) return; try { var ctx = _getAudioCtx(); if (!ctx) return; var osc = ctx.createOscillator(); var gain = ctx.createGain(); osc.connect(gain); gain.connect(ctx.destination); osc.type = type || 'sine'; osc.frequency.value = freq; var t = ctx.currentTime + (startDelay || 0); gain.gain.setValueAtTime(vol || 0.18, t); gain.gain.exponentialRampToValueAtTime(0.001, t + duration); osc.start(t); osc.stop(t + duration); } catch(e) {} } function soundTap() { _playTone(880, 'sine', 0.04, 0.12); } function soundCorrect() { _playTone(660, 'sine', 0.12, 0.18); _playTone(880, 'sine', 0.12, 0.18, 0.1); } function soundWrong() { _playTone(220, 'sawtooth', 0.15, 0.2); } function soundMatch() { _playTone(523, 'sine', 0.1, 0.2); _playTone(659, 'sine', 0.1, 0.2, 0.1); _playTone(784, 'sine', 0.12, 0.22, 0.2); } function soundGameEnd() { [523,659,784,1047].forEach(function(f,i){ _playTone(f,'sine',0.2,0.2,i*0.12); }); } function soundPB() { [784,988,1175,1568].forEach(function(f,i){ _playTone(f,'triangle',0.25,0.25,i*0.1); }); } function soundCountdown(n) { _playTone(n <= 3 ? 660 : 440, 'square', 0.08, 0.15); } function soundRankReveal(rank) { if (rank <= 3) { [523,659,784,1047,1319].forEach(function(f,i){ _playTone(f,'sine',0.3,0.25,i*0.09); }); } else if (rank <= 10) { [523,659,784].forEach(function(f,i){ _playTone(f,'sine',0.2,0.2,i*0.1); }); } else { _playTone(440,'sine',0.2,0.18); } } function toggleSound() { _soundEnabled = !_soundEnabled; var btn = document.getElementById('soundToggleBtn'); if (btn) { btn.textContent = _soundEnabled ? '🔊' : '🔇'; btn.classList.toggle('muted', !_soundEnabled); } try { localStorage.setItem('sh_sound', _soundEnabled ? '1' : '0'); } catch(e) {} } function _initSound() { try { _soundEnabled = localStorage.getItem('sh_sound') !== '0'; } catch(e) {} var btn = document.getElementById('soundToggleBtn'); if (btn) { btn.textContent = _soundEnabled ? '🔊' : '🔇'; btn.classList.toggle('muted', !_soundEnabled); } } /* ═══════════════════════════════════════════════════════════ PERSONAL BEST CONFETTI BURST ═══════════════════════════════════════════════════════════ */ function showPBBurst(label) { soundPB(); var el = document.getElementById('pbBurst'); if (!el) return; var colors = ['#FFD700','#FF6B6B','#4ADE80','#60A5FA','#F472B6','#FBBF24','#A78BFA']; var particles = ''; for (var i = 0; i < 18; i++) { var x = 10 + Math.random() * 80; var y = 10 + Math.random() * 80; var size = 6 + Math.random() * 10; var color = colors[i % colors.length]; var delay = (Math.random() * 0.4).toFixed(2); particles += '
'; } el.innerHTML = '
🏆 New Personal Best!
' + (label||'') + '
' + particles; el.classList.add('show'); setTimeout(function() { el.classList.remove('show'); el.innerHTML = ''; }, 1800); } /* ═══════════════════════════════════════════════════════════ NEAR-RANK NUDGE — show if rank 11-20 or just outside top X ═══════════════════════════════════════════════════════════ */ function _showNearRankNudge(rank) { var el = document.getElementById('nearRankNudge'); if (!el) return; var msg = ''; if (rank >= 11 && rank <= 15) msg = '🔥 So close! Just ' + (rank-10) + ' spot' + (rank-10>1?'s':'') + ' away from Top 10!'; else if (rank >= 16 && rank <= 20) msg = '💪 You are in Top 20 — keep pushing!'; else if (rank >= 4 && rank <= 5) msg = '⭐ Just ' + (rank-3) + ' step' + (rank-3>1?'s':'') + ' from the podium!'; else if (rank === 101) msg = '😤 Just missed Top 100 — one more try!'; else if (rank >= 96 && rank <= 100) msg = '🎯 You are in Top 100 — almost Top 50!'; if (msg) { el.textContent = msg; el.classList.add('show'); } else { el.classList.remove('show'); } } /* ═══════════════════════════════════════════════════════════ WHATSAPP RANK SHARE ═══════════════════════════════════════════════════════════ */ var _lastRevealedRank = 0; var _lastRevealedGame = ''; function shareRankOnWhatsApp() { if (!_lastRevealedRank) return; var medal = _lastRevealedRank===1?'🥇':_lastRevealedRank===2?'🥈':_lastRevealedRank===3?'🥉':'🏅'; var gameTitle = _ex ? _ex.title : (_lastRevealedGame || 'Shah Hayaat'); var msg = medal + ' I just ranked #' + _lastRevealedRank + ' globally in "' + gameTitle + '" on Shah Hayaat Wellness Clinic!\n\n' + '🧠 Free brain training & wellness exercises — no login, no cost.\n' + '👉 https://www.shahhayaat.com/exercises.html\n\nCan you beat my rank? 💪'; window.open('https://wa.me/?text=' + encodeURIComponent(msg), '_blank'); } /* ═══════════════════════════════════════════════════════════ STREAK BONUS MULTIPLIER ═══════════════════════════════════════════════════════════ */ function _getStreakBonus() { try { var data = JSON.parse(localStorage.getItem('sh_wellness') || '{}'); var streak = data.streak || 0; if (streak >= 7) return { mult: 1.5, label: '🔥 7-day streak bonus: ×1.5!' }; if (streak >= 3) return { mult: 1.2, label: '🔥 3-day streak bonus: ×1.2!' }; return { mult: 1, label: '' }; } catch(e) { return { mult: 1, label: '' }; } } /* ═══════════════════════════════════════════════════════════ DAILY CHALLENGE — seeded by date so everyone gets same game ═══════════════════════════════════════════════════════════ */ var _dcGames = ['reaction-test','math-challenge','memory-match','number-sequence']; function _getDailyChallengeGame() { var today = new Date(); var seed = today.getFullYear() * 10000 + (today.getMonth()+1) * 100 + today.getDate(); return _dcGames[seed % _dcGames.length]; } function _getDailyChallengeKey() { var today = new Date(); return 'sh_dc_' + today.getFullYear() + '_' + (today.getMonth()+1) + '_' + today.getDate(); } function _hasDoneDailyChallenge() { try { return !!localStorage.getItem(_getDailyChallengeKey()); } catch(e) { return false; } } function _markDailyChallengeDone(score) { try { if (!localStorage.getItem(_getDailyChallengeKey())) { checkAchievements('daily', 1); } localStorage.setItem(_getDailyChallengeKey(), String(score)); } catch(e) {} } function startDailyChallenge() { var gameId = _getDailyChallengeGame(); var banner = document.getElementById('dailyChallengeBanner'); if (banner) banner.style.display = 'none'; openExercise(gameId); } function _showDailyChallengeOnDone() { var banner = document.getElementById('dailyChallengeBanner'); var desc = document.getElementById('dcBannerDesc'); if (!banner || !desc) return; var gameId = _getDailyChallengeGame(); var ex = EXERCISES.find(function(e){ return e.id === gameId; }); var done = _hasDoneDailyChallenge(); if (done) { banner.style.display = 'none'; return; } desc.textContent = "Today\'s challenge: " + (ex ? ex.title : gameId) + " — play now to earn your daily badge!"; banner.style.display = 'block'; } /* ═══════════════════════════════════════════════════════════ PERSONAL STATS PANEL ═══════════════════════════════════════════════════════════ */ function openStatsPanel() { var panel = document.getElementById('statsPanel'); if (!panel) return; _renderStatsPanel(); panel.classList.add('show'); } function closeStatsPanel() { var panel = document.getElementById('statsPanel'); if (panel) panel.classList.remove('show'); } function _renderStatsPanel() { try { var data = JSON.parse(localStorage.getItem('sh_wellness') || '{}'); var pb = data.pb || {}; var streak = data.streak || 0; var best = data.bestStreak || 0; // Stats grid var grid = document.getElementById('statsGrid'); if (grid) { var items = [ { icon:'⚡', val: pb.reaction ? pb.reaction + ' ms' : '—', lbl:'Best Reaction' }, { icon:'🧠', val: pb.math ? pb.math + ' correct' : '—', lbl:'Best Math' }, { icon:'🃏', val: pb.memory ? pb.memory + ' attempts' : '—', lbl:'Best Memory' }, { icon:'⌨️', val: pb.typing ? pb.typing + ' WPM' : '—', lbl:'Best Typing' }, { icon:'🔢', val: pb.sequence ? pb.sequence + 's' : '—', lbl:'Best Sequence' }, { icon:'🔥', val: streak + ' days', lbl:'Current Streak' }, { icon:'🏆', val: best + ' days', lbl:'Best Streak' }, { icon:'📅', val: data.lastActive ? data.lastActive.split(' ').slice(1,3).join(' ') : '—', lbl:'Last Active' } ]; grid.innerHTML = items.map(function(it) { return '
' + it.icon + '
' + '
' + it.val + '
' + '
' + it.lbl + '
'; }).join(''); } // Streak display var streakEl = document.getElementById('statsStreak'); if (streakEl) { var bonus = _getStreakBonus(); streakEl.innerHTML = '
🔥
' + '
' + streak + ' days
' + '
Best: ' + best + ' days
' + (bonus.label ? '
' + bonus.label + '
' : ''); } // Rank board — pull from localStorage cache var ranksEl = document.getElementById('statsRanks'); if (ranksEl) { var ranks = []; try { ranks = JSON.parse(localStorage.getItem('sh_my_ranks') || '[]'); } catch(e) {} if (!ranks.length) { ranksEl.innerHTML = '
Play games to see your global ranks here
'; } else { ranksEl.innerHTML = ranks.map(function(r) { var medal = r.rank===1?'🥇':r.rank===2?'🥈':r.rank===3?'🥉':'#'+r.rank; return '
' + r.game + '' + '' + medal + ' Rank ' + r.rank + '
'; }).join(''); } } } catch(e) {} } function _saveMyRank(gameTitle, rank) { try { var ranks = JSON.parse(localStorage.getItem('sh_my_ranks') || '[]'); // Update or insert var idx = ranks.findIndex(function(r){ return r.game === gameTitle; }); var entry = { game: gameTitle, rank: rank, date: new Date().toDateString() }; if (idx >= 0) ranks[idx] = entry; else ranks.unshift(entry); ranks = ranks.slice(0, 10); // keep last 10 games localStorage.setItem('sh_my_ranks', JSON.stringify(ranks)); } catch(e) {} } /* ═══════════════════════════════════════════════════════════ WEEKLY LEADERBOARD — stored in GAS with date prefix (lightweight: just tags each score with the week number) ═══════════════════════════════════════════════════════════ */ function _getWeekKey() { var d = new Date(); var jan1 = new Date(d.getFullYear(), 0, 1); var week = Math.ceil((((d - jan1) / 86400000) + jan1.getDay() + 1) / 7); return d.getFullYear() + 'W' + week; } /* ═══════════════════════════════════════════════════════════════ SPEED READING GAME ═══════════════════════════════════════════════════════════════ */ /* ═══════════════════════════════════════════════════════════════ LEADERBOARD TABS — Global / This Week / India ═══════════════════════════════════════════════════════════════ */ var _lbCurrentTab = 'global'; var _lbAllRows = []; // cache of all rows from last fetch function lbSetTab(tab) { _lbCurrentTab = tab; ['global','weekly'].forEach(function(t) { var btn = document.getElementById('lbTab' + t.charAt(0).toUpperCase() + t.slice(1)); if (btn) btn.classList.toggle('active', t === tab); }); lbRenderFiltered(_lbAllRows); } function lbRenderFiltered(rows) { _lbAllRows = rows || _lbAllRows; var tab = _lbCurrentTab; var clean = (_lbAllRows || []).filter(function(r) { return !String(r.name||'').startsWith('__auto__') && r.wpm === undefined; }); if (tab === 'weekly') { var weekScores = _lbGetWeeklyScores(); if (weekScores.length) { lbRenderRows(weekScores, true); } else { var list = document.getElementById('lbList'); if (list) list.innerHTML = '
No scores this week yet — play to be first! 🏆
'; } return; } // Overall (default) lbRenderRows(clean.slice(0, 500), false); } function lbRenderRows(rows, isWeekly) { var list = document.getElementById('lbList'); var myRankEl = document.getElementById('lbMyRank'); if (!list) return; if (!rows.length) { list.innerHTML = '
' + (isWeekly ? 'No scores this week yet!' : 'No scores yet — be first! 🏆') + '
'; return; } list.innerHTML = rows.map(function(r, i) { var pos = i + 1; var rankCls = pos === 1 ? 'top1' : pos === 2 ? 'top2' : pos === 3 ? 'top3' : ''; var isMe = _lbMyRank && pos === _lbMyRank; var displayVal = r.score !== undefined ? r.score : r.taps; var displayLbl = r.score !== undefined ? 'pts' : 'taps'; return '
' + '' + (pos <= 3 ? ['🥇','🥈','🥉'][pos-1] : '#'+pos) + '' + '' + _esc(r.name) + '' + '' + displayVal + ' ' + displayLbl + '' + '
'; }).join('') + '
Showing ' + rows.length + ' entries' + (isWeekly ? ' this week' : '') + '
'; if (_lbMyRank && myRankEl) { myRankEl.textContent = 'Your rank: #' + _lbMyRank; myRankEl.style.display = ''; } } // Weekly scores stored locally (scores submitted this week) var _WEEKLY_KEY = 'sh_weekly_scores'; function _lbSaveWeeklyScore(taps, score, name) { try { var week = _getWeekKey(); var data = JSON.parse(localStorage.getItem(_WEEKLY_KEY) || '{}'); if (!data[week]) data[week] = []; data[week].push({ name: name || 'You', score: score, taps: taps, ts: Date.now() }); // Keep only last 2 weeks var keys = Object.keys(data).sort(); while (keys.length > 2) { delete data[keys.shift()]; keys = Object.keys(data).sort(); } localStorage.setItem(_WEEKLY_KEY, JSON.stringify(data)); } catch(e) {} } function _lbGetWeeklyScores() { try { var week = _getWeekKey(); var data = JSON.parse(localStorage.getItem(_WEEKLY_KEY) || '{}'); return (data[week] || []).sort(function(a,b){ return b.score - a.score; }); } catch(e) { return []; } } /* ═══════════════════════════════════════════════════════════════ ACHIEVEMENT SYSTEM ═══════════════════════════════════════════════════════════════ */ const ACH_KEY = 'sh_achievements'; const ACHIEVEMENTS = [ // Reaction { id:'tap_50', icon:'⚡', name:'Quick Fingers', desc:'Score 50+ taps in Reaction Test', cat:'reaction' }, { id:'tap_80', icon:'🔥', name:'Speed Demon', desc:'Score 80+ taps in Reaction Test', cat:'reaction' }, { id:'tap_100', icon:'💥', name:'Century Club', desc:'Score 100+ taps in Reaction Test', cat:'reaction' }, { id:'tap_120', icon:'🚀', name:'Superhuman', desc:'Score 120+ taps in Reaction Test', cat:'reaction' }, // Math { id:'math_20', icon:'🧮', name:'Number Cruncher', desc:'Answer 20+ correct in Math Challenge', cat:'math' }, { id:'math_40', icon:'📐', name:'Math Wizard', desc:'Answer 40+ correct in Math Challenge', cat:'math' }, { id:'math_60', icon:'🎓', name:'Einstein Mode', desc:'Answer 60+ correct in Math Challenge', cat:'math' }, // Memory { id:'mem_8', icon:'🃏', name:'Perfect Memory', desc:'Match all pairs in exactly 8 attempts', cat:'memory' }, { id:'mem_12', icon:'🧠', name:'Sharp Mind', desc:'Match all pairs in 12 or fewer attempts',cat:'memory' }, // Typing { id:'type_40', icon:'⌨️', name:'Typist', desc:'Type 40+ WPM in Typing Speed Test', cat:'typing' }, { id:'type_60', icon:'💨', name:'Speed Typist', desc:'Type 60+ WPM in Typing Speed Test', cat:'typing' }, { id:'type_80', icon:'🏎️', name:'Keyboard Racer', desc:'Type 80+ WPM in Typing Speed Test', cat:'typing' }, // Streak { id:'streak_3', icon:'🔥', name:'On Fire', desc:'Maintain a 3-day wellness streak', cat:'streak' }, { id:'streak_7', icon:'🌟', name:'Week Warrior', desc:'Maintain a 7-day wellness streak', cat:'streak' }, { id:'streak_30', icon:'💎', name:'Diamond Habit', desc:'Maintain a 30-day wellness streak', cat:'streak' }, // Rank { id:'rank_top10', icon:'🏆', name:'Elite', desc:'Reach Top 10 on any global leaderboard', cat:'rank' }, { id:'rank_top3', icon:'🥇', name:'Podium Finisher', desc:'Reach Top 3 on any global leaderboard', cat:'rank' }, // General { id:'first_game', icon:'🌱', name:'First Step', desc:'Complete your first brain game', cat:'general' }, { id:'all_games', icon:'🎯', name:'All-Rounder', desc:'Play all 5 brain games at least once', cat:'general' }, { id:'daily_done', icon:'🗓️', name:'Daily Champion', desc:'Complete the Daily Challenge', cat:'general' }, { id:'pb_beat', icon:'⭐', name:'Personal Best', desc:'Beat your own personal best in any game', cat:'general' }, ]; function _loadAchievements() { try { return JSON.parse(localStorage.getItem(ACH_KEY) || '{}'); } catch(e) { return {}; } } function _saveAchievements(data) { try { localStorage.setItem(ACH_KEY, JSON.stringify(data)); } catch(e) {} } function _unlockAchievement(id) { var data = _loadAchievements(); if (data[id]) return false; // already unlocked data[id] = { date: new Date().toDateString(), ts: Date.now() }; _saveAchievements(data); return true; } function _checkAndUnlock(id) { if (_unlockAchievement(id)) { var ach = ACHIEVEMENTS.find(function(a){ return a.id === id; }); if (ach) _showAchievementToast(ach); _updateAchieveBtnLabel(); return true; } return false; } function _showAchievementToast(ach) { var toast = document.getElementById('achToast'); var icon = document.getElementById('achToastIcon'); var name = document.getElementById('achToastName'); var desc = document.getElementById('achToastDesc'); if (!toast) return; if (icon) icon.textContent = ach.icon; if (name) name.textContent = ach.name; if (desc) desc.textContent = ach.desc; soundPB(); toast.classList.add('show'); setTimeout(function() { toast.classList.remove('show'); }, 3500); } function _updateAchieveBtnLabel() { var data = _loadAchievements(); var count = Object.keys(data).length; var total = ACHIEVEMENTS.length; var btn = document.getElementById('ovAchieveBtn'); var lbl = document.getElementById('ovAchieveBtnLbl'); if (btn) btn.classList.add('show'); if (lbl) lbl.textContent = 'Achievements (' + count + '/' + total + ')'; } function openAchievements() { var panel = document.getElementById('achievementPanel'); if (!panel) return; _renderAchievements(); panel.classList.add('show'); } function closeAchievements() { var panel = document.getElementById('achievementPanel'); if (panel) panel.classList.remove('show'); } function _renderAchievements() { var data = _loadAchievements(); var total = ACHIEVEMENTS.length; var count = Object.keys(data).length; var countEl = document.getElementById('achCount'); var grid = document.getElementById('achGrid'); if (countEl) countEl.textContent = count + ' / ' + total + ' unlocked'; if (!grid) return; // Sort: unlocked first, then locked var sorted = ACHIEVEMENTS.slice().sort(function(a, b) { var ua = !!data[a.id], ub = !!data[b.id]; if (ua && !ub) return -1; if (!ua && ub) return 1; return 0; }); grid.innerHTML = sorted.map(function(ach) { var unlocked = !!data[ach.id]; var dateStr = unlocked ? data[ach.id].date || '' : ''; return '
' + '
' + ach.icon + '
' + '
' + '
' + ach.name + '
' + '
' + (unlocked ? ach.desc : '???') + '
' + (unlocked && dateStr ? '
Earned ' + dateStr + '
' : '') + (!unlocked ? '
' : '') + '
' + '
'; }).join(''); } /* Called after each game to check achievements */ function checkAchievements(type, value) { var data = JSON.parse(localStorage.getItem('sh_wellness') || '{}'); var pb = data.pb || {}; if (type === 'reaction') { if (value >= 50) _checkAndUnlock('tap_50'); if (value >= 80) _checkAndUnlock('tap_80'); if (value >= 100) _checkAndUnlock('tap_100'); if (value >= 120) _checkAndUnlock('tap_120'); _checkAndUnlock('first_game'); _checkGamesPlayed(); } if (type === 'math') { if (value >= 20) _checkAndUnlock('math_20'); if (value >= 40) _checkAndUnlock('math_40'); if (value >= 60) _checkAndUnlock('math_60'); _checkAndUnlock('first_game'); _checkGamesPlayed(); } if (type === 'memory') { if (value <= 8) _checkAndUnlock('mem_8'); if (value <= 12) _checkAndUnlock('mem_12'); _checkAndUnlock('first_game'); _checkGamesPlayed(); } if (type === 'typing') { if (value >= 40) _checkAndUnlock('type_40'); if (value >= 60) _checkAndUnlock('type_60'); if (value >= 80) _checkAndUnlock('type_80'); _checkAndUnlock('first_game'); _checkGamesPlayed(); } if (type === 'rank') { if (value <= 10) _checkAndUnlock('rank_top10'); if (value <= 3) _checkAndUnlock('rank_top3'); } if (type === 'streak') { if (value >= 3) _checkAndUnlock('streak_3'); if (value >= 7) _checkAndUnlock('streak_7'); if (value >= 30) _checkAndUnlock('streak_30'); } if (type === 'pb') _checkAndUnlock('pb_beat'); if (type === 'daily') _checkAndUnlock('daily_done'); _updateAchieveBtnLabel(); } function _checkGamesPlayed() { try { var played = JSON.parse(localStorage.getItem('sh_games_played') || '{}'); if (_ex) played[_ex.cat === 'brain' ? _ex.id : ''] = true; var brainGames = ['reaction-test','math-challenge','memory-match','number-sequence','typing-speed']; var allPlayed = brainGames.every(function(id) { return !!played[id]; }); if (allPlayed) _checkAndUnlock('all_games'); localStorage.setItem('sh_games_played', JSON.stringify(played)); } catch(e) {} } /* ═══════════════════════════════════════════════════════════════ SHARE CARD — Canvas-generated shareable image ═══════════════════════════════════════════════════════════════ */ var _shareCardDataUrl = ''; function openShareCard() { var overlay = document.getElementById('shareCardOverlay'); if (!overlay) return; _generateShareCard(); overlay.classList.add('show'); } function closeShareCard() { var overlay = document.getElementById('shareCardOverlay'); if (overlay) overlay.classList.remove('show'); } function _generateShareCard() { var canvas = document.getElementById('shareCardCanvas'); if (!canvas) return; var ctx = canvas.getContext('2d'); var W = 640, H = 360; canvas.width = W; canvas.height = H; // Background gradient var bg = ctx.createLinearGradient(0, 0, W, H); bg.addColorStop(0, '#071830'); bg.addColorStop(0.5, '#0a1f3c'); bg.addColorStop(1, '#0e2448'); ctx.fillStyle = bg; ctx.fillRect(0, 0, W, H); // Gold border ctx.strokeStyle = 'rgba(212,160,23,0.6)'; ctx.lineWidth = 2.5; _roundRect(ctx, 4, 4, W-8, H-8, 20); ctx.stroke(); // Subtle inner glow var glow = ctx.createRadialGradient(W/2, H/2, 0, W/2, H/2, W*0.7); glow.addColorStop(0, 'rgba(184,134,11,0.06)'); glow.addColorStop(1, 'rgba(184,134,11,0)'); ctx.fillStyle = glow; ctx.fillRect(0, 0, W, H); // Game info var gameTitle = _ex ? _ex.title : 'Brain Training'; var rank = _lastRevealedRank || 0; var medal = rank === 1 ? '🥇' : rank === 2 ? '🥈' : rank === 3 ? '🥉' : rank <= 10 ? '🏅' : '#' + rank; // Shah Hayaat logo text (top left) ctx.fillStyle = 'rgba(212,160,23,0.85)'; ctx.font = 'bold 18px serif'; ctx.fillText('🌿 Shah Hayaat', 32, 44); ctx.fillStyle = 'rgba(255,255,255,0.35)'; ctx.font = '13px sans-serif'; ctx.fillText('Wellness Clinic', 32, 62); // Big rank display (centre) if (rank > 0) { ctx.textAlign = 'center'; // Medal emoji ctx.font = '72px serif'; ctx.fillText(rank <= 3 ? (rank===1?'🥇':rank===2?'🥈':'🥉') : '🏅', W/2, H/2 - 20); // Rank number ctx.fillStyle = rank <= 3 ? '#FFD700' : rank <= 10 ? '#D4A017' : '#22C55E'; ctx.font = 'bold 52px sans-serif'; ctx.fillText('Rank #' + rank, W/2, H/2 + 50); // Game name ctx.fillStyle = 'rgba(255,255,255,0.65)'; ctx.font = '18px sans-serif'; ctx.fillText(gameTitle, W/2, H/2 + 78); // Score pills (if available) var scoreText = _lastChallengeScore > 0 ? _lastChallengeScore + ' ' + (_lastChallengeName || 'points') : ''; if (scoreText) { ctx.fillStyle = 'rgba(212,160,23,0.7)'; ctx.font = '15px sans-serif'; ctx.fillText(scoreText, W/2, H/2 + 102); } } else { // No rank — show wellness card ctx.textAlign = 'center'; ctx.font = '54px serif'; ctx.fillText('🧠', W/2, H/2 - 10); ctx.fillStyle = '#fff'; ctx.font = 'bold 28px sans-serif'; ctx.fillText('Brain Training Complete!', W/2, H/2 + 40); ctx.fillStyle = 'rgba(255,255,255,0.5)'; ctx.font = '17px sans-serif'; ctx.fillText(_ex ? _ex.title : 'Wellness Exercise', W/2, H/2 + 68); } // Achievements unlocked count (bottom left) var achData = _loadAchievements(); var achCount = Object.keys(achData).length; if (achCount > 0) { ctx.textAlign = 'left'; ctx.fillStyle = 'rgba(212,160,23,0.6)'; ctx.font = '13px sans-serif'; ctx.fillText('🏅 ' + achCount + '/' + ACHIEVEMENTS.length + ' achievements', 32, H - 36); } // Streak (bottom left below achievements) try { var wdata = JSON.parse(localStorage.getItem('sh_wellness') || '{}'); var streak = wdata.streak || 0; if (streak > 1) { ctx.fillStyle = 'rgba(255,140,0,0.75)'; ctx.font = '13px sans-serif'; ctx.fillText('🔥 ' + streak + '-day streak', 32, H - 18); } } catch(e) {} // Website URL (bottom right) ctx.textAlign = 'right'; ctx.fillStyle = 'rgba(255,255,255,0.25)'; ctx.font = '12px sans-serif'; ctx.fillText('shahhayaat.com/exercises.html', W - 28, H - 18); ctx.textAlign = 'left'; // reset _shareCardDataUrl = canvas.toDataURL('image/png'); } function _roundRect(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.quadraticCurveTo(x + w, y, x + w, y + r); ctx.lineTo(x + w, y + h - r); ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h); ctx.lineTo(x + r, y + h); ctx.quadraticCurveTo(x, y + h, x, y + h - r); ctx.lineTo(x, y + r); ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); } function shareCardWhatsApp() { closeShareCard(); var medal = _lastRevealedRank > 0 ? ( _lastRevealedRank === 1 ? '🥇' : _lastRevealedRank === 2 ? '🥈' : _lastRevealedRank === 3 ? '🥉' : '🏅' ) : '🧠'; var game = _ex ? _ex.title : 'brain training'; var rankStr = _lastRevealedRank > 0 ? ' I ranked #' + _lastRevealedRank + ' globally!' : ''; var msg = medal + ' Just completed ' + game + ' on Shah Hayaat Wellness Clinic!' + rankStr + '\n\n🌿 Free guided wellness exercises — brain, breathing & body.\n' + '👉 https://www.shahhayaat.com/exercises.html\n\nCan you beat me? 💪'; window.open('https://wa.me/?text=' + encodeURIComponent(msg), '_blank'); } function downloadShareCard() { if (!_shareCardDataUrl) return; var a = document.createElement('a'); a.href = _shareCardDataUrl; a.download = 'shahhayaat-rank.png'; a.click(); } /* ── WHATSAPP SHARE after exercise completion ── */ var _lastCompletedExName = ''; function shareOnWhatsApp() { var streak = 0; try{ streak = parseInt(localStorage.getItem('sh_streak_cur')||'0'); }catch(e){} var msg = '🌿 I just completed "' + (_lastCompletedExName||'a wellness exercise') + '" on Shah Hayaat Wellness Clinic!' + (streak > 1 ? ' 🔥 Day ' + streak + ' streak!' : '') + '\n\nFree guided exercises for brain, breathing & body:\nhttps://www.shahhayaat.com/exercises.html'; window.open('https://wa.me/?text=' + encodeURIComponent(msg), '_blank', 'noopener'); }
🌿
⭐⭐⭐⭐⭐
You\'re doing amazing
could you do us one favour?
Shah Hayaat has been quietly changing lives for generations — but we need your voice to reach the people who need us most.

A 5-star review takes 30 seconds and means the world to our small team. Share what you love — even one honest line makes a huge difference. 🙏
⭐ Leave a 5-Star Review
🏆
You scored taps!
Enter your name to save your score on the global leaderboard, or skip to save as Anonymous.
📊 Your Stats
🏆 Your Global Ranks
🔥 Streak
🏅
Achievement Unlocked!
🏅 Achievements
Loading…