{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "specimen-document-deck",
  "type": "registry:component",
  "title": "Specimen Document Deck",
  "description": "An archival document and PDF specimen reader featuring 4 view modes (single, spread, continuous, grid), 2.5x tactile loupe, 3-tier epistemic data overlays ([LIVE], [MODELED], [MATURING]), and slide-out thesis commentary drawer.",
  "dependencies": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "components/SpecimenDocumentDeck.tsx",
      "content": "/* Experience Design System influenced by Chromologium (https://chromologium.com/) */\n\"use client\";\n\nimport React, { useState, useEffect, useRef } from \"react\";\nimport {\n  ChevronLeft,\n  ChevronRight,\n  Download,\n  Maximize2,\n  Minimize2,\n  BookOpen,\n  LayoutGrid,\n  FileText,\n  Sparkles,\n  Search,\n  Copy,\n  Check,\n  ZoomIn,\n  Layers,\n  MessageSquareText,\n  Scroll,\n  Info,\n  ExternalLink,\n  X,\n} from \"lucide-react\";\nimport { embedWatermark } from \"@/lib/watermark\";\n\nexport interface EpistemicRegion {\n  x: number; // % from left\n  y: number; // % from top\n  width: number; // % width\n  height: number; // % height\n  tier: \"live\" | \"modeled\" | \"maturing\";\n  label: string;\n  source: string;\n}\n\nexport interface AuthorCommentary {\n  thesis: string;\n  narrative: string[];\n  linchpinQuote?: string;\n  strategicOutcome?: string;\n}\n\nexport interface DocumentPageAnnotation {\n  x: number;\n  y: number;\n  title: string;\n  description: string;\n  badge?: string;\n}\n\nexport interface DocumentPage {\n  pageNumber: number;\n  title: string;\n  section?: string;\n  imageSrc: string;\n  highlights?: string;\n  searchKeywords?: string[];\n  authorCommentary?: AuthorCommentary;\n  epistemicRegions?: EpistemicRegion[];\n  annotations?: DocumentPageAnnotation[];\n}\n\nexport interface SpecimenDocumentDeckProps {\n  accessionId?: string;\n  title?: string;\n  citationText?: string;\n  pages: DocumentPage[];\n  pdfDownloadUrl?: string;\n  initialPage?: number;\n  allowSpreadView?: boolean;\n  className?: string;\n}\n\nexport function SpecimenDocumentDeck({\n  accessionId = \"ACCESSION // MONO-884-C\",\n  title = \"Specimen Document Deck\",\n  citationText,\n  pages,\n  pdfDownloadUrl = \"/reports/chromologium-specimen-deck-sample.pdf\",\n  initialPage = 1,\n  allowSpreadView = true,\n  className = \"\",\n}: SpecimenDocumentDeckProps) {\n  const [currentPage, setCurrentPage] = useState<number>(initialPage);\n  const [viewMode, setViewMode] = useState<\n    \"single\" | \"spread\" | \"continuous\" | \"grid\"\n  >(\"single\");\n  const [showAnnotations, setShowAnnotations] = useState<boolean>(true);\n  const [isEpistemicActive, setIsEpistemicActive] = useState<boolean>(false);\n  const [isLoupeActive, setIsLoupeActive] = useState<boolean>(false);\n  const [isCommentaryOpen, setIsCommentaryOpen] = useState<boolean>(false);\n  const [isFullscreen, setIsFullscreen] = useState<boolean>(false);\n  const [searchQuery, setSearchQuery] = useState<string>(\"\");\n  const [copyToast, setCopyToast] = useState<string | null>(null);\n\n  // Loupe pointer state\n  const [loupePos, setLoupePos] = useState<{\n    x: number;\n    y: number;\n    relX: number;\n    relY: number;\n  } | null>(null);\n\n  const [activeAnnotation, setActiveAnnotation] =\n    useState<DocumentPageAnnotation | null>(null);\n  const [activeEpistemicModal, setActiveEpistemicModal] =\n    useState<EpistemicRegion | null>(null);\n  const [isAttributionOpen, setIsAttributionOpen] = useState<boolean>(false);\n\n  const filmstripRef = useRef<HTMLDivElement>(null);\n  const pageContainerRef = useRef<HTMLDivElement>(null);\n  const rootDeckRef = useRef<HTMLDivElement>(null);\n\n  const totalPages = pages.length;\n\n  const goToPage = (num: number) => {\n    const target = Math.max(1, Math.min(totalPages, num));\n    setCurrentPage(target);\n    setActiveAnnotation(null);\n    setActiveEpistemicModal(null);\n  };\n\n  const handlePageMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\n    if (!isLoupeActive) return;\n    const rect = e.currentTarget.getBoundingClientRect();\n    const x = e.clientX - rect.left;\n    const y = e.clientY - rect.top;\n    const relX = Math.max(0, Math.min(100, (x / rect.width) * 100));\n    const relY = Math.max(0, Math.min(100, (y / rect.height) * 100));\n    setLoupePos({ x, y, relX, relY });\n  };\n\n  const handlePageMouseLeave = () => {\n    setLoupePos(null);\n  };\n\n  const toggleFullscreen = async () => {\n    try {\n      if (!isFullscreen) {\n        if (rootDeckRef.current?.requestFullscreen) {\n          await rootDeckRef.current.requestFullscreen();\n        }\n      } else {\n        if (document.fullscreenElement && document.exitFullscreen) {\n          await document.exitFullscreen();\n        }\n      }\n    } catch {\n      // Fallback state toggle\n      setIsFullscreen(!isFullscreen);\n    }\n  };\n\n  useEffect(() => {\n    const handleFullscreenChange = () => {\n      setIsFullscreen(!!document.fullscreenElement);\n    };\n    document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n    return () => {\n      document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n    };\n  }, []);\n\n  // Keyboard navigation\n  useEffect(() => {\n    const handleKeyDown = (e: KeyboardEvent) => {\n      if (\n        document.activeElement?.tagName === \"INPUT\" ||\n        document.activeElement?.tagName === \"TEXTAREA\"\n      ) {\n        return;\n      }\n      if (e.key === \"ArrowRight\") {\n        e.preventDefault();\n        goToPage(\n          viewMode === \"spread\" && allowSpreadView\n            ? currentPage + 2\n            : currentPage + 1,\n        );\n      } else if (e.key === \"ArrowLeft\") {\n        e.preventDefault();\n        goToPage(\n          viewMode === \"spread\" && allowSpreadView\n            ? currentPage - 2\n            : currentPage - 1,\n        );\n      } else if (e.key === \"Escape\") {\n        setActiveAnnotation(null);\n        setActiveEpistemicModal(null);\n        setIsAttributionOpen(false);\n        setIsCommentaryOpen(false);\n      }\n    };\n    window.addEventListener(\"keydown\", handleKeyDown);\n    return () => window.removeEventListener(\"keydown\", handleKeyDown);\n  }, [currentPage, viewMode, allowSpreadView]);\n\n  // Center thumbnail in filmstrip\n  useEffect(() => {\n    if (filmstripRef.current) {\n      const activeThumb = filmstripRef.current.querySelector(\n        `[data-page=\"${currentPage}\"]`,\n      ) as HTMLElement;\n      if (activeThumb) {\n        const stripRect = filmstripRef.current.getBoundingClientRect();\n        const thumbRect = activeThumb.getBoundingClientRect();\n        const offset =\n          thumbRect.left -\n          stripRect.left -\n          stripRect.width / 2 +\n          thumbRect.width / 2;\n        filmstripRef.current.scrollBy({ left: offset, behavior: \"smooth\" });\n      }\n    }\n  }, [currentPage]);\n\n  const copyToClipboard = (text: string, label: string) => {\n    if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n      navigator.clipboard.writeText(embedWatermark(text));\n      setCopyToast(`Copied ${label} ◈`);\n      setTimeout(() => setCopyToast(null), 2400);\n    }\n  };\n\n  const filteredPages = pages.filter((p) => {\n    if (!searchQuery.trim()) return true;\n    const q = searchQuery.toLowerCase();\n    return (\n      p.title.toLowerCase().includes(q) ||\n      (p.section && p.section.toLowerCase().includes(q)) ||\n      (p.highlights && p.highlights.toLowerCase().includes(q)) ||\n      (p.searchKeywords &&\n        p.searchKeywords.some((k) => k.toLowerCase().includes(q))) ||\n      (p.authorCommentary &&\n        (p.authorCommentary.thesis.toLowerCase().includes(q) ||\n          p.authorCommentary.narrative.some((n) =>\n            n.toLowerCase().includes(q),\n          )))\n    );\n  });\n\n  const currentPageObj =\n    pages.find((p) => p.pageNumber === currentPage) || pages[0];\n  const secondPageObj =\n    viewMode === \"spread\" && allowSpreadView && currentPage < totalPages\n      ? pages.find((p) => p.pageNumber === currentPage + 1)\n      : null;\n\n  const apaCitation =\n    citationText ||\n    `The Chromologium Curatorial Board. (2026). ${title}: Multi-view specimen reader with epistemic data overlays and tactile inspection. The Chromologium Archives. https://chromologium.com/components/specimen-document-deck`;\n\n  const bibtexCitation = `@software{chromologium_specimen_deck_2026,\n  title = {${title}},\n  author = {{The Chromologium Curatorial Board}},\n  year = {2026},\n  url = {https://chromologium.com/components/specimen-document-deck}\n}`;\n\n  return (\n    <div\n      ref={rootDeckRef}\n      className={`relative flex w-full flex-col overflow-hidden rounded-xl border border-white/10 bg-[#090b11] text-[#e8e4dc] shadow-2xl transition-all duration-300 ${\n        isFullscreen ? \"fixed inset-0 z-50 h-screen w-screen rounded-none\" : \"\"\n      } ${className}`}\n      style={{\n        fontFamily: \"var(--font-sans, system-ui, sans-serif)\",\n      }}\n    >\n      {/* ── TOP CONTROL BAR ─────────────────────────────────────────────── */}\n      <header className=\"z-30 flex flex-wrap items-center justify-between gap-2 border-b border-white/10 bg-[#0d101a] px-4 py-3\">\n        <div className=\"flex min-w-0 items-center gap-3\">\n          <div className=\"flex items-center gap-2\">\n            <span className=\"inline-flex h-5 w-5 items-center justify-center rounded-full border border-[#c9a55a]/40 bg-[#c9a55a]/20 font-serif text-xs font-bold text-[#c9a55a]\">\n              ◈\n            </span>\n            <span className=\"truncate font-mono text-[11px] tracking-widest text-[#c9a55a] uppercase\">\n              {accessionId}\n            </span>\n          </div>\n          <span className=\"hidden text-white/30 sm:inline\">|</span>\n          <h2 className=\"max-w-[200px] truncate font-serif text-xs font-medium text-white/90 sm:text-sm md:max-w-md\">\n            {currentPageObj?.title || title}\n          </h2>\n        </div>\n\n        {/* View mode buttons & actions */}\n        <div className=\"flex shrink-0 items-center gap-1.5\">\n          <div className=\"flex items-center rounded-lg border border-white/10 bg-white/5 p-0.5\">\n            <button\n              type=\"button\"\n              onClick={() => setViewMode(\"single\")}\n              title=\"Single Page View\"\n              className={`rounded p-1.5 text-xs transition-colors ${\n                viewMode === \"single\"\n                  ? \"bg-[#c9a55a] font-bold text-[#0a0c13]\"\n                  : \"text-white/60 hover:text-white\"\n              }`}\n            >\n              <FileText className=\"h-3.5 w-3.5\" />\n            </button>\n            {allowSpreadView && (\n              <button\n                type=\"button\"\n                onClick={() => setViewMode(\"spread\")}\n                title=\"2-Page Spread View\"\n                className={`rounded p-1.5 text-xs transition-colors ${\n                  viewMode === \"spread\"\n                    ? \"bg-[#c9a55a] font-bold text-[#0a0c13]\"\n                    : \"text-white/60 hover:text-white\"\n                }`}\n              >\n                <BookOpen className=\"h-3.5 w-3.5\" />\n              </button>\n            )}\n            <button\n              type=\"button\"\n              onClick={() => setViewMode(\"continuous\")}\n              title=\"Continuous Scroll View\"\n              className={`rounded p-1.5 text-xs transition-colors ${\n                viewMode === \"continuous\"\n                  ? \"bg-[#c9a55a] font-bold text-[#0a0c13]\"\n                  : \"text-white/60 hover:text-white\"\n              }`}\n            >\n              <Scroll className=\"h-3.5 w-3.5\" />\n            </button>\n            <button\n              type=\"button\"\n              onClick={() => setViewMode(\"grid\")}\n              title=\"Thumbnail Grid View\"\n              className={`rounded p-1.5 text-xs transition-colors ${\n                viewMode === \"grid\"\n                  ? \"bg-[#c9a55a] font-bold text-[#0a0c13]\"\n                  : \"text-white/60 hover:text-white\"\n              }`}\n            >\n              <LayoutGrid className=\"h-3.5 w-3.5\" />\n            </button>\n          </div>\n\n          <div className=\"mx-1 hidden h-4 w-px bg-white/10 sm:block\" />\n\n          {/* Inspection toggles */}\n          <button\n            type=\"button\"\n            onClick={() => setIsLoupeActive(!isLoupeActive)}\n            title=\"Toggle 2.5x Loupe Magnifier\"\n            className={`flex items-center gap-1 rounded-md border px-2 py-1 font-mono text-xs transition-all ${\n              isLoupeActive\n                ? \"border-[#c9a55a] bg-[#c9a55a]/20 text-[#dbb978]\"\n                : \"border-white/10 bg-white/5 text-white/60 hover:text-white\"\n            }`}\n          >\n            <ZoomIn className=\"h-3.5 w-3.5\" />\n            <span className=\"hidden md:inline\">Loupe</span>\n          </button>\n\n          <button\n            type=\"button\"\n            onClick={() => setIsEpistemicActive(!isEpistemicActive)}\n            title=\"Toggle Epistemic Taxonomy Layers\"\n            className={`flex items-center gap-1 rounded-md border px-2 py-1 font-mono text-xs transition-all ${\n              isEpistemicActive\n                ? \"border-[#34d399] bg-[#34d399]/20 text-[#34d399]\"\n                : \"border-white/10 bg-white/5 text-white/60 hover:text-white\"\n            }`}\n          >\n            <Layers className=\"h-3.5 w-3.5\" />\n            <span className=\"hidden md:inline\">Epistemic</span>\n          </button>\n\n          <button\n            type=\"button\"\n            onClick={() => setShowAnnotations(!showAnnotations)}\n            title=\"Toggle Page Highlights & Pins\"\n            className={`flex items-center gap-1 rounded-md border px-2 py-1 font-mono text-xs transition-all ${\n              showAnnotations\n                ? \"border-[#38bdf8] bg-[#38bdf8]/20 text-[#38bdf8]\"\n                : \"border-white/10 bg-white/5 text-white/60 hover:text-white\"\n            }`}\n          >\n            <Sparkles className=\"h-3.5 w-3.5\" />\n            <span className=\"hidden lg:inline\">Pins</span>\n          </button>\n\n          <button\n            type=\"button\"\n            onClick={() => setIsCommentaryOpen(!isCommentaryOpen)}\n            title=\"Toggle Author Commentary Drawer\"\n            className={`flex items-center gap-1 rounded-md border px-2 py-1 font-mono text-xs transition-all ${\n              isCommentaryOpen\n                ? \"border-[#c9a55a] bg-[#c9a55a]/20 text-[#dbb978]\"\n                : \"border-white/10 bg-white/5 text-white/60 hover:text-white\"\n            }`}\n          >\n            <MessageSquareText className=\"h-3.5 w-3.5\" />\n            <span className=\"hidden md:inline\">Thesis</span>\n          </button>\n\n          <div className=\"mx-1 hidden h-4 w-px bg-white/10 sm:block\" />\n\n          {/* Attribution colophon modal trigger */}\n          <button\n            type=\"button\"\n            onClick={() => setIsAttributionOpen(true)}\n            title=\"Attribution & Citations\"\n            className=\"flex items-center gap-1 rounded-md border border-white/10 bg-white/5 px-2 py-1 font-mono text-xs text-[#c9a55a] transition-all hover:bg-[#c9a55a]/20\"\n          >\n            <Info className=\"h-3.5 w-3.5\" />\n            <span className=\"hidden xl:inline\">Cite</span>\n          </button>\n\n          {/* Download PDF button */}\n          {pdfDownloadUrl && (\n            <a\n              href={pdfDownloadUrl}\n              download\n              title=\"Download Companion Archival PDF\"\n              className=\"flex items-center gap-1.5 rounded-md border border-[#c9a55a]/60 bg-[#c9a55a]/10 px-2.5 py-1 font-mono text-xs font-medium text-[#dbb978] transition-all hover:bg-[#c9a55a]/25\"\n            >\n              <Download className=\"h-3.5 w-3.5\" />\n              <span className=\"hidden sm:inline\">PDF</span>\n            </a>\n          )}\n\n          {/* Fullscreen button */}\n          <button\n            type=\"button\"\n            onClick={toggleFullscreen}\n            title={isFullscreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"}\n            className=\"rounded-md border border-white/10 bg-white/5 p-1.5 text-white/60 transition-all hover:text-white\"\n          >\n            {isFullscreen ? (\n              <Minimize2 className=\"h-3.5 w-3.5\" />\n            ) : (\n              <Maximize2 className=\"h-3.5 w-3.5\" />\n            )}\n          </button>\n        </div>\n      </header>\n\n      {/* ── SEARCH & FILTER STRIP ────────────────────────────────────────── */}\n      <div className=\"flex items-center justify-between border-b border-white/5 bg-[#08090f] px-4 py-2 text-xs\">\n        <div className=\"relative max-w-sm flex-1\">\n          <Search className=\"absolute top-1/2 left-2.5 h-3.5 w-3.5 -translate-y-1/2 text-white/40\" />\n          <input\n            type=\"text\"\n            value={searchQuery}\n            onChange={(e) => setSearchQuery(e.target.value)}\n            placeholder=\"Search keywords, optics, Cauchy, Kubelka...\"\n            className=\"w-full rounded-md border border-white/10 bg-white/5 py-1 pr-7 pl-8 text-xs text-white placeholder-white/40 focus:border-[#c9a55a]/60 focus:outline-none\"\n          />\n          {searchQuery && (\n            <button\n              type=\"button\"\n              onClick={() => setSearchQuery(\"\")}\n              className=\"absolute top-1/2 right-2 -translate-y-1/2 text-white/40 hover:text-white\"\n            >\n              <X className=\"h-3 w-3\" />\n            </button>\n          )}\n        </div>\n\n        <div className=\"flex items-center gap-3 font-mono text-[11px] text-white/50\">\n          <span>\n            PAGE <span className=\"font-bold text-[#c9a55a]\">{currentPage}</span>{\" \"}\n            / {totalPages}\n          </span>\n          {searchQuery && (\n            <span className=\"text-emerald-400\">\n              {filteredPages.length} match\n              {filteredPages.length === 1 ? \"\" : \"es\"}\n            </span>\n          )}\n        </div>\n      </div>\n\n      {/* ── MAIN STAGE ─────────────────────────────────────────────────── */}\n      <div\n        ref={pageContainerRef}\n        className=\"relative flex min-h-[500px] flex-1 overflow-hidden bg-[#06070a]\"\n      >\n        {/* Flank Margin Left Navigation */}\n        {viewMode !== \"continuous\" && viewMode !== \"grid\" && (\n          <button\n            type=\"button\"\n            onClick={(e) => {\n              e.preventDefault();\n              goToPage(\n                viewMode === \"spread\" && allowSpreadView\n                  ? currentPage - 2\n                  : currentPage - 1,\n              );\n            }}\n            disabled={currentPage <= 1}\n            title=\"Previous Page (ArrowLeft)\"\n            className=\"absolute top-1/2 left-2 z-30 -translate-y-1/2 rounded-full border border-white/15 bg-black/60 p-2.5 text-white/70 shadow-xl backdrop-blur-sm transition-all hover:bg-black/90 hover:text-white disabled:pointer-events-none disabled:opacity-0\"\n          >\n            <ChevronLeft className=\"h-5 w-5\" />\n          </button>\n        )}\n\n        {/* Flank Margin Right Navigation */}\n        {viewMode !== \"continuous\" && viewMode !== \"grid\" && (\n          <button\n            type=\"button\"\n            onClick={(e) => {\n              e.preventDefault();\n              goToPage(\n                viewMode === \"spread\" && allowSpreadView\n                  ? currentPage + 2\n                  : currentPage + 1,\n              );\n            }}\n            disabled={\n              viewMode === \"spread\" && allowSpreadView\n                ? currentPage >= totalPages - 1\n                : currentPage >= totalPages\n            }\n            title=\"Next Page (ArrowRight)\"\n            className=\"absolute top-1/2 right-2 z-30 -translate-y-1/2 rounded-full border border-white/15 bg-black/60 p-2.5 text-white/70 shadow-xl backdrop-blur-sm transition-all hover:bg-black/90 hover:text-white disabled:pointer-events-none disabled:opacity-0\"\n          >\n            <ChevronRight className=\"h-5 w-5\" />\n          </button>\n        )}\n\n        {/* Viewport Center */}\n        <div className=\"relative flex flex-1 items-center justify-center overflow-y-auto p-4 select-none sm:p-8\">\n          {viewMode === \"continuous\" ? (\n            /* Continuous Vertical Scroll */\n            <div className=\"flex w-full max-w-2xl flex-col items-center gap-8 py-4\">\n              {filteredPages.map((p) => (\n                <div\n                  key={p.pageNumber}\n                  id={`page-anchor-${p.pageNumber}`}\n                  className=\"w-full overflow-hidden rounded-lg border border-white/15 bg-[#0f1118] shadow-2xl\"\n                >\n                  <img\n                    src={p.imageSrc}\n                    alt={p.title}\n                    className=\"block h-auto w-full\"\n                    loading=\"lazy\"\n                  />\n                  <div className=\"flex items-center justify-between border-t border-white/10 bg-[#0d101a] p-3 font-mono text-[10px] text-white/70\">\n                    <span className=\"font-bold text-[#c9a55a]\">\n                      PLATE {String(p.pageNumber).padStart(2, \"0\")}\n                    </span>\n                    <span className=\"max-w-xs truncate\">{p.title}</span>\n                  </div>\n                </div>\n              ))}\n            </div>\n          ) : viewMode === \"grid\" ? (\n            /* Thumbnail Grid View */\n            <div className=\"grid w-full max-w-5xl grid-cols-2 gap-4 p-4 sm:grid-cols-3 md:grid-cols-4\">\n              {filteredPages.map((p) => (\n                <div\n                  key={p.pageNumber}\n                  onClick={() => {\n                    goToPage(p.pageNumber);\n                    setViewMode(\"single\");\n                  }}\n                  className={`group cursor-pointer overflow-hidden rounded-lg border shadow-lg transition-all hover:scale-102 ${\n                    currentPage === p.pageNumber\n                      ? \"border-[#c9a55a] ring-2 ring-[#c9a55a]/40\"\n                      : \"border-white/10 hover:border-white/30\"\n                  }`}\n                >\n                  <img\n                    src={p.imageSrc}\n                    alt={p.title}\n                    className=\"block h-auto w-full\"\n                    loading=\"lazy\"\n                  />\n                  <div className=\"flex items-center justify-between border-t border-white/10 bg-[#0d101a] p-2 font-mono text-[10px]\">\n                    <span className=\"font-bold text-[#c9a55a]\">\n                      P.{String(p.pageNumber).padStart(2, \"0\")}\n                    </span>\n                    <span className=\"max-w-[80px] truncate text-white/60\">\n                      {p.section || p.title}\n                    </span>\n                  </div>\n                </div>\n              ))}\n            </div>\n          ) : (\n            /* Single or 2-Page Spread View */\n            <div\n              className={`relative flex w-full items-center justify-center gap-0 transition-all duration-300 ${\n                viewMode === \"spread\" && allowSpreadView\n                  ? \"max-w-5xl\"\n                  : \"max-w-2xl\"\n              }`}\n            >\n              {/* Left Page (or Single Page) */}\n              <div\n                onMouseMove={handlePageMouseMove}\n                onMouseLeave={handlePageMouseLeave}\n                className={`group relative w-full overflow-hidden rounded-xl border border-white/15 bg-[#0f1118] shadow-2xl select-none ${\n                  viewMode === \"spread\" && allowSpreadView && secondPageObj\n                    ? \"max-w-[440px] rounded-r-none border-r-0 lg:max-w-[480px]\"\n                    : \"max-w-[620px]\"\n                }`}\n              >\n                <img\n                  src={currentPageObj.imageSrc}\n                  alt={currentPageObj.title}\n                  className=\"block h-auto w-full\"\n                  loading=\"eager\"\n                />\n\n                {/* Annotation Pins */}\n                {showAnnotations &&\n                  currentPageObj.annotations?.map((ann, i) => (\n                    <div\n                      key={i}\n                      style={{ left: `${ann.x}%`, top: `${ann.y}%` }}\n                      className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2\"\n                    >\n                      <button\n                        type=\"button\"\n                        onClick={(e) => {\n                          e.stopPropagation();\n                          setActiveAnnotation(\n                            activeAnnotation === ann ? null : ann,\n                          );\n                        }}\n                        className=\"relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-full border-2 border-white bg-[#c9a55a] text-[#0a0c13] shadow-xl transition-transform hover:scale-125\"\n                        title={ann.title}\n                      >\n                        <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-[#c9a55a] opacity-75\" />\n                        <Sparkles className=\"relative z-10 h-3 w-3\" />\n                      </button>\n                    </div>\n                  ))}\n\n                {/* Epistemic Regions */}\n                {isEpistemicActive &&\n                  currentPageObj.epistemicRegions?.map((reg, idx) => (\n                    <div\n                      key={idx}\n                      onClick={(e) => {\n                        e.stopPropagation();\n                        setActiveEpistemicModal(reg);\n                      }}\n                      style={{\n                        left: `${reg.x}%`,\n                        top: `${reg.y}%`,\n                        width: `${reg.width}%`,\n                        height: `${reg.height}%`,\n                      }}\n                      className={`absolute z-20 flex cursor-pointer flex-col justify-between rounded border-2 p-1.5 transition-all ${\n                        reg.tier === \"live\"\n                          ? \"border-emerald-400 bg-emerald-500/20 text-emerald-300 hover:bg-emerald-500/30\"\n                          : reg.tier === \"modeled\"\n                            ? \"border-sky-400 bg-sky-500/20 text-sky-200 hover:bg-sky-500/30\"\n                            : \"border-amber-400 bg-amber-500/20 text-amber-200 hover:bg-amber-500/30\"\n                      }`}\n                    >\n                      <span className=\"w-fit rounded bg-black/80 px-1.5 py-0.5 font-mono text-[9px] font-bold\">\n                        [{reg.tier.toUpperCase()}]\n                      </span>\n                    </div>\n                  ))}\n\n                {/* Tactile Loupe */}\n                {isLoupeActive && loupePos && (\n                  <div\n                    style={{\n                      left: `${loupePos.x}px`,\n                      top: `${loupePos.y}px`,\n                      backgroundImage: `url(${currentPageObj.imageSrc})`,\n                      backgroundPosition: `${loupePos.relX}% ${loupePos.relY}%`,\n                      backgroundSize: `500%`,\n                    }}\n                    className=\"pointer-events-none absolute z-40 h-44 w-44 -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-full border-2 border-[#c9a55a] bg-black shadow-2xl ring-4 ring-black/50\"\n                  >\n                    <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center opacity-40\">\n                      <div className=\"h-px w-full bg-[#c9a55a]\" />\n                      <div className=\"absolute h-full w-px bg-[#c9a55a]\" />\n                    </div>\n                  </div>\n                )}\n              </div>\n\n              {/* Right Page (Spread Mode) */}\n              {viewMode === \"spread\" && allowSpreadView && secondPageObj && (\n                <>\n                  {/* Book Gutter Spine Shading */}\n                  <div className=\"pointer-events-none z-30 -mx-1.5 h-full w-3 bg-gradient-to-r from-black/50 via-black/80 to-black/50 shadow-inner\" />\n                  <div\n                    onMouseMove={handlePageMouseMove}\n                    onMouseLeave={handlePageMouseLeave}\n                    className=\"group relative hidden w-full max-w-[440px] rounded-xl rounded-l-none border border-l-0 border-white/15 bg-[#0f1118] shadow-2xl select-none md:block lg:max-w-[480px]\"\n                  >\n                    <img\n                      src={secondPageObj.imageSrc}\n                      alt={secondPageObj.title}\n                      className=\"block h-auto w-full\"\n                      loading=\"eager\"\n                    />\n\n                    {/* Annotations on Page 2 */}\n                    {showAnnotations &&\n                      secondPageObj.annotations?.map((ann, i) => (\n                        <div\n                          key={i}\n                          style={{ left: `${ann.x}%`, top: `${ann.y}%` }}\n                          className=\"absolute z-20 -translate-x-1/2 -translate-y-1/2\"\n                        >\n                          <button\n                            type=\"button\"\n                            onClick={(e) => {\n                              e.stopPropagation();\n                              setActiveAnnotation(\n                                activeAnnotation === ann ? null : ann,\n                              );\n                            }}\n                            className=\"relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-full border-2 border-white bg-[#c9a55a] text-[#0a0c13] shadow-xl transition-transform hover:scale-125\"\n                            title={ann.title}\n                          >\n                            <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-[#c9a55a] opacity-75\" />\n                            <Sparkles className=\"relative z-10 h-3 w-3\" />\n                          </button>\n                        </div>\n                      ))}\n                  </div>\n                </>\n              )}\n            </div>\n          )}\n        </div>\n\n        {/* ── AUTHOR COMMENTARY DRAWER ─────────────────────────────────── */}\n        {isCommentaryOpen && currentPageObj.authorCommentary && (\n          <aside className=\"animate-in slide-in-from-right z-30 flex w-80 flex-col justify-between overflow-y-auto border-l border-white/10 bg-[#0c0e18]/95 p-5 shadow-2xl backdrop-blur-xl duration-200 md:w-96\">\n            <div className=\"space-y-4\">\n              <div className=\"flex items-center justify-between border-b border-white/10 pb-3\">\n                <span className=\"font-mono text-[11px] font-bold tracking-wider text-[#c9a55a] uppercase\">\n                  CURATORIAL THESIS &amp; NOTES\n                </span>\n                <button\n                  type=\"button\"\n                  onClick={() => setIsCommentaryOpen(false)}\n                  className=\"p-1 font-mono text-xs text-white/40 hover:text-white\"\n                >\n                  <X className=\"h-4 w-4\" />\n                </button>\n              </div>\n\n              <div className=\"font-serif text-sm font-bold text-white\">\n                {currentPageObj.title}\n              </div>\n\n              {/* Linchpin Quote Card */}\n              {currentPageObj.authorCommentary.linchpinQuote && (\n                <div className=\"group relative rounded-lg border border-[#c9a55a]/30 bg-[#c9a55a]/10 p-3.5\">\n                  <p className=\"font-serif text-xs leading-relaxed text-[#dbb978] italic\">\n                    \"{currentPageObj.authorCommentary.linchpinQuote}\"\n                  </p>\n                  <button\n                    type=\"button\"\n                    onClick={() =>\n                      copyToClipboard(\n                        currentPageObj.authorCommentary?.linchpinQuote || \"\",\n                        \"Quote\",\n                      )\n                    }\n                    className=\"mt-2.5 flex cursor-pointer items-center gap-1 font-mono text-[10px] text-[#c9a55a] hover:underline\"\n                  >\n                    <Copy className=\"h-3 w-3\" />\n                    <span>Copy Quote</span>\n                  </button>\n                </div>\n              )}\n\n              {/* Core Thesis Statement */}\n              <div className=\"rounded-lg border border-white/10 bg-white/5 p-3 text-xs leading-relaxed font-medium text-white/90\">\n                {currentPageObj.authorCommentary.thesis}\n              </div>\n\n              {/* Narrative paragraphs */}\n              <div className=\"space-y-2.5 font-sans text-xs leading-relaxed text-white/70\">\n                {currentPageObj.authorCommentary.narrative.map((n, i) => (\n                  <p key={i}>{n}</p>\n                ))}\n              </div>\n\n              {/* Strategic outcome badge */}\n              {currentPageObj.authorCommentary.strategicOutcome && (\n                <div className=\"border-t border-white/10 pt-2\">\n                  <span className=\"font-mono text-[10px] font-bold tracking-wider text-[#34d399] uppercase\">\n                    STRATEGIC OUTCOME:\n                  </span>\n                  <p className=\"mt-1 text-[11px] text-white/80\">\n                    {currentPageObj.authorCommentary.strategicOutcome}\n                  </p>\n                </div>\n              )}\n            </div>\n\n            <div className=\"flex justify-between border-t border-white/10 pt-4 font-mono text-[10px] text-white/40\">\n              <span>\n                PLATE {currentPage} OF {totalPages}\n              </span>\n              <span>THE CHROMOLOGIUM</span>\n            </div>\n          </aside>\n        )}\n      </div>\n\n      {/* ── FILMSTRIP THUMBNAIL BAR ──────────────────────────────────────── */}\n      <div className=\"z-30 border-t border-white/10 bg-[#0d101a]/95 p-2.5 backdrop-blur-md\">\n        <div\n          ref={filmstripRef}\n          className=\"scrollbar-thin scrollbar-thumb-white/10 scrollbar-track-transparent flex items-center gap-2 overflow-x-auto pb-1\"\n        >\n          {pages.map((p) => {\n            const isActive = currentPage === p.pageNumber;\n            return (\n              <button\n                key={p.pageNumber}\n                data-page={p.pageNumber}\n                type=\"button\"\n                onClick={(e) => {\n                  e.preventDefault();\n                  goToPage(p.pageNumber);\n                  if (viewMode === \"grid\") setViewMode(\"single\");\n                }}\n                className={`relative flex shrink-0 cursor-pointer items-center gap-2 rounded-lg border px-3 py-1.5 transition-all ${\n                  isActive\n                    ? \"border-[#c9a55a] bg-[#c9a55a]/20 text-white\"\n                    : \"border-white/10 bg-white/5 text-white/50 hover:border-white/20 hover:text-white\"\n                }`}\n              >\n                <span\n                  className={`font-mono text-[10px] font-bold ${\n                    isActive ? \"text-[#dbb978]\" : \"text-white/40\"\n                  }`}\n                >\n                  P.{String(p.pageNumber).padStart(2, \"0\")}\n                </span>\n                <span className=\"max-w-[110px] truncate text-left text-xs\">\n                  {p.title}\n                </span>\n              </button>\n            );\n          })}\n        </div>\n      </div>\n\n      {/* ── ANNOTATION CALLOUT POPUP ─────────────────────────────────────── */}\n      {activeAnnotation && (\n        <div\n          onClick={() => setActiveAnnotation(null)}\n          className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm\"\n        >\n          <div\n            onClick={(e) => e.stopPropagation()}\n            className=\"relative w-full max-w-sm rounded-xl border border-white/20 bg-[#0f121e] p-5 shadow-2xl\"\n          >\n            <div className=\"mb-3 flex items-center justify-between\">\n              <span className=\"rounded border border-[#c9a55a]/40 bg-[#c9a55a]/20 px-2 py-0.5 font-mono text-[9px] font-bold text-[#dbb978]\">\n                {activeAnnotation.badge || \"SPECIMEN HIGHLIGHT\"}\n              </span>\n              <button\n                type=\"button\"\n                onClick={() => setActiveAnnotation(null)}\n                className=\"text-white/40 hover:text-white\"\n              >\n                <X className=\"h-4 w-4\" />\n              </button>\n            </div>\n            <h3 className=\"mb-2 font-serif text-base font-bold text-white\">\n              {activeAnnotation.title}\n            </h3>\n            <p className=\"mb-4 text-xs leading-relaxed text-white/80\">\n              {activeAnnotation.description}\n            </p>\n            <button\n              type=\"button\"\n              onClick={() => setActiveAnnotation(null)}\n              className=\"w-full rounded-md bg-white/10 py-1.5 font-mono text-xs text-white transition-colors hover:bg-white/20\"\n            >\n              Dismiss\n            </button>\n          </div>\n        </div>\n      )}\n\n      {/* ── EPISTEMIC METHODOLOGY MODAL ──────────────────────────────────── */}\n      {activeEpistemicModal && (\n        <div\n          onClick={() => setActiveEpistemicModal(null)}\n          className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-4 backdrop-blur-sm\"\n        >\n          <div\n            onClick={(e) => e.stopPropagation()}\n            className=\"relative w-full max-w-md rounded-xl border border-white/20 bg-[#0f121e] p-6 shadow-2xl\"\n          >\n            <div className=\"mb-4 flex items-center justify-between\">\n              <span\n                className={`rounded px-2.5 py-0.5 font-mono text-[10px] font-bold ${\n                  activeEpistemicModal.tier === \"live\"\n                    ? \"border border-emerald-500/40 bg-emerald-500/20 text-emerald-300\"\n                    : activeEpistemicModal.tier === \"modeled\"\n                      ? \"border border-sky-500/40 bg-sky-500/20 text-sky-300\"\n                      : \"border border-amber-500/40 bg-amber-500/20 text-amber-300\"\n                }`}\n              >\n                [{activeEpistemicModal.tier.toUpperCase()} DATA TIER]\n              </span>\n              <button\n                type=\"button\"\n                onClick={() => setActiveEpistemicModal(null)}\n                className=\"text-white/40 hover:text-white\"\n              >\n                <X className=\"h-4 w-4\" />\n              </button>\n            </div>\n\n            <h3 className=\"mb-2 font-serif text-lg font-bold text-white\">\n              {activeEpistemicModal.label}\n            </h3>\n\n            <div className=\"mb-4 rounded-lg border border-white/10 bg-black/40 p-3.5\">\n              <div className=\"mb-1 font-mono text-[10px] text-[#c9a55a] uppercase\">\n                Empirical Source &amp; Methodology:\n              </div>\n              <p className=\"text-xs leading-relaxed text-white/90\">\n                {activeEpistemicModal.source}\n              </p>\n            </div>\n\n            <button\n              type=\"button\"\n              onClick={() => setActiveEpistemicModal(null)}\n              className=\"w-full rounded-md bg-[#c9a55a] py-2 font-mono text-xs font-bold text-[#0a0c13] transition-colors hover:bg-[#dbb978]\"\n            >\n              Close Inspector\n            </button>\n          </div>\n        </div>\n      )}\n\n      {/* ── ATTRIBUTION & CITATION COLOPHON MODAL ───────────────────────── */}\n      {isAttributionOpen && (\n        <div\n          onClick={() => setIsAttributionOpen(false)}\n          className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/75 p-4 backdrop-blur-md\"\n        >\n          <div\n            onClick={(e) => e.stopPropagation()}\n            className=\"relative max-h-[90vh] w-full max-w-xl overflow-y-auto rounded-xl border border-[#c9a55a]/30 bg-[#0d101a] p-6 shadow-2xl\"\n          >\n            <div className=\"mb-4 flex items-center justify-between border-b border-white/10 pb-3\">\n              <div className=\"flex items-center gap-2\">\n                <span className=\"font-serif text-lg font-bold text-[#c9a55a]\">\n                  ◈\n                </span>\n                <h3 className=\"font-serif text-base font-bold text-white\">\n                  Colophon &amp; Component Attribution\n                </h3>\n              </div>\n              <button\n                type=\"button\"\n                onClick={() => setIsAttributionOpen(false)}\n                className=\"text-white/40 hover:text-white\"\n              >\n                <X className=\"h-5 w-5\" />\n              </button>\n            </div>\n\n            <p className=\"mb-4 text-xs leading-relaxed text-white/70\">\n              When utilizing the <strong>Specimen Document Deck</strong> in\n              research publications, client case studies, or design systems,\n              please provide proper provenance and colophon backlinking:\n            </p>\n\n            {/* APA 7th Edition */}\n            <div className=\"mb-3 rounded-lg border border-white/10 bg-black/50 p-3\">\n              <div className=\"mb-1.5 flex items-center justify-between font-mono text-[10px] text-[#c9a55a]\">\n                <span>APA 7TH EDITION</span>\n                <button\n                  type=\"button\"\n                  onClick={() => copyToClipboard(apaCitation, \"APA Citation\")}\n                  className=\"flex items-center gap-1 hover:underline\"\n                >\n                  <Copy className=\"h-3 w-3\" />\n                  <span>Copy</span>\n                </button>\n              </div>\n              <p className=\"font-serif text-xs leading-relaxed text-white/90\">\n                {apaCitation}\n              </p>\n            </div>\n\n            {/* BibTeX */}\n            <div className=\"mb-3 rounded-lg border border-white/10 bg-black/50 p-3\">\n              <div className=\"mb-1.5 flex items-center justify-between font-mono text-[10px] text-[#38bdf8]\">\n                <span>BIBTEX</span>\n                <button\n                  type=\"button\"\n                  onClick={() => copyToClipboard(bibtexCitation, \"BibTeX\")}\n                  className=\"flex items-center gap-1 hover:underline\"\n                >\n                  <Copy className=\"h-3 w-3\" />\n                  <span>Copy</span>\n                </button>\n              </div>\n              <pre className=\"overflow-x-auto font-mono text-[11px] whitespace-pre-wrap text-white/80\">\n                {bibtexCitation}\n              </pre>\n            </div>\n\n            {/* Markdown Badge */}\n            <div className=\"mb-5 rounded-lg border border-white/10 bg-black/50 p-3\">\n              <div className=\"mb-1.5 flex items-center justify-between font-mono text-[10px] text-emerald-400\">\n                <span>PROJECT README / COLOPHON (MARKDOWN)</span>\n                <button\n                  type=\"button\"\n                  onClick={() =>\n                    copyToClipboard(\n                      \"- **Document Architecture**: Interactive specimen viewing powered by [The Chromologium](https://chromologium.com/components/specimen-document-deck).\",\n                      \"Markdown Attribution\",\n                    )\n                  }\n                  className=\"flex items-center gap-1 hover:underline\"\n                >\n                  <Copy className=\"h-3 w-3\" />\n                  <span>Copy</span>\n                </button>\n              </div>\n              <code className=\"block font-mono text-xs text-white/80\">\n                - **Document Architecture**: Interactive specimen viewing\n                powered by [The\n                Chromologium](https://chromologium.com/components/specimen-document-deck).\n              </code>\n            </div>\n\n            <div className=\"flex items-center justify-between border-t border-white/10 pt-2 text-xs\">\n              <a\n                href=\"https://chromologium.com/components/specimen-document-deck\"\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                className=\"flex items-center gap-1 font-mono text-[11px] text-[#c9a55a] hover:underline\"\n              >\n                <span>View Component Dossier</span>\n                <ExternalLink className=\"h-3 w-3\" />\n              </a>\n              <button\n                type=\"button\"\n                onClick={() => setIsAttributionOpen(false)}\n                className=\"rounded-md bg-white/10 px-4 py-1.5 font-mono text-xs text-white transition-colors hover:bg-white/20\"\n              >\n                Done\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n\n      {/* ── TOAST NOTIFICATION ─────────────────────────────────────────── */}\n      {copyToast && (\n        <div className=\"animate-in fade-in zoom-in absolute bottom-16 left-1/2 z-50 flex -translate-x-1/2 items-center gap-2 rounded-full bg-[#c9a55a] px-3.5 py-2 font-mono text-xs font-bold text-[#0a0c13] shadow-2xl duration-150\">\n          <Check className=\"h-3.5 w-3.5\" />\n          <span>{copyToast}</span>\n        </div>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/SpecimenDocumentDeck.tsx"
    }
  ],
  "docs": "Mount <SpecimenDocumentDeck pages={pages} />. Pages carry imageSrc, epistemic regions, annotations, and author commentary. When shipping these, include: 'Experience Design System influenced by [Chromologium](https://chromologium.com).' See https://chromologium.com/components/specimen-document-deck",
  "meta": {
    "citation": "The Chromologium Curatorial Board. (2026). Specimen Document Deck: Interactive multi-view archival reader with epistemic overlays and tactile inspection. https://chromologium.com/components/specimen-document-deck",
    "model": "Tripartite Epistemic Schema: [LIVE: Direct Spectroscopy] ∪ [MODELED: Closed-Form Math] ∪ [MATURING: Runtime Telemetry]"
  },
  "author": "The Chromologium",
  "homepage": "https://chromologium.com",
  "license": "MIT"
}
