diff --git a/studio/frontend/src/components/navbar.tsx b/studio/frontend/src/components/navbar.tsx index aee6105cf3..9b9cdf557e 100644 --- a/studio/frontend/src/components/navbar.tsx +++ b/studio/frontend/src/components/navbar.tsx @@ -29,7 +29,7 @@ export function Navbar() { const [logoHovered, setLogoHovered] = useState(false); return ( -
+
{/* Left: logo */}
{ + /** + * Width of the border in pixels + * @default 1 + */ + borderWidth?: number + /** + * Duration of the animation in seconds + * @default 14 + */ + duration?: number + /** + * Color of the border, can be a single color or an array of colors + * @default "#000000" + */ + shineColor?: string | string[] +} + +/** + * Shine Border + * + * An animated background border effect component with configurable properties. + */ +export function ShineBorder({ + borderWidth = 1, + duration = 14, + shineColor = "#000000", + className, + style, + ...props +}: ShineBorderProps) { + return ( +
+ ) +} diff --git a/studio/frontend/src/features/studio/sections/model-section.tsx b/studio/frontend/src/features/studio/sections/model-section.tsx index b21d433fb0..a2d58ad066 100644 --- a/studio/frontend/src/features/studio/sections/model-section.tsx +++ b/studio/frontend/src/features/studio/sections/model-section.tsx @@ -140,9 +140,9 @@ export function ModelSection() { className="shadow-border ring-1 ring-border" >
-
- - Local Model +
+ + Local Model
-
+
Base Model @@ -272,7 +272,7 @@ export function ModelSection() {
-
+
Method diff --git a/studio/frontend/src/features/studio/studio-page.tsx b/studio/frontend/src/features/studio/studio-page.tsx index 61654f4954..1a6d0ace85 100644 --- a/studio/frontend/src/features/studio/studio-page.tsx +++ b/studio/frontend/src/features/studio/studio-page.tsx @@ -33,22 +33,34 @@ export function StudioPage(): ReactElement { const tourSteps = useMemo( () => [ { - id: "header", - target: "studio-header", - title: "This page is a pipeline", - body: "Pick a base model, attach data, tune params, then launch training. We’ll hit the 5 things that matter.", + id: "nav", + target: "navbar", + title: "Quick orientation", + body: "Studio is where you fine-tune. Export ships results. Chat is for poking at models. This tour is Studio-only (for now).", }, { - id: "model", - target: "studio-model", - title: "Choose model + method", - body: "Base model sets your ceiling. Method sets speed vs quality. Start here, then everything else follows.", + id: "local-model", + target: "studio-local-model", + title: "Local model path", + body: "Point to a local folder (`./models/...`) or a custom HF repo. Use this when you already downloaded weights.", + }, + { + id: "base-model", + target: "studio-base-model", + title: "Base model from Hugging Face", + body: "Search Hub here. Paste `org/model` too. Pick something close to your target domain to save compute.", + }, + { + id: "method", + target: "studio-method", + title: "Method: QLoRA vs LoRA vs Full", + body: "QLoRA: lowest VRAM (4-bit). LoRA: fast + solid (16-bit adapters). Full: slowest, highest cost, updates all weights.", }, { id: "dataset", target: "studio-dataset", - title: "Bring a dataset", - body: "Search Hub or paste `user/dataset`. Preview a few rows before you commit hours of compute.", + title: "Dataset", + body: "Search Hub or paste `user/dataset`. Preview a few rows before you burn hours of compute.", }, { id: "params", @@ -102,7 +114,7 @@ export function StudioPage(): ReactElement { )} {/* Header */} -
+

Fine-tuning Studio

diff --git a/studio/frontend/src/features/tour/guided-tour.tsx b/studio/frontend/src/features/tour/guided-tour.tsx index 6fabe80d26..d94185e5f6 100644 --- a/studio/frontend/src/features/tour/guided-tour.tsx +++ b/studio/frontend/src/features/tour/guided-tour.tsx @@ -1,4 +1,5 @@ import { Button } from "@/components/ui/button"; +import { ShineBorder } from "@/components/ui/shine-border"; import { cn } from "@/lib/utils"; import { HugeiconsIcon } from "@hugeicons/react"; import { @@ -313,16 +314,25 @@ export function GuidedTour({ transition={{ duration: 0.22, ease: [0.165, 0.84, 0.44, 1] }} className={cn( "relative overflow-hidden rounded-[28px] corner-squircle", - "bg-[#0b0f16]/95 text-white ring-1 ring-white/10", - "shadow-[0_30px_120px_rgba(0,0,0,0.65)]", + "bg-white/95 text-foreground ring-1 ring-black/10", + "shadow-[0_30px_120px_rgba(0,0,0,0.35)]", )} style={{ fontFamily: "'Figtree Variable', ui-sans-serif, sans-serif", }} > +
-
-
+
+
-
+
{idx + 1}/{total} - + guided tour
{step?.title ?? "Quick tour"} - + {step?.body ?? "Let’s get you oriented."}
@@ -360,7 +370,7 @@ export function GuidedTour({
-
-
+
+
Tip: `Esc` skips. Tour blocks clicks so you can read.
diff --git a/studio/frontend/src/index.css b/studio/frontend/src/index.css index df14df684a..f8b445a1b2 100644 --- a/studio/frontend/src/index.css +++ b/studio/frontend/src/index.css @@ -242,6 +242,18 @@ background-position: calc(100% + var(--shiny-width)) 0; } } + --animate-shine: shine var(--duration) infinite linear; + @keyframes shine { + 0% { + background-position: 0% 0%; + } + 50% { + background-position: 100% 100%; + } + 100% { + background-position: 0% 0%; + } + } } @layer base {