9:41 ●●● 🔋
Clari with Baby and Thor
Clari
Your daily practice for the life
you actually want to be living.
Already have an account? Sign in →
Meet Clari →
Someone you love needs to see this 🌿
Meet Clari
Welcome — Clari with Baby and Thor
Welcome!So glad you're here.
I'm Clari. With my dogs Baby and Thor by my side, I'm here to guide you through 10 gentle minutes every morning that will actually change how you feel.
Created by Dr. Maritsa Yzaguirre-Kelley, a licensed mental health professional. Clari brings clinically-informed, guided AI support to anyone ready to feel better — no experience needed.
Clari
Hi, I am Clari.
Let me set this up just right for you.
How old are you?
Hi, parent or guardian
Setting up your child
You choose what Clari discusses. Weekly mood summaries only — never journal content.
🔒 Content permissions
🔒 Journals are always private. Mood trend summaries only.

I am so glad you found your way here. Baby and Thor too. What is your name?

First — what is your name?
I will use it every single day. This is your space now.

What is pulling at you right now? Pick what feels closest to home.

What brings you here?
Pick everything that resonates.
💕Love & Relationships
🌊Anxiety
🔥Stress & Burnout
🕊️Grief & Loss
🧸Inner Child Work
👑Self-Worth
👨‍👧Parenting
⚖️Divorce & Separation
Anger
🌱Recovery
🧭Life Purpose
💼Career

No judgment here — ever. You are safe to be honest.

Where are you right now?
Pick everything that feels true. No wrong answers here.

Now the good part. Who are you becoming? She is already in there.

Who are you becoming?
She is already in there. Just describe her.

Last one. How do you like to be talked to? I will match you.

How do you like to be supported?
I will show up exactly this way, every day.
Warm and gentle
Direct and honest
Both — warm but real
Like a big sister
Like a coach
Let me lead myself
Good morning ☀️
friend
Streak
0 days
Mood
-/10
Sessions
0
✦ Today
Loading your daily reminder...
— Clari 🌿
Your focus Progress →
Quick tools All tools →
🌬️
Breathe
📓
Journal
💬
Chat
😊
Check-In
📊
Progress
👨‍👧
Family
🛠️
All Tools
Step 1 of 8 · Your Morning Ritual
"
Loading your quote...
— Clari 🌿
Reading of the Day
2 of 8
Today's coaching read
Step 3 of 8 · Presence Process Breathing
Inhale
4
Just breathe.
In for 4 · Hold for 4 · Out for 8
How are you right now?
4 of 8
🌿
Be honest. No wrong answer here. This tells me where to show up for you today.
😊 Mood7
🎯 Focus5
⚡ Energy6
🌊 Stress6
💡 Clarity5
Let us go there
5 of 8
Your journal
6 of 8
No pressure. No perfection. Just what is actually true right now.
What is actually going on underneath everything today?
Tap a prompt if you need a nudge
What am I really afraid of right now?
What do I need that I have not asked for?
What would feel like relief today?
Your one thing today
7 of 8
Based on everything you shared — here is your one thing. Small enough to actually do. Real enough to matter.
🌿
Today's micro action
Clari waving
You showed up
today.
That is everything. Seriously.
🔥
Day 1
keep going
Baby is wiggling. Thor approves. 🐾
Clari
with Baby and Thor · always here
Your Progress
Your Toolkit
12 tools to shift how you feel, right now.

Hi! I am Clari. Baby and Thor are here too. What is your name?

What is your name?
I will use it every single day. This is your space.

Nice to meet you, friend! What do you want help with?

What would you like help with?
Pick everything that feels true.
😢Big Feelings
👯Friend Drama
🏠Family Stuff
📚School Stress
💪Confidence
😰Worry and Anxiety
🍎Healthy Habits
😡Anger

No right or wrong. Just how you really feel.

