1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 7 <title>GymDose: Gym Supplement Tracker for iOS & Android | Never Miss a Dose</title> 8 <meta name="description" content="Track your gym supplements with ease. Four time slots, smart reminders, streaks, widgets, Live Activity, 7 themes, 13 languages. Free on iOS & Android."> 9 <meta name="keywords" content="gym supplement tracker, supplement reminder, creatine tracker, pre workout tracker, fitness supplements, iOS supplement app, workout supplements, daily supplement tracker, gym app"> 10 <meta name="author" content="Baransel"> 11 <meta name="robots" content="index, follow"> 12 <meta name="theme-color" content="#F2F3F7"> 13 <link rel="canonical" href="https://baransel.dev/gymdose"> 14 <meta property="og:type" content="website"> 15 <meta property="og:title" content="GymDose: Never Miss a Supplement Again"> 16 <meta property="og:description" content="The cleanest supplement tracker. Four time slots, smart reminders, widgets, Live Activity, streaks. Free to download."> 17 <meta property="og:url" content="https://baransel.dev/gymdose"> 18 <meta property="og:site_name" content="GymDose"> 19 <meta property="og:image" content="https://baransel.dev/gymdose/og-image.png"> 20 <meta name="twitter:card" content="summary_large_image"> 21 <meta name="twitter:title" content="GymDose: Never Miss a Supplement Again"> 22 <meta name="twitter:description" content="The cleanest supplement tracker. Smart reminders, widgets, Live Activity, streaks."> 23 <meta name="twitter:image" content="https://baransel.dev/gymdose/og-image.png"> 24 <meta name="apple-itunes-app" content="app-id=6756020237"> 25 <link rel="icon" type="image/png" href="icon-180.png"> 26 <link rel="apple-touch-icon" href="icon-180.png"> 27 <link rel="preconnect" href="https://fonts.googleapis.com"> 28 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 29 <link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@500;600;800&display=swap" rel="stylesheet"> 30 <style> 31 *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box } 32 33 :root { 34 --bg: #F2F3F7; 35 --card: #FFFFFF; 36 --panel: #F6F7FA; 37 --ink: #101114; 38 --dim: #6B6F7A; 39 --faint: #9DA0AB; 40 --line: #E3E5EC; 41 --blue: #0A7AFF; 42 --blue-deep: #0063D6; 43 --morning: #FF9500; 44 --pre: #FF3B30; 45 --post: #34C759; 46 --night: #5E5CE6; 47 --dark: #141417; 48 } 49 50 @property --p { syntax: '<number>'; inherits: false; initial-value: 0 } 51 52 html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale } 53 html, body { overflow-x: clip } 54 55 body { 56 font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; 57 background: var(--bg); 58 color: var(--ink); 59 } 60 61 ::selection { background: var(--blue); color: #fff } 62 a { color: inherit } 63 :focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 6px } 64 65 .disp { 66 font-family: 'Barlow Condensed', 'Arial Narrow', sans-serif; 67 font-weight: 800; 68 text-transform: uppercase; 69 letter-spacing: -.005em; 70 } 71 72 .container { max-width: 1120px; margin: 0 auto; padding: 0 24px } 73 74 /* scroll reveals */ 75 .r { opacity: 0; transform: translateY(26px); transition: opacity .8s cubic-bezier(.16,1,.3,1), transform .8s cubic-bezier(.16,1,.3,1) } 76 .r.v { opacity: 1; transform: none } 77 .r.d1 { transition-delay: .08s } 78 .r.d2 { transition-delay: .16s } 79 .r.d3 { transition-delay: .24s } 80 81 /* ---------- nav ---------- */ 82 nav { 83 position: fixed; top: 0; left: 0; right: 0; z-index: 50; 84 background: rgba(242,243,247,.82); 85 -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); 86 border-bottom: 1px solid transparent; 87 transition: border-color .3s; 88 } 89 nav.s { border-color: var(--line) } 90 .nv { max-width: 1120px; margin: 0 auto; padding: 14px 24px; display: flex; align-items: center; justify-content: space-between } 91 .logo { display: flex; align-items: center; gap: 10px; text-decoration: none; font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 1.35rem; text-transform: uppercase; letter-spacing: .04em } 92 .logo img { border-radius: 8px; display: block } 93 .nav-dl { 94 font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .92rem; 95 letter-spacing: .12em; text-transform: uppercase; text-decoration: none; 96 color: #fff; background: var(--blue); padding: 9px 20px 8px; border-radius: 999px; 97 transition: background .2s; 98 } 99 .nav-dl:hover { background: var(--blue-deep) } 100 101 /* ---------- hero ---------- */ 102 .hero { padding: 132px 0 84px } 103 .hero-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: 56px; align-items: center } 104 .hero-grid > * { min-width: 0 } 105 106 .eb { 107 display: inline-flex; align-items: center; gap: 10px; 108 font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .88rem; 109 letter-spacing: .22em; text-transform: uppercase; color: var(--dim); 110 margin-bottom: 18px; 111 } 112 .eb::before { content: ''; width: 9px; height: 9px; border-radius: 3px; background: var(--eb-c, var(--blue)) } 113 114 h1 { 115 font-size: clamp(3.5rem, 8vw, 6.15rem); 116 line-height: .88; 117 margin-bottom: 24px; 118 } 119 h1 .blue { color: var(--blue) } 120 121 .hero-sub { font-size: 1.08rem; line-height: 1.65; color: var(--dim); max-width: 46ch; margin-bottom: 32px } 122 .hero-sub b { color: var(--ink); font-weight: 600 } 123 124 .badges { display: flex; gap: 14px; flex-wrap: wrap; align-items: center } 125 .badges a { display: inline-block; transition: transform .2s } 126 .badges a:hover { transform: translateY(-2px) } 127 .badges .apple img { height: 52px; width: auto; display: block } 128 .badges .google img { height: 76px; width: auto; display: block; margin: -12px 0 } 129 130 .hero-note { 131 margin-top: 20px; 132 font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .8rem; 133 letter-spacing: .2em; text-transform: uppercase; color: var(--faint); 134 } 135 136 /* ---------- live demo card ---------- */ 137 .demo-wrap { position: relative; max-width: 430px; justify-self: end; width: 100% } 138 139 .notif { 140 position: absolute; top: -34px; right: -14px; z-index: 3; 141 width: min(310px, 92%); 142 display: flex; gap: 10px; align-items: center; 143 background: rgba(252,252,253,.9); 144 -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); 145 border: 1px solid var(--line); border-radius: 16px; 146 padding: 10px 14px 10px 10px; 147 box-shadow: 0 14px 36px rgba(24,30,50,.16); 148 opacity: 0; transform: translateY(-16px); 149 transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1); 150 } 151 .notif.on { opacity: 1; transform: none } 152 .notif img { width: 32px; height: 32px; border-radius: 8px } 153 .notif-t { flex: 1; min-width: 0 } 154 .notif-t em { display: flex; justify-content: space-between; font-style: normal; font-size: .64rem; font-weight: 700; letter-spacing: .08em; color: var(--faint); text-transform: uppercase } 155 .notif-t p { font-size: .8rem; font-weight: 500; line-height: 1.35; color: var(--ink) } 156 157 .demo { 158 position: relative; z-index: 2; 159 background: var(--card); border-radius: 28px; 160 padding: 22px 22px 10px; 161 box-shadow: 0 30px 70px rgba(24,30,50,.12), 0 2px 10px rgba(24,30,50,.05); 162 } 163 .demo-head { display: flex; align-items: flex-start; justify-content: space-between } 164 .demo-head h2 { font-size: 1.55rem; font-weight: 800; letter-spacing: -.02em } 165 .demo-head small { display: block; margin-top: 2px; font-size: .82rem; color: var(--dim) } 166 .flame { 167 background: #FFF3E0; color: #B45D00; border-radius: 999px; 168 padding: 7px 13px; font-weight: 700; font-size: .92rem; white-space: nowrap; 169 } 170 .flame.pop { animation: pop .5s cubic-bezier(.16,1,.3,1) } 171 @keyframes pop { 40% { transform: scale(1.22) } } 172 173 .demo-sum { 174 display: flex; align-items: center; gap: 18px; 175 background: var(--panel); border-radius: 20px; 176 padding: 16px; margin-top: 16px; 177 } 178 .ring { 179 --p: 0; 180 width: 96px; height: 96px; border-radius: 50%; flex-shrink: 0; 181 background: conic-gradient(var(--rc, var(--blue)) calc(var(--p) * 1%), #E5E7EF 0); 182 display: grid; place-items: center; 183 transition: --p .7s cubic-bezier(.16,1,.3,1); 184 } 185 .ring i { width: 70px; height: 70px; border-radius: 50%; background: var(--card); display: grid; place-items: center; font-style: normal; text-align: center } 186 .ring b { display: block; font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em } 187 .ring small { display: block; font-size: .6rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--faint) } 188 .sum-t b { display: block; font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.1 } 189 .sum-t span { display: block; font-size: .85rem; color: var(--dim) } 190 .sum-t em { display: block; margin-top: 8px; font-style: normal; font-size: .8rem; font-weight: 600; color: var(--ink) } 191 .sum-t em i { font-style: normal;
191 color: var(--faint); font-weight: 500 } 192 193 .dslot { 194 display: flex; align-items: center; gap: 9px; 195 margin-top: 16px; padding-bottom: 7px; 196 font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .82rem; 197 letter-spacing: .16em; text-transform: uppercase; color: var(--dim); 198 } 199 .dslot i { width: 23px; height: 23px; border-radius: 7px; background: color-mix(in srgb, var(--c) 16%, #fff); display: grid; place-items: center; font-size: 12px; font-style: normal } 200 .dslot span { margin-left: auto; font-size: .72rem; letter-spacing: .12em; color: var(--faint) } 201 202 .dose { 203 display: flex; align-items: center; gap: 12px; width: 100%; 204 padding: 9px 2px; border: 0; border-top: 1px solid var(--panel); 205 background: none; cursor: pointer; font: inherit; text-align: left; 206 border-radius: 8px; 207 } 208 .dchk { 209 width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; 210 border: 2px solid #D5D8E1; display: grid; place-items: center; 211 transition: background .25s, border-color .25s; 212 } 213 .dchk::after { content: 'â'; color: #fff; font-size: .78rem; font-weight: 800; opacity: 0; transform: scale(.4); transition: opacity .2s, transform .25s cubic-bezier(.16,1,.3,1) } 214 .dose[aria-pressed="true"] .dchk { background: var(--c); border-color: var(--c) } 215 .dose[aria-pressed="true"] .dchk::after { opacity: 1; transform: scale(1) } 216 .dname { flex: 1; font-size: .95rem; font-weight: 500; position: relative; transition: color .25s } 217 .dname::after { content: ''; position: absolute; left: -2px; right: -2px; top: 54%; height: 1.5px; background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .3s cubic-bezier(.16,1,.3,1) } 218 .dose[aria-pressed="true"] .dname { color: var(--faint) } 219 .dose[aria-pressed="true"] .dname::after { transform: scaleX(1) } 220 .ddose { font-size: .72rem; font-weight: 600; letter-spacing: .07em; color: var(--faint); text-transform: uppercase; font-variant-numeric: tabular-nums } 221 222 .demo-hint { text-align: center; padding: 12px 0 8px; font-size: .78rem; color: var(--faint); border-top: 1px solid var(--panel); margin-top: 10px } 223 224 /* ---------- dose strip ---------- */ 225 .strip { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 15px 0; overflow: hidden } 226 .strip-in { display: flex; gap: 38px; width: max-content; animation: mq 30s linear infinite } 227 .strip-in span { display: flex; align-items: center; gap: 9px; font-size: .78rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); white-space: nowrap } 228 .strip-in span i { width: 7px; height: 7px; border-radius: 50%; background: var(--c); flex-shrink: 0 } 229 .strip-in span b { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums } 230 @keyframes mq { to { transform: translateX(-50%) } } 231 232 /* ---------- sections ---------- */ 233 .sec { padding: 100px 0 } 234 .sec-head { max-width: 660px; margin-bottom: 48px } 235 .h2 { font-size: clamp(2.5rem, 4.8vw, 3.8rem); line-height: .92 } 236 .sub { margin-top: 16px; font-size: 1.04rem; line-height: 1.62; color: var(--dim) } 237 .sub b { color: var(--ink); font-weight: 600 } 238 239 /* ---------- slots ---------- */ 240 .slotgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px } 241 .slot { background: var(--card); border-radius: 24px; padding: 24px 22px 22px; display: flex; flex-direction: column; gap: 0 } 242 .slot-ic { width: 46px; height: 46px; border-radius: 13px; background: color-mix(in srgb, var(--c) 15%, #fff); display: grid; place-items: center; font-size: 21px; margin-bottom: 16px } 243 .slot h3 { font-family: 'Barlow Condensed', sans-serif; font-weight: 800; font-size: 1.6rem; text-transform: uppercase; letter-spacing: .01em } 244 .slot-time { display: inline-flex; align-items: center; gap: 7px; margin: 6px 0 12px; font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .8rem; letter-spacing: .18em; text-transform: uppercase; color: var(--c) } 245 .slot p { font-size: .9rem; line-height: 1.55; color: var(--dim); flex: 1 } 246 .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px } 247 .chip { border: 1px solid var(--line); border-radius: 8px; padding: 4px 8px 3px; font-size: .66rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); white-space: nowrap } 248 .chip.hot { border-color: transparent; background: color-mix(in srgb, var(--c) 14%, #fff); color: color-mix(in srgb, var(--c) 78%, #000) } 249 250 /* ---------- supplement facts ---------- */ 251 .facts-grid { display: grid; grid-template-columns: 1fr 430px; gap: 64px; align-items: start } 252 .facts-copy .sub { max-width: 44ch } 253 .facts-copy .eb { --eb-c: var(--ink) } 254 .fine { margin-top: 28px; font-size: .8rem; line-height: 1.6; color: var(--faint); max-width: 40ch } 255 256 .label { 257 background: #fff; border: 2.5px solid var(--ink); border-radius: 6px; 258 padding: 16px 18px 14px; color: var(--ink); 259 box-shadow: 12px 12px 0 var(--line); 260 } 261 .label h3 { font-weight: 900; font-size: clamp(1.7rem, 3vw, 2.15rem); letter-spacing: -.045em; line-height: 1.05 } 262 .label-meta { font-size: .84rem; padding: 5px 0 7px } 263 .label-meta div { display: flex; justify-content: space-between; gap: 12px } 264 .lbar { height: 8px; background: var(--ink); margin: 3px 0 } 265 .lbar.thin { height: 4px } 266 .lhead { display: flex; justify-content: space-between; font-size: .72rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: 6px 0; border-bottom: 1px solid var(--ink) } 267 .lrow { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; padding: 6.5px 0; border-bottom: 1px solid var(--ink); font-size: .92rem } 268 .lrow:last-of-type { border-bottom: none } 269 .lrow b { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap } 270 .lfoot { padding-top: 9px; font-size: .7rem; line-height: 1.5; color: #3A3C42 } 271 272 /* ---------- screenshots ---------- */ 273 .shots .sec-head { margin-bottom: 40px } 274 .shots-track { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 8px 24px 28px; cursor: grab } 275 .shots-track::-webkit-scrollbar { display: none } 276 .shots-in { display: flex; gap: 20px; width: max-content; margin: 0 auto } 277 .shot { width: 234px; flex-shrink: 0 } 278 .shot img { width: 100%; height: auto; display: block; border-radius: 26px; border: 1px solid var(--line); box-shadow: 0 16px 40px rgba(24,30,50,.09) } 279 .shot figcaption { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 13px; font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .84rem; letter-spacing: .18em; text-transform: uppercase; color: var(--dim) } 280 .shot figcaption i { width: 7px; height: 7px; border-radius: 50%; background: var(--c, var(--blue)) } 281 282 /* ---------- cta ---------- */ 283 .cta-card { 284 position: relative; overflow: hidden; 285 background: var(--dark); border-radius: 32px; 286 padding: clamp(60px, 8vw, 96px) 28px; text-align: center; color: #fff; 287 } 288 .cta-card::before { 289 content: ''; position: absolute; inset: 0; pointer-events: none; 290 background: radial-gradient(44% 52% at 50% 0%, rgba(255,149,0,.14), transparent 70%), 291 radial-gradient(40% 44% at 50% 108%, rgba(10,122,255,.12), transparent 70%); 292 } 293 .cta-in { position: relative; z-index: 1 } 294 .cta-card .h2 { color: #fff } 295 .cta-card .h2 .hot { color: var(--morning) } 296 .cta-card .sub { color: rgba(255,255,255,.55); max-width: 46ch; margin-left: auto; margin-right: auto } 297 .cta-card .badges { justify-content: center; margin-top: 34px } 298 .cta-note { margin-top: 22px; font-family: 'Barlow Condensed', sans-serif; font-weight: 600; font-size: .8rem; letter-spacing: .22em; text-transform: uppercase; color: rgba(255,255,255,.38) } 299 300 /* ---------- footer ---------- */ 301 footer { padding: 36px 0 40px } 302 .ft { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px } 303 .ft-l { font-size: .8rem; color: var(--faint) } 304 .ft-r { display: flex; gap: 22px } 305 .ft-r a { font-size: .8rem; color: var(--dim); text-decoration: none } 306 .ft-r a:hover { color: var(--blue) } 307 308 /* ---------- responsive ---------- */ 309 @media (max-width: 980px) { 310 .hero { padding: 116px 0 64px } 311 .hero-grid { grid-template-columns: 1fr; gap: 64px } 312 .demo-wrap { justify-self: center; max-width: 420px } 313 .slotgrid { grid-template-columns: 1fr 1fr } 314 .facts-grid { grid-template-columns: 1fr; gap: 44px } 315 .label { max-width: 460px } 316 .sec { padding: 76px 0 } 317 } 318 @media (max-width: 560px) { 319 .slotgrid { grid-template-columns: 1fr } 320 .notif { right: 0; top: -30px } 321 .shot { width: 196px } 322 h1 { font-size: clamp(3.2rem, 15vw, 4.4rem) } 323 } 324 325 @media (prefers-reduced-motion: reduce) { 326 html { scroll-behavior: auto } 327 .r { opacity: 1; transform: none; transition: none } 328 .strip-in { animation: none } 329 .ring { transition: none } 330 .notif { transition: none } 331 .badges a, .flame.pop { transition: none; animation: none } 332 } 333 </style> 334
334<script type="application/ld+json">{"@context":"https://schema.org","@type":"MobileApplication","name":"GymDose","description":"The cleanest gym supplement tracker. Track daily supplements across 4 time slots with smart reminders, widgets, Live Activity, and streak tracking.","operatingSystem":"iOS, Android","applicationCategory":"HealthApplication","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"aggregateRating":{"@type":"AggregateRating","ratingValue":"4.8","ratingCount":"120"},"author":{"@type":"Person","name":"Baransel"}}</script>
334 335</head> 336 337<body> 338 <nav id="nav"> 339 <div class="nv"> 340 <a href="#" class="logo"><img src="icon-small.webp" alt="" width="30" height="30">GymDose</a> 341 <a href="#cta" class="nav-dl">Download</a> 342 </div> 343 </nav> 344 345 <!-- ================= hero ================= --> 346 <header class="hero"> 347 <div class="container hero-grid"> 348 <div> 349 <p class="eb r">Gym supplement tracker · iOS & Android</p> 350 <h1 class="disp r d1">Never miss a<br><span class="blue">supplement</span> again.</h1> 351 <p class="hero-sub r d2">Your whole stack in four slots: <b>morning, pre, post, night</b>. One tap logs a dose. A streak keeps you honest.</p> 352 <div class="badges r d3"> 353 <a class="apple" href="https://apps.apple.com/app/gymdose-supplement-tracker/id6756020237" aria-label="Download GymDose on the App Store"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83" alt="Download on the App Store" width="156" height="52" loading="eager"></a> 354 <a class="google" href="https://play.google.com/store/apps/details?id=com.baransel.dev.gym.supplement.tracker" aria-label="Get GymDose on Google Play"><img src="android.png" alt="Get it on Google Play" height="76" loading="eager"></a> 355 </div> 356 <p class="hero-note r d3">Free to use · 100% offline · No account</p> 357 </div> 358 359 <div class="demo-wrap r d2"> 360 <div class="notif" id="notif" role="status"> 361 <img src="icon-small.webp" alt="" width="32" height="32"> 362 <div class="notif-t"> 363 <em>GymDose <span>now</span></em> 364 <p id="notif-msg">Night stack at 21:00. Don't break the streak.</p> 365 </div> 366 </div> 367 368 <div class="demo" id="demo"> 369 <div class="demo-head"> 370 <div> 371 <h2>Today</h2> 372 <small>Thu, 20 Aug</small> 373 </div> 374 <span class="flame" id="flame">ð¥ 15</span> 375 </div> 376 377 <div class="demo-sum"> 378 <div class="ring" id="ring" role="img" aria-label="0 of 8 doses taken"> 379 <i><span><b id="ring-n">0/8</b><small>taken</small></span></i> 380 </div> 381 <div class="sum-t" aria-live="polite"> 382 <b id="rem">8</b> 383 <span>Remaining</span> 384 <em id="next"><i>Next up</i> âï¸ Morning</em> 385 </div> 386 </div> 387 388 <div class="dslot" style="--c:var(--morning)"><i>âï¸</i>Morning<span>08:00</span></div> 389 <button class="dose" style="--c:var(--morning)" data-slot="morning" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Vitamin D3</span><span class="ddose">4000 iu</span></button> 390 <button class="dose" style="--c:var(--morning)" data-slot="morning" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Omega-3</span><span class="ddose">2 capsules</span></button> 391 392 <div class="dslot" style="--c:var(--pre)"><i>â¡</i>Pre-Workout<span>Tâ30 min</span></div> 393 <button class="dose" style="--c:var(--pre)" data-slot="pre" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Pre-Workout</span><span class="ddose">1 scoop</span></button> 394 395 <div class="dslot" style="--c:var(--post)"><i>ðï¸</i>Post-Workout<span>19:00</span></div> 396 <button class="dose" style="--c:var(--post)" data-slot="post" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Creatine</span><span class="ddose">5 g</span></button> 397 <button class="dose" style="--c:var(--post)" data-slot="post" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Protein</span><span class="ddose">1 scoop</span></button> 398 399 <div class="dslot" style="--c:var(--night)"><i>ð</i>Night<span>21:00</span></div> 400 <button class="dose" style="--c:var(--night)" data-slot="night" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Ashwagandha</span><span class="ddose">600 mg</span></button> 401 <button class="dose" style="--c:var(--night)" data-slot="night" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">Magnesium</span><span class="ddose">400 mg</span></button> 402 <button class="dose" style="--c:var(--night)" data-slot="night" aria-pressed="false"><span class="dchk" aria-hidden="true"></span><span class="dname">ZMA</span><span class="ddose">3 capsules</span></button> 403 404 <p class="demo-hint" id="hint">Live demo: tap a dose to log it.</p> 405 </div> 406 </div> 407 </div> 408 </header> 409 410 <!-- ================= dose strip ================= --> 411 <div class="strip" aria-hidden="true"> 412 <div class="strip-in" id="strip">
413 <span style="--c:var(--morning)"><i></i>Vitamin D3 <b>4000 iu</b></span> 414 <span style="--c:var(--morning)"><i></i>Omega-3 <b>2 capsules</b></span> 415 <span style="--c:var(--pre)"><i></i>Pre-Workout <b>1 scoop</b></span> 416 <span style="--c:var(--post)"><i></i>Creatine <b>5 g</b></span> 417 <span style="--c:var(--post)"><i></i>Protein <b>1 scoop</b></span> 418 <span style="--c:var(--night)"><i></i>Ashwagandha <b>600 mg</b></span> 419 <span style="--c:var(--night)"><i></i>Magnesium <b>400 mg</b></span> 420 <span style="--c:var(--night)"><i></i>ZMA <b>3 capsules</b></span> 421 </div> 422 </div> 423 424 <!-- ================= slots ================= --> 425 <section class="sec"> 426 <div class="container"> 427 <div class="sec-head r"> 428 <p class="eb" style="--eb-c:var(--morning)">The system</p> 429 <h2 class="h2 disp">A day has four slots.</h2> 430 <p class="sub">That's the entire model. No per-pill alarms, no spreadsheet. Every supplement lives in a slot, every slot pings you once, <b>and rest days reschedule themselves</b>.</p> 431 </div> 432 <div class="slotgrid"> 433 <div class="slot r" style="--c:var(--morning)"> 434 <div class="slot-ic">âï¸</div> 435 <h3>Morning</h3> 436 <span class="slot-time">08:00 · Everyday</span> 437 <p>Starts with breakfast. The vitamins you forget the second you grab your keys.</p> 438 <div class="chips"><span class="chip">D3 · 4000 iu</span><span class="chip">Omega-3 · 2 caps</span></div> 439 </div> 440 <div class="slot r d1" style="--c:var(--pre)"> 441 <div class="slot-ic">â¡</div> 442 <h3>Pre-Workout</h3> 443 <span class="slot-time">30 min before</span> 444 <p>Timed to your session, not the clock. Caffeine when it counts.</p> 445 <div class="chips"><span class="chip">Pre · 1 scoop</span></div> 446 </div> 447 <div class="slot r d2" style="--c:var(--post)"> 448 <div class="slot-ic">ðï¸</div> 449 <h3>Post-Workout</h3> 450 <span class="slot-time">19:00 · Training days</span> 451 <p>While the shaker's still out. Creatine doesn't care how tired you are.</p> 452 <div class="chips"><span class="chip">Creatine · 5 g</span><span class="chip">Protein · 1 scoop</span><span class="chip hot">Rest-day aware</span></div> 453 </div> 454 <div class="slot r d3" style="--c:var(--night)"> 455 <div class="slot-ic">ð</div> 456 <h3>Night</h3> 457 <span class="slot-time">21:00 · Everyday</span> 458 <p>The sleep stack. The slot everyone skips, until the streak's on the line.</p> 459 <div class="chips"><span class="chip">Ashwagandha · 600 mg</span><span class="chip">Magnesium · 400 mg</span><span class="chip">ZMA · 3 caps</span></div> 460 </div> 461 </div> 462 </div> 463 </section> 464 465 <!-- ================= supplement facts ================= --> 466 <section class="sec"> 467 <div class="container facts-grid"> 468 <div class="facts-copy r"> 469 <p class="eb">No proprietary blends</p> 470 <h2 class="h2 disp">Read the label.</h2> 471 <p class="sub">Supplement companies hide behind blends. GymDose doesn't. Every feature disclosed, every amount exact, and the numbers that should be zero are <b>zero</b>.</p> 472 <p class="fine">Reminders fire per slot. The widget and Live Activity keep today's doses on your lock screen. Everything stays on your phone. There's no server to sync with, nothing to sign into.</p> 473 </div> 474 <div class="label r d1" role="table" aria-label="GymDose feature list, styled as a supplement facts panel"> 475 <h3>Supplement Facts</h3> 476 <div class="label-meta"> 477 <div><span>Serving size</span><b>1 day (4 slots)</b></div> 478 <div><span>Servings per container</span><b>Unlimited</b></div> 479 </div> 480 <div class="lbar"></div> 481 <div class="lhead"><span>Amount per day</span><span>Included</span></div> 482 <div class="lrow"><span>Time slots</span><b>4</b></div> 483 <div class="lrow"><span>Smart reminders</span><b>1 per slot</b></div> 484 <div class="lrow"><span>Streak tracking</span><b>1 flame</b></div> 485 <div class="lrow"><span>Progress calendar</span><b>Monthly</b></div> 486 <div class="lrow"><span>Home screen widget</span><b>1</b></div> 487 <div class="lrow"><span>Live Activity</span><b>1</b></div> 488 <div class="lrow"><span>Themes</span><b>7</b></div> 489 <div class="lrow"><span>Languages</span><b>13</b></div> 490 <div class="lbar thin"></div> 491 <div class="lrow"><span>Internet required</span><b>0%</b></div> 492 <div class="lrow"><span>Accounts required</span><b>0</b></div> 493 <div class="lrow"><span>Ads</span><b>0</b></div> 494 <div class="lrow"><span>Price</span><b>$0.00</b></div> 495 <div class="lbar"></div> 496 <p class="lfoot">* Daily Values based on a lift-heavy, sleep-well routine. Not a significant source of sign-up forms, sync errors, or subscription pop-ups.</p> 497 </div> 498 </div> 499 </section> 500 501 <!-- ================= screenshots ================= --> 502 <section class="sec shots"> 503 <div class="container"> 504 <div class="sec-head r"> 505 <p class="eb" style="--eb-c:var(--night)">In your pocket</p> 506 <h2 class="h2 disp">Straight from the app.</h2> 507 <p class="sub">No mockups. These are the real screens, theme and all.</p> 508 </div> 509 </div> 510 <div class="shots-track r"> 511 <div class="shots-in"> 512 <figure class="shot" style="--c:var(--blue)"><img src="screen-tracker-med.webp" alt="GymDose daily tracker with four time slots and a progress ring" width="234" height="508" loading="lazy"><figcaption><i></i>
512Tracker</figcaption></figure> 513 <figure class="shot" style="--c:var(--post)"><img src="screen-supplements-med.webp" alt="GymDose supplement list with dosage details" width="234" height="508" loading="lazy"><figcaption><i></i>Your stack</figcaption></figure> 514 <figure class="shot" style="--c:var(--morning)"><img src="screen-reminders-med.webp" alt="GymDose reminders for morning, post-workout and night slots" width="234" height="508" loading="lazy"><figcaption><i></i>Reminders</figcaption></figure> 515 <figure class="shot" style="--c:var(--pre)"><img src="screen-progress-med.webp" alt="GymDose monthly progress calendar with completion stats" width="234" height="508" loading="lazy"><figcaption><i></i>Progress</figcaption></figure> 516 <figure class="shot" style="--c:var(--night)"><img src="screen-dark-med.webp" alt="GymDose tracker in dark mode" width="234" height="508" loading="lazy"><figcaption><i></i>Dark mode</figcaption></figure> 517 </div> 518 </div> 519 </section> 520 521 <!-- ================= cta ================= --> 522 <section class="sec" id="cta"> 523 <div class="container"> 524 <div class="cta-card r"> 525 <div class="cta-in"> 526 <h2 class="h2 disp">Start the <span class="hot">streak</span> tonight.</h2> 527 <p class="sub">Add your stack in two minutes, log the night slot before bed. That's day one.</p> 528 <div class="badges"> 529 <a class="apple" href="https://apps.apple.com/app/gymdose-supplement-tracker/id6756020237" aria-label="Download GymDose on the App Store"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/white/en-us?size=250x83" alt="Download on the App Store" width="156" height="52" loading="lazy"></a> 530 <a class="google" href="https://play.google.com/store/apps/details?id=com.baransel.dev.gym.supplement.tracker" aria-label="Get GymDose on Google Play"><img src="android.png" alt="Get it on Google Play" height="76" loading="lazy"></a> 531 </div> 532 <p class="cta-note">iOS 16+ · Android · Free</p> 533 </div> 534 </div> 535 </div> 536 </section> 537 538 <footer> 539 <div class="container ft"> 540 <div class="ft-l">© 2026 GymDose · built by Baransel between sets</div> 541 <div class="ft-r"> 542 <a href="https://baransel.dev/gymdose/privacy">Privacy</a> 543 <a href="https://baransel.dev/gymdose/terms">Terms</a> 544 <a href="mailto:[email protected]">Contact</a> 545 </div> 546 </div> 547 </footer> 548 549
549<script> 550 (function () { 551 var reduced = matchMedia('(prefers-reduced-motion: reduce)').matches; 552 553 // nav border on scroll 554 var nav = document.getElementById('nav'); 555 addEventListener('scroll', function () { nav.classList.toggle('s', scrollY > 40); }, { passive: true }); 556 557 // scroll reveals 558 var io = new IntersectionObserver(function (es) { 559 es.forEach(function (e) { 560 if (e.isIntersecting) { e.target.classList.add('v'); io.unobserve(e.target); } 561 }); 562 }, { threshold: .1, rootMargin: '0px 0px -40px 0px' }); 563 document.querySelectorAll('.r').forEach(function (el) { io.observe(el); }); 564 565 // duplicate dose strip for a seamless loop 566 var strip = document.getElementById('strip'); 567 strip.innerHTML += strip.innerHTML; 568 569 // ---------- live tracker demo ---------- 570 var doses = Array.prototype.slice.call(document.querySelectorAll('.dose')); 571 var TOTAL = doses.length, STREAK = 15; 572 var ring = document.getElementById('ring'), ringN = document.getElementById('ring-n'); 573 var rem = document.getElementById('rem'), next = document.getElementById('next'); 574 var flame = document.getElementById('flame'), hint = document.getElementById('hint'); 575 var notifMsg = document.getElementById('notif-msg'), notif = document.getElementById('notif'); 576 var slotMeta = { 577 morning: 'âï¸ Morning', pre: 'â¡ Pre-Workout', 578 post: 'ðï¸ Post-Workout', night: 'ð Night' 579 }; 580 var touched = false, wasDone = false; 581 582 function update() { 583 var taken = doses.filter(function (d) { return d.getAttribute('aria-pressed') === 'true'; }).length; 584 var done = taken === TOTAL; 585 ring.style.setProperty('--p', taken / TOTAL * 100); 586 ring.style.setProperty('--rc', done ? 'var(--post)' : 'var(--blue)'); 587 ring.setAttribute('aria-label', taken + ' of ' + TOTAL + ' doses taken'); 588 ringN.textContent = taken + '/' + TOTAL; 589 rem.textContent = TOTAL - taken; 590 var first = doses.filter(function (d) { return d.getAttribute('aria-pressed') !== 'true'; })[0]; 591 next.innerHTML = done ? 'â Day complete' : '<i>Next up</i> ' + slotMeta[first.dataset.slot]; 592 flame.textContent = 'ð¥ ' + (done ? STREAK + 1 : STREAK); 593 if (done && !wasDone) { 594 flame.classList.remove('pop'); void flame.offsetWidth; flame.classList.add('pop'); 595 notifMsg.textContent = 'Streak extended: ' + (STREAK + 1) + ' days. See you tomorrow.'; 596 notif.classList.add('on'); 597 hint.textContent = 'Full day logged. That\'s the whole app.'; 598 } else if (!done && wasDone) { 599 notifMsg.textContent = 'Night stack at 21:00. Don\'t break the streak.'; 600 } 601 wasDone = done; 602 } 603 604 doses.forEach(function (d) { 605 d.addEventListener('click', function () { 606 touched = true; 607 d.setAttribute('aria-pressed', d.getAttribute('aria-pressed') === 'true' ? 'false' : 'true'); 608 update(); 609 }); 610 }); 611 612 // show the reminder notification, then auto-log the morning pair 613 setTimeout(function () { notif.classList.add('on'); }, reduced ? 0 : 1100); 614 if (!reduced) { 615 [0, 1].forEach(function (i, k) { 616 setTimeout(function () { 617 if (touched) return; 618 doses[i].setAttribute('aria-pressed', 'true'); 619 update(); 620 }, 1700 + k * 550); 621 }); 622 } 623 624 update(); 625 })(); 626 </script>
626 627</body> 628 629</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.