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 (