PageSourceSearch

https://tokdash.github.io/privacy/

html tokdash.github.io collected 2026-10-03 10:05:24 UTC 18,220 bytes, 391 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.0" />
6  <meta name="theme-color" content="#1E40AF" />
7
8  <title>Privacy Policy: Tokdash</title>
9  <meta name="description" content="Privacy policy for Tokdash Companion (the desktop tray/menu-bar app) and for the tokdash.github.io website. Covers what data each one collects, and what it does not." />
10
11  <link rel="icon" href="/static/icons/icon-192.png" sizes="192x192" />
12  <link rel="canonical" href="https://tokdash.github.io/privacy/" />
13
14  <!-- Open Graph -->
15  <meta property="og:type" content="website" />
16  <meta property="og:title" content="Privacy Policy: Tokdash" />
17  <meta property="og:description" content="What Tokdash Companion collects (nothing) and what tokdash.github.io collects (standard website analytics)." />
18  <meta property="og:url" content="https://tokdash.github.io/privacy/" />
19  <meta property="og:image" content="https://tokdash.github.io/static/icons/icon-512.png" />
20  <meta name="twitter:card" content="summary_large_image" />
21
22  <!-- Fonts (Design System: Fira Code / Fira Sans) -->
23  <link rel="preconnect" href="https://fonts.googleapis.com" />
24  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
25  <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Fira+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
26
27  <!-- Tailwind: prebuilt static CSS shared with the rest of the site -->
28  <link rel="stylesheet" href="/static/landing.css" />
29
30  <!-- Avoid theme flash: set the class before paint (mirrors index.html) -->
31  
31<script>
32    (function () {
33      document.documentElement.classList.add('js');
34      try {
35        var saved = localStorage.getItem('tokdash-site-theme');
36        var dark = saved ? saved === 'dark'
37          : (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
38        if (dark) document.documentElement.classList.add('dark');
39      } catch (e) {}
40    })();
41  </script>
41
42
43  <style>
44    /* ---- Design tokens (mirrored from index.html) ---- */
45    :root {
46      --color-primary: #1E40AF;
47      --color-secondary: #3B82F6;
48      --color-cta: #F59E0B;
49      --color-bg: #F8FAFC;
50      --color-text: #0F172A;
51      --color-muted: #475569;
52      --color-border: #E2E8F0;
53      --color-cost: #0F766E;
54      --radius-md: 12px;
55      --radius-lg: 16px;
56      --t-fast: 180ms;
57      --shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
58      --shadow-md: 0 8px 24px rgba(15, 23, 42, 0.08);
59    }
60
61    /* ---- Lenis smooth scroll ---- */
62    html.lenis, html.lenis body { height: auto; }
63    html, html.lenis { scroll-behavior: auto !important; }
64    .lenis.lenis-smooth { scroll-behavior: auto !important; }
65    .lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
66    .lenis.lenis-stopped { overflow: clip; }
67    .lenis.lenis-smooth iframe { pointer-events: none; }
68    header, .card {
69      transform: translateZ(0);
70      -webkit-transform: translateZ(0);
71    }
72    html.dark {
73      --color-primary: #60A5FA;
74      --color-secondary: #93C5FD;
75      --color-cta: #FBBF24;
76      --color-bg: #0F172A;
77      --color-text: #E2E8F0;
78      --color-muted: #94A3B8;
79      --color-border: #334155;
80      --color-cost: #34D399;
81      --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
82      --shadow-md: 0 8px 24px rgba(0,0,0,0.4);
83    }
84
85    html, body { min-height: 100%; overflow-x: clip; }
86    html { scroll-behavior: smooth; }
87
88    body {
89      font-family: "Fira Sans", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Noto Sans";
90      background: radial-gradient(1200px 600px at 20% -10%, rgba(59,130,246,0.16), transparent 65%),
91                  radial-gradient(900px 600px at 90% 10%, rgba(245,158,11,0.12), transparent 55%),
92                  var(--color-bg);
93      color: var(--color-text);
94      -webkit-font-smoothing: antialiased;
95    }
96    html.dark body {
97      background: radial-gradient(1200px 600px at 20% -10%, rgba(59,130,246,0.10), transparent 65%),
98                  radial-gradient(900px 600px at 90% 10%, rgba(245,158,11,0.06), transparent 55%),
99                  var(--color-bg);
100    }
101
102    .mono { font-family: "Fira Code", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
103    .text-muted { color: var(--color-muted); }
104
105    .surface {
106      background: rgba(255, 255, 255, 0.95);
107      border: 1px solid var(--color-border);
108      border-radius: var(--radius-lg);
109      box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06);
110    }
111    html.dark .surface {
112      background: rgba(30, 41, 59, 0.9);
113      border-color: #334155;
114      box-shadow: 0 4px 6px -1px rgba(0,0,0,0.3), 0 2px 4px -1px rgba(0,0,0,0.2);
115    }
116
117    .btn {
118      display: inline-flex; align-items: center; justify-content: center; gap: 10px;
119      border-radius: 10px; padding: 12px 18px; min-height: 48px;
120      font-weight: 600; cursor: pointer; user-select: none; white-space: nowrap;
121      transition: transform var(--t-fast) ease, box-shadow var(--t-fast) ease, background var(--t-fast) ease, border-color var(--t-fast) ease;
122      text-decoration: none;
123    }
124    .btn-ghost {
125      background: rgba(15, 23, 42, 0.04); color: var(--color-text);
126      border: 1px solid rgba(226,232,240,0.9);
127    }
128    .btn-ghost:hover { background: rgba(15, 23, 42, 0.08); transform: translateY(-1px); border-color: rgba(30,64,175,0.3); }
129    html.dark .btn-ghost { background: rgba(148,163,184,0.08); border-color: #475569; }
130    html.dark .btn-ghost:hover { background: rgba(148,163,184,0.15); border-color: rgba(96,165,250,0.4); }
131
132    .site-nav {
133      position: sticky; top: 0; z-index: 50;
134      backdrop-filter: blur(14px);
135      background: color-mix(in srgb, var(--color-bg) 78%, transparent);
136      border-bottom: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
137    }
138    .nav-link {
139      font-size: 14px; font-weight: 600; color: var(--color-muted);
140      padding: 8px 12px; border-radius: 8px; transition: color var(--t-fast) ease, background var(--t-fast) ease;
141    }
142    .nav-link:hover { color: var(--color-text); background: rgba(30,64,175,0.06); }
143
144    .divider-grad { height: 1px; background: linear-gradient(90deg, transparent, var(--color-border), transparent); }
145
146    .chip {
147      display: inline-flex; align-items: center; gap: 8px;
148      padding: 6px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
149      letter-spacing: 0.02em; color: var(--color-primary);
150      background: color-mix(in srgb, var(--color-primary) 10%, transparent);
151      border: 1px solid color-mix(in srgb, var(--color-primary) 24%, transparent);
152    }
153
154    /* ---- Policy article typography (page-local; not part of shared landing.css) ---- */
155    .policy h2 {
156      font-size: 1.35rem; font-weight: 800; letter-spacing: -0.01em;
157      margin-top: 2.5rem; padding-top: 1.5rem;
158      border-top: 1px solid var(--color-border);
159    }
160    .policy h2:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
161    .policy p { margin-top: 0.9rem; line-height: 1.7; color: var(--color-text); }
162    .policy p.lede { color: var(--color-muted); }
163    .policy ul { margin-top: 0.9rem; padding-left: 1.25rem; line-height: 1.7; }
164    .policy li { list-style: disc; margin-top: 0.4rem; }
165    .policy li::marker { color: var(--color-primary); }
166    .policy a { color: var(--color-primary); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
167    .policy code {
168      font-family: "Fira Code", monospace; font-size: 0.9em;
169      background: color-mix(in srgb, var(--color-border) 45%, transparent);
170      padding: 0.15em 0.4em; border-radius: 5px;
171    }
172    .policy strong { font-weight: 700; }
173
174    .callout {
175      border-radius: var(--radius-md);
176      border: 1px solid color-mix(in srgb, var(--color-primary) 26%, var(--color-border));
177      background: color-mix(in srgb, var(--color-primary) 7%, transparent);
178      padding: 1.1rem 1.25rem;
179      margin-top: 1.5rem;
180    }
181    .callout p { margin-top: 0; }
182    .callout p + p { margin-top: 0.6rem; }
183
184    .callout-amber {
185      border-color: color-mix(in srgb, var(--color-cta) 34%, var(--color-border));
186      background: color-mix(in srgb, var(--color-cta) 9%, transparent);
187    }
188  </style>
189</head>
190<body>
191
192  <header class="site-nav">
193    <div class="max-w-[1180px] mx-auto px-4 sm:px-6 h-16 flex items-center justify-between gap-4">
194      <a href="/" class="flex items-center gap-2.5 shrink-0">
195        <img src="/static/icons/logo.png" alt="Tokdash logo" width="32" height="32" style="width:32px;height:32px;object-fit:contain;" />
196        <span class="mono text-lg font-extrabold tracking-tight">Tokdash</span>
197      </a>
198      <div class="flex items-center gap-2">
199        <button id="themeToggle" class="btn btn-ghost" style="min-height:40px;padding:8px 10px;" aria-label="Toggle dark mode">
200          <svg id="iconMoon" width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
201          <svg id="iconSun" width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true" style="display:none;"><circle cx="12" cy="12" r="5" stroke="currentColor" stroke-width="2"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
202        </button>
203        <a href="/demo/" class="nav-link">Live demo</a>
204        <a href="/" class="nav-link">
204← Home</a>
205      </div>
206    </div>
207  </header>
208
209  <main>
210    <section class="max-w-3xl mx-auto px-4 sm:px-6 pt-12 pb-4">
211      <span class="chip"><span class="dot" style="width:7px;height:7px;border-radius:50%;background:var(--color-cta);display:inline-block;"></span> Privacy policy</span>
212      <h1 class="text-3xl sm:text-4xl font-extrabold tracking-tight mt-4">Tokdash privacy policy</h1>
213      <p class="text-muted mt-3">
214        This page covers two different things: the <strong>Tokdash Companion</strong> desktop
215        app (Microsoft Store and portable builds), and <strong>this website</strong>
216        (tokdash.github.io). They behave differently, so each gets its own section below:
217        read the heading before assuming a claim applies to both.
218      </p>
219      <p class="text-xs text-muted mt-4">Last updated: 2026-08-18</p>
220    </section>
221
222    <div class="max-w-3xl mx-auto px-4 sm:px-6"><div class="divider-grad"></div></div>
223
224    <section class="max-w-3xl mx-auto px-4 sm:px-6 py-10">
225      <article class="policy surface" style="padding: 2rem;">
226
227        <h2>What Tokdash Companion is</h2>
228        <p>
229          Tokdash Companion is a notification-area (system tray) client for Tokdash, a
230          service you run on your own machine or on a machine you control. The companion
231          displays usage and quota figures that the Tokdash service reports. It is a
232          viewer; it does not itself gather usage data.
233        </p>
234
235        <h2>Data collected by the app</h2>
236        <p>
237          <strong>None.</strong> Tokdash Companion collects no personal information, sends
238          no analytics or telemetry, and has no server component operated by the
239          developer.
240        </p>
241
242        <h2>Data stored on your device</h2>
243        <p>
244          Your settings, including server addresses and labels, notification thresholds, language,
245          launch-at-login preference, and update-check preference, are stored on your
246          device. In the Microsoft Store build they live in the app's own package storage
247          and are removed when you uninstall the app.
248        </p>
249        <p>
250          Usage and quota figures are held in memory while the app is running and are not
251          written to disk.
252        </p>
253
254        <h2>Network connections the app makes</h2>
255        <p>Tokdash Companion connects only to:</p>
256        <ul>
257          <li>
258            <strong>The Tokdash server addresses you configure.</strong> The default is
259            <code>http://127.0.0.1:55423</code> on your own machine. If you add another
260            address, the companion connects to that one too. It connects to nothing you
261            have not entered.
262          </li>
263          <li>
264            <strong>GitHub's public releases API</strong>, only in the portable
265            (non-Store) build, and only if you turn update checking on. It is off by
266            default. The request is unauthenticated and sends no information about you or
267            your usage. <strong>The Microsoft Store build never contacts GitHub</strong>;
268            the Store delivers updates instead.
269          </li>
270        </ul>
271        <p>No data is sent to the developer.</p>
272
273        <h2>What the app does not do</h2>
274        <p>
275          It does not read browser data, credential stores, or session files. It does not
276          scan your network or enumerate ports. It does not run background services
277          beyond its own tray process, and it does not install or download additional
278          software.
279        </p>
280
281        <h2>Permissions</h2>
282        <p>
283          The app runs as a full-trust desktop application (<code>runFullTrust</code>).
284          This is what a packaged WPF desktop application requires; it is not used to
285          access anything described above as out of scope.
286        </p>
287
288        <h2>Website analytics</h2>
289        <p class="lede">
290          This section is about <strong>tokdash.github.io, the website rather than the app.</strong>
291          Nothing in this section applies to Tokdash Companion or to the Tokdash server;
292          those remain exactly as described above: no telemetry, no accounts, no
293          phone-home.
294        </p>
295        <p>
296          This website uses <strong>Google Analytics</strong> to understand how visitors
297          use the site. Google Analytics sets cookies in your browser and collects
298          standard web-analytics data such as the pages you visit, approximate location
299          (derived from IP address), and your browser and device type. This data is
300          processed by Google; see
301          <a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Google's Privacy Policy</a>
302          for how Google handles it. You can limit this via your browser's cookie
303          settings, tracking-protection features, or an ad/tracker blocker.
304        </p>
305        <div class="callout callout-amber">
306          <p>
307            <strong>Why the split.</strong> The Tokdash <em>app</em> is local-first and
308            collects nothing. The Tokdash <em>website</em>, including the marketing pages and demo
309            you may have arrived from, runs standard Google Analytics like most websites
310            do. Those are two different pieces of software with two different privacy
311            postures; this page states both plainly instead of letting one claim be read
312            as covering the other.
313          </p>
314        </div>
315
316        <h2>Children</h2>
317        <p>The app is not directed at children and collects no information from anyone.</p>
318
319        <h2>Changes to this policy</h2>
320        <p>Material changes to this policy will be published at this URL with an updated date.</p>
321
322        <h2>Contact</h2>
323        <p>
324          Open an issue at
325          <a href="https://github.com/JingbiaoMei/Tokdash/issues" target="_blank" rel="noopener">github.com/JingbiaoMei/Tokdash/issues</a>.
326        </p>
327
328      </article>
329
330      <p class="text-center mt-8">
331        <a href="/" class="btn btn-ghost">← Back to the Tokdash homepage</a>
332      </p>
333    </section>
334  </main>
335
336  <footer class="border-t" style="border-color: color-mix(in srgb, var(--color-border) 70%, transparent);">
337    <div class="max-w-[1180px] mx-auto px-4 sm:px-6 py-10 flex flex-col sm:flex-row items-center justify-between gap-6">
338      <div class="flex items-center gap-2.5">
339        <img src="/static/icons/logo.png" alt="" width="26" height="26" style="width:26px;height:26px;object-fit:contain;" />
340        <div>
341          <div class="mono font-extrabold leading-tight">Tokdash</div>
342          <div class="text-xs text-muted">Local token &amp; cost dashboard · MIT</div>
343        </div>
344      </div>
345      <nav class="flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-sm" aria-label="Footer">
346        <a href="/demo/" class="nav-link" style="padding:6px 0;">Live demo</a>
347        <a href="https://github.com/JingbiaoMei/Tokdash" target="_blank" rel="noopener" class="nav-link" style="padding:6px 0;">GitHub</a>
348        <a href="https://github.com/JingbiaoMei/Tokdash/blob/main/LICENSE" target="_blank" rel="noopener" class="nav-link" style="padding:6px 0;">License</a>
349      </nav>
350    </div>
351  </footer>
352
353  
353<script>
354    // ---- Theme toggle (mirrors index.html) ----
355    (function () {
356      var root = document.documentElement;
357      var moon = document.getElementById('iconMoon');
358      var sun = document.getElementById('iconSun');
359      function sync() {
360        var dark = root.classList.contains('dark');
361        moon.style.display = dark ? 'none' : 'block';
362        sun.style.display = dark ? 'block' : 'none';
363      }
364      sync();
365      document.getElementById('themeToggle').addEventListener('click', function () {
366        root.classList.toggle('dark');
367        try { localStorage.setItem('tokdash-site-theme', root.classList.contains('dark') ? 'dark' : 'light'); } catch (e) {}
368        sync();
369      });
370    })();
371  </script>
371
372
373  <!-- Lenis Smooth Scrolling -->
374  
374<script src="/static/lenis.min.js"></script>
374
375  
375<script>
376    (function () {
377      if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
378      if (typeof Lenis === 'undefined') return;
379      var lenis = new Lenis({
380        lerp: 0.12,
381        wheelMultiplier: 1.0,
382        touchMultiplier: 1.5,
383        smoothWheel: true,
384      });
385      function raf(time) { lenis.raf(time); requestAnimationFrame(raf); }
386      requestAnimationFrame(raf);
387      window.__lenis = lenis;
388    })();
389  </script>
389
390</body>
391</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.