diff --git a/studio/frontend/bun.lock b/studio/frontend/bun.lock index b4c447145a..5b9c526480 100644 --- a/studio/frontend/bun.lock +++ b/studio/frontend/bun.lock @@ -43,7 +43,7 @@ "dexie": "^4.3.0", "framer-motion": "^11.18.2", "katex": "^0.16.28", - "lucide-react": "^0.563.0", + "lucide-react": "^0.575.0", "mammoth": "^1.11.0", "motion": "^12.34.0", "next": "^16.1.6", @@ -1451,7 +1451,7 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "lucide-react": ["lucide-react@0.563.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA=="], + "lucide-react": ["lucide-react@0.575.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], diff --git a/studio/frontend/package.json b/studio/frontend/package.json index 4b9f8350bb..b4f1dea296 100644 --- a/studio/frontend/package.json +++ b/studio/frontend/package.json @@ -51,7 +51,7 @@ "dexie": "^4.3.0", "framer-motion": "^11.18.2", "katex": "^0.16.28", - "lucide-react": "^0.563.0", + "lucide-react": "^0.575.0", "mammoth": "^1.11.0", "motion": "^12.34.0", "next": "^16.1.6", diff --git a/studio/frontend/public/blacklogo.png b/studio/frontend/public/blacklogo.png new file mode 100644 index 0000000000..df95e02291 Binary files /dev/null and b/studio/frontend/public/blacklogo.png differ diff --git a/studio/frontend/public/whitelogo.png b/studio/frontend/public/whitelogo.png new file mode 100644 index 0000000000..5a3bc56354 Binary files /dev/null and b/studio/frontend/public/whitelogo.png differ diff --git a/studio/frontend/src/components/navbar.tsx b/studio/frontend/src/components/navbar.tsx index 82f89ed995..7b741dffa9 100644 --- a/studio/frontend/src/components/navbar.tsx +++ b/studio/frontend/src/components/navbar.tsx @@ -3,6 +3,7 @@ import { HoverCardContent, HoverCardTrigger, } from "@/components/ui/hover-card"; +import { AnimatedThemeToggler } from "@/components/ui/animated-theme-toggler"; import { Sheet, SheetContent, @@ -160,6 +161,11 @@ export function Navbar() { {/* Right: docs/tour desktop */}
+ { + duration?: number +} + +export const AnimatedThemeToggler = ({ + className, + duration = 400, + ...props +}: AnimatedThemeTogglerProps) => { + const [isDark, setIsDark] = useState(false) + const buttonRef = useRef(null) + + useEffect(() => { + const updateTheme = () => { + setIsDark(document.documentElement.classList.contains("dark")) + } + + updateTheme() + + const observer = new MutationObserver(updateTheme) + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"], + }) + + return () => observer.disconnect() + }, []) + + const toggleTheme = useCallback(async () => { + if (!buttonRef.current) return + + await document.startViewTransition(() => { + flushSync(() => { + const newTheme = !isDark + setIsDark(newTheme) + document.documentElement.classList.toggle("dark") + localStorage.setItem("theme", newTheme ? "dark" : "light") + }) + }).ready + + const { top, left, width, height } = + buttonRef.current.getBoundingClientRect() + const x = left + width / 2 + const y = top + height / 2 + const maxRadius = Math.hypot( + Math.max(left, window.innerWidth - left), + Math.max(top, window.innerHeight - top) + ) + + document.documentElement.animate( + { + clipPath: [ + `circle(0px at ${x}px ${y}px)`, + `circle(${maxRadius}px at ${x}px ${y}px)`, + ], + }, + { + duration, + easing: "ease-in-out", + pseudoElement: "::view-transition-new(root)", + } + ) + }, [isDark, duration]) + + return ( + + ) +} diff --git a/studio/frontend/src/features/studio/studio-page.tsx b/studio/frontend/src/features/studio/studio-page.tsx index 26353b9b7e..0c8904f8df 100644 --- a/studio/frontend/src/features/studio/studio-page.tsx +++ b/studio/frontend/src/features/studio/studio-page.tsx @@ -1,5 +1,4 @@ import { Button } from "@/components/ui/button"; -import { LightRays } from "@/components/ui/light-rays"; import { shouldShowTrainingView, useDatasetPreviewDialogStore, @@ -73,14 +72,6 @@ export function StudioPage(): ReactElement { return (
-
diff --git a/studio/frontend/src/features/studio/training-view.tsx b/studio/frontend/src/features/studio/training-view.tsx index fe616ea88a..368d0b6ed0 100644 --- a/studio/frontend/src/features/studio/training-view.tsx +++ b/studio/frontend/src/features/studio/training-view.tsx @@ -1,5 +1,4 @@ import { cn } from "@/lib/utils"; -import { LightRays } from "@/components/ui/light-rays"; import { useTrainingRuntimeStore } from "@/features/training"; import type { ReactElement } from "react"; import { useShallow } from "zustand/react/shallow"; @@ -33,14 +32,6 @@ export function TrainingView(): ReactElement { return (
-