Index: chapterx-frontend/src/components/story/ChapterList.tsx
===================================================================
--- chapterx-frontend/src/components/story/ChapterList.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/story/ChapterList.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,85 @@
+import React from 'react'
+import { useNavigate } from 'react-router-dom'
+import { Eye, BookOpen, Lock } from 'lucide-react'
+import { Chapter } from '../../types'
+
+interface ChapterListProps {
+  chapters: Chapter[]
+  storyId: number
+  showEditLinks?: boolean
+  onEdit?: (chapterId: number) => void
+}
+
+function formatDate(str: string) {
+  return new Date(str).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
+}
+
+export const ChapterList: React.FC<ChapterListProps> = ({ chapters, storyId, showEditLinks, onEdit }) => {
+  const navigate = useNavigate()
+  const sorted = [...chapters].sort((a, b) => a.chapter_number - b.chapter_number)
+
+  if (sorted.length === 0) {
+    return (
+      <div className="flex flex-col items-center py-10 text-slate-500">
+        <BookOpen size={36} className="mb-3 opacity-40" />
+        <p>No chapters yet.</p>
+      </div>
+    )
+  }
+
+  return (
+    <div className="space-y-2">
+      {sorted.map(chapter => (
+        <div
+          key={chapter.chapter_id}
+          className={`flex items-center gap-4 p-4 rounded-xl bg-slate-800 border border-slate-700 transition-all ${
+            chapter.is_published
+              ? 'hover:border-indigo-500/40 hover:bg-slate-700/50 cursor-pointer'
+              : 'opacity-60'
+          }`}
+          onClick={() => {
+            if (chapter.is_published) navigate(`/story/${storyId}/chapter/${chapter.chapter_id}`)
+          }}
+        >
+          {/* Number */}
+          <div className="w-10 h-10 rounded-lg bg-slate-700 flex items-center justify-center text-indigo-400 font-semibold text-sm flex-shrink-0">
+            {chapter.chapter_number}
+          </div>
+
+          {/* Info */}
+          <div className="flex-1 min-w-0">
+            <div className="flex items-center gap-2">
+              <h4 className="text-white text-sm font-medium truncate">{chapter.title}</h4>
+              {!chapter.is_published && (
+                <span className="flex items-center gap-1 text-amber-400 text-xs">
+                  <Lock size={11} />
+                  Draft
+                </span>
+              )}
+            </div>
+            <div className="flex items-center gap-3 text-slate-500 text-xs mt-0.5">
+              <span>{chapter.word_count.toLocaleString()} words</span>
+              <span>{formatDate(chapter.created_at)}</span>
+            </div>
+          </div>
+
+          {/* Views */}
+          <div className="flex items-center gap-1 text-slate-500 text-xs flex-shrink-0">
+            <Eye size={12} />
+            {chapter.view_count.toLocaleString()}
+          </div>
+
+          {/* Edit button */}
+          {showEditLinks && onEdit && (
+            <button
+              onClick={(e) => { e.stopPropagation(); onEdit(chapter.chapter_id) }}
+              className="text-indigo-400 hover:text-indigo-300 text-xs px-2 py-1 rounded bg-indigo-500/10 hover:bg-indigo-500/20 transition-colors flex-shrink-0"
+            >
+              Edit
+            </button>
+          )}
+        </div>
+      ))}
+    </div>
+  )
+}
Index: chapterx-frontend/src/components/story/CommentSection.tsx
===================================================================
--- chapterx-frontend/src/components/story/CommentSection.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/story/CommentSection.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,148 @@
+import React, { useState } from 'react'
+import { MessageCircle, Trash2, Send } from 'lucide-react'
+import { useAuthStore } from '../../store/authStore'
+import { useStoryStore } from '../../store/storyStore'
+import { useNotificationStore } from '../../store/notificationStore'
+import { useUIStore } from '../../store/uiStore'
+import { Comment } from '../../types'
+import { Avatar } from '../ui/Avatar'
+import { Button } from '../ui/Button'
+
+interface CommentSectionProps {
+  storyId: number
+  authorUserId: number
+}
+
+function timeAgo(str: string): string {
+  const diff = Date.now() - new Date(str).getTime()
+  const m = Math.floor(diff / 60000)
+  if (m < 1) return 'just now'
+  if (m < 60) return `${m}m ago`
+  const h = Math.floor(m / 60)
+  if (h < 24) return `${h}h ago`
+  return `${Math.floor(h / 24)}d ago`
+}
+
+export const CommentSection: React.FC<CommentSectionProps> = ({ storyId, authorUserId }) => {
+  const { currentUser } = useAuthStore()
+  const { comments, addComment, deleteComment } = useStoryStore()
+  const { addNotification } = useNotificationStore()
+  const { addToast } = useUIStore()
+  const [text, setText] = useState('')
+  const [submitting, setSubmitting] = useState(false)
+
+  const storyComments = comments
+    .filter(c => c.story_id === storyId)
+    .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())
+
+  const handleSubmit = async () => {
+    if (!text.trim() || !currentUser) return
+    setSubmitting(true)
+    await new Promise(r => setTimeout(r, 300))
+    const comment: Comment = {
+      comment_id: Date.now(),
+      story_id: storyId,
+      user_id: currentUser.user_id,
+      username: currentUser.username,
+      content: text.trim(),
+      created_at: new Date().toISOString(),
+    }
+    addComment(comment)
+    if (currentUser.user_id !== authorUserId) {
+      addNotification({
+        user_id: authorUserId,
+        type: 'comment',
+        title: 'New Comment',
+        message: `${currentUser.username} commented: "${text.trim().slice(0, 60)}..."`,
+        link: `/story/${storyId}`,
+      })
+    }
+    setText('')
+    setSubmitting(false)
+    addToast('Comment posted!')
+  }
+
+  return (
+    <div className="space-y-4">
+      <div className="flex items-center gap-2 mb-4">
+        <MessageCircle size={18} className="text-indigo-400" />
+        <h3 className="text-white font-semibold">Comments ({storyComments.length})</h3>
+      </div>
+
+      {/* Input */}
+      {currentUser ? (
+        <div className="flex gap-3">
+          <Avatar name={currentUser.name} size="sm" />
+          <div className="flex-1">
+            <textarea
+              value={text}
+              onChange={e => setText(e.target.value)}
+              placeholder="Share your thoughts..."
+              rows={3}
+              className="w-full bg-slate-800 border border-slate-700 rounded-xl px-4 py-3 text-sm text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500 resize-none"
+            />
+            <div className="flex justify-end mt-2">
+              <Button
+                size="sm"
+                onClick={handleSubmit}
+                loading={submitting}
+                disabled={!text.trim()}
+              >
+                <Send size={14} />
+                Post Comment
+              </Button>
+            </div>
+          </div>
+        </div>
+      ) : (
+        <div className="bg-slate-800 border border-slate-700 rounded-xl p-4 text-center">
+          <p className="text-slate-400 text-sm">
+            <a href="/login" className="text-indigo-400 hover:text-indigo-300">Sign in</a> to leave a comment.
+          </p>
+        </div>
+      )}
+
+      {/* Comment list */}
+      <div className="space-y-3">
+        {storyComments.length === 0 ? (
+          <div className="text-center py-8 text-slate-500 text-sm">
+            No comments yet. Be the first to share your thoughts!
+          </div>
+        ) : (
+          storyComments.map(comment => (
+            <CommentCard
+              key={comment.comment_id}
+              comment={comment}
+              canDelete={currentUser?.user_id === comment.user_id || currentUser?.role === 'admin'}
+              onDelete={() => { deleteComment(comment.comment_id); addToast('Comment deleted', 'info') }}
+            />
+          ))
+        )}
+      </div>
+    </div>
+  )
+}
+
+const CommentCard: React.FC<{
+  comment: Comment
+  canDelete: boolean
+  onDelete: () => void
+}> = ({ comment, canDelete, onDelete }) => (
+  <div className="flex gap-3 p-4 bg-slate-800 rounded-xl border border-slate-700">
+    <Avatar name={comment.username} size="sm" />
+    <div className="flex-1 min-w-0">
+      <div className="flex items-center justify-between">
+        <span className="text-sm font-medium text-white">{comment.username}</span>
+        <div className="flex items-center gap-2">
+          <span className="text-xs text-slate-500">{timeAgo(comment.created_at)}</span>
+          {canDelete && (
+            <button onClick={onDelete} className="text-slate-500 hover:text-rose-400 transition-colors">
+              <Trash2 size={13} />
+            </button>
+          )}
+        </div>
+      </div>
+      <p className="text-slate-300 text-sm mt-1 leading-relaxed">{comment.content}</p>
+    </div>
+  </div>
+)
Index: chapterx-frontend/src/components/story/GenreBadge.tsx
===================================================================
--- chapterx-frontend/src/components/story/GenreBadge.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/story/GenreBadge.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,27 @@
+import React from 'react'
+import { GenreBadge as GenreBadgeUI } from '../ui/Badge'
+
+interface GenreBadgeProps {
+  genre: string
+  onClick?: () => void
+}
+
+export const GenreBadge: React.FC<GenreBadgeProps> = ({ genre, onClick }) => (
+  <GenreBadgeUI genre={genre} onClick={onClick} />
+)
+
+export function getGenreGradient(genre: string): string {
+  const gradients: Record<string, string> = {
+    Fantasy: 'from-purple-900 via-indigo-900 to-indigo-800',
+    'Sci-Fi': 'from-cyan-900 via-blue-900 to-blue-800',
+    Romance: 'from-pink-900 via-rose-900 to-rose-800',
+    'Historical Fiction': 'from-amber-900 via-orange-900 to-orange-800',
+    Adventure: 'from-green-900 via-emerald-900 to-emerald-800',
+    Thriller: 'from-gray-900 via-slate-800 to-slate-700',
+    Mystery: 'from-violet-900 via-purple-900 to-purple-800',
+    Horror: 'from-red-900 via-rose-900 to-slate-900',
+    Contemporary: 'from-blue-900 via-indigo-900 to-slate-800',
+    Poetry: 'from-rose-900 via-pink-900 to-pink-800',
+  }
+  return gradients[genre] || 'from-indigo-900 via-violet-900 to-violet-800'
+}
Index: chapterx-frontend/src/components/story/LikeButton.tsx
===================================================================
--- chapterx-frontend/src/components/story/LikeButton.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/story/LikeButton.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,56 @@
+import React from 'react'
+import { Heart } from 'lucide-react'
+import { useNavigate } from 'react-router-dom'
+import { useAuthStore } from '../../store/authStore'
+import { useStoryStore } from '../../store/storyStore'
+import { useNotificationStore } from '../../store/notificationStore'
+import { useUIStore } from '../../store/uiStore'
+
+interface LikeButtonProps {
+  storyId: number
+  authorUserId: number
+  totalLikes: number
+}
+
+export const LikeButton: React.FC<LikeButtonProps> = ({ storyId, authorUserId, totalLikes }) => {
+  const navigate = useNavigate()
+  const { currentUser } = useAuthStore()
+  const { toggleLike, isLiked } = useStoryStore()
+  const { addNotification } = useNotificationStore()
+  const { addToast } = useUIStore()
+
+  const liked = currentUser ? isLiked(currentUser.user_id, storyId) : false
+
+  const handleClick = () => {
+    if (!currentUser) {
+      addToast('Please sign in to like stories.', 'info')
+      navigate('/login')
+      return
+    }
+    toggleLike(currentUser.user_id, storyId)
+    if (!liked && currentUser.user_id !== authorUserId) {
+      addNotification({
+        user_id: authorUserId,
+        type: 'like',
+        title: 'New Like',
+        message: `${currentUser.username} liked your story.`,
+        link: `/story/${storyId}`,
+      })
+    }
+    addToast(liked ? 'Removed from likes' : 'Added to likes!', liked ? 'info' : 'success')
+  }
+
+  return (
+    <button
+      onClick={handleClick}
+      className={`flex items-center gap-2 px-4 py-2 rounded-xl border transition-all duration-200 ${
+        liked
+          ? 'bg-rose-500/20 border-rose-500/40 text-rose-400 hover:bg-rose-500/30'
+          : 'bg-slate-800 border-slate-700 text-slate-400 hover:border-rose-500/40 hover:text-rose-400 hover:bg-rose-500/10'
+      }`}
+    >
+      <Heart size={16} className={liked ? 'fill-rose-400' : ''} />
+      <span className="text-sm font-medium">{totalLikes.toLocaleString()}</span>
+    </button>
+  )
+}
Index: chapterx-frontend/src/components/story/StoryGrid.tsx
===================================================================
--- chapterx-frontend/src/components/story/StoryGrid.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
+++ chapterx-frontend/src/components/story/StoryGrid.tsx	(revision b62cefc14094ca5ac7154f7d48797a1e6c444935)
@@ -0,0 +1,69 @@
+import React, { useState, useEffect } from 'react'
+import { Story } from '../../types'
+import { StoryCard } from '../ui/StoryCard'
+import { BookOpen } from 'lucide-react'
+
+interface StoryGridProps {
+  stories: Story[]
+  showStatus?: boolean
+  emptyMessage?: string
+  loading?: boolean
+}
+
+const SkeletonCard = () => (
+  <div className="rounded-xl overflow-hidden bg-slate-800 border border-slate-700 animate-pulse">
+    <div className="h-40 bg-slate-700" />
+    <div className="p-4 space-y-2">
+      <div className="h-4 bg-slate-700 rounded w-3/4" />
+      <div className="h-3 bg-slate-700 rounded w-1/3" />
+      <div className="h-3 bg-slate-700 rounded w-full" />
+      <div className="h-3 bg-slate-700 rounded w-5/6" />
+      <div className="flex gap-2 mt-2">
+        <div className="h-5 bg-slate-700 rounded-full w-16" />
+        <div className="h-5 bg-slate-700 rounded-full w-16" />
+      </div>
+    </div>
+  </div>
+)
+
+export const StoryGrid: React.FC<StoryGridProps> = ({
+  stories,
+  showStatus = false,
+  emptyMessage = 'No stories found.',
+  loading: externalLoading,
+}) => {
+  const [loading, setLoading] = useState(true)
+
+  useEffect(() => {
+    const timer = setTimeout(() => setLoading(false), 800)
+    return () => clearTimeout(timer)
+  }, [])
+
+  const isLoading = externalLoading !== undefined ? externalLoading : loading
+
+  if (isLoading) {
+    return (
+      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
+        {Array.from({ length: 3 }).map((_, i) => <SkeletonCard key={i} />)}
+      </div>
+    )
+  }
+
+  if (stories.length === 0) {
+    return (
+      <div className="flex flex-col items-center justify-center py-20 text-slate-500">
+        <BookOpen size={48} className="mb-4 opacity-40" />
+        <p className="text-lg font-medium">{emptyMessage}</p>
+        <p className="text-sm mt-1">Try adjusting your search or filters.</p>
+      </div>
+    )
+  }
+
+  return (
+    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
+      {stories.map(story => (
+        <StoryCard key={story.story_id} story={story} showStatus={showStatus} />
+      ))}
+    </div>
+  )
+}
