# Cronicas de los Reinos - Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Build a digital book-style website that preserves MMORPG lore as narrative chapters, with a bookshelf UI and e-reader experience.

**Architecture:** Next.js App Router with static generation. Content stored as MDX files per game/chapter. Three page types: bookshelf (home), book cover (game index), chapter reader. All pages statically generated at build time.

**Tech Stack:** Next.js 14+, TypeScript, Tailwind CSS, MDX (via next-mdx-remote or @next/mdx), Google Fonts (Playfair Display for headings, Lora for body text).

---

### Task 1: Project Scaffolding

**Files:**
- Create: `package.json`, `tsconfig.json`, `tailwind.config.ts`, `next.config.ts`, `src/app/layout.tsx`, `src/app/page.tsx`, `src/app/globals.css`

**Step 1: Initialize Next.js project**

Run:
```bash
npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm
```

Expected: Project scaffolded with all config files.

**Step 2: Install MDX dependencies**

Run:
```bash
npm install next-mdx-remote gray-matter
```

Expected: Dependencies added to package.json.

**Step 3: Add Google Fonts to layout**

Modify `src/app/layout.tsx`:
```tsx
import type { Metadata } from "next";
import { Playfair_Display, Lora } from "next/font/google";
import "./globals.css";

const playfair = Playfair_Display({
  subsets: ["latin"],
  variable: "--font-playfair",
});

const lora = Lora({
  subsets: ["latin"],
  variable: "--font-lora",
});

export const metadata: Metadata = {
  title: "Cronicas de los Reinos",
  description: "Las historias completas de los MMORPGs que marcaron una era",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="es" className={`${playfair.variable} ${lora.variable}`}>
      <body className="bg-stone-900 text-stone-100 font-lora antialiased">
        {children}
      </body>
    </html>
  );
}
```

**Step 4: Configure Tailwind with custom fonts**

Modify `tailwind.config.ts`:
```ts
import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      fontFamily: {
        playfair: ["var(--font-playfair)", "serif"],
        lora: ["var(--font-lora)", "serif"],
      },
      colors: {
        parchment: "#f5f0e8",
        "parchment-dark": "#e8dfd3",
        "wood-dark": "#2c1810",
        "wood-medium": "#4a2c1a",
        "wood-light": "#6b3d2e",
      },
    },
  },
  plugins: [],
};
export default config;
```

**Step 5: Set base global styles**

Replace `src/app/globals.css`:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  ::selection {
    background-color: rgba(180, 140, 80, 0.3);
  }
}
```

**Step 6: Verify dev server starts**

Run: `npm run dev`
Expected: Server starts at localhost:3000, shows default page.

**Step 7: Commit**

```bash
git add -A
git commit -m "feat: scaffold Next.js project with Tailwind, MDX deps, and custom fonts"
```

---

### Task 2: Content System (MDX + meta.json)

**Files:**
- Create: `content/wow/meta.json`, `content/ragnarok/meta.json`, `content/maplestory/meta.json`, `content/tales-of-pirates/meta.json`
- Create: `src/lib/content.ts`
- Create: `src/types/index.ts`

**Step 1: Create type definitions**

Create `src/types/index.ts`:
```ts
export interface GameMeta {
  slug: string;
  title: string;
  subtitle: string;
  description: string;
  color: string;
  colorDark: string;
  accentColor: string;
  coverImage?: string;
}

export interface Chapter {
  slug: string;
  number: number;
  title: string;
  content: string;
}

