VibeCoderzVibeCoderz
All Prompts
AiWorkspaceIslands v2 (Copy) UI Preview

AiWorkspaceIslands v2 (Copy)

AiWorkspaceIslands v2 (Copy): UI-компонент для создания адаптивных рабочих пространств. Версия 2.

by LovinBot DesignLive Preview

Prompt

# AiWorkspaceIslands v2 (Copy)

You are given a task to integrate an existing React component in the codebase

~~~/README.md
# AI Workspace - Floating Islands Variant

A split-screen workspace interface featuring a "Floating Islands" layout concept.

## Features

- **Split-Screen Layout**: Detached panels for Chat (Left) and Workspace (Right).
- **Floating Island Aesthetic**: Deep shadows and rounded corners on a soft background.
- **Agent Chat Stream**: Interactive chat history with "Thinking" blocks.
- **Storyboard Canvas**: Grid of vertical video scenes with hover interactions.
- **Motion Light Design**: Uses project fonts (Archivo, Manrope) and soft color palette.

## Usage

```tsx
import { AiWorkspaceIslands } from '@/sd-components/d866d390-878f-492e-be87-60e82682e126';

function App() {
  return <AiWorkspaceIslands />;
}
```
~~~

~~~/src/App.tsx
import AiWorkspaceIslands from './Component';

