<script setup>
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from "vue";
import { marked } from "marked";

const docs = ref([]);
const loading = ref(true);
const error = ref(null);
const selected = ref(null);
const searchQuery = ref("");
const showMobileSidebar = ref(false);
const scrollProgress = ref(0);
const currentToc = ref([]);
const showToc = ref(false);
const activeSection = ref(null);

// Initialize marked with custom renderer for better HTML
marked.setOptions({
  breaks: true,
  gfm: true,
  headerIds: true,
});

definePageMeta({
  title: "Documentation",
  layout: "empty",
});

// Configure custom renderer for TOC extraction
const renderer = new marked.Renderer();
const originalHeading = renderer.heading;
const originalLink = renderer.link;
renderer.heading = function (text, level, raw) {
  const safeRaw = String(raw || text || "");
  const id = safeRaw
    .toLowerCase()
    .replace(/[^\w\s-]/g, "")
    .replace(/[\s]+/g, "-");
  return `<h${level} id="${id}" class="scroll-mt-20">${text}</h${level}>`;
};
// Custom link renderer for internal .md links
renderer.link = function (href, title, text) {
  if (href && String(href).endsWith('.md')) {
    const file = String(href).split('/').pop();
    // Use a special class for delegation
    return `<a href="#" class="doc-link" data-doc="${file}">${text}</a>`;
  }
  return originalLink.call(this, href, title, text);
};
marked.setOptions({ renderer });

onMounted(async () => {
  try {
    const files = await $fetch("/api/documentation");
    const docPromises = files.map(async (file) => {
      try {
        const response = await $fetch(`/api/documentation/${file}`);
        let content = response?.content || "";

        if (!content) {
          console.warn(`Empty content for file: ${file}`);
          return null;
        }

        // Enhanced content cleaning to remove any object serialization issues
        content = String(content)
          .replace(/\[object Object\]/g, "")
          .replace(/\[object\s+Object\]/gi, "")
          .replace(/\bobject Object\b/gi, "")
          .replace(/\[Object\]/gi, "")
          .replace(/Object\s*\{[^}]*\}/gi, "")
          .replace(/\{\s*\[native code\]\s*\}/gi, "")
          .replace(/^\s*\[object.*?\]\s*$/gim, "")
          .trim();
        
        let html = marked.parse(content);
        
        // Post-process HTML to remove any remaining object references
        html = html
          .replace(/\[object Object\]/g, "")
          .replace(/\[object\s+Object\]/gi, "")
          .replace(/\bobject Object\b/gi, "")
          .replace(/<p>\s*\[object.*?\]\s*<\/p>/gi, "")
          .replace(/<[^>]*>\s*\[object.*?\]\s*<\/[^>]*>/gi, "");

        // Extract metadata from filename
        const match = file.match(/^(\d+)-(.+)\.md$/);
        const order = match ? parseInt(match[1]) : 999;
        const cleanTitle = (match ? match[2] : file.replace(/\.md$/, ""))
          .replace(/[-_]/g, " ")
          .replace(/\b\w/g, (l) => l.toUpperCase());

        // Extract table of contents
        const tocMatch = content.match(
          /## Table of Contents([\s\S]*?)(?=\n---|\n##[^#]|$)/
        );
        const toc = tocMatch ? extractTocFromContent(tocMatch[1]) : [];

        // Estimate reading time (250 words per minute)
        const wordCount = content
          .split(/\s+/)
          .filter((word) => word.length > 0).length;
        const readingTime = Math.max(1, Math.ceil(wordCount / 250));

        return {
          file,
          title: cleanTitle,
          html,
          content,
          order,
          toc,
          readingTime,
          category: getCategoryFromOrder(order),
        };
      } catch (error) {
        console.error(`Error processing file ${file}:`, error);
        return null;
      }
    });

    docs.value = (await Promise.all(docPromises))
      .filter((doc) => doc !== null)
      .sort((a, b) => a.order - b.order);

    selected.value = docs.value[0]?.file || null;
    updateToc();

    // Add keyboard listeners
    document.addEventListener("keydown", handleKeyNavigation);
  } catch (e) {
    error.value = "Failed to load documentation.";
    console.error("Documentation loading error:", e);
  } finally {
    loading.value = false;
  }
});