export interface GameWithChapters extends GameMeta {
  chapters: Omit<Chapter, "content">[];
}
```

**Step 2: Create meta.json files for each game**

Create `content/wow/meta.json`:
```json
{
  "title": "World of Warcraft",
  "subtitle": "Cronicas de Azeroth",
  "description": "Desde la creacion del universo por los Titanes hasta las guerras que definieron el destino de Azeroth, esta es la historia epica del mundo mas grande jamas creado en un MMORPG.",
  "color": "#1a3a5c",
  "colorDark": "#0f2440",
  "accentColor": "#d4a843"
}
```

Create `content/ragnarok/meta.json`:
```json
{
  "title": "Ragnarok Online",
  "subtitle": "La Saga de Midgard",
  "description": "En un mundo donde dioses y mortales coexisten, la tierra de Midgard se enfrenta a amenazas que podrian desatar el Ragnarok, el fin de todas las cosas.",
  "color": "#8b2500",
  "colorDark": "#5c1a00",
  "accentColor": "#ff8c42"
}
```

Create `content/maplestory/meta.json`:
```json
{
  "title": "MapleStory",
  "subtitle": "El Mundo del Arce",
  "description": "Bajo la sombra del Arbol del Mundo, heroes de todas las eras se alzan contra la oscuridad del Mago Negro en un mundo vibrante lleno de aventura y misterio.",
  "color": "#2d5a1e",
  "colorDark": "#1a3a12",
  "accentColor": "#ff9b2e"
}
```

Create `content/tales-of-pirates/meta.json`:
```json
{
  "title": "Tales of Pirates",
  "subtitle": "Leyendas del Mar",
  "description": "En un mundo de islas infinitas y mares inexplorados, piratas, aventureros y cazadores de tesoros escriben su legenda en las aguas del destino.",
  "color": "#1a3050",
  "colorDark": "#0f1e35",
  "accentColor": "#d4a843"
}
```

**Step 3: Create content library**

Create `src/lib/content.ts`:
```ts
import fs from "fs";
import path from "path";
import matter from "gray-matter";
import { GameMeta, Chapter, GameWithChapters } from "@/types";

const contentDir = path.join(process.cwd(), "content");

export function getAllGames(): GameMeta[] {
  const gameDirs = fs.readdirSync(contentDir).filter((dir) => {
    const fullPath = path.join(contentDir, dir);
    return fs.statSync(fullPath).isDirectory();
  });

  return gameDirs.map((slug) => {
    const metaPath = path.join(contentDir, slug, "meta.json");
    const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
    return { slug, ...meta };
  });
}

export function getGame(slug: string): GameWithChapters {
  const metaPath = path.join(contentDir, slug, "meta.json");
  const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));

  const gameDir = path.join(contentDir, slug);
  const chapterFiles = fs
    .readdirSync(gameDir)
    .filter((f) => f.endsWith(".mdx"))
    .sort();

  const chapters = chapterFiles.map((file, index) => {
    const filePath = path.join(gameDir, file);
    const raw = fs.readFileSync(filePath, "utf-8");
    const { data } = matter(raw);
    const chapterSlug = file.replace(".mdx", "");

    return {
      slug: chapterSlug,
      number: index + 1,
      title: (data.title as string) || chapterSlug,
    };
  });

  return { slug, ...meta, chapters };
}

export function getChapter(gameSlug: string, chapterSlug: string): Chapter {
  const gameDir = path.join(contentDir, gameSlug);
  const chapterFiles = fs
    .readdirSync(gameDir)
    .filter((f) => f.endsWith(".mdx"))
    .sort();

  const chapterIndex = chapterFiles.findIndex(
    (f) => f.replace(".mdx", "") === chapterSlug
  );
  const filePath = path.join(gameDir, `${chapterSlug}.mdx`);
  const raw = fs.readFileSync(filePath, "utf-8");
  const { data, content } = matter(raw);

  return {
    slug: chapterSlug,
    number: chapterIndex + 1,
    title: (data.title as string) || chapterSlug,
    content,
  };
}

export function getAdjacentChapters(
  gameSlug: string,
  chapterSlug: string
): { prev: string | null; next: string | null } {
  const gameDir = path.join(contentDir, gameSlug);
  const chapterFiles = fs
    .readdirSync(gameDir)
    .filter((f) => f.endsWith(".mdx"))
    .sort();

  const currentIndex = chapterFiles.findIndex(
    (f) => f.replace(".mdx", "") === chapterSlug
  );

  return {
    prev:
      currentIndex > 0
        ? chapterFiles[currentIndex - 1].replace(".mdx", "")
        : null,
    next:
      currentIndex < chapterFiles.length - 1
        ? chapterFiles[currentIndex + 1].replace(".mdx", "")
        : null,
  };
}
```

**Step 4: Verify types compile**

Run: `npx tsc --noEmit`
Expected: No type errors.

**Step 5: Commit**

```bash
git add -A
git commit -m "feat: add content system with MDX support, types, and meta files for 4 games"
```

---

### Task 3: Bookshelf Page (Home)

**Files:**
- Create: `src/components/BookShelf.tsx`
- Create: `src/components/BookSpine.tsx`
- Modify: `src/app/page.tsx`

**Step 1: Create BookSpine component**

Create `src/components/BookSpine.tsx`:
```tsx
import Link from "next/link";
import { GameMeta } from "@/types";

