mirror of
https://github.com/Anil-matcha/Open-Generative-AI.git
synced 2026-08-30 17:33:11 +08:00
feat(studio): persist background tab states, clean inputs, and align empty/results views
This commit is contained in:
@@ -80,28 +80,24 @@ export default function StandaloneShell() {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [droppedFiles, setDroppedFiles] = useState(null);
|
||||
|
||||
// Sync tab with URL if user navigates manually or via browser back/forward
|
||||
|
||||
// Popstate event listener to sync tab state with URL on back/forward navigation
|
||||
useEffect(() => {
|
||||
const info = getWorkflowInfo();
|
||||
if (info.id) {
|
||||
setActiveTab('workflows');
|
||||
} else if (slug.includes('agents')) {
|
||||
setActiveTab('agents');
|
||||
} else if (slug.includes('design-agent')) {
|
||||
setActiveTab('design-agent');
|
||||
} else if (slug.includes('apps')) {
|
||||
setActiveTab('apps');
|
||||
} else {
|
||||
const firstSegment = slug[0];
|
||||
if (firstSegment && TABS.find(t => t.id === firstSegment)) {
|
||||
setActiveTab(firstSegment);
|
||||
}
|
||||
}
|
||||
}, [slug, getWorkflowInfo]);
|
||||
const handlePopState = () => {
|
||||
const path = window.location.pathname;
|
||||
const segments = path.split('/').filter(Boolean);
|
||||
const tabId = segments[1] || 'image';
|
||||
if (TABS.find(t => t.id === tabId)) {
|
||||
setActiveTab(tabId);
|
||||
}
|
||||
};
|
||||
window.addEventListener('popstate', handlePopState);
|
||||
return () => window.removeEventListener('popstate', handlePopState);
|
||||
}, []);
|
||||
|
||||
const handleTabChange = (tabId) => {
|
||||
router.push(`/studio/${tabId}`);
|
||||
// setActiveTab(tabId);
|
||||
window.history.pushState(null, '', `/studio/${tabId}`);
|
||||
setActiveTab(tabId);
|
||||
};
|
||||
|
||||
// Auto-hide header when inside a specific workflow view or design agent
|
||||
@@ -359,20 +355,50 @@ export default function StandaloneShell() {
|
||||
|
||||
{/* Studio Content */}
|
||||
<div className="flex-1 min-h-0 relative overflow-hidden">
|
||||
{activeTab === 'image' && <ImageStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'video' && <VideoStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'clipping' && <ClippingStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'vibe-motion' && <VibeMotionStudio apiKey={apiKey} />}
|
||||
{activeTab === 'lipsync' && <LipSyncStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'body-swap' && <RecastStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'cinema' && <CinemaStudio apiKey={apiKey} />}
|
||||
{activeTab === 'audio' && <AudioStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'marketing' && <MarketingStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />}
|
||||
{activeTab === 'workflows' && <WorkflowStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />}
|
||||
{activeTab === 'agents' && <AgentStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />}
|
||||
{activeTab === 'design-agent' && <DesignAgentStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />}
|
||||
{activeTab === 'apps' && <AppsStudio apiKey={apiKey} />}
|
||||
{activeTab === 'ai-influencer' && <AiInfluencerStudio apiKey={apiKey} />}
|
||||
<div className={activeTab === 'image' ? "h-full w-full" : "hidden"}>
|
||||
<ImageStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'video' ? "h-full w-full" : "hidden"}>
|
||||
<VideoStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'clipping' ? "h-full w-full" : "hidden"}>
|
||||
<ClippingStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'vibe-motion' ? "h-full w-full" : "hidden"}>
|
||||
<VibeMotionStudio apiKey={apiKey} />
|
||||
</div>
|
||||
<div className={activeTab === 'lipsync' ? "h-full w-full" : "hidden"}>
|
||||
<LipSyncStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'body-swap' ? "h-full w-full" : "hidden"}>
|
||||
<RecastStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'cinema' ? "h-full w-full" : "hidden"}>
|
||||
<CinemaStudio apiKey={apiKey} />
|
||||
</div>
|
||||
<div className={activeTab === 'audio' ? "h-full w-full" : "hidden"}>
|
||||
<AudioStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'marketing' ? "h-full w-full" : "hidden"}>
|
||||
<MarketingStudio apiKey={apiKey} droppedFiles={droppedFiles} onFilesHandled={handleFilesHandled} />
|
||||
</div>
|
||||
<div className={activeTab === 'workflows' ? "h-full w-full" : "hidden"}>
|
||||
<WorkflowStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />
|
||||
</div>
|
||||
<div className={activeTab === 'agents' ? "h-full w-full" : "hidden"}>
|
||||
<AgentStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />
|
||||
</div>
|
||||
<div className={activeTab === 'design-agent' ? "h-full w-full" : "hidden"}>
|
||||
{activeTab === 'design-agent' && (
|
||||
<DesignAgentStudio apiKey={apiKey} isHeaderVisible={isHeaderVisible} onToggleHeader={setIsHeaderVisible} />
|
||||
)}
|
||||
</div>
|
||||
<div className={activeTab === 'apps' ? "h-full w-full" : "hidden"}>
|
||||
<AppsStudio apiKey={apiKey} />
|
||||
</div>
|
||||
<div className={activeTab === 'ai-influencer' ? "h-full w-full" : "hidden"}>
|
||||
<AiInfluencerStudio apiKey={apiKey} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Settings Modal */}
|
||||
|
||||
@@ -770,6 +770,24 @@ export default function CinemaStudio({
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (confirm("Are you sure you want to delete this generated item?")) {
|
||||
setInternalHistory(prev => prev.filter((_, i) => i !== idx));
|
||||
}
|
||||
}}
|
||||
className="p-2 bg-black/60 backdrop-blur-md rounded-full text-red-400 hover:bg-red-500 hover:text-white transition-all border border-white/10"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
@@ -794,24 +812,46 @@ export default function CinemaStudio({
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-center px-4 animate-fade-in-up transition-all duration-700 min-h-[50vh]">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded-[2rem] flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded-2xl flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110">
|
||||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="text-primary opacity-80">
|
||||
<path d="M23 7l-7 5 7 5V7z" />
|
||||
<rect x="1" y="5" width="15" height="14" rx="2" ry="2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="absolute top-4 right-4 text-[10px] text-primary/40 animate-pulse">REC</div>
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium">START CREATING WITH</span><br />
|
||||
<span className="text-white uppercase tracking-wider">Cinema Studio</span>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
CINEMA STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed">
|
||||
What would you shoot with infinite budget?
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
What would you shoot with infinite budget? Control cameras, lighting, lenses, and prompt high-end cinematic scenes.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -427,21 +427,46 @@ export default function ClippingStudio({
|
||||
{/* 1. Empty State (No history, no result active) */}
|
||||
{!result && history.length === 0 && (
|
||||
<div className="flex-grow flex flex-col items-center justify-center animate-fade-in-up transition-all duration-700 min-h-[55vh]">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded-[2rem] flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded-2xl flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110">
|
||||
<ScissorsIcon className="text-primary opacity-80 w-8 h-8" />
|
||||
</div>
|
||||
<div className="absolute top-4 right-4 text-[10px] text-primary/40 animate-pulse">✨</div>
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium">START CREATING WITH</span><br />
|
||||
<span className="text-white">AI CLIPPING STUDIO</span>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
AI CLIPPING STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed">
|
||||
Extract viral highlights and timings from your videos automatically
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
Extract viral highlights and precise timings from your videos automatically.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -800,6 +800,24 @@ export default function LipSyncStudio({
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (confirm("Are you sure you want to delete this generated item?")) {
|
||||
setInternalHistory(prev => prev.filter((_, i) => i !== idx));
|
||||
}
|
||||
}}
|
||||
className="p-2 bg-black/60 backdrop-blur-md rounded-full text-red-400 hover:bg-red-500 hover:text-white transition-all border border-white/10"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
@@ -818,26 +836,46 @@ export default function LipSyncStudio({
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full animate-fade-in-up transition-all duration-700 min-h-[50vh]">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded-[2rem] flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded-2xl flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110">
|
||||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="text-primary opacity-80">
|
||||
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
|
||||
<path d="M19 10v2a7 7 0 0 1-14 0v-2" />
|
||||
<line x1="12" y1="19" x2="12" y2="23" />
|
||||
<line x1="8" y1="23" x2="16" y2="23" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="absolute top-4 right-4 text-[10px] text-primary/40 animate-pulse">🎙</div>
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium">START CREATING WITH</span><br />
|
||||
<span className="text-white">LIP SYNC</span>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
LIP SYNC STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed">
|
||||
Animate portraits or sync lips to audio with AI
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
Sync any voice with any face video to create premium talking avatars and videos.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -392,6 +392,24 @@ export default function MarketingStudio({ apiKey, droppedFiles, onFilesHandled }
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (confirm("Are you sure you want to delete this generated item?")) {
|
||||
setHistory(prev => prev.filter(h => h.id !== entry.id));
|
||||
}
|
||||
}}
|
||||
className="p-2 bg-black/60 backdrop-blur-md rounded-full text-red-400 hover:bg-red-500 hover:text-white transition-all border border-white/10"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="p-3 bg-black/80 backdrop-blur-sm border-t border-white/5 flex flex-col gap-1.5 flex-1">
|
||||
@@ -407,27 +425,48 @@ export default function MarketingStudio({ apiKey, droppedFiles, onFilesHandled }
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-full flex flex-col items-center justify-center animate-fade-in-up transition-all duration-700">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded-[2rem] flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded-2xl flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110 shadow-inner">
|
||||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" strokeWidth="1.5">
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
|
||||
<line x1="8" y1="21" x2="16" y2="21" />
|
||||
<line x1="12" y1="17" x2="12" y2="21" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full flex flex-col items-center justify-center animate-fade-in-up transition-all duration-700 min-h-[50vh]">
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium uppercase tracking-widest">START CREATING WITH</span>
|
||||
<br />
|
||||
<span className="text-white uppercase tracking-tight">MARKETING STUDIO</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed px-6">
|
||||
Describe your scene, upload your product, and watch high-converting AI video ads come to life.
|
||||
</p>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
MARKETING STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
Describe your scene, upload your product, and watch high-converting AI video ads come to life.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -585,6 +585,24 @@ export default function RecastStudio({
|
||||
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (confirm("Are you sure you want to delete this generated item?")) {
|
||||
setInternalHistory(prev => prev.filter((_, i) => i !== idx));
|
||||
}
|
||||
}}
|
||||
className="p-2 bg-black/60 backdrop-blur-md rounded-full text-red-400 hover:bg-red-500 hover:text-white transition-all border border-white/10"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Details */}
|
||||
@@ -600,27 +618,46 @@ export default function RecastStudio({
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full animate-fade-in-up transition-all duration-700 min-h-[50vh]">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded-[2rem] flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded-2xl flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110">
|
||||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="text-primary opacity-80">
|
||||
<path d="M16 3h5v5" />
|
||||
<path d="M8 21H3v-5" />
|
||||
<path d="M21 3l-7 7" />
|
||||
<path d="M3 21l7-7" />
|
||||
<circle cx="12" cy="12" r="2.2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="absolute top-4 right-4 text-[10px] text-primary/40 animate-pulse">🎭</div>
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium">START CREATING WITH</span><br />
|
||||
<span className="text-white">BODY SWAP</span>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
BODY SWAP STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed">
|
||||
Swap the character in any video — drop in a clip and a character image
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
Swap the character in any video dynamically by choosing a video clip and a target character image.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -349,6 +349,24 @@ export default function VibeMotionStudio({ apiKey }) {
|
||||
</svg>
|
||||
</div>
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
title="Delete"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (confirm("Are you sure you want to delete this generated item?")) {
|
||||
setHistory(prev => prev.filter((_, i) => i !== idx));
|
||||
}
|
||||
}}
|
||||
className="p-2 bg-black/60 backdrop-blur-md rounded-full text-red-400 hover:bg-red-500 hover:text-white transition-all border border-white/10"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
|
||||
<line x1="10" y1="11" x2="10" y2="17" />
|
||||
<line x1="14" y1="11" x2="14" y2="17" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* ── Card footer: prompt + metadata ── */}
|
||||
@@ -376,23 +394,46 @@ export default function VibeMotionStudio({ apiKey }) {
|
||||
) : !generating ? (
|
||||
/* ── Empty State ── */
|
||||
<div className="flex flex-col items-center justify-center h-full animate-fade-in-up transition-all duration-700 min-h-[50vh]">
|
||||
<div className="mb-12 relative group">
|
||||
<div className="absolute inset-0 bg-primary/10 blur-[120px] rounded-full opacity-30 group-hover:opacity-60 transition-opacity duration-1000" />
|
||||
<div className="relative w-24 h-24 md:w-32 md:h-32 bg-white/[0.02] rounded flex items-center justify-center border border-white/[0.05] overflow-hidden backdrop-blur-sm">
|
||||
<div className="w-16 h-16 bg-primary/5 rounded flex items-center justify-center border border-primary/10 relative z-10 transition-transform duration-500 group-hover:scale-110">
|
||||
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="text-primary opacity-80">
|
||||
<path d="M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4L12 17l-6.2 4.3 2.4-7.4L2 9.4h7.6z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="absolute top-4 right-4 text-[10px] text-primary/40 animate-pulse">✨</div>
|
||||
{/* Overlapping floating cards */}
|
||||
<div className="flex items-center justify-center gap-1.5 md:gap-3 mb-10 select-none scale-90 sm:scale-100">
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/sdxl-image.avif"
|
||||
alt="Creative asset 1"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl -rotate-[4deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/chroma-image.avif"
|
||||
alt="Creative asset 2"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-18 sm:w-24 sm:h-24 rounded-full border border-white/10 shadow-2xl rotate-[6deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/neta-lumina.avif"
|
||||
alt="Creative asset 3"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="w-18 h-22 sm:w-24 sm:h-28 rounded-2xl border border-white/10 shadow-2xl rotate-[12deg] transform hover:rotate-0 hover:scale-110 hover:z-20 transition-all duration-300 overflow-hidden bg-white/[0.01] -ml-3 sm:-ml-4 flex-shrink-0">
|
||||
<img
|
||||
src="https://d3adwkbyhxyrtq.cloudfront.net/webassets/videomodels/perfect-pony-xl.avif"
|
||||
alt="Creative asset 4"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-5xl md:text-6xl font-extrabold text-white tracking-tight mb-4 text-center px-4">
|
||||
<span className="text-white/40 font-medium">START CREATING WITH</span><br />
|
||||
<span className="text-white">VIBE MOTION</span>
|
||||
|
||||
<h1 className="text-2xl sm:text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-center px-4 flex flex-col items-center">
|
||||
<span className="text-white font-black uppercase text-xl sm:text-3xl tracking-wide mb-1 opacity-90">START CREATING WITH</span>
|
||||
<span className="text-[#22d3ee] font-black uppercase text-2xl sm:text-4xl sm:mt-1 tracking-tight">
|
||||
VIBE MOTION STUDIO
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-white/40 text-sm md:text-base font-medium tracking-wide text-center max-w-lg leading-relaxed">
|
||||
Generate animated motion graphics from a text prompt — kinetic typography, data charts, logo reveals and more
|
||||
<p className="text-white/40 text-xs sm:text-sm font-medium tracking-wide text-center max-w-lg leading-relaxed px-4">
|
||||
Generate animated motion graphics from a text prompt — kinetic typography, data charts, logo reveals, and more.
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user