diff --git a/frontend/src/app/(pages)/tabular-reviews/page.tsx b/frontend/src/app/(pages)/tabular-reviews/page.tsx index 39776eb..99e88c6 100644 --- a/frontend/src/app/(pages)/tabular-reviews/page.tsx +++ b/frontend/src/app/(pages)/tabular-reviews/page.tsx @@ -23,7 +23,6 @@ import { useAuth } from "@/app/contexts/AuthContext"; import { PageHeader } from "@/app/components/shared/PageHeader"; import { TABLE_CHECKBOX_CLASS, - TABLE_STICKY_CELL_BG, SkeletonDot, SkeletonLine, TableBody, @@ -519,12 +518,10 @@ export default function TabularReviewsPage() { const projectName = review.project_id ? projectNameById.get(review.project_id) : null; - const rowBg = selectedIds.includes(review.id) - ? "bg-gray-50" - : TABLE_STICKY_CELL_BG; return ( ( )}
setIsExpanded(false)} - className={`relative z-10 flex h-4 w-4 items-center justify-center rounded ${ + className={`relative z-10 flex h-4 w-4 items-center justify-center rounded-full ${ !isExpanded ? "text-gray-800" : "text-gray-500 hover:text-gray-700" @@ -132,7 +132,7 @@ export function CitationQuotesHeader({ setIsExpanded(true); setViewMode("single"); }} - className={`relative z-10 flex h-4 w-4 items-center justify-center rounded ${ + className={`relative z-10 flex h-4 w-4 items-center justify-center rounded-full ${ isExpanded && viewMode === "single" ? "text-gray-800" : "text-gray-500 hover:text-gray-700" @@ -148,7 +148,7 @@ export function CitationQuotesHeader({ setIsExpanded(true); setViewMode("list"); }} - className={`relative z-10 flex h-4 w-4 items-center justify-center rounded ${ + className={`relative z-10 flex h-4 w-4 items-center justify-center rounded-full ${ isExpanded && viewMode === "list" ? "text-gray-800" : "text-gray-500 hover:text-gray-700" diff --git a/frontend/src/app/components/assistant/message/EventBlocks.tsx b/frontend/src/app/components/assistant/message/EventBlocks.tsx index 7e4a037..7cc57ae 100644 --- a/frontend/src/app/components/assistant/message/EventBlocks.tsx +++ b/frontend/src/app/components/assistant/message/EventBlocks.tsx @@ -43,7 +43,7 @@ export function EventBlock({ ? "bg-green-400 shadow-[0_1px_3px_rgba(15,23,42,0.15),inset_0_1px_0_rgba(255,255,255,0.5)]" : dotColor === "red" ? "bg-red-400 shadow-[0_1px_3px_rgba(15,23,42,0.15),inset_0_1px_0_rgba(255,255,255,0.5)]" - : "bg-gray-300 shadow-[0_1px_3px_rgba(15,23,42,0.15),inset_0_1px_0_rgba(255,255,255,0.35)]"; + : "bg-gray-500 shadow-[0_1px_3px_rgba(15,23,42,0.15)]"; return (
{showConnector && } diff --git a/frontend/src/app/components/documents/DocTable.tsx b/frontend/src/app/components/documents/DocTable.tsx index b8717c7..050bdb9 100644 --- a/frontend/src/app/components/documents/DocTable.tsx +++ b/frontend/src/app/components/documents/DocTable.tsx @@ -64,6 +64,11 @@ import { } from "@/app/components/projects/ProjectPageParts"; import { DocumentSidePanel } from "@/app/components/shared/DocumentSidePanel"; import { LibrarySkeuoIcon } from "@/app/components/shared/AppSidebarSkeuoIcons"; +import { + APP_SURFACE_ACTIVE_CLASS, + APP_SURFACE_GROUP_HOVER_CLASS, + APP_SURFACE_HOVER_CLASS, +} from "@/app/components/ui/liquid-surface"; import { TABLE_CHECKBOX_CLASS, TableFilters, @@ -271,9 +276,6 @@ export function DocTable({ const [addDocsOpen, setAddDocsOpen] = useState(false); const { user } = useAuth(); const stickyCellBg = "bg-app-surface"; - const activeRowBg = "bg-app-surface-active"; - const surfaceHoverBg = "hover:bg-app-surface-hover"; - const surfaceGroupHoverBg = "group-hover:bg-app-surface-hover"; const [viewingDoc, setViewingDoc] = useState(null); const [viewingDocVersion, setViewingDocVersion] = useState<{ id: string; @@ -1434,6 +1436,7 @@ export function DocTable({ const isUploadingVersion = uploadingVersionDocIds.has( doc.id, ); + const isSelected = selectedDocIds.includes(doc.id); const isDeletingDoc = deletingDocIds.has(doc.id); if (isDeletingDoc) { return renderDocumentActivityRow({ @@ -1447,6 +1450,7 @@ export function DocTable({ return (
{ if (renamingDocumentId === doc.id) { @@ -1487,18 +1491,18 @@ export function DocTable({ showFolderActions: false, }); }} - className={`group flex h-10 min-w-max items-center pr-8 ${surfaceHoverBg} cursor-pointer transition-colors ${isVersionDragOver ? "bg-blue-50 ring-1 ring-inset ring-blue-200" : ""}`} + className={`group flex h-10 min-w-max items-center pr-8 cursor-pointer transition-colors ${isVersionDragOver ? "bg-blue-50 ring-1 ring-inset ring-blue-200" : isSelected ? APP_SURFACE_ACTIVE_CLASS : APP_SURFACE_HOVER_CLASS}`} > {(() => { const rowBg = isVersionDragOver ? "bg-blue-50" - : selectedDocIds.includes(doc.id) - ? activeRowBg + : isSelected + ? APP_SURFACE_ACTIVE_CLASS : stickyCellBg; return ( <>
@@ -1632,7 +1636,7 @@ export function DocTable({ doc.id, ) } - className="flex items-center gap-1 rounded px-1 py-0.5 hover:bg-app-surface-hover transition-colors" + className={`flex items-center gap-1 rounded px-1 py-0.5 transition-colors ${APP_SURFACE_HOVER_CLASS}`} > {versionNumber} @@ -1815,10 +1819,10 @@ export function DocTable({ showFolderActions: true, }); }} - className={`group flex h-10 min-w-max items-center pr-8 ${surfaceHoverBg} cursor-pointer transition-colors ${isRenaming ? "" : "select-none"} ${dragOverFolderId === folder.id ? "bg-blue-50 ring-1 ring-inset ring-blue-200" : ""}`} + className={`group flex h-10 min-w-max items-center pr-8 ${APP_SURFACE_HOVER_CLASS} cursor-pointer transition-colors ${isRenaming ? "" : "select-none"} ${dragOverFolderId === folder.id ? "bg-blue-50 ring-1 ring-inset ring-blue-200" : ""}`} >
@@ -2557,6 +2561,10 @@ export function DocTable({ uploadingVersionDocIds.has( doc.id, ); + const isSelected = + selectedDocIds.includes( + doc.id, + ); const isDeletingDoc = deletingDocIds.has( doc.id, @@ -2578,6 +2586,7 @@ export function DocTable({ return (
{isProcessing || @@ -2806,7 +2815,7 @@ export function DocTable({ doc.id, ) } - className="flex items-center gap-1 rounded px-1 py-0.5 hover:bg-app-surface-hover transition-colors" + className={`flex items-center gap-1 rounded px-1 py-0.5 transition-colors ${APP_SURFACE_HOVER_CLASS}`} > { diff --git a/frontend/src/app/components/modals/ProjectPickerModal.tsx b/frontend/src/app/components/modals/ProjectPickerModal.tsx index a8d629b..4ef73cb 100644 --- a/frontend/src/app/components/modals/ProjectPickerModal.tsx +++ b/frontend/src/app/components/modals/ProjectPickerModal.tsx @@ -5,6 +5,10 @@ import { SearchBar } from "@/app/components/ui/search-bar"; import { ClosedProjectSvgIcon } from "@/app/components/shared/FolderSvgIcon"; import type { Project } from "../shared/types"; import { Modal } from "./Modal"; +import { + APP_SURFACE_ACTIVE_CLASS, + APP_SURFACE_HOVER_CLASS, +} from "@/app/components/ui/liquid-surface"; type PrimaryAction = Omit< ButtonHTMLAttributes, @@ -101,7 +105,7 @@ export function ProjectPickerModal({ isSelected ? null : project.id, ) } - className={`w-full flex rounded-md items-center gap-2 px-2 py-2 text-xs transition-all text-left ${isSelected ? "bg-gray-100" : "hover:bg-gray-100/70"}`} + className={`w-full flex rounded-md items-center gap-2 px-2 py-2 text-xs transition-all text-left ${isSelected ? APP_SURFACE_ACTIVE_CLASS : APP_SURFACE_HOVER_CLASS}`} > ( ( setSelectedChatIds((prev) => diff --git a/frontend/src/app/components/projects/ProjectDocumentsView.tsx b/frontend/src/app/components/projects/ProjectDocumentsView.tsx index fbd780c..0e53bf0 100644 --- a/frontend/src/app/components/projects/ProjectDocumentsView.tsx +++ b/frontend/src/app/components/projects/ProjectDocumentsView.tsx @@ -29,6 +29,7 @@ import { } from "@/app/components/documents/DocTable"; import { TabPillButton } from "@/app/components/ui/tab-pill-button"; import { ProjectSectionToolbar, useProjectWorkspace } from "./ProjectWorkspace"; +import { APP_SURFACE_HOVER_CLASS } from "@/app/components/ui/liquid-surface"; interface Props { projectId: string; @@ -139,7 +140,7 @@ export function ProjectDocumentsView({ projectId }: Props) { setActionsOpen(false); void selectionActions.onDownload(); }} - className="w-full px-3 py-1.5 text-left text-xs text-gray-600 transition-colors hover:bg-app-surface-hover" + className={`w-full px-3 py-1.5 text-left text-xs text-gray-600 transition-colors ${APP_SURFACE_HOVER_CLASS}`} > Download @@ -149,7 +150,7 @@ export function ProjectDocumentsView({ projectId }: Props) { setActionsOpen(false); void selectionActions.onRemoveFromFolder(); }} - className="w-full px-3 py-1.5 text-left text-xs text-gray-600 transition-colors hover:bg-app-surface-hover" + className={`w-full px-3 py-1.5 text-left text-xs text-gray-600 transition-colors ${APP_SURFACE_HOVER_CLASS}`} > Remove from subfolder diff --git a/frontend/src/app/components/projects/ProjectReviewsTable.tsx b/frontend/src/app/components/projects/ProjectReviewsTable.tsx index b8b2f9a..3f08db5 100644 --- a/frontend/src/app/components/projects/ProjectReviewsTable.tsx +++ b/frontend/src/app/components/projects/ProjectReviewsTable.tsx @@ -8,7 +8,6 @@ import { } from "@/app/components/shared/RowActions"; import { TABLE_CHECKBOX_CLASS, - TABLE_STICKY_CELL_BG, SkeletonDot, SkeletonLine, TableBody, @@ -255,6 +254,7 @@ export function ProjectReviewsTable({ {visibleReviews.map((review) => ( ( setSelectedReviewIds((prev) => diff --git a/frontend/src/app/components/projects/ProjectsOverview.tsx b/frontend/src/app/components/projects/ProjectsOverview.tsx index 31e93d3..d5fb3bd 100644 --- a/frontend/src/app/components/projects/ProjectsOverview.tsx +++ b/frontend/src/app/components/projects/ProjectsOverview.tsx @@ -25,7 +25,6 @@ import { } from "@/app/components/shared/FolderSvgIcon"; import { TABLE_CHECKBOX_CLASS, - TABLE_STICKY_CELL_BG, SkeletonDot, SkeletonLine, TableBody, @@ -660,12 +659,10 @@ export function ProjectsOverview() { ) : ( {filtered.map((project) => { - const rowBg = selectedIds.includes(project.id) - ? "bg-gray-50" - : TABLE_STICKY_CELL_BG; return ( {/* Project Name */} toggleOne(project.id) diff --git a/frontend/src/app/components/shared/AppSidebar.tsx b/frontend/src/app/components/shared/AppSidebar.tsx index 834fd18..ec46d29 100644 --- a/frontend/src/app/components/shared/AppSidebar.tsx +++ b/frontend/src/app/components/shared/AppSidebar.tsx @@ -27,6 +27,10 @@ import { import { listProjects } from "@/app/lib/mikeApi"; import type { Project } from "@/app/components/shared/types"; import { cn } from "@/app/lib/utils"; +import { + APP_SURFACE_ACTIVE_CLASS, + APP_SURFACE_HOVER_CLASS, +} from "@/app/components/ui/liquid-surface"; const NAV_ITEMS = [ { href: "/assistant", label: "Assistant", icon: ChatSkeuoIcon }, @@ -176,7 +180,8 @@ export function AppSidebar({ isOpen, onToggle }: AppSidebarProps) { onClick={handleToggle} className={cn( "h-9 w-9 p-2.5 items-center flex transition-colors", - "rounded-md hover:bg-gray-100", + "rounded-md", + APP_SURFACE_HOVER_CLASS, )} title={isOpen ? "Close sidebar" : "Open sidebar"} > @@ -201,8 +206,8 @@ export function AppSidebar({ isOpen, onToggle }: AppSidebarProps) { className={cn( "w-full h-9 flex items-center gap-3 px-2.5 py-2 rounded-md transition-colors text-left", isActive - ? "bg-app-surface-active text-gray-900" - : "text-gray-700 hover:bg-gray-100", + ? `${APP_SURFACE_ACTIVE_CLASS} text-gray-900` + : `text-gray-700 ${APP_SURFACE_HOVER_CLASS}`, !isOpen ? "hidden md:flex" : "flex", )} > @@ -301,8 +306,8 @@ export function AppSidebar({ isOpen, onToggle }: AppSidebarProps) { className={cn( "flex h-8 w-full items-center gap-2 rounded-md px-2.5 py-1 text-left text-xs transition-colors", isActive - ? "bg-app-surface-active text-gray-900" - : "text-gray-700 hover:bg-gray-100", + ? `${APP_SURFACE_ACTIVE_CLASS} text-gray-900` + : `text-gray-700 ${APP_SURFACE_HOVER_CLASS}`, )} > Load more @@ -436,8 +441,8 @@ export function AppSidebar({ isOpen, onToggle }: AppSidebarProps) { "rounded-xl border-white/60", !isOpen ? "hidden md:flex" : "", pathname === "/account" || isDropdownOpen - ? "bg-app-surface-active" - : "hover:bg-gray-100", + ? APP_SURFACE_ACTIVE_CLASS + : APP_SURFACE_HOVER_CLASS, )} title={!isOpen ? user.email : undefined} > diff --git a/frontend/src/app/components/shared/DocumentSidePanel.tsx b/frontend/src/app/components/shared/DocumentSidePanel.tsx index c971b71..68ea4c0 100644 --- a/frontend/src/app/components/shared/DocumentSidePanel.tsx +++ b/frontend/src/app/components/shared/DocumentSidePanel.tsx @@ -6,6 +6,7 @@ import { AlertCircle, Check, Download, + Eye, Loader2, Pencil, Trash2, @@ -164,6 +165,56 @@ export function DocumentSidePanel({ setMobilePane("document"); }, [doc?.id, versionId, currentVersionId]); + useEffect(() => { + if (!mounted || !doc) return; + + const handleOutsidePointerDown = (event: PointerEvent) => { + const target = event.target; + if ( + !(target instanceof Node) || + panelRef.current?.contains(target) + ) { + return; + } + + if ( + event + .composedPath() + .some( + (node) => + node instanceof HTMLElement && + node.hasAttribute("data-document-row"), + ) + ) { + return; + } + + if ( + extensionWarningOpen || + replaceConfirmOpen || + confirmDeleteDocumentOpen + ) { + return; + } + + onClose(); + }; + + document.addEventListener("pointerdown", handleOutsidePointerDown); + return () => + document.removeEventListener( + "pointerdown", + handleOutsidePointerDown, + ); + }, [ + confirmDeleteDocumentOpen, + doc, + extensionWarningOpen, + mounted, + onClose, + replaceConfirmOpen, + ]); + if (!mounted || !doc) return null; const activeDoc = doc; @@ -517,357 +568,337 @@ export function DocumentSidePanel({