export default function BookSpine({ game }: { game: GameMeta }) {
  return (
    <Link href={`/${game.slug}`} className="group block">
      <div
        className="relative w-44 h-64 md:w-48 md:h-72 rounded-r-md shadow-lg cursor-pointer transition-all duration-300 group-hover:-translate-y-3 group-hover:rotate-[-2deg] group-hover:shadow-2xl"
        style={{
          background: `linear-gradient(135deg, ${game.color} 0%, ${game.colorDark} 100%)`,
        }}
      >
        {/* Book spine edge */}
        <div
          className="absolute left-0 top-0 bottom-0 w-3 rounded-l-sm"
          style={{ backgroundColor: game.colorDark }}
        />

        {/* Book cover content */}
        <div className="flex flex-col items-center justify-center h-full px-4 text-center">
          <div
            className="w-12 h-0.5 mb-3"
            style={{ backgroundColor: game.accentColor }}
          />
          <h2
            className="font-playfair text-lg md:text-xl font-bold leading-tight text-white"
          >
            {game.title}
          </h2>
          <p
            className="text-xs mt-2 opacity-75 font-lora italic"
            style={{ color: game.accentColor }}
          >
            {game.subtitle}
          </p>
          <div
            className="w-12 h-0.5 mt-3"
            style={{ backgroundColor: game.accentColor }}
          />
        </div>

        {/* Shine effect on hover */}
        <div className="absolute inset-0 bg-gradient-to-r from-white/0 via-white/10 to-white/0 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-r-md" />
      </div>
    </Link>
  );
}
```

**Step 2: Create BookShelf component**

Create `src/components/BookShelf.tsx`:
```tsx
import { GameMeta } from "@/types";
import BookSpine from "./BookSpine";

export default function BookShelf({ games }: { games: GameMeta[] }) {
  return (
    <div className="min-h-screen flex flex-col items-center justify-center px-4 py-16">
      {/* Title */}
      <div className="text-center mb-16">
        <h1 className="font-playfair text-4xl md:text-6xl font-bold text-parchment mb-4">
          Cronicas de los Reinos
        </h1>
        <p className="font-lora text-stone-400 text-lg italic max-w-lg mx-auto">
          Las historias epicas de los mundos que nos unieron
        </p>
        <div className="w-32 h-0.5 bg-amber-700/50 mx-auto mt-6" />
      </div>

      {/* Shelf */}
      <div className="relative">
        {/* Books row */}
        <div className="flex gap-6 md:gap-8 items-end justify-center flex-wrap px-8 pb-4">
          {games.map((game) => (
            <BookSpine key={game.slug} game={game} />
          ))}
        </div>

        {/* Shelf surface */}
        <div className="h-4 bg-gradient-to-b from-wood-medium to-wood-dark rounded-sm shadow-[0_4px_12px_rgba(0,0,0,0.5)]" />
        <div className="h-2 bg-wood-dark/50 rounded-b-sm" />
      </div>

      {/* Footer */}
      <p className="mt-16 text-stone-600 text-sm font-lora">
        Selecciona un tomo para comenzar a leer
      </p>
    </div>
  );
}
```

**Step 3: Wire up the home page**

Replace `src/app/page.tsx`:
```tsx
import { getAllGames } from "@/lib/content";
import BookShelf from "@/components/BookShelf";

export default function Home() {
  const games = getAllGames();
  return <BookShelf games={games} />;
}
```

**Step 4: Verify it renders**

Run: `npm run dev`
Navigate to http://localhost:3000
Expected: See the bookshelf with 4 book spines, hovering tilts them.

**Step 5: Commit**

```bash
git add -A
git commit -m "feat: add bookshelf home page with animated book spine components"
```

---

### Task 4: Game Cover Page (Book Index)

**Files:**
- Create: `src/app/[game]/page.tsx`
- Create: `src/components/BookCover.tsx`

**Step 1: Create BookCover component**

Create `src/components/BookCover.tsx`:
```tsx
import Link from "next/link";
import { GameWithChapters } from "@/types";

