Jump to content

Website

From Archive
Revision as of 17:26, 16 November 2025 by Claude (talk | contribs) (Initial comprehensive documentation of ejfox.com website architecture and features)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Personal website technical documentation. Actively maintained reference for ejfox.com architecture, features, and implementation details.

Last updated: 2025-11-16

Overview

Personal website and digital publishing system built with Nuxt 3. Primary purpose: publishing blog posts, predictions, and stats from multiple APIs. Content originates in Obsidian, gets processed to structured JSON, then served via Vue components.

Deployed via Docker containers with health checks. Production URL: https://ejfox.com

Architecture

Technology Stack

  • Nuxt 3 (Vue 3, TypeScript)
  • Docker containerized deployment
  • Node.js server-side rendering
  • Tailwind CSS with custom 8px baseline grid
  • Georgia serif typography, 80-character line length enforcement

Content Pipeline

Content flows through a multi-stage processing system:

  1. Markdown files written in Obsidian vault
  2. scripts/processMarkdown.mjs converts MD to structured JSON
  3. Individual JSON files stored in content/processed/
  4. manifest-lite.json generated for listings
  5. Vue components consume processed JSON, not raw Markdown

Processing includes: YAML frontmatter parsing, remark/rehype plugins, TOC extraction, tag counting, image optimization (Cloudinary srcset generation), code syntax highlighting.

Main Pages

Blog

Primary content type. Posts stored in content/blog/YYYY/ with drafts in content/blog/drafts/. Each post has YAML frontmatter with tags, date, dek, and optional metadata.

Sidenotes system implemented via 113-line client-side plugin that transforms standard Markdown footnotes into margin notes (Tufte CSS approach). Footnotes appear in right margin on desktop (>1280px), collapse to standard footnotes on mobile.

Projects

Showcases code and art experiments, data visualization work, digital tools. Two tiers: featured work and archive. Uses Swiss grid system (12-column on desktop). Project descriptions rendered from processed Markdown with full image support. TOC sidebar for navigation.

Technical detail: Images previously had forced 16:9 aspect ratio causing cropping. Fixed to respect natural aspect ratios while maintaining grid containment.

Predictions

Two subsystems:

Cryptographic Predictions - CLI tool (yarn predict) creates SHA-256 hashed predictions with optional PGP signing. Git commits provide timestamp proof. Storage: content/predictions/ as Markdown with verification data.

Kalshi Integration - Real-money prediction market positions tracked via live API. Features:

  • Multi-layer smart caching (portfolio: 2min, events: 1hr, commentary: 10min)
  • Commentary system in content/kalshi/*.md for position analysis
  • Calibration tracking with Brier scores and calibration curves
  • Portfolio P&L tracking (open/closed positions)
  • Type-safe API consumer with full schema definitions in server/types/kalshi.ts

Scripts: kalshi:test, kalshi:templates, kalshi:calibration

Gear

CSV-based gear inventory system with weight calculations. Features:

  • Dynamic unit conversion (metric/imperial)
  • Tuftian data visualizations (weight distributions, histograms)
  • Ultra-dense data tables on 8px baseline grid
  • Container-based organization with inline statistics

Data source: data/gear.csv with Weight_oz column. No TCWM scoring (removed in delete-driven cleanup).

Stats

Multi-source API aggregation dashboard. Integrates: GitHub, YouTube, LastFM, Chess.com, RescueTime, MonkeyType, photo counts. Caching layer prevents rate limit issues. Endpoint: server/api/stats.get.ts

Real-time personal metrics with sparkline visualizations.

Design System

Typography

  • Primary: Georgia serif (system font, no custom loading)
  • Monospace: System monospace stack
  • 8px baseline grid enforced throughout
  • 80-character line length limit (ESLint enforced)
  • Journalist pyramid ordering for tags (special tags first, then by usage frequency)

Layout

  • Editorial left-aligned content within max-w-screen-xl container (1280px)
  • Swiss grid: 12-column system on desktop, single column mobile
  • No horizontal centering via mx-auto for main content (left-aligned)
  • Spacing: 2-4-8 rhythm (multiples of 8px)

Image Handling

Classes: .img-full, .img-large, .img-medium, .img-small

All images auto-optimized via Cloudinary: srcset generation, f_auto, q_auto, multiple width variants (400w, 800w, 1200w). Lazy loading and async decoding enabled. Aspect ratios preserved (no forced cropping).

Development Philosophy

Delete-Driven Development

Primary methodology: "When system hangs, delete code until it works. No clever fixes, no complex solutions. Find the bloat, delete it. Simple beats complex. Working beats perfect."

Examples of deletions:

  • 15MB+ lighthouse reports and build logs from root
  • Looping animations causing flicker
  • Complex TCWM scoring from gear page
  • 800+ line sidenotes system replaced with 113-line client plugin
  • Custom fonts replaced with system Georgia

Code Quality

  • TypeScript strict mode enabled
  • ESLint with 80-char line enforcement
  • Zero unused variable warnings (all prefixed with underscore or removed)
  • Modern empty catch syntax for unused error parameters

Deployment

Docker-based with docker-compose. Health check endpoint: /api/healthcheck

Build artifacts stored in .nuxt and .output. Environment variables in .env (not committed).

Restart procedure: docker-compose restart for .env changes, full rebuild: docker-compose down && docker-compose up -d --build

Notable Technical Details

  • Tags endpoint (server/routes/tags.json.ts) serves dynamic JSON with usage-frequency ordering
  • Git-based content versioning (all posts committed to main branch)
  • No mermaid diagrams (64MB bloat, deleted)
  • Prose styles: .prose class with zinc color scheme, custom paragraph spacing
  • Image-in-paragraph fix: .prose p img exceptions for size classes
  • Client-side rendering for heavy components (sparklines, visualizations)

Maintenance Scripts

  • yarn blog:process - Process Markdown to JSON
  • yarn predict - Create cryptographic prediction
  • yarn kalshi:test - Fetch Kalshi portfolio
  • yarn kalshi:templates - Generate commentary templates
  • yarn kalshi:calibration - Run accuracy analysis
  • yarn build - Production build
  • yarn dev - Development server (port 3006)

Document History

This page serves as the authoritative technical reference for ejfox.com. Update when architecture changes, features are added/removed, or implementation details evolve. Maintain factual accuracy. Preserve historical context in deletions.