onUnmounted(() => {
  document.removeEventListener("keydown", handleKeyNavigation);
});

// Scrollspy for TOC
function handleScrollSpy() {
  const headings = Array.from(document.querySelectorAll('.prose h2, .prose h3'));
  const scrollY = window.scrollY || document.querySelector('.main-content')?.scrollTop || 0;
  let current = null;
  for (const heading of headings) {
    const rect = heading.getBoundingClientRect();
    if (rect.top + window.scrollY - 120 <= scrollY) {
      current = heading.id;
    }
  }
  activeSection.value = current;
}

onMounted(() => {
  document.querySelector('.main-content')?.addEventListener('scroll', handleScrollSpy);
  window.addEventListener('scroll', handleScrollSpy);
});
onUnmounted(() => {
  document.querySelector('.main-content')?.removeEventListener('scroll', handleScrollSpy);
  window.removeEventListener('scroll', handleScrollSpy);
});

// Event delegation for .doc-link clicks
onMounted(() => {
  const handler = (e) => {
    const target = e.target.closest('.doc-link');
    if (target && target.dataset.doc) {
      e.preventDefault();
      e.stopPropagation();
      selectDoc(target.dataset.doc);
    }
  };
  document.addEventListener('click', handler);
  window.__docLinkHandler = handler;
});
onUnmounted(() => {
  if (window.__docLinkHandler) {
    document.removeEventListener('click', window.__docLinkHandler);
    delete window.__docLinkHandler;
  }
});

