refactor: wrap splash screen content in a card for improved layout and consistency

This commit is contained in:
Shine1i 2026-02-17 21:08:45 +01:00
commit 9c353f7bc2
8 changed files with 99 additions and 60 deletions

View file

@ -1,4 +1,5 @@
import { LightRays } from "@/components/ui/light-rays";
import { Card } from "@/components/ui/card";
import { AuthForm } from "./components/auth-form";
export function LoginPage() {
@ -12,9 +13,9 @@ export function LoginPage() {
length="70vh"
style={{ opacity: 0.4 }}
/>
<div className="relative z-10 w-full max-w-sm">
<Card className="relative z-10 w-full max-w-sm px-6 py-8 shadow-border ring-1 ring-border">
<AuthForm mode="login" />
</div>
</Card>
</div>
);
}

View file

@ -1,4 +1,5 @@
import { LightRays } from "@/components/ui/light-rays";
import { Card } from "@/components/ui/card";
import { AuthForm } from "./components/auth-form";
export function SignupPage() {
@ -12,9 +13,9 @@ export function SignupPage() {
length="70vh"
style={{ opacity: 0.4 }}
/>
<div className="relative z-10 w-full max-w-sm">
<Card className="relative z-10 w-full max-w-sm px-6 py-8 shadow-border ring-1 ring-border">
<AuthForm mode="signup" />
</div>
</Card>
</div>
);
}

View file

@ -278,7 +278,7 @@ export function ExportPage() {
<div className="grid grid-cols-2 gap-8">
<div className="flex flex-col gap-4">
{/* Training run dropdown */}
<div className="flex flex-col gap-2">
<div data-tour="export-training-run" className="flex flex-col gap-2">
<label className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
Training Run
<Tooltip>
@ -344,7 +344,7 @@ export function ExportPage() {
</div>
{/* Checkpoint dropdown */}
<div className="flex flex-col gap-2">
<div data-tour="export-checkpoint" className="flex flex-col gap-2">
<label className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
Checkpoint
<Tooltip>
@ -378,7 +378,7 @@ export function ExportPage() {
onValueChange={setCheckpoint}
disabled={!selectedModelIdx}
>
<SelectTrigger data-tour="export-checkpoint" className="w-full">
<SelectTrigger className="w-full">
<SelectValue
placeholder={
!selectedModelIdx

View file

@ -1,6 +1,17 @@
import type { TourStep } from "@/features/tour";
export const exportTourSteps: TourStep[] = [
{
id: "training-run",
target: "export-training-run",
title: "Pick training run",
body: (
<>
Start by selecting the training run. Each run groups the checkpoints
produced by that specific fine-tuning job.
</>
),
},
{
id: "checkpoint",
target: "export-checkpoint",

View file

@ -1,4 +1,5 @@
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { motion } from "motion/react";
interface SplashScreenProps {
@ -11,57 +12,61 @@ export function SplashScreen({
onGoToStudio,
}: SplashScreenProps) {
return (
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-gradient-to-b from-background via-background to-primary/5">
{/* Mascot */}
<motion.img
src="/Sloth emojis/Sloth loca pc.png"
alt="Sloth mascot"
className="size-30"
initial={{ opacity: 0, y: 40, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{
type: "spring",
duration: 0.7,
bounce: 0.3,
delay: 0.1,
}}
/>
<div className="fixed inset-0 z-50 flex items-center justify-center bg-gradient-to-b from-background via-background to-primary/5 p-6">
<Card className="w-full max-w-md px-8 py-8 shadow-border ring-1 ring-border">
{/* Mascot */}
<div className="flex justify-center">
<motion.img
src="/Sloth emojis/Sloth loca pc.png"
alt="Sloth mascot"
className="size-30"
initial={{ opacity: 0, y: 40, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{
type: "spring",
duration: 0.7,
bounce: 0.3,
delay: 0.1,
}}
/>
</div>
{/* Brand text */}
<motion.div
className="flex flex-col items-center gap-1 mt-4"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.4,
ease: [0.165, 0.84, 0.44, 1],
delay: 0.4,
}}
>
<h1 className="text-2xl font-semibold tracking-tight">
Unsloth Studio
</h1>
<p className="text-sm text-muted-foreground">Fine-tune LLMs faster</p>
</motion.div>
{/* Brand text */}
<motion.div
className="mt-4 flex flex-col items-center gap-1"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.4,
ease: [0.165, 0.84, 0.44, 1],
delay: 0.4,
}}
>
<h1 className="text-2xl font-semibold tracking-tight">
Unsloth Studio
</h1>
<p className="text-sm text-muted-foreground">Fine-tune LLMs faster</p>
</motion.div>
{/* Buttons */}
<motion.div
className="flex flex-col gap-3 mt-8"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.4,
ease: [0.165, 0.84, 0.44, 1],
delay: 0.8,
}}
>
<Button size="lg" onClick={onStartOnboarding}>
Start Onboarding
</Button>
<Button size="lg" variant="outline" onClick={onGoToStudio}>
Skip Onboarding
</Button>
</motion.div>
{/* Buttons */}
<motion.div
className="mt-8 flex flex-col gap-3"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.4,
ease: [0.165, 0.84, 0.44, 1],
delay: 0.8,
}}
>
<Button size="lg" onClick={onStartOnboarding}>
Start Onboarding
</Button>
<Button size="lg" variant="outline" onClick={onGoToStudio}>
Skip Onboarding
</Button>
</motion.div>
</Card>
</div>
);
}

View file

@ -81,7 +81,7 @@ export function WizardLayout() {
ease: [0.165, 0.84, 0.44, 1],
}}
>
<Card className="relative z-10 w-full !gap-0 h-[640px] flex flex-row overflow-hidden !p-0 !m-0 shadow-border ring-1 ring-border">
<Card className="relative z-10 h-[660px] w-full !gap-0 !m-0 !p-0 flex flex-row overflow-hidden shadow-border ring-1 ring-border">
<WizardSidebar />
<div className="flex-1 flex flex-col">
<WizardContent />

View file

@ -1,4 +1,5 @@
import { Button } from "@/components/ui/button";
import { LightRays } from "@/components/ui/light-rays";
import {
shouldShowTrainingView,
useDatasetPreviewDialogStore,
@ -62,8 +63,16 @@ export function StudioPage(): ReactElement {
}, [selectedModel, ensureModelDefaultsLoaded]);
return (
<div className="min-h-screen bg-background">
<main className="mx-auto max-w-7xl px-6 py-4">
<div className="relative min-h-screen overflow-hidden bg-background">
<LightRays
count={6}
color="rgba(34, 197, 94, 0.14)"
blur={30}
speed={18}
length="62vh"
style={{ opacity: 0.45 }}
/>
<main className="relative z-10 mx-auto max-w-7xl px-6 py-4">
<GuidedTour {...tour.tourProps} celebrate={isConfigTour} />
<DatasetPreviewDialog

View file

@ -1,4 +1,5 @@
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";
@ -30,8 +31,19 @@ export function TrainingView(): ReactElement {
return (
<div className={cn("relative", showOverlay && "min-h-[72vh]")}>
<LightRays
count={4}
color="rgba(16, 185, 129, 0.13)"
blur={28}
speed={20}
length="52vh"
style={{ opacity: 0.35 }}
/>
<div
className={cn("flex flex-col gap-6 transition-[filter]", showOverlay && "blur")}
className={cn(
"relative z-10 flex flex-col gap-6 transition-[filter]",
showOverlay && "blur",
)}
>
<div data-tour="studio-training-progress">
<ProgressSection />