export default function BookCover({ game }: { game: GameWithChapters }) {
  return (
    <div className="min-h-screen bg-parchment text-stone-800">
      {/* Back to shelf */}
      <div className="p-4 md:p-6">
        <Link
          href="/"
          className="inline-flex items-center text-stone-500 hover:text-stone-700 font-lora text-sm transition-colors"
        >
          <span className="mr-2">&larr;</span> Volver a la estanteria
        </Link>
      </div>

      {/* Cover */}
      <div className="max-w-2xl mx-auto px-6 py-12 text-center">
        {/* Decorative top */}
        <div
          className="w-24 h-1 mx-auto mb-8 rounded"
          style={{ backgroundColor: game.accentColor }}
        />

        <h1
          className="font-playfair text-4xl md:text-5xl font-bold mb-3"
          style={{ color: game.colorDark }}
        >
          {game.title}
        </h1>

        <p
          className="font-lora italic text-lg mb-8"
          style={{ color: game.color }}
        >
          {game.subtitle}
        </p>

        {/* Decorative divider */}
        <div className="flex items-center justify-center gap-4 mb-8">
          <div className="w-16 h-px bg-stone-300" />
          <div
            className="w-2 h-2 rotate-45"
            style={{ backgroundColor: game.accentColor }}
          />
          <div className="w-16 h-px bg-stone-300" />
        </div>

        <p className="font-lora text-stone-600 text-base leading-relaxed max-w-lg mx-auto mb-16">
          {game.description}
        </p>

        {/* Table of Contents */}
        <div className="text-left max-w-md mx-auto">
          <h2 className="font-playfair text-xl font-semibold text-stone-700 mb-6 text-center tracking-wide uppercase">
            Indice
          </h2>

          <div className="space-y-1">
            {game.chapters.map((chapter) => (
              <Link
                key={chapter.slug}
                href={`/${game.slug}/${chapter.slug}`}
                className="flex items-baseline gap-3 py-3 px-2 rounded hover:bg-parchment-dark transition-colors group"
              >
                <span
                  className="font-playfair text-sm font-bold min-w-[2rem]"
                  style={{ color: game.color }}
                >
                  {String(chapter.number).padStart(2, "0")}
                </span>
                <span className="font-lora text-stone-700 group-hover:text-stone-900 flex-1">
                  {chapter.title}
                </span>
                <span className="text-stone-300 group-hover:text-stone-500 text-sm">
                  &rarr;
                </span>
              </Link>
            ))}
          </div>
        </div>

        {/* Decorative bottom */}
        <div
          className="w-24 h-1 mx-auto mt-16 rounded"
          style={{ backgroundColor: game.accentColor }}
        />
      </div>
    </div>
  );
}
```

**Step 2: Create the game page route**

Create `src/app/[game]/page.tsx`:
```tsx
import { notFound } from "next/navigation";
import { getAllGames, getGame } from "@/lib/content";
import BookCover from "@/components/BookCover";

interface PageProps {
  params: Promise<{ game: string }>;
}

export async function generateStaticParams() {
  const games = getAllGames();
  return games.map((game) => ({ game: game.slug }));
}

export async function generateMetadata({ params }: PageProps) {
  const { game: gameSlug } = await params;
  try {
    const game = getGame(gameSlug);
    return {
      title: `${game.title} | Cronicas de los Reinos`,
      description: game.description,
    };
  } catch {
    return { title: "No encontrado" };
  }
}

export default async function GamePage({ params }: PageProps) {
  const { game: gameSlug } = await params;
  try {
    const game = getGame(gameSlug);
    return <BookCover game={game} />;
  } catch {
    notFound();
  }
}
```

**Step 3: Verify route works**

Run: `npm run dev`
Navigate to http://localhost:3000/wow
Expected: See WoW book cover with title, description, and empty chapter index (no MDX files yet).

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: add game cover page with table of contents and dynamic routing"
```

---

### Task 5: Chapter Reader Page

**Files:**
- Create: `src/app/[game]/[chapter]/page.tsx`
- Create: `src/components/ChapterReader.tsx`
- Create: `src/components/ReadingProgress.tsx`

**Step 1: Create ReadingProgress component**

Create `src/components/ReadingProgress.tsx`:
```tsx
"use client";

import { useEffect, useState } from "react";

export default function ReadingProgress({ color }: { color: string }) {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    function handleScroll() {
      const scrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight - window.innerHeight;
      setProgress(docHeight > 0 ? (scrollTop / docHeight) * 100 : 0);
    }

    window.addEventListener("scroll", handleScroll, { passive: true });
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <div className="fixed top-0 left-0 right-0 h-1 z-50 bg-parchment-dark/50">
      <div
        className="h-full transition-[width] duration-150"
        style={{ width: `${progress}%`, backgroundColor: color }}
      />
    </div>
  );
}
```

