# TOPEDU SEO OS — Phase 1

Internal SEO operating system for **topeduprep.uk**. Phase 1 ships the
real, working app shell: project architecture, routing, layout,
navigation, theme, and local-first storage. Every other module is
registered in the navigation and command palette so the information
architecture is complete and honest about status — modules not yet
built route to a clearly-labeled "Phase N" screen instead of fake UI.

## Run it

This is a zero-build vanilla ES-module app — no npm install required
to view it. Browsers block `import` over `file://`, so serve the
folder instead of double-clicking `index.html`:

```bash
cd topedu-seo-os
python3 -m http.server 8080
# or: npx serve .
```

Then open `http://localhost:8080`.

## Stack decision (Phase 1)

The brief specified Tailwind CSS. Phase 1 ships hand-written CSS with
a token system (`src/css/theme.css`) instead — Tailwind's utility
defaults fight against building a distinctive, non-templated visual
identity, and a zero-build project has no CDN dependency to break
offline. If a future phase wants Tailwind for velocity on new modules,
it can be added as a build step without touching the existing
components (they're plain HTML strings + CSS classes, not JSX).

Everything else matches the spec: vanilla JS ES modules, Local
Storage, IndexedDB, PWA manifest + service worker. Chart.js,
Mermaid.js, SortableJS, Fuse.js, and Marked.js aren't loaded yet —
they come in with the modules that actually need them (Keyword
Explorer, Topic Cluster, Content Planner) in Phase 2, rather than
sitting unused in Phase 1.

## Design direction

**Scantron precision** — the product's own subject is a test-prep
company's SEO operations, so the UI borrows from an answer sheet: a
deep ink-navy dark theme (not pure black), a warm amber accent used
only for primary actions and "marked" states, a teal for
correct/complete states, and a monospace utility face for anything
that reads like a score. The signature element is the **scantron
badge** (`src/components/ScantronBadge.js`) — a row of filled/unfilled
bubbles used everywhere a module needs to show a level at a glance:
priority, difficulty, score, phase progress. It replaces the generic
"progress bar" or "star rating" with something specific to this
brief.

Layout follows the Linear/Notion/Cursor reference: fixed collapsible
sidebar, thin topbar with a global search trigger, content in a
scrollable main pane. Cmd/Ctrl+K opens a command palette over every
module plus a couple of system actions (theme, sidebar).

## Project structure

```
index.html               Shell markup — three mount points, nothing else
manifest.json             PWA manifest
sw.js                     Service worker — cache-first app shell for offline boot
assets/icons/             App icon (SVG, scales to any manifest size)
src/
  css/
    theme.css              Design tokens — color, type, spacing, motion (dark + light)
    base.css                Resets, typography, app-shell grid
    components.css          Sidebar, topbar, cards, command palette, scantron badge, buttons
  js/
    app.js                  Boot sequence: theme → shell → router → service worker
    router.js                Hash router; gates unbuilt modules to the ComingSoon page
    state.js                  Tiny pub/sub for cross-component UI state (not module data)
  services/
    storage.js               kv (localStorage) + db (IndexedDB) — the only place that
                              touches browser storage APIs directly
    theme.js                  Dark/light get/set/toggle, persisted via storage.kv
  components/
    icons.js                  Inline SVG icon set
    Sidebar.js / Topbar.js     App-shell chrome
    CommandPalette.js          Ctrl+K launcher
    Card.js                    metricCard() / moduleCard() renderers
    ScantronBadge.js            The signature bubble-row indicator
    Toasts.js                   Transient notification stack
  data/
    modules.js                  Single source of truth for all 20 modules — nav,
                                 palette, and router all read from this one registry
  pages/
    Dashboard.js                Phase 1 real page: mock metrics (labeled), module grid
    Settings.js                 Phase 1 real page: theme, storage/API info
    ComingSoon.js                Rendered for any module whose `phase` > CURRENT_PHASE
```

## Adding a module (for future phases)

1. Add an entry to `MODULES` in `src/data/modules.js` — it now appears
   in the sidebar, the command palette, and routes correctly.
2. Build `src/pages/<Module>.js` exporting a `render()` (and optional
   `bind(root)` for event wiring, see `Settings.js` for the pattern).
3. Register it in the `PAGES` map in `src/js/router.js` and set its
   `phase` to the current phase in `modules.js` — it flips from
   ComingSoon to live with that one change.
4. Reuse `src/components/Card.js`, `ScantronBadge.js`, and the design
   tokens in `theme.css` rather than introducing new one-off styles.

## Phase roadmap (per the build brief)

- **Phase 1 — done:** architecture, routing, layout, navigation,
  dashboard, theme, storage.
- **Phase 2:** Keyword Explorer, Topic Cluster Builder, Content
  Planner, Daily Mission.
- **Phase 3:** Site Audit, Competitor Analysis, Content/FAQ/Schema
  Generators, Internal Link Builder, the five scoring modules.
- **Phase 4:** AI Assistant, Prompt Library, OpenAI/Claude/Gemini
  wiring, Google Search Console / Analytics, Cloudflare.
- **Phase 5:** Animation polish, accessibility pass, full PWA caching
  strategy, performance tuning.
