<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="theme-color" content="#ff6600">
<title>Gamawareness254 β€” Recovery Tracker</title>
<style>
:root{
  --green:#ff6600; --green-dark:#cc5200; --green-soft:#ffede0; --red:#c0392b;
  --ink:#1c2420; --muted:#6b7a72; --bg:#f4f6f4; --card:#ffffff; --line:#e2e8e4;
  --amber:#b9770e;
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
body{font-family:-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--ink);padding-bottom:76px}
header{background:linear-gradient(135deg,var(--green),var(--green-dark));color:#fff;padding:14px 16px;position:sticky;top:0;z-index:10}
header h1{font-size:1.05rem;font-weight:700;display:flex;align-items:center;gap:8px}
header .sub{font-size:.72rem;opacity:.85;margin-top:2px}
main{max-width:560px;margin:0 auto;padding:14px}
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:14px;margin-bottom:12px}
.card h3{font-size:.8rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:10px}
.tab{display:none}
.tab.active{display:block}
/* streak card */
.streak{display:flex;align-items:center;gap:14px}
.flame{font-size:2.2rem}
.streak .num{font-size:2rem;font-weight:800;color:var(--green-dark)}
.streak .lbl{font-size:.8rem;color:var(--muted)}
.gf-btn{margin-left:auto;background:var(--green-soft);color:var(--green-dark);border:2px solid var(--green);border-radius:12px;padding:12px 14px;font-weight:700;font-size:.85rem;cursor:pointer;transition:.15s}
.gf-btn.done{background:var(--green);color:#fff}
/* score ring */
.ring-wrap{display:flex;align-items:center;gap:16px}
.ring{transform:rotate(-90deg)}
.ring .bg{stroke:var(--line)}
.ring .fg{stroke:var(--green);stroke-linecap:round;transition:stroke-dashoffset .4s}
.ring-txt{font-size:1.6rem;font-weight:800}
/* habit list */
.habit{display:flex;align-items:center;gap:10px;padding:10px 4px;border-bottom:1px solid var(--line);cursor:pointer}
.habit:last-child{border-bottom:none}
.habit .box{width:24px;height:24px;border:2px solid #b9c6bf;border-radius:7px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:.85rem;color:#fff;transition:.12s}
.habit.done .box{background:var(--green);border-color:var(--green)}
.habit .name{flex:1;font-size:.92rem}
.habit.done .name{color:var(--muted);text-decoration:line-through}
.habit .note{width:88px;border:none;border-bottom:1px dashed var(--line);font-size:.75rem;color:var(--amber);background:transparent;text-align:right;outline:none}
.habit .note::placeholder{color:#c3cdc8}
.grp{margin-top:6px}
.grp-title{font-size:.72rem;font-weight:700;color:var(--green-dark);text-transform:uppercase;letter-spacing:.05em;margin:12px 0 2px}
/* buttons */
.btn{display:inline-block;background:var(--green);color:#fff;border:none;border-radius:10px;padding:11px 16px;font-size:.88rem;font-weight:700;cursor:pointer}
.btn.ghost{background:#fff;color:var(--green-dark);border:1.5px solid var(--green)}
.btn.danger{background:#fdecea;color:var(--red);border:1.5px solid var(--red)}
.btn.block{width:100%;text-align:center;margin-top:8px}
.sos{background:linear-gradient(135deg,#c0392b,#96281b);color:#fff;border:none;border-radius:14px;padding:16px;font-size:1rem;font-weight:800;width:100%;cursor:pointer;margin-bottom:12px}
input[type=text],input[type=tel],input[type=number],textarea,select{width:100%;padding:10px;border:1.5px solid var(--line);border-radius:10px;font-size:.9rem;margin-top:6px;font-family:inherit}
label.f{display:block;font-size:.8rem;color:var(--muted);margin-top:10px}
.row{display:flex;gap:8px}.row>*{flex:1}
/* bottom nav */
nav{position:fixed;bottom:0;left:0;right:0;background:#fff;border-top:1px solid var(--line);display:flex;z-index:20;padding-bottom:env(safe-area-inset-bottom)}
nav button{flex:1;background:none;border:none;padding:9px 4px 7px;font-size:.68rem;color:var(--muted);cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px}
nav button .ic{font-size:1.15rem}
nav button.active{color:var(--green-dark);font-weight:700}
/* lists */
.log-item{border-bottom:1px solid var(--line);padding:9px 2px;font-size:.85rem}
.log-item:last-child{border:none}
.log-item .meta{font-size:.72rem;color:var(--muted)}
.pill{display:inline-block;font-size:.68rem;padding:2px 8px;border-radius:20px;background:var(--green-soft);color:var(--green-dark);font-weight:700}
.pill.red{background:#fdecea;color:var(--red)}
.big-num{font-size:1.8rem;font-weight:800;color:var(--green-dark)}
/* stats */
.bar-row{display:flex;align-items:center;gap:8px;margin-bottom:7px;font-size:.8rem}
.bar-row .lbl{width:110px;flex-shrink:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--muted)}
.bar-row .track{flex:1;height:8px;background:var(--line);border-radius:6px;overflow:hidden}
.bar-row .fill{height:100%;background:var(--green);border-radius:6px}
.bar-row .pct{width:34px;text-align:right;font-weight:700}
/* SOS overlay */
#sosOverlay{position:fixed;inset:0;background:#141a17;color:#fff;z-index:50;display:none;flex-direction:column;padding:22px;overflow-y:auto}
#sosOverlay.open{display:flex}
#breathCircle{width:170px;height:170px;border-radius:50%;background:radial-gradient(circle,#ff9a4d,#ff6600);margin:26px auto;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:1.05rem;transition:transform 4s ease-in-out}
#breathPhase{text-align:center;font-size:1.05rem;font-weight:700;margin-top:8px}
.reason{background:#202925;border:1px solid #33413a;border-radius:12px;padding:12px;margin-bottom:8px;font-size:.9rem}
.empty{color:var(--muted);font-size:.85rem;text-align:center;padding:14px}
.toast{position:fixed;bottom:86px;left:50%;transform:translateX(-50%);background:var(--ink);color:#fff;padding:10px 18px;border-radius:24px;font-size:.82rem;opacity:0;transition:.25s;z-index:60;pointer-events:none}
.toast.show{opacity:1}
details summary{cursor:pointer;font-size:.82rem;font-weight:700;color:var(--green-dark);margin-top:10px}
@media (min-width:561px){body{padding-bottom:0}nav{position:sticky;bottom:auto;top:57px;border-top:none;border-bottom:1px solid var(--line)}}
</style>
<base target="_blank">
</head>
<body>
<header>
  <h1>🧑 Gamawareness254 <span style="font-weight:400;font-size:.85rem">Recovery Tracker</span></h1>
  <div class="sub" id="hdrDate"></div>
</header>

<main>
<!-- ============ TODAY ============ -->
<section class="tab active" id="tab-today">
  <div class="card" id="introCard" style="background:linear-gradient(135deg,#fff4ec,#ffe8d6);border-color:#ffcc99">
    <div style="display:flex;gap:10px">
      <div style="font-size:1.5rem">🧑</div>
      <div>
        <b style="color:var(--green-dark)">Why this tracker exists</b>
        <p style="font-size:.82rem;margin-top:4px;line-height:1.55">Addiction grows in secrecy and chaos β€” this tracker rebuilds structure instead: small daily wins, honest urge logs, and money kept instead of lost. The method comes from people with <b>lived experience of beating gambling</b>, including the founder of Gamawareness254, who used this exact daily scoring system to take back control. One day at a time. <b>Zero bets is the only bet that wins.</b></p>
        <button class="btn ghost" style="margin-top:8px;padding:6px 14px;font-size:.75rem" onclick="hideIntro()">Got it β€” start my day</button>
      </div>
    </div>
  </div>
  <div class="card streak">
    <div class="flame">πŸ”₯</div>
    <div><div class="num" id="streakNum">0</div><div class="lbl">days gamble-free</div></div>
    <button class="gf-btn" id="gfBtn" onclick="toggleGF()">βœ“ Gamble-free today</button>
  </div>

  <button class="sos" onclick="openSOS()">πŸ†˜ URGE RIGHT NOW β€” tap here</button>

  <div class="card">
    <div class="ring-wrap">
      <svg class="ring" width="86" height="86" viewBox="0 0 86 86">
        <circle class="bg" cx="43" cy="43" r="37" fill="none" stroke-width="9"/>
        <circle class="fg" id="ringFg" cx="43" cy="43" r="37" fill="none" stroke-width="9" stroke-dasharray="232.5" stroke-dashoffset="232.5"/>
      </svg>
      <div><div class="ring-txt" id="scoreTxt">0%</div><div class="lbl" style="font-size:.8rem;color:var(--muted)" id="scoreSub">today's discipline score</div></div>
    </div>
  </div>

  <div class="card"><div id="habitList"></div></div>

  <details class="card">
    <summary>βš™οΈ Edit habits (add / remove / rename)</summary>
    <div class="row" style="margin-top:10px">
      <input type="text" id="newHabitName" placeholder="New habit e.g. No betting apps">
      <select id="newHabitGrp"></select>
    </div>
    <button class="btn ghost block" onclick="addHabit()">+ Add habit</button>
    <div id="habitEditor" style="margin-top:12px"></div>
  </details>

  <div class="card" style="font-size:.72rem;color:var(--muted);line-height:1.55">
    <b>βš•οΈ An honest note.</b> Gamawareness254 is a peer-support tool built by people with lived experience of gambling addiction, shared for information and encouragement only. It is <b>not medical advice</b> and not a substitute for professional care. Recovery journeys differ β€” if you feel at risk of harming yourself or others, please reach out to a qualified professional or a local helpline. Asking for help is strength, not failure. You are not alone.
  </div>
</section>

<!-- ============ URGES ============ -->
<section class="tab" id="tab-urges">
  <div class="card">
    <h3>Log an urge</h3>
    <label class="f">Trigger</label>
    <select id="urgeTrigger">
      <option>Stress / anxiety</option><option>Payday / having money</option>
      <option>Boredom</option><option>Loneliness</option><option>Alcohol / nightlife</option>
      <option>Sports event</option><option>Saw betting ad / social media</option><option>Other</option>
    </select>
    <label class="f">Intensity: <b id="urgeIntVal">5</b>/10</label>
    <input type="range" id="urgeInt" min="1" max="10" value="5" style="width:100%">
    <input type="text" id="urgeNote" placeholder="What did you do instead? (optional)">
    <button class="btn block" onclick="logUrge(true)">πŸ’ͺ I resisted it</button>
    <button class="btn danger block" onclick="logUrge(false)">I slipped β€” log it, no shame, learn</button>
  </div>
  <div class="card">
    <h3>History & patterns</h3>
    <div id="urgeSummary" style="font-size:.85rem;margin-bottom:8px"></div>
    <div id="urgeList"></div>
  </div>
</section>

<!-- ============ MONEY ============ -->
<section class="tab" id="tab-money">
  <div class="card" style="text-align:center">
    <h3 style="text-align:left">Money I did NOT gamble</h3>
    <div class="big-num" id="moneyTotal">0</div>
    <div style="font-size:.8rem;color:var(--muted)">total kept in your life</div>
    <div class="row" style="margin-top:12px">
      <input type="number" id="moneyAmt" placeholder="Amount" min="0">
      <input type="text" id="moneyNote" placeholder="Note (e.g. 'wager I skipped')">
    </div>
    <button class="btn block" onclick="addMoney()">+ Add</button>
  </div>
  <div class="card"><h3>This month</h3><div class="big-num" id="moneyMonth">0</div><div id="moneyList"></div></div>
</section>

<!-- ============ STATS ============ -->
<section class="tab" id="tab-stats">
  <div class="card">
    <h3>Daily score β€” last 14 days</h3>
    <div id="chart"></div>
  </div>
  <div class="card">
    <h3>Habit consistency (all time)</h3>
    <div id="consistency"></div>
  </div>
</section>

<!-- ============ SETTINGS ============ -->
<section class="tab" id="tab-settings">
  <div class="card">
    <h3>Accountability partner</h3>
    <label class="f">Name</label><input type="text" id="setPartnerName" placeholder="e.g. my sponsor, brother, friend">
    <label class="f">Phone (one-tap SOS call)</label><input type="tel" id="setPartnerPhone" placeholder="+254...">
    <label class="f">My reasons to quit (one per line)</label>
    <textarea id="setReasons" rows="4"></textarea>
    <button class="btn block" onclick="saveSettings()">Save</button>
  </div>
  <div class="card">
    <h3>Data</h3>
    <button class="btn ghost block" onclick="exportData()">⬇ Export backup (JSON)</button>
    <label class="btn ghost block" style="display:block;text-align:center">⬆ Import backup<input type="file" id="importFile" accept=".json" style="display:none" onchange="importData(event)"></label>
    <button class="btn danger block" onclick="resetAll()">Reset everything</button>
    <p style="font-size:.72rem;color:var(--muted);margin-top:8px">Data is stored only on this device (private, free, works offline). Cloud accounts for Gamawareness254 users can come in v2.</p>
    <p style="font-size:.72rem;color:var(--muted);margin-top:8px;line-height:1.55">βš•οΈ <b>Disclaimer:</b> This app was created by a person with lived experience of gambling addiction and is provided for informational and motivational purposes only. It does not constitute medical, psychological, or professional advice of any kind. Always seek the advice of a qualified professional with any questions about your health or recovery.</p>
  </div>
  <div class="card" style="background:linear-gradient(135deg,#fff4ec,#ffe8d6);border-color:#ffcc99">
    <h3 style="color:var(--green-dark)">🧑 Support Gamawareness254</h3>
    <p style="font-size:.82rem;line-height:1.6;margin-bottom:10px">This app is <b>free β€” and it will always be free</b>. Recovery should never have a price tag. If it has helped you and you <i>choose</i> to support the work, a donation is welcome. It is entirely your choice β€” no pressure, ever.</p>
    <div style="background:#fff;border:1px dashed var(--green);border-radius:10px;padding:10px;margin-bottom:10px">
      <div style="font-size:.75rem;font-weight:700;color:var(--green-dark);margin-bottom:4px">M-PESA Β· DONATE</div>
      <div style="font-size:.85rem;display:flex;justify-content:space-between;align-items:center;padding:3px 0">Paybill: <b>522522</b> <button class="btn ghost" style="padding:3px 10px;font-size:.7rem" onclick="copyTxt('522522')">Copy</button></div>
      <div style="font-size:.85rem;display:flex;justify-content:space-between;align-items:center;padding:3px 0">Account: <b>1267894334</b> <button class="btn ghost" style="padding:3px 10px;font-size:.7rem" onclick="copyTxt('1267894334')">Copy</button></div>
    </div>
    <a href="mailto:info@gamaware.org" style="display:block;font-size:.85rem;color:var(--green-dark);text-decoration:none;padding:6px 0">βœ‰οΈ info@gamaware.org</a>
    <a href="tel:+254773828328" style="display:block;font-size:.85rem;color:var(--green-dark);text-decoration:none;padding:6px 0">πŸ“ž +254 773 828 328</a>
  </div>
</section>
</main>

<!-- ============ SOS OVERLAY ============ -->
<div id="sosOverlay">
  <button class="btn" style="background:#202925;border:1px solid #33413a" onclick="closeSOS()">← Back</button>
  <h2 style="margin:16px 0 4px">This urge will pass. It always does.</h2>
  <p style="opacity:.7;font-size:.85rem">Average urge fades in ~15–20 minutes if you don't feed it.</p>
  <div id="breathCircle">Breathe</div>
  <div id="breathPhase">Tap circle to start breathing</div>
  <a class="btn block" id="callBtn" style="text-align:center;text-decoration:none;background:#2ea383;display:none">πŸ“ž Call my accountability partner</a>
  <h3 style="margin:18px 0 8px">Why I quit</h3>
  <div id="reasonsList"></div>
  <button class="btn ghost block" onclick="logUrge(true);closeSOS()" style="border-color:#ff6600;color:#ffb380">Urge survived β€” log it πŸ’ͺ</button>
</div>

<nav>
  <button class="active" data-tab="today"><span class="ic">βœ…</span>Today</button>
  <button data-tab="urges"><span class="ic">🌊</span>Urges</button>
  <button data-tab="money"><span class="ic">πŸ’°</span>Money</button>
  <button data-tab="stats"><span class="ic">πŸ“Š</span>Stats</button>
  <button data-tab="settings"><span class="ic">βš™οΈ</span>More</button>
</nav>
<div class="toast" id="toast"></div>

<script>
const LS='gamaware_v1';
const DEFAULT_HABITS=[
 {id:'h1',n:'Woke up at my set time',g:'Morning'},
 {id:'h2',n:'Exercise or moved my body',g:'Morning'},
 {id:'h3',n:'Cold shower or bath',g:'Morning'},
 {id:'h4',n:'Quiet time β€” prayer, meditation or reflection',g:'Morning'},
 {id:'h5',n:'Breakfast',g:'Food & Body'},
 {id:'h6',n:'Lunch',g:'Food & Body'},
 {id:'h7',n:'Supper',g:'Food & Body'},
 {id:'h8',n:'Fruit or vegetables',g:'Food & Body'},
 {id:'h9',n:'Drank enough water',g:'Food & Body'},
 {id:'h20',n:'In bed by my set time',g:'Food & Body'},
 {id:'h10',n:'Learned something new (course, skill, study)',g:'Growth'},
 {id:'h11',n:'Read (book or articles)',g:'Growth'},
 {id:'h16',n:'Journaled, spoke or wrote about my day',g:'Growth'},
 {id:'h12',n:'Replied to messages promptly',g:'Connection'},
 {id:'h13',n:'Called someone I care about',g:'Connection'},
 {id:'h14',n:'Time outdoors or with people',g:'Connection'},
 {id:'h15',n:'One step toward my goals (apply, build, plan)',g:'Connection'},
 {id:'h17',n:'Chores done / space tidy',g:'Discipline'},
 {id:'h18',n:'Avoided or blocked a trigger (ad, site, place, invite)',g:'Discipline'},
 {id:'h19',n:'Gamble-free today β€” no bet placed',g:'Discipline'},
];
const DEFAULT_REASONS=["Gambling took my money, my time and my peace β€” I want them back.","One bet always leads to ten. Zero is the only number that works.","Every gamble-free day, my future gets bigger and my chains get lighter.","The people who love me deserve the real me β€” not the betting me."];
let S=load();
function load(){try{const d=JSON.parse(localStorage.getItem(LS));if(d&&d.habits){
  if(!d.habitsV||d.habitsV<2){d.habits=JSON.parse(JSON.stringify(DEFAULT_HABITS));d.habitsV=2;localStorage.setItem(LS,JSON.stringify(d));}
  return d}}catch(e){}
 return {habits:JSON.parse(JSON.stringify(DEFAULT_HABITS)),habitsV:2,days:{},urges:[],money:[],settings:{partnerName:'',partnerPhone:'',reasons:DEFAULT_REASONS}};}
function save(){localStorage.setItem(LS,JSON.stringify(S));}
function dkey(d){d=d||new Date();return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');}
function day(k){if(!S.days[k])S.days[k]={done:{},notes:{},gf:null};return S.days[k];}
function toast(m){const t=document.getElementById('toast');t.textContent=m;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),1800);}
/* ---- TODAY ---- */
function toggleGF(){const k=dkey(),r=day(k);r.gf=!r.gf;
 if(r.gf===true)r.done['h19']=true;else delete r.done['h19'];save();renderToday();}
function toggleHabit(id){const k=dkey(),r=day(k);r.done[id]=!r.done[id];if(!r.done[id])delete r.done[id];
 if(id==='h19')r.gf=r.done[id]?true:null;save();renderToday();}
function setNote(id,v){day(dkey()).notes[id]=v;save();}
function score(k){const r=S.days[k];if(!r)return null;const done=S.habits.filter(h=>r.done[h.id]).length;return Math.round(done/S.habits.length*100);}
function streak(){let n=0,d=new Date();
 if(S.days[dkey(d)]&&S.days[dkey(d)].gf===true){n++;}else{d.setDate(d.getDate()-1);}
 while(S.days[dkey(d)]&&S.days[dkey(d)].gf===true){n++;d.setDate(d.getDate()-1);}
 return n;}
function renderToday(){
 const k=dkey(),r=day(k);
 document.getElementById('streakNum').textContent=streak();
 const gf=document.getElementById('gfBtn');
 if(r.gf===true){gf.classList.add('done');gf.textContent='βœ“ Gamble-free!';}
 else if(r.gf===false){gf.classList.remove('done');gf.textContent='Slipped β€” log in Urges';}
 else{gf.classList.remove('done');gf.textContent='βœ“ Gamble-free today';}
 const sc=score(k);const C=232.5;
 document.getElementById('ringFg').style.strokeDashoffset=C-(C*sc/100);
 document.getElementById('scoreTxt').textContent=sc+'%';
 document.getElementById('scoreSub').textContent=Object.keys(r.done).length+' of '+S.habits.length+' habits';
 const groups=[...new Set(S.habits.map(h=>h.g))];
 document.getElementById('habitList').innerHTML=groups.map(g=>
  '<div class="grp"><div class="grp-title">'+g+'</div>'+
  S.habits.filter(h=>h.g===g).map(h=>
   '<div class="habit '+(r.done[h.id]?'done':'')+'" onclick="toggleHabit(\''+h.id+'\')">'+
   '<div class="box">'+(r.done[h.id]?'βœ“':'')+'</div>'+
   '<div class="name">'+esc(h.n)+'</div>'+
   '<input type="text" class="note" placeholder="note…" value="'+esc(r.notes[h.id]||'')+'" onclick="event.stopPropagation()" onchange="setNote(\''+h.id+'\',this.value)">'+
   '</div>').join('')+'</div>').join('');
 document.getElementById('habitEditor').innerHTML=S.habits.map(h=>
  '<div class="habit"><div class="name" style="font-size:.82rem">'+esc(h.n)+' <span style="color:var(--muted)">('+esc(h.g)+')</span></div>'+
  '<button class="btn danger" style="padding:5px 10px;font-size:.72rem" onclick="delHabit(\''+h.id+'\')">βœ•</button></div>').join('');
 document.getElementById('newHabitGrp').innerHTML=groups.map(g=>'<option>'+g+'</option>').join('');
}
function addHabit(){const n=document.getElementById('newHabitName').value.trim();if(!n)return toast('Type a habit name');
 S.habits.push({id:'h'+Date.now(),n,g:document.getElementById('newHabitGrp').value});
 document.getElementById('newHabitName').value='';save();renderToday();}
function delHabit(id){S.habits=S.habits.filter(h=>h.id!==id);save();renderToday();}
/* ---- URGES ---- */
document.getElementById('urgeInt').oninput=e=>document.getElementById('urgeIntVal').textContent=e.target.value;
function logUrge(resisted){const t=document.getElementById('urgeTrigger').value,int=document.getElementById('urgeInt').value,
 note=document.getElementById('urgeNote').value.trim();
 S.urges.unshift({ts:Date.now(),trigger:t,intensity:+int,note,resisted});
 if(!resisted){const k=dkey();day(k).gf=false;save();renderToday();}
 document.getElementById('urgeNote').value='';save();renderUrges();toast(resisted?'Logged β€” you beat it πŸ’ͺ':'Logged. Learn the trigger, move on.');}
function renderUrges(){const u=S.urges;
 const resisted=u.filter(x=>x.resisted).length;
 document.getElementById('urgeSummary').innerHTML=u.length?
  '<b>'+u.length+'</b> urges logged Β· <b style="color:var(--green-dark)">'+resisted+' resisted</b> Β· '+(u.length?Math.round(resisted/u.length*100):0)+'% win rate':'';
 document.getElementById('urgeList').innerHTML=u.length?u.slice(0,40).map(x=>
  '<div class="log-item"><span class="pill '+(x.resisted?'':'red')+'">'+(x.resisted?'resisted':'slip')+'</span> '+
  '<b>'+x.trigger+'</b> Β· intensity '+x.intensity+'/10'+(x.note?'<br>πŸ“ '+esc(x.note):'')+
  '<div class="meta">'+new Date(x.ts).toLocaleString()+'</div></div>').join(''):'<div class="empty">No urges logged yet. Logging them is how you spot your patterns.</div>';}
/* ---- MONEY ---- */
function fmt(n){return n.toLocaleString();}
function addMoney(){const a=parseFloat(document.getElementById('moneyAmt').value);
 if(!a||a<=0)return toast('Enter an amount');
 S.money.unshift({ts:Date.now(),amt:a,note:document.getElementById('moneyNote').value.trim()||'kept'});
 document.getElementById('moneyAmt').value='';document.getElementById('moneyNote').value='';save();renderMoney();toast('Money kept in your life πŸ’š');}
function renderMoney(){const tot=S.money.reduce((s,m)=>s+m.amt,0);
 document.getElementById('moneyTotal').textContent=fmt(tot);
 const mk=dkey().slice(0,7);
 document.getElementById('moneyMonth').textContent=fmt(S.money.filter(m=>dkey(new Date(m.ts)).slice(0,7)===mk).reduce((s,m)=>s+m.amt,0));
 document.getElementById('moneyList').innerHTML=S.money.length?S.money.slice(0,20).map(m=>
  '<div class="log-item">πŸ’° <b>'+fmt(m.amt)+'</b> β€” '+esc(m.note)+'<div class="meta">'+new Date(m.ts).toLocaleDateString()+'</div></div>').join(''):'<div class="empty">Every amount you don\u2019t gamble counts. Log it here.</div>';}
/* ---- STATS ---- */
function renderStats(){const keys=Object.keys(S.days).sort();
 const last14=[];for(let i=13;i>=0;i--){const d=new Date();d.setDate(d.getDate()-i);const s=score(dkey(d));
  if(s!==null)last14.push({k:dkey(d).slice(5),s});}
 const W=Math.min(520,last14.length*38);
 document.getElementById('chart').innerHTML=last14.length?'<svg width="100%" viewBox="0 0 '+Math.max(W,300)+' 120">'+
  last14.map((d,i)=>{const x=i*(Math.max(W,300)/Math.max(last14.length,1))+6;const h=d.s*1.0;
   return '<rect x="'+x+'" y="'+(105-h)+'" width="20" height="'+h+'" rx="4" fill="'+(d.s>=70?'var(--green)':d.s>=40?'#d9a441':'var(--red)')+'"/>'+
   '<text x="'+(x+10)+'" y="117" font-size="8" text-anchor="middle" fill="var(--muted)">'+d.k+'</text>';}).join('')+'</svg>':
  '<div class="empty">Complete a day to see your chart.</div>';
 const daysWith=keys.filter(k=>Object.keys(S.days[k].done||{}).length>0);
 document.getElementById('consistency').innerHTML=daysWith.length?S.habits.map(h=>{
  const done=daysWith.filter(k=>S.days[k].done[h.id]).length;const pct=Math.round(done/Math.max(daysWith.length,1)*100);
  return '<div class="bar-row"><div class="lbl" title="'+esc(h.n)+'">'+esc(h.n)+'</div><div class="track"><div class="fill" style="width:'+pct+'%"></div></div><div class="pct">'+pct+'</div></div>';}).join(''):
  '<div class="empty">Your per-habit consistency appears here β€” like the summary column in your sheet.</div>';}
/* ---- SETTINGS ---- */
function fillSettings(){document.getElementById('setPartnerName').value=S.settings.partnerName;
 document.getElementById('setPartnerPhone').value=S.settings.partnerPhone;
 document.getElementById('setReasons').value=(S.settings.reasons||[]).join('\n');}
function saveSettings(){S.settings.partnerName=document.getElementById('setPartnerName').value.trim();
 S.settings.partnerPhone=document.getElementById('setPartnerPhone').value.trim();
 S.settings.reasons=document.getElementById('setReasons').value.split('\n').map(s=>s.trim()).filter(Boolean);
 save();toast('Saved');}
function exportData(){const b=new Blob([JSON.stringify(S,null,2)],{type:'application/json'});
 const a=document.createElement('a');a.href=URL.createObjectURL(b);a.download='gamaware-backup-'+dkey()+'.json';a.click();}
function importData(e){const f=e.target.files[0];if(!f)return;const r=new FileReader();
 r.onload=()=>{try{S=JSON.parse(r.result);save();renderAll();toast('Backup restored');}catch(err){toast('Invalid file');}};r.readAsText(f);}
function resetAll(){if(confirm('Delete ALL data on this device?')){localStorage.removeItem(LS);location.reload();}}
/* ---- SOS ---- */
let breathTimer=null,phaseIdx=0;
const PHASES=[['Breathe in',4,1.5],['Hold',4,1.5],['Breathe out',6,1]];
function openSOS(){document.getElementById('sosOverlay').classList.add('open');
 const p=S.settings;const cb=document.getElementById('callBtn');
 if(p.partnerPhone){cb.style.display='block';cb.href='tel:'+p.partnerPhone.replace(/\s/g,'');
  cb.textContent='πŸ“ž Call '+(p.partnerName||'my accountability partner');}else cb.style.display='none';
 document.getElementById('reasonsList').innerHTML=(p.reasons||DEFAULT_REASONS).map(r=>'<div class="reason">'+esc(r)+'</div>').join('');}
function closeSOS(){document.getElementById('sosOverlay').classList.remove('open');stopBreath();}
function stopBreath(){clearTimeout(breathTimer);document.getElementById('breathPhase').textContent='Tap circle to start breathing';
 const c=document.getElementById('breathCircle');c.style.transform='scale(1)';}
document.getElementById('breathCircle').onclick=function(){stopBreath();
 (function cycle(){const[txt,dur,scale]=PHASES[phaseIdx%3];phaseIdx++;
  const c=document.getElementById('breathCircle');
  document.getElementById('breathPhase').textContent=txt+'… '+dur+'s';
  c.style.transitionDuration=dur+'s';c.style.transform='scale('+scale+')';
  breathTimer=setTimeout(cycle,dur*1000);})();};
/* ---- NAV ---- */
document.querySelectorAll('nav button').forEach(b=>b.onclick=()=>{
 document.querySelectorAll('nav button').forEach(x=>x.classList.remove('active'));b.classList.add('active');
 document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
 document.getElementById('tab-'+b.dataset.tab).classList.add('active');
 window.scrollTo(0,0);});
function esc(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/"/g,'&quot');}
function hideIntro(){localStorage.setItem('gw_intro','1');document.getElementById('introCard').style.display='none';}
function copyTxt(s){if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(s).then(()=>toast('Copied: '+s)).catch(()=>toast(s));}
 else{const t=document.createElement('textarea');t.value=s;document.body.appendChild(t);t.select();try{document.execCommand('copy');toast('Copied: '+s);}catch(e){toast(s);}document.body.removeChild(t);}}
function renderAll(){renderToday();renderUrges();renderMoney();renderStats();fillSettings();}
document.getElementById('hdrDate').textContent=new Date().toLocaleDateString(undefined,{weekday:'long',year:'numeric',month:'long',day:'numeric'});
if(localStorage.getItem('gw_intro'))document.getElementById('introCard').style.display='none';
renderAll();
</script>
</body>
</html>