# Website Redesign Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Redesign the word search frontend with a dark indigo palette, pill-style navbar, footer, two new content pages (How to Play, About), and emoji/icon accents. **Architecture:** Enhance existing Tornado template hierarchy in place. `base.html` gets navbar restructure, Bootstrap Icons CDN, semantic HTML, and a footer. Child templates set an `active_page` block for nav highlighting. Two new handlers + templates for the new pages. CSS swaps teal variables for indigo palette. **Tech Stack:** Python/Tornado, Bootstrap 5.3 (dark mode), Bootstrap Icons (CDN), pytest + pytest-tornasync **Spec:** `docs/superpowers/specs/2026-05-06-website-redesign-design.md` --- ## File Map ### Modified | File | Responsibility | |------|---------------| | `tests/e2e/test_hello.py` | E2e tests for all routes including new ones | | `app.py` | Route registration — add `/howtoplay` and `/about` | | `static/css/theme.css` | Full palette swap + new component styles | | `templates/base.html` | Shared layout: navbar, footer, Bootstrap Icons, active page logic | | `templates/main.html` | Homepage hero with emoji and coral CTA | | `templates/game.html` | Game board card restyled for new palette | ### Created | File | Responsibility | |------|---------------| | `handlers/howtoplay.py` | HowToPlayHandler — renders howtoplay.html | | `handlers/about.py` | AboutHandler — renders about.html | | `templates/howtoplay.html` | How to Play instructions page | | `templates/about.html` | About page with app description and authors | --- ### Task 1: Add e2e tests for new routes **Files:** - Modify: `tests/e2e/test_hello.py` - [ ] **Step 1: Add tests for `/howtoplay` and `/about` routes** Replace the contents of `tests/e2e/test_hello.py` with: ```python import pytest from app import make_app @pytest.fixture def app(): return make_app() async def test_homepage_returns_200(http_server_client): response = await http_server_client.fetch("/") assert response.code == 200 async def test_game_returns_200(http_server_client): response = await http_server_client.fetch("/game") assert response.code == 200 async def test_howtoplay_returns_200(http_server_client): response = await http_server_client.fetch("/howtoplay") assert response.code == 200 async def test_about_returns_200(http_server_client): response = await http_server_client.fetch("/about") assert response.code == 200 ``` - [ ] **Step 2: Run tests to verify new tests fail** Run: `uv run pytest tests/e2e/ -v` Expected: `test_homepage_returns_200` PASS, `test_game_returns_200` PASS, `test_howtoplay_returns_200` FAIL (404), `test_about_returns_200` FAIL (404) --- ### Task 2: Create handlers and register routes **Files:** - Create: `handlers/howtoplay.py` - Create: `handlers/about.py` - Create: `templates/howtoplay.html` (minimal placeholder) - Create: `templates/about.html` (minimal placeholder) - Modify: `app.py` - [ ] **Step 1: Create HowToPlayHandler** Create `handlers/howtoplay.py`: ```python import tornado.web class HowToPlayHandler(tornado.web.RequestHandler): def get(self): self.render("howtoplay.html") ``` - [ ] **Step 2: Create AboutHandler** Create `handlers/about.py`: ```python import tornado.web class AboutHandler(tornado.web.RequestHandler): def get(self): self.render("about.html") ``` - [ ] **Step 3: Create placeholder templates** Create `templates/howtoplay.html`: ```html {% extends "base.html" %} {% block title %}Word Search — How to Play{% end %} {% block content %}

How to Play

Instructions coming soon.

{% end %} ``` Create `templates/about.html`: ```html {% extends "base.html" %} {% block title %}Word Search — About{% end %} {% block content %}

About

About page coming soon.

{% end %} ``` - [ ] **Step 4: Register routes in app.py** In `app.py`, add imports after the existing handler imports: ```python from handlers.howtoplay import HowToPlayHandler from handlers.about import AboutHandler ``` Add routes to the `make_app()` route list, after the `/game` route: ```python (r"/howtoplay", HowToPlayHandler), (r"/about", AboutHandler), ``` - [ ] **Step 5: Run tests to verify all pass** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 6: Lint and commit** Run: `uv run black . && uv run flake8` ```bash git add handlers/howtoplay.py handlers/about.py templates/howtoplay.html templates/about.html app.py tests/e2e/test_hello.py git commit -m "feat: add howtoplay and about routes with placeholder templates" ``` --- ### Task 3: Swap CSS palette and add component styles **Files:** - Modify: `static/css/theme.css` - [ ] **Step 1: Replace full contents of `static/css/theme.css`** ```css :root { --indigo-darkest: #1a1a2e; --indigo-dark: #16213e; --indigo-mid: #0f3460; --coral: #e94560; --coral-light: #ff6b81; --gold: #f5c518; --text-primary: #e0e0e0; --text-muted: #a0aec0; } body { background-color: var(--indigo-darkest); color: var(--text-primary); } /* Navbar */ .navbar { background-color: var(--indigo-dark); border-bottom: 1px solid var(--indigo-mid); } .navbar-brand { color: var(--coral); font-weight: 700; display: flex; align-items: center; gap: 0.4rem; } .navbar-brand:hover { color: var(--coral-light); } .navbar-nav .nav-link { color: var(--text-muted); border-radius: 6px; padding: 0.4rem 1rem; margin: 0 0.15rem; font-weight: 500; transition: background-color 0.2s, color 0.2s; } .navbar-nav .nav-link:hover { color: #ffffff; background-color: rgba(15, 52, 96, 0.5); } .navbar-nav .nav-link.active { color: #ffffff; background-color: var(--indigo-mid); } /* Hero */ .hero { text-align: center; padding: 3rem 1rem; } .hero-emoji { font-size: 3rem; margin-bottom: 0.75rem; } .hero h1 { color: #ffffff; font-weight: 800; } .hero .lead { color: var(--text-muted); max-width: 500px; margin-left: auto; margin-right: auto; } /* Buttons */ .btn-accent { background-color: var(--coral); border-color: var(--coral); color: #ffffff; font-weight: 600; } .btn-accent:hover { background-color: var(--coral-light); border-color: var(--coral-light); color: #ffffff; } /* Cards */ .card { background-color: var(--indigo-dark); border-color: var(--indigo-mid); } /* Content pages */ .content-section { background-color: var(--indigo-dark); border: 1px solid var(--indigo-mid); border-radius: 8px; padding: 2rem; margin-bottom: 1.5rem; } .step-number { display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; background-color: var(--indigo-mid); color: var(--gold); border-radius: 50%; font-weight: 700; font-size: 0.875rem; flex-shrink: 0; } .step-item { display: flex; gap: 1rem; align-items: flex-start; margin-bottom: 1.25rem; } .step-item p { margin: 0; } .tip-card { background-color: rgba(15, 52, 96, 0.4); border-left: 3px solid var(--gold); border-radius: 4px; padding: 1rem 1.25rem; margin-bottom: 0.75rem; } /* Footer */ .site-footer { border-top: 1px solid var(--indigo-mid); padding: 1.25rem 0; text-align: center; color: var(--text-muted); font-size: 0.85rem; margin-top: 3rem; } ``` - [ ] **Step 2: Verify the app still renders** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS (CSS changes don't break templates) - [ ] **Step 3: Commit** ```bash git add static/css/theme.css git commit -m "style: swap teal palette for dark indigo with coral accents" ``` --- ### Task 4: Restructure base.html **Files:** - Modify: `templates/base.html` - [ ] **Step 1: Replace full contents of `templates/base.html`** ```html {% block title %}Word Search{% end %} {% block active_page %}{% end %}
{% block content %}{% end %}
``` **Note on active page logic:** Tornado templates don't support `{% set %}` like Jinja2. The `{% block active_page %}{% end %}` block is intentionally empty in the base. Each child template overrides it with `{% block active_page %}{% set active_page = "home" %}{% end %}`. Tornado's `{% set %}` creates a template variable accessible in the rest of the template including the base. - [ ] **Step 2: Update child templates to set active_page** In `templates/main.html`, add after the `{% extends %}` line: ```html {% block active_page %}{% set active_page = "home" %}{% end %} ``` In `templates/game.html`, add after the `{% extends %}` line: ```html {% block active_page %}{% set active_page = "play" %}{% end %} ``` In `templates/howtoplay.html`, add after the `{% extends %}` line: ```html {% block active_page %}{% set active_page = "howtoplay" %}{% end %} ``` In `templates/about.html`, add after the `{% extends %}` line: ```html {% block active_page %}{% set active_page = "about" %}{% end %} ``` - [ ] **Step 3: Run tests** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 4: Commit** ```bash git add templates/base.html templates/main.html templates/game.html templates/howtoplay.html templates/about.html git commit -m "feat: restructure base template with navbar pills, footer, and active page logic" ``` --- ### Task 5: Restyle homepage hero **Files:** - Modify: `templates/main.html` - [ ] **Step 1: Replace content block in `templates/main.html`** Full file contents: ```html {% extends "base.html" %} {% block active_page %}{% set active_page = "home" %}{% end %} {% block title %}Word Search — Home{% end %} {% block content %}
🧩

Word Search

Find hidden words in a grid of letters. Words can appear horizontally, vertically, or diagonally. How fast can you find them all?

🎮 Start Game
{% end %} ``` - [ ] **Step 2: Run tests** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 3: Commit** ```bash git add templates/main.html git commit -m "style: restyle homepage hero with emoji and coral CTA" ``` --- ### Task 6: Update game page for new palette **Files:** - Modify: `templates/game.html` - [ ] **Step 1: Replace full contents of `templates/game.html`** ```html {% extends "base.html" %} {% block active_page %}{% set active_page = "play" %}{% end %} {% block title %}Word Search — Play{% end %} {% block content %}

🎯 Game Board

Game board coming soon.

{% end %} ``` - [ ] **Step 2: Run tests** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 3: Commit** ```bash git add templates/game.html git commit -m "style: update game page with active nav and emoji heading" ``` --- ### Task 7: Create How to Play page content **Files:** - Modify: `templates/howtoplay.html` - [ ] **Step 1: Replace full contents of `templates/howtoplay.html`** ```html {% extends "base.html" %} {% block active_page %}{% set active_page = "howtoplay" %}{% end %} {% block title %}Word Search — How to Play{% end %} {% block content %}

📖 How to Play

Step-by-Step Instructions

1

📋 Check the word list — Look at the list of words displayed alongside the grid. These are the words you need to find.

2

🔍 Scan for the first letter — Pick a word from the list and scan the grid for its first letter. This gives you a starting point.

3

↗️ Look in all directions — Words can run horizontally, vertically, or diagonally — and they can go forward or backward. Check all eight directions from your starting letter.

4

👆 Select the word — Click or tap the first letter of the word, then click the last letter to highlight the entire word.

5

Words get crossed off — When you correctly find a word, it gets crossed off the list so you can track your progress.

6

🏆 Find them all to win! — The puzzle is complete when every word on the list has been found. Try to beat your best time!

💡 Tips

Start with uncommon letters — Letters like Q, X, Z, and J appear less often in the grid, making words with those letters easier to spot.
Scan systematically — Work through the grid row by row or column by column rather than jumping around randomly.
Look for word shapes — Sometimes you can spot diagonal words by the distinctive slanted pattern they make in the grid.
{% end %} ``` - [ ] **Step 2: Run tests** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 3: Commit** ```bash git add templates/howtoplay.html git commit -m "feat: add How to Play page with step-by-step instructions and tips" ``` --- ### Task 8: Create About page content **Files:** - Modify: `templates/about.html` - [ ] **Step 1: Replace full contents of `templates/about.html`** ```html {% extends "base.html" %} {% block active_page %}{% set active_page = "about" %}{% end %} {% block title %}Word Search — About{% end %} {% block content %}

ℹ️ About

🧩 What is Word Search?

Word Search is a browser-based puzzle game where you find hidden words in a grid of letters. Words can be placed horizontally, vertically, or diagonally — forwards or backwards. The backend generates puzzles, validates your selections, and tracks your progress in real time.

🛠️ Built With

✍️ Authors

📂 Source Code

The source code for this project will be available on GitHub. Link coming soon.

{% end %} ``` - [ ] **Step 2: Run tests** Run: `uv run pytest tests/e2e/ -v` Expected: All 4 tests PASS - [ ] **Step 3: Commit** ```bash git add templates/about.html git commit -m "feat: add About page with app description, tech stack, and authors" ``` --- ### Task 9: Final verification - [ ] **Step 1: Run full test suite** Run: `uv run pytest -v` Expected: All tests PASS (unit + e2e) - [ ] **Step 2: Lint and format** Run: `uv run black . && uv run flake8` Expected: No errors - [ ] **Step 3: Start the server and visually verify with Playwright** Start the app: `uv run python app.py &` Use Playwright MCP tools to: 1. Navigate to `http://localhost:8888` — verify indigo palette, navbar with 4 pill-style links, "Home" is active, hero section with puzzle emoji, coral "Start Game" button, footer with copyright 2. Navigate to `http://localhost:8888/game` — verify "Play" is active in navbar, game card renders 3. Navigate to `http://localhost:8888/howtoplay` — verify "How to Play" is active, 6 numbered steps visible, 3 tip cards visible 4. Navigate to `http://localhost:8888/about` — verify "About" is active, 4 content sections visible (What is, Built With, Authors, Source Code) 5. Resize browser to mobile width — verify navbar collapses to hamburger menu - [ ] **Step 4: Stop the server and commit any fixes** Kill the background server process. If any visual issues were found and fixed, commit the fixes.