// Extract TOC from markdown content
function extractTocFromContent(tocContent) {
  if (!tocContent || typeof tocContent !== "string") {
    return [];
  }

  try {
    const lines = tocContent.split("\n").filter((line) => line.trim());
    return lines
      .map((line) => {
        const match = line.match(/^\s*\d+\.\s*\[([^\]]+)\]\(#([^)]+)\)/);
        if (match) {
          return { title: match[1], id: match[2], level: 1 };
        }
        return null;
      })
      .filter(Boolean);
  } catch (error) {
    console.error("Error extracting TOC:", error);
    return [];
  }
}

// Get category based on chapter order
function getCategoryFromOrder(order) {
  if (order <= 1) return "Getting Started";
  if (order <= 3) return "Form Management";
  if (order <= 5) return "Process Management";
  return "Advanced Topics";
}

// Computed properties
const filteredDocs = computed(() => {
  if (!searchQuery.value.trim()) return docs.value;

  const query = searchQuery.value.toLowerCase();
  return docs.value.filter((doc) => {
    if (!doc || !doc.title || !doc.content) return false;
    return (
      doc.title.toLowerCase().includes(query) ||
      doc.content.toLowerCase().includes(query)
    );
  });
});

const selectedDoc = computed(() => {
  return docs.value.find((doc) => doc.file === selected.value);
});

const currentDocIndex = computed(() => {
  return docs.value.findIndex((doc) => doc.file === selected.value);
});

const previousDoc = computed(() => {
  const index = currentDocIndex.value;
  return index > 0 ? docs.value[index - 1] : null;
});

const nextDoc = computed(() => {
  const index = currentDocIndex.value;
  return index < docs.value.length - 1 ? docs.value[index + 1] : null;
});

// Functions
const selectDoc = (file) => {
  selected.value = file;
  showMobileSidebar.value = false;
  scrollProgress.value = 0;
  searchQuery.value = "";
  updateToc();
  scrollToTop();
};

// Keyboard navigation
const handleKeyNavigation = (event) => {
  if (event.ctrlKey || event.metaKey) {
    switch (event.key) {
      case "k":
        event.preventDefault();
        document.querySelector('input[type="text"]')?.focus();
        break;
      case "ArrowLeft":
        if (previousDoc.value) {
          event.preventDefault();
          selectDoc(previousDoc.value.file);
        }
        break;
      case "ArrowRight":
        if (nextDoc.value) {
          event.preventDefault();
          selectDoc(nextDoc.value.file);
        }
        break;
    }
  }

  if (event.key === "Escape") {
    searchQuery.value = "";
    showMobileSidebar.value = false;
  }
};

const updateToc = () => {
  nextTick(() => {
    const headings = document.querySelectorAll(".prose h2, .prose h3");
    currentToc.value = Array.from(headings).map((heading) => ({
      id: heading.id,
      title: heading.textContent,
      level: parseInt(heading.tagName.charAt(1)),
    }));
    showToc.value = currentToc.value.length > 3;
  });
};

const scrollToTop = () => {
  const mainContent = document.querySelector(".main-content");
  if (mainContent) {
    mainContent.scrollTo({ top: 0, behavior: "smooth" });
  }
};

const scrollToSection = (id) => {
  const element = document.getElementById(id);
  if (element) {
    element.scrollIntoView({ behavior: "smooth", block: "start" });
  }
};

// Add copy buttons to code blocks after content is loaded
const addCopyButtons = () => {
  nextTick(() => {
    const codeBlocks = document.querySelectorAll(".prose pre");
    codeBlocks.forEach((block) => {
      // Skip if button already exists
      if (block.querySelector(".copy-button")) return;

      const button = document.createElement("button");
      button.className =
        "copy-button absolute top-2 right-2 px-2 py-1 text-xs bg-gray-700 hover:bg-gray-600 text-white rounded transition-colors";
      button.textContent = "Copy";
      button.onclick = () => {
        const code = block.querySelector("code");
        if (code) {
          navigator.clipboard.writeText(code.textContent).then(() => {
            button.textContent = "Copied!";
            button.classList.add("bg-green-500");
            setTimeout(() => {
              button.textContent = "Copy";
              button.classList.remove("bg-green-500");
            }, 2000);
          });
        }
      };

      block.style.position = "relative";
      block.appendChild(button);
    });
  });
};

// Watch for scroll progress and add copy buttons
watch(selected, () => {
  nextTick(() => {
    const mainContent = document.querySelector(".main-content");
    if (mainContent) {
      const updateProgress = () => {
        const scrollTop = mainContent.scrollTop;
        const scrollHeight =
          mainContent.scrollHeight - mainContent.clientHeight;
        scrollProgress.value =
          scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;
      };

      mainContent.addEventListener("scroll", updateProgress);
      updateProgress();
    }

    // Add copy buttons to code blocks
    addCopyButtons();
  });
});
</script>

<template>
  <div class="flex flex-col h-screen bg-gray-50">
    <!-- Header Bar ---->
    <header class="bg-white border-b border-gray-200 px-6 py-4 flex items-center justify-between shadow-sm">
      <div class="flex items-center gap-4">
        <NuxtLink to="/" class="cursor-pointer">
          <Icon
            name="ph:arrow-circle-left-duotone"
            class="w-6 h-6 hover:text-gray-600 text-gray-500"
          />
        </NuxtLink>
        <div class="flex items-center gap-3">
          <img
            src="@/assets/img/logo/logo-word-black.svg"
            alt="Corrad Logo"
            class="h-8"
          />
          <div class="border-l border-gray-300 pl-3">
            <h1 class="text-xl font-semibold text-gray-900">Documentation</h1>
            <p class="text-sm text-gray-500">System guides and references</p>
          </div>
        </div>
      </div>

      <div class="flex items-center gap-3">
        <!-- Search Bar -->
        <div class="relative">
          <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
            <Icon name="material-symbols:search" class="h-5 w-5 text-gray-400" />
          </div>
          <input
            v-model="searchQuery"
            type="text"
            placeholder="Search documentation... (Ctrl+K)"
            class="pl-10 pr-4 py-2 w-80 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
          />
        </div>
        
        <!-- Mobile menu button -->
        <button
          @click="showMobileSidebar = !showMobileSidebar"
          class="lg:hidden p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
        >
          <Icon name="material-symbols:menu" class="h-6 w-6" />
        </button>
      </div>
    </header>

    <!-- Main Content Area -->
    <div class="flex-1 overflow-auto">
      <div class="p-6">
        <div class="flex gap-6">
          <!-- Sidebar -->
          <aside
            class="w-80 flex-shrink-0 sticky top-6 h-fit"
            :class="showMobileSidebar ? 'block' : 'hidden lg:block'"
          >
            <div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
              <h2 class="text-lg font-semibold text-gray-900 mb-6">Contents</h2>

              <!-- Category Filter -->
              <div class="space-y-1" v-if="!searchQuery">
                <div
                  v-for="category in [
                    'Getting Started',
                    'Form Management',
                    'Process Management',
                    'Advanced Topics',
                  ]"
                  :key="category"
                  class="mb-6"
                >
                  <h3 class="text-xs font-medium text-gray-500 uppercase tracking-wide mb-3">
                    {{ category }}
                  </h3>
                  <div class="space-y-1">
                    <button
                      v-for="doc in docs.filter((d) => d.category === category && d.order !== 999)"
                      :key="doc.file"
                      @click="selectDoc(doc.file)"
                      class="w-full text-left px-3 py-2 rounded-lg text-sm transition-colors group"
                      :class="
                        selected === doc.file
                          ? 'bg-blue-50 text-blue-700 font-medium border border-blue-200'
                          : 'text-gray-700 hover:bg-gray-50 hover:text-gray-900'
                      "
                    >
                      <div class="flex items-center justify-between">
                        <div class="flex items-center space-x-3">
                          <span
                            class="flex-shrink-0 w-6 h-6 rounded-full bg-blue-600 text-white text-xs font-bold flex items-center justify-center"
                            >{{ doc.order }}</span
                          >
                          <span>{{ doc.title }}</span>
                        </div>
                        <div class="flex items-center space-x-2 opacity-0 group-hover:opacity-100 transition-opacity">
                          <span class="text-xs text-gray-400">{{ doc.readingTime }} min</span>
                          <Icon
                            v-if="selected === doc.file"
                            name="material-symbols:check-circle"
                            class="w-4 h-4 text-blue-500"
                          />
                        </div>
                      </div>
                    </button>
                  </div>
                </div>
              </div>

              <!-- Search Results -->
              <div v-else class="space-y-1">
                <div
                  v-if="filteredDocs.filter((doc) => doc.order !== 999).length === 0"
                  class="text-sm text-gray-500 text-center py-4"
                >
                  No results found for "{{ searchQuery }}"
                </div>
                <button
                  v-for="doc in filteredDocs.filter((doc) => doc.order !== 999)"
                  :key="doc.file"
                  @click="selectDoc(doc.file)"
                  class="w-full text-left px-3 py-2 rounded-lg text-sm transition-colors"
                  :class="
                    selected === doc.file
                      ? 'bg-blue-50 text-blue-700 font-medium'
                      : 'text-gray-700 hover:bg-gray-50'
                  "
                >
                  <div class="flex items-center justify-between">
                    <span>{{ doc.title }}</span>
                    <span class="text-xs text-gray-400">{{ doc.readingTime }} min</span>
                  </div>
                </button>
              </div>
            </div>
          </aside>

          <!-- Main Content -->
          <main class="flex-1 min-w-0">
            <div class="flex gap-6">
              <!-- Document Content -->
              <div class="flex-1">
                <div class="bg-white rounded-xl shadow-sm border border-gray-200">
                  <!-- Loading State -->
                  <div v-if="loading" class="p-12 text-center">
                    <Icon name="material-symbols:progress-activity" class="w-8 h-8 animate-spin text-blue-500 mx-auto mb-4" />
                    <p class="text-gray-500">Loading documentation...</p>
                  </div>

                  <!-- Error State -->
                  <div v-else-if="error" class="p-12 text-center">
                    <Icon name="material-symbols:error-outline" class="w-16 h-16 text-red-300 mx-auto mb-4" />
                    <div class="text-red-500 text-lg font-medium mb-2">{{ error }}</div>
                    <p class="text-gray-500">Please try refreshing the page</p>
                  </div>

                  <!-- Document Content -->
                  <div v-else-if="selectedDoc">
                    <!-- Document Header -->
                    <div class="px-8 py-4 border-b border-gray-200 bg-gray-50">
                      <div class="flex items-center justify-between my-4">
                        <div class="flex items-center space-x-4">
                          <span class="w-10 h-10 rounded-full bg-blue-600 text-white text-lg font-bold flex items-center justify-center">
                            {{ selectedDoc.order }}
                          </span>
                          <div>
                            <div class="flex items-center gap-2 mb-2">
                              <RsBadge variant="secondary" size="sm">
                                {{ selectedDoc.category }}
                              </RsBadge>
                            </div>
                            <h1 class="text-2xl font-bold text-gray-900">
                              {{ selectedDoc.title }}
                            </h1>
                          </div>
                        </div>
                        <div class="text-right text-sm text-gray-500">
                          <div class="flex items-center gap-1">
                            <Icon name="material-symbols:schedule" class="w-4 h-4" />
                            <span>{{ selectedDoc.readingTime }} min read</span>
                          </div>
                        </div>
                      </div>
                    </div>

                    <!-- Document Body -->
                    <div class="main-content bg-gradient-to-br from-gray-50 to-white shadow-xl rounded-2xl" style="overflow-y: auto; position:relative;">
                      <div class="relative">
                        <!-- Subtle background pattern -->
                        <div class="absolute inset-0 opacity-10 pointer-events-none">
                          <div class="absolute inset-0" style="background-image: radial-gradient(circle at 1px 1px, #3b82f6 1px, transparent 0); background-size: 32px 32px;"></div>
                        </div>
                        <div class="relative px-8 py-12">
                          <div class="max-w-4xl mx-auto">
                            <!-- Divider after TOC and before first heading -->
                            <div v-if="currentToc.length > 0" class="mb-8">
                              <hr class="border-t-2 border-blue-100 my-6" />
                            </div>
                            <div
                              class="prose prose-lg max-w-none prose-headings:font-semibold prose-headings:tracking-tight prose-headings:scroll-mt-20 prose-h1:text-3xl prose-h1:mt-0 prose-h1:mb-8 prose-h1:text-gray-900 prose-h2:text-xl prose-h2:mt-10 prose-h2:mb-6 prose-h2:text-gray-800 prose-h3:text-lg prose-h3:mt-8 prose-h3:mb-4 prose-h3:text-gray-700 prose-p:mb-6 prose-p:leading-relaxed prose-p:text-gray-600 prose-p:text-base prose-code:bg-blue-50 prose-code:text-blue-700 prose-code:px-2 prose-code:py-1 prose-code:rounded-md prose-code:text-sm prose-code:font-medium prose-code:border prose-code:border-blue-200 prose-pre:bg-slate-900 prose-pre:text-slate-100 prose-pre:rounded-xl prose-pre:p-6 prose-pre:overflow-x-auto prose-pre:my-8 prose-pre:shadow-lg prose-table:rounded-xl prose-table:overflow-hidden prose-table:border-0 prose-table:border-gray-200 prose-table:my-8 prose-table:shadow-sm prose-th:bg-gray-100 prose-th:font-semibold prose-th:p-4 prose-th:text-gray-800 prose-td:p-4 prose-td:border-b prose-td:border-gray-100 prose-a:text-blue-600 prose-a:no-underline prose-a:font-medium hover:prose-a:underline hover:prose-a:text-blue-700 prose-blockquote:border-l-4 prose-blockquote:border-blue-500 prose-blockquote:bg-gradient-to-r prose-blockquote:from-blue-50 prose-blockquote:to-indigo-50 prose-blockquote:p-6 prose-blockquote:rounded-r-xl prose-blockquote:my-8 prose-blockquote:shadow-sm prose-ul:my-6 prose-ul:pl-0 prose-ol:my-6 prose-ol:pl-0 prose-li:my-2 prose-li:leading-relaxed prose-li:text-gray-600 prose-strong:font-semibold prose-strong:text-gray-900"
                              v-html="selectedDoc.html"
                            />
                          </div>
                        </div>
                      </div>
                    </div>

                    <!-- Navigation Footer -->
                    <div class="px-8 py-6 bg-gray-50 border-t border-gray-200 flex justify-between items-center">
                      <RsButton
                        v-if="previousDoc"
                        @click="selectDoc(previousDoc.file)"
                        variant="secondary"
                        size="sm"
                      >
                        <Icon name="material-symbols:chevron-left" class="mr-1" />
                        {{ previousDoc.title }}
                      </RsButton>
                      <div v-else></div>

                      <RsButton
                        v-if="nextDoc"
                        @click="selectDoc(nextDoc.file)"
                        variant="primary"
                        size="sm"
                      >
                        {{ nextDoc.title }}
                        <Icon name="material-symbols:chevron-right" class="ml-1" />
                      </RsButton>
                      <div v-else></div>
                    </div>
                  </div>

                  <!-- Empty State -->
                  <div v-else class="p-12 text-center">
                    <Icon name="material-symbols:description-outline" class="w-16 h-16 text-gray-300 mx-auto mb-4" />
                    <h3 class="text-lg font-medium text-gray-900 mb-2">Select a document</h3>
                    <p class="text-gray-600">Choose a documentation topic from the sidebar to get started</p>
                  </div>
                </div>
              </div>

              <!-- Table of Contents -->
              <aside
                v-if="showToc && currentToc.length > 0"
                class="hidden xl:block w-64 flex-shrink-0 sticky top-24 h-fit"
              >
                <div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6">
                  <h3 class="text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4">
                    On This Page
                  </h3>
                  <nav class="space-y-2">
                    <a
                      v-for="item in currentToc"
                      :key="item.id"
                      @click.prevent="scrollToSection(item.id)"
                      href="#"
                      class="block text-sm text-gray-600 hover:text-blue-600 transition-colors py-1 border-l-2 border-transparent hover:border-blue-500 pl-3"
                      :class="[{'ml-4': item.level === 3}, activeSection === item.id ? 'border-blue-500 text-blue-700 font-semibold bg-blue-50' : '']"
                    >
                      {{ item.title }}
                    </a>
                  </nav>
                </div>
              </aside>
            </div>
          </main>
        </div>
      </div>
    </div>

    <!-- Mobile Sidebar Overlay -->
    <div
      v-if="showMobileSidebar"
      @click="showMobileSidebar = false"
      class="fixed inset-0 bg-black bg-opacity-50 z-40 lg:hidden"
    ></div>
  </div>
