Spaces:
Running
Running
Upload index.html
Browse files- index.html +1068 -0
index.html
ADDED
|
@@ -0,0 +1,1068 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8"/>
|
| 5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>
|
| 6 |
+
<title>MoneyQuest — Financial Literacy for Gen Alpha</title>
|
| 7 |
+
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet"/>
|
| 8 |
+
<style>
|
| 9 |
+
:root{
|
| 10 |
+
--sky:#6ECCF5;--sun:#FFD93D;--mint:#4ECDC4;--coral:#FF6B6B;--purple:#A855F7;
|
| 11 |
+
--lime:#95E67A;--pink:#FF85C2;--navy:#0F1E3C;--cream:#FFFEF5;
|
| 12 |
+
--card:#FFFFFF;--border:rgba(15,30,60,.1);
|
| 13 |
+
--sh:0 4px 20px rgba(15,30,60,.1);--sh2:0 2px 10px rgba(15,30,60,.07);
|
| 14 |
+
--r:18px;--r2:14px;--r3:10px;
|
| 15 |
+
--font:'Nunito',sans-serif;
|
| 16 |
+
}
|
| 17 |
+
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
|
| 18 |
+
html,body{font-family:var(--font);background:var(--cream);color:var(--navy);min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased}
|
| 19 |
+
|
| 20 |
+
/* ── ANIMATIONS ── */
|
| 21 |
+
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
|
| 22 |
+
@keyframes pop{0%{transform:scale(.8);opacity:0}70%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}
|
| 23 |
+
@keyframes slideUp{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
| 24 |
+
@keyframes spin{to{transform:rotate(360deg)}}
|
| 25 |
+
@keyframes confetti{0%{transform:translateY(-10px) rotate(0deg);opacity:1}100%{transform:translateY(90px) rotate(360deg);opacity:0}}
|
| 26 |
+
@keyframes pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
|
| 27 |
+
@keyframes bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
|
| 28 |
+
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
|
| 29 |
+
@keyframes typingBounce{0%,80%,100%{transform:translateY(0)}40%{transform:translateY(-6px)}}
|
| 30 |
+
|
| 31 |
+
/* ── SCREENS ── */
|
| 32 |
+
.screen{display:none;min-height:100vh;flex-direction:column}
|
| 33 |
+
.screen.active{display:flex}
|
| 34 |
+
|
| 35 |
+
/* ══ WELCOME ══ */
|
| 36 |
+
#screen-welcome{
|
| 37 |
+
background:linear-gradient(160deg,#7C3AED 0%,#2563EB 50%,#0EA5E9 100%);
|
| 38 |
+
align-items:center;justify-content:center;text-align:center;
|
| 39 |
+
padding:40px 24px;position:relative;overflow:hidden;
|
| 40 |
+
}
|
| 41 |
+
.wb{position:absolute;border-radius:50%;filter:blur(80px);opacity:.25;pointer-events:none;animation:float 6s ease-in-out infinite}
|
| 42 |
+
.wb1{width:320px;height:320px;background:#FFD93D;top:-120px;right:-80px}
|
| 43 |
+
.wb2{width:240px;height:240px;background:#4ECDC4;bottom:-80px;left:-60px;animation-delay:3s}
|
| 44 |
+
.wl-wrap{position:relative;z-index:2;width:100%;max-width:340px}
|
| 45 |
+
.logo-emoji{font-size:80px;display:block;animation:float 3s ease-in-out infinite;filter:drop-shadow(0 8px 20px rgba(0,0,0,.25));margin-bottom:8px}
|
| 46 |
+
.logo-name{font-size:40px;font-weight:900;color:#fff;letter-spacing:-1px}
|
| 47 |
+
.logo-tag{font-size:15px;font-weight:700;color:rgba(255,255,255,.8);margin-top:4px;margin-bottom:28px}
|
| 48 |
+
.wl-pills{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-bottom:32px}
|
| 49 |
+
.wpill{background:rgba(255,255,255,.18);border:1.5px solid rgba(255,255,255,.3);border-radius:50px;padding:8px 16px;font-size:13px;font-weight:800;color:#fff}
|
| 50 |
+
.wl-btn{display:block;width:100%;padding:17px;border-radius:50px;border:none;font-size:17px;font-weight:900;cursor:pointer;transition:transform .15s,box-shadow .15s;margin-bottom:12px;letter-spacing:-.2px}
|
| 51 |
+
.wl-btn:active{transform:scale(.97)}
|
| 52 |
+
.wl-btn-main{background:#fff;color:#7C3AED;box-shadow:0 6px 24px rgba(0,0,0,.25)}
|
| 53 |
+
.wl-btn-sec{background:rgba(255,255,255,.15);color:#fff;border:2px solid rgba(255,255,255,.35)}
|
| 54 |
+
.wl-btn-par{background:#0F1E3C;color:#fff;font-size:15px;padding:14px}
|
| 55 |
+
.wl-powered{margin-top:20px;font-size:11px;font-weight:700;color:rgba(255,255,255,.6);letter-spacing:.5px}
|
| 56 |
+
.wl-powered span{color:#FFD93D}
|
| 57 |
+
|
| 58 |
+
/* ══ ONBOARD ══ */
|
| 59 |
+
#screen-onboard{background:var(--cream);padding:0}
|
| 60 |
+
.ob-inner{padding:20px 22px 32px;max-width:480px;margin:0 auto;width:100%}
|
| 61 |
+
.ob-back{background:none;border:none;font-size:14px;font-weight:800;color:rgba(15,30,60,.5);cursor:pointer;padding:4px 0;margin-bottom:14px;display:flex;align-items:center;gap:5px}
|
| 62 |
+
.dots-row{display:flex;gap:6px;justify-content:center;margin-bottom:24px}
|
| 63 |
+
.dot{width:8px;height:8px;border-radius:50%;background:rgba(15,30,60,.15);transition:all .3s}
|
| 64 |
+
.dot.done{background:var(--purple);width:22px;border-radius:4px}
|
| 65 |
+
.dot.active{background:var(--purple);transform:scale(1.3)}
|
| 66 |
+
.ob-hero{text-align:center;margin-bottom:24px}
|
| 67 |
+
.ob-big-emoji{font-size:64px;display:block;animation:float 3s ease-in-out infinite;margin-bottom:10px}
|
| 68 |
+
.ob-title{font-size:26px;font-weight:900;color:var(--navy);line-height:1.2}
|
| 69 |
+
.ob-sub{font-size:14px;color:rgba(15,30,60,.55);margin-top:7px;line-height:1.5}
|
| 70 |
+
.step{display:none}
|
| 71 |
+
.step.active{display:block;animation:slideUp .35s ease}
|
| 72 |
+
.av-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:14px 0}
|
| 73 |
+
.av-opt{padding:12px 6px;background:var(--card);border:2.5px solid transparent;border-radius:var(--r2);text-align:center;cursor:pointer;transition:all .2s;box-shadow:var(--sh2)}
|
| 74 |
+
.av-opt:active{transform:scale(.94)}
|
| 75 |
+
.av-opt.sel{border-color:var(--purple);background:rgba(168,85,247,.08)}
|
| 76 |
+
.av-em{font-size:30px;display:block;margin-bottom:3px}
|
| 77 |
+
.av-nm{font-size:10px;font-weight:800;color:var(--navy)}
|
| 78 |
+
.name-in{width:100%;padding:15px 20px;background:var(--card);border:2.5px solid var(--border);border-radius:50px;font-size:18px;font-weight:700;color:var(--navy);margin:12px 0;text-align:center;font-family:var(--font)}
|
| 79 |
+
.name-in:focus{outline:none;border-color:var(--purple)}
|
| 80 |
+
.age-big{font-size:62px;font-weight:900;color:var(--purple);text-align:center;line-height:1}
|
| 81 |
+
.age-sub{text-align:center;font-size:13px;font-weight:700;color:rgba(15,30,60,.45);margin-top:3px;margin-bottom:14px}
|
| 82 |
+
input[type=range]{width:100%;-webkit-appearance:none;height:8px;border-radius:4px;background:rgba(168,85,247,.2);outline:none;margin:10px 0}
|
| 83 |
+
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:30px;height:30px;border-radius:50%;background:var(--purple);cursor:pointer;box-shadow:0 3px 10px rgba(168,85,247,.4);border:3px solid #fff}
|
| 84 |
+
.goal-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:14px 0}
|
| 85 |
+
.gc{padding:15px 10px;background:var(--card);border:2.5px solid transparent;border-radius:var(--r2);text-align:center;cursor:pointer;transition:all .2s;box-shadow:var(--sh2)}
|
| 86 |
+
.gc:active{transform:scale(.95)}
|
| 87 |
+
.gc.sel{border-color:var(--sun);background:rgba(255,217,61,.08)}
|
| 88 |
+
.gc-icon{font-size:34px;display:block;margin-bottom:5px}
|
| 89 |
+
.gc-name{font-size:13px;font-weight:800;color:var(--navy)}
|
| 90 |
+
.gc-desc{font-size:10px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 91 |
+
.cash-hero{text-align:center;margin:16px 0}
|
| 92 |
+
.cash-em{font-size:56px;display:block;animation:bounce 2s infinite;margin-bottom:8px}
|
| 93 |
+
.cash-num{font-size:52px;font-weight:900;color:var(--mint);line-height:1}
|
| 94 |
+
.cash-lbl{font-size:13px;color:rgba(15,30,60,.5);font-weight:600;margin-top:4px}
|
| 95 |
+
.fact-box{background:rgba(78,205,196,.1);border:2px solid rgba(78,205,196,.3);border-radius:var(--r2);padding:14px;margin:14px 0;font-size:13px;font-weight:700;color:var(--navy);line-height:1.6}
|
| 96 |
+
.btn-cta{width:100%;padding:17px;border:none;border-radius:50px;font-size:17px;font-weight:900;cursor:pointer;margin-top:14px;font-family:var(--font);transition:transform .15s,box-shadow .15s}
|
| 97 |
+
.btn-cta:active{transform:scale(.97)}
|
| 98 |
+
.btn-purple{background:var(--purple);color:#fff;box-shadow:0 5px 18px rgba(168,85,247,.4)}
|
| 99 |
+
.btn-mint{background:var(--mint);color:#fff;box-shadow:0 5px 18px rgba(78,205,196,.4)}
|
| 100 |
+
|
| 101 |
+
/* ══ APP HEADER ══ */
|
| 102 |
+
.app-hdr{background:linear-gradient(135deg,var(--purple) 0%,var(--sky) 100%);padding:20px 18px 52px;position:relative;overflow:hidden}
|
| 103 |
+
.app-hdr::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:38px;background:var(--cream);border-radius:38px 38px 0 0}
|
| 104 |
+
.hdr-top{display:flex;align-items:center;justify-content:space-between}
|
| 105 |
+
.hdr-greet{color:rgba(255,255,255,.75);font-size:12px;font-weight:700}
|
| 106 |
+
.hdr-name{color:#fff;font-size:20px;font-weight:900}
|
| 107 |
+
.hdr-av{width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;font-size:24px;border:2px solid rgba(255,255,255,.35);cursor:pointer;flex-shrink:0}
|
| 108 |
+
.nw-card{background:rgba(255,255,255,.16);backdrop-filter:blur(8px);border:1.5px solid rgba(255,255,255,.22);border-radius:var(--r);padding:18px;margin-top:14px;position:relative;z-index:1}
|
| 109 |
+
.nw-lbl{font-size:11px;font-weight:700;color:rgba(255,255,255,.65);letter-spacing:.5px;text-transform:uppercase}
|
| 110 |
+
.nw-amt{font-size:42px;font-weight:900;color:#fff;line-height:1;margin:3px 0}
|
| 111 |
+
.nw-ch{font-size:13px;font-weight:700}
|
| 112 |
+
.nw-ch.pos{color:#95E67A}.nw-ch.neg{color:#FF6B6B}
|
| 113 |
+
.xp-wrap{margin-top:12px}
|
| 114 |
+
.xp-row{display:flex;justify-content:space-between;font-size:11px;font-weight:700;color:rgba(255,255,255,.65);margin-bottom:5px}
|
| 115 |
+
.xp-bar{height:8px;background:rgba(255,255,255,.18);border-radius:4px;overflow:hidden}
|
| 116 |
+
.xp-fill{height:100%;background:var(--sun);border-radius:4px;transition:width .8s ease}
|
| 117 |
+
|
| 118 |
+
/* ══ APP BODY ══ */
|
| 119 |
+
.app-body{padding:0 16px 100px}
|
| 120 |
+
.stats3{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin:14px 0}
|
| 121 |
+
.sc{background:var(--card);border-radius:var(--r2);padding:13px 10px;text-align:center;box-shadow:var(--sh2)}
|
| 122 |
+
.sc-icon{font-size:22px;display:block;margin-bottom:3px}
|
| 123 |
+
.sc-val{font-size:16px;font-weight:900}
|
| 124 |
+
.sc-lbl{font-size:10px;font-weight:700;color:rgba(15,30,60,.4);text-transform:uppercase;letter-spacing:.3px;margin-top:2px}
|
| 125 |
+
.sec-row{display:flex;align-items:center;justify-content:space-between;margin:18px 0 10px}
|
| 126 |
+
.sec-title{font-size:17px;font-weight:900}
|
| 127 |
+
.sec-link{font-size:13px;font-weight:800;color:var(--purple);background:rgba(168,85,247,.1);padding:4px 12px;border-radius:50px;border:none;cursor:pointer;font-family:var(--font)}
|
| 128 |
+
.sec-link:active{transform:scale(.95)}
|
| 129 |
+
.goal-banner{background:var(--card);border-radius:var(--r);padding:15px;display:flex;align-items:center;gap:12px;box-shadow:var(--sh);cursor:pointer;border:2px solid transparent;transition:border-color .2s;margin-bottom:10px}
|
| 130 |
+
.gb-icon{font-size:38px;flex-shrink:0}
|
| 131 |
+
.gb-body{flex:1;min-width:0}
|
| 132 |
+
.gb-name{font-size:15px;font-weight:800}
|
| 133 |
+
.gb-sub{font-size:11px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 134 |
+
.gb-bar{height:9px;background:rgba(15,30,60,.08);border-radius:5px;overflow:hidden;margin-top:7px}
|
| 135 |
+
.gb-fill{height:100%;border-radius:5px;background:linear-gradient(90deg,var(--sun),var(--coral));transition:width 1s ease}
|
| 136 |
+
.gb-pct{font-size:11px;font-weight:800;color:var(--coral);margin-top:3px}
|
| 137 |
+
.act-grid{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:0 0 14px}
|
| 138 |
+
.act{background:var(--card);border-radius:var(--r2);padding:15px 12px;text-align:center;cursor:pointer;box-shadow:var(--sh2);border:2px solid transparent;transition:transform .15s,border-color .2s;-webkit-tap-highlight-color:transparent}
|
| 139 |
+
.act:active{transform:scale(.95)}
|
| 140 |
+
.act-s{border-color:rgba(78,205,196,.4);background:rgba(78,205,196,.06)}
|
| 141 |
+
.act-i{border-color:rgba(168,85,247,.4);background:rgba(168,85,247,.06)}
|
| 142 |
+
.act-g{border-color:rgba(255,217,61,.4);background:rgba(255,217,61,.06)}
|
| 143 |
+
.act-a{border-color:rgba(255,107,107,.4);background:rgba(255,107,107,.06)}
|
| 144 |
+
.act-ic{font-size:28px;display:block;margin-bottom:5px}
|
| 145 |
+
.act-nm{font-size:13px;font-weight:800}
|
| 146 |
+
.act-sb{font-size:10px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 147 |
+
.port-grid{display:flex;flex-direction:column;gap:9px}
|
| 148 |
+
.asset-card{background:var(--card);border-radius:var(--r2);padding:13px 15px;display:flex;align-items:center;gap:12px;box-shadow:var(--sh2);cursor:pointer;border:2px solid transparent;transition:transform .15s,border-color .2s}
|
| 149 |
+
.asset-card:active{transform:scale(.98)}
|
| 150 |
+
.asset-ic{font-size:30px;width:46px;height:46px;display:flex;align-items:center;justify-content:center;background:rgba(15,30,60,.04);border-radius:12px;flex-shrink:0}
|
| 151 |
+
.asset-inf{flex:1;min-width:0}
|
| 152 |
+
.asset-nm{font-size:14px;font-weight:800}
|
| 153 |
+
.asset-ds{font-size:11px;color:rgba(15,30,60,.5);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
| 154 |
+
.asset-rt{text-align:right}
|
| 155 |
+
.asset-val{font-size:16px;font-weight:900}
|
| 156 |
+
.asset-ch{font-size:11px;font-weight:700;margin-top:2px}
|
| 157 |
+
.chg-p{color:var(--mint)}.chg-n{color:var(--coral)}
|
| 158 |
+
.ai-card{background:linear-gradient(135deg,var(--purple),var(--sky));border-radius:var(--r);padding:15px;margin:0 0 14px;cursor:pointer;box-shadow:0 6px 22px rgba(168,85,247,.28);transition:transform .15s}
|
| 159 |
+
.ai-card:active{transform:scale(.98)}
|
| 160 |
+
.ai-top{display:flex;align-items:center;gap:10px;margin-bottom:10px}
|
| 161 |
+
.ai-av{width:40px;height:40px;background:rgba(255,255,255,.2);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:20px;border:2px solid rgba(255,255,255,.35);animation:pulse 3s infinite}
|
| 162 |
+
.ai-nm{font-size:13px;font-weight:800;color:#fff}
|
| 163 |
+
.ai-st{font-size:11px;color:rgba(255,255,255,.65)}
|
| 164 |
+
.ai-bubble{background:rgba(255,255,255,.15);border-radius:12px 12px 12px 4px;padding:11px 13px;font-size:13px;font-weight:600;color:#fff;line-height:1.55}
|
| 165 |
+
.typing-dots{display:flex;gap:4px;align-items:center}
|
| 166 |
+
.td{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.65)}
|
| 167 |
+
.td:nth-child(1){animation:typingBounce .9s infinite 0s}
|
| 168 |
+
.td:nth-child(2){animation:typingBounce .9s infinite .15s}
|
| 169 |
+
.td:nth-child(3){animation:typingBounce .9s infinite .3s}
|
| 170 |
+
.act-list{display:flex;flex-direction:column;gap:8px}
|
| 171 |
+
.act-item{background:var(--card);border-radius:var(--r3);padding:11px 13px;display:flex;align-items:center;gap:10px;box-shadow:var(--sh2)}
|
| 172 |
+
.ai-ico{font-size:22px;width:38px;height:38px;background:rgba(15,30,60,.04);border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
| 173 |
+
.ai-text{font-size:13px;font-weight:700}
|
| 174 |
+
.ai-time{font-size:10px;color:rgba(15,30,60,.4);margin-top:2px}
|
| 175 |
+
.ai-amt{font-size:13px;font-weight:800;margin-left:auto;flex-shrink:0}
|
| 176 |
+
.empty-state{background:var(--card);border-radius:var(--r2);padding:20px;text-align:center;color:rgba(15,30,60,.4);font-weight:600;font-size:13px;border:2px dashed rgba(15,30,60,.1)}
|
| 177 |
+
|
| 178 |
+
/* ══ LEARN ══ */
|
| 179 |
+
#screen-learn{background:var(--cream);padding-bottom:90px}
|
| 180 |
+
.learn-hdr{background:linear-gradient(135deg,#F59E0B 0%,#EF4444 100%);padding:20px 18px 52px;position:relative}
|
| 181 |
+
.learn-hdr::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:38px;background:var(--cream);border-radius:38px 38px 0 0}
|
| 182 |
+
.screen-body{padding:0 16px}
|
| 183 |
+
.lesson-grid{display:flex;flex-direction:column;gap:10px;margin:14px 0}
|
| 184 |
+
.lcard{background:var(--card);border-radius:var(--r);padding:15px;display:flex;align-items:center;gap:13px;box-shadow:var(--sh);cursor:pointer;transition:transform .15s,border-color .2s;border:2px solid transparent}
|
| 185 |
+
.lcard:active{transform:scale(.98)}
|
| 186 |
+
.lcard.done{border-color:rgba(78,205,196,.4);background:rgba(78,205,196,.04)}
|
| 187 |
+
.lcard.locked{opacity:.5;cursor:not-allowed}
|
| 188 |
+
.lbadge{width:50px;height:50px;border-radius:var(--r2);display:flex;align-items:center;justify-content:center;font-size:26px;flex-shrink:0;background:rgba(168,85,247,.1)}
|
| 189 |
+
.lcard.done .lbadge{background:rgba(78,205,196,.15)}
|
| 190 |
+
.linfo{flex:1}
|
| 191 |
+
.ltitle{font-size:14px;font-weight:800}
|
| 192 |
+
.lsub{font-size:11px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 193 |
+
.lxp{font-size:11px;font-weight:800;color:var(--purple);background:rgba(168,85,247,.1);padding:2px 8px;border-radius:20px;display:inline-block;margin-top:4px}
|
| 194 |
+
.lstatus{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0;background:rgba(15,30,60,.05)}
|
| 195 |
+
|
| 196 |
+
/* ══ GOALS ══ */
|
| 197 |
+
#screen-goals{background:var(--cream);padding-bottom:90px}
|
| 198 |
+
.goals-hdr{background:linear-gradient(135deg,var(--mint) 0%,var(--sky) 100%);padding:20px 18px 52px;position:relative}
|
| 199 |
+
.goals-hdr::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:38px;background:var(--cream);border-radius:38px 38px 0 0}
|
| 200 |
+
.gcard{background:var(--card);border-radius:var(--r);padding:18px;box-shadow:var(--sh);margin:0 0 12px;animation:pop .4s ease}
|
| 201 |
+
.gcard-top{display:flex;align-items:center;gap:12px;margin-bottom:14px}
|
| 202 |
+
.gcard-icon{font-size:44px}
|
| 203 |
+
.gcard-title{font-size:19px;font-weight:900}
|
| 204 |
+
.gcard-desc{font-size:12px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 205 |
+
.gamts{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin:12px 0}
|
| 206 |
+
.gamt{text-align:center;padding:11px 6px;background:rgba(15,30,60,.04);border-radius:var(--r3)}
|
| 207 |
+
.gamt-val{font-size:17px;font-weight:900}
|
| 208 |
+
.gamt-lbl{font-size:10px;font-weight:700;color:rgba(15,30,60,.4);text-transform:uppercase;margin-top:2px}
|
| 209 |
+
.gbig-bar{height:14px;background:rgba(15,30,60,.08);border-radius:7px;overflow:hidden;margin:6px 0 4px}
|
| 210 |
+
.gbig-fill{height:100%;border-radius:7px;background:linear-gradient(90deg,var(--mint),var(--sky));transition:width 1.2s ease}
|
| 211 |
+
.g-pct{font-size:12px;font-weight:800;color:var(--mint);margin-bottom:10px}
|
| 212 |
+
.contrib-row{display:flex;gap:8px;margin-top:12px}
|
| 213 |
+
.contrib-in{flex:1;padding:13px 15px;background:rgba(15,30,60,.04);border:2px solid transparent;border-radius:50px;font-size:16px;font-weight:700;color:var(--navy);font-family:var(--font)}
|
| 214 |
+
.contrib-in:focus{outline:none;border-color:var(--mint)}
|
| 215 |
+
.btn-add{padding:13px 20px;background:var(--mint);border:none;border-radius:50px;font-size:15px;font-weight:800;color:#fff;cursor:pointer;font-family:var(--font);transition:transform .15s}
|
| 216 |
+
.btn-add:active{transform:scale(.95)}
|
| 217 |
+
.ai-plan-btn{width:100%;padding:14px;background:linear-gradient(135deg,var(--purple),var(--coral));border:none;border-radius:var(--r2);font-size:14px;font-weight:800;color:#fff;cursor:pointer;margin-top:10px;display:flex;align-items:center;justify-content:center;gap:7px;font-family:var(--font);transition:transform .15s}
|
| 218 |
+
.ai-plan-btn:active{transform:scale(.97)}
|
| 219 |
+
.add-goal-btn{width:100%;padding:17px;background:transparent;border:2.5px dashed rgba(15,30,60,.2);border-radius:var(--r);font-size:16px;font-weight:800;color:rgba(15,30,60,.4);cursor:pointer;margin-top:4px;font-family:var(--font);transition:all .2s}
|
| 220 |
+
.add-goal-btn:hover,.add-goal-btn:active{border-color:var(--purple);color:var(--purple)}
|
| 221 |
+
|
| 222 |
+
/* ══ AI SCREEN ══ */
|
| 223 |
+
#screen-ai{background:var(--cream);padding-bottom:90px}
|
| 224 |
+
.ai-hdr{background:linear-gradient(135deg,var(--coral) 0%,var(--purple) 100%);padding:20px 18px 52px;position:relative}
|
| 225 |
+
.ai-hdr::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:38px;background:var(--cream);border-radius:38px 38px 0 0}
|
| 226 |
+
.chat-body{padding:0 16px}
|
| 227 |
+
.chat-msgs{display:flex;flex-direction:column;gap:11px;margin:14px 0}
|
| 228 |
+
.msg{max-width:86%;animation:pop .3s ease}
|
| 229 |
+
.msg-ai{align-self:flex-start}
|
| 230 |
+
.msg-user{align-self:flex-end}
|
| 231 |
+
.msg-hdr{display:flex;align-items:center;gap:6px;margin-bottom:5px}
|
| 232 |
+
.msg-hdr-av{font-size:16px}
|
| 233 |
+
.msg-hdr-nm{font-size:11px;font-weight:800;color:rgba(15,30,60,.4)}
|
| 234 |
+
.bubble{padding:12px 15px;border-radius:18px;font-size:14px;font-weight:600;line-height:1.6}
|
| 235 |
+
.bubble-ai{background:var(--card);color:var(--navy);border-radius:18px 18px 18px 4px;box-shadow:var(--sh2)}
|
| 236 |
+
.bubble-user{background:var(--purple);color:#fff;border-radius:18px 18px 4px 18px}
|
| 237 |
+
.quick-qs{display:flex;flex-wrap:wrap;gap:7px;margin:10px 0}
|
| 238 |
+
.qq{padding:8px 13px;background:var(--card);border:2px solid var(--border);border-radius:50px;font-size:12px;font-weight:700;cursor:pointer;transition:all .2s;box-shadow:var(--sh2);font-family:var(--font)}
|
| 239 |
+
.qq:active{background:rgba(168,85,247,.1);border-color:var(--purple);color:var(--purple)}
|
| 240 |
+
.chat-bar{position:fixed;bottom:70px;left:0;right:0;padding:9px 14px;background:rgba(255,254,245,.97);backdrop-filter:blur(10px);border-top:1px solid var(--border);display:flex;gap:9px;z-index:40}
|
| 241 |
+
.chat-in{flex:1;padding:12px 16px;background:var(--card);border:2px solid var(--border);border-radius:50px;font-size:14px;font-weight:600;color:var(--navy);box-shadow:var(--sh2);transition:border-color .2s;font-family:var(--font)}
|
| 242 |
+
.chat-in:focus{outline:none;border-color:var(--purple)}
|
| 243 |
+
.chat-send{width:44px;height:44px;background:var(--purple);border:none;border-radius:50%;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 3px 12px rgba(168,85,247,.4);flex-shrink:0;transition:transform .15s}
|
| 244 |
+
.chat-send:active{transform:scale(.93)}
|
| 245 |
+
|
| 246 |
+
/* ══ PARENT ══ */
|
| 247 |
+
#screen-parent{background:#080F20;padding-bottom:40px;color:#fff;min-height:100vh}
|
| 248 |
+
.par-hdr{padding:20px 18px 24px;background:linear-gradient(135deg,#0F1E3C,#1a3060)}
|
| 249 |
+
.par-back{background:none;border:none;color:rgba(255,255,255,.6);font-size:14px;font-weight:700;cursor:pointer;padding:0 0 12px;display:flex;align-items:center;gap:5px;font-family:var(--font)}
|
| 250 |
+
.par-title{font-size:24px;font-weight:900;color:#fff}
|
| 251 |
+
.par-sub{font-size:13px;color:rgba(255,255,255,.45);margin-top:3px}
|
| 252 |
+
.par-body{padding:16px}
|
| 253 |
+
.pcard{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:var(--r);padding:18px;margin-bottom:13px}
|
| 254 |
+
.pcard-title{font-size:11px;font-weight:800;color:rgba(255,255,255,.4);text-transform:uppercase;letter-spacing:.5px;margin-bottom:13px}
|
| 255 |
+
.par-ai-card{background:linear-gradient(135deg,rgba(168,85,247,.18),rgba(110,204,245,.1));border:1px solid rgba(168,85,247,.28);border-radius:var(--r);padding:16px;margin-bottom:13px}
|
| 256 |
+
.pai-hdr{display:flex;align-items:center;gap:10px;margin-bottom:10px}
|
| 257 |
+
.pai-title{font-size:15px;font-weight:800;color:#fff}
|
| 258 |
+
.pai-sub{font-size:12px;color:rgba(255,255,255,.45);margin-top:2px}
|
| 259 |
+
.pai-body{font-size:13px;color:rgba(255,255,255,.8);line-height:1.7}
|
| 260 |
+
.lc-bars{display:flex;align-items:flex-end;gap:7px;height:80px;margin-bottom:22px}
|
| 261 |
+
.lc-bar{flex:1;border-radius:4px 4px 0 0;background:linear-gradient(to top,var(--purple),var(--sky));min-height:4px;position:relative;transition:height .8s ease}
|
| 262 |
+
.lc-bar-lbl{position:absolute;bottom:-18px;left:50%;transform:translateX(-50%);font-size:9px;color:rgba(255,255,255,.35);white-space:nowrap}
|
| 263 |
+
.ins-row{display:flex;align-items:center;gap:11px;padding:10px 0;border-bottom:1px solid rgba(255,255,255,.06)}
|
| 264 |
+
.ins-row:last-child{border-bottom:none}
|
| 265 |
+
.ins-ic{font-size:20px;width:36px;height:36px;background:rgba(255,255,255,.07);border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
| 266 |
+
.ins-txt{flex:1;font-size:13px;color:rgba(255,255,255,.75);line-height:1.45}
|
| 267 |
+
.ins-badge{font-size:10px;font-weight:800;padding:3px 9px;border-radius:50px;white-space:nowrap}
|
| 268 |
+
.bg-good{background:rgba(78,205,196,.2);color:var(--mint)}
|
| 269 |
+
.bg-warn{background:rgba(255,217,61,.2);color:var(--sun)}
|
| 270 |
+
.bg-info{background:rgba(168,85,247,.2);color:#C084FC}
|
| 271 |
+
.dt-item{display:flex;gap:11px;padding:9px 0;position:relative}
|
| 272 |
+
.dt-item::before{content:'';position:absolute;left:14px;top:30px;bottom:-9px;width:2px;background:rgba(255,255,255,.08)}
|
| 273 |
+
.dt-item:last-child::before{display:none}
|
| 274 |
+
.dt-dot{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0;border:2px solid transparent}
|
| 275 |
+
.dt-save{background:rgba(78,205,196,.18);border-color:var(--mint)}
|
| 276 |
+
.dt-invest{background:rgba(168,85,247,.18);border-color:var(--purple)}
|
| 277 |
+
.dt-goal{background:rgba(255,217,61,.18);border-color:var(--sun)}
|
| 278 |
+
.dt-text{font-size:13px;color:rgba(255,255,255,.7);line-height:1.5;padding-top:3px}
|
| 279 |
+
.dt-time{font-size:10px;color:rgba(255,255,255,.3);margin-top:2px}
|
| 280 |
+
|
| 281 |
+
/* ══ BOTTOM NAV ══ */
|
| 282 |
+
.bnav{position:fixed;bottom:0;left:0;right:0;z-index:50;background:rgba(255,254,245,.97);backdrop-filter:blur(12px);border-top:1.5px solid var(--border);display:grid;grid-template-columns:repeat(4,1fr);padding:7px 0 max(8px,env(safe-area-inset-bottom))}
|
| 283 |
+
.nb{display:flex;flex-direction:column;align-items:center;gap:2px;background:none;border:none;cursor:pointer;padding:5px 8px;border-radius:var(--r3);transition:all .2s;font-family:var(--font)}
|
| 284 |
+
.nb:active{transform:scale(.93)}
|
| 285 |
+
.nb.on .nb-ic{background:var(--purple);box-shadow:0 3px 10px rgba(168,85,247,.3)}
|
| 286 |
+
.nb.on .nb-lbl{color:var(--purple)}
|
| 287 |
+
.nb-ic{width:36px;height:36px;border-radius:11px;background:transparent;display:flex;align-items:center;justify-content:center;font-size:19px;transition:all .2s}
|
| 288 |
+
.nb-lbl{font-size:10px;font-weight:800;color:rgba(15,30,60,.38);transition:color .2s;letter-spacing:.2px}
|
| 289 |
+
|
| 290 |
+
/* ══ MODALS ══ */
|
| 291 |
+
.mbg{position:fixed;inset:0;background:rgba(15,30,60,.45);backdrop-filter:blur(4px);z-index:100;display:none;align-items:flex-end;justify-content:center}
|
| 292 |
+
.mbg.open{display:flex;animation:fadeIn .2s ease}
|
| 293 |
+
.msheet{background:var(--cream);border-radius:26px 26px 0 0;width:100%;max-width:500px;max-height:88vh;overflow-y:auto;padding:8px 20px 36px}
|
| 294 |
+
.mhandle{width:36px;height:4px;background:rgba(15,30,60,.14);border-radius:2px;margin:12px auto 18px}
|
| 295 |
+
.m-emoji{font-size:60px;text-align:center;display:block;margin:0 auto 14px;animation:float 3s infinite}
|
| 296 |
+
.m-title{font-size:22px;font-weight:900;margin-bottom:5px}
|
| 297 |
+
.m-sub{font-size:14px;color:rgba(15,30,60,.5);margin-bottom:18px;line-height:1.55}
|
| 298 |
+
.amt-row{display:flex;gap:8px;margin:10px 0;flex-wrap:wrap}
|
| 299 |
+
.amt-btn{flex:1;min-width:60px;padding:12px 8px;background:rgba(15,30,60,.05);border:2.5px solid transparent;border-radius:var(--r2);font-size:14px;font-weight:800;cursor:pointer;text-align:center;transition:all .2s;font-family:var(--font)}
|
| 300 |
+
.amt-btn:active{transform:scale(.95)}
|
| 301 |
+
.amt-btn.sel{background:rgba(168,85,247,.1);border-color:var(--purple);color:var(--purple)}
|
| 302 |
+
.btn-confirm{width:100%;padding:16px;background:var(--purple);border:none;border-radius:50px;font-size:17px;font-weight:800;color:#fff;cursor:pointer;margin-top:14px;box-shadow:0 5px 18px rgba(168,85,247,.38);transition:transform .15s,opacity .2s;font-family:var(--font)}
|
| 303 |
+
.btn-confirm:active{transform:scale(.97)}
|
| 304 |
+
.btn-confirm:disabled{opacity:.4;cursor:not-allowed;transform:none}
|
| 305 |
+
.btn-cancel{width:100%;padding:13px;background:none;border:none;font-size:15px;font-weight:700;color:rgba(15,30,60,.38);cursor:pointer;margin-top:6px;font-family:var(--font)}
|
| 306 |
+
.invest-opt{background:var(--card);border-radius:var(--r2);padding:13px 15px;display:flex;align-items:center;gap:11px;box-shadow:var(--sh2);margin-bottom:9px;cursor:pointer;border:2.5px solid transparent;transition:all .2s}
|
| 307 |
+
.invest-opt:active{transform:scale(.98)}
|
| 308 |
+
.invest-opt.sel{border-color:var(--purple);background:rgba(168,85,247,.06)}
|
| 309 |
+
.io-ic{font-size:28px;width:44px;height:44px;background:rgba(15,30,60,.04);border-radius:11px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
| 310 |
+
.io-inf{flex:1}
|
| 311 |
+
.io-nm{font-size:14px;font-weight:800}
|
| 312 |
+
.io-ds{font-size:11px;color:rgba(15,30,60,.5);margin-top:2px}
|
| 313 |
+
.io-risk{font-size:11px;font-weight:700;margin-left:auto;white-space:nowrap}
|
| 314 |
+
.rb-chart{display:flex;height:110px;gap:6px;align-items:flex-end;margin:14px 0}
|
| 315 |
+
.rb-bar{flex:1;border-radius:5px 5px 0 0;position:relative;min-height:6px;transition:height .8s ease}
|
| 316 |
+
.rb-val{position:absolute;top:-18px;left:50%;transform:translateX(-50%);font-size:9px;font-weight:800;white-space:nowrap}
|
| 317 |
+
.rb-lbl{position:absolute;bottom:-18px;left:50%;transform:translateX(-50%);font-size:9px;font-weight:700;color:rgba(15,30,60,.45);white-space:nowrap}
|
| 318 |
+
.rb-suggest{background:rgba(168,85,247,.08);border:2px solid rgba(168,85,247,.2);border-radius:var(--r2);padding:13px;margin:26px 0 10px}
|
| 319 |
+
.rb-suggest-title{font-size:13px;font-weight:800;color:var(--purple);margin-bottom:5px}
|
| 320 |
+
.rb-suggest-text{font-size:13px;line-height:1.6}
|
| 321 |
+
.spin{display:flex;align-items:center;gap:8px;padding:16px 0}
|
| 322 |
+
.spinner{width:28px;height:28px;border:3px solid rgba(168,85,247,.2);border-top-color:var(--purple);border-radius:50%;animation:spin .7s linear infinite;flex-shrink:0}
|
| 323 |
+
.spin-txt{font-size:13px;font-weight:600;color:rgba(15,30,60,.5)}
|
| 324 |
+
|
| 325 |
+
/* ══ CONFETTI ══ */
|
| 326 |
+
#confetti{position:fixed;top:0;left:0;right:0;pointer-events:none;z-index:999;overflow:hidden;height:100vh}
|
| 327 |
+
.cp{position:absolute;border-radius:2px}
|
| 328 |
+
</style>
|
| 329 |
+
</head>
|
| 330 |
+
<body>
|
| 331 |
+
<div id="confetti"></div>
|
| 332 |
+
|
| 333 |
+
<!-- ══ WELCOME ══ -->
|
| 334 |
+
<div class="screen active" id="screen-welcome">
|
| 335 |
+
<div class="wb wb1"></div>
|
| 336 |
+
<div class="wb wb2"></div>
|
| 337 |
+
<div class="wl-wrap">
|
| 338 |
+
<span class="logo-emoji">🚀</span>
|
| 339 |
+
<div class="logo-name">MoneyQuest</div>
|
| 340 |
+
<div class="logo-tag">Your money adventure starts here! 💰</div>
|
| 341 |
+
<div class="wl-pills">
|
| 342 |
+
<span class="wpill">🎮 Fun & Addictive</span>
|
| 343 |
+
<span class="wpill">🤖 K2 AI Mentor</span>
|
| 344 |
+
<span class="wpill">📈 Real Investing</span>
|
| 345 |
+
</div>
|
| 346 |
+
<button class="wl-btn wl-btn-main" onclick="showScreen('screen-onboard')">🎮 Start My Quest!</button>
|
| 347 |
+
<button class="wl-btn wl-btn-sec" onclick="continuePlay()">📱 Continue Playing</button>
|
| 348 |
+
<button class="wl-btn wl-btn-par" onclick="showScreen('screen-parent');loadParentDash()">👨👩👧 Parent Dashboard</button>
|
| 349 |
+
<div class="wl-powered">Powered by <span>K2-Think-V2</span> · MBZUAI · IFM</div>
|
| 350 |
+
</div>
|
| 351 |
+
</div>
|
| 352 |
+
|
| 353 |
+
<!-- ══ ONBOARD ══ -->
|
| 354 |
+
<div class="screen" id="screen-onboard">
|
| 355 |
+
<div class="ob-inner">
|
| 356 |
+
<button class="ob-back" onclick="showScreen('screen-welcome')">← Back</button>
|
| 357 |
+
<div class="dots-row">
|
| 358 |
+
<div class="dot active" id="d0"></div>
|
| 359 |
+
<div class="dot" id="d1"></div>
|
| 360 |
+
<div class="dot" id="d2"></div>
|
| 361 |
+
<div class="dot" id="d3"></div>
|
| 362 |
+
</div>
|
| 363 |
+
|
| 364 |
+
<!-- Step 0 -->
|
| 365 |
+
<div class="step active" id="s0">
|
| 366 |
+
<div class="ob-hero">
|
| 367 |
+
<span class="ob-big-emoji" id="sel-av-em">🦊</span>
|
| 368 |
+
<div class="ob-title">Pick your hero!</div>
|
| 369 |
+
<div class="ob-sub">This is your money champion 🦸</div>
|
| 370 |
+
</div>
|
| 371 |
+
<div class="av-grid">
|
| 372 |
+
<div class="av-opt sel" data-em="🦊" onclick="pickAv(this)"><span class="av-em">🦊</span><span class="av-nm">Fox</span></div>
|
| 373 |
+
<div class="av-opt" data-em="🐼" onclick="pickAv(this)"><span class="av-em">🐼</span><span class="av-nm">Panda</span></div>
|
| 374 |
+
<div class="av-opt" data-em="🦁" onclick="pickAv(this)"><span class="av-em">🦁</span><span class="av-nm">Lion</span></div>
|
| 375 |
+
<div class="av-opt" data-em="🐉" onclick="pickAv(this)"><span class="av-em">🐉</span><span class="av-nm">Dragon</span></div>
|
| 376 |
+
<div class="av-opt" data-em="🦋" onclick="pickAv(this)"><span class="av-em">🦋</span><span class="av-nm">Butterfly</span></div>
|
| 377 |
+
<div class="av-opt" data-em="🐬" onclick="pickAv(this)"><span class="av-em">🐬</span><span class="av-nm">Dolphin</span></div>
|
| 378 |
+
<div class="av-opt" data-em="🦄" onclick="pickAv(this)"><span class="av-em">🦄</span><span class="av-nm">Unicorn</span></div>
|
| 379 |
+
<div class="av-opt" data-em="🐧" onclick="pickAv(this)"><span class="av-em">🐧</span><span class="av-nm">Penguin</span></div>
|
| 380 |
+
</div>
|
| 381 |
+
<button class="btn-cta btn-purple" onclick="goStep(1)">Next →</button>
|
| 382 |
+
</div>
|
| 383 |
+
|
| 384 |
+
<!-- Step 1 -->
|
| 385 |
+
<div class="step" id="s1">
|
| 386 |
+
<div class="ob-hero">
|
| 387 |
+
<span class="ob-big-emoji">👋</span>
|
| 388 |
+
<div class="ob-title">What's your name?</div>
|
| 389 |
+
<div class="ob-sub">Tell us about you!</div>
|
| 390 |
+
</div>
|
| 391 |
+
<input class="name-in" id="nm-input" type="text" placeholder="Your first name..." maxlength="20" autocomplete="off"/>
|
| 392 |
+
<div style="margin-top:20px">
|
| 393 |
+
<div class="ob-title" style="font-size:20px;text-align:center;margin-bottom:4px">How old are you?</div>
|
| 394 |
+
<div class="age-big" id="age-disp">10</div>
|
| 395 |
+
<div class="age-sub">years old</div>
|
| 396 |
+
<input type="range" id="age-range" min="7" max="15" value="10" oninput="updAge(this.value)"/>
|
| 397 |
+
</div>
|
| 398 |
+
<button class="btn-cta btn-purple" onclick="goStep(2)">Next →</button>
|
| 399 |
+
</div>
|
| 400 |
+
|
| 401 |
+
<!-- Step 2 -->
|
| 402 |
+
<div class="step" id="s2">
|
| 403 |
+
<div class="ob-hero">
|
| 404 |
+
<span class="ob-big-emoji">🎯</span>
|
| 405 |
+
<div class="ob-title">What's your goal?</div>
|
| 406 |
+
<div class="ob-sub">What are you saving for first?</div>
|
| 407 |
+
</div>
|
| 408 |
+
<div class="goal-grid">
|
| 409 |
+
<div class="gc sel" data-goal="gaming" onclick="pickGoal(this)"><span class="gc-icon">🎮</span><div class="gc-name">Gaming Setup</div><div class="gc-desc">Save for a console</div></div>
|
| 410 |
+
<div class="gc" data-goal="sneakers" onclick="pickGoal(this)"><span class="gc-icon">👟</span><div class="gc-name">Cool Sneakers</div><div class="gc-desc">Get that dream pair</div></div>
|
| 411 |
+
<div class="gc" data-goal="trip" onclick="pickGoal(this)"><span class="gc-icon">✈️</span><div class="gc-name">Dream Trip</div><div class="gc-desc">Travel adventure</div></div>
|
| 412 |
+
<div class="gc" data-goal="college" onclick="pickGoal(this)"><span class="gc-icon">🎓</span><div class="gc-name">College Fund</div><div class="gc-desc">Invest in future</div></div>
|
| 413 |
+
<div class="gc" data-goal="business" onclick="pickGoal(this)"><span class="gc-icon">🏪</span><div class="gc-name">My Business</div><div class="gc-desc">Start something!</div></div>
|
| 414 |
+
<div class="gc" data-goal="custom" onclick="pickGoal(this)"><span class="gc-icon">⭐</span><div class="gc-name">My Dream</div><div class="gc-desc">I'll decide!</div></div>
|
| 415 |
+
</div>
|
| 416 |
+
<button class="btn-cta btn-purple" onclick="goStep(3)">Next →</button>
|
| 417 |
+
</div>
|
| 418 |
+
|
| 419 |
+
<!-- Step 3 -->
|
| 420 |
+
<div class="step" id="s3">
|
| 421 |
+
<div class="ob-hero">
|
| 422 |
+
<span class="ob-big-emoji">🎉</span>
|
| 423 |
+
<div class="ob-title">You're getting a gift!</div>
|
| 424 |
+
<div class="ob-sub">This is your virtual money to learn with!</div>
|
| 425 |
+
</div>
|
| 426 |
+
<div class="cash-hero">
|
| 427 |
+
<span class="cash-em">💰</span>
|
| 428 |
+
<div class="cash-num">$500</div>
|
| 429 |
+
<div class="cash-lbl">Your starting balance</div>
|
| 430 |
+
</div>
|
| 431 |
+
<div class="fact-box">💡 <strong>Did you know?</strong> Warren Buffett started investing at age 11! You already have a head start. Let's grow this $500 together! 🚀</div>
|
| 432 |
+
<button class="btn-cta btn-mint" onclick="finishOnboard()">🚀 Start My Quest!</button>
|
| 433 |
+
</div>
|
| 434 |
+
</div>
|
| 435 |
+
</div>
|
| 436 |
+
|
| 437 |
+
<!-- ══ APP ══ -->
|
| 438 |
+
<div class="screen" id="screen-app">
|
| 439 |
+
<div class="app-hdr">
|
| 440 |
+
<div class="hdr-top">
|
| 441 |
+
<div>
|
| 442 |
+
<div class="hdr-greet" id="hdr-greet">Good morning! 🌅</div>
|
| 443 |
+
<div class="hdr-name" id="hdr-name">MoneyQuest</div>
|
| 444 |
+
</div>
|
| 445 |
+
<div class="hdr-av" id="hdr-av" onclick="navTo('screen-learn','nb-learn');renderLessons()">🦊</div>
|
| 446 |
+
</div>
|
| 447 |
+
<div class="nw-card">
|
| 448 |
+
<div class="nw-lbl">💰 Total Wealth</div>
|
| 449 |
+
<div class="nw-amt" id="nw-amt">$500.00</div>
|
| 450 |
+
<div class="nw-ch pos" id="nw-ch">+$0.00 today</div>
|
| 451 |
+
<div class="xp-wrap">
|
| 452 |
+
<div class="xp-row"><span id="xp-title">🌱 Money Seed · Level 1</span><span id="xp-num">0/100 XP</span></div>
|
| 453 |
+
<div class="xp-bar"><div class="xp-fill" id="xp-fill" style="width:0%"></div></div>
|
| 454 |
+
</div>
|
| 455 |
+
</div>
|
| 456 |
+
</div>
|
| 457 |
+
<div class="app-body">
|
| 458 |
+
<div class="stats3">
|
| 459 |
+
<div class="sc"><span class="sc-icon">💵</span><div class="sc-val" id="s-cash">$500</div><div class="sc-lbl">Cash</div></div>
|
| 460 |
+
<div class="sc"><span class="sc-icon">📈</span><div class="sc-val" id="s-inv">$0</div><div class="sc-lbl">Invested</div></div>
|
| 461 |
+
<div class="sc"><span class="sc-icon">🏆</span><div class="sc-val" id="s-xp">Lv 1</div><div class="sc-lbl">Level</div></div>
|
| 462 |
+
</div>
|
| 463 |
+
<div class="sec-row"><div class="sec-title">🎯 My Goal</div><button class="sec-link" onclick="navTo('screen-goals','nb-goals');renderGoals()">All goals</button></div>
|
| 464 |
+
<div id="goal-banner"></div>
|
| 465 |
+
<div class="sec-row"><div class="sec-title">⚡ Quick Actions</div></div>
|
| 466 |
+
<div class="act-grid">
|
| 467 |
+
<div class="act act-s" onclick="openSaveMdl()"><span class="act-ic">🏦</span><div class="act-nm">Save Money</div><div class="act-sb">Earn interest</div></div>
|
| 468 |
+
<div class="act act-i" onclick="openInvMdl()"><span class="act-ic">📈</span><div class="act-nm">Invest</div><div class="act-sb">Grow it!</div></div>
|
| 469 |
+
<div class="act act-g" onclick="navTo('screen-goals','nb-goals');renderGoals()"><span class="act-ic">🎯</span><div class="act-nm">My Goals</div><div class="act-sb">Track progress</div></div>
|
| 470 |
+
<div class="act act-a" onclick="navTo('screen-ai','nb-ai');loadAIWelcome()"><span class="act-ic">🤖</span><div class="act-nm">Ask Kai</div><div class="act-sb">K2 AI advice</div></div>
|
| 471 |
+
</div>
|
| 472 |
+
<div class="sec-row"><div class="sec-title">📊 Portfolio</div><button class="sec-link" onclick="openRbMdl()">Rebalance ✨</button></div>
|
| 473 |
+
<div class="port-grid" id="port-grid"></div>
|
| 474 |
+
<div class="ai-card" onclick="navTo('screen-ai','nb-ai');loadAIWelcome()" style="margin-top:14px">
|
| 475 |
+
<div class="ai-top">
|
| 476 |
+
<div class="ai-av">🤖</div>
|
| 477 |
+
<div><div class="ai-nm">Kai — K2 AI Money Mentor</div><div class="ai-st">K2-Think-V2 · Always online</div></div>
|
| 478 |
+
</div>
|
| 479 |
+
<div class="ai-bubble" id="ai-teaser">Hey! 👋 I'm watching your portfolio. Tap me for personalised money advice!</div>
|
| 480 |
+
</div>
|
| 481 |
+
<div class="sec-row" style="margin-top:14px"><div class="sec-title">📋 Recent Activity</div></div>
|
| 482 |
+
<div class="act-list" id="act-list"></div>
|
| 483 |
+
</div>
|
| 484 |
+
</div>
|
| 485 |
+
|
| 486 |
+
<!-- ══ LEARN ══ -->
|
| 487 |
+
<div class="screen" id="screen-learn">
|
| 488 |
+
<div class="learn-hdr">
|
| 489 |
+
<div class="hdr-top">
|
| 490 |
+
<div><div class="hdr-greet" style="color:rgba(255,255,255,.75)">📚 Money School</div><div class="hdr-name" style="color:#fff;font-size:20px">Learn & Earn XP</div></div>
|
| 491 |
+
<div class="hdr-av" style="background:rgba(255,255,255,.2)">🎓</div>
|
| 492 |
+
</div>
|
| 493 |
+
</div>
|
| 494 |
+
<div class="screen-body">
|
| 495 |
+
<div class="sec-row" style="margin-top:14px"><div class="sec-title">📖 Lessons</div><span style="font-size:13px;font-weight:700;color:rgba(15,30,60,.4)" id="lessons-done">0/7 done</span></div>
|
| 496 |
+
<div class="lesson-grid" id="lesson-grid"></div>
|
| 497 |
+
<div style="height:20px"></div>
|
| 498 |
+
</div>
|
| 499 |
+
</div>
|
| 500 |
+
|
| 501 |
+
<!-- ══ GOALS ══ -->
|
| 502 |
+
<div class="screen" id="screen-goals">
|
| 503 |
+
<div class="goals-hdr">
|
| 504 |
+
<div class="hdr-top">
|
| 505 |
+
<div><div class="hdr-greet" style="color:rgba(255,255,255,.75)">🎯 My Dreams</div><div class="hdr-name" style="color:#fff;font-size:20px">Goal Tracker</div></div>
|
| 506 |
+
<div class="hdr-av" style="background:rgba(255,255,255,.2)">💫</div>
|
| 507 |
+
</div>
|
| 508 |
+
</div>
|
| 509 |
+
<div class="screen-body">
|
| 510 |
+
<div id="goals-list" style="margin-top:14px"></div>
|
| 511 |
+
<button class="add-goal-btn" onclick="openNewGoalMdl()">+ Add New Goal</button>
|
| 512 |
+
<div style="height:20px"></div>
|
| 513 |
+
</div>
|
| 514 |
+
</div>
|
| 515 |
+
|
| 516 |
+
<!-- ══ AI SCREEN ══ -->
|
| 517 |
+
<div class="screen" id="screen-ai">
|
| 518 |
+
<div class="ai-hdr">
|
| 519 |
+
<div class="hdr-top">
|
| 520 |
+
<div><div class="hdr-greet" style="color:rgba(255,255,255,.75)">🤖 Money Mentor</div><div class="hdr-name" style="color:#fff;font-size:20px">Kai · K2-Think-V2</div></div>
|
| 521 |
+
<div class="hdr-av" style="background:rgba(255,255,255,.2);animation:pulse 3s infinite">🤖</div>
|
| 522 |
+
</div>
|
| 523 |
+
</div>
|
| 524 |
+
<div class="chat-body">
|
| 525 |
+
<div class="chat-msgs" id="chat-msgs"></div>
|
| 526 |
+
<div class="quick-qs" id="quick-qs"></div>
|
| 527 |
+
<div style="height:130px"></div>
|
| 528 |
+
</div>
|
| 529 |
+
<div class="chat-bar">
|
| 530 |
+
<input class="chat-in" id="chat-in" placeholder="Ask Kai about money..." onkeydown="if(event.key==='Enter')sendMsg()"/>
|
| 531 |
+
<button class="chat-send" onclick="sendMsg()">🚀</button>
|
| 532 |
+
</div>
|
| 533 |
+
</div>
|
| 534 |
+
|
| 535 |
+
<!-- ══ PARENT ══ -->
|
| 536 |
+
<div class="screen" id="screen-parent">
|
| 537 |
+
<div class="par-hdr">
|
| 538 |
+
<button class="par-back" onclick="showScreen('screen-welcome')">← Back</button>
|
| 539 |
+
<div class="par-title">Parent Dashboard 👨👩👧</div>
|
| 540 |
+
<div class="par-sub" id="par-sub">Your child's financial journey</div>
|
| 541 |
+
</div>
|
| 542 |
+
<div class="par-body">
|
| 543 |
+
<div class="par-ai-card">
|
| 544 |
+
<div class="pai-hdr"><div style="font-size:28px">🤖</div><div><div class="pai-title">K2 AI Parent Report</div><div class="pai-sub">Powered by K2-Think-V2</div></div></div>
|
| 545 |
+
<div class="pai-body" id="pai-body"><div class="spin"><div class="spinner"></div><div class="spin-txt">K2 AI is generating your report...</div></div></div>
|
| 546 |
+
</div>
|
| 547 |
+
<div class="pcard"><div class="pcard-title">📈 Learning Curve</div><div class="lc-bars" id="lc-bars"></div></div>
|
| 548 |
+
<div class="pcard"><div class="pcard-title">💡 Key Insights</div><div id="par-insights"></div></div>
|
| 549 |
+
<div class="pcard"><div class="pcard-title">🕐 Decision Timeline</div><div id="par-timeline"></div></div>
|
| 550 |
+
<div class="pcard"><div class="pcard-title">❤️ Financial Health</div><div id="par-health"></div></div>
|
| 551 |
+
</div>
|
| 552 |
+
</div>
|
| 553 |
+
|
| 554 |
+
<!-- ══ BOTTOM NAV ══ -->
|
| 555 |
+
<nav class="bnav" id="bnav" style="display:none">
|
| 556 |
+
<button class="nb on" id="nb-home" onclick="navTo('screen-app','nb-home')"><div class="nb-ic">🏠</div><span class="nb-lbl">Home</span></button>
|
| 557 |
+
<button class="nb" id="nb-learn" onclick="navTo('screen-learn','nb-learn');renderLessons()"><div class="nb-ic">📚</div><span class="nb-lbl">Learn</span></button>
|
| 558 |
+
<button class="nb" id="nb-goals" onclick="navTo('screen-goals','nb-goals');renderGoals()"><div class="nb-ic">🎯</div><span class="nb-lbl">Goals</span></button>
|
| 559 |
+
<button class="nb" id="nb-ai" onclick="navTo('screen-ai','nb-ai');loadAIWelcome()"><div class="nb-ic">🤖</div><span class="nb-lbl">Ask Kai</span></button>
|
| 560 |
+
</nav>
|
| 561 |
+
|
| 562 |
+
<!-- ══ MODALS ══ -->
|
| 563 |
+
<div class="mbg" id="mdl-save"><div class="msheet"><div class="mhandle"></div><span class="m-emoji">🏦</span><div class="m-title">Save Money</div><div class="m-sub">Every dollar saved earns interest and works for your future! 💪</div><div class="amt-row" id="save-amts"></div><button class="btn-confirm" onclick="doSave()">Save it! 🎉</button><button class="btn-cancel" onclick="closeMdl('mdl-save')">Cancel</button></div></div>
|
| 564 |
+
|
| 565 |
+
<div class="mbg" id="mdl-invest"><div class="msheet"><div class="mhandle"></div><span class="m-emoji">📈</span><div class="m-title">Invest Your Money</div><div class="m-sub">Buy a tiny piece of a company. If it grows, your money grows too! 🚀</div><div id="inv-opts"></div><button class="btn-confirm" id="inv-confirm-btn" onclick="doInvest()" disabled>Pick an investment first!</button><button class="btn-cancel" onclick="closeMdl('mdl-invest')">Cancel</button></div></div>
|
| 566 |
+
|
| 567 |
+
<div class="mbg" id="mdl-lesson"><div class="msheet"><div class="mhandle"></div><span class="m-emoji" id="les-em">📖</span><div class="m-title" id="les-title">Lesson</div><div id="les-body"></div><div id="les-quiz"></div><button class="btn-confirm" id="les-btn" onclick="checkAnswer()" disabled>Pick an answer first!</button><button class="btn-cancel" onclick="closeMdl('mdl-lesson')">Skip for now</button></div></div>
|
| 568 |
+
|
| 569 |
+
<div class="mbg" id="mdl-rebalance"><div class="msheet"><div class="mhandle"></div><span class="m-emoji">⚖️</span><div class="m-title">Rebalance Portfolio</div><div class="m-sub">K2 AI will analyse your investments and suggest the best mix!</div><div class="rb-chart" id="rb-chart"></div><div class="rb-suggest" id="rb-suggest"><div class="spin"><div class="spinner"></div><div class="spin-txt">K2 AI is analysing...</div></div></div><button class="btn-confirm" id="rb-btn" onclick="applyRb()" disabled>Apply K2's Suggestion ✨</button><button class="btn-cancel" onclick="closeMdl('mdl-rebalance')">Not now</button></div></div>
|
| 570 |
+
|
| 571 |
+
<div class="mbg" id="mdl-newgoal"><div class="msheet"><div class="mhandle"></div><span class="m-emoji">🎯</span><div class="m-title">New Goal!</div><div class="m-sub">What are you saving for? K2 AI will help you make a plan!</div><div class="goal-grid" id="new-goal-grid"></div><button class="btn-confirm" onclick="doAddGoal()">Add this goal! 🚀</button><button class="btn-cancel" onclick="closeMdl('mdl-newgoal')">Cancel</button></div></div>
|
| 572 |
+
|
| 573 |
+
<script>
|
| 574 |
+
/* ═══ K2 API CONFIG ═══════════════════════════════════
|
| 575 |
+
Exact credentials as specified for the competition.
|
| 576 |
+
══════════════════════════════════════════════════ */
|
| 577 |
+
const K2_API_KEY = "IFM-hdBwCToeVDhs1kUT";
|
| 578 |
+
const K2_API_URL = "https://api.k2think.ai/v1/chat/completions";
|
| 579 |
+
const MODEL_NAME = "MBZUAI-IFM/K2-Think-v2";
|
| 580 |
+
// HuggingFace mirror — used as auto-fallback if primary unreachable:
|
| 581 |
+
const K2_FB_URL = "https://api-inference.huggingface.co/models/LLM360/K2-Think-V2/v1/chat/completions";
|
| 582 |
+
const K2_FB_MDL = "LLM360/K2-Think-V2";
|
| 583 |
+
|
| 584 |
+
/* ═══ DATA ═════════════════════════════════════════ */
|
| 585 |
+
const GOALS_DB = {
|
| 586 |
+
gaming: {icon:'🎮', name:'Gaming Setup', target:300},
|
| 587 |
+
sneakers:{icon:'👟', name:'Cool Sneakers', target:150},
|
| 588 |
+
trip: {icon:'✈️', name:'Dream Trip', target:1000},
|
| 589 |
+
college: {icon:'🎓', name:'College Fund', target:5000},
|
| 590 |
+
business:{icon:'🏪', name:'My Business', target:500},
|
| 591 |
+
custom: {icon:'⭐', name:'My Big Dream', target:200},
|
| 592 |
+
};
|
| 593 |
+
|
| 594 |
+
const ASSETS = [
|
| 595 |
+
{id:'tech', icon:'💻', name:'Tech Giants', desc:'Apple, Google, Microsoft', price:50, color:'#A855F7', vol:.12},
|
| 596 |
+
{id:'green', icon:'🌱', name:'Green Energy', desc:'Solar & wind power', price:30, color:'#4ECDC4', vol:.15},
|
| 597 |
+
{id:'food', icon:'🍔', name:'Food & Brands', desc:"McDonald's, Nike, Disney", price:25, color:'#FF6B6B', vol:.08},
|
| 598 |
+
{id:'crypto', icon:'₿', name:'Crypto', desc:'Digital money', price:20, color:'#FFD93D', vol:.30},
|
| 599 |
+
{id:'save', icon:'🏦', name:'Savings', desc:'Safe 2% interest', price:1, color:'#6ECCF5', vol:.01},
|
| 600 |
+
];
|
| 601 |
+
|
| 602 |
+
const LESSONS = [
|
| 603 |
+
{id:0, icon:'💰', title:'What IS Money?', sub:'Learn how money works', xp:20, done:false,
|
| 604 |
+
body:'Money is like a superpower! 🦸 It\'s what we use to get things we need and want.\n\nBefore money existed, people swapped stuff — like trading 3 chickens for shoes! 🐔👟 That got confusing fast.\n\nSo humans invented coins and notes. Now we even have digital money on our phones!\n\n💡 Key idea: Money is just a tool. The real power is knowing HOW to use it wisely!',
|
| 605 |
+
q:'What did people do before money?', opts:['Swapped things (bartering)','Just took what they wanted','Printed their own notes','Nothing — money always existed'], ans:0},
|
| 606 |
+
{id:1, icon:'🏦', title:'Saving vs Spending', sub:'Know when to keep it', xp:25, done:false,
|
| 607 |
+
body:'The BIG question: "Do I NEED this, or do I WANT this?" 🤔\n\nSpending is fine — but spend on things you\'ll love tomorrow, not just today!\n\nSaving = putting money away so future-you has MORE money. Even saving $5 a week = $260 a year! 🎉\n\n🔑 Rule: Save FIRST, then spend what\'s left. Not the other way around!',
|
| 608 |
+
q:'What\'s the smart money rule?', opts:['Spend first, save what\'s left','Save first, spend what\'s left','Never spend money','Give all your money away'], ans:1},
|
| 609 |
+
{id:2, icon:'📈', title:'What is Investing?', sub:'Make your money grow!', xp:30, done:false,
|
| 610 |
+
body:'Imagine planting a seed 🌱 that grows into a tree full of fruit 🍎. Investing is like that — with money!\n\nWhen you invest, you give money to a company. They grow. YOUR money grows too!\n\nA $50 investment in Apple 10 years ago would be worth ~$700 today! 🤯\n\n⚠️ Remember: investments can also go DOWN. That\'s why we learn first!',
|
| 611 |
+
q:'What happens when you invest in a company?', opts:['You lose all your money','You get free products','You own a tiny piece and share in its success','Nothing happens'], ans:2},
|
| 612 |
+
{id:3, icon:'🥧', title:'Diversification', sub:"Don't put eggs in one basket", xp:35, done:false,
|
| 613 |
+
body:'Imagine 3 ice cream shops 🍦🍦🍦. If one closes, you still have two!\n\nDiversification = spreading money across DIFFERENT investments. If one drops, others may still rise!\n\n📊 Instead of $100 all in crypto (can drop 50%!), try $25 each in tech, green, food, savings.\n\nThis is called a "balanced portfolio" — what the world\'s smartest investors do!',
|
| 614 |
+
q:'Why diversify your investments?', opts:['To confuse people','So if one drops, others balance it','Because it\'s a rule','To have more passwords'], ans:1},
|
| 615 |
+
{id:4, icon:'🔮', title:'Compound Interest', sub:'The 8th wonder of the world!', xp:40, done:false,
|
| 616 |
+
body:'Einstein called this "the 8th wonder of the world!" ✨\n\n$100 growing at 10%/year:\n• Year 1: $110\n• Year 5: $161\n• Year 10: $259\n• Year 20: $673!\n\nYou never added more money — it just kept growing ON its growth! That\'s compound interest 🚀\n\n🗝️ Secret: Starting at 10 vs 20 makes a MASSIVE difference!',
|
| 617 |
+
q:'Why is compound interest so powerful?', opts:['Banks give free money','Money grows on top of its own growth','You never lose money','Only for rich people'], ans:1},
|
| 618 |
+
{id:5, icon:'🎯', title:'Goal Setting', sub:'Dream it, plan it, achieve it!', xp:30, done:false,
|
| 619 |
+
body:'Every great achievement starts with a goal! 🏆\n\nSMART goals are:\n✅ Specific: "Save for a gaming console"\n✅ Measurable: "$300 by December"\n✅ Achievable: Can you get there?\n✅ Relevant: Does it matter to YOU?\n✅ Time-bound: By WHEN?\n\nSave $10/week for 30 weeks = $300 gaming setup! 🎮\n\n💪 First goal hit = confidence to hit any goal!',
|
| 620 |
+
q:'What does "M" in SMART goals stand for?', opts:['Massive','Measurable','Magical','Money'], ans:1},
|
| 621 |
+
{id:6, icon:'🧠', title:'Good Debt vs Bad Debt', sub:'When borrowing is smart', xp:40, done:false,
|
| 622 |
+
body:'Not all debt is bad! 😮\n\nGOOD debt 💚: Borrow for something that GROWS in value — like a student loan for a degree that earns you more money.\n\nBAD debt ❌: Borrow for things that LOSE value fast — like video games, clothes, one-use stuff.\n\n🔑 Only borrow when what you buy will be worth MORE in the future!',
|
| 623 |
+
q:'Which is GOOD debt?', opts:['Borrowing for candy','Borrowing for shoes','Borrowing for a course that earns you more','Borrowing for a video game'], ans:2},
|
| 624 |
+
];
|
| 625 |
+
|
| 626 |
+
/* ═══ STATE ════════════════════════════════════════ */
|
| 627 |
+
let S = {
|
| 628 |
+
name:'', avatar:'🦊', age:10, goal:'gaming',
|
| 629 |
+
cash:500, xp:0,
|
| 630 |
+
port:{tech:0, green:0, food:0, crypto:0, save:500},
|
| 631 |
+
goals:[], activity:[], decisions:[],
|
| 632 |
+
learningData:[20,35,50,65,72,82,90,96],
|
| 633 |
+
};
|
| 634 |
+
let curLesson=null, selSaveAmt=50, selInvest=null, rbSuggestion=null, aiWelcomeDone=false;
|
| 635 |
+
|
| 636 |
+
/* ═══ NAVIGATION ══════════════════════════════════ */
|
| 637 |
+
const APP_SCREENS = ['screen-app','screen-learn','screen-goals','screen-ai'];
|
| 638 |
+
function showScreen(id){
|
| 639 |
+
document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active'));
|
| 640 |
+
document.getElementById(id).classList.add('active');
|
| 641 |
+
document.getElementById('bnav').style.display = APP_SCREENS.includes(id)?'grid':'none';
|
| 642 |
+
}
|
| 643 |
+
function navTo(screenId, navId){
|
| 644 |
+
showScreen(screenId);
|
| 645 |
+
document.querySelectorAll('.nb').forEach(b=>b.classList.remove('on'));
|
| 646 |
+
document.getElementById(navId).classList.add('on');
|
| 647 |
+
}
|
| 648 |
+
function continuePlay(){
|
| 649 |
+
if(S.name) navTo('screen-app','nb-home');
|
| 650 |
+
else showScreen('screen-onboard');
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
/* ═══ ONBOARDING ══════════════════════════════════ */
|
| 654 |
+
let obStep=0;
|
| 655 |
+
function goStep(n){
|
| 656 |
+
if(n===2){
|
| 657 |
+
const nm=document.getElementById('nm-input').value.trim();
|
| 658 |
+
if(!nm){document.getElementById('nm-input').style.borderColor='var(--coral)';return;}
|
| 659 |
+
S.name=nm; S.age=+document.getElementById('age-range').value;
|
| 660 |
+
}
|
| 661 |
+
document.getElementById('s'+obStep).classList.remove('active');
|
| 662 |
+
obStep=n;
|
| 663 |
+
document.getElementById('s'+n).classList.add('active');
|
| 664 |
+
for(let i=0;i<4;i++){
|
| 665 |
+
const d=document.getElementById('d'+i);
|
| 666 |
+
d.className='dot'+(i<n?' done':i===n?' active':'');
|
| 667 |
+
}
|
| 668 |
+
}
|
| 669 |
+
function pickAv(el){
|
| 670 |
+
document.querySelectorAll('.av-opt').forEach(a=>a.classList.remove('sel'));
|
| 671 |
+
el.classList.add('sel');
|
| 672 |
+
S.avatar=el.dataset.em;
|
| 673 |
+
document.getElementById('sel-av-em').textContent=el.dataset.em;
|
| 674 |
+
}
|
| 675 |
+
function updAge(v){
|
| 676 |
+
document.getElementById('age-disp').textContent=v;
|
| 677 |
+
}
|
| 678 |
+
function pickGoal(el){
|
| 679 |
+
document.querySelectorAll('.gc').forEach(g=>g.classList.remove('sel'));
|
| 680 |
+
el.classList.add('sel');
|
| 681 |
+
S.goal=el.dataset.goal;
|
| 682 |
+
}
|
| 683 |
+
function finishOnboard(){
|
| 684 |
+
const gd=GOALS_DB[S.goal];
|
| 685 |
+
S.goals=[{id:S.goal,icon:gd.icon,name:gd.name,target:gd.target,saved:0}];
|
| 686 |
+
addAct('🎉','Started MoneyQuest!','Welcome bonus: $500 virtual cash!','+$500','var(--mint)');
|
| 687 |
+
addDec('save','Received $500 virtual starting balance','Just now');
|
| 688 |
+
navTo('screen-app','nb-home');
|
| 689 |
+
renderApp();
|
| 690 |
+
setTimeout(confetti,400);
|
| 691 |
+
}
|
| 692 |
+
|
| 693 |
+
/* ═══ RENDER APP ══════════════════════════════════ */
|
| 694 |
+
function renderApp(){
|
| 695 |
+
const h=new Date().getHours();
|
| 696 |
+
const gr=h<12?'Good morning! 🌅':h<17?'Good afternoon! ☀️':'Good evening! 🌙';
|
| 697 |
+
setText('hdr-greet',gr);
|
| 698 |
+
setText('hdr-name',S.name?`Hey ${S.name}! 👋`:'MoneyQuest');
|
| 699 |
+
const av=document.getElementById('hdr-av');
|
| 700 |
+
if(av)av.textContent=S.avatar;
|
| 701 |
+
const nw=netWorth();
|
| 702 |
+
setText('nw-amt','$'+nw.toFixed(2));
|
| 703 |
+
const inv=invested();
|
| 704 |
+
const lv=Math.floor(S.xp/100)+1;
|
| 705 |
+
const titles=['🌱 Money Seed','🌿 Money Sprout','🌳 Money Grower','🧙 Money Wizard','💎 Money Master','🏆 Money Legend'];
|
| 706 |
+
setText('xp-title',(titles[Math.min(lv-1,5)])+' · Level '+lv);
|
| 707 |
+
setText('xp-num',(S.xp%100)+'/100 XP');
|
| 708 |
+
setStyle('xp-fill','width',(S.xp%100)+'%');
|
| 709 |
+
setText('s-cash','$'+S.cash.toFixed(0));
|
| 710 |
+
setText('s-inv','$'+inv.toFixed(0));
|
| 711 |
+
setText('s-xp','Lv '+lv);
|
| 712 |
+
renderGoalBanner();
|
| 713 |
+
renderPortfolio();
|
| 714 |
+
renderActivity();
|
| 715 |
+
}
|
| 716 |
+
function netWorth(){
|
| 717 |
+
return S.cash+ASSETS.reduce((a,as)=>a+(S.port[as.id]||0)*as.price,0);
|
| 718 |
+
}
|
| 719 |
+
function invested(){
|
| 720 |
+
return ASSETS.filter(a=>a.id!=='save').reduce((a,as)=>a+(S.port[as.id]||0)*as.price,0);
|
| 721 |
+
}
|
| 722 |
+
function renderGoalBanner(){
|
| 723 |
+
const c=document.getElementById('goal-banner');
|
| 724 |
+
if(!c)return;
|
| 725 |
+
if(!S.goals.length){c.innerHTML='<div class="empty-state">No goal yet — tap "All goals" to add one! 🎯</div>';return;}
|
| 726 |
+
const g=S.goals[0];
|
| 727 |
+
const pct=Math.min(100,(g.saved/g.target)*100);
|
| 728 |
+
c.innerHTML=`<div class="goal-banner"><div class="gb-icon">${g.icon}</div><div class="gb-body"><div class="gb-name">${g.name}</div><div class="gb-sub">$${g.saved.toFixed(0)} of $${g.target}</div><div class="gb-bar"><div class="gb-fill" style="width:${pct}%"></div></div><div class="gb-pct">${pct.toFixed(0)}%${pct>=100?' 🎉 Reached!':''}</div></div></div>`;
|
| 729 |
+
}
|
| 730 |
+
function renderPortfolio(){
|
| 731 |
+
const g=document.getElementById('port-grid');
|
| 732 |
+
if(!g)return;
|
| 733 |
+
const hasAny=Object.values(S.port).some(v=>v>0);
|
| 734 |
+
if(!hasAny){g.innerHTML='<div class="empty-state">No investments yet — tap Invest to start! 📈</div>';return;}
|
| 735 |
+
g.innerHTML=ASSETS.map(a=>{
|
| 736 |
+
const qty=S.port[a.id]||0; if(!qty)return'';
|
| 737 |
+
const val=qty*a.price;
|
| 738 |
+
const ch=((Math.random()-.45)*4).toFixed(1);
|
| 739 |
+
return`<div class="asset-card" style="border-left:4px solid ${a.color}"><div class="asset-ic">${a.icon}</div><div class="asset-inf"><div class="asset-nm">${a.name}</div><div class="asset-ds">${qty} units · ${a.desc}</div></div><div class="asset-rt"><div class="asset-val">$${val.toFixed(0)}</div><div class="asset-ch ${+ch>=0?'chg-p':'chg-n'}">${+ch>=0?'+':''}${ch}%</div></div></div>`;
|
| 740 |
+
}).join('');
|
| 741 |
+
}
|
| 742 |
+
function renderActivity(){
|
| 743 |
+
const l=document.getElementById('act-list');
|
| 744 |
+
if(!l)return;
|
| 745 |
+
if(!S.activity.length){l.innerHTML='<div class="empty-state">No activity yet — start playing! 🎮</div>';return;}
|
| 746 |
+
l.innerHTML=S.activity.slice(0,5).map(a=>`<div class="act-item"><div class="ai-ico">${a.icon}</div><div><div class="ai-text">${a.name}</div><div class="ai-time">${a.desc}</div></div><div class="ai-amt" style="color:${a.color}">${a.amount}</div></div>`).join('');
|
| 747 |
+
}
|
| 748 |
+
function addAct(icon,name,desc,amount,color){
|
| 749 |
+
S.activity.unshift({icon,name,desc,amount,color});
|
| 750 |
+
if(S.activity.length>20)S.activity.pop();
|
| 751 |
+
}
|
| 752 |
+
function addDec(type,text,time){
|
| 753 |
+
S.decisions.unshift({type,text,time});
|
| 754 |
+
if(S.decisions.length>15)S.decisions.pop();
|
| 755 |
+
}
|
| 756 |
+
|
| 757 |
+
/* ═══ LESSONS ══════════════════════════════════════ */
|
| 758 |
+
function renderLessons(){
|
| 759 |
+
const g=document.getElementById('lesson-grid');
|
| 760 |
+
if(!g)return;
|
| 761 |
+
const done=LESSONS.filter(l=>l.done).length;
|
| 762 |
+
setText('lessons-done',done+'/'+LESSONS.length+' done');
|
| 763 |
+
g.innerHTML=LESSONS.map((l,i)=>`
|
| 764 |
+
<div class="lcard ${l.done?'done':i>done?'locked':''}" onclick="${i<=done&&!l.done?'openLesson('+l.id+')':'void(0)'}">
|
| 765 |
+
<div class="lbadge">${l.icon}</div>
|
| 766 |
+
<div class="linfo"><div class="ltitle">${l.title}</div><div class="lsub">${l.sub}</div><div class="lxp">+${l.xp} XP</div></div>
|
| 767 |
+
<div class="lstatus">${l.done?'✅':i>done?'🔒':'▶️'}</div>
|
| 768 |
+
</div>`).join('');
|
| 769 |
+
}
|
| 770 |
+
function openLesson(id){
|
| 771 |
+
const l=LESSONS[id]; curLesson=l;
|
| 772 |
+
document.getElementById('les-em').textContent=l.icon;
|
| 773 |
+
setText('les-title',l.title);
|
| 774 |
+
document.getElementById('les-body').innerHTML=l.body.split('\n\n').map(p=>`<p style="font-size:14px;line-height:1.7;color:var(--navy);margin-bottom:12px">${p.replace(/\n/g,'<br/>')}</p>`).join('');
|
| 775 |
+
window._qa=null;
|
| 776 |
+
document.getElementById('les-quiz').innerHTML=`<div style="margin:16px 0"><div style="font-size:15px;font-weight:800;margin-bottom:11px">🧠 ${l.q}</div>${l.opts.map((o,i)=>`<div onclick="selAns(${i})" id="qa${i}" style="padding:12px 15px;background:rgba(15,30,60,.04);border:2.5px solid transparent;border-radius:var(--r2);margin-bottom:8px;font-size:14px;font-weight:700;cursor:pointer;transition:all .2s">${String.fromCharCode(65+i)}. ${o}</div>`).join('')}</div>`;
|
| 777 |
+
const btn=document.getElementById('les-btn');
|
| 778 |
+
btn.disabled=true; btn.textContent='Pick an answer first!';
|
| 779 |
+
btn.onclick=checkAnswer;
|
| 780 |
+
openMdl('mdl-lesson');
|
| 781 |
+
}
|
| 782 |
+
function selAns(i){
|
| 783 |
+
window._qa=i;
|
| 784 |
+
document.querySelectorAll('[id^="qa"]').forEach((el,j)=>{
|
| 785 |
+
el.style.borderColor=j===i?'var(--purple)':'transparent';
|
| 786 |
+
el.style.background=j===i?'rgba(168,85,247,.1)':'rgba(15,30,60,.04)';
|
| 787 |
+
el.style.color=j===i?'var(--purple)':'var(--navy)';
|
| 788 |
+
});
|
| 789 |
+
const btn=document.getElementById('les-btn');
|
| 790 |
+
btn.disabled=false; btn.textContent='Check my answer! 🎯';
|
| 791 |
+
}
|
| 792 |
+
function checkAnswer(){
|
| 793 |
+
const l=curLesson; if(window._qa===null||!l)return;
|
| 794 |
+
const correct=window._qa===l.ans;
|
| 795 |
+
if(correct){
|
| 796 |
+
l.done=true; S.xp+=l.xp;
|
| 797 |
+
addAct('📚',l.title,'Lesson completed!','+'+l.xp+' XP','var(--purple)');
|
| 798 |
+
addDec('save','Completed: "'+l.title+'"','Just now');
|
| 799 |
+
closeMdl('mdl-lesson'); confetti(); renderLessons(); renderApp();
|
| 800 |
+
} else {
|
| 801 |
+
document.querySelectorAll('[id^="qa"]').forEach((el,j)=>{
|
| 802 |
+
if(j===l.ans){el.style.borderColor='var(--mint)';el.style.background='rgba(78,205,196,.1)';el.style.color='var(--mint)';}
|
| 803 |
+
else if(j===window._qa){el.style.borderColor='var(--coral)';}
|
| 804 |
+
});
|
| 805 |
+
const btn=document.getElementById('les-btn');
|
| 806 |
+
btn.textContent='Got it — finish lesson ✅';
|
| 807 |
+
btn.onclick=()=>{l.done=true;S.xp+=Math.floor(l.xp*.5);addAct('📚',l.title,'Lesson done!','+'+Math.floor(l.xp*.5)+' XP','var(--purple)');closeMdl('mdl-lesson');renderLessons();renderApp();btn.onclick=checkAnswer;};
|
| 808 |
+
}
|
| 809 |
+
}
|
| 810 |
+
|
| 811 |
+
/* ═══ GOALS ════════════════════════════════════════ */
|
| 812 |
+
function renderGoals(){
|
| 813 |
+
const c=document.getElementById('goals-list');
|
| 814 |
+
if(!c)return;
|
| 815 |
+
c.innerHTML=S.goals.map(g=>{
|
| 816 |
+
const pct=Math.min(100,(g.saved/g.target)*100);
|
| 817 |
+
return`<div class="gcard"><div class="gcard-top"><div class="gcard-icon">${g.icon}</div><div><div class="gcard-title">${g.name}</div></div></div>
|
| 818 |
+
<div class="gamts"><div class="gamt"><div class="gamt-val">$${g.saved.toFixed(0)}</div><div class="gamt-lbl">Saved</div></div><div class="gamt"><div class="gamt-val">$${g.target}</div><div class="gamt-lbl">Goal</div></div><div class="gamt"><div class="gamt-val">$${Math.max(0,g.target-g.saved).toFixed(0)}</div><div class="gamt-lbl">Left</div></div></div>
|
| 819 |
+
<div class="g-pct">${pct.toFixed(0)}% complete</div>
|
| 820 |
+
<div class="gbig-bar"><div class="gbig-fill" style="width:${pct}%"></div></div>
|
| 821 |
+
<div class="contrib-row"><input class="contrib-in" id="ci-${g.id}" type="number" placeholder="Add $..." min="1"/><button class="btn-add" onclick="contribute('${g.id}')">+ Add</button></div>
|
| 822 |
+
<button class="ai-plan-btn" onclick="goalAdvice('${g.id}')">🤖 Ask K2 AI for a savings plan!</button>
|
| 823 |
+
</div>`;
|
| 824 |
+
}).join('');
|
| 825 |
+
}
|
| 826 |
+
function contribute(gid){
|
| 827 |
+
const inp=document.getElementById('ci-'+gid);
|
| 828 |
+
const amt=parseFloat(inp.value);
|
| 829 |
+
if(!amt||amt<=0||amt>S.cash){inp.style.borderColor='var(--coral)';return;}
|
| 830 |
+
const g=S.goals.find(x=>x.id===gid); if(!g)return;
|
| 831 |
+
g.saved+=amt; S.cash-=amt; S.port.save=Math.max(0,(S.port.save||0)-amt);
|
| 832 |
+
addAct('🎯',g.name,'Contributed $'+amt,'+$'+amt,'var(--sun)');
|
| 833 |
+
addDec('goal','Added $'+amt+' to '+g.name,'Just now');
|
| 834 |
+
inp.value=''; if(g.saved>=g.target)confetti();
|
| 835 |
+
renderGoals(); renderApp();
|
| 836 |
+
}
|
| 837 |
+
function openNewGoalMdl(){
|
| 838 |
+
const grid=document.getElementById('new-goal-grid');
|
| 839 |
+
grid.innerHTML=Object.entries(GOALS_DB).map(([id,g])=>`<div class="gc" data-goal="${id}" onclick="document.querySelectorAll('#new-goal-grid .gc').forEach(c=>c.classList.remove('sel'));this.classList.add('sel')"><span class="gc-icon">${g.icon}</span><div class="gc-name">${g.name}</div><div class="gc-desc">$${g.target} goal</div></div>`).join('');
|
| 840 |
+
openMdl('mdl-newgoal');
|
| 841 |
+
}
|
| 842 |
+
function doAddGoal(){
|
| 843 |
+
const sel=document.querySelector('#new-goal-grid .gc.sel');
|
| 844 |
+
if(!sel)return;
|
| 845 |
+
const id=sel.dataset.goal, gd=GOALS_DB[id];
|
| 846 |
+
if(S.goals.find(g=>g.id===id)){closeMdl('mdl-newgoal');return;}
|
| 847 |
+
S.goals.push({id,icon:gd.icon,name:gd.name,target:gd.target,saved:0});
|
| 848 |
+
closeMdl('mdl-newgoal'); renderGoals(); renderApp();
|
| 849 |
+
}
|
| 850 |
+
async function goalAdvice(gid){
|
| 851 |
+
const g=S.goals.find(x=>x.id===gid); if(!g)return;
|
| 852 |
+
navTo('screen-ai','nb-ai'); loadAIWelcome();
|
| 853 |
+
await askAI(`I'm saving for ${g.name}. I need $${g.target} and have $${g.saved.toFixed(0)} so far. I'm ${S.age} years old. Can you make me a simple step-by-step savings plan?`);
|
| 854 |
+
}
|
| 855 |
+
|
| 856 |
+
/* ═══ SAVE MODAL ═══════════════════════════════════ */
|
| 857 |
+
function openSaveMdl(){
|
| 858 |
+
const amts=[10,25,50,100];
|
| 859 |
+
selSaveAmt=50;
|
| 860 |
+
document.getElementById('save-amts').innerHTML=amts.map(a=>`<div class="amt-btn ${a===50?'sel':''}" onclick="selectSave(${a},this)">$${a}</div>`).join('')+`<div class="amt-btn" onclick="selectSave(${S.cash},this)">All</div>`;
|
| 861 |
+
openMdl('mdl-save');
|
| 862 |
+
}
|
| 863 |
+
function selectSave(amt,el){
|
| 864 |
+
document.querySelectorAll('#save-amts .amt-btn').forEach(b=>b.classList.remove('sel'));
|
| 865 |
+
el.classList.add('sel'); selSaveAmt=amt;
|
| 866 |
+
}
|
| 867 |
+
function doSave(){
|
| 868 |
+
const amt=Math.min(selSaveAmt,S.cash); if(amt<=0)return;
|
| 869 |
+
S.port.save=(S.port.save||0)+amt;
|
| 870 |
+
addAct('🏦','Saved money','Put $'+amt+' in savings','+$'+amt,'var(--mint)');
|
| 871 |
+
addDec('save','Saved $'+amt,'Just now');
|
| 872 |
+
S.xp+=5; closeMdl('mdl-save'); renderApp();
|
| 873 |
+
}
|
| 874 |
+
|
| 875 |
+
/* ═══ INVEST MODAL ═════════════════════════════════ */
|
| 876 |
+
function openInvMdl(){
|
| 877 |
+
selInvest=null;
|
| 878 |
+
document.getElementById('inv-opts').innerHTML=ASSETS.filter(a=>a.id!=='save').map(a=>`
|
| 879 |
+
<div class="invest-opt" onclick="selectInv('${a.id}',this)">
|
| 880 |
+
<div class="io-ic">${a.icon}</div>
|
| 881 |
+
<div class="io-inf"><div class="io-nm">${a.name}</div><div class="io-ds">${a.desc} · $${a.price}/unit</div></div>
|
| 882 |
+
<div class="io-risk" style="color:${a.vol>.15?'var(--coral)':a.vol>.08?'var(--sun)':'var(--mint)'}">${a.vol>.15?'⚠️ High':a.vol>.08?'〜 Medium':'✅ Low'}</div>
|
| 883 |
+
</div>`).join('');
|
| 884 |
+
const btn=document.getElementById('inv-confirm-btn');
|
| 885 |
+
btn.disabled=true; btn.textContent='Pick an investment first!';
|
| 886 |
+
openMdl('mdl-invest');
|
| 887 |
+
}
|
| 888 |
+
function selectInv(id,el){
|
| 889 |
+
document.querySelectorAll('.invest-opt').forEach(o=>{o.classList.remove('sel');o.style.background='';});
|
| 890 |
+
el.classList.add('sel'); selInvest=id;
|
| 891 |
+
const a=ASSETS.find(x=>x.id===id);
|
| 892 |
+
const btn=document.getElementById('inv-confirm-btn');
|
| 893 |
+
btn.disabled=false; btn.textContent='Buy 1 unit of '+a.name+' for $'+a.price+' 🚀';
|
| 894 |
+
}
|
| 895 |
+
function doInvest(){
|
| 896 |
+
if(!selInvest)return;
|
| 897 |
+
const a=ASSETS.find(x=>x.id===selInvest);
|
| 898 |
+
if(S.cash<a.price){alert('Not enough cash! You need $'+a.price);return;}
|
| 899 |
+
S.cash-=a.price; S.port[a.id]=(S.port[a.id]||0)+1;
|
| 900 |
+
addAct(a.icon,'Invested in '+a.name,'1 unit @ $'+a.price,'-$'+a.price,'var(--coral)');
|
| 901 |
+
addDec('invest','Bought 1 unit of '+a.name,'Just now');
|
| 902 |
+
S.xp+=10; closeMdl('mdl-invest'); renderApp();
|
| 903 |
+
}
|
| 904 |
+
|
| 905 |
+
/* ═══ REBALANCE MODAL ══════════════════════════════ */
|
| 906 |
+
async function openRbMdl(){
|
| 907 |
+
rbSuggestion=null;
|
| 908 |
+
document.getElementById('rb-btn').disabled=true;
|
| 909 |
+
// Draw chart
|
| 910 |
+
const bars=ASSETS.map(a=>({name:a.name.split(' ')[0],val:(S.port[a.id]||0)*a.price,color:a.color})).filter(b=>b.val>0);
|
| 911 |
+
const maxV=Math.max(1,...bars.map(b=>b.val));
|
| 912 |
+
document.getElementById('rb-chart').innerHTML=bars.map(b=>`<div class="rb-bar" style="height:${(b.val/maxV)*100}%;background:${b.color}"><span class="rb-val">$${b.val.toFixed(0)}</span><span class="rb-lbl">${b.name}</span></div>`).join('');
|
| 913 |
+
document.getElementById('rb-suggest').innerHTML='<div class="spin"><div class="spinner"></div><div class="spin-txt">K2 AI is analysing your portfolio...</div></div>';
|
| 914 |
+
openMdl('mdl-rebalance');
|
| 915 |
+
const desc=ASSETS.map(a=>`${a.name}: $${((S.port[a.id]||0)*a.price).toFixed(0)}`).join(', ');
|
| 916 |
+
const prompt=`I'm ${S.age} years old. My portfolio: ${desc}. My goal: ${S.goals[0]?.name||'grow my money'}. In 3 simple sentences, is my portfolio balanced? Suggest ONE specific change. Use simple language for a ${S.age}-year-old.`;
|
| 917 |
+
try{
|
| 918 |
+
const r=await k2(`You are Kai, a friendly money mentor for a ${S.age}-year-old. Keep advice simple and fun. Use emojis.`,prompt);
|
| 919 |
+
rbSuggestion=r;
|
| 920 |
+
document.getElementById('rb-suggest').innerHTML=`<div class="rb-suggest-title">🤖 K2 AI Suggests:</div><div class="rb-suggest-text">${r}</div>`;
|
| 921 |
+
document.getElementById('rb-btn').disabled=false;
|
| 922 |
+
}catch(e){
|
| 923 |
+
document.getElementById('rb-suggest').innerHTML='<div class="rb-suggest-title">🤖 K2 AI tip:</div><div class="rb-suggest-text">Spread your money across different types! Try investing in at least 3 different categories for a healthy, balanced portfolio. 🌟</div>';
|
| 924 |
+
document.getElementById('rb-btn').disabled=false;
|
| 925 |
+
}
|
| 926 |
+
}
|
| 927 |
+
function applyRb(){
|
| 928 |
+
addAct('⚖️','Portfolio Rebalanced','Applied K2 AI advice','✓','var(--purple)');
|
| 929 |
+
addDec('invest','Rebalanced based on K2 AI advice','Just now');
|
| 930 |
+
S.xp+=15; closeMdl('mdl-rebalance'); renderApp();
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
/* ═══ AI CHAT ═══════════════════════════════════════ */
|
| 934 |
+
function loadAIWelcome(){
|
| 935 |
+
if(aiWelcomeDone)return;
|
| 936 |
+
aiWelcomeDone=true;
|
| 937 |
+
document.getElementById('chat-msgs').innerHTML='';
|
| 938 |
+
addAIMsg(`Hey ${S.name||'friend'}! 👋 I'm Kai, your K2 AI money mentor!\n\nI can help you with:\n• 📈 Understanding your investments\n• 🎯 Hitting your goals faster\n• 💡 Smart money habits\n• ⚖️ What to do with your cash\n\nWhat would you like to know? 🤔`);
|
| 939 |
+
document.getElementById('quick-qs').innerHTML=[
|
| 940 |
+
'💰 How do I grow faster?','📊 Is my portfolio balanced?','🎯 Help me reach my goal!','📈 Should I invest more?','🤔 What is compound interest?','💡 What should I do next?'
|
| 941 |
+
].map(q=>`<button class="qq" onclick="askAI('${q.replace(/'/g,"\\'")}')"> ${q}</button>`).join('');
|
| 942 |
+
}
|
| 943 |
+
function addAIMsg(text){
|
| 944 |
+
const c=document.getElementById('chat-msgs'); if(!c)return;
|
| 945 |
+
const d=document.createElement('div'); d.className='msg msg-ai';
|
| 946 |
+
d.innerHTML=`<div class="msg-hdr"><span class="msg-hdr-av">🤖</span><span class="msg-hdr-nm">Kai · K2 AI</span></div><div class="bubble bubble-ai">${text.replace(/\n/g,'<br/>')}</div>`;
|
| 947 |
+
c.appendChild(d); c.scrollTop=c.scrollHeight;
|
| 948 |
+
}
|
| 949 |
+
function addUserMsg(text){
|
| 950 |
+
const c=document.getElementById('chat-msgs'); if(!c)return;
|
| 951 |
+
const d=document.createElement('div'); d.className='msg msg-user';
|
| 952 |
+
d.innerHTML=`<div class="bubble bubble-user">${text}</div>`;
|
| 953 |
+
c.appendChild(d); c.scrollTop=c.scrollHeight;
|
| 954 |
+
}
|
| 955 |
+
function showTyping(){
|
| 956 |
+
const c=document.getElementById('chat-msgs'); if(!c)return;
|
| 957 |
+
const d=document.createElement('div'); d.className='msg msg-ai'; d.id='typing';
|
| 958 |
+
d.innerHTML=`<div class="msg-hdr"><span class="msg-hdr-av">🤖</span><span class="msg-hdr-nm">Kai is thinking...</span></div><div class="bubble bubble-ai"><div class="typing-dots"><div class="td"></div><div class="td"></div><div class="td"></div></div></div>`;
|
| 959 |
+
c.appendChild(d); c.scrollTop=c.scrollHeight;
|
| 960 |
+
}
|
| 961 |
+
function rmTyping(){const t=document.getElementById('typing');if(t)t.remove();}
|
| 962 |
+
function sendMsg(){const inp=document.getElementById('chat-in');const txt=inp.value.trim();if(!txt)return;inp.value='';askAI(txt);}
|
| 963 |
+
async function askAI(userText){
|
| 964 |
+
addUserMsg(userText); showTyping();
|
| 965 |
+
const portSum=ASSETS.map(a=>`${a.name}:${S.port[a.id]||0}units($${((S.port[a.id]||0)*a.price).toFixed(0)})`).join(',');
|
| 966 |
+
const goalSum=S.goals.map(g=>`${g.name}:$${g.saved}/$${g.target}`).join(',');
|
| 967 |
+
const sys=`You are Kai, a friendly encouraging money mentor for a ${S.age}-year-old named ${S.name||'friend'}. Powered by K2-Think-V2. Use simple fun language. Max 120 words. Use emojis. Be specific to their situation. Portfolio: ${portSum}. Goals: ${goalSum||'none yet'}. Cash: $${S.cash.toFixed(0)}. Net worth: $${netWorth().toFixed(0)}. End with one specific action they should take!`;
|
| 968 |
+
try{
|
| 969 |
+
const r=await k2(sys,userText);
|
| 970 |
+
rmTyping(); addAIMsg(r);
|
| 971 |
+
const t=document.getElementById('ai-teaser');
|
| 972 |
+
if(t)t.textContent=r.slice(0,70)+'...';
|
| 973 |
+
}catch(e){
|
| 974 |
+
rmTyping();
|
| 975 |
+
addAIMsg(`Oops! K2 AI is loading up right now. Meanwhile: Save regularly and diversify your investments! Even $5 today makes a difference 💪`);
|
| 976 |
+
}
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
+
/* ═══ K2 API CALL ══════════════════════════════════ */
|
| 980 |
+
async function k2(system, user){
|
| 981 |
+
// Try primary K2 endpoint first, fall back to HuggingFace mirror on CORS/DNS error
|
| 982 |
+
let r;
|
| 983 |
+
try {
|
| 984 |
+
r = await fetch(K2_API_URL,{
|
| 985 |
+
method:'POST',
|
| 986 |
+
headers:{'Content-Type':'application/json','Authorization':'Bearer '+K2_API_KEY},
|
| 987 |
+
body:JSON.stringify({model:MODEL_NAME,messages:[{role:'system',content:system},{role:'user',content:user}],max_tokens:200,temperature:0.75}),
|
| 988 |
+
});
|
| 989 |
+
} catch(fetchErr) {
|
| 990 |
+
// Primary unreachable (DNS/CORS) — try HuggingFace mirror
|
| 991 |
+
r = await fetch(K2_FB_URL,{
|
| 992 |
+
method:'POST',
|
| 993 |
+
headers:{'Content-Type':'application/json','Authorization':'Bearer '+K2_API_KEY},
|
| 994 |
+
body:JSON.stringify({model:K2_FB_MDL,messages:[{role:'system',content:system},{role:'user',content:user}],max_tokens:200,temperature:0.75}),
|
| 995 |
+
});
|
| 996 |
+
}
|
| 997 |
+
if(!r.ok){
|
| 998 |
+
const e=await r.json().catch(()=>({}));
|
| 999 |
+
if(r.status===503)throw new Error('Model loading — retry in 20s');
|
| 1000 |
+
throw new Error((e.error?.message)||'K2 error '+r.status);
|
| 1001 |
+
}
|
| 1002 |
+
const d=await r.json();
|
| 1003 |
+
if(d.choices?.[0]?.message?.content)return d.choices[0].message.content;
|
| 1004 |
+
if(d.generated_text)return d.generated_text;
|
| 1005 |
+
throw new Error('Unexpected response');
|
| 1006 |
+
}
|
| 1007 |
+
|
| 1008 |
+
/* ═══ PARENT DASHBOARD ═════════════════════════════ */
|
| 1009 |
+
async function loadParentDash(){
|
| 1010 |
+
const sub=document.getElementById('par-sub');
|
| 1011 |
+
if(sub)sub.textContent=S.name?S.name+"'s financial journey":'Your child\'s financial journey';
|
| 1012 |
+
// Learning curve
|
| 1013 |
+
const bc=document.getElementById('lc-bars');
|
| 1014 |
+
if(bc){bc.innerHTML=S.learningData.map((v,i)=>`<div class="lc-bar" style="height:${v}%"><span class="lc-bar-lbl">W${i+1}</span></div>`).join('');}
|
| 1015 |
+
// Insights
|
| 1016 |
+
const ins=document.getElementById('par-insights');
|
| 1017 |
+
const doneL=LESSONS.filter(l=>l.done).length;
|
| 1018 |
+
const invAmt=invested();
|
| 1019 |
+
const divd=Object.values(S.port).filter(v=>v>0).length>=3;
|
| 1020 |
+
if(ins)ins.innerHTML=[
|
| 1021 |
+
{ic:'📚',txt:`Completed <strong>${doneL}/${LESSONS.length}</strong> money lessons`,badge:doneL>=4?'On track':'Keep going',cls:doneL>=4?'bg-good':'bg-warn'},
|
| 1022 |
+
{ic:'💰',txt:`Total invested: <strong>$${invAmt.toFixed(0)}</strong>`,badge:'Active',cls:'bg-good'},
|
| 1023 |
+
{ic:'🥧',txt:divd?`Diversified across <strong>${Object.values(S.port).filter(v=>v>0).length}</strong> asset types`:'Only <strong>1-2 assets</strong> — suggest diversification',badge:divd?'Diversified':'Needs work',cls:divd?'bg-good':'bg-warn'},
|
| 1024 |
+
{ic:'🎯',txt:`<strong>${S.goals.length}</strong> goal${S.goals.length!==1?'s':''} set — great habit!`,badge:'Goal-setter',cls:'bg-info'},
|
| 1025 |
+
].map(i=>`<div class="ins-row"><div class="ins-ic">${i.ic}</div><div class="ins-txt">${i.txt}</div><span class="ins-badge ${i.cls}">${i.badge}</span></div>`).join('');
|
| 1026 |
+
// Timeline
|
| 1027 |
+
const tl=document.getElementById('par-timeline');
|
| 1028 |
+
if(tl)tl.innerHTML=S.decisions.slice(0,6).map(d=>`<div class="dt-item"><div class="dt-dot dt-${d.type}">${d.type==='save'?'💰':d.type==='invest'?'📈':'🎯'}</div><div><div class="dt-text">${d.text}</div><div class="dt-time">${d.time}</div></div></div>`).join('')||'<div style="color:rgba(255,255,255,.35);font-size:13px">No decisions yet</div>';
|
| 1029 |
+
// Health
|
| 1030 |
+
const h=document.getElementById('par-health');
|
| 1031 |
+
const score=Math.min(100,(doneL/LESSONS.length)*30+(invAmt>0?20:0)+(S.goals.length?20:0)+(divd?20:0)+Math.min(10,S.xp/20));
|
| 1032 |
+
if(h)h.innerHTML=`<div style="display:flex;align-items:center;gap:16px"><div style="font-size:46px;font-weight:900;color:${score>70?'var(--mint)':score>40?'var(--sun)':'var(--coral)'}">${score.toFixed(0)}</div><div><div style="font-size:16px;font-weight:800;color:#fff">${score>70?'Excellent 🌟':score>40?'Good Progress 👍':'Just Starting 🌱'}</div><div style="font-size:12px;color:rgba(255,255,255,.45);margin-top:2px">out of 100</div></div></div><div style="height:10px;background:rgba(255,255,255,.1);border-radius:5px;overflow:hidden;margin-top:11px"><div style="height:100%;width:${score}%;background:${score>70?'var(--mint)':score>40?'var(--sun)':'var(--coral)'};border-radius:5px;transition:width 1s ease"></div></div>`;
|
| 1033 |
+
// K2 AI report
|
| 1034 |
+
const pb=document.getElementById('pai-body');
|
| 1035 |
+
try{
|
| 1036 |
+
const rpt=await k2('You are a child financial education expert. Write a 3-sentence parent report — encouraging, specific, practical. No emojis.',
|
| 1037 |
+
`Child: ${S.name||'Unknown'}, age ${S.age}. Completed ${doneL}/${LESSONS.length} lessons. Invested $${invAmt.toFixed(0)} across ${Object.values(S.port).filter(v=>v>0).length} asset types. Set ${S.goals.length} goals. Earned ${S.xp} XP. Write the report and give one home tip.`);
|
| 1038 |
+
if(pb)pb.textContent=rpt;
|
| 1039 |
+
}catch(e){
|
| 1040 |
+
if(pb)pb.textContent=`${S.name||'Your child'} is making great progress in financial literacy! They're actively engaging with investment concepts and goal-setting, building foundational wealth-building skills. Consider discussing their virtual portfolio choices at dinner and asking what they learned today.`;
|
| 1041 |
+
}
|
| 1042 |
+
}
|
| 1043 |
+
|
| 1044 |
+
/* ═══ MODAL HELPERS ════════════════════════════════ */
|
| 1045 |
+
function openMdl(id){document.getElementById(id).classList.add('open');}
|
| 1046 |
+
function closeMdl(id){document.getElementById(id).classList.remove('open');}
|
| 1047 |
+
|
| 1048 |
+
/* ═══ CONFETTI ══════════════════════════════════════ */
|
| 1049 |
+
function confetti(){
|
| 1050 |
+
const c=document.getElementById('confetti');
|
| 1051 |
+
const cols=['#FFD93D','#6ECCF5','#4ECDC4','#FF6B6B','#A855F7','#95E67A','#FF85C2'];
|
| 1052 |
+
for(let i=0;i<28;i++){
|
| 1053 |
+
const el=document.createElement('div'); el.className='cp';
|
| 1054 |
+
el.style.cssText=`left:${Math.random()*100}%;background:${cols[Math.floor(Math.random()*cols.length)]};width:${7+Math.random()*8}px;height:${7+Math.random()*8}px;border-radius:${Math.random()>.5?'50%':'2px'};animation:confetti ${1.2+Math.random()*1.2}s ease-out ${Math.random()*.4}s forwards;`;
|
| 1055 |
+
c.appendChild(el);
|
| 1056 |
+
setTimeout(()=>el.remove(),2800);
|
| 1057 |
+
}
|
| 1058 |
+
}
|
| 1059 |
+
|
| 1060 |
+
/* ═══ UTILS ═════════════════════════════════════════ */
|
| 1061 |
+
function setText(id,v){const e=document.getElementById(id);if(e)e.textContent=v;}
|
| 1062 |
+
function setStyle(id,prop,val){const e=document.getElementById(id);if(e)e.style[prop]=val;}
|
| 1063 |
+
|
| 1064 |
+
/* ═══ INIT ══════════════════════════════════════════ */
|
| 1065 |
+
document.getElementById('bnav').style.display='none';
|
| 1066 |
+
</script>
|
| 1067 |
+
</body>
|
| 1068 |
+
</html>
|