Web.Showdown.mp4
A full-stack web application exploring the Sator Square, one of the oldest known palindromes in human history. Features a Three.js 3D stone tablet visualization, an interactive puzzle game, a reading direction explorer, and ML-powered pattern analysis — all connected through a Python FastAPI backend with React.js frontend.
The Sator Square is a five-word Latin palindrome arranged in a 5x5 grid, readable from left-to-right, right-to-left, top-to-bottom, and bottom-to-top — all producing the same five words:
S A T O R
A R E P O
T E N E T
O P E R A
R O T A S
Discovered in Pompeii (buried 79 AD), it has been found across the Roman Empire and medieval Europe. Its letters can also be rearranged to form two copies of "PATER NOSTER" (Our Father) with the letters A and O remaining — symbols of Alpha and Omega in early Christianity.
+---------------------------------------------+
| React.js Frontend (Port 5173) |
| +----------+ +----------+ +------------+ |
| | Three.js | | Puzzle | | Explore | |
| | 3D View | | Game | | Modes | |
| +----+-----+ +----+-----+ +------+-----+ |
| +------------+-------------+ |
| Services / Hooks |
| | |
| API Service Layer |
| | |
+--------------------+------------------------+
| HTTP / Proxy
+--------------------+------------------------+
| Python FastAPI Backend (Port 8000) |
| +----------+ +----------+ +------------+ |
| | Sator | | Pattern | | Stats | |
| | Analyzer | | Analyzer | | Service | |
| | (Logic) | | (ML) | | | |
| +----+-----+ +----+-----+ +------+-----+ |
| +------------+-------------+ |
| Repository Layer |
| | |
| +-----------------+------------------+ |
| | SQLAlchemy + SQLite (ORM) | |
| +-----------------------------------+ |
+---------------------------------------------+
| Layer | Technology | Responsibility |
|---|---|---|
| API Server | Python FastAPI | REST endpoints, CORS, request routing |
| Service Layer | Python classes | Business logic: validation, analysis, shuffling |
| Repository Layer | SQLAlchemy ORM | Database abstraction: CRUD on SQLite |
| ML Engine | scikit-learn + NumPy | Symmetry scoring, entropy calculation, anomaly detection |
| API Client | Axios | HTTP requests with automatic fallback to local data |
| State Management | React Hooks | usePuzzle, useSatorData — UI state logic |
| 3D Renderer | Three.js + R3F | Stone tablet with gold letters, particles, orbit controls |
| Styling | TailwindCSS 4 | Utility-first CSS with custom theme tokens |
sator-square-project/
+-- backend/
| +-- app/
| | +-- __init__.py
| | +-- main.py # FastAPI app, routes, CORS
| | +-- database.py # SQLAlchemy engine, session
| | +-- models.py # PuzzleAttempt, HistoricalSite ORM
| | +-- schemas.py # Pydantic request/response models
| | +-- services/
| | +-- __init__.py
| | +-- sator_logic.py # SatorAnalyzer: validate, directions, shuffle
| | +-- pattern_analyzer.py # PatternAnalyzer: symmetry, entropy, ML
| +-- requirements.txt
| +-- run.py # Uvicorn entry point
|
+-- frontend/
| +-- src/
| | +-- main.jsx # React entry point
| | +-- App.jsx # Root component, layout
| | +-- index.css # Tailwind + custom theme + keyframes
| | +-- utils/
| | | +-- constants.js # SATOR_SQUARE data, meanings, helpers
| | +-- services/
| | | +-- api.js # Axios client with fallback logic
| | +-- hooks/
| | | +-- usePuzzle.js # Puzzle state machine (timer, pool, grid)
| | | +-- useSatorData.js # Data fetching for square, stats, sites
| | +-- components/
| | +-- Navbar.jsx # Fixed nav with scroll tracking
| | +-- HeroSection.jsx # Animated letter reveal
| | +-- Sator3DViewer.jsx # Three.js 3D stone tablet
| | +-- ExploreSection.jsx # Direction highlight explorer
| | +-- PuzzleSection.jsx # Interactive puzzle game
| | +-- TutorialModal.jsx # Step-by-step tutorial overlay
| | +-- HistorySection.jsx # Historical sites cards
| +-- index.html
| +-- vite.config.js # Vite + Tailwind + API proxy
| +-- package.json
|
+-- README.md
- Three.js with @react-three/fiber and @react-three/drei
- 25 letter blocks arranged on a stone slab
- Gold metallic letter plates with hover glow effects
- Floating dust particles in the scene
- Auto-rotation with orbit controls (drag to rotate, scroll to zoom)
- Dynamic lighting with warm gold and white tones
- 25 letters shuffled into a pool
- Click-to-select from pool, click-to-place on 5x5 grid
- Click filled cells to remove letters
- Real-time timer with hint penalty tracking (+15s per hint)
- Hint system that auto-places one correct letter
- Visual feedback: flash on place, shake on wrong, glow celebration on solve
- Tutorial modal with 6 illustrated steps before playing
- Best time and solve count persisted via API
- Four directional buttons: Right, Left, Down, Up
- Staggered cell highlighting animation (cascade effect)
- Word chips with Latin meanings appear per direction
- Hover on word chip to highlight corresponding row/column
- "Reveal All" mode for full illumination
- Symmetry Score: Compares grid against its transpose and 180 degree rotation using NumPy
- Shannon Entropy: Calculates letter distribution randomness
- PATER NOSTER Check: Verifies if all letters can form two "PATER NOSTER" with A and O remaining
- Anomaly Detection: Isolation Forest trained on the known-correct Sator Square to detect if a given grid is anomalous
- All analysis exposed via POST /api/puzzle/analyze
- Data fetched from backend API with database seeding
- 5 real archaeological sites: Pompeii, Dura-Europos, Cirencester, Cihampelas, Austria
- Cards with hover animations and gradient reveals
| Package | Purpose |
|---|---|
| FastAPI | High-performance async web framework with auto-generated Swagger docs |
| Uvicorn | ASGI server with hot-reload |
| SQLAlchemy 2.0 | ORM with declarative models, SQLite backend |
| Pydantic 2.0 | Request/response validation with type safety |
| NumPy | Array operations for symmetry and entropy calculations |
| scikit-learn | Isolation Forest for anomaly detection |
| Package | Purpose |
|---|---|
| React 19 | UI component library with hooks |
| Three.js | 3D WebGL rendering engine |
| @react-three/fiber | React renderer for Three.js (declarative 3D) |
| @react-three/drei | Useful Three.js helpers (OrbitControls, Float, Text) |
| Axios | HTTP client with interceptors |
| TailwindCSS 4 | Utility-first CSS framework with CSS theme variables |
| Vite | Fast build tool with HMR and API proxy |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health | Health check |
| GET | /api/square | All reading directions with meanings |
| GET | /api/puzzle/pool | Generate shuffled letter pool |
| POST | /api/puzzle/validate | Validate a 5x5 grid against correct square |
| POST | /api/puzzle/analyze | ML pattern analysis (symmetry, entropy, PATER NOSTER) |
| POST | /api/puzzle/complete | Save puzzle completion to database |
| GET | /api/stats | Get top 20 completion times |
| GET | /api/sites | Get historical sites (auto-seeded on first call) |
Full interactive API documentation available at http://localhost:8000/docs (Swagger UI).
- Python 3.8+ (tested on 3.10)
- Node.js 18+ and npm
- Git
mkdir sator-square-project
cd sator-square-projectmkdir -p backend/app/services
New-Item -ItemType File -Force -Path backend/app/__init__.py
New-Item -ItemType File -Force -Path backend/app/services/__init__.pyCreate backend/requirements.txt:
fastapi
uvicorn
sqlalchemy
pydantic
numpy
scikit-learn
Create backend/run.py:
import uvicorn
if __name__ == "__main__":
print("=== Sator Square API ===")
print("Running at http://localhost:8000")
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=False)Install and run:
cd backend
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt
python run.pyVerify: open http://localhost:8000/docs (Swagger UI should appear).
Open a new terminal:
cd sator-square-project
npm create vite@latest frontendSelect React > JavaScript > Oxlint > Yes when prompted. Then:
cd frontend
npm install three @react-three/fiber @react-three/drei
npm install axios framer-motion
npm install -D tailwindcss @tailwindcss/viteReplace vite.config.js, index.html, src/index.css, and create all source files under src/components/, src/services/, src/hooks, src/utils/ as shown in the source code.
Remove Vite defaults:
Remove-Item -Force src/App.css -ErrorAction SilentlyContinueRun:
npm run devOpen http://localhost:5173 — the app should load with both terminals running.
- Never use
touch— it is a Linux command. UseNew-Item -ItemType File -Forceinstead - Use
python -m venv venvwith the full Python path if multiple versions are installed - Use
reload=Falsein run.py —reload=Truecrashes on Windows - Frontend works offline — if backend is down, all data falls back to local constants
- Use Python for writing files with backticks — PowerShell breaks on backticks inside here-strings
The frontend works standalone without the backend. If the API is unavailable, all data falls back to local constants. The puzzle uses client-side validation, and historical sites use hardcoded data.
- Color Palette: Warm dark theme (#080706 abyss, #c4915a ember gold) — inspired by ancient stone and firelight, avoids generic blue/purple schemes
- Typography: Cinzel (headings — classical Roman feel) + Cormorant Garamond (body — elegant serif with light weights)
- 3D Camera: Angled top-down view (position: [0, 5, 3]) to simulate viewing a real stone tablet lying on a surface
- Fallback Architecture: Every API call has a try/catch fallback, making the frontend resilient to backend downtime
- No SQL Required: Uses SQLite via SQLAlchemy ORM — zero database setup needed, file-based and portable
- Tutorial Before Play: 6-step modal tutorial prevents confusion for first-time users
| Word | Latin | English | Role |
|---|---|---|---|
| SATOR | Sator, satoris | The sower, planter | The one who plants |
| AREPO | unknown | Possibly a name or specialized term | Mysterious — unique to this square |
| TENET | Tenet, tenere | Holds, keeps | That which holds together |
| OPERA | Opera, opus | Works, labor, deeds | The results of labor |
| ROTAS | Rota, rotae | Wheels, rotations | The turning of wheels |
This project is for personal purposes.
- Historical data sourced from archaeological research on Roman-era inscriptions
- 3D visualization inspired by ancient stone carvings and tabula ansata
- The Sator Square itself — a mystery created nearly 2,000 years ago