</template>

<style scoped>
/* Enhanced prose styling with visual richness */
.prose :where(h1):not(:where([class~="not-prose"] *)) {
  font-size: 2.5rem;
  margin-top: 0;
  margin-bottom: 2.5rem;
  color: #1f2937;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.025em;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.prose :where(h2):not(:where([class~="not-prose"] *)) {
  font-size: 1.75rem;
  margin-top: 3.5rem;
  margin-bottom: 1.5rem;
  color: #1f2937;
  position: relative;
  font-weight: 700;
  line-height: 1.3;
  padding-left: 1.5rem;
  border-left: 4px solid transparent;
  background: linear-gradient(white, white) padding-box, 
              linear-gradient(135deg, #3b82f6, #6366f1) border-box;
  border-left: 4px solid;
  background-clip: padding-box, border-box;
  padding: 0.75rem 0 0.75rem 1.5rem;
  margin-left: -1.5rem;
  border-radius: 0 8px 8px 0;
  background-color: rgba(59, 130, 246, 0.03);
}

.prose :where(h2):not(:where([class~="not-prose"] *))::after {
  content: "";
  position: absolute;
  right: -1.5rem;
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
  border-radius: 50%;
  opacity: 0.6;
}

.prose :where(h3):not(:where([class~="not-prose"] *)) {
  font-size: 1.375rem;
  margin-top: 2.5rem;
  margin-bottom: 1.25rem;
  color: #374151;
  font-weight: 600;
  line-height: 1.4;
  position: relative;
  padding-left: 1rem;
}

.prose :where(h3):not(:where([class~="not-prose"] *))::before {
  content: "▶";
  position: absolute;
  left: 0;
  top: 0;
  color: #3b82f6;
  font-size: 0.75rem;
  transform: rotate(90deg);
  transition: transform 0.2s ease;
}

.prose :where(p):not(:where([class~="not-prose"] *)) {
  margin-bottom: 1.75rem;
  line-height: 1.8;
  color: #4b5563;
  font-size: 1rem;
}

.prose :where(p):not(:where([class~="not-prose"] *)):first-child {
  margin-top: 0;
  font-size: 1.125rem;
  color: #374151;
  font-weight: 500;
}

.prose :where(ul):not(:where([class~="not-prose"] *)),
.prose :where(ol):not(:where([class~="not-prose"] *)) {
  margin: 2rem 0;
  padding-left: 0;
}

.prose :where(li):not(:where([class~="not-prose"] *)) {
  margin: 0.75rem 0;
  line-height: 1.7;
  color: #4b5563;
  position: relative;
  padding-left: 1.5rem;
}

.prose :where(ul li):not(:where([class~="not-prose"] *))::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.75rem;
  width: 6px;
  height: 6px;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
  border-radius: 50%;
  transform: translateY(-50%);
}

