Merge pull request #141 from unslothai/feature/uxui-heuristics
style: improve layout consistency and responsiveness across components
This commit is contained in:
commit
43fac18d40
14 changed files with 163 additions and 47 deletions
|
|
@ -112,7 +112,10 @@ function ModelSelectorContent({
|
|||
<PopoverContent
|
||||
align="start"
|
||||
data-tour={dataTour}
|
||||
className={cn("w-[440px] min-w-[440px] gap-0 p-2", className)}
|
||||
className={cn(
|
||||
"w-[min(440px,calc(100vw-1rem))] max-w-[calc(100vw-1rem)] min-w-0 gap-0 p-2",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Tabs defaultValue="hub" className="w-full">
|
||||
<TabsList className="mb-2 w-full">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,13 @@ import {
|
|||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from "@/components/ui/hover-card";
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
AiChat02Icon,
|
||||
|
|
@ -29,6 +36,7 @@ const NAV_ITEMS = [
|
|||
export function Navbar() {
|
||||
const pathname = useRouterState({ select: (s) => s.location.pathname });
|
||||
const [logoHovered, setLogoHovered] = useState(false);
|
||||
const [mobileOpen, setMobileOpen] = useState(false);
|
||||
|
||||
const tourId =
|
||||
pathname === "/studio"
|
||||
|
|
@ -39,9 +47,16 @@ export function Navbar() {
|
|||
? "export"
|
||||
: null;
|
||||
|
||||
const openTour = () => {
|
||||
if (!tourId) return;
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(TOUR_OPEN_EVENT, { detail: { id: tourId } }),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="top-0 z-40 h-16 w-full">
|
||||
<div className="mx-auto flex h-full max-w-7xl items-center justify-between px-6">
|
||||
<div className="mx-auto flex h-full max-w-7xl items-center justify-between px-4 sm:px-6">
|
||||
{/* Left: logo */}
|
||||
<div
|
||||
className="relative flex items-center gap-2.5 cursor-pointer select-none"
|
||||
|
|
@ -55,7 +70,7 @@ export function Navbar() {
|
|||
animate={{ rotate: logoHovered ? 360 : 0 }}
|
||||
transition={{ duration: 0.5, ease: [0.165, 0.84, 0.44, 1] }}
|
||||
/>
|
||||
<span className="text-2xl font-bold tracking-wide font-heading">
|
||||
<span className="text-xl font-bold tracking-wide font-heading sm:text-2xl">
|
||||
unsloth
|
||||
</span>
|
||||
<AnimatePresence>
|
||||
|
|
@ -76,7 +91,7 @@ export function Navbar() {
|
|||
{/* Center: pill nav */}
|
||||
<nav
|
||||
data-tour="navbar"
|
||||
className="flex items-center rounded-full border border-border bg-card p-1 ring-1 ring-foreground/5"
|
||||
className="hidden items-center rounded-full border border-border bg-card p-1 ring-1 ring-foreground/5 md:flex"
|
||||
>
|
||||
{NAV_ITEMS.map((item) => {
|
||||
const active = pathname === item.href;
|
||||
|
|
@ -138,8 +153,8 @@ export function Navbar() {
|
|||
})}
|
||||
</nav>
|
||||
|
||||
{/* Right: docs link */}
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Right: docs/tour desktop */}
|
||||
<div className="hidden items-center gap-2 md:flex">
|
||||
<HoverCard openDelay={200} closeDelay={100}>
|
||||
<HoverCardTrigger asChild={true}>
|
||||
<a
|
||||
|
|
@ -177,11 +192,7 @@ export function Navbar() {
|
|||
{tourId ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(TOUR_OPEN_EVENT, { detail: { id: tourId } }),
|
||||
);
|
||||
}}
|
||||
onClick={openTour}
|
||||
className="flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
|
||||
title="Tour"
|
||||
>
|
||||
|
|
@ -189,6 +200,77 @@ export function Navbar() {
|
|||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Right: mobile */}
|
||||
<div className="flex items-center gap-2 md:hidden">
|
||||
{tourId ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={openTour}
|
||||
className="flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"
|
||||
title="Tour"
|
||||
>
|
||||
<HugeiconsIcon icon={CursorInfo02Icon} className="size-4" />
|
||||
</button>
|
||||
) : null}
|
||||
<Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
|
||||
<SheetTrigger asChild={true}>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-md border border-border px-3 py-1.5 text-sm font-medium text-foreground"
|
||||
aria-label="Open navigation menu"
|
||||
>
|
||||
Menu
|
||||
</button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right" className="w-[300px] p-4">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Navigate</SheetTitle>
|
||||
</SheetHeader>
|
||||
<div className="mt-6 flex flex-col gap-2">
|
||||
{NAV_ITEMS.filter((item) => item.enabled).map((item) => {
|
||||
const active = pathname === item.href;
|
||||
return (
|
||||
<Link
|
||||
key={item.href}
|
||||
to={item.href}
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={cn(
|
||||
"rounded-md border px-3 py-2 text-sm font-medium",
|
||||
active
|
||||
? "border-foreground bg-foreground text-background"
|
||||
: "border-border text-foreground hover:bg-accent",
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
<a
|
||||
href="https://unsloth.ai/docs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground hover:bg-accent"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
>
|
||||
Learn more (Docs)
|
||||
</a>
|
||||
{tourId ? (
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-md border border-border px-3 py-2 text-left text-sm font-medium text-foreground hover:bg-accent"
|
||||
onClick={() => {
|
||||
openTour();
|
||||
setMobileOpen(false);
|
||||
}}
|
||||
>
|
||||
Start tour
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { AuthForm } from "./components/auth-form";
|
|||
|
||||
export function LoginPage() {
|
||||
return (
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-background px-6 py-10 md:px-10">
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-background px-4 py-8 sm:px-6 sm:py-10 md:px-10">
|
||||
<LightRays
|
||||
count={6}
|
||||
color="rgba(34, 197, 94, 0.25)"
|
||||
|
|
@ -13,7 +13,7 @@ export function LoginPage() {
|
|||
length="70vh"
|
||||
style={{ opacity: 0.4 }}
|
||||
/>
|
||||
<Card className="relative z-10 w-full max-w-sm px-6 py-8 shadow-border ring-1 ring-border">
|
||||
<Card className="relative z-10 w-full max-w-sm px-5 py-6 shadow-border ring-1 ring-border sm:px-6 sm:py-8">
|
||||
<AuthForm mode="login" />
|
||||
</Card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { AuthForm } from "./components/auth-form";
|
|||
|
||||
export function SignupPage() {
|
||||
return (
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-background px-6 py-10 md:px-10">
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-background px-4 py-8 sm:px-6 sm:py-10 md:px-10">
|
||||
<LightRays
|
||||
count={6}
|
||||
color="rgba(34, 197, 94, 0.25)"
|
||||
|
|
@ -13,7 +13,7 @@ export function SignupPage() {
|
|||
length="70vh"
|
||||
style={{ opacity: 0.4 }}
|
||||
/>
|
||||
<Card className="relative z-10 w-full max-w-sm px-6 py-8 shadow-border ring-1 ring-border">
|
||||
<Card className="relative z-10 w-full max-w-sm px-5 py-6 shadow-border ring-1 ring-border sm:px-6 sm:py-8">
|
||||
<AuthForm mode="signup" />
|
||||
</Card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ import {
|
|||
import { Thread } from "@/components/assistant-ui/thread";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { SidebarProvider, SidebarTrigger, useSidebar } from "@/components/ui/sidebar";
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
} from "@/components/ui/sheet";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
|
|
@ -127,7 +134,10 @@ const CompareContent = memo(function CompareContent({
|
|||
return (
|
||||
<CompareHandlesProvider handlesRef={handlesRef}>
|
||||
<div className="flex min-h-0 flex-1 flex-col">
|
||||
<div data-tour="chat-compare-view" className="grid min-h-0 flex-1 grid-cols-2 px-0">
|
||||
<div
|
||||
data-tour="chat-compare-view"
|
||||
className="grid min-h-0 flex-1 grid-cols-1 px-0 md:grid-cols-2"
|
||||
>
|
||||
<div className="flex min-h-0 flex-col">
|
||||
<div className="px-3 py-1.5">
|
||||
<span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
|
|
@ -145,8 +155,8 @@ const CompareContent = memo(function CompareContent({
|
|||
</ChatRuntimeProvider>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex min-h-0 flex-col">
|
||||
<div className="text-end px-3 py-1.5">
|
||||
<div className="flex min-h-0 flex-col border-t border-border/60 md:border-t-0 md:border-l">
|
||||
<div className="px-3 py-1.5 text-start md:text-end">
|
||||
<span className="text-[10px] font-semibold uppercase tracking-wider text-primary">
|
||||
Fine-tuned (LoRA)
|
||||
</span>
|
||||
|
|
@ -178,8 +188,23 @@ function InlineSidebar({
|
|||
children: ReactNode;
|
||||
side?: "left" | "right";
|
||||
}) {
|
||||
const { state } = useSidebar();
|
||||
const { state, isMobile, openMobile, setOpenMobile } = useSidebar();
|
||||
const collapsed = state === "collapsed";
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<Sheet open={openMobile} onOpenChange={setOpenMobile}>
|
||||
<SheetContent side={side} className="w-[18rem] p-0">
|
||||
<SheetHeader className="sr-only">
|
||||
<SheetTitle>Chat sidebar</SheetTitle>
|
||||
<SheetDescription>Chat threads and actions</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div className="h-full overflow-auto">{children}</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="group shrink-0 h-full"
|
||||
|
|
@ -447,13 +472,13 @@ export function ChatPage(): ReactElement {
|
|||
}, [modelSelectorLocked, tour.open]);
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-4rem)] bg-background overflow-hidden">
|
||||
<div className="h-[calc(100dvh-4rem)] bg-background overflow-hidden">
|
||||
<GuidedTour {...tour.tourProps} />
|
||||
<SidebarProvider
|
||||
defaultOpen={true}
|
||||
open={sidebarOpen}
|
||||
onOpenChange={setSidebarOpen}
|
||||
className="!min-h-0 h-full max-w-7xl mx-auto px-4"
|
||||
className="!min-h-0 h-full w-full max-w-7xl mx-auto px-2 sm:px-4"
|
||||
style={
|
||||
{
|
||||
"--sidebar-width": "14rem",
|
||||
|
|
@ -472,7 +497,7 @@ export function ChatPage(): ReactElement {
|
|||
</InlineSidebar>
|
||||
|
||||
<div className="flex min-h-0 min-w-0 flex-1 flex-col">
|
||||
<div className="flex h-11 shrink-0 items-center px-2">
|
||||
<div className="flex h-11 shrink-0 items-center px-1.5 sm:px-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<SidebarTrigger />
|
||||
<TopBarActions
|
||||
|
|
@ -491,6 +516,7 @@ export function ChatPage(): ReactElement {
|
|||
onOpenChange={handleModelSelectorOpenChange}
|
||||
triggerDataTour="chat-model-selector"
|
||||
contentDataTour="chat-model-selector-popover"
|
||||
className="max-w-[62vw] sm:max-w-none"
|
||||
/>
|
||||
</div>
|
||||
{modelsError && (
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ export function ExportPage() {
|
|||
// ---- Render ----
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<main className="mx-auto max-w-7xl px-6 py-4">
|
||||
<main className="mx-auto max-w-7xl px-4 py-4 sm:px-6">
|
||||
<GuidedTour {...tour.tourProps} />
|
||||
|
||||
<div className="mb-8 flex flex-col gap-0.5">
|
||||
|
|
@ -275,7 +275,7 @@ export function ExportPage() {
|
|||
{!loadingCheckpoints && !checkpointError && (
|
||||
<>
|
||||
{/* Top row: Dropdowns + metadata | Guide */}
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 md:gap-8">
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Training run dropdown */}
|
||||
<div data-tour="export-training-run" className="flex flex-col gap-2">
|
||||
|
|
@ -410,7 +410,7 @@ export function ExportPage() {
|
|||
<span className="text-[11px] font-medium text-muted-foreground uppercase tracking-wider">
|
||||
Training Info
|
||||
</span>
|
||||
<div className="grid grid-cols-2 gap-x-6 gap-y-1.5 text-xs">
|
||||
<div className="grid grid-cols-1 gap-x-6 gap-y-1.5 text-xs sm:grid-cols-2">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-muted-foreground">Base Model</span>
|
||||
<span className="font-medium">{baseModelName}</span>
|
||||
|
|
|
|||
|
|
@ -31,19 +31,19 @@ export function WizardContent() {
|
|||
|
||||
return (
|
||||
<main className="flex-1 flex flex-col overflow-y-auto">
|
||||
<header className="flex items-center gap-4 p-6 pb-4">
|
||||
<img src={mascotSrc} alt="Unsloth mascot" className="size-14" />
|
||||
<header className="flex flex-wrap items-start gap-3 p-4 pb-3 sm:p-6 sm:pb-4">
|
||||
<img src={mascotSrc} alt="Unsloth mascot" className="size-12 sm:size-14" />
|
||||
<div className="flex flex-col min-w-0">
|
||||
<h1 className="text-xl font-semibold">{stepConfig.title}</h1>
|
||||
<h1 className="text-lg font-semibold sm:text-xl">{stepConfig.title}</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{stepConfig.description}
|
||||
</p>
|
||||
</div>
|
||||
<p className="ml-auto shrink-0 text-xs text-muted-foreground uppercase tracking-wider">
|
||||
<p className="ml-auto hidden shrink-0 text-xs text-muted-foreground uppercase tracking-wider md:block">
|
||||
Step {currentStep} of {STEPS.length}
|
||||
</p>
|
||||
</header>
|
||||
<div className="flex-1 p-6 pt-2">
|
||||
<div className="flex-1 p-4 pt-1.5 sm:p-6 sm:pt-2">
|
||||
<StepComponent />
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export function WizardLayout() {
|
|||
}, [isFinalStep]);
|
||||
|
||||
return (
|
||||
<div className="relative min-h-screen flex items-center justify-center p-8 bg-gradient-to-br from-primary/5 via-background to-primary/3 overflow-hidden">
|
||||
<div className="relative min-h-screen flex items-center justify-center overflow-hidden bg-gradient-to-br from-primary/5 via-background to-primary/3 p-4 sm:p-6 md:p-8">
|
||||
{showSplash && (
|
||||
<SplashScreen
|
||||
onStartOnboarding={() => setShowSplash(false)}
|
||||
|
|
@ -81,7 +81,7 @@ export function WizardLayout() {
|
|||
ease: [0.165, 0.84, 0.44, 1],
|
||||
}}
|
||||
>
|
||||
<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">
|
||||
<Card className="relative z-10 w-full !gap-0 !m-0 !p-0 flex min-h-[560px] flex-col overflow-hidden shadow-border ring-1 ring-border md:min-h-[620px] md:flex-row lg:h-[660px]">
|
||||
<WizardSidebar />
|
||||
<div className="flex-1 flex flex-col">
|
||||
<WizardContent />
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ export function WizardSidebar() {
|
|||
const progress = ((currentStep - 1) / (STEPS.length - 1)) * 100;
|
||||
|
||||
return (
|
||||
<aside className="w-64 flex flex-col gap-4 p-6 shrink-0 bg-muted/70">
|
||||
<div className="flex items-center gap-3 py-2">
|
||||
<aside className="w-full shrink-0 bg-muted/70 p-4 md:w-64 md:p-6">
|
||||
<div className="flex items-center gap-3 py-1 md:py-2">
|
||||
<img
|
||||
src="https://unsloth.ai/cgi/image/unsloth_sticker_no_shadow_ldN4V4iydw00qSIIWDCUv.png?width=96&quality=80&format=auto"
|
||||
alt="Unsloth"
|
||||
|
|
@ -20,8 +20,13 @@ export function WizardSidebar() {
|
|||
<span className="text-xs text-muted-foreground">Studio</span>
|
||||
</div>
|
||||
</div>
|
||||
<Progress value={progress} className="h-1.5" />
|
||||
<nav className="flex flex-col gap-1">
|
||||
<div className="mt-3 md:mt-0">
|
||||
<Progress value={progress} className="h-1.5" />
|
||||
</div>
|
||||
<p className="mt-2 text-xs text-muted-foreground md:hidden">
|
||||
Step {currentStep} of {STEPS.length}
|
||||
</p>
|
||||
<nav className="mt-3 hidden flex-col gap-1 md:flex">
|
||||
{STEPS.map((step) => (
|
||||
<WizardStepItem key={step.number} step={step} />
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -121,13 +121,13 @@ export function DatasetSection() {
|
|||
);
|
||||
|
||||
return (
|
||||
<div data-tour="studio-dataset" className="lg:col-span-4">
|
||||
<div data-tour="studio-dataset" className="col-span-1 xl:col-span-4">
|
||||
<SectionCard
|
||||
icon={<HugeiconsIcon icon={Database02Icon} className="size-5" />}
|
||||
title="Dataset"
|
||||
description="Select or upload training data"
|
||||
accent="indigo"
|
||||
className="min-h-[450px]"
|
||||
className="md:min-h-[450px]"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-2">
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export function ModelSection() {
|
|||
);
|
||||
|
||||
return (
|
||||
<div data-tour="studio-model" className="col-span-12">
|
||||
<div data-tour="studio-model" className="col-span-1 md:col-span-2 xl:col-span-12">
|
||||
<SectionCard
|
||||
icon={<HugeiconsIcon icon={ChipIcon} className="size-5" />}
|
||||
title="Model"
|
||||
|
|
@ -179,7 +179,7 @@ export function ModelSection() {
|
|||
badge="2x Faster Training"
|
||||
className="shadow-border ring-1 ring-border"
|
||||
>
|
||||
<div className="grid gap-4 lg:grid-cols-4">
|
||||
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div data-tour="studio-local-model" className="flex flex-col gap-2">
|
||||
<span className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
|
||||
Local Model
|
||||
|
|
|
|||
|
|
@ -116,13 +116,13 @@ export function ParamsSection(): ReactElement {
|
|||
const epochsSliderMax = Math.max(20, store.epochs, 1);
|
||||
|
||||
return (
|
||||
<div data-tour="studio-params" className="lg:col-span-4">
|
||||
<div data-tour="studio-params" className="col-span-1 xl:col-span-4">
|
||||
<SectionCard
|
||||
icon={<HugeiconsIcon icon={Settings04Icon} className="size-5" />}
|
||||
title="Parameters"
|
||||
description="Configure training hyperparameters"
|
||||
accent="orange"
|
||||
className="min-h-[450px]"
|
||||
className="md:min-h-[450px]"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Max Steps */}
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ export function TrainingSection() {
|
|||
|
||||
|
||||
return (
|
||||
<div data-tour="studio-training" className="lg:col-span-4">
|
||||
<div data-tour="studio-training" className="col-span-1 xl:col-span-4">
|
||||
<SectionCard
|
||||
icon={<HugeiconsIcon icon={ChartAverageIcon} className="size-5" />}
|
||||
title="Training"
|
||||
description="Monitor and control training"
|
||||
accent="blue"
|
||||
className="min-h-[450px]"
|
||||
className="md:min-h-[450px]"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Loss chart */}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export function StudioPage(): ReactElement {
|
|||
length="62vh"
|
||||
style={{ opacity: 0.45 }}
|
||||
/>
|
||||
<main className="relative z-10 mx-auto max-w-7xl px-6 py-4">
|
||||
<main className="relative z-10 mx-auto max-w-7xl px-4 py-4 sm:px-6">
|
||||
<GuidedTour {...tour.tourProps} celebrate={isConfigTour} />
|
||||
|
||||
<DatasetPreviewDialog
|
||||
|
|
@ -103,7 +103,7 @@ export function StudioPage(): ReactElement {
|
|||
</Button>
|
||||
)}
|
||||
|
||||
<div className="mb-8 flex flex-col gap-0.5">
|
||||
<div className="mb-6 flex flex-col gap-0.5 sm:mb-8">
|
||||
<h1 className="text-2xl font-semibold tracking-tight">
|
||||
Fine-tuning Studio
|
||||
</h1>
|
||||
|
|
@ -121,7 +121,7 @@ export function StudioPage(): ReactElement {
|
|||
) : showTrainingView ? (
|
||||
<TrainingView />
|
||||
) : (
|
||||
<div className="grid grid-cols-12 items-start gap-6">
|
||||
<div className="grid grid-cols-1 items-start gap-4 md:grid-cols-2 md:gap-6 xl:grid-cols-12">
|
||||
<ModelSection />
|
||||
<DatasetSection />
|
||||
<ParamsSection />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue