Skip to content

Instantly share code, notes, and snippets.

@shahidcodes
Created June 9, 2026 08:10
Show Gist options
  • Select an option

  • Save shahidcodes/58da208000e34c6fb9ff677ad0cc7533 to your computer and use it in GitHub Desktop.

Select an option

Save shahidcodes/58da208000e34c6fb9ff677ad0cc7533 to your computer and use it in GitHub Desktop.
PP-Idea
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PainFree — App Concept</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700&family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet">
<style>
:root{
--bg:#FAF7F2;--white:#FFFFFF;--dim:#F2EEE7;
--primary:#3D7B6F;--primary-d:#2D6258;--primary-l:#E4F0EC;
--accent:#D47B5B;--accent-l:#FDF0EC;
--text:#1A1816;--t2:#6B6560;--t3:#A9A39D;
--line:#EBE6DF;--green:#4A9E6F;--red:#C85A4A;--amber:#D4A34A;
}
*{margin:0;padding:0;box-sizing:border-box}
body{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#111010;font-family:'DM Sans',sans-serif;color:var(--text);padding:20px}
/* ── Demo Frame ── */
.demo-head{text-align:center;margin-bottom:24px}
.demo-head h1{font-family:'Instrument Serif',serif;font-size:28px;color:#E8E4DE;font-weight:400}
.demo-head p{font-size:12px;color:#6B6560;margin-top:4px;letter-spacing:1.5px;text-transform:uppercase;font-weight:500}
/* ── Phone ── */
.phone{width:390px;height:844px;background:var(--bg);border-radius:50px;position:relative;overflow:hidden;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.06),0 0 0 3px #1E1C1A,0 40px 80px rgba(0,0,0,.5);flex-shrink:0}
.phone::after{content:'';position:absolute;bottom:9px;left:50%;transform:translateX(-50%);width:134px;height:4.5px;background:rgba(0,0,0,.14);border-radius:3px;z-index:999;pointer-events:none}
.island{position:absolute;top:10px;left:50%;transform:translateX(-50%);width:124px;height:35px;background:#000;border-radius:18px;z-index:999}
/* ── Status Bar ── */
.sbar{height:54px;display:flex;align-items:center;justify-content:space-between;padding:0 30px;font-size:15px;font-weight:600;position:relative;z-index:10}
.sb-r{display:flex;align-items:center;gap:6px}
.sb-r svg{height:12px}
.bat{width:24px;height:11px;border:1.5px solid var(--text);border-radius:3px;display:flex;align-items:center;padding:1.5px;position:relative}
.bat::after{content:'';position:absolute;right:-3.5px;top:2.5px;width:2px;height:4.5px;background:var(--text);border-radius:0 1px 1px 0}
.bat-f{width:72%;height:100%;background:var(--text);border-radius:1px}
/* ── Screens Container ── */
.scrs{position:absolute;top:54px;left:0;right:0;bottom:0}
.scr{position:absolute;inset:0;overflow-y:auto;opacity:0;pointer-events:none;transform:translateY(5px);transition:opacity .3s,transform .3s;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.scr::-webkit-scrollbar{display:none}
.scr.on{opacity:1;pointer-events:auto;transform:translateY(0)}
.si{padding:14px 22px 100px}
/* ── Tab Bar ── */
.tbar{position:absolute;bottom:0;left:0;right:0;display:flex;justify-content:space-around;padding:6px 4px 28px;background:rgba(250,247,242,.88);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-top:1px solid var(--line);z-index:50;transition:opacity .3s,transform .3s}
.tbar.hide{opacity:0;transform:translateY(10px);pointer-events:none}
.tbtn{display:flex;flex-direction:column;align-items:center;gap:3px;border:none;background:none;cursor:pointer;padding:5px 14px;color:var(--t3);transition:color .2s;font-family:inherit}
.tbtn svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.tbtn span{font-size:10px;font-weight:600;letter-spacing:.3px}
.tbtn.on{color:var(--primary)}
.tbtn.on svg{stroke-width:2.3}
/* ── Shared Components ── */
.card{background:var(--white);border-radius:18px;padding:18px;border:1px solid var(--line)}
.btn{width:100%;padding:16px;border-radius:14px;border:none;font-family:'DM Sans',sans-serif;font-size:16px;font-weight:600;cursor:pointer;transition:all .2s;letter-spacing:.2px}
.btn-p{background:var(--primary);color:#fff}
.btn-p:hover:not(:disabled){background:var(--primary-d);transform:translateY(-1px);box-shadow:0 6px 20px rgba(61,123,111,.3)}
.btn-p:disabled{background:var(--t3);cursor:default}
.btn-g{background:var(--dim);color:var(--t2);border:1px solid var(--line)}
.btn-g:hover{background:var(--line)}
.sec-h{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:14px}
.sec-h h2{font-family:'Instrument Serif',serif;font-size:20px;font-weight:400}
.sec-h .dur{font-size:13px;color:var(--t3);font-weight:500}
/* ── Stagger Animations ── */
[data-a]{opacity:0}
.scr.on [data-a]{animation:fu .45s ease both}
.scr.on [data-a="1"]{animation-delay:.04s}
.scr.on [data-a="2"]{animation-delay:.1s}
.scr.on [data-a="3"]{animation-delay:.16s}
.scr.on [data-a="4"]{animation-delay:.22s}
.scr.on [data-a="5"]{animation-delay:.28s}
.scr.on [data-a="6"]{animation-delay:.34s}
.scr.on [data-a="7"]{animation-delay:.4s}
@keyframes fu{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
/* ═══════════════════════════════════
ONBOARDING
═══════════════════════════════════ */
.ob-head{text-align:center;margin-bottom:2px}
.ob-head h1{font-family:'Instrument Serif',serif;font-size:28px;font-weight:400;line-height:1.15}
.ob-head .sub{color:var(--t2);font-size:15px;margin-top:6px}
.body-wrap{display:flex;justify-content:center;height:310px;position:relative;margin:6px 0}
.body-svg{height:100%;width:auto}
.body-svg path,.body-svg line,.body-svg circle.base{fill:none;stroke:#C4BDB4;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.hs{fill:transparent;stroke:transparent;stroke-width:2.5;cursor:pointer;transition:fill .25s,stroke .25s,filter .25s}
.hs:hover{fill:rgba(61,123,111,.1);stroke:rgba(61,123,111,.3)}
.hs.sel{fill:rgba(61,123,111,.22);stroke:var(--primary);filter:drop-shadow(0 0 8px rgba(61,123,111,.3))}
.chips{display:flex;flex-wrap:wrap;gap:8px;min-height:36px;justify-content:center;margin:8px 0 22px}
.chip{background:var(--primary-l);color:var(--primary-d);font-size:12px;font-weight:600;padding:6px 12px 6px 14px;border-radius:20px;animation:chipIn .25s ease;display:flex;align-items:center;gap:6px}
.chip button{width:16px;height:16px;background:rgba(61,123,111,.18);border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--primary-d);line-height:1;font-family:inherit}
@keyframes chipIn{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}
.ob-foot{padding:0 0 10px}
/* ═══════════════════════════════════
HOME
═══════════════════════════════════ */
.hdr{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18px}
.greet{color:var(--t2);font-size:14px;font-weight:500;margin-bottom:2px}
.hdr h1{font-family:'Instrument Serif',serif;font-size:28px;font-weight:400}
.strk{background:linear-gradient(135deg,#FFF3E0,#FFE0B2);padding:8px 14px;border-radius:14px;font-weight:700;font-size:15px;color:#E65100;display:flex;align-items:center;gap:4px;box-shadow:0 2px 8px rgba(230,81,0,.1)}
.chk{background:linear-gradient(135deg,var(--primary),var(--primary-d));border:none;border-radius:20px;padding:20px 20px 18px;margin-bottom:16px;color:#fff}
.chk-t{font-size:16px;font-weight:600;margin-bottom:14px}
.pain-sc{display:flex;gap:6px;flex-wrap:wrap}
.pn{width:30px;height:30px;border-radius:50%;border:1.5px solid rgba(255,255,255,.3);background:rgba(255,255,255,.08);color:rgba(255,255,255,.65);font-size:12px;font-weight:600;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;font-family:inherit}
.pn:hover{background:rgba(255,255,255,.18)}
.pn.sel{background:#fff;color:var(--primary-d);border-color:#fff;transform:scale(1.12)}
.start-card{background:var(--white);border:1.5px solid var(--primary-l);border-radius:18px;padding:18px 20px;margin-bottom:20px;cursor:pointer;transition:border-color .2s,transform .15s,box-shadow .2s;display:flex;align-items:center;gap:16px}
.start-card:hover{border-color:var(--primary);transform:translateY(-1px);box-shadow:0 4px 16px rgba(61,123,111,.1)}
.play-btn{width:48px;height:48px;border-radius:14px;background:var(--primary);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.play-btn svg{width:20px;height:20px;fill:#fff;margin-left:2px}
.start-info h3{font-size:15px;font-weight:600;margin-bottom:3px}
.start-info p{font-size:13px;color:var(--t3);font-weight:400}
.ex-item{display:flex;align-items:center;gap:14px;padding:13px 16px;background:var(--white);border-radius:16px;border:1px solid var(--line);margin-bottom:9px;cursor:pointer;transition:border-color .2s,transform .15s}
.ex-item:hover{border-color:var(--primary);transform:translateX(3px)}
.ex-n{width:36px;height:36px;border-radius:12px;background:var(--primary-l);color:var(--primary);font-weight:700;font-size:14px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.ex-bd{flex:1}
.ex-nm{font-weight:600;font-size:14px;margin-bottom:2px}
.ex-mt{font-size:12px;color:var(--t3)}
.ex-ar{color:var(--t3);font-size:18px}
.st-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:18px}
.st-c{background:var(--white);border-radius:16px;border:1px solid var(--line);padding:16px;text-align:center}
.st-v{font-family:'Instrument Serif',serif;font-size:28px;color:var(--primary);line-height:1}
.st-l{font-size:11px;color:var(--t3);font-weight:600;text-transform:uppercase;letter-spacing:.8px;margin-top:4px}
/* ═══════════════════════════════════
SESSION
═══════════════════════════════════ */
.dots{display:flex;justify-content:center;gap:10px;margin-bottom:6px}
.dot{width:10px;height:10px;border-radius:50%;background:var(--line);transition:all .3s}
.dot.done{background:var(--primary)}
.dot.cur{background:var(--accent);transform:scale(1.3)}
.timer-wrap{position:relative;width:200px;height:200px;margin:8px auto 14px}
.t-ring{width:200px;height:200px;transform:rotate(-90deg)}
.tbg{fill:none;stroke:var(--line);stroke-width:6}
.tprog{fill:none;stroke:var(--primary);stroke-width:6;stroke-linecap:round;stroke-dasharray:534;stroke-dashoffset:0;transition:stroke-dashoffset 1s linear}
.t-disp{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.t-time{font-family:'Instrument Serif',serif;font-size:50px;letter-spacing:-1px;line-height:1}
.t-sub{font-family:'DM Sans',sans-serif;font-size:12px;color:var(--t3);font-weight:500;margin-top:2px}
.s-info{text-align:center;margin-bottom:24px}
.s-vis{width:150px;height:110px;margin:0 auto 14px;border-radius:20px;background:linear-gradient(135deg,var(--primary-l),#F5EDE6);display:flex;align-items:center;justify-content:center}
.s-vis svg{width:70px;height:50px;stroke:var(--primary);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.s-info h2{font-family:'Instrument Serif',serif;font-size:22px;font-weight:400;margin-bottom:8px}
.s-info p{color:var(--t2);font-size:14px;line-height:1.5;max-width:280px;margin:0 auto}
.s-btns{display:flex;gap:12px}
.s-btns .btn{flex:1}
/* ═══════════════════════════════════
PROGRESS
═══════════════════════════════════ */
.t-tabs{display:flex;gap:6px;margin:12px 0 18px;background:var(--dim);border-radius:12px;padding:4px}
.t-tb{flex:1;padding:9px;border:none;border-radius:10px;font-family:inherit;font-size:13px;font-weight:600;cursor:pointer;background:transparent;color:var(--t3);transition:all .2s}
.t-tb.on{background:var(--white);color:var(--text);box-shadow:0 1px 4px rgba(0,0,0,.06)}
.chart-c{background:var(--white);border-radius:18px;border:1px solid var(--line);padding:20px 14px 12px;margin-bottom:20px}
.chart-h{display:flex;justify-content:space-between;margin-bottom:8px}
.chart-h span:first-child{font-weight:600;font-size:14px}
.chart-h .cv{font-weight:700;font-size:14px;color:var(--green)}
.chart-svg{width:100%;height:auto;display:block}
.cg{stroke:var(--line);stroke-width:1}
.cl{fill:none;stroke:var(--primary);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:500;stroke-dashoffset:500}
.scr.on .cl{animation:drawLine 1.2s .3s ease forwards}
@keyframes drawLine{to{stroke-dashoffset:0}}
.ca{fill:url(#cg);opacity:0}
.scr.on .ca{animation:fadeInA .8s .8s ease forwards}
@keyframes fadeInA{to{opacity:.35}}
.cd{fill:var(--primary)}
.scr.on .cd{opacity:0}
.scr.on .cd{animation:fu .35s ease both}
.scr.on .cd:nth-child(7){animation-delay:.5s}
.scr.on .cd:nth-child(8){animation-delay:.6s}
.scr.on .cd:nth-child(9){animation-delay:.7s}
.scr.on .cd:nth-child(10){animation-delay:.8s}
.scr.on .cd:nth-child(11){animation-delay:.9s}
.scr.on .cd:nth-child(12){animation-delay:1s}
.scr.on .cd:nth-child(13){animation-delay:1.1s}
.dl{font-size:10px;fill:var(--t3);font-family:'DM Sans',sans-serif;font-weight:500}
.imp-row{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.imp-area{width:85px;font-size:13px;font-weight:600;flex-shrink:0}
.imp-track{flex:1;height:10px;background:var(--dim);border-radius:5px;overflow:hidden}
.imp-fill{height:100%;border-radius:5px;transition:width 1.2s ease}
.imp-pct{font-size:13px;font-weight:700;width:42px;text-align:right;color:var(--green)}
.ins-card{background:linear-gradient(135deg,#F5EDE6,#EDE4DA);border-radius:18px;padding:20px;margin-top:4px}
.ins-hd{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.ins-icon{width:32px;height:32px;border-radius:10px;background:var(--amber);display:flex;align-items:center;justify-content:center;font-size:16px}
.ins-hd span{font-weight:700;font-size:14px}
.ins-txt{font-size:13px;color:var(--t2);line-height:1.55}
/* ═══════════════════════════════════
PROFILE
═══════════════════════════════════ */
.pr-av{width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,var(--primary),var(--primary-d));display:flex;align-items:center;justify-content:center;font-family:'Instrument Serif',serif;font-size:28px;color:#fff;margin:0 auto 14px;box-shadow:0 4px 16px rgba(61,123,111,.2)}
.pr-name{text-align:center;font-family:'Instrument Serif',serif;font-size:24px;font-weight:400;margin-bottom:2px}
.pr-email{text-align:center;font-size:13px;color:var(--t3);margin-bottom:4px}
.pr-since{text-align:center;font-size:12px;color:var(--t3);margin-bottom:22px}
.pr-stats{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:24px}
.pr-st{text-align:center;background:var(--white);border:1px solid var(--line);border-radius:14px;padding:14px 8px}
.pr-st-v{font-family:'Instrument Serif',serif;font-size:24px;color:var(--primary);line-height:1}
.pr-st-l{font-size:10px;color:var(--t3);font-weight:600;text-transform:uppercase;letter-spacing:.6px;margin-top:3px}
.pr-sec{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:1px;color:var(--t3);margin-bottom:12px}
.pr-pi{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;background:var(--white);border:1px solid var(--line);border-radius:14px;margin-bottom:8px}
.pr-pl{display:flex;align-items:center;gap:12px}
.pr-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.pr-pn{font-size:14px;font-weight:600}
.pr-ps{font-size:13px;font-weight:700}
.pr-si{display:flex;align-items:center;justify-content:space-between;padding:15px 16px;background:var(--white);border:1px solid var(--line);border-radius:14px;margin-bottom:8px;cursor:pointer;transition:border-color .2s}
.pr-si:hover{border-color:var(--primary)}
.pr-sl{display:flex;align-items:center;gap:12px}
.pr-sic{width:34px;height:34px;border-radius:10px;background:var(--dim);display:flex;align-items:center;justify-content:center;font-size:16px}
.pr-stx{font-size:14px;font-weight:500}
.pr-sr{display:flex;align-items:center;gap:8px}
.pr-sv{font-size:13px;color:var(--t3);font-weight:500}
.pr-sa{color:var(--t3);font-size:16px}
.btn-out{margin-top:18px;background:transparent;color:var(--red);border:1.5px solid rgba(200,90,74,.2);font-weight:600}
.btn-out:hover{background:rgba(200,90,74,.06);border-color:rgba(200,90,74,.35)}
/* ── Loading Overlay ── */
.ld{position:absolute;inset:0;background:rgba(250,247,242,.96);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:center;z-index:200;opacity:0;pointer-events:none;transition:opacity .4s}
.ld.show{opacity:1;pointer-events:auto}
.ld-body{text-align:center}
.ld-star{font-size:32px;margin-bottom:20px;animation:pls 1.5s ease infinite}
@keyframes pls{0%,100%{transform:scale(1)}50%{transform:scale(1.15)}}
.ld-step{font-size:15px;color:var(--t2);margin-bottom:10px;opacity:0;transform:translateY(6px);transition:all .4s}
.ld-step.vis{opacity:1;transform:translateY(0)}
.ld-step.done{color:var(--green);font-weight:600}
.ld-dots{display:flex;gap:6px;justify-content:center;margin-top:14px}
.ld-dot{width:8px;height:8px;border-radius:50%;background:var(--line);transition:background .3s}
.ld-dot.active{background:var(--primary);animation:pls .6s ease infinite}
/* ── Responsive ── */
@media(max-height:920px){.phone{height:780px;border-radius:44px}.body-wrap{height:260px}}
@media(max-width:420px){.phone{width:100%;height:100vh;border-radius:0;box-shadow:none}body{padding:0}.demo-head{display:none}}
</style>
</head>
<body>
<div class="demo-head">
<h1>PainFree</h1>
<p>Interactive App Mockup</p>
</div>
<div class="phone">
<div class="island"></div>
<!-- Status Bar -->
<div class="sbar">
<span>9:41</span>
<div class="sb-r">
<svg viewBox="0 0 16 12"><path d="M1 8.5C3.5 4 7 2 8 1c1 1 4.5 3 7 7.5" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linecap="round"/><path d="M4 10.5C5.5 7 7 5.5 8 4.5c1 1 2.5 2.5 4 6" stroke="currentColor" stroke-width="1.4" fill="none" stroke-linecap="round"/><circle cx="8" cy="11" r="1" fill="currentColor"/></svg>
<div class="bat"><div class="bat-f"></div></div>
</div>
</div>
<div class="scrs">
<!-- ════ ONBOARDING ════ -->
<div class="scr on" id="s-ob">
<div class="si">
<div class="ob-head" data-a="1">
<h1>Where does<br>it hurt?</h1>
<p class="sub">Tap the areas where you feel pain</p>
</div>
<div class="body-wrap" data-a="2">
<svg class="body-svg" viewBox="0 0 200 400">
<circle class="base" cx="100" cy="32" r="22"/>
<line x1="88" y1="54" x2="88" y2="68"/>
<line x1="112" y1="54" x2="112" y2="68"/>
<path d="M58,88 C58,72 74,66 88,68 L112,68 C126,66 142,72 142,88"/>
<path d="M58,88 L58,182 C58,196 70,200 82,200 L118,200 C130,200 142,196 142,182 L142,88"/>
<path d="M58,88 L32,140 L22,186"/>
<path d="M142,88 L168,140 L178,186"/>
<path d="M22,186 L16,200 M22,186 L22,202 M22,186 L28,200"/>
<path d="M178,186 L184,200 M178,186 L178,202 M178,186 L172,200"/>
<path d="M82,200 L78,286 L76,348"/>
<path d="M118,200 L122,286 L124,348"/>
<path d="M76,348 L62,360 L78,358"/>
<path d="M124,348 L122,360 L138,360"/>
<!-- Hotspots -->
<circle class="hs" data-area="Neck" cx="100" cy="64" r="14"/>
<circle class="hs" data-area="L Shoulder" cx="58" cy="86" r="15"/>
<circle class="hs" data-area="R Shoulder" cx="142" cy="86" r="15"/>
<circle class="hs" data-area="Upper Back" cx="100" cy="112" r="20"/>
<circle class="hs" data-area="Lower Back" cx="100" cy="162" r="18"/>
<circle class="hs" data-area="L Elbow" cx="30" cy="156" r="12"/>
<circle class="hs" data-area="R Elbow" cx="170" cy="156" r="12"/>
<circle class="hs" data-area="L Wrist" cx="22" cy="190" r="11"/>
<circle class="hs" data-area="R Wrist" cx="178" cy="190" r="11"/>
<circle class="hs" data-area="L Hip" cx="82" cy="196" r="13"/>
<circle class="hs" data-area="R Hip" cx="118" cy="196" r="13"/>
<circle class="hs" data-area="L Knee" cx="76" cy="305" r="14"/>
<circle class="hs" data-area="R Knee" cx="124" cy="305" r="14"/>
</svg>
</div>
<div class="chips" id="chips" data-a="3"></div>
<div class="ob-foot" data-a="4">
<button class="btn btn-p" id="btnBuild" disabled>Build My Routine</button>
</div>
</div>
</div>
<!-- ════ HOME ════ -->
<div class="scr" id="s-home">
<div class="si">
<div class="hdr" data-a="1">
<div><p class="greet">Good morning</p><h1>Alex</h1></div>
<div class="strk">&#128293; 7 days</div>
</div>
<div class="chk" data-a="2">
<p class="chk-t">How's your pain today?</p>
<div class="pain-sc" id="painSc"></div>
</div>
<div class="start-card" id="startRoutine" data-a="3">
<div class="play-btn">
<svg viewBox="0 0 24 24"><polygon points="8,5 20,12 8,19"/></svg>
</div>
<div class="start-info">
<h3>Start Today's Routine</h3>
<p>12 min &middot; 5 exercises</p>
</div>
</div>
<div class="sec-h" data-a="4"><h2>Exercises</h2><span class="dur">Preview</span></div>
<div data-a="5">
<div class="ex-item" data-goto="s-sess"><div class="ex-n">1</div><div class="ex-bd"><div class="ex-nm">Cat-Cow Stretch</div><div class="ex-mt">8 reps &middot; Spine mobility</div></div><div class="ex-ar">&#8250;</div></div>
<div class="ex-item" data-goto="s-sess"><div class="ex-n">2</div><div class="ex-bd"><div class="ex-nm">Child's Pose</div><div class="ex-mt">45 sec &middot; Lower back release</div></div><div class="ex-ar">&#8250;</div></div>
<div class="ex-item" data-goto="s-sess"><div class="ex-n">3</div><div class="ex-bd"><div class="ex-nm">Bird Dog</div><div class="ex-mt">6 each side &middot; Core stability</div></div><div class="ex-ar">&#8250;</div></div>
<div class="ex-item" data-goto="s-sess"><div class="ex-n">4</div><div class="ex-bd"><div class="ex-nm">Doorway Chest Stretch</div><div class="ex-mt">30 sec &middot; Shoulder opener</div></div><div class="ex-ar">&#8250;</div></div>
<div class="ex-item" data-goto="s-sess"><div class="ex-n">5</div><div class="ex-bd"><div class="ex-nm">Neck Tilts</div><div class="ex-mt">10 each side &middot; Neck relief</div></div><div class="ex-ar">&#8250;</div></div>
</div>
<div class="st-row" data-a="6">
<div class="st-c"><div class="st-v">23</div><div class="st-l">Sessions</div></div>
<div class="st-c"><div class="st-v">4.2</div><div class="st-l">Avg Pain</div></div>
</div>
</div>
</div>
<!-- ════ SESSION ════ -->
<div class="scr" id="s-sess">
<div class="si">
<div class="dots" data-a="1">
<div class="dot done"></div>
<div class="dot cur"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<div class="timer-wrap" data-a="2">
<svg class="t-ring" viewBox="0 0 200 200">
<circle class="tbg" cx="100" cy="100" r="85"/>
<circle class="tprog" id="tprog" cx="100" cy="100" r="85"/>
</svg>
<div class="t-disp">
<span class="t-time" id="tdisp">0:30</span>
<span class="t-sub">hold &amp; breathe</span>
</div>
</div>
<div class="s-info" data-a="3">
<div class="s-vis">
<svg viewBox="0 0 100 70">
<circle cx="30" cy="14" r="8"/>
<path d="M30 22L30 42Q30 48 38 48L62 48Q68 48 68 42L68 36"/>
<path d="M30 28L18 38L12 50"/>
<path d="M42 48L40 64M56 48L58 64"/>
</svg>
</div>
<h2>Cat-Cow Stretch</h2>
<p>Slowly alternate between arching your back upward and dipping it down. Breathe deeply with each movement.</p>
</div>
<div class="s-btns" data-a="4">
<button class="btn btn-g" id="btnSkip">Skip</button>
<button class="btn btn-p" id="btnDone">Done &#8594;</button>
</div>
</div>
</div>
<!-- ════ PROGRESS ════ -->
<div class="scr" id="s-prog">
<div class="si">
<h1 style="font-family:'Instrument Serif',serif;font-size:28px;font-weight:400" data-a="1">Your Progress</h1>
<div class="t-tabs" data-a="2">
<button class="t-tb on">7D</button>
<button class="t-tb">30D</button>
<button class="t-tb">All</button>
</div>
<div class="chart-c" data-a="2">
<div class="chart-h"><span>Pain Level</span><span class="cv">&#8595; 42%</span></div>
<svg class="chart-svg" viewBox="0 0 320 130">
<defs>
<linearGradient id="cg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#3D7B6F" stop-opacity=".3"/>
<stop offset="100%" stop-color="#3D7B6F" stop-opacity="0"/>
</linearGradient>
</defs>
<line class="cg" x1="0" y1="26" x2="320" y2="26"/>
<line class="cg" x1="0" y1="52" x2="320" y2="52"/>
<line class="cg" x1="0" y1="78" x2="320" y2="78"/>
<line class="cg" x1="0" y1="104" x2="320" y2="104"/>
<polygon class="ca" points="24,28 68,37 112,32 156,46 200,51 244,64 288,76 288,130 24,130"/>
<polyline class="cl" points="24,28 68,37 112,32 156,46 200,51 244,64 288,76"/>
<circle class="cd" cx="24" cy="28" r="4.5"/>
<circle class="cd" cx="68" cy="37" r="4.5"/>
<circle class="cd" cx="112" cy="32" r="4.5"/>
<circle class="cd" cx="156" cy="46" r="4.5"/>
<circle class="cd" cx="200" cy="51" r="4.5"/>
<circle class="cd" cx="244" cy="64" r="4.5"/>
<circle class="cd" cx="288" cy="76" r="4.5"/>
<text class="dl" x="24" y="124" text-anchor="middle">Mon</text>
<text class="dl" x="68" y="124" text-anchor="middle">Tue</text>
<text class="dl" x="112" y="124" text-anchor="middle">Wed</text>
<text class="dl" x="156" y="124" text-anchor="middle">Thu</text>
<text class="dl" x="200" y="124" text-anchor="middle">Fri</text>
<text class="dl" x="244" y="124" text-anchor="middle">Sat</text>
<text class="dl" x="288" y="124" text-anchor="middle">Sun</text>
</svg>
</div>
<div class="sec-h" data-a="3"><h2>Pain Reduction</h2></div>
<div data-a="3">
<div class="imp-row">
<span class="imp-area">Lower Back</span>
<div class="imp-track"><div class="imp-fill" style="width:65%;background:var(--primary)"></div></div>
<span class="imp-pct">&#8722;65%</span>
</div>
<div class="imp-row">
<span class="imp-area">Neck</span>
<div class="imp-track"><div class="imp-fill" style="width:40%;background:var(--primary)"></div></div>
<span class="imp-pct">&#8722;40%</span>
</div>
<div class="imp-row">
<span class="imp-area">R Shoulder</span>
<div class="imp-track"><div class="imp-fill" style="width:55%;background:var(--amber)"></div></div>
<span class="imp-pct">&#8722;55%</span>
</div>
</div>
<div class="ins-card" data-a="4">
<div class="ins-hd"><div class="ins-icon">&#10022;</div><span>AI Insight</span></div>
<p class="ins-txt">Your lower back pain dropped significantly this week. The Cat-Cow stretch and Bird Dog exercises seem most effective. On days you completed sessions, your pain was <strong>40% lower</strong> than rest days. Keep the streak going.</p>
</div>
</div>
</div>
<!-- ════ PROFILE ════ -->
<div class="scr" id="s-prof">
<div class="si">
<div class="pr-av" data-a="1">AM</div>
<div class="pr-name" data-a="1">Alex Mitchell</div>
<div class="pr-email" data-a="1">alex.m@email.com</div>
<div class="pr-since" data-a="1">Member since Jan 2024</div>
<div class="pr-stats" data-a="2">
<div class="pr-st"><div class="pr-st-v">23</div><div class="pr-st-l">Sessions</div></div>
<div class="pr-st"><div class="pr-st-v">7</div><div class="pr-st-l">Streak</div></div>
<div class="pr-st"><div class="pr-st-v">4.2</div><div class="pr-st-l">Avg Pain</div></div>
</div>
<div class="pr-sec" data-a="3">Pain Areas</div>
<div data-a="3">
<div class="pr-pi">
<div class="pr-pl"><div class="pr-dot" style="background:var(--red)"></div><div class="pr-pn">Lower Back</div></div>
<div class="pr-ps" style="color:var(--red)">7/10</div>
</div>
<div class="pr-pi">
<div class="pr-pl"><div class="pr-dot" style="background:var(--amber)"></div><div class="pr-pn">Right Shoulder</div></div>
<div class="pr-ps" style="color:var(--amber)">5/10</div>
</div>
<div class="pr-pi">
<div class="pr-pl"><div class="pr-dot" style="background:var(--amber)"></div><div class="pr-pn">Neck</div></div>
<div class="pr-ps" style="color:var(--amber)">4/10</div>
</div>
</div>
<div class="pr-sec" style="margin-top:22px" data-a="4">Settings</div>
<div data-a="4">
<div class="pr-si"><div class="pr-sl"><div class="pr-sic">&#128276;</div><div class="pr-stx">Notifications</div></div><div class="pr-sr"><div class="pr-sv">On</div><div class="pr-sa">&#8250;</div></div></div>
<div class="pr-si"><div class="pr-sl"><div class="pr-sic">&#9200;</div><div class="pr-stx">Daily Reminder</div></div><div class="pr-sr"><div class="pr-sv">9:00 AM</div><div class="pr-sa">&#8250;</div></div></div>
<div class="pr-si"><div class="pr-sl"><div class="pr-sic">&#9201;</div><div class="pr-stx">Session Length</div></div><div class="pr-sr"><div class="pr-sv">15 min</div><div class="pr-sa">&#8250;</div></div></div>
<div class="pr-si"><div class="pr-sl"><div class="pr-sic">&#128202;</div><div class="pr-stx">Export My Data</div></div><div class="pr-sr"><div class="pr-sa">&#8250;</div></div></div>
<div class="pr-si"><div class="pr-sl"><div class="pr-sic">&#10067;</div><div class="pr-stx">Help &amp; FAQ</div></div><div class="pr-sr"><div class="pr-sa">&#8250;</div></div></div>
</div>
<button class="btn btn-out" data-a="5">Sign Out</button>
</div>
</div>
</div>
<!-- Loading Overlay -->
<div class="ld" id="load">
<div class="ld-body">
<div class="ld-star">&#10022;</div>
<div class="ld-step" id="ls1">Analyzing your pain profile...</div>
<div class="ld-step" id="ls2">Selecting personalized exercises...</div>
<div class="ld-step" id="ls3">Your plan is ready!</div>
<div class="ld-dots">
<div class="ld-dot" id="ld1"></div>
<div class="ld-dot" id="ld2"></div>
<div class="ld-dot" id="ld3"></div>
</div>
</div>
</div>
<!-- Tab Bar -->
<div class="tbar hide" id="tbar">
<button class="tbtn on" data-s="s-home">
<svg viewBox="0 0 24 24"><path d="M3 12L12 4l9 8"/><path d="M5 10v9a1 1 0 001 1h4v-5h4v5h4a1 1 0 001-1v-9"/></svg>
<span>Home</span>
</button>
<button class="tbtn" data-s="s-sess">
<svg viewBox="0 0 24 24"><path d="M4 6h16"/><path d="M4 12h16"/><path d="M4 18h10"/></svg>
<span>Routine</span>
</button>
<button class="tbtn" data-s="s-prog">
<svg viewBox="0 0 24 24"><path d="M4 20h16"/><path d="M4 16l5-5 4 3 7-8"/></svg>
<span>Progress</span>
</button>
<button class="tbtn" data-s="s-prof">
<svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 21v-1a7 7 0 0114 0v1"/></svg>
<span>Profile</span>
</button>
</div>
</div>
<script>
const $ = s => document.querySelector(s);
const $$ = s => document.querySelectorAll(s);
const areas = new Set();
let tInt = null;
let tSec = 30;
const CIRC = 2 * Math.PI * 85;
const tprog = $('#tprog');
tprog.style.strokeDasharray = CIRC;
tprog.style.strokeDashoffset = '0';
/* ── Screen Navigation ── */
function show(id) {
$$('.scr').forEach(s => s.classList.remove('on'));
const el = $('#' + id);
if (el) el.classList.add('on');
$$('.tbtn').forEach(t => t.classList.toggle('on', t.dataset.s === id));
if (id === 's-ob') {
$('#tbar').classList.add('hide');
} else {
$('#tbar').classList.remove('hide');
}
if (id === 's-sess') {
resetTimer();
startTimer();
}
}
/* Tab bar clicks */
$$('.tbtn').forEach(t => {
t.addEventListener('click', () => {
const s = t.dataset.s;
if (s) show(s);
});
});
/* Exercise items navigate to session */
$$('[data-goto]').forEach(el => {
el.addEventListener('click', () => show(el.dataset.goto));
});
/* Start Routine card */
$('#startRoutine').addEventListener('click', () => show('s-sess'));
/* ── Body Map Interaction ── */
$$('.hs').forEach(h => {
h.addEventListener('click', () => {
const a = h.dataset.area;
if (areas.has(a)) {
areas.delete(a);
h.classList.remove('sel');
} else {
areas.add(a);
h.classList.add('sel');
}
renderChips();
$('#btnBuild').disabled = areas.size === 0;
});
});
function renderChips() {
const c = $('#chips');
c.innerHTML = '';
areas.forEach(a => {
const d = document.createElement('div');
d.className = 'chip';
d.innerHTML = a + '<button data-area="' + a + '">&times;</button>';
c.appendChild(d);
});
c.querySelectorAll('button').forEach(b => {
b.addEventListener('click', e => {
e.stopPropagation();
const a = b.dataset.area;
areas.delete(a);
document.querySelector('.hs[data-area="' + a + '"]').classList.remove('sel');
renderChips();
$('#btnBuild').disabled = areas.size === 0;
});
});
}
/* ── Build Routine → Loading → Home ── */
$('#btnBuild').addEventListener('click', () => {
if (areas.size === 0) return;
const ld = $('#load');
const s1 = $('#ls1'), s2 = $('#ls2'), s3 = $('#ls3');
const d1 = $('#ld1'), d2 = $('#ld2'), d3 = $('#ld3');
/* Reset */
[s1, s2, s3].forEach(s => s.className = 'ld-step');
[d1, d2, d3].forEach(d => d.className = 'ld-dot');
ld.classList.add('show');
/* Step 1 */
setTimeout(() => {
s1.classList.add('vis');
d1.classList.add('active');
}, 100);
/* Step 2 */
setTimeout(() => {
s1.classList.add('done');
s1.classList.remove('vis');
s2.classList.add('vis');
d2.classList.add('active');
}, 900);
/* Step 3 */
setTimeout(() => {
s2.classList.add('done');
s2.classList.remove('vis');
s3.classList.add('vis');
d3.classList.add('active');
}, 1700);
/* Transition to home */
setTimeout(() => {
ld.classList.remove('show');
show('s-home');
}, 2600);
});
/* ── Pain Scale (Home) ── */
for (let i = 1; i <= 10; i++) {
const b = document.createElement('button');
b.className = 'pn';
b.textContent = i;
b.addEventListener('click', () => {
$$('.pn').forEach(p => p.classList.remove('sel'));
b.classList.add('sel');
});
$('#painSc').appendChild(b);
}
/* ── Timer ── */
function resetTimer() {
clearInterval(tInt);
tSec = 30;
$('#tdisp').textContent = '0:30';
tprog.style.strokeDashoffset = '0';
}
function startTimer() {
tInt = setInterval(() => {
tSec--;
if (tSec < 0) {
clearInterval(tInt);
$('#tdisp').textContent = '0:00';
return;
}
const m = Math.floor(tSec / 60);
const s = tSec % 60;
$('#tdisp').textContent = m + ':' + String(s).padStart(2, '0');
tprog.style.strokeDashoffset = String(CIRC * ((30 - tSec) / 30));
}, 1000);
}
$('#btnSkip').addEventListener('click', () => { resetTimer(); startTimer(); });
$('#btnDone').addEventListener('click', () => { resetTimer(); startTimer(); });
/* ── Time Tabs (Progress) ── */
$$('.t-tb').forEach(t => {
t.addEventListener('click', () => {
$$('.t-tb').forEach(x => x.classList.remove('on'));
t.classList.add('on');
});
});
/* ── Preselect Lower Back for demo ── */
setTimeout(() => {
const demo = document.querySelector('.hs[data-area="Lower Back"]');
if (demo) demo.click();
}, 500);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment