PageSourceSearch

https://baransel.dev/gymdose/

html baransel.dev collected 2026-10-01 15:40:02 UTC 39,185 bytes, 629 lines download raw bytes

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 &amp; 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.