**Step 2: Create ChapterReader component**

Create `src/components/ChapterReader.tsx`:
```tsx
import Link from "next/link";
import { MDXRemote } from "next-mdx-remote/rsc";
import { GameMeta, Chapter } from "@/types";
import ReadingProgress from "./ReadingProgress";

interface Props {
  game: GameMeta;
  chapter: Chapter;
  totalChapters: number;
  prevChapter: string | null;
  nextChapter: string | null;
}

export default function ChapterReader({
  game,
  chapter,
  totalChapters,
  prevChapter,
  nextChapter,
}: Props) {
  return (
    <div className="min-h-screen bg-parchment text-stone-800">
      <ReadingProgress color={game.accentColor} />

      {/* Header */}
      <header className="max-w-3xl mx-auto px-6 pt-8 pb-4">
        <Link
          href={`/${game.slug}`}
          className="inline-flex items-center text-stone-500 hover:text-stone-700 font-lora text-sm transition-colors"
        >
          <span className="mr-2">&larr;</span> {game.title}
        </Link>
      </header>

      {/* Chapter heading */}
      <div className="max-w-3xl mx-auto px-6 pt-8 pb-12 text-center">
        <p
          className="font-playfair text-sm font-semibold tracking-widest uppercase mb-3"
          style={{ color: game.color }}
        >
          Capitulo {chapter.number} de {totalChapters}
        </p>
        <h1 className="font-playfair text-3xl md:text-4xl font-bold text-stone-800 mb-4">
          {chapter.title}
        </h1>
        <div className="flex items-center justify-center gap-4">
          <div className="w-12 h-px bg-stone-300" />
          <div
            className="w-2 h-2 rotate-45"
            style={{ backgroundColor: game.accentColor }}
          />
          <div className="w-12 h-px bg-stone-300" />
        </div>
      </div>

      {/* Chapter content */}
      <article className="max-w-[700px] mx-auto px-6 pb-20 font-lora text-lg leading-relaxed text-stone-700 prose prose-stone prose-lg prose-headings:font-playfair prose-headings:text-stone-800 prose-p:mb-6 prose-p:indent-8 first:prose-p:indent-0">
        <MDXRemote source={chapter.content} />
      </article>

      {/* Chapter navigation */}
      <nav className="max-w-[700px] mx-auto px-6 pb-16">
        <div className="border-t border-stone-300 pt-8 flex justify-between items-center">
          {prevChapter ? (
            <Link
              href={`/${game.slug}/${prevChapter}`}
              className="font-lora text-sm hover:text-stone-900 transition-colors"
              style={{ color: game.color }}
            >
              &larr; Capitulo anterior
            </Link>
          ) : (
            <span />
          )}
          <Link
            href={`/${game.slug}`}
            className="font-lora text-sm text-stone-400 hover:text-stone-600 transition-colors"
          >
            Indice
          </Link>
          {nextChapter ? (
            <Link
              href={`/${game.slug}/${nextChapter}`}
              className="font-lora text-sm hover:text-stone-900 transition-colors"
              style={{ color: game.color }}
            >
              Siguiente capitulo &rarr;
            </Link>
          ) : (
            <span />
          )}
        </div>
      </nav>
    </div>
  );
}
```

**Step 3: Create the chapter page route**