.prose :where(strong):not(:where([class~="not-prose"] *)) {
  font-weight: 700;
  color: #1f2937;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* Enhanced visual elements */
.prose :where(em):not(:where([class~="not-prose"] *)) {
  font-style: italic;
  color: #6366f1;
  font-weight: 500;
}

.prose :where(hr):not(:where([class~="not-prose"] *)) {
  border: none;
  height: 2px;
  background: linear-gradient(to right, transparent, #3b82f6, transparent);
  margin: 3rem 0;
  border-radius: 1px;
}

.prose :where(pre):not(:where([class~="not-prose"] *)) {
  background: #0f172a;
  color: #f1f5f9;
  border-radius: 0.75rem;
  padding: 1.5rem;
  border: 1px solid #334155;
  position: relative;
  overflow-x: auto;
}

.prose :where(pre):not(:where([class~="not-prose"] *))::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: #3b82f6;
}

.prose :where(code):not(:where([class~="not-prose"] *)) {
  background: #f1f5f9;
  color: #3b82f6;
  border-radius: 0.375rem;
  padding: 0.2em 0.5em;
  font-weight: 500;
  border: 1px solid #e2e8f0;
}

.prose :where(blockquote):not(:where([class~="not-prose"] *)) {
  border: none;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(99, 102, 241, 0.08));
  margin: 2.5rem 0;
  padding: 2rem;
  border-radius: 1rem;
  position: relative;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  border-left: 4px solid transparent;
  background-clip: padding-box;
  overflow: hidden;
}