How are you feeling right now?
Overwhelmed
Worried a lot
Sad sometimes
Left out
Frustrated
Pretty okay
Going through something hard
Wanting to feel happier
Friend,
you are home.
Every day with Clari is a fresh start.
Baby and Thor are already excited.
10 minutes. Every morning. Everything shifts.
Good morning ☀️
friend
Day 1 — let us begin!
Day 1
I am so happy you showed up today! Baby is doing her happy dance. What do you want to do?
Today's adventure See all
🌬️
Bubble Breathing with Baby
Baby needs your help blowing the biggest invisible bubble! Big breath in, hold it, slowly blow it all out. 3 times together!
What do you want to do?
📖
Word of the Day
Courageous
Being brave even when things feel scary. You are courageous every time you try something new!
This week's book
📕
The Invisible String
Love connects us even when we are apart. Great for big feelings about family changes.
🏠
Home
Tasks
😊
Feelings
📚
Books
🌟
My Wins
Good morning
friend
Day 1
Day 1
What you are working on See all
Quick tools All
🌬️
Breathe
📓
Journal
💬
Chat
🎧
Audio
🚫
Say No
💪
Confidence
💡
Word of the Day
Resilience
The ability to bounce back after hard things. You build this every single day you show up.
This week's read
📗
The 7 Habits of Highly Effective Teens
Practical and built for you. Chapter 3 — putting first things first.
🏠
Home
▶️
Today
👨‍👧
Family
📊
Progress
🛠️
Tools
Your Clari Family
Every person gets their own space.
+
Add a family member
Up to 6 profiles on the family plan
Add a family member
Each person gets their own daily flow, journal, and progress. Completely private.
🌿
🌸
🐾
🌊
🦋
🌻
Their journal is always private. You see mood trends only in the Parent Dashboard.
Parent Dashboard
Mood summaries only. Journals always private.
How this works
Ready when you are.
// ══════════════════════════════════════════════════════════ // CLARI — COMPLETE JAVASCRIPT // All strings use single quotes. No apostrophes in strings. // All HTML uses template strings only where safe. // ══════════════════════════════════════════════════════════ // ─── STATE ─────────────────────────────────────────────── var DB = { get: function(k) { try { var v = localStorage.getItem('clari_' + k); return v ? JSON.parse(v) : null; } catch(e) { return null; } }, set: function(k, v) { try { localStorage.setItem('clari_' + k, JSON.stringify(v)); } catch(e) {} } }; var state = DB.get('state') || { name: '', age: 0, isKid: false, tone: 'warm but real', focusAreas: [], currentSelf: [], futureSelf: [], streak: 0, lastSession: null, sessions: [], chatHistory: [], onboardingDone: false, familyProfiles: [] }; function saveState() { DB.set('state', state); } var checkIn = { mood: 7, focus: 5, energy: 6, stress: 6, clarity: 5 }; // ─── CLAUDE API ────────────────────────────────────────── function buildSystem() { return 'You are Clari, a warm direct non-judgmental daily clarity companion. ' + 'You understand EFT, somatic work, NLP, CBT, inner child work, ' + 'A Course in Miracles, and the Presence Process by Michael Brown. ' + 'Tone: warm cozy friend meets trusted coach. Never clinical. Never preachy. ' + 'User: ' + (state.name || 'friend') + ' | Age: ' + state.age + ' | Focus: ' + (state.focusAreas.join(', ') || 'general wellbeing') + ' | Tone: ' + state.tone + ' | Current self: ' + (state.currentSelf.join(', ') || 'working on growth') + ' | Becoming: ' + (state.futureSelf.join(', ') || 'not set') + ' | Today mood: ' + checkIn.mood + '/10' + ', focus: ' + checkIn.focus + '/10' + ', energy: ' + checkIn.energy + '/10' + ', stress: ' + checkIn.stress + '/10' + ', clarity: ' + checkIn.clarity + '/10' + '. Keep responses warm, real, under 150 words unless journaling. ' + 'For any crisis indicators respond immediately with the 988 Suicide and Crisis Lifeline.'; } async function callClaude(messages, maxTokens) { maxTokens = maxTokens || 300; try { var res = await fetch('https://api.tryclari.app', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'claude-sonnet-4-20250514', max_tokens: maxTokens, system: buildSystem(), messages: messages }) }); var data = await res.json(); return (data.content && data.content[0] && data.content[0].text) || ''; } catch(e) { return ''; } // Return empty so callers can use their own fallback } // ─── NAVIGATION ────────────────────────────────────────── function goTo(id) { var cur = document.querySelector('.screen.active'); var nxt = document.getElementById(id); if (!nxt || nxt === cur) return; var lightIds = ['about-clari','s-age','s-parent','ob-a1','ob-a2','ob-a3','ob-a4','ob-a5', 'ob-k1','ob-k2','ob-k3','home','home-kids','home-teen', 'progress','tools','tool-detail','family','add-profile','parent-dash', 'df-2','df-4','df-5','df-6','df-7','chat']; document.getElementById('sb').style.color = (lightIds.indexOf(id) >= 0) ? 'var(--char)' : 'white'; cur.classList.add('exit'); cur.classList.remove('active'); setTimeout(function() { cur.classList.remove('exit'); }, 480); nxt.classList.add('active'); nxt.scrollTop = 0; // Screen init if (id === 'df-1') initFlow(); if (id === 'ob-a3') populateCurrentSelfChips(); if (id === 'ob-a4') populateFutureSelfChips(); if (id === 'df-2') loadReading(); if (id === 'df-5') loadFollowup(); if (id === 'df-7') loadMicroAction(); if (id === 'chat') initChat(); if (id === 'home') refreshHome(); if (id === 'home-kids') refreshKidsHome(); if (id === 'home-teen') refreshTeenHome(); if (id === 'progress') renderProgress(); if (id === 'tools') renderTools(); if (id === 'family') renderFamily(); if (id === 'parent-dash') renderParentDash(); } // ─── SPLASH QUOTES ─────────────────────────────────────── var voices = [ 'Pull up a chair. You do not need to have it all figured out. You just have to show up.', 'You are not broken. You are just carrying things that were never yours to carry alone.', 'What if feeling good was not something you had to earn? What if it was just your normal?', 'No hustle culture. No toxic positivity. Just you, your life, and a daily practice that fits.', '10 minutes every morning. That is all I need to help you come home to yourself.', 'For the parents too. You cannot pour from an empty cup. Let us fill yours first.', 'Every beautiful thing begins with a single moment of presence. This is yours.' ]; var qi = 0; setInterval(function() { qi = (qi + 1) % voices.length; var el = document.getElementById('splashQ'); if (!el || !document.getElementById('splash').classList.contains('active')) return; el.style.opacity = '0'; setTimeout(function() { el.textContent = voices[qi]; el.style.transition = 'opacity .5s'; el.style.opacity = '1'; }, 380); }, 5500); // ─── AGE ───────────────────────────────────────────────── function onAge(v) { state.age = parseInt(v) || 0; var btn = document.getElementById('ageBtn'); var hint = document.getElementById('ageHint'); if (!v || state.age < 1 || state.age > 110) { btn.classList.add('btn-dim'); hint.textContent = ''; return; } btn.classList.remove('btn-dim'); if (state.age <= 8) hint.textContent = 'Clari has something special for little ones.'; else if (state.age <= 12) hint.textContent = 'Ready for you — real topics, the right way.'; else if (state.age <= 17) hint.textContent = 'Your space is ready — real talk, real tools.'; else hint.textContent = 'Welcome home. Everything is set up for you.'; } function routeAge() { if (!state.age || state.age < 1) return; state.isKid = state.age < 18; saveState(); goTo(state.isKid ? 's-parent' : 'ob-a1'); } // ─── ADULT OB ──────────────────────────────────────────── function onAdultName(v) { state.name = v; var sp = document.getElementById('a1sp'); if (sp) sp.textContent = v || 'friend'; var btn = document.getElementById('a1btn'); if (v.trim()) btn.classList.remove('btn-dim'); else btn.classList.add('btn-dim'); } function saveAdultFocus() { state.focusAreas = [].slice.call(document.querySelectorAll('#ob-a2 .fc.on')) .map(function(el) { return el.querySelector('.fc-nm').textContent; }); saveState(); // Populate dynamic chips for steps 3 and 4 populateCurrentSelfChips(); populateFutureSelfChips(); } var currentSelfMap = { 'Love & Relationships': ['Replaying past relationships','Afraid of getting hurt again','Feeling unlovable','In a hard relationship season','Lonely even around people','Giving more than I receive'], 'Anxiety': ['Anxious most of the day','Mind racing constantly','Avoiding things out of fear','Physical anxiety symptoms','Catastrophizing everything','Panic attacks'], 'Stress & Burnout': ['Running on empty','No time for myself','Overwhelmed by responsibilities','Exhausted but cannot stop','Disconnected from joy','Going through the motions'], 'Grief & Loss': ['Grieving someone I lost','Grieving a version of my life','Feeling stuck in sadness','Angry at what was taken','Struggling to move forward','Carrying this alone'], 'Inner Child Work': ['Repeating childhood patterns','People-pleasing constantly','Afraid of abandonment','Self-critical voice is loud','Never felt good enough','Parenting triggers me'], 'Self-Worth': ['Waiting to feel worthy','Comparing myself to everyone','Hard time saying no','Apologizing for existing','Not believing in myself','Putting everyone else first'], 'Parenting': ['Losing patience too easily','Triggered by my kids','Guilt about my parenting','Co-parenting is hard','Worried about my kids','Feeling like I am failing'], 'Divorce & Separation': ['Navigating co-parenting','Grieving my marriage','Rebuilding my identity','Angry at what happened','Worried about my kids','Starting over feels scary'], 'Anger': ['Anger takes over fast','Saying things I regret','Holding in resentment','Anger scaring me or others','Feeling unheard and invisible','Rage that has nowhere to go'], 'Recovery': ['One day at a time','Navigating cravings','Rebuilding trust with others','Rebuilding trust with myself','Shame about my past','Finding who I am sober'], 'Life Purpose': ['Feeling completely lost','Going through the motions','Wasted potential weighs on me','Do not know what I want','Living for others not myself','Searching for meaning'], 'Career': ['Dreading work every day','Imposter syndrome is loud','Undervalued and overlooked','Burned out from overworking','Do not know my next step','Afraid to chase what I want'], }; var defaultCurrentSelf = ['Overwhelmed','Stuck in patterns','Lost and unsure','Anxious a lot','Healing but slowly','Disconnected from myself','Going through a hard season','Ready for something to shift']; var futureSelfMap = { 'Love & Relationships': ['Loving without losing myself','Open to real connection','Secure in who I am','Attracting healthy love','At peace with my past','Trusting again fully'], 'Anxiety': ['Calm in my nervous system','Responding not reacting','Anxiety no longer runs me','Present in my own life','Feeling safe in my body','Free from constant worry'], 'Stress & Burnout': ['Rested and restored','Clear on my priorities','Saying no without guilt','Energy that lasts all day','Work that does not drain me','Enjoying my life again'], 'Grief & Loss': ['Carrying love not just pain','Honoring what I lost','Moving forward gently','Feeling whole again','Grief as part of my story','Finding meaning in loss'], 'Inner Child Work': ['Reparenting myself','Setting limits from love','Breaking generational patterns','Self-compassion as a default','Secure attachment with myself','Healing the root'], 'Self-Worth': ['Knowing I am enough','Boundaries that feel good','Showing up as myself','No longer shrinking','Choosing myself daily','Confident in my voice'], 'Parenting': ['Present and regulated parent','Breaking the cycle','Repairing after rupture','Parenting with intention','My kids feel safe with me','Patient and grounded'], 'Divorce & Separation': ['Co-parenting with peace','Thriving on my own terms','My kids are okay','My new chapter is beautiful','Healed not bitter','Rebuilt and strong'], 'Anger': ['Calm and in control','Anger as information','Expressing without destroying','Relationships that feel safe','Processing not suppressing','Peaceful in my body'], 'Recovery': ['Free and clear-headed','Proud of who I am becoming','Relationships rebuilt','My story inspires others','Purposeful and present','Living fully sober'], 'Life Purpose': ['Living with intention','A life that feels like mine','Following what lights me up','Purpose I wake up for','Leaving a real legacy','Doing work that matters'], 'Career': ['Doing work I love','Valued for what I bring','A career on my terms','Boundaries at work','Confident in my path','Building something real'], }; var defaultFutureSelf = ['Calm and regulated','Confident in herself','A present grounded parent','Free from the past','At peace with her family','Trusts herself fully','Living with real purpose','Fully unleashed']; function toggleChip(el) { el.classList.toggle('on'); } function populateCurrentSelfChips() { var el = document.getElementById('currentSelfChips'); if (!el) return; var chips = []; state.focusAreas.forEach(function(fa) { var mapped = currentSelfMap[fa]; if (mapped) chips = chips.concat(mapped); }); if (!chips.length) chips = defaultCurrentSelf; // Deduplicate chips = chips.filter(function(c, i) { return chips.indexOf(c) === i; }); el.innerHTML = chips.map(function(c) { return '
' + c + '
'; }).join(''); } function populateFutureSelfChips() { var el = document.getElementById('futureSelfChips'); if (!el) return; var chips = []; state.focusAreas.forEach(function(fa) { var mapped = futureSelfMap[fa]; if (mapped) chips = chips.concat(mapped); }); if (!chips.length) chips = defaultFutureSelf; chips = chips.filter(function(c, i) { return chips.indexOf(c) === i; }); el.innerHTML = chips.map(function(c) { return '
' + c + '
'; }).join(''); } function saveCurrentSelf() { state.currentSelf = [].slice.call(document.querySelectorAll('#ob-a3 .chip.on')) .map(function(el) { return el.textContent; }); saveState(); } function saveFutureSelf() { state.futureSelf = [].slice.call(document.querySelectorAll('#ob-a4 .chip.on')) .map(function(el) { return el.textContent; }); saveState(); } function selOne(el) { [].slice.call(document.querySelectorAll('#ob-a5 .chip')).forEach(function(c) { c.classList.remove('on'); }); el.classList.add('on'); state.tone = el.textContent; } function finishAdultOnboarding() { state.onboardingDone = true; saveState(); goTo('home'); } // ─── KIDS OB ───────────────────────────────────────────── function onChildName(v) { var t = document.getElementById('childNameTitle'); if (t) t.textContent = v ? v + "'s account" : 'your child'; } function goToKidsFlow() { var nm = (document.getElementById('childNameIn') || {}).value || ''; state.name = nm.trim() || 'friend'; [].slice.call(document.querySelectorAll('.kND')).forEach(function(e) { e.textContent = state.name; }); if (state.age >= 13) { var sr = document.getElementById('substRow'); if (sr) sr.style.display = 'flex'; } saveState(); goTo('ob-k1'); } function onKidName(v) { state.name = v; [].slice.call(document.querySelectorAll('.kND')).forEach(function(e) { e.textContent = v || 'friend'; }); var btn = document.getElementById('k1btn'); if (v.trim()) btn.classList.remove('btn-dim'); else btn.classList.add('btn-dim'); } function saveKidsFocus() { state.focusAreas = [].slice.call(document.querySelectorAll('#ob-k2 .fc.on')) .map(function(el) { return el.querySelector('.fc-nm').textContent; }); saveState(); } function finishKidsOnboarding() { var rn = document.getElementById('kReadyName'); if (rn) rn.textContent = state.name || 'Friend'; state.onboardingDone = true; saveState(); goTo(state.age >= 13 ? 'home-teen' : 'home-kids'); } // ─── PERMISSIONS ───────────────────────────────────────── var perms = [ ['Daily mood check-ins', 'Feelings, emotions, everyday wellbeing', true], ['Friendships and social topics', 'Bullying, fitting in, friendship conflict', true], ['Family topics', 'Divorce, family changes, home stress', true], ['Body positivity and nutrition', 'Healthy habits, body image, food', true], ['Chores and home responsibility', 'Age-appropriate tasks, independence', true], ['Identity and self-worth', 'Confidence, purpose, who they are becoming', true] ]; (function() { var pr = document.getElementById('permRows'); if (!pr) return; pr.innerHTML = perms.map(function(p) { var bg = p[2] ? 'var(--sage-600)' : '#c5d5cc'; var on = p[2] ? ' on' : ''; return '
' + '
' + p[0] + '
' + '
' + p[1] + '
' + '
'; }).join(''); })(); // ─── QUOTES ────────────────────────────────────────────── var dailyQuotes = [ { text: 'You do not have to earn your peace. You just have to come home to it.' }, { text: 'The goal is not to feel better. It is to get better at feeling.' }, { text: 'You are not behind. You are right on time for the version of you that is coming.' }, { text: 'Healing is not linear. But showing up every day? That is the whole thing.' }, { text: 'She is already in there. We are just helping her out.' }, { text: 'What if feeling good was just your normal? Let us build that.' }, { text: 'Every beautiful thing begins with a single moment of presence.' } ]; var toolIcons = ['💕','🌊','🔥','🕊️','🧸','👑','👨‍👧','⚖️','⚡','🌱','🧭','💼']; // ─── HOME ───────────────────────────────────────────────── function refreshHome() { var h = new Date().getHours(); var greet = h < 12 ? 'Good morning ☀️' : h < 17 ? 'Good afternoon 🌿' : 'Good evening 🌙'; var gEl = document.getElementById('homeGreeting'); if (gEl) gEl.textContent = greet; var ne = document.getElementById('homeNameDisp'); if (ne) ne.textContent = state.name || 'friend'; var se = document.getElementById('homeStreak'); if (se) se.textContent = (state.streak || 0) + ' days'; var ls = state.sessions[state.sessions.length - 1]; var me = document.getElementById('homeMood'); if (me) me.textContent = ls ? ls.mood + '/10' : '-/10'; var sess = document.getElementById('homeSessions'); if (sess) sess.textContent = state.sessions.length; var qi = new Date().getDate() % dailyQuotes.length; var qt = document.getElementById('homeQuoteText'); if (qt) qt.textContent = dailyQuotes[qi].text; var fc = document.getElementById('homeFocusCards'); if (!fc) return; if (state.focusAreas.length) { fc.innerHTML = state.focusAreas.slice(0, 2).map(function(fa, i) { var prog = Math.min(state.sessions.length * 3, 100); return '
' + '
' + toolIcons[i % 12] + '
' + '
' + '
' + fa + '
' + '
' + '
Day ' + state.sessions.length + ' of 30
' + '
'; }).join(''); } else { fc.innerHTML = '
Complete your morning flow to see your focus progress.
'; } } // ─── KIDS HOME ──────────────────────────────────────────── var words = [ { word: 'Courageous', def: 'Being brave even when things feel scary. You are courageous every time you try something new!' }, { word: 'Resilient', def: 'The ability to bounce back after hard things. You build this every single day.' }, { word: 'Compassionate', def: 'Being kind and understanding to others and yourself. Especially yourself.' }, { word: 'Grateful', def: 'Noticing the good things around you. Even tiny ones count.' }, { word: 'Authentic', def: 'Being truly yourself, not what others want you to be. That person is amazing.' }, { word: 'Curious', def: 'Asking questions and exploring. The best people never stop being curious.' }, { word: 'Determined', def: 'Sticking with something even when it gets hard. That is how big things happen.' } ]; var kidsTileData = [ { ic: '😊', nm: 'How I Feel' }, { ic: '👯', nm: 'Friend Stuff' }, { ic: '🏠', nm: 'Family' }, { ic: '📚', nm: 'Story Time' }, { ic: '🧹', nm: 'My Chores' }, { ic: '🍎', nm: 'Healthy Me' } ]; function refreshKidsHome() { var n = document.getElementById('kidsNameDisp'); if (n) n.textContent = state.name || 'friend'; var d = document.getElementById('kidsDayDisp'); if (d) d.textContent = 'Day ' + (state.streak || 1) + ', keep going!'; var b = document.getElementById('kidsStreakBadge'); if (b) b.textContent = 'Day ' + (state.streak || 1); var w = words[new Date().getDay()]; var ww = document.getElementById('wotdWord'); if (ww) ww.textContent = w.word; var wd = document.getElementById('wotdDef'); if (wd) wd.textContent = w.def; var tiles = document.getElementById('kidsTilesEl'); if (tiles) { tiles.innerHTML = kidsTileData.map(function(t) { return '
' + '
' + t.ic + '
' + '
' + t.nm + '
' + '
'; }).join(''); } } function refreshTeenHome() { var n = document.getElementById('teenNameDisp'); if (n) n.textContent = state.name || 'friend'; var d = document.getElementById('teenDayDisp'); if (d) d.textContent = 'Day ' + (state.streak || 1); var b = document.getElementById('teenStreakBadge'); if (b) b.textContent = 'Day ' + (state.streak || 1); var w = words[new Date().getDay()]; var tw = document.getElementById('teenWotdWord'); if (tw) tw.textContent = w.word; var td = document.getElementById('teenWotdDef'); if (td) td.textContent = w.def; var fc = document.getElementById('teenFocusCards'); if (!fc) return; if (state.focusAreas.length) { fc.innerHTML = state.focusAreas.slice(0, 2).map(function(fa, i) { var prog = Math.min(state.sessions.length * 3, 100); return '
' + '
' + toolIcons[i % 12] + '
' + '
' + '
' + fa + '
' + '
' + '
Day ' + state.sessions.length + ' of 30
' + '
'; }).join(''); } else { fc.innerHTML = '
Complete onboarding to see your focus areas.
'; } } // ─── DAILY FLOW ─────────────────────────────────────────── var LOADER = '
'; function initFlow() { var qi = new Date().getDate() % dailyQuotes.length; var q = dailyQuotes[qi]; var qt = document.getElementById('df1Qt'); if (qt) qt.textContent = q.text; var qa = document.getElementById('df1Qa'); if (qa) qa.textContent = '— Clari 🌿'; checkIn = { mood: 7, focus: 5, energy: 6, stress: 6, clarity: 5 }; // Reset sliders ['vMood','vFocus','vEnergy','vStress','vClarity'].forEach(function(id, i) { var el = document.getElementById(id); var defaults = [7,5,6,6,5]; if (el) el.textContent = defaults[i]; }); } var readingFallbacks = { 'Anxiety': 'There is a version of you who already knows how to be calm. She is not somewhere in the future — she is underneath the noise. Today we are not trying to eliminate anxiety. We are learning to move through it without it running the show.', 'Stress & Burnout': 'You cannot pour from an empty cup. That is not a metaphor — it is a biological fact. Rest is not a reward you earn after you finish everything. Rest is part of how you finish anything at all. Today, one thing. Just one.', 'Inner Child Work': 'The patterns you are trying to break were once survival strategies. They worked when you were small. They kept you safe. You are allowed to thank them for their service — and gently let them know you do not need them anymore.', 'Love & Relationships': 'The relationship you have with yourself sets the template for every relationship you have with others. You are not being selfish when you tend to yourself. You are becoming someone who has something real to give.', 'Parenting': 'Repair matters more than perfection. Your kids do not need a parent who never loses it. They need a parent who comes back, who says sorry, who models what it looks like to be human and keep trying. That is you.', 'Divorce & Separation': 'Grief and growth can happen at the same time. You are allowed to mourn what you lost and build something new without guilt. Both things are true. Both things are allowed.', 'Self-Worth': 'You have been waiting to feel worthy until something external changes. But worth is not something you earn — it is something you claim. Today, claim a little more of it.', 'default': 'Showing up is the whole thing. Not showing up perfectly. Not having it all figured out. Just opening the door and walking through. You did that today. That matters more than you know.' }; async function loadReading() { var el = document.getElementById('df2Content'); if (!el) return; el.innerHTML = LOADER; var focus = state.focusAreas[0] || 'general wellbeing'; var prompt = 'Write a 4-6 sentence coaching read for today. Topic: ' + focus + '. Current state: ' + (state.currentSelf.join(', ') || 'working on themselves') + '. Style: intimate and direct, like a warm note from a wise friend. ' + 'Simple language. No emojis. No lists. Just flowing paragraphs. ' + 'Make it feel written specifically for them today.'; var text = await callClaude([{ role: 'user', content: prompt }], 250); if (!text || text.length < 20) { // Rich fallback — never show API error message var fallback = readingFallbacks[focus] || readingFallbacks['default']; text = fallback; } el.innerHTML = text.split('\n').filter(function(l) { return l.trim(); }) .map(function(l) { return '