Create `src/app/[game]/[chapter]/page.tsx`:
```tsx
import { notFound } from "next/navigation";
import { getAllGames, getGame, getChapter, getAdjacentChapters } from "@/lib/content";
import ChapterReader from "@/components/ChapterReader";

interface PageProps {
  params: Promise<{ game: string; chapter: string }>;
}

export async function generateStaticParams() {
  const games = getAllGames();
  const paths: { game: string; chapter: string }[] = [];

  for (const gameMeta of games) {
    const game = getGame(gameMeta.slug);
    for (const chapter of game.chapters) {
      paths.push({ game: gameMeta.slug, chapter: chapter.slug });
    }
  }

  return paths;
}

export async function generateMetadata({ params }: PageProps) {
  const { game: gameSlug, chapter: chapterSlug } = await params;
  try {
    const game = getGame(gameSlug);
    const chapter = getChapter(gameSlug, chapterSlug);
    return {
      title: `${chapter.title} - ${game.title} | Cronicas de los Reinos`,
      description: `Capitulo ${chapter.number} de ${game.title}`,
    };
  } catch {
    return { title: "No encontrado" };
  }
}

export default async function ChapterPage({ params }: PageProps) {
  const { game: gameSlug, chapter: chapterSlug } = await params;
  try {
    const game = getGame(gameSlug);
    const chapter = getChapter(gameSlug, chapterSlug);
    const { prev, next } = getAdjacentChapters(gameSlug, chapterSlug);

    return (
      <ChapterReader
        game={game}
        chapter={chapter}
        totalChapters={game.chapters.length}
        prevChapter={prev}
        nextChapter={next}
      />
    );
  } catch {
    notFound();
  }
}
```

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: add chapter reader with reading progress bar and navigation"
```

---

### Task 6: Content - World of Warcraft (3 chapters)

**Files:**
- Create: `content/wow/01-origenes.mdx`
- Create: `content/wow/02-primera-guerra.mdx`
- Create: `content/wow/03-arthas-y-la-plaga.mdx`

**Step 1: Write WoW Chapter 1 - Origenes**

Create `content/wow/01-origenes.mdx` with frontmatter `title: "Los Origenes de Azeroth"` followed by ~600-800 words of narrative lore covering: the Titans discovering Azeroth, the ordering of the world, the Old Gods imprisoned beneath the surface, the creation of the Dragon Aspects, and the Well of Eternity.

**Step 2: Write WoW Chapter 2 - Primera Guerra**

Create `content/wow/02-primera-guerra.mdx` with frontmatter `title: "La Primera Guerra"` followed by ~600-800 words covering: the Orcs on Draenor, Medivh's corruption, the opening of the Dark Portal, the Orcish Horde invasion of Azeroth, the fall of Stormwind.

**Step 3: Write WoW Chapter 3 - Arthas y la Plaga**

Create `content/wow/03-arthas-y-la-plaga.mdx` with frontmatter `title: "Arthas y la Plaga"` followed by ~600-800 words covering: Prince Arthas Menethil, the plague of undeath at Stratholme, the journey to Northrend, Frostmourne, Arthas becoming the Lich King.

**Step 4: Verify chapters render**

Run: `npm run dev`
Navigate to http://localhost:3000/wow then click Chapter 1.
Expected: Full narrative text renders in e-reader style.

**Step 5: Commit**

```bash
git add -A
git commit -m "feat: add World of Warcraft lore chapters (origins, first war, arthas)"
```

---

### Task 7: Content - Ragnarok Online (3 chapters)

**Files:**
- Create: `content/ragnarok/01-creacion-de-midgard.mdx`
- Create: `content/ragnarok/02-guerra-de-los-dioses.mdx`
- Create: `content/ragnarok/03-heroes-de-rune-midgard.mdx`

**Step 1: Write Ragnarok Chapter 1 - Creacion de Midgard**

Create `content/ragnarok/01-creacion-de-midgard.mdx` with frontmatter `title: "La Creacion de Midgard"` followed by ~600-800 words covering: Odin and the gods, the creation of the world of Midgard, the Norse mythology roots, the Yggdrasil tree, the races of the world.

**Step 2: Write Ragnarok Chapter 2 - Guerra de los Dioses**

Create `content/ragnarok/02-guerra-de-los-dioses.mdx` with frontmatter `title: "La Guerra de los Dioses"` followed by ~600-800 words covering: the conflict between gods, the thousand-year war, Satan Morocc, the seal of the demons, the aftermath.

**Step 3: Write Ragnarok Chapter 3 - Heroes de Rune-Midgard**

Create `content/ragnarok/03-heroes-de-rune-midgard.mdx` with frontmatter `title: "Los Heroes de Rune-Midgard"` followed by ~600-800 words covering: the adventurers' guilds, the classes, the quest to prevent Ragnarok, the monsters and dungeons.

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: add Ragnarok Online lore chapters (midgard, gods war, heroes)"
```

---

### Task 8: Content - MapleStory (3 chapters)

**Files:**
- Create: `content/maplestory/01-mundo-del-arce.mdx`
- Create: `content/maplestory/02-heroes-legendarios.mdx`
- Create: `content/maplestory/03-el-mago-negro.mdx`

**Step 1: Write MapleStory Chapter 1 - Mundo del Arce**

