Index: chapterx-frontend/src/pages/story/ChapterReadPage.tsx
===================================================================
--- chapterx-frontend/src/pages/story/ChapterReadPage.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/pages/story/ChapterReadPage.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,165 @@
+import React, { useEffect, useState } from 'react'
+import { useParams, useNavigate } from 'react-router-dom'
+import { ArrowLeft, ArrowRight, BookOpen, Eye, ChevronLeft, ChevronRight } from 'lucide-react'
+import { useStoryStore } from '../../store/storyStore'
+import { Button } from '../../components/ui/Button'
+
+export const ChapterReadPage: React.FC = () => {
+  const { storyId, chapterId } = useParams<{ storyId: string; chapterId: string }>()
+  const navigate = useNavigate()
+  const { stories, chapters, incrementViewCount } = useStoryStore()
+  const [scrollProgress, setScrollProgress] = useState(0)
+  const [viewed, setViewed] = useState(false)
+
+  const story = stories.find(s => s.story_id === Number(storyId))
+  const chapter = chapters.find(c => c.chapter_id === Number(chapterId))
+  const storyChapters = chapters
+    .filter(c => c.story_id === Number(storyId) && c.is_published)
+    .sort((a, b) => a.chapter_number - b.chapter_number)
+
+  const currentIndex = storyChapters.findIndex(c => c.chapter_id === Number(chapterId))
+  const prevChapter = currentIndex > 0 ? storyChapters[currentIndex - 1] : null
+  const nextChapter = currentIndex < storyChapters.length - 1 ? storyChapters[currentIndex + 1] : null
+
+  // Track scroll progress
+  useEffect(() => {
+    const handler = () => {
+      const el = document.documentElement
+      const progress = (el.scrollTop / (el.scrollHeight - el.clientHeight)) * 100
+      setScrollProgress(Math.min(100, progress))
+      // Increment view count when 30% read
+      if (progress > 30 && !viewed) {
+        setViewed(true)
+        if (chapter) incrementViewCount(chapter.chapter_id)
+      }
+    }
+    window.addEventListener('scroll', handler)
+    return () => window.removeEventListener('scroll', handler)
+  }, [chapter, viewed, incrementViewCount])
+
+  if (!story || !chapter) {
+    return (
+      <div className="max-w-4xl mx-auto px-4 py-20 text-center">
+        <h2 className="text-2xl text-white mb-4">Chapter not found</h2>
+        <Button onClick={() => navigate('/browse')}>Browse Stories</Button>
+      </div>
+    )
+  }
+
+  return (
+    <div className="min-h-screen">
+      {/* Progress bar */}
+      <div className="fixed top-0 left-0 right-0 z-50 h-1 bg-slate-800">
+        <div
+          className="h-full bg-gradient-to-r from-indigo-500 to-violet-500 transition-all duration-100"
+          style={{ width: `${scrollProgress}%` }}
+        />
+      </div>
+
+      {/* Top nav */}
+      <div className="sticky top-1 z-40 glass border-b border-white/5">
+        <div className="max-w-3xl mx-auto px-4 py-3 flex items-center justify-between">
+          <button
+            onClick={() => navigate(`/story/${story.story_id}`)}
+            className="flex items-center gap-2 text-slate-400 hover:text-white text-sm transition-colors"
+          >
+            <ArrowLeft size={16} />
+            <span className="hidden sm:block">{story.title}</span>
+          </button>
+
+          <div className="text-center">
+            <p className="text-white text-sm font-medium">{chapter.title}</p>
+            <p className="text-slate-500 text-xs">Chapter {chapter.chapter_number}</p>
+          </div>
+
+          <div className="flex items-center gap-1 text-slate-400 text-xs">
+            <Eye size={12} />
+            {scrollProgress.toFixed(0)}%
+          </div>
+        </div>
+      </div>
+
+      {/* Content */}
+      <div className="max-w-3xl mx-auto px-4 py-12">
+        {/* Chapter header */}
+        <div className="text-center mb-12">
+          <p className="text-indigo-400 text-sm font-medium mb-2 uppercase tracking-widest">
+            Chapter {chapter.chapter_number}
+          </p>
+          <h1 className="font-serif text-3xl sm:text-4xl font-bold text-white mb-4">
+            {chapter.title}
+          </h1>
+          <div className="flex items-center justify-center gap-4 text-slate-500 text-sm">
+            <span className="flex items-center gap-1">
+              <BookOpen size={13} />
+              {chapter.word_count.toLocaleString()} words
+            </span>
+            <span className="flex items-center gap-1">
+              <Eye size={13} />
+              {chapter.view_count.toLocaleString()} reads
+            </span>
+          </div>
+          <div className="mt-4 w-16 h-px bg-gradient-to-r from-transparent via-indigo-500 to-transparent mx-auto" />
+        </div>
+
+        {/* Chapter content */}
+        <div className="prose prose-lg prose-invert max-w-none">
+          {chapter.content.split('\n\n').map((para, i) => (
+            <p
+              key={i}
+              className="text-slate-300 leading-relaxed text-lg mb-6 first-letter:text-4xl first-letter:font-serif first-letter:font-bold first-letter:text-white first-letter:float-left first-letter:mr-2 first-letter:mt-1"
+              style={i !== 0 ? { textIndent: '2rem' } : undefined}
+            >
+              {para}
+            </p>
+          ))}
+        </div>
+
+        {/* Chapter navigation */}
+        <div className="mt-16 pt-8 border-t border-slate-700">
+          <div className="flex items-center justify-between gap-4">
+            {prevChapter ? (
+              <button
+                onClick={() => navigate(`/story/${storyId}/chapter/${prevChapter.chapter_id}`)}
+                className="flex items-center gap-2 px-4 py-3 bg-slate-800 border border-slate-700 rounded-xl hover:border-indigo-500/50 transition-all group flex-1 max-w-[45%]"
+              >
+                <ChevronLeft size={18} className="text-slate-400 group-hover:text-indigo-400 flex-shrink-0" />
+                <div className="text-left min-w-0">
+                  <p className="text-xs text-slate-500">Previous</p>
+                  <p className="text-white text-sm truncate">{prevChapter.title}</p>
+                </div>
+              </button>
+            ) : (
+              <div className="flex-1" />
+            )}
+
+            <Button
+              variant="ghost"
+              size="sm"
+              onClick={() => navigate(`/story/${story.story_id}`)}
+            >
+              Contents
+            </Button>
+
+            {nextChapter ? (
+              <button
+                onClick={() => navigate(`/story/${storyId}/chapter/${nextChapter.chapter_id}`)}
+                className="flex items-center gap-2 px-4 py-3 bg-slate-800 border border-slate-700 rounded-xl hover:border-indigo-500/50 transition-all group flex-1 max-w-[45%] justify-end"
+              >
+                <div className="text-right min-w-0">
+                  <p className="text-xs text-slate-500">Next</p>
+                  <p className="text-white text-sm truncate">{nextChapter.title}</p>
+                </div>
+                <ChevronRight size={18} className="text-slate-400 group-hover:text-indigo-400 flex-shrink-0" />
+              </button>
+            ) : (
+              <div className="flex-1 text-center">
+                <p className="text-slate-500 text-sm">End of story</p>
+              </div>
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  )
+}
Index: chapterx-frontend/src/pages/story/StoryDetailPage.tsx
===================================================================
--- chapterx-frontend/src/pages/story/StoryDetailPage.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/pages/story/StoryDetailPage.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,282 @@
+import React, { useState } from 'react'
+import { useParams, useNavigate } from 'react-router-dom'
+import { ArrowLeft, BookOpen, Eye, Users, Calendar, Plus, BookmarkPlus } from 'lucide-react'
+import { useStoryStore } from '../../store/storyStore'
+import { useAuthStore } from '../../store/authStore'
+import { useUIStore } from '../../store/uiStore'
+import { Button } from '../../components/ui/Button'
+import { GenreBadge } from '../../components/ui/Badge'
+import { Avatar } from '../../components/ui/Avatar'
+import { ChapterList } from '../../components/story/ChapterList'
+import { CommentSection } from '../../components/story/CommentSection'
+import { LikeButton } from '../../components/story/LikeButton'
+import { Modal } from '../../components/ui/Modal'
+import { getGenreGradient } from '../../components/story/GenreBadge'
+import { ReadingListItem } from '../../types'
+
+export const StoryDetailPage: React.FC = () => {
+  const { id } = useParams<{ id: string }>()
+  const navigate = useNavigate()
+  const { stories, chapters, collaborations, readingLists, addStoryToList, createReadingList } = useStoryStore()
+  const { currentUser } = useAuthStore()
+  const { addToast } = useUIStore()
+  const [listModalOpen, setListModalOpen] = useState(false)
+  const [newListName, setNewListName] = useState('')
+
+  const story = stories.find(s => s.story_id === Number(id))
+  if (!story) {
+    return (
+      <div className="max-w-4xl mx-auto px-4 py-20 text-center">
+        <h2 className="text-2xl text-white mb-4">Story not found</h2>
+        <Button onClick={() => navigate('/browse')}>Browse Stories</Button>
+      </div>
+    )
+  }
+
+  const storyChapters = chapters.filter(c => c.story_id === story.story_id)
+  const storyCollabs = collaborations.filter(c => c.story_id === story.story_id)
+  const gradient = getGenreGradient(story.genres[0])
+  const myLists = currentUser ? readingLists.filter(l => l.user_id === currentUser.user_id) : []
+
+  const handleAddToList = (listId: number) => {
+    const list = readingLists.find(l => l.list_id === listId)
+    if (!list) return
+    if (list.stories.some(s => s.story_id === story.story_id)) {
+      addToast('Already in this list', 'info')
+      return
+    }
+    const item: ReadingListItem = {
+      item_id: Date.now(),
+      list_id: listId,
+      story_id: story.story_id,
+      story_title: story.title,
+      author_username: story.author_username,
+      added_at: new Date().toISOString(),
+      genres: story.genres,
+    }
+    addStoryToList(listId, item)
+    addToast(`Added to "${list.name}"!`)
+    setListModalOpen(false)
+  }
+
+  const handleCreateList = () => {
+    if (!newListName.trim() || !currentUser) return
+    const newList = {
+      list_id: Date.now(),
+      user_id: currentUser.user_id,
+      username: currentUser.username,
+      name: newListName.trim(),
+      is_public: false,
+      created_at: new Date().toISOString(),
+      stories: [{
+        item_id: Date.now() + 1,
+        list_id: Date.now(),
+        story_id: story.story_id,
+        story_title: story.title,
+        author_username: story.author_username,
+        added_at: new Date().toISOString(),
+        genres: story.genres,
+      }],
+    }
+    createReadingList(newList)
+    addToast(`Created "${newListName}" and added story!`)
+    setNewListName('')
+    setListModalOpen(false)
+  }
+
+  const isOwner = currentUser?.user_id === story.user_id
+
+  return (
+    <div className="max-w-5xl mx-auto px-4 py-8">
+      {/* Back */}
+      <button
+        onClick={() => navigate(-1)}
+        className="flex items-center gap-2 text-slate-400 hover:text-white mb-6 text-sm transition-colors"
+      >
+        <ArrowLeft size={16} />
+        Back
+      </button>
+
+      {/* Hero */}
+      <div className={`relative rounded-2xl overflow-hidden mb-8 bg-gradient-to-br ${gradient}`}>
+        <div className="absolute inset-0 bg-gradient-to-t from-slate-950/90 via-slate-950/30 to-transparent" />
+        <div className="relative p-8 sm:p-12">
+          <div className="flex flex-wrap gap-2 mb-4">
+            {story.genres.map(g => <GenreBadge key={g} genre={g} />)}
+            {story.mature_content && (
+              <span className="px-2 py-0.5 text-xs font-medium rounded-full border bg-rose-500/20 text-rose-400 border-rose-500/30">
+                18+
+              </span>
+            )}
+          </div>
+          <h1 className="font-serif text-3xl sm:text-4xl font-bold text-white mb-3">{story.title}</h1>
+          <p className="text-slate-300 text-lg mb-6 leading-relaxed max-w-2xl">{story.short_description}</p>
+
+          <div className="flex items-center gap-4 flex-wrap">
+            <div className="flex items-center gap-2">
+              <Avatar name={story.author_username} size="sm" />
+              <span className="text-white text-sm font-medium">{story.author_username}</span>
+            </div>
+            <div className="flex items-center gap-1 text-slate-400 text-sm">
+              <Eye size={14} />
+              {story.total_views.toLocaleString()} views
+            </div>
+            <div className="flex items-center gap-1 text-slate-400 text-sm">
+              <BookOpen size={14} />
+              {story.total_chapters} chapters
+            </div>
+            <div className="flex items-center gap-1 text-slate-400 text-sm">
+              <Calendar size={14} />
+              {new Date(story.created_at).toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
+        {/* Main content */}
+        <div className="lg:col-span-2 space-y-8">
+          {/* Action bar */}
+          <div className="flex items-center gap-3 flex-wrap">
+            <LikeButton storyId={story.story_id} authorUserId={story.user_id} totalLikes={story.total_likes} />
+            {currentUser && (
+              <Button variant="secondary" size="sm" onClick={() => setListModalOpen(true)}>
+                <BookmarkPlus size={14} />
+                Save to List
+              </Button>
+            )}
+            {isOwner && (
+              <Button variant="ghost" size="sm" onClick={() => navigate(`/writer/edit-story/${story.story_id}`)}>
+                Edit Story
+              </Button>
+            )}
+          </div>
+
+          {/* Chapters */}
+          <div>
+            <div className="flex items-center justify-between mb-4">
+              <h2 className="font-serif text-xl font-bold text-white">Chapters</h2>
+              {isOwner && (
+                <Button size="sm" onClick={() => navigate(`/writer/create-chapter/${story.story_id}`)}>
+                  <Plus size={14} />
+                  Add Chapter
+                </Button>
+              )}
+            </div>
+            <ChapterList chapters={storyChapters} storyId={story.story_id} />
+          </div>
+
+          {/* Comments */}
+          <div className="border-t border-slate-700 pt-8">
+            <CommentSection storyId={story.story_id} authorUserId={story.user_id} />
+          </div>
+        </div>
+
+        {/* Sidebar */}
+        <div className="space-y-6">
+          {/* Story info */}
+          <div className="bg-slate-800 border border-slate-700 rounded-2xl p-5">
+            <h3 className="text-white font-semibold mb-4">Story Info</h3>
+            <div className="space-y-3 text-sm">
+              <div className="flex justify-between">
+                <span className="text-slate-400">Status</span>
+                <span className="text-white capitalize">{story.status}</span>
+              </div>
+              <div className="flex justify-between">
+                <span className="text-slate-400">Chapters</span>
+                <span className="text-white">{story.total_chapters}</span>
+              </div>
+              <div className="flex justify-between">
+                <span className="text-slate-400">Likes</span>
+                <span className="text-white">{story.total_likes.toLocaleString()}</span>
+              </div>
+              <div className="flex justify-between">
+                <span className="text-slate-400">Views</span>
+                <span className="text-white">{story.total_views.toLocaleString()}</span>
+              </div>
+              <div className="flex justify-between">
+                <span className="text-slate-400">Comments</span>
+                <span className="text-white">{story.total_comments}</span>
+              </div>
+              <div className="flex justify-between">
+                <span className="text-slate-400">Published</span>
+                <span className="text-white">{new Date(story.created_at).toLocaleDateString()}</span>
+              </div>
+            </div>
+          </div>
+
+          {/* Collaborators */}
+          {storyCollabs.length > 0 && (
+            <div className="bg-slate-800 border border-slate-700 rounded-2xl p-5">
+              <div className="flex items-center gap-2 mb-4">
+                <Users size={16} className="text-violet-400" />
+                <h3 className="text-white font-semibold">Collaborators</h3>
+              </div>
+              <div className="space-y-3">
+                {storyCollabs.map(c => (
+                  <div key={c.collab_id} className="flex items-center gap-2">
+                    <Avatar name={c.name} size="sm" />
+                    <div>
+                      <p className="text-white text-sm">@{c.username}</p>
+                      <p className="text-slate-500 text-xs">{c.role}</p>
+                    </div>
+                  </div>
+                ))}
+              </div>
+            </div>
+          )}
+        </div>
+      </div>
+
+      {/* Reading list modal */}
+      <Modal isOpen={listModalOpen} onClose={() => setListModalOpen(false)} title="Save to Reading List">
+        <div className="space-y-3">
+          {myLists.length > 0 ? (
+            <>
+              <p className="text-slate-400 text-sm mb-3">Select a list:</p>
+              {myLists.map(list => (
+                <button
+                  key={list.list_id}
+                  onClick={() => handleAddToList(list.list_id)}
+                  className="w-full flex items-center justify-between p-3 bg-slate-800 rounded-xl border border-slate-700 hover:border-indigo-500/50 transition-colors"
+                >
+                  <span className="text-white text-sm">{list.name}</span>
+                  <span className="text-slate-500 text-xs">{list.stories.length} stories</span>
+                </button>
+              ))}
+              <div className="border-t border-slate-700 pt-3">
+                <p className="text-slate-400 text-sm mb-2">Or create a new list:</p>
+                <div className="flex gap-2">
+                  <input
+                    value={newListName}
+                    onChange={e => setNewListName(e.target.value)}
+                    placeholder="List name..."
+                    className="flex-1 px-3 py-2 bg-slate-800 border border-slate-700 rounded-xl text-white text-sm placeholder-slate-500 focus:outline-none focus:border-indigo-500"
+                  />
+                  <Button size="sm" onClick={handleCreateList} disabled={!newListName.trim()}>
+                    Create
+                  </Button>
+                </div>
+              </div>
+            </>
+          ) : (
+            <div>
+              <p className="text-slate-400 text-sm mb-3">You don't have any reading lists yet. Create one:</p>
+              <div className="flex gap-2">
+                <input
+                  value={newListName}
+                  onChange={e => setNewListName(e.target.value)}
+                  placeholder="My Favorites..."
+                  className="flex-1 px-3 py-2 bg-slate-800 border border-slate-700 rounded-xl text-white text-sm placeholder-slate-500 focus:outline-none focus:border-indigo-500"
+                />
+                <Button size="sm" onClick={handleCreateList} disabled={!newListName.trim()}>
+                  Create
+                </Button>
+              </div>
+            </div>
+          )}
+        </div>
+      </Modal>
+    </div>
+  )
+}
