diff --git a/src/app/[game]/[chapter]/page.tsx b/src/app/[game]/[chapter]/page.tsx
new file mode 100644
index 0000000..3ad1bf1
--- /dev/null
+++ b/src/app/[game]/[chapter]/page.tsx
@@ -0,0 +1,54 @@
+import { notFound } from "next/navigation";
+import { getAllGames, getGame, getChapter, getAdjacentChapters } from "@/lib/content";
+import ChapterReader from "@/components/ChapterReader";
+
+interface PageProps {
+ params: { game: string; chapter: string };
+}
+
+export 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 function generateMetadata({ params }: PageProps) {
+ try {
+ const game = getGame(params.game);
+ const chapter = getChapter(params.game, params.chapter);
+ return {
+ title: `${chapter.title} - ${game.title} | Cronicas de los Reinos`,
+ description: `Capitulo ${chapter.number} de ${game.title}`,
+ };
+ } catch {
+ return { title: "No encontrado" };
+ }
+}
+
+export default function ChapterPage({ params }: PageProps) {
+ try {
+ const game = getGame(params.game);
+ const chapter = getChapter(params.game, params.chapter);
+ const { prev, next } = getAdjacentChapters(params.game, params.chapter);
+
+ return (
+
+ );
+ } catch {
+ notFound();
+ }
+}
diff --git a/src/components/ChapterReader.tsx b/src/components/ChapterReader.tsx
new file mode 100644
index 0000000..fb5fd66
--- /dev/null
+++ b/src/components/ChapterReader.tsx
@@ -0,0 +1,96 @@
+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 (
+
+
+
+ {/* Header */}
+
+
+ {/* Chapter heading */}
+
+
+ Capitulo {chapter.number} de {totalChapters}
+
+
+ {chapter.title}
+
+
+
+
+ {/* Chapter content */}
+
+
+
+
+ {/* Chapter navigation */}
+
+
+ );
+}
diff --git a/src/components/ReadingProgress.tsx b/src/components/ReadingProgress.tsx
new file mode 100644
index 0000000..54c4e01
--- /dev/null
+++ b/src/components/ReadingProgress.tsx
@@ -0,0 +1,27 @@
+"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 (
+
+ );
+}