Create `content/maplestory/01-mundo-del-arce.mdx` with frontmatter `title: "El Mundo del Arce"` followed by ~600-800 words covering: Maple World geography (Victoria Island, Ossyria, etc.), the Maple Tree, the peaceful beginnings, the different peoples.

**Step 2: Write MapleStory Chapter 2 - Heroes Legendarios**

Create `content/maplestory/02-heroes-legendarios.mdx` with frontmatter `title: "Los Heroes Legendarios"` followed by ~600-800 words covering: the six heroes (Aran, Mercedes, Phantom, Luminous, Evan, Shade), their battle against the Black Mage, their sacrifice and freezing in time.

**Step 3: Write MapleStory Chapter 3 - El Mago Negro**

Create `content/maplestory/03-el-mago-negro.mdx` with frontmatter `title: "El Mago Negro"` followed by ~600-800 words covering: the origin of the Black Mage, his quest for ultimate power, the corruption, the Commanders of the Black Mage, the return.

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: add MapleStory lore chapters (maple world, heroes, black mage)"
```

---

### Task 9: Content - Tales of Pirates (3 chapters)

**Files:**
- Create: `content/tales-of-pirates/01-el-mar-infinito.mdx`
- Create: `content/tales-of-pirates/02-islas-del-tesoro.mdx`
- Create: `content/tales-of-pirates/03-era-de-los-piratas.mdx`

**Step 1: Write Tales of Pirates Chapter 1 - El Mar Infinito**

Create `content/tales-of-pirates/01-el-mar-infinito.mdx` with frontmatter `title: "El Mar Infinito"` followed by ~600-800 words covering: the vast ocean world, the mysterious origins, the first sailors, the discovery of scattered islands.

**Step 2: Write Tales of Pirates Chapter 2 - Islas del Tesoro**

Create `content/tales-of-pirates/02-islas-del-tesoro.mdx` with frontmatter `title: "Las Islas del Tesoro"` followed by ~600-800 words covering: Argent City, the major islands, the treasures hidden across the seas, the legends of great pirates.

**Step 3: Write Tales of Pirates Chapter 3 - Era de los Piratas**

Create `content/tales-of-pirates/03-era-de-los-piratas.mdx` with frontmatter `title: "La Era de los Piratas"` followed by ~600-800 words covering: the rise of pirate crews, the class system, naval battles, the endless quest for glory.

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: add Tales of Pirates lore chapters (sea, islands, pirate era)"
```

---

### Task 10: Tailwind Typography Plugin + Final Polish

**Files:**
- Modify: `package.json` (add @tailwindcss/typography)
- Modify: `tailwind.config.ts` (add typography plugin)
- Modify: `src/app/globals.css` (prose customizations)

**Step 1: Install typography plugin**

Run:
```bash
npm install @tailwindcss/typography
```

**Step 2: Add plugin to Tailwind config**

Add to `tailwind.config.ts` plugins array:
```ts
plugins: [require("@tailwindcss/typography")],
```

**Step 3: Add custom prose styles for the book feel**

Add to `src/app/globals.css`:
```css
@layer components {
  .prose p:first-of-type::first-letter {
    font-family: var(--font-playfair), serif;
    font-size: 3.5em;
    float: left;
    line-height: 0.8;
    margin-right: 0.1em;
    margin-top: 0.1em;
    color: #44403c;
  }
}
```

**Step 4: Full build test**

Run: `npm run build`
Expected: Build succeeds with all static pages generated.

**Step 5: Run production preview**

Run: `npm run start`
Expected: All pages load correctly.

**Step 6: Commit**

```bash
git add -A
git commit -m "feat: add typography plugin and drop cap styling for book feel"
```

---

### Task 11: Responsive + Mobile Polish

**Files:**
- Modify: `src/components/BookShelf.tsx` (responsive grid)
- Modify: `src/components/BookSpine.tsx` (mobile sizing)
- Modify: `src/components/ChapterReader.tsx` (mobile padding)

**Step 1: Test on mobile viewport**

Open dev tools, test at 375px width.
Note any layout issues.

**Step 2: Fix any responsive issues**

Adjust components as needed: ensure books wrap on small screens, reading text has adequate padding on mobile, navigation is touch-friendly.

**Step 3: Final build verification**

Run: `npm run build && npm run start`
Expected: Clean build, all pages render correctly.

**Step 4: Commit**

```bash
git add -A
git commit -m "feat: responsive polish for mobile and tablet viewports"
```