' + l + '

'; }).join(''); } async function loadFollowup() { var msgEl = document.getElementById('df5Msg'); var optEl = document.getElementById('df5Opts'); if (!msgEl || !optEl) return; msgEl.innerHTML = LOADER; optEl.innerHTML = ''; var areas = { mood: checkIn.mood, focus: checkIn.focus, energy: checkIn.energy, stress: checkIn.stress, clarity: checkIn.clarity }; var lowest = Object.entries(areas).sort(function(a, b) { return a[1] - b[1]; })[0]; var msgPrompt = 'The user\'s ' + lowest[0] + ' is at ' + lowest[1] + '/10 today. ' + 'Write 1-2 warm sentences responding and asking what is underneath it. ' + 'Warm, conversational, not clinical.'; var optsPrompt = 'For someone whose ' + lowest[0] + ' is low today, give 4 short tap-to-select ' + 'follow-up options (each under 10 words, real, grounded). ' + 'Return ONLY a JSON array of 4 strings, nothing else.'; var results = await Promise.all([ callClaude([{ role: 'user', content: msgPrompt }], 120), callClaude([{ role: 'user', content: optsPrompt }], 160) ]); var clariMsg = results[0]; if (!clariMsg || clariMsg.length < 10) { var msgFallbacks = { mood: 'Your mood is sitting low today. That matters to me. What is underneath it?', focus: 'Focus is scattered right now. That usually means something is pulling at your attention. What is it?', energy: 'Your energy is low. That tells me something. What has been draining you?', stress: 'Stress is high today. I see that. What is the thing that is actually weighing on you most?', clarity:'Clarity is hard to find right now. When we are unclear, it usually means we know the answer and we are afraid of it. What do you think it is?' }; clariMsg = msgFallbacks[lowest[0]] || 'Something feels hard today. Tell me what is really going on.'; } msgEl.textContent = clariMsg; var areaOpts = { mood: ['Something feels heavy but I cannot name it', 'Going through the motions today', 'Tired of feeling this way', 'Disconnected from myself'], focus: ['Brain will not stop jumping around', 'Too many things at once', 'Avoiding something I know I need to do', 'Overwhelmed before I even start'], energy: ['Running on empty', 'Poor sleep is catching up with me', 'Giving too much and not refilling', 'Body feels heavy and slow'], stress: ['Pressure from every direction', 'Something specific is weighing on me', 'I am holding it all together but barely', 'Anxiety underneath the busyness'], clarity: ['Cannot see the path forward', 'Too many decisions at once', 'Lost in my own head', 'Not sure what I actually want'] }; var opts = areaOpts[lowest[0]] || ['Overthinking, mind will not quiet', 'Avoiding something I need to face', 'Too many things at once', 'Just feel off today']; try { var parsed = JSON.parse(results[1].replace(/```json|```/g, '').trim()); if (Array.isArray(parsed) && parsed.length >= 4) opts = parsed; } catch(e) {} opts.forEach(function(opt) { var btn = document.createElement('button'); btn.className = 'option-btn'; btn.textContent = opt; btn.onclick = function() { [].slice.call(document.querySelectorAll('.option-btn')).forEach(function(b) { b.classList.remove('chosen'); }); this.classList.add('chosen'); checkIn.followupAnswer = opt; }; optEl.appendChild(btn); }); var jpEl = document.getElementById('df6Prompt'); if (jpEl) { var jpPrompt = 'Based on low ' + lowest[0] + ', write ONE short journal prompt under 15 words starting with What, Where, or When. Return only the question.'; var jp = await callClaude([{ role: 'user', content: jpPrompt }], 50); jpEl.textContent = jp || 'What is actually going on underneath everything today?'; } } function setJP(text) { var ta = document.getElementById('journalEntry'); if (ta) { ta.value = text; ta.focus(); } } function saveJournal() { checkIn.journal = (document.getElementById('journalEntry') || {}).value || ''; } async function loadMicroAction() { var iconEl = document.getElementById('df7Icon'); var textEl = document.getElementById('df7Text'); var whyEl = document.getElementById('df7Why'); if (!textEl) return; textEl.innerHTML = '
' + '' + '' + '
'; var context = 'Mood:' + checkIn.mood + ', Focus:' + checkIn.focus + ', Stress:' + checkIn.stress + '. Followup: ' + (checkIn.followupAnswer || 'general') + '. Journal excerpt: ' + ((checkIn.journal || '').slice(0, 100)) + '. Focus area: ' + (state.focusAreas[0] || 'wellbeing'); var prompt = 'Based on this session: ' + context + '. Return JSON only with keys: action (specific, under 20 words, starts with a verb), ' + 'why (1 sentence under 20 words), icon (one emoji).'; var result = await callClaude([{ role: 'user', content: prompt }], 150); try { var json = JSON.parse(result.replace(/```json|```/g, '').trim()); if (iconEl) iconEl.textContent = json.icon || '🌿'; textEl.textContent = '"' + json.action + '"'; if (whyEl) whyEl.textContent = json.why || ''; } catch(e) { // Meaningful fallbacks based on focus area and check-in data var fallbacks = [ { action: 'Place one hand on your chest, breathe in for 4, hold 4, out for 8. Just once.', why: 'One conscious breath tells your nervous system you are safe.', icon: '🌿' }, { action: 'Write down the one thing that is actually bothering you. Not the story around it, just the thing.', why: 'Naming the real source shrinks its power over you.', icon: '📓' }, { action: 'Text one person you love something you appreciate about them.', why: 'Giving love redirects stuck energy and opens your heart.', icon: '💕' }, { action: 'Step outside for 5 minutes. No phone. Just be in your body.', why: 'Your nervous system resets faster with fresh air and movement.', icon: '🌱' }, { action: 'Say out loud: I am allowed to feel this. It does not define me.', why: 'Permission to feel is the first step to moving through it.', icon: '✨' }, ]; var fb = fallbacks[new Date().getDate() % fallbacks.length]; if (state.sessions.length > 0) { var lastSession = state.sessions[state.sessions.length - 1]; if (lastSession.stress > 7) fb = fallbacks[0]; else if (lastSession.focus < 4) fb = fallbacks[3]; } textEl.textContent = '"' + fb.action + '"'; if (whyEl) whyEl.textContent = fb.why; if (iconEl) iconEl.textContent = fb.icon; } } function completeFlow() { var today = new Date().toDateString(); var yesterday = new Date(Date.now() - 86400000).toDateString(); if (state.lastSession === yesterday) state.streak = (state.streak || 0) + 1; else if (state.lastSession !== today) state.streak = 1; state.lastSession = today; state.sessions.push({ date: today, mood: checkIn.mood, focus: checkIn.focus, energy: checkIn.energy, stress: checkIn.stress, clarity: checkIn.clarity, journal: checkIn.journal || '', timestamp: Date.now() }); saveState(); var msgEl = document.getElementById('df8Msg'); if (msgEl) msgEl.textContent = 'That is everything, ' + (state.name || 'friend') + '. Seriously.'; var stEl = document.getElementById('streakDisp'); if (stEl) stEl.textContent = 'Day ' + state.streak; launchConfetti(); goTo('df-8'); } function launchConfetti() { var area = document.getElementById('confettiArea'); if (!area) return; area.innerHTML = ''; var colors = ['#7a9e87','#d4898e','#eebbbd','#a8c4b0','#c9943a','#faf8f4','#4d7260','#f5f0ea']; for (var i = 0; i < 70; i++) { var d = document.createElement('div'); var sz = 5 + Math.random() * 8; d.style.cssText = 'position:absolute;width:' + sz + 'px;height:' + sz + 'px;border-radius:50%;' + 'background:' + colors[Math.floor(Math.random() * colors.length)] + ';' + 'left:' + Math.random() * 100 + '%;top:0;' + 'animation:confetti ' + (2 + Math.random() * 2.5) + 's ' + (Math.random() * 1.8) + 's linear both;z-index:2;'; area.appendChild(d); (function(el) { setTimeout(function() { if (el.parentNode) el.parentNode.removeChild(el); }, 6000); })(d); } } // ─── CHAT ──────────────────────────────────────────────── var chatMsgs = []; function initChat() { var msgsEl = document.getElementById('chatMessages'); if (!msgsEl) return; chatMsgs = state.chatHistory || []; msgsEl.innerHTML = ''; if (!chatMsgs.length) { var h = new Date().getHours(); var timeGreet = h < 12 ? 'Good morning' : h < 17 ? 'Hey' : 'Hey'; var opening = timeGreet + (state.name ? ', ' + state.name : '') + '. I am really glad you are here. ' + (state.sessions.length > 0 ? 'You have been showing up. That matters. What is on your mind today?' : 'This is your space. No judgment, no agenda. Just tell me what is going on.'); appendMsg('clari', opening); chatMsgs = [{ role: 'assistant', content: opening }]; } else { chatMsgs.forEach(function(m) { appendMsg(m.role === 'assistant' ? 'clari' : 'user', m.content); }); } } function appendMsg(role, text) { var msgsEl = document.getElementById('chatMessages'); if (!msgsEl) return; var outer = document.createElement('div'); outer.className = 'msg-outer msg-' + role; if (role === 'clari') { var label = document.createElement('div'); label.className = 'msg-from'; label.textContent = 'Clari 🌿'; var bubble = document.createElement('div'); bubble.className = 'msg-bubble-clari'; bubble.textContent = text; outer.appendChild(label); outer.appendChild(bubble); } else { var bubble = document.createElement('div'); bubble.className = 'msg-bubble-user'; bubble.textContent = text; outer.appendChild(bubble); } msgsEl.appendChild(outer); setTimeout(function() { msgsEl.scrollTop = msgsEl.scrollHeight; }, 50); return outer; } async function sendChat() { var inp = document.getElementById('chatIn'); var text = inp ? inp.value.trim() : ''; if (!text) return; inp.value = ''; appendMsg('user', text); chatMsgs.push({ role: 'user', content: text }); var typing = appendMsg('clari', '...'); if (typing && typing.lastChild) { typing.lastChild.innerHTML = LOADER; } var msgsEl = document.getElementById('chatMessages'); setTimeout(function() { msgsEl.scrollTop = msgsEl.scrollHeight; }, 50); var reply = await callClaude(chatMsgs.slice(-10), 320); if (typing && typing.parentNode) typing.parentNode.removeChild(typing); appendMsg('clari', reply); chatMsgs.push({ role: 'assistant', content: reply }); state.chatHistory = chatMsgs.slice(-20); saveState(); } // ─── PROGRESS ──────────────────────────────────────────── function renderProgress() { var statsEl = document.getElementById('progressStats'); var bodyEl = document.getElementById('progressBody'); if (!statsEl || !bodyEl) return; var sessions = state.sessions || []; statsEl.innerHTML = [ ['Streak', (state.streak || 0) + ' days'], ['Sessions', sessions.length], ['Avg Mood', sessions.length ? (sessions.reduce(function(a,s){return a+s.mood;},0)/sessions.length).toFixed(1) : '-'] ].map(function(s) { return '
' + s[0] + '
' + s[1] + '
'; }).join(''); var last7 = sessions.slice(-7); var emptyBars = Array(7 - last7.length).fill('
').join(''); var bars = emptyBars + last7.map(function(s, i) { return '
'; }).join(''); var journals = sessions.filter(function(s) { return s.journal; }).slice(-3).reverse(); var html = '
' + '
Mood this week ' + sessions.length + ' sessions
' + '
' + '
' + bars + '
' + '
MonTueWedThuFriSatToday
' + (sessions.length ? '
Latest: ' + (last7[last7.length-1] ? last7[last7.length-1].mood : '-') + '/10  ↑
' : '') + '
'; if (sessions.length) { html += '
'; [['Avg Focus','focus'],['Avg Energy','energy'],['Avg Stress','stress'],['Avg Clarity','clarity']].forEach(function(pair) { var avg = (sessions.reduce(function(a,s) { return a+(s[pair[1]]||5); }, 0)/sessions.length).toFixed(1); html += '
' + avg + '
' + pair[0] + '
'; }); html += '
'; } if (journals.length) { html += '
Recent journal entries
'; journals.forEach(function(s) { html += '
' + s.date + '
' + '
' + s.journal.slice(0, 130) + (s.journal.length > 130 ? '...' : '') + '
'; }); } if (!sessions.length) { html += '
' + '
Your story starts with your first session.
' + '' + '
'; } html += '
'; bodyEl.innerHTML = html; } // ─── TOOLS ─────────────────────────────────────────────── var toolsList = [ { ic: '🫳', nm: 'EFT Tapping', dest: 'df-3', desc: 'Tap away anxiety, stress and stuck emotions in minutes.', how: 'Emotional Freedom Technique (EFT) combines tapping on acupressure points with verbal affirmations. Clinically proven to reduce cortisol by up to 43% in a single session.', steps: ['Start with the breathwork to regulate first','Follow the tapping sequence on 9 points','State what you are feeling out loud as you tap','End with a full breath and a self-compassion statement'], clariMsg: 'EFT is one of my favorite tools. It feels a little weird at first — but the results are real. Even one round can shift something.', actionLabel: 'Start with breathwork' }, { ic: '🌬️', nm: 'Breathwork', dest: 'df-3', desc: 'Regulate your nervous system with intentional breathing.', how: 'The Presence Process breathing pattern — in for 4, hold for 4, out for 8 — activates the parasympathetic nervous system. This is the fastest way to move from stress to calm.', steps: ['Find a comfortable seat','Follow the 4-4-8 pattern for at least 3 full cycles','Notice how your body shifts with each breath','You cannot do this wrong — just breathe'], clariMsg: 'Breathwork is where everything starts for me. Before you think, before you journal — just breathe. Your body knows what to do.', actionLabel: 'Start breathing now' }, { ic: '📓', nm: 'Guided Journal', dest: 'df-6', desc: 'AI-guided prompts tailored to exactly what you need today.', how: 'Clari generates a personalized journal prompt based on your mood check-in, your focus areas, and what came up in your session. No blank page. Just the right question at the right moment.', steps: ['Complete your mood check-in first for best results','Read the prompt and let it land','Write without editing — this is not for anyone but you','Notice what surprises you'], clariMsg: 'The journal is where the real stuff comes out. I will give you one question — just one — that I think will open something for you today.', actionLabel: 'Open your journal' }, { ic: '🎧', nm: 'Meditation and Audio', dest: 'chat', desc: 'Guided sessions for sleep, focus, calm and healing.', how: 'Audio-guided meditations tailored to your current emotional state. Ask Clari for a sleep meditation, an anxiety reset, a body scan, or a visualization — she will guide you through it in real time.', steps: ['Tell Clari what you need: sleep, calm, focus, or healing','Find somewhere quiet and comfortable','Let Clari guide you with her voice','No experience needed — just listen'], clariMsg: 'Tell me what you need and I will guide you through it. Sleep, anxiety, a body scan, a visualization — I have got you.', actionLabel: 'Ask Clari for a meditation' }, { ic: '🧸', nm: 'Inner Child Work', dest: 'chat', desc: 'Gentle, loving work on the patterns from your past.', how: 'Inner child work helps you identify and heal the root beliefs formed in childhood that are still running your adult life. This is some of the deepest, most powerful work you can do.', steps: ['Come to this one gently — no rushing','Tell Clari what pattern you want to explore','She will guide you to the root with compassion','Expect to feel things — that is the point'], clariMsg: 'Inner child work changed everything for me. The part of you that is still hurting deserves to be heard. I will be right there with you.', actionLabel: 'Begin inner child work' }, { ic: '🧠', nm: 'CBT Tools', dest: 'chat', desc: 'Reframe thoughts, change patterns, evidence-based.', how: 'Cognitive Behavioral Therapy tools help you identify distorted thinking patterns and replace them with more accurate, helpful ones. These are the same tools used in therapy sessions.', steps: ['Identify the thought that is causing distress','Examine the evidence for and against it','Find a more balanced, accurate perspective','Practice the new thought consistently'], clariMsg: 'CBT is about catching the thought before it catches you. Tell me what your brain is telling you and we will look at it together.', actionLabel: 'Start CBT work with Clari' }, { ic: '💃', nm: 'Somatic Tools', dest: 'chat', desc: 'Body-based tools to release stored stress and trauma.', how: 'Somatic work recognizes that stress and trauma are stored in the body, not just the mind. These tools use movement, breath, and body awareness to release what words cannot reach.', steps: ['Check in with your body before you begin','Notice where you are holding tension right now','Follow Clari through a somatic sequence','Move slowly — the body communicates in whispers'], clariMsg: 'Your body is keeping score. Somatic work is how we help it put the score down. Tell me where you feel it and we will start there.', actionLabel: 'Start somatic work' }, { ic: '🌟', nm: 'NLP Techniques', dest: 'chat', desc: 'Rewire how you talk to yourself and see your world.', how: 'Neuro-Linguistic Programming tools help you change the internal language and mental images that create your emotional experience. Fast, practical, and often surprisingly effective.', steps: ['Notice the story you are telling yourself right now','Clari will walk you through a reframing technique','Practice the new internal language','Repetition is how the new pattern becomes the default'], clariMsg: 'The words you use inside your own head are creating your reality. Let us change the language and watch what shifts.', actionLabel: 'Start NLP with Clari' }, { ic: '👨‍👧', nm: 'Parenting Support', dest: 'chat', desc: 'Real tools for the hardest and most beautiful job.', how: 'Parenting tools focused on regulation, repair, and connection. You cannot pour from an empty cup — so this starts with you. Clari helps you get regulated so you can show up the way you want to for your kids.', steps: ['Start with your own regulation — always','Tell Clari what happened or what you are struggling with','Get a specific tool for the situation','Practice repair — it is never too late'], clariMsg: 'Parenting is the most triggering job on earth because it reaches the deepest parts of us. You are not failing. You are growing. Let me help.', actionLabel: 'Talk to Clari about parenting' }, { ic: '⚖️', nm: 'Co-Parenting and Divorce', dest: 'chat', desc: 'Navigate transitions with grace and clarity.', how: 'Specific tools for the unique grief, anger, and complexity of separation and co-parenting. Clari holds this space without judgment — she knows it is layered.', steps: ['Tell Clari where you are in the process','Name what you are actually feeling underneath the logistics','Get a grounded tool for today','Come back whenever it gets hard — because it will'], clariMsg: 'This is one of the hardest things a person can navigate. I am not here to give you cliches. I am here to actually help. Talk to me.', actionLabel: 'Open this conversation' }, { ic: '🧘', nm: 'Mindfulness', dest: 'chat', desc: 'Present-moment practices that fit real life.', how: 'Mindfulness is not about emptying your mind — it is about learning to observe it without being controlled by it. Clari will give you micro-practices you can use anywhere, anytime.', steps: ['Start with just one breath — seriously, just one','Notice what is actually happening right now','Clari will guide you through a presence practice','Even 60 seconds counts — do not wait for the perfect moment'], clariMsg: 'Every beautiful thing begins with a single moment of presence. That is not just a tagline — that is the whole practice. Let me show you.', actionLabel: 'Practice mindfulness now' }, { ic: '✨', nm: 'Hypnosis Tracks', dest: 'chat', desc: 'Guided audio for deep-level pattern shifts.', how: 'Conversational hypnosis uses relaxation and guided imagery to access the subconscious mind where deep beliefs and patterns live. More relaxing than you expect, more effective than you think.', steps: ['Find a quiet space where you will not be interrupted','Lie down if possible','Let Clari guide you into a relaxed state','Trust the process — your subconscious knows what to do'], clariMsg: 'Hypnosis is just a deeply relaxed, focused state — you are always in control. Some of the fastest shifts I have seen happen here. Want to try?', actionLabel: 'Start a hypnosis session' } ]; function renderTools() { var el = document.getElementById('toolsBody'); if (!el) return; // Group tools into categories var categories = [ { label: 'Regulation and Body', tools: [0, 1, 6] }, { label: 'Mind and Thinking', tools: [5, 7, 10, 11] }, { label: 'Healing and Growth', tools: [2, 4, 3] }, { label: 'Relationships', tools: [8, 9] }, ]; var html = ''; categories.forEach(function(cat) { html += '
' + cat.label + '
'; cat.tools.forEach(function(i) { var t = toolsList[i]; html += '
' + '
' + t.ic + '
' + '
' + t.nm + '
' + t.desc + '
' + '
'; }); }); el.innerHTML = html; } function openTool(idx) { var t = toolsList[idx]; if (!t) return; // Populate detail screen var hero = document.getElementById('tdHero'); if (hero) hero.style.background = 'linear-gradient(160deg,var(--sage-900),var(--sage-800))'; var nameEl = document.getElementById('tdName'); if (nameEl) nameEl.textContent = t.nm; var iconEl = document.getElementById('tdIcon'); if (iconEl) iconEl.textContent = t.ic; var descEl = document.getElementById('tdDesc'); if (descEl) descEl.textContent = t.desc; var howEl = document.getElementById('tdHow'); if (howEl) howEl.textContent = t.how; var stepsEl = document.getElementById('tdSteps'); if (stepsEl && t.steps) { stepsEl.innerHTML = '
What to expect
' + t.steps.map(function(s, i) { return '
' + '
' + (i+1) + '
' + '
' + s + '
' + '
'; }).join(''); } var msgEl = document.getElementById('tdClariMsg'); if (msgEl) msgEl.textContent = t.clariMsg || 'Ready when you are.'; var btnEl = document.getElementById('tdActionBtn'); if (btnEl) { btnEl.textContent = (t.actionLabel || 'Start now') + ' →'; btnEl.onclick = function() { goTo(t.dest); }; } goTo('tool-detail'); } // ─── FAMILY ────────────────────────────────────────────── var selectedAvatar = '🌿'; function selectAvatar(el, emoji) { selectedAvatar = emoji; [].slice.call(document.querySelectorAll('.av-opt')).forEach(function(d) { d.classList.remove('sel'); }); el.classList.add('sel'); } function addFamilyProfile() { var name = (document.getElementById('newProfileName') || {}).value || ''; var age = parseInt((document.getElementById('newProfileAge') || {}).value) || 0; if (!name.trim() || !age) { alert('Please enter a name and age.'); return; } if (!state.familyProfiles) state.familyProfiles = []; state.familyProfiles.push({ id: Date.now(), name: name.trim(), age: age, avatar: selectedAvatar, isKid: age < 18, sessions: [], streak: 0, lastSession: null, focusAreas: [], onboardingDone: false }); saveState(); var n = document.getElementById('newProfileName'); if (n) n.value = ''; var a = document.getElementById('newProfileAge'); if (a) a.value = ''; goTo('family'); } function renderFamily() { var el = document.getElementById('familyProfiles'); if (!el) return; var profiles = state.familyProfiles || []; var primaryHTML = '
' + '
🌿
' + '
' + (state.name || 'Me') + '
' + '
Age ' + state.age + ' · ' + (state.focusAreas[0] || 'Getting started') + '
' + '
🔥 ' + (state.streak || 0) + ' day streak
' + '
Active
'; var kidHTML = profiles.map(function(p) { var bg = p.age <= 12 ? 'linear-gradient(135deg,#e8f8ee,#d0f0dc)' : 'linear-gradient(135deg,#f0eaff,#e0d0ff)'; return '
' + '
' + p.avatar + '
' + '
' + p.name + '
' + '
Age ' + p.age + ' · ' + (p.age <= 12 ? 'Little Explorer' : p.age <= 17 ? 'Teen Zone' : 'Adult') + '
' + '
🔥 ' + (p.streak || 0) + ' day streak
' + '
'; }).join(''); el.innerHTML = primaryHTML + kidHTML; } function switchProfile(profileId) { var profiles = state.familyProfiles || []; var profile = profiles.find(function(p) { return p.id === profileId; }); if (!profile) return; state.name = profile.name; state.age = profile.age; state.isKid = profile.isKid; state.focusAreas = profile.focusAreas || []; state.streak = profile.streak || 0; state.sessions = profile.sessions || []; state.onboardingDone = profile.onboardingDone || false; saveState(); if (!profile.onboardingDone) goTo('ob-k1'); else if (profile.age >= 13 && profile.age < 18) goTo('home-teen'); else if (profile.age < 18) goTo('home-kids'); else goTo('home'); } function renderParentDash() { var el = document.getElementById('parentDashBody'); if (!el) return; var profiles = state.familyProfiles || []; if (!profiles.length) { el.innerHTML = '
No child profiles yet.
'; return; } el.innerHTML = profiles.map(function(p) { var sessions = p.sessions || []; var avgMood = sessions.length ? (sessions.reduce(function(a,s){return a+s.mood;},0)/sessions.length).toFixed(1) : '-'; var avgStress = sessions.length ? (sessions.reduce(function(a,s){return a+s.stress;},0)/sessions.length).toFixed(1) : '-'; var bg = p.age <= 12 ? '#e8f8ee' : '#f0eaff'; return '
' + '
' + '
' + p.avatar + '
' + '
' + p.name + '
Age ' + p.age + ' · ' + sessions.length + ' sessions · 🔥 ' + (p.streak || 0) + ' streak
' + '
' + '
' + '
' + avgMood + '
Avg Mood
' + '
' + avgStress + '
Avg Stress
' + '
' + (p.streak || 0) + '
Streak
' + '
' + '
Journals are private. Mood trends only.
' + '
'; }).join(''); } // ─── UTILITIES ─────────────────────────────────────────── function shareClari() { var msg = 'I found this app called Clari. It is like a cozy daily practice for actually feeling good about your life. There is even a version for kids. You need to see this: https://clari.app'; if (navigator.share) { navigator.share({ title: 'Clari', text: msg, url: 'https://clari.app' }); } else if (navigator.clipboard) { navigator.clipboard.writeText('https://clari.app').then(function() { alert('Link copied!'); }); } } function loadUser() { if (state.name && state.onboardingDone) { goTo(state.isKid ? (state.age >= 13 ? 'home-teen' : 'home-kids') : 'home'); } } // Presence Process breathing // Cycle: Inhale 4s → Hold 4s → Exhale 8s = 16s total var breathState = { phase: 'inhale', count: 4, cycle: 0 }; var breathPhases = [ { name: 'Inhale', duration: 4, color: 'rgba(168,196,176,.8)' }, { name: 'Hold', duration: 4, color: 'rgba(201,148,58,.7)' }, { name: 'Exhale', duration: 8, color: 'rgba(212,137,142,.7)' } ]; var breathPhaseIdx = 0; var breathTick = 0; var breathTotalTicks = 0; // 0..15 var breathCircumference = 565; // 2*pi*90 setInterval(function() { var scr = document.getElementById('df-3'); if (!scr || !scr.classList.contains('active')) return; var phase = breathPhases[breathPhaseIdx]; var countEl = document.getElementById('breathCount'); var phaseEl = document.getElementById('breathPhase'); var ringEl = document.getElementById('breathRing'); var dotEl = document.getElementById('breathDot'); if (countEl) countEl.textContent = phase.duration - breathTick; if (phaseEl) phaseEl.textContent = phase.name; // Ring progress within current phase var phaseProgress = breathTick / phase.duration; var totalProgress = (breathTotalTicks) / 16; var offset = breathCircumference * (1 - totalProgress); if (ringEl) { ringEl.style.strokeDashoffset = offset; ringEl.style.stroke = phase.color; } // Travelling dot around the ring if (dotEl) { var angle = totalProgress * 360 - 90; var rad = angle * Math.PI / 180; var cx = 100 + 90 * Math.cos(rad); var cy = 100 + 90 * Math.sin(rad); dotEl.setAttribute('cx', cx.toFixed(1)); dotEl.setAttribute('cy', cy.toFixed(1)); dotEl.style.fill = phase.color; } // Cycle indicators if (breathTotalTicks === 0) { for (var i = 1; i <= 4; i++) { var dot = document.getElementById('breathCycle' + i); if (dot) dot.style.background = i <= breathState.cycle ? 'rgba(255,255,255,.7)' : 'rgba(255,255,255,.2)'; } } breathTick++; breathTotalTicks++; if (breathTick >= phase.duration) { breathTick = 0; breathPhaseIdx = (breathPhaseIdx + 1) % 3; // Reset ring when cycle completes if (breathPhaseIdx === 0) { breathTotalTicks = 0; breathState.cycle = Math.min((breathState.cycle || 0) + 1, 4); if (ringEl) ringEl.style.strokeDashoffset = breathCircumference; } } }, 1000); // Clock (function tick() { var now = new Date(); var t = document.getElementById('sbTime'); if (t) t.textContent = now.getHours() + ':' + (now.getMinutes() < 10 ? '0' : '') + now.getMinutes(); setTimeout(tick, 10000); })(); // Auto-login window.addEventListener('load', function() { if (state.name && state.onboardingDone) { setTimeout(function() { goTo(state.isKid ? (state.age >= 13 ? 'home-teen' : 'home-kids') : 'home'); }, 1200); } if (!state.familyProfiles) { state.familyProfiles = []; saveState(); } });