.prose :where(blockquote):not(:where([class~="not-prose"] *))::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: linear-gradient(135deg, #3b82f6, #6366f1);
}

.prose :where(blockquote):not(:where([class~="not-prose"] *))::after {
  content: "\201C";
  position: absolute;
  top: 0.5rem;
  right: 1rem;
  font-size: 4rem;
  color: rgba(59, 130, 246, 0.15);
  font-family: Georgia, serif;
  line-height: 1;
}

.prose :where(table):not(:where([class~="not-prose"] *)) {
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid #e5e7eb;
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  background: white;
  margin: 2.5rem 0;
}

.prose :where(th):not(:where([class~="not-prose"] *)) {
  background: linear-gradient(135deg, #f8fafc, #f1f5f9);
  font-weight: 700;
  color: #1f2937;
  text-align: left;
  padding: 1rem 1.5rem;
  border-bottom: 2px solid #e5e7eb;
  position: relative;
}

.prose :where(th):not(:where([class~="not-prose"] *))::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(to right, #3b82f6, #6366f1);
}

.prose :where(td):not(:where([class~="not-prose"] *)) {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #f3f4f6;
  transition: background-color 0.2s ease;
}

.prose :where(tr):not(:where([class~="not-prose"] *)):hover {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.02), rgba(99, 102, 241, 0.02));
}

/* Add some visual enhancements */
.prose {
  position: relative;
}

.prose::before {
  content: "";
  position: absolute;
  top: 0;
  left: -2rem;
  width: 2px;
  height: 100%;
  background: linear-gradient(to bottom, transparent, rgba(59, 130, 246, 0.3), transparent);
  border-radius: 1px;
}

/* Smooth scrolling */
html {
  scroll-behavior: smooth;
}

/* Custom scrollbar */
.main-content::-webkit-scrollbar {
  width: 6px;
}

.main-content::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 3px;
}

.main-content::-webkit-scrollbar-thumb {
  background: #3b82f6;
  border-radius: 3px;
}

.main-content::-webkit-scrollbar-thumb:hover {
  background: #2563eb;
}

/* Animation for sidebar toggle */
@media (max-width: 1024px) {
  aside {
    transition: transform 0.3s ease-in-out;
  }
}

/* Focus styles */
.prose :where(a):not(:where([class~="not-prose"] *)):focus {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
  border-radius: 0.25rem;
}

/* Transitions */
.transition-colors {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}

.transition-opacity {
  transition-property: opacity;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}

/* Print styles */
@media print {
  .prose {
    max-width: none;
  }
  
  .prose :where(pre):not(:where([class~="not-prose"] *)) {
    background: #f8f9fa !important;
    color: #212529 !important;
    border: 1px solid #dee2e6 !important;
  }
  
  .prose :where(code):not(:where([class~="not-prose"] *)) {
    background: #f8f9fa !important;
    color: #212529 !important;
  }
}

