← Back to today

Privacy

Short version: no accounts, no tracking cookies, no profile. Your IP is hashed before it's stored. Demographics are opt-in.

What gets sent when you play

When you submit a guess, the server receives the lat/lng you clicked, a Turnstile token (Cloudflare's privacy-friendly bot challenge), and the standard request metadata every web server sees: your IP address and user-agent string. That's it. No cookies, no localStorage beacons, no third-party trackers.

How your IP is handled

Your IP is never stored in plaintext. Before any row hits the database, the server computes:

fingerprint = sha256(ip_/24 || user_agent || daily_salt || puzzle_id)
  • The IP is truncated to its /24 (the last octet is zeroed out) before hashing — so the hash maps to a network neighbourhood, not to you specifically.
  • A daily salt rotates every 24 hours, which means yesterday's hash can't be linked to today's even on the same network.
  • The hash is scoped per puzzle, so a hash from one day's puzzle can't be cross-referenced against another's.

Why hash at all? To enforce one guess per device per day so a single person can't submit 50 guesses and skew the public heatmap. We never need the original IP after the hash is computed.

Demographics (opt-in)

After your first guess you'll see an optional sheet asking for your country and an age bucket. Both are optional, both default to "skip", and both can be cleared from the settings cog at any time. When set, they're attached only to your own guess rows — so the heatmap can show "what did 26–35 year-olds guess?" without ever joining your data to a profile.

Demographics are validated server-side against a fixed allow-list (shared/types.ts); anything else is silently dropped.

Backfilling demographics

If you save demographics after already playing several days, the client lists past puzzle IDs from localStorage and the server rederives the same fingerprint hash from the current request to find rows you can update. No hash ever crosses the wire and a different network/UA can't impersonate yours.

Analytics

We use Cloudflare Web Analytics, a cookieless beacon that aggregates anonymous traffic stats (page views, geographic distribution, browser shares). It does not set any persistent identifier, does not follow you across sites, and is not sold or shared with third parties.

What we don't have

  • No accounts. No email, no login, no password.
  • No advertising. No marketing pixels, no third-party SDKs.
  • No persistent tracking cookies of any kind.
  • No cross-site tracking. Nothing is sold, ever.

Data we do store

  • The lat/lng you guessed, plus the score we computed.
  • The fingerprint hash described above.
  • Your country / age bucket if (and only if) you provided them.

Streaks, history, and onboarding flags live in your browser's localStorage — they never reach our server.