PageSourceSearch

https://truelike.com/

html truelike.com collected 2026-09-24 14:01:00 UTC 23,851 bytes, 531 lines download raw bytes

1<!doctype html>
2<html lang="en">
3<head>
4  <meta charset="utf-8" />
5  <meta name="viewport" content="width=device-width, initial-scale=1" />
6  <title>truelike - the daily game for your true friends</title>
7  <meta name="description" content="the daily game for your true friends - one question a day. get closer with the friends who matter, every day. no strangers, no broadcast." />
8
9  <!-- og + twitter cards. Shows nice preview when the link is pasted into iMessage / WhatsApp / DM. -->
10  <meta property="og:title" content="truelike - the daily game for your true friends" />
11  <meta property="og:description" content="the daily game for your true friends - one question a day. get closer with the friends who matter, every day. no strangers, no broadcast." />
12  <meta property="og:type" content="website" />
13  <meta property="og:image" content="https://truelike.com/og.png" />
14  <meta property="og:url" content="https://truelike.com/" />
15  <meta name="twitter:card" content="summary_large_image" />
16
17  <!-- Termly cookie consent banner (must load before other scripts so autoBlock can gate them) -->
18  
18<script src="https://app.termly.io/resource-blocker/cfeb2592-4db0-4a8a-b85c-7242f6f5891c?autoBlock=on"></script>
18
19  <!-- PostHog product analytics - gated by Termly autoBlock; person_profiles:'identified_only' avoids creating profiles for anonymous visitors -->
20  
20<script>
21    !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once unregister identify setPersonProperties group resetGroups reset get_distinct_id getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys captureException opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing set_config debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
22    posthog.init('phc_wyTWQtyiaWx6QmhmPxvfSHn7DUJirK9YjdTNkpcd94A3', {
23      api_host: 'https://us.i.posthog.com',
24      person_profiles: 'identified_only'
25    });
26  </script>
26
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=Bagel+Fat+One&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
30  
30<script src="https://cdn.tailwindcss.com"></script>
30
31  
31<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/dist/umd/supabase.min.js"></script>
31
32  <style>
33    body {
34      font-family: 'Inter', system-ui, sans-serif;
35      background: #00bfff;
36      color: #001a33;
37      min-height: 100vh;
38      position: relative;
39      overflow-x: hidden;
40    }
41    body::before {
42      content: "";
43      position: fixed;
44      inset: 0;
45      background-image:
46        radial-gradient(circle at 0% 0%, rgba(255, 255, 0, 0.18), transparent 40%),
47        radial-gradient(circle at 100% 100%, rgba(163, 230, 53, 0.20), transparent 40%);
48      pointer-events: none;
49      z-index: 0;
50    }
51    .wordmark, .display {
52      font-family: 'Bagel Fat One', system-ui, sans-serif;
53      letter-spacing: -0.01em;
54      line-height: 0.95;
55    }
56    .lime { color: #a3e635; }
57    .lime-bg { background: #a3e635; }
58    /* Orange text (was #fb923c) - darkened to #c2410c so it passes
59       WCAG AA on white (5.6:1) and reads clearly on the cyan background
60       too. The brighter #fb923c is kept for solid orange backgrounds
61       and dots, where the contrast equation is reversed. */
62    .orange { color: #c2410c; }
63    .orange-bg { background: #fb923c; }
64    .yellow-bg { background: #fde047; }
65    .cyan-bg { background: #00bfff; }
66    .sticker {
67      background: #fff;
68      border: 3px solid #001a33;
69      box-shadow: 5px 5px 0 #001a33;
70    }
71    .sticker-yellow {
72      background: #fde047;
73      border: 3px solid #001a33;
74      box-shadow: 5px 5px 0 #001a33;
75    }
76    .sticker-lime {
77      background: #a3e635;
78      border: 3px solid #001a33;
79      box-shadow: 5px 5px 0 #001a33;
80    }
81    .cta-btn {
82      background: #fde047;
83      color: #001a33;
84      border: 4px solid #001a33;
85      box-shadow: 6px 6px 0 #001a33;
86      transition: transform 0.12s ease, box-shadow 0.12s ease;
87      font-weight: 800;
88    }
89    .cta-btn:hover {
90      transform: translate(-2px, -2px) rotate(-1deg);
91      box-shadow: 8px 8px 0 #001a33;
92    }
93    .cta-btn:active {
94      transform: translate(3px, 3px);
95      box-shadow: 1px 1px 0 #001a33;
96    }
97    .store-btn {
98      background: #fff;
99      color: #001a33;
100      border: 3px solid #001a33;
101      box-shadow: 4px 4px 0 #001a33;
102      transition: transform 0.12s ease, box-shadow 0.12s ease;
103      font-weight: 800;
104      display: inline-block;
105    }
106    .store-btn:hover {
107      transform: translate(-2px, -2px);
108      box-shadow: 6px 6px 0 #001a33;
109    }
110    .store-btn:active {
111      transform: translate(2px, 2px);
112      box-shadow: 1px 1px 0 #001a33;
113    }
114    .cta-btn:disabled {
115      opacity: 0.6;
116      cursor: not-allowed;
117      transform: none;
118      box-shadow: 3px 3px 0 #001a33;
119    }
120    .phone-frame {
121      background: #001a33;
122      border-radius: 38px;
123      padding: 10px;
124      border: 4px solid #001a33;
125      box-shadow: 10px 10px 0 #fde047;
126      transform: rotate(2deg);
127    }
128    .phone-screen {
129      background: #fff;
130      border-radius: 30px;
131      overflow: hidden;
132      aspect-ratio: 9 / 19.5;
133    }
134    .selected {
135      background: #fb923c;
136      color: #001a33;
137      border-color: #001a33;
138      transform: rotate(-2deg) scale(1.05);
139    }
140    .input-pop {
141      background: #fff;
142      border: 4px solid #001a33;
143      color: #001a33;
144      font-weight: 600;
145    }
146    .input-pop::placeholder { color: #6b7c8a; }
147    .input-pop:focus {
148      outline: none;
149      box-shadow: 4px 4px 0 #001a33;
150      transform: translate(-2px, -2px);
151    }
152    .tilt-left { transform: rotate(-2deg); }
153    .tilt-right { transform: rotate(2deg); }
154    .tilt-tiny { transform: rotate(-1deg); }
155    .pulse-orange {
156      animation: pulse-orange 1.5s ease-in-out infinite;
157    }
158    @keyframes pulse-orange {
159      0%, 100% { transform: scale(1); }
160      50% { transform: scale(1.2); }
161    }
162
163    /* Play section option cards */
164    .option-card {
165      background: #fff;
166      border: 3px solid #001a33;
167      box-shadow: 4px 4px 0 #001a33;
168      transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
169      cursor: pointer;
170      user-select: none;
171    }
172    .option-card:hover:not(.voted) {
173      transform: translate(-2px, -2px);
174      box-shadow: 6px 6px 0 #001a33;
175    }
176    .option-card:active:not(.voted) {
177      transform: translate(2px, 2px);
178      box-shadow: 1px 1px 0 #001a33;
179    }
180    .option-card.my-pick {
181      background: #fb923c;
182      transform: rotate(-1deg) scale(1.03);
183    }
184    .option-card.voted {
185      cursor: default;
186    }
187    .option-card.voted:hover {
188      transform: none;
189    }
190    .bar-fill {
191      height: 100%;
192      background: #a3e635;
193      border-radius: 3px;
194      transition: width 0.6s ease;
195    }
196    .bar-fill.my-pick-bar {
197      background: #fb923c;
198    }
199    @keyframes pop-in {
200      0% { transform: scale(0.85); opacity: 0; }
201      60% { transform: scale(1.05); }
202      100% { transform: scale(1); opacity: 1; }
203    }
204    .pop-in { animation: pop-in 0.35s ease forwards; }
205  </style>
206</head>
207<body>
208  <!-- Nav -->
209  <header class="max-w-6xl mx-auto px-6 py-6 flex items-center justify-between relative z-10">
210    <div class="wordmark text-4xl text-white">truelike</div>
211    <a href="#download" class="sticker px-4 py-2 rounded-full text-sm font-extrabold tilt-tiny">get the app →</a>
212  </header>
213
214  <!-- Hero -->
215  <section class="max-w-6xl mx-auto px-6 pt-8 pb-16 md:pt-16 md:pb-24 grid md:grid-cols-2 gap-12 items-center relative z-10">
216    <div>
217      <span class="sticker-yellow inline-flex items-center gap-2 text-xs font-extrabold uppercase tracking-wider px-3 py-2 rounded-full tilt-left">
218        <span class="w-2 h-2 rounded-full bg-orange-500 pulse-orange"></span>
219        out now · free · 13+
220      </span>
221      <h1 class="display text-5xl md:text-7xl mt-6 text-white" style="text-shadow: 4px 4px 0 #001a33;">
222        the daily game<br />for your<br /><span class="lime">true friends</span>
223      </h1>
224      <p class="text-lg md:text-xl mt-6 max-w-md font-semibold text-white">
225        one question a day with your closest friends - find out how alike (or different) you really are.
226      </p>
227      <div class="sticker-lime tilt-right inline-block mt-4 px-3 py-1.5 rounded-full text-sm font-extrabold">
228        no strangers. no dms. just your circle.
229      </div>
230
231      <div class="mt-8 flex flex-col sm:flex-row gap-3 max-w-md">
232        <a data-store="app_store" data-placement="hero" href="#" class="cta-btn px-6 py-4 rounded-2xl text-center whitespace-nowrap">📱 download on App Store</a>
233        <a data-store="play_store" data-placement="hero" href="#" class="cta-btn px-6 py-4 rounded-2xl text-center whitespace-nowrap">🤖 get it on Google Play</a>
234      </div>
235      <p class="mt-3 text-sm font-extrabold text-white" style="text-shadow: 2px 2px 0 #001a33;">
236        free - start a circle and get your friends in
237      </p>
238    </div>
239
240    <!-- App screenshot: the reveal moment.
241         Composited from the App Store screenshot set (store-screenshots/composited/04-reveal.png) - already
242         has the navy phone bezel + brutalist offset and a marketing caption built in
243         ("everyone's answers, all at once."). Replaces the previous CSS phone-mock that showed a
244         hand-rolled pick-one round; the real screenshot keeps the landing in sync with the actual app
245         build instead of having to update HTML mocks when the UI changes. -->
246    <div class="flex justify-center">
247      <img
248        src="/landing-app-reveal.png"
249        alt="truelike app - the reveal moment: everyone's answers shown at once"
250        class="max-w-xs w-full rounded-3xl"
251        style="transform: rotate(2deg); box-shadow: 10px 10px 0 #001a33;"
252      />
253    </div>
254  </section>
255
256  <!-- Daily public Play section -->
257  <section class="max-w-3xl mx-auto px-6 py-12 relative z-10">
258    <div class="sticker rounded-3xl p-8 md:p-10">
259      <div class="flex items-center gap-3 mb-2">
260        <span class="sticker-yellow text-xs font-extrabold uppercase tracking-wider px-2 py-1 rounded-full inline-flex items-center gap-1.5">
261          <span class="w-2 h-2 rounded-full bg-orange-500 pulse-orange inline-block"></span>
262          live · today's question
263        </span>
264      </div>
265
266      <div id="play-loading" class="text-center py-8 text-stone-400 font-bold">loading today's question…</div>
267
268      <div id="play-content" class="hidden">
269        <div class="display text-3xl md:text-4xl mt-4 leading-tight" id="play-prompt-text"></div>
270        <p class="mt-3 text-sm font-semibold text-stone-600">Pick one - see how everyone else answers</p>
271
272        <div id="play-options" class="grid grid-cols-2 gap-3 mt-6"></div>
273
274        <div id="play-results" class="hidden mt-6 space-y-3 pop-in">
275          <p class="text-xs uppercase tracking-wider font-extrabold text-stone-500 mb-4">here's how everyone voted today</p>
276          <div id="play-bars"></div>
277          <p class="mt-4 text-sm font-bold text-stone-600">
278            <span id="play-vote-count"></span> votes today
279          </p>
280        </div>
281
282        <div id="play-cta" class="hidden mt-8 pt-6 border-t-2 border-[#001a33] pop-in">
283          <p class="display text-2xl">want truelike with <span class="orange">your</span> friends?</p>
284          <p class="text-sm font-semibold mt-2 text-stone-700">a new prompt every day - 7 rotating types, friends only, named answers.</p>
285          <div class="mt-4 flex flex-col sm:flex-row gap-3">
286            <a data-store="app_store" data-placement="play" href="#" class="store-btn px-5 py-3 rounded-xl text-center text-sm whitespace-nowrap">📱 download on App Store</a>
287            <a data-store="play_store" data-placement="play" href="#" class="store-btn px-5 py-3 rounded-xl text-center text-sm whitespace-nowrap">🤖 get it on Google Play</a>
288          </div>
289        </div>
290      </div>
291
292      <div id="play-error" class="hidden py-6 text-center text-stone-400 font-bold text-sm">
293        no question today - check back tomorrow
294      </div>
295    </div>
296  </section>
297
298  <!-- How it works -->
299  <section class="max-w-6xl mx-auto px-6 py-16 md:py-24 relative z-10">
300    <h2 class="display text-4xl md:text-5xl mb-12 text-white" style="text-shadow: 3px 3px 0 #001a33;">how it works</h2>
301    <div class="grid md:grid-cols-3 gap-6">
302      <div class="sticker rounded-3xl p-6 tilt-left">
303        <div class="display text-5xl orange">01</div>
304        <h3 class="display text-2xl mt-3">start a circle.</h3>
305        <p class="font-medium mt-3">Invite 3–12 close friends. Private. Just you and them.</p>
306      </div>
307      <div class="sticker rounded-3xl p-6 tilt-right">
308        <div class="display text-5xl lime">02</div>
309        <h3 class="display text-2xl mt-3">show up every day.</h3>
310        <p class="font-medium mt-3">one quick round drops at the same time. pick one, hot take, two truths, guess who said it, and more.</p>
311      </div>
312      <div class="sticker rounded-3xl p-6 tilt-left">
313        <div class="display text-5xl orange">03</div>
314        <h3 class="display text-2xl mt-3">find out who you really are.</h3>
315        <p class="font-medium mt-3">Together. See who matches your taste, who surprises you, who's been holding out.</p>
316      </div>
317    </div>
318  </section>
319
320  <!-- Compare -->
321  <section class="max-w-6xl mx-auto px-6 py-12 relative z-10">
322    <div class="sticker rounded-3xl p-8 md:p-12">
323      <h2 class="display text-3xl md:text-4xl mb-8">why not just…</h2>
324      <ul class="space-y-3 text-lg font-medium">
325        <li><span class="font-extrabold text-stone-400 line-through">BeReal</span> - one prompt, gets old.</li>
326        <li><span class="font-extrabold text-stone-400 line-through">Gas / TBH</span> - anonymous polls, got mean.</li>
327        <li><span class="font-extrabold text-stone-400 line-through">group chats</span> - flat, nothing happens.</li>
328        <li class="pt-2 border-t-2 border-[#001a33]"><span class="wordmark orange text-2xl">truelike</span> - the group chat that plays back.</li>
329      </ul>
330    </div>
331  </section>
332
333  <!-- Download CTA -->
334  <section id="download" class="max-w-3xl mx-auto px-6 py-20 text-center relative z-10">
335    <h2 class="display text-4xl md:text-6xl leading-tight text-white" style="text-shadow: 4px 4px 0 #001a33;">be first<br/>in your <span class="lime">circle.</span></h2>
336    <p class="text-lg mt-6 font-bold text-white">Download truelike, start a circle, and get your friends in.</p>
337    <div class="mt-8 flex flex-col sm:flex-row gap-3 justify-center">
338      <a data-store="app_store" data-placement="footer" href="#" class="cta-btn px-6 py-4 rounded-2xl text-center whitespace-nowrap">📱 download on App Store</a>
339      <a data-store="play_store" data-placement="footer" href="#" class="cta-btn px-6 py-4 rounded-2xl text-center whitespace-nowrap">🤖 get it on Google Play</a>
340    </div>
341  </section>
342
343  <!-- Footer -->
344  <footer class="max-w-6xl mx-auto px-6 py-12 text-sm flex flex-col md:flex-row justify-between items-center gap-4 border-t-2 border-[#001a33] text-white font-bold relative z-10">
345    <div class="wordmark text-xl">truelike</div>
346    <div class="flex items-center gap-2"><span class="w-2 h-2 rounded-full bg-orange-400 inline-block"></span>privacy-first. no dms. no strangers. 13+.</div>
347    <div class="flex flex-wrap items-center gap-4">
348      <a href="/for-parents" class="hover:underline">For Parents</a>
349      <a href="/child-safety" class="hover:underline">Child Safety</a>
350      <a href="/privacy" class="hover:underline">Privacy</a>
351      <a href="/terms" class="hover:underline">Terms</a>
352      <a href="/cookies" class="hover:underline">Cookies</a>
353      <a href="#" class="termly-display-preferences hover:underline">Consent Preferences</a>
354      <span>© 2026</span>
355    </div>
356  </footer>
357
358  
358<script>
359    const SUPABASE_URL = 'https://slrngimolxelqygkjkhh.supabase.co';
360    const SUPABASE_ANON_KEY = 'sb_publishable_3qHvnHe9ycvXguoRxB0SVw_rXbi0gvP';
361    const sb = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
362
363    // ── Store CTAs (founder path live in both stores since 1.0.21) ──────────
364    const APP_STORE_URL = 'https://apps.apple.com/app/id6771850307';
365    const PLAY_STORE_URL = 'https://play.google.com/store/apps/details?id=com.truelike.app';
366    document.querySelectorAll('a[data-store]').forEach(a => {
367      a.href = a.dataset.store === 'app_store' ? APP_STORE_URL : PLAY_STORE_URL;
368      // Named conversion event. Consent-safe: no-op when Termly blocked PostHog.
369      a.addEventListener('click', () => {
370        try { window.posthog?.capture?.('landing_store_tapped', { store: a.dataset.store, placement: a.dataset.placement }); } catch (_) {}
371      });
372    });
373
374    // ── Daily public Play section ────────────────────────────────────────────
375    (async function initPlay() {
376      const loadingEl = document.getElementById('play-loading');
377      const contentEl = document.getElementById('play-content');
378      const errorEl   = document.getElementById('play-error');
379
380      try {
381        const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
382
383        // Fetch today's featured prompt
384        const { data: dailyRows, error: dailyErr } = await sb
385          .from('public_daily_prompt')
386          .select('prompt_id')
387          .eq('date', today)
388          .limit(1);
389
390        if (dailyErr || !dailyRows || dailyRows.length === 0) {
391          loadingEl.classList.add('hidden');
392          errorEl.classList.remove('hidden');
393          return;
394        }
395
396        const promptId = dailyRows[0].prompt_id;
397
398        // Fetch the prompt data
399        const { data: promptRows, error: promptErr } = await sb
400          .from('prompts')
401          .select('prompt, options')
402          .eq('id', promptId)
403          .limit(1);
404
405        if (promptErr || !promptRows || promptRows.length === 0) {
406          loadingEl.classList.add('hidden');
407          errorEl.classList.remove('hidden');
408          return;
409        }
410
411        const promptData = promptRows[0];
412        const options = promptData.options || [];
413
414        // Fetch existing vote counts for distribution display
415        const { data: votes } = await sb
416          .from('public_votes')
417          .select('option_index')
418          .eq('prompt_id', promptId)
419          .eq('date', today);
420
421        const voteCounts = new Array(options.length).fill(0);
422        if (votes) {
423          votes.forEach(v => { if (v.option_index < options.length) voteCounts[v.option_index]++; });
424        }
425
426        // Check if user already voted today (sessionStorage)
427        const storageKey = 'truelike:played:' + today;
428        const myPick = sessionStorage.getItem(storageKey);
429        const hasVoted = myPick !== null;
430
431        // Render prompt
432        document.getElementById('play-prompt-text').textContent = promptData.prompt;
433
434        const optionsEl = document.getElementById('play-options');
435        options.forEach((opt, i) => {
436          const card = document.createElement('button');
437          card.className = 'option-card rounded-2xl p-4 text-center font-extrabold text-sm' + (hasVoted ? ' voted' : '');
438          if (hasVoted && String(i) === myPick) card.classList.add('my-pick');
439          card.textContent = opt;
440          card.setAttribute('data-index', i);
441          if (!hasVoted) {
442            card.addEventListener('click', () => handleVote(i, promptId, today, options, voteCounts));
443          }
444          optionsEl.appendChild(card);
445        });
446
447        loadingEl.classList.add('hidden');
448        contentEl.classList.remove('hidden');
449
450        if (hasVoted) {
451          showResults(options, voteCounts, votes ? votes.length : 0, Number(myPick));
452        }
453
454      } catch (err) {
455        loadingEl.classList.add('hidden');
456        errorEl.classList.remove('hidden');
457      }
458    })();
459
460    async function handleVote(index, promptId, today, options, prevCounts) {
461      // Optimistically update
462      sessionStorage.setItem('truelike:played:' + today, String(index));
463
464      // The landing's engagement beat - a visitor played the public demo
465      // round. Consent-safe no-op when Termly blocked PostHog.
466      try { window.posthog?.capture?.('landing_demo_voted', { prompt_id: promptId }); } catch (_) {}
467
468      // Record vote
469      await sb.from('public_votes').insert({ prompt_id: promptId, date: today, option_index: index });
470
471      // Fetch fresh counts
472      const { data: freshVotes } = await sb
473        .from('public_votes')
474        .select('option_index')
475        .eq('prompt_id', promptId)
476        .eq('date', today);
477
478      const counts = new Array(options.length).fill(0);
479      if (freshVotes) {
480        freshVotes.forEach(v => { if (v.option_index < options.length) counts[v.option_index]++; });
481      }
482
483      // Mark all cards as voted
484      document.querySelectorAll('#play-options .option-card').forEach((card, i) => {
485        card.classList.add('voted');
486        card.style.cursor = 'default';
487        if (i === index) card.classList.add('my-pick');
488        // Remove click listener by replacing element
489        const clone = card.cloneNode(true);
490        clone.classList.add('voted');
491        if (i === index) clone.classList.add('my-pick');
492        card.parentNode.replaceChild(clone, card);
493      });
494
495      showResults(options, counts, freshVotes ? freshVotes.length : prevCounts.reduce((a,b)=>a+b,0) + 1, index);
496    }
497
498    function showResults(options, counts, totalVotes, myPickIndex) {
499      const resultsEl  = document.getElementById('play-results');
500      const barsEl     = document.getElementById('play-bars');
501      const countEl    = document.getElementById('play-vote-count');
502      const ctaEl      = document.getElementById('play-cta');
503
504      const total = Math.max(totalVotes, counts.reduce((a,b)=>a+b,0), 1);
505
506      barsEl.innerHTML = '';
507      options.forEach((opt, i) => {
508        const pct = Math.round((counts[i] / total) * 100);
509        const isMine = i === myPickIndex;
510        const row = document.createElement('div');
511        row.className = 'mb-3';
512        row.innerHTML = `
513          <div class="flex items-center justify-between mb-1">
514            <span class="text-sm font-bold${isMine ? ' orange' : ''}">${opt}${isMine ? ' ← you' : ''}</span>
515            <span class="text-sm font-extrabold">${pct}%</span>
516          </div>
517          <div class="h-3 bg-stone-100 rounded-full border-2 border-[#001a33] overflow-hidden">
518            <div class="bar-fill${isMine ? ' my-pick-bar' : ''}" style="width:${pct}%"></div>
519          </div>`;
520        barsEl.appendChild(row);
521      });
522
523      countEl.textContent = total.toLocaleString();
524      resultsEl.classList.remove('hidden');
525      ctaEl.classList.remove('hidden');
526    }
527
528  </script>
528
529  
529<script defer src="/_vercel/insights/script.js"></script>
529
530</body>
531</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.