export default function App() {
  return (
    <div className="w-full h-full bg-[#F8FAFC]">
       <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Archivo:wght@100;200;300;400;500;600;700;800;900&display=swap');
        @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@200;300;400;500;600;700;800&display=swap');
        
        :root {
          --font-archivo: 'Archivo', sans-serif;
          --font-manrope: 'Manrope', sans-serif;
        }

        .font-archivo { font-family: var(--font-archivo); }
        .font-manrope { font-family: var(--font-manrope); }
      `}</style>
      <AiWorkspaceIslands />
    </div>
  );
}
~~~

~~~/package.json
{
  "name": "ai-workspace-islands",
  "version": "1.0.0",
  "description": "Floating Islands layout for AI Video Agent workspace",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "framer-motion": "^10.16.4",
    "lucide-react": "^0.294.0",
    "clsx": "^2.0.0",
    "tailwind-merge": "^2.0.0"
  }
}
~~~

~~~/src/Component.tsx
import React, { useState, useEffect, useRef } from 'react';
import { 
  Send, 
  Paperclip, 
  Mic, 
  Settings, 
  CheckCircle2, 
  RotateCw, 
  Play, 
  Sparkles,
  Layout,
  Film,
  Image as ImageIcon,
  Clock,
  FileText,
  User,
  MoreHorizontal,
  Music,
  ChevronDown,
  Expand,
  Loader2,
  Share2,
  Download,
  Palette,
  Wind,
  Volume2,
  AlignLeft,
  X,
  Pause,
  Maximize2,
  VolumeX,
  SkipBack,
  SkipForward
} from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

// Import reusable components from Motion Light system
import { Button } from '@/sd-components/ea4073da-1d86-4d53-a727-8251a694f49d';
import { Card } from '@/sd-components/e3000fab-cc5b-4d46-87b4-27befb6faec9';
import { Input } from '@/sd-components/6c73260c-764b-4370-8e55-4fdad7f394b7';

// Utility for Tailwind class merging
function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

// --- Types ---
interface Message {
  id: string;
  role: 'user' | 'agent';
  content: string;
  timestamp: string;
}

interface Scene {
  id: string;
  number: string;
  startTime: string;
  endTime: string;
  script: string;
  state: 'concept' | 'generating' | 'ready';
  thumbnailUrl: string;
  specs: {
    visuals: string;
    animation: string;
    sfx: string;
  };
}

// --- Sub-components ---

const ChatBubble = ({ 
  isUser, 
  content, 
  isThinking 
}: { 
  isUser: boolean; 
  content: React.ReactNode; 
  isThinking?: boolean 
}) => {
  return (
    <motion.div
      initial={{ opacity: 0, y: 10, scale: 0.95 }}
      animate={{ opacity: 1, y: 0, scale: 1 }}
      className={cn(
        "flex w-full mb-6",
        isUser ? "justify-end" : "justify-start"
      )}
    >
      <div className={cn(
        "max-w-[85%] p-4 rounded-2xl relative",
        isUser 
          ? "bg-blue-600 text-white rounded-br-sm shadow-lg shadow-blue-500/20" 
          : "bg-white text-slate-800 rounded-bl-sm shadow-sm border border-slate-100"
      )}>
        {isThinking && (
          <div className="flex items-center gap-2 mb-2 text-xs font-semibold uppercase tracking-wider text-blue-500">
            <Sparkles size={12} />
            <span>AI Reasoning</span>
          </div>
        )}
        <div className={cn("text-sm leading-relaxed", isUser ? "font-medium" : "font-normal")}>
          {content}
        </div>
      </div>
    </motion.div>
  );
};

const ThinkingStep = ({ text, delay }: { text: string; delay: number }) => (
  <motion.div 
    initial={{ opacity: 0, x: -10 }}
    animate={{ opacity: 1, x: 0 }}
    transition={{ delay }}
    className="flex items-center gap-2 text-xs text-slate-500 mb-1"
  >
    <CheckCircle2 size={14} className="text-emerald-500" />
    <span>{text}</span>
  </motion.div>
);

const TabButton = ({ active, label, onClick, icon: Icon }: { active: boolean; label: string; onClick: () => void; icon: any }) => (
  <button 
    onClick={onClick}
    className={cn(
      "flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-all duration-200",
      active 
        ? "bg-slate-900 text-white shadow-lg shadow-slate-900/10" 
        : "text-slate-500 hover:text-slate-900 hover:bg-slate-100"
    )}
  >
    <Icon size={16} />
    {label}
  </button>
);

// --- Data ---
const SCENES: Scene[] = [
  {
    id: 's1',
    number: '01',
    startTime: '0:00',
    endTime: '0:05',
    script: "We guarantee quality that lasts a lifetime.",
    state: 'ready',
    thumbnailUrl: 'https://images.unsplash.com/photo-1542291026-7eec264c27ff?ixlib=rb-4.0.3&auto=format&fit=crop&w=1740&q=80',
    specs: {
      visuals: "Icon: 'Warranty Shield' (Gold). Text: '1 Year Guarantee'. Font: Manrope Bold.",
      animation: "Main Icon: Rotates 360°. Text: Slides in from left side (opacity 0% → 100%).",
      sfx: "Subtle 'Pop' sound on icon appearance, soft wind swoosh."
    }
  },
  {
    id: 's2',
    number: '02',
    startTime: '0:05',
    endTime: '0:09',
    script: "Crafted with precision for the modern explorer.",
    state: 'generating',
    thumbnailUrl: 'https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb?ixlib=rb-4.0.3&auto=format&fit=crop&w=1740&q=80',
    specs: {
      visuals: "Close up of sneaker texture. Overlay text: 'Premium Materials'.",
      animation: "Camera: Slow zoom in. Text: Fade in with blur effect.",
      sfx: "Fabric texture sound, low bass hum."
    }
  },
  {
    id: 's3',
    number: '03',
    startTime: '0:09',
    endTime: '0:15',
    script: "Step into the future of comfort today.",
    state: 'concept',
    thumbnailUrl: 'https://images.unsplash.com/photo-1460353581641-37baddab0fa2?ixlib=rb-4.0.3&auto=format&fit=crop&w=1740&q=80',
    specs: {
      visuals: "Model walking in city setting. Sunlight flare.",
      animation: "Transition: Cross-dissolve from previous scene.",
      sfx: "City ambience, optimistic synth chord."
    }
  }
];

// --- Main Component ---

export default function AiWorkspaceIslands() {
  const [activeTab, setActiveTab] = useState<'script' | 'storyboard' | 'preview'>('storyboard');
  const [activeSceneId, setActiveSceneId] = useState<string | null>(null);
  const [inputValue, setInputValue] = useState('');
  
  // Preview Player State
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const duration = 15; // Total duration in seconds
  const playerInterval = useRef<NodeJS.Timeout | null>(null);

  // Handle Play/Pause logic
  useEffect(() => {
    if (isPlaying) {
      playerInterval.current = setInterval(() => {
        setCurrentTime(prev => {
          if (prev >= duration) {
            setIsPlaying(false);
            return 0;
          }
          return prev + 0.1;
        });
      }, 100);
    } else {
      if (playerInterval.current) clearInterval(playerInterval.current);
    }
    return () => {
      if (playerInterval.current) clearInterval(playerInterval.current);
    };
  }, [isPlaying]);

  // Derive current scene from time
  const getCurrentScene = () => {
    if (currentTime < 5) return SCENES[0];
    if (currentTime < 9) return SCENES[1];
    return SCENES[2];
  };

  const currentScene = getCurrentScene();

  const formatTime = (time: number) => {
    const minutes = Math.floor(time / 60);
    const seconds = Math.floor(time % 60);
    return `${minutes}:${seconds.toString().padStart(2, '0')}`;
  };

  return (
    <div className="h-screen w-full bg-slate-50 p-4 md:p-6 overflow-hidden flex flex-col md:flex-row gap-6 font-manrope text-slate-900 selection:bg-blue-100 selection:text-blue-900">
      
      {/* --- LEFT ISLAND: Agent Brain --- */}
      <motion.div 
        initial={{ x: -50, opacity: 0 }}
        animate={{ x: 0, opacity: 1 }}
        transition={{ type: "spring", damping: 25, stiffness: 100 }}
        className="w-full md:w-[35%] lg:w-[30%] flex flex-col h-full rounded-[32px] bg-white shadow-2xl shadow-slate-200/50 relative overflow-hidden ring-1 ring-slate-100/50"
      >
        {/* Header */}
        <div className="p-6 border-b border-slate-50 flex items-center justify-between bg-white/50 backdrop-blur-sm z-10 sticky top-0">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-full bg-gradient-to-tr from-blue-600 to-indigo-600 flex items-center justify-center text-white shadow-lg shadow-blue-500/25">
              <Sparkles size={20} />
            </div>
            <div>
              <h2 className="font-archivo font-bold text-lg leading-none">Video Agent</h2>
              <span className="text-xs text-emerald-500 font-medium flex items-center gap-1 mt-1">
                <span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse" />
                Active & Thinking
              </span>
            </div>
          </div>
          <Button variant="ghost" size="icon" className="text-slate-400 hover:text-slate-600 rounded-full hover:bg-slate-50">
            <Settings size={20} />
          </Button>
        </div>

        {/* Chat Area */}
        <div className="flex-1 overflow-y-auto p-6 bg-slate-50/30 scroll-smooth">
          <ChatBubble 
            isUser={false}
            content="I've analyzed the script. Shall we start with a warranty focus to emphasize durability?" 
          />
          <ChatBubble 
            isUser={true}
            content="Yes, let's make sure the visuals feel premium." 
          />
          <ChatBubble 
            isUser={false} 
            isThinking={true}
            content={
              <div className="space-y-3">
                <p>Great choice. I'm generating scene concepts that highlight material quality and longevity.</p>
                <div className="pl-1 border-l-2 border-slate-100 py-1 space-y-2">
                  <ThinkingStep text="Analyzing tone: Premium & Reliable" delay={0.2} />
                  <ThinkingStep text="Matching stock footage..." delay={0.8} />
                  <ThinkingStep text="Drafting scene sequence..." delay={1.4} />
                </div>
              </div>
            }
          />
          
          <div className="h-4" /> {/* Spacer */}
        </div>

        {/* Input Area */}
        <div className="p-4 bg-white border-t border-slate-100">
          <div className="relative bg-slate-50 rounded-3xl p-2 pr-2 flex items-center ring-1 ring-slate-200 focus-within:ring-2 focus-within:ring-blue-500/20 transition-all shadow-inner">
            <Button variant="ghost" size="icon" className="text-slate-400 hover:text-blue-600 rounded-full hover:bg-white shadow-none">
              <Paperclip size={20} />
            </Button>
            <input 
              type="text" 
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
              placeholder="Describe your change..."
              className="flex-1 bg-transparent border-none focus:ring-0 text-sm font-medium placeholder:text-slate-400 px-2 min-w-0"
            />
            <div className="flex items-center gap-1">
              <Button variant="ghost" size="icon" className="text-slate-400 hover:text-slate-600 rounded-full hover:bg-white shadow-none">
                <Mic size={20} />
              </Button>
              <Button 
                size="icon" 
                className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg shadow-blue-500/25 h-10 w-10 ml-1"
              >
                <Send size={18} className="ml-0.5" />
              </Button>
            </div>
          </div>
        </div>
      </motion.div>

      {/* --- RIGHT ISLAND: Workspace --- */}
      <motion.div 
        initial={{ x: 50, opacity: 0 }}
        animate={{ x: 0, opacity: 1 }}
        transition={{ type: "spring", damping: 25, stiffness: 100, delay: 0.1 }}
        className="flex-1 flex flex-col h-full rounded-[32px] bg-white shadow-2xl shadow-slate-200/50 relative overflow-hidden ring-1 ring-slate-100/50"
      >
        {/* Workspace Header */}
        <div className="h-20 px-8 border-b border-slate-100 flex items-center justify-between bg-white/80 backdrop-blur-md sticky top-0 z-20">
          <div className="flex items-center gap-2 bg-slate-100/50 p-1.5 rounded-full border border-slate-100">
            <TabButton 
              active={activeTab === 'script'} 
              label="Script" 
              onClick={() => setActiveTab('script')}
              icon={FileText}
            />
            <TabButton 
              active={activeTab === 'storyboard'} 
              label="Storyboard" 
              onClick={() => setActiveTab('storyboard')}
              icon={Layout}
            />
            <TabButton 
              active={activeTab === 'preview'} 
              label="Preview" 
              onClick={() => setActiveTab('preview')}
              icon={Play}
            />
          </div>

          <div className="flex items-center gap-4">
            <div className="flex -space-x-3">
              {[1, 2, 3].map((i) => (
                <div key={i} className="w-9 h-9 rounded-full border-2 border-white bg-slate-200 flex items-center justify-center text-xs font-bold text-slate-500 shadow-sm relative z-0 hover:z-10 transition-all cursor-pointer hover:scale-110">
                  <img src={`https://i.pravatar.cc/100?img=${10+i}`} className="w-full h-full rounded-full" alt="Team" />
                </div>
              ))}
            </div>
            <div className="h-8 w-px bg-slate-200" />
            <Button variant="ghost" className="rounded-full text-slate-500 font-medium">
              <Share2 className="w-4 h-4 mr-2" /> Share
            </Button>
            <Button className="bg-slate-900 text-white rounded-full px-6 font-medium shadow-lg shadow-slate-900/20 hover:bg-slate-800">
              <Download className="w-4 h-4 mr-2" /> Export
            </Button>
          </div>
        </div>

        {/* Workspace Content */}
        <div className="flex-1 overflow-hidden relative bg-slate-50/30">
          <AnimatePresence mode="wait">
            
            {/* --- SCRIPT TAB --- */}
            {activeTab === 'script' && (
              <motion.div 
                key="script-view"
                className="absolute inset-0 flex flex-col"
                initial={{ opacity: 0, y: 10 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: -10 }}
                transition={{ duration: 0.3 }}
              >
                <div className="flex-1 overflow-y-auto p-8 flex justify-center">
                  <div className="w-full max-w-3xl bg-slate-900 rounded-[24px] p-10 shadow-2xl relative overflow-hidden text-white my-4">
                    <div className="absolute -top-20 -right-20 w-64 h-64 bg-indigo-500/20 rounded-full blur-3xl pointer-events-none" />
                    <div className="relative z-10 space-y-8">
                      <div className="flex items-start gap-4">
                        <span className="text-indigo-400 font-mono text-sm pt-1">0:00</span>
                        <p className="text-2xl font-medium leading-relaxed text-white/90">
                          We guarantee <span className="text-indigo-400 font-bold bg-indigo-500/10 px-1 rounded">quality that lasts</span> a lifetime. 
                          Crafted with precision for the modern explorer.
                        </p>
                      </div>
                      <div className="flex items-start gap-4">
                        <span className="text-indigo-400 font-mono text-sm pt-1">0:05</span>
                        <p className="text-2xl font-medium leading-relaxed text-white/90">
                          Whether you're scaling peaks or navigating city streets, 
                          our gear moves with you. <span className="text-emerald-400 font-bold bg-emerald-500/10 px-1 rounded">Sustainable. Durable. Timeless.</span>
                        </p>
                      </div>
                      <div className="flex items-start gap-4 opacity-50">
                        <span className="text-slate-500 font-mono text-sm pt-1">0:12</span>
                        <p className="text-2xl font-medium leading-relaxed text-white/90">
                          Step into the future of comfort today. 
                          <span className="border-b border-dashed border-slate-600 ml-2 text-slate-400 text-lg">[Visual Cue: Product Reveal]</span>
                        </p>
                      </div>
                    </div>
                  </div>
                </div>
                <div className="h-20 bg-white border-t border-slate-100 px-8 flex items-center justify-between shrink-0">
                  <div className="flex items-center gap-6">
                    <div className="flex items-center gap-3">
                      <div className="w-10 h-10 rounded-full bg-indigo-50 flex items-center justify-center text-indigo-600">
                        <User className="w-5 h-5" />
                      </div>
                      <div>
                        <p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Voice Profile</p>
                        <div className="flex items-center gap-2">
                          <span className="font-bold text-slate-800">Brittney</span>
                          <span className="text-xs bg-slate-100 px-2 py-0.5 rounded-full text-slate-500 border border-slate-200">English</span>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div className="flex items-center gap-8">
                     <div className="flex items-center gap-3">
                      <div className="w-10 h-10 rounded-full bg-emerald-50 flex items-center justify-center text-emerald-600">
                        <FileText className="w-5 h-5" />
                      </div>
                      <div>
                        <p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Word Count</p>
                        <p className="font-bold text-slate-800">359 Words</p>
                      </div>
                    </div>
                     <div className="flex items-center gap-3">
                      <div className="w-10 h-10 rounded-full bg-amber-50 flex items-center justify-center text-amber-600">
                        <Clock className="w-5 h-5" />
                      </div>
                      <div>
                        <p className="text-xs font-semibold text-slate-500 uppercase tracking-wider">Est. Duration</p>
                        <p className="font-bold text-slate-800">2:52</p>
                      </div>
                    </div>
                  </div>
                </div>
              </motion.div>
            )}

            {/* --- STORYBOARD TAB --- */}
            {activeTab === 'storyboard' && (
              <motion.div 
                key="storyboard-view"
                className="absolute inset-0 overflow-y-auto"
                initial={{ opacity: 0, x: 20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: -20 }}
                transition={{ duration: 0.3 }}
              >
                <div className="p-8 pb-32 max-w-5xl mx-auto space-y-6">
                  {/* Scene List Header */}
                  <div className="flex items-center justify-between mb-2 px-2">
                    <h3 className="text-lg font-bold text-slate-900">Sequence Timeline</h3>
                    <div className="flex items-center gap-2 text-sm text-slate-500 font-medium">
                      <span>Total: 3 Scenes</span>
                      <span className="text-slate-300">|</span>
                      <span>00:15 Duration</span>
                    </div>
                  </div>

                  {/* Scene Cards List */}
                  {SCENES.map((scene) => (
                    <motion.div
                      key={scene.id}
                      layout
                      initial={{ opacity: 0, y: 20 }}
                      animate={{ opacity: 1, y: 0 }}
                      className="group relative"
                    >
                      {/* Connecting Line */}
                      <div className="absolute left-[88px] top-full h-6 w-0.5 bg-slate-100 last:hidden z-0" />

                      <div className="flex bg-white rounded-[32px] p-5 shadow-sm border border-slate-100 hover:shadow-xl hover:shadow-slate-200/50 transition-all duration-300 relative z-10">
                        
                        {/* Left: Thumbnail (9:16) */}
                        <div className="relative w-[120px] aspect-[9/16] rounded-2xl overflow-hidden bg-slate-100 flex-shrink-0 cursor-pointer group/thumb shadow-inner border border-slate-100">
                          <img 
                            src={scene.thumbnailUrl} 
                            alt={`Scene ${scene.number}`}
                            className={cn(
                              "w-full h-full object-cover transition-transform duration-700",
                              scene.state === 'generating' ? "opacity-50 blur-sm scale-110" : "scale-100 group-hover/thumb:scale-110"
                            )}
                          />
                          
                          {/* State Overlays */}
                          {scene.state === 'ready' && (
                            <div className="absolute inset-0 flex items-center justify-center bg-black/10 group-hover/thumb:bg-black/30 transition-colors">
                              <div className="w-10 h-10 rounded-full bg-white/20 backdrop-blur-md flex items-center justify-center border border-white/40 shadow-lg text-white group-hover/thumb:scale-110 transition-transform">
                                <Play className="w-4 h-4 fill-white" />
                              </div>
                            </div>
                          )}

                          {scene.state === 'generating' && (
                            <div className="absolute inset-0 flex flex-col items-center justify-center bg-indigo-900/10 backdrop-blur-[2px]">
                              <Loader2 className="w-8 h-8 text-indigo-600 animate-spin mb-2" />
                              <span className="text-[10px] font-bold text-indigo-900 bg-white/80 px-2 py-0.5 rounded-full">Rendering...</span>
                            </div>
                          )}

                          {scene.state === 'concept' && (
                            <div className="absolute top-2 right-2 opacity-0 group-hover/thumb:opacity-100 transition-opacity">
                              <div className="p-1.5 rounded-full bg-black/50 backdrop-blur-md text-white">
                                <Expand className="w-3 h-3" />
                              </div>
                            </div>
                          )}
                        </div>

                        {/* Right: Data Container */}
                        <div className="flex-1 ml-8 py-1 flex flex-col">
                          {/* Attractive Header: Production Slate Style */}
                          <div className="flex items-center gap-2 mb-4">
                            <div className="flex items-center overflow-hidden rounded-full border border-slate-200 shadow-sm">
                              <span className="px-3 py-1 bg-slate-900 text-white text-[10px] font-black tracking-[0.1em] font-archivo">
                                SCENE {scene.number}
                              </span>
                              <div className="flex items-center gap-1.5 px-3 py-1 bg-white text-slate-500 text-[10px] font-bold font-archivo">
                                <Clock className="w-3 h-3 text-slate-400" />
                                <span>{scene.startTime}</span>
                                <span className="text-slate-300">→</span>
                                <span>{scene.endTime}</span>
                              </div>
                            </div>
                            
                            {scene.state === 'generating' && (
                              <div className="flex items-center gap-1.5 ml-2">
                                <div className="w-1.5 h-1.5 rounded-full bg-indigo-500 animate-ping" />
                                <span className="text-[10px] text-indigo-600 font-bold uppercase tracking-wider">Production in progress</span>
                              </div>
                            )}
                          </div>

                          {/* Script */}
                          <h4 className="text-2xl font-bold text-slate-800 leading-snug mb-6 pr-12 font-archivo">
                            "{scene.script}"
                          </h4>

                          {/* Production Specs Box */}
                          <div className="mt-auto bg-slate-50/80 rounded-[20px] p-5 border border-slate-100 grid grid-cols-3 gap-6 group-hover:bg-white group-hover:shadow-sm transition-all">
                            <div className="space-y-2">
                              <div className="flex items-center gap-2 text-[10px] font-black text-slate-400 uppercase tracking-widest font-archivo">
                                <Palette className="w-3.5 h-3.5" /> Visuals
                              </div>
                              <p className="text-xs text-slate-600 leading-relaxed font-medium">
                                {scene.specs.visuals}
                              </p>
                            </div>
                            
                            <div className="space-y-2 border-l border-slate-200/60 pl-6">
                              <div className="flex items-center gap-2 text-[10px] font-black text-slate-400 uppercase tracking-widest font-archivo">
                                <Wind className="w-3.5 h-3.5" /> Animation
                              </div>
                              <p className="text-xs text-slate-600 leading-relaxed font-medium">
                                {scene.specs.animation}
                              </p>
                            </div>

                            <div className="space-y-2 border-l border-slate-200/60 pl-6">
                              <div className="flex items-center gap-2 text-[10px] font-black text-slate-400 uppercase tracking-widest font-archivo">
                                <Volume2 className="w-3.5 h-3.5" /> SFX
                              </div>
                              <p className="text-xs text-slate-600 leading-relaxed font-medium">
                                {scene.specs.sfx}
                              </p>
                            </div>
                          </div>
                        </div>
                        
                        {/* Actions Menu */}
                        <div className="absolute top-5 right-5 opacity-0 group-hover:opacity-100 transition-opacity">
                          <Button variant="ghost" size="icon" className="h-10 w-10 text-slate-400 hover:text-slate-900 rounded-full hover:bg-slate-50 border border-transparent hover:border-slate-100">
                            <MoreHorizontal className="w-5 h-5" />
                          </Button>
                        </div>
                      </div>
                    </motion.div>
                  ))}
                </div>

                {/* Fixed Global Audio Footer */}
                <div className="sticky bottom-6 left-6 right-6 mx-auto max-w-3xl z-30">
                   <div className="bg-slate-900/95 backdrop-blur-xl text-white rounded-full p-2 pl-7 pr-2 shadow-2xl flex items-center justify-between border border-white/10 ring-1 ring-white/5">
                      <div className="flex items-center gap-10">
                        {/* Voice */}
                        <button className="flex items-center gap-3.5 hover:opacity-80 transition-opacity group">
                          <div className="w-9 h-9 rounded-full bg-gradient-to-tr from-indigo-500 to-blue-500 flex items-center justify-center shadow-lg shadow-indigo-500/20">
                            <User className="w-4.5 h-4.5 text-white" />
                          </div>
                          <div className="text-left">
                            <p className="text-[10px] text-slate-400 uppercase tracking-[0.15em] font-black font-archivo">Voiceover</p>
                            <div className="flex items-center gap-2">
                              <span className="text-sm font-bold font-archivo tracking-tight">Brittney</span>
                              <div className="flex items-center gap-1.5">
                                <span className="w-1 h-1 rounded-full bg-slate-700" />
                                <span className="text-[10px] text-slate-500 font-bold uppercase tracking-wider">English Soft</span>
                              </div>
                              <ChevronDown className="w-3 h-3 text-slate-600 group-hover:text-white transition-colors" />
                            </div>
                          </div>
                        </button>

                        {/* Divider */}
                        <div className="h-10 w-px bg-white/10" />

                        {/* Music */}
                        <button className="flex items-center gap-3.5 hover:opacity-80 transition-opacity group">
                          <div className="w-9 h-9 rounded-full bg-gradient-to-tr from-emerald-500 to-teal-500 flex items-center justify-center shadow-lg shadow-emerald-500/20">
                            <Music className="w-4.5 h-4.5 text-white" />
                          </div>
                          <div className="text-left">
                            <p className="text-[10px] text-slate-400 uppercase tracking-[0.15em] font-black font-archivo">Music</p>
                            <div className="flex items-center gap-2">
                              <span className="text-sm font-bold font-archivo tracking-tight">Morning Adventure</span>
                              <div className="flex items-center gap-1.5">
                                <span className="w-1 h-1 rounded-full bg-slate-700" />
                                <span className="text-[10px] text-slate-500 font-bold uppercase tracking-wider">Upbeat</span>
                              </div>
                              <ChevronDown className="w-3 h-3 text-slate-600 group-hover:text-white transition-colors" />
                            </div>
                          </div>
                        </button>
                      </div>

                      <Button className="bg-white text-slate-950 hover:bg-slate-100 rounded-full px-8 h-12 font-black text-xs uppercase tracking-widest font-archivo shadow-xl shadow-white/10 active:scale-95 transition-all">
                        Generate All
                      </Button>
                   </div>
                </div>
              </motion.div>
            )}

            {/* --- PREVIEW TAB --- */}
            {activeTab === 'preview' && (
              <motion.div 
                key="preview-view"
                className="absolute inset-0 flex flex-col items-center justify-center bg-slate-50/50"
                initial={{ opacity: 0, scale: 0.95 }}
                animate={{ opacity: 1, scale: 1 }}
                exit={{ opacity: 0, scale: 1.05 }}
                transition={{ duration: 0.3 }}
              >
                {/* Main Preview Container */}
                <div className="flex-1 w-full max-w-7xl flex flex-col items-center justify-center relative p-8">
                  {/* Vertical Phone Frame / Pedestal */}
                  <motion.div 
                    className="relative w-[360px] h-[640px] bg-white rounded-[32px] shadow-2xl shadow-slate-300 overflow-hidden border border-white ring-1 ring-slate-100 group"
                    initial={{ y: 20 }}
                    animate={{ y: 0 }}
                  >
                    {/* Video Screen */}
                    <div className="absolute inset-0 bg-slate-900">
                      <img 
                        src={currentScene.thumbnailUrl}
                        className="w-full h-full object-cover opacity-80"
                        alt="Scene Preview"
                      />
                      <div className="absolute inset-0 bg-gradient-to-b from-black/10 via-transparent to-black/60" />
                    </div>

                    {/* Captions Overlay */}
                    <div className="absolute bottom-20 left-0 right-0 px-6 text-center">
                      <motion.p 
                        key={currentScene.id}
                        initial={{ opacity: 0, y: 10 }}
                        animate={{ opacity: 1, y: 0 }}
                        exit={{ opacity: 0, y: -10 }}
                        className="text-white font-archivo font-bold text-xl leading-snug drop-shadow-md"
                      >
                        "{currentScene.script}"
                      </motion.p>
                    </div>

                    {/* Play/Pause Overlay Button */}
                    <AnimatePresence>
                      {!isPlaying && (
                        <motion.button 
                          initial={{ opacity: 0, scale: 0.8 }}
                          animate={{ opacity: 1, scale: 1 }}
                          exit={{ opacity: 0, scale: 1.2 }}
                          onClick={() => setIsPlaying(true)}
                          className="absolute inset-0 m-auto w-20 h-20 bg-white/20 backdrop-blur-md rounded-full flex items-center justify-center text-white border border-white/40 shadow-xl hover:scale-110 transition-transform z-10"
                        >
                          <Play className="w-8 h-8 ml-1 fill-white" />
                        </motion.button>
                      )}
                    </AnimatePresence>

                    {/* Progress Bar (Phone internal) */}
                    <div className="absolute top-2 left-2 right-2 flex gap-1 z-20">
                      {SCENES.map((scene, idx) => (
                        <div key={idx} className="h-1 flex-1 bg-white/30 rounded-full overflow-hidden">
                          <motion.div 
                            className="h-full bg-white"
                            initial={{ width: "0%" }}
                            animate={{ 
                              width: currentScene.id === scene.id 
                                ? "100%" 
                                : SCENES.indexOf(currentScene) > idx ? "100%" : "0%"
                            }}
                            transition={{ duration: currentScene.id === scene.id && isPlaying ? 5 : 0, ease: "linear" }}
                          />
                        </div>
                      ))}
                    </div>
                  </motion.div>
                </div>

                {/* Bottom Interactive Timeline (Editor Style) */}
                <div className="w-full h-40 bg-white border-t border-slate-100 shadow-[0_-10px_40px_-15px_rgba(0,0,0,0.05)] z-20 flex flex-col">
                  {/* Controls & Scrubber */}
                  <div className="h-14 px-8 flex items-center gap-6 border-b border-slate-50">
                    <div className="flex items-center gap-4">
                      <Button 
                        variant="ghost" 
                        size="icon" 
                        onClick={() => setIsPlaying(!isPlaying)}
                        className="w-10 h-10 rounded-full bg-slate-900 text-white hover:bg-slate-800 hover:scale-105 transition-all"
                      >
                        {isPlaying ? <Pause size={18} fill="currentColor" /> : <Play size={18} fill="currentColor" className="ml-0.5" />}
                      </Button>
                      <div className="flex items-center gap-1 text-slate-400">
                        <Button variant="ghost" size="icon" className="hover:text-slate-900 rounded-full w-8 h-8"><SkipBack size={16} /></Button>
                        <Button variant="ghost" size="icon" className="hover:text-slate-900 rounded-full w-8 h-8"><SkipForward size={16} /></Button>
                      </div>
                      <span className="font-mono text-xs font-medium text-slate-500 min-w-[80px]">
                        {formatTime(currentTime)} <span className="text-slate-300">/</span> {formatTime(duration)}
                      </span>
                    </div>

                    {/* Scrubber */}
                    <div className="flex-1 relative h-8 flex items-center group cursor-pointer" 
                         onClick={(e) => {
                           const rect = e.currentTarget.getBoundingClientRect();
                           const percent = (e.clientX - rect.left) / rect.width;
                           setCurrentTime(Math.min(Math.max(0, percent * duration), duration));
                         }}>
                      <div className="absolute inset-x-0 h-1.5 bg-slate-100 rounded-full overflow-hidden">
                        <motion.div 
                          className="h-full bg-blue-500 rounded-full" 
                          style={{ width: `${(currentTime / duration) * 100}%` }}
                        />
                      </div>
                      <motion.div 
                        className="absolute w-4 h-4 bg-white border-2 border-blue-500 rounded-full shadow-md z-10"
                        style={{ left: `${(currentTime / duration) * 100}%` }}
                        layoutId="scrubber"
                      />
                    </div>

                    <div className="flex items-center gap-2">
                       <Button variant="ghost" size="icon" className="text-slate-400 hover:text-slate-900 rounded-full"><Volume2 size={18} /></Button>
                       <Button variant="ghost" size="icon" className="text-slate-400 hover:text-slate-900 rounded-full"><Maximize2 size={18} /></Button>
                    </div>
                  </div>

                  {/* Filmstrip */}
                  <div className="flex-1 overflow-x-auto px-8 py-3 flex items-center gap-3 no-scrollbar">
                    {SCENES.map((scene, idx) => (
                      <button 
                        key={scene.id}
                        onClick={() => setCurrentTime(parseFloat(scene.startTime.split(':')[1]))}
                        className={cn(
                          "relative h-16 aspect-video rounded-lg overflow-hidden flex-shrink-0 transition-all duration-200 border-2",
                          currentScene.id === scene.id 
                            ? "border-blue-500 ring-2 ring-blue-500/20 scale-105" 
                            : "border-transparent opacity-60 hover:opacity-100 hover:scale-105"
                        )}
                      >
                        <img src={scene.thumbnailUrl} className="w-full h-full object-cover" alt="" />
                        <div className="absolute bottom-0 left-0 right-0 h-6 bg-gradient-to-t from-black/80 to-transparent flex items-end justify-between px-1.5 pb-0.5">
                          <span className="text-[8px] font-bold text-white font-archivo">SCENE {scene.number}</span>
                          <span className="text-[8px] font-mono text-white/80">{scene.endTime}s</span>
                        </div>
                        {currentScene.id === scene.id && (
                          <div className="absolute inset-0 bg-blue-500/10 z-10" />
                        )}
                      </button>
                    ))}
                    {/* Add some fake future scenes to fill space */}
                    {[4, 5, 6].map(i => (
                      <div key={i} className="h-16 aspect-video rounded-lg bg-slate-100 border-2 border-dashed border-slate-200 flex items-center justify-center flex-shrink-0">
                        <span className="text-xs font-bold text-slate-300">SC {i.toString().padStart(2, '0')}</span>
                      </div>
                    ))}
                  </div>
                </div>
              </motion.div>
            )}

          </AnimatePresence>
        </div>
      </motion.div>
    </div>
  );
}
~~~

Implementation Guidelines

1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system

Help me integrate this into my design
All Prompts