Version History · Dev Log · Changelog

Patch Notes

A running record of everything added, fixed, and changed — written as a technical changelog, game-style patch notes, and a dev log of how the site was built.

Current version: v
v1.5.1Fix

Truth Entries Invisible + Firebase Rules Fix

Fixed The Truth page showing no content after the Firebase voting update.

🐞 Bug 1 — Truths invisible on page load

  • Root cause: truth entries had opacity: 0 in CSS by default, relying on JS adding a .visible class to show them. When truth.js became type="module" for Firebase, the script deferred and the IntersectionObserver missed elements already in the viewport.
  • Fix: entries are now visible by default. JS adds .animated only to entries below the fold. Already-visible entries are never hidden.
  • Animation is now progressive enhancement — content is always visible regardless of JS timing or errors.

🐞 Bug 2 — Firebase rules syntax error

  • The Firestore rules had invalid syntax: allow read: true is not valid — Firestore requires allow read: if true.
  • A second typo in the provided rules also caused a parse error on the write line.
  • Corrected rules use allow read: if true; allow write: if true; scoped to /votes/{"{truthId}"}.

📝 Dev Note

Never use CSS to hide content that JS is responsible for showing. If JS fails or times out, the user sees nothing. Content should always be visible by default — JS should only add animations on top. This is called progressive enhancement.

Firestore rules have their own syntax distinct from JavaScript. allow read: true looks valid but is a parse error. Firestore always requires allow read: if <condition> even when the condition is the literal true.

v1.5.0Feature

Real Contact Form + Real Shared Voting

Wired the contact form to Formspree and replaced localStorage voting with Firebase Firestore. Votes are now shared in real time across all visitors.

✉ Contact Form (Formspree)

  • Contact form now sends real emails via Formspree (form ID: maqpzpyg)
  • Submission uses fetch() to POST JSON — page never reloads
  • Button shows "Sending..." while in flight; handles success and error responses
  • Network errors (offline) caught and shown to the user

📊 Shared Voting (Firebase)

  • Agree/Disagree votes write to Firebase Firestore — shared across all visitors
  • Counts update in real time via onSnapshot — no page refresh needed
  • Each truth entry maps to a document in the votes Firestore collection
  • User vote tracked in localStorage to prevent double-voting from the same browser
  • Firebase v10 modular SDK loaded from CDN — no build step required

📝 Dev Note

Firebase modular SDK requires type="module" on the script tag. Only truth.js needed this change. Firestore's onSnapshot keeps an open connection and fires whenever any visitor votes, updating everyone live.

Formspree was chosen because it requires zero client-side configuration beyond a form ID — data is POSTed as JSON and Formspree routes it to the inbox.

v1.4.0Feature

Patch Notes Page

Added a dedicated page for version history combining changelog format, game-style patch notes, and a narrative dev log.

📄 What Shipped

  • New page: patch-notes.html with full version history from v1.0.0
  • Three formats per entry: bullet changelog, categorized patch notes, dev log narrative
  • Version type badges: Launch (green), Feature (blue), Fix (red)
  • Patch Notes link added to sidebar and footer on all pages
  • Header badge shows current version pulled from SITE_VERSION in sidebar.js

📝 Dev Note

The patch notes page is static HTML — every entry is hand-written markup. This keeps it simple, loads instantly, and lets the dev log be as narrative as needed without a CMS.

v1.3.1Fix

Dark Mode Toggle Icon Alignment

Fixed the dark/light mode toggle icon being off-center in the collapsed sidebar.

🐞 What Was Fixed

  • .sidebar-footer had 16px padding pushing the toggle button inward, misaligning it with nav icons.
  • Toggle button lacked border-left: 3px solid transparent that all nav links have, causing a 3px horizontal offset.
  • Fixed by removing footer padding, adding matching border-left to the toggle, and giving footer text its own padding.

📝 Dev Note

The sidebar nav links all look aligned because they share an invisible 3px left border. The toggle button was the odd one out. Simple fix once the cause was found.

v1.3.0Feature

More Content, Search Bars, Dark Mode

The biggest single update. 18 new pieces of content, search bars on every content page, a dark/light mode toggle, and 6 new games.

🎮 Games (6 new, 12 total)

  • Added Tennis Random, Football Random, Basketball Stars, Subway Surfers, Stickman Hook, Getaway Shootout
  • Added filter tabs: All / 2 Player / 1 Player / Sports / Other
  • Added live search bar

◎ Truths (5 new, 12 total)

  • Added: Radioactive bananas, Birthday Paradox, Oxford older than Aztecs, Mammoths and pyramids, Monty Hall problem
  • Added live search bar

∞ Paradoxes (3 new, 10 total)

  • Added: Sorites Paradox, Fermi Paradox, Bootstrap Paradox
  • Featured rotation expanded to 8 paradoxes, quiz to 8 questions
  • Added live search bar

🌓 Dark / Light Mode

  • Toggle in sidebar, defaults to OS preference, saved in localStorage
  • No flash on load — inline script in <head> sets theme before first paint
  • SVG sun/moon icons replace inconsistent unicode characters

📝 Dev Note

Dark mode uses CSS custom property overrides on html[data-theme]. Search bars filter client-side via data-search attributes on each item — no backend needed.

v1.2.0Feature

Featured Paradox Rotation + Version System

Auto-rotating featured paradox card with nav controls, and the site-wide version number.

🔄 Featured Rotation

  • Auto-rotates every 7 seconds through 6 paradoxes
  • Prev/next arrows and dot indicators; hover pauses timer
  • Smooth slide animation between paradoxes

📋 Version System

  • Version shown in footer of every page and About page fact card
  • Single source: change SITE_VERSION in sidebar.js to update everywhere

📝 Dev Note

The rotation system was rebuilt twice. First version injected elements dynamically and queried by class — failed silently when structure differed. Fix: explicit IDs on every element JS touches.

v1.1.0Feature

Full Site — All Pages Built

Expanded from a homepage to a complete 6-page site. All pages share the sidebar, styles.css, and sidebar.js.

🎮 Games

  • Password gate remembered for the session
  • 6 browser games embedded in a fullscreen iframe modal

◎ The Truth

  • 7 debatable facts with scroll-triggered animations
  • Agree/Disagree voting saved in localStorage

∞ Paradoxes

  • Featured card, 7-entry accordion list, 6-question quiz

▲ Shared Infrastructure

  • All CSS moved to styles.css, all JS to dedicated .js files
  • Active nav link auto-detected by URL

📝 Dev Note

Cloudflare's proxy intercepts email addresses in HTML and replaces them with obfuscated garbage. Fix: write all HTML files through Python and assemble the address from concatenated parts at write time so it never appears as a raw string.

v1.0.0Launch

Initial Launch — Homepage

First version of evundavis.com.

📄 What Shipped

  • Homepage: hero, cards grid, about strip, highlights, stats strip
  • Sticky collapsible sidebar — state saved in localStorage
  • Mobile overlay sidebar with tap-to-close backdrop
  • Scroll-triggered entrance animations (IntersectionObserver)
  • Dynamic copyright year, favicon, footer with phone and email

📄 Tech Stack

  • Pure HTML, CSS, vanilla JavaScript — no frameworks, no build tools
  • Playfair Display + DM Sans + DM Mono via Google Fonts
  • CSS custom properties for the full design system
  • 3 files at launch: index.html, styles.css, sidebar.js

📝 Dev Note

Sidebar collapse uses a CSS width transition with overflow: hidden to hide labels, and margin-left on the main wrapper to shift with it. localStorage remembers state so it does not flash on reload.