/* Callout styles for markdown notes/warnings/tips */
.prose blockquote p strong {
  display: inline-block;
  margin-right: 0.5em;
}
.prose blockquote p strong:contains('Note:') {
  color: #2563eb;
}
.prose blockquote p strong:contains('Warning:') {
  color: #f59e42;
}
.prose blockquote p strong:contains('Tip:') {
  color: #10b981;
}
.prose blockquote {
  border-left: 6px solid #3b82f6;
  background: linear-gradient(135deg, #eff6ff 80%, #f0fdfa 100%);
  padding: 1.5rem 2rem;
  margin: 2rem 0;
  border-radius: 0.75rem;
  box-shadow: 0 2px 8px 0 rgba(59,130,246,0.04);
}
/* Responsive tables */
.prose table {
  display: block;
  width: 100%;
  overflow-x: auto;
  border-radius: 0.5rem;
}
.prose th, .prose td {
  white-space: nowrap;
}
/* Code block improvements */
.prose pre {
  font-size: 1rem;
  line-height: 1.6;
  background: #0f172a;
  color: #f1f5f9;
  border-radius: 0.75rem;
  padding: 1.5rem;
  border: 1px solid #334155;
  overflow-x: auto;
}
.prose code {
  font-size: 1em;
  background: #f1f5f9;
  color: #3b82f6;
  border-radius: 0.375rem;
  padding: 0.2em 0.5em;
  font-weight: 500;
  border: 1px solid #e2e8f0;
}
/* Spacing tweaks for readability */
.prose p, .prose ul, .prose ol {
  margin-bottom: 1.5em;
}
.prose h2 {
  margin-top: 2.5em;
  margin-bottom: 1.2em;
}
.prose h3 {
  margin-top: 2em;
  margin-bottom: 1em;
}
/* Make first paragraph after h1 larger and more readable */
.prose h1 + p {
  font-size: 1.25rem;
  color: #3730a3;
  font-weight: 500;
  margin-bottom: 2.5rem;
  margin-top: 0.5rem;
}
/* Divider after TOC and before first heading */
hr {
  border: none;
  border-top: 2px solid #dbeafe;
  margin: 2.5rem 0 2rem 0;
}
/* Callout styles with icons */
.prose blockquote {
  position: relative;
  padding-left: 3.5rem;
  border-left: 6px solid #3b82f6;
  background: linear-gradient(135deg, #eff6ff 80%, #f0fdfa 100%);
  margin: 2.5rem 0;
  border-radius: 0.75rem;
  box-shadow: 0 2px 8px 0 rgba(59,130,246,0.04);
}
.prose blockquote p strong {
  display: inline-block;
  margin-right: 0.5em;
}
.prose blockquote p strong:contains('Note:')::before {
  content: '\2139'; /* info icon */
  color: #2563eb;
  font-size: 1.2em;
  margin-right: 0.5em;
}
.prose blockquote p strong:contains('Warning:')::before {
  content: '\26A0'; /* warning icon */
  color: #f59e42;
  font-size: 1.2em;
  margin-right: 0.5em;
}
.prose blockquote p strong:contains('Tip:')::before {
  content: '\1F4A1'; /* lightbulb icon */
  color: #10b981;
  font-size: 1.2em;
  margin-right: 0.5em;
}
/* Zebra striping for tables */
.prose tr:nth-child(even) td {
  background: #f3f4f6;
}
/* Custom bullets for lists */
.prose ul > li::before {
  content: '\2022';
  color: #3b82f6;
  font-size: 1.2em;
  margin-right: 0.75em;
  position: absolute;
  left: 0;
  top: 0.5em;
}
.prose ul > li {
  position: relative;
  padding-left: 2em;
}
/* Enhance active TOC item */
.toc a.border-blue-500 {
  background: linear-gradient(90deg, #dbeafe 60%, transparent);
  border-left: 4px solid #3b82f6 !important;
  color: #1d4ed8 !important;
  font-weight: 600;
}
/* Card shadow for main content */
.main-content {
  box-shadow: 0 8px 32px 0 rgba(30, 64, 175, 0.10), 0 1.5px 4px 0 rgba(59,130,246,0.04);
  border-radius: 1.25rem;
  background: linear-gradient(135deg, #f8fafc 80%, #f0fdfa 100%);
}
</style>