     1→'use client';
     2→
     3→import { useState, useCallback, useRef, useEffect } from 'react';
     4→import { motion, AnimatePresence } from 'framer-motion';
     5→import {
     6→  Upload, Image as ImageIcon, Sparkles, Download, ArrowRight,
     7→  Palette, Camera, Layers, SlidersHorizontal, Loader2, Check,
     8→  Trash2, RotateCcw, Eye, Wand2, Sun, Paintbrush, Film,
     9→  Pencil, History, ChevronLeft, X, GripVertical, WandSparkles,
    10→  Square, RectangleVertical, Monitor
    11→} from 'lucide-react';
    12→import { Button } from '@/components/ui/button';
    13→import { Textarea } from '@/components/ui/textarea';
    14→import { Progress } from '@/components/ui/progress';
    15→import { Card, CardContent } from '@/components/ui/card';
    16→import {
    17→  Dialog,
    18→  DialogContent,
    19→  DialogHeader,
    20→  DialogTitle,
    21→  DialogTrigger,
    22→} from '@/components/ui/dialog';
    23→import { useAppStore, type PhotoProject } from '@/store/photo-store';
    24→
    25→/* ─── Edit Tool Definitions ─── */
    26→const EDIT_TOOLS = [
    27→  { id: 'oil-painting', label: 'لوحة زيتية', icon: Paintbrush, prompt: 'Transform this image into an oil painting style, with visible brushstrokes and rich, vibrant colors, maintain the composition and subject', color: 'from-amber-500/20 to-orange-600/20' },
    28→  { id: 'cartoon', label: 'رسم كرتوني', icon: Pencil, prompt: 'Transform this image into a cartoon illustration style, with bold outlines, flat colors, and simplified shapes, keep the main subject recognizable', color: 'from-pink-500/20 to-rose-600/20' },
    29→  { id: 'bw', label: 'أبيض وأسود', icon: Camera, prompt: 'Convert this image to a stunning black and white photograph with high contrast and dramatic lighting, professional photography style', color: 'from-gray-500/20 to-gray-700/20' },
    30→  { id: 'golden-hour', label: 'إضاءة ذهبية', icon: Sun, prompt: 'Apply warm golden hour lighting to this image, with beautiful warm tones, soft shadows, and a magical sunset glow, maintain all subjects', color: 'from-yellow-500/20 to-amber-600/20' },
    31→  { id: 'enhance', label: 'تحسين الجودة', icon: Sparkles, prompt: 'Enhance the quality and sharpness of this image, improve colors, add more detail and clarity, make it look professional and high-resolution', color: 'from-emerald-500/20 to-teal-600/20' },
    32→  { id: 'bg-remove', label: 'خلفية احترافية', icon: Layers, prompt: 'Enhance this photo with a clean neutral studio background while preserving the main subject naturally', color: 'from-cyan-500/20 to-blue-600/20' },
    33→  { id: 'cinematic', label: 'تأثير سينمائي', icon: Film, prompt: 'Apply a cinematic color grading to this image, with deep shadows, teal and orange tones, letterbox style, dramatic and moody atmosphere', color: 'from-violet-500/20 to-purple-600/20' },
    34→  { id: 'illustration', label: 'أسلوب رسومي', icon: Palette, prompt: 'Transform this image into a digital illustration style, clean lines, artistic rendering, vibrant but harmonious colors, maintain the scene composition', color: 'from-fuchsia-500/20 to-pink-600/20' },
    35→];
    36→
    37→/* ─── Header Component ─── */
    38→function Header() {
    39→  const { currentView, setView } = useAppStore();
    40→  return (
    41→    <header className="glass sticky top-0 z-50">
    42→      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
    43→        <button
    44→          onClick={() => setView('home')}
    45→          className="flex items-center gap-3 group"
    46→        >
    47→          <div className="w-9 h-9 rounded-lg bg-primary/20 flex items-center justify-center">
    48→            <Wand2 className="w-5 h-5 text-primary" />
    49→          </div>
    50→          <span className="text-lg font-bold gradient-text">محرر الصور Fouad AI</span>
    51→        </button>
    52→        <nav className="flex items-center gap-1">
    53→          <Button
    54→            variant={currentView === 'home' ? 'default' : 'ghost'}
    55→            size="sm"
    56→            onClick={() => setView('home')}
    57→            className="gap-2"
    58→          >
    59→            <ImageIcon className="w-4 h-4" />
    60→            <span className="hidden sm:inline">الرئيسية</span>
    61→          </Button>
    62→          <Button
    63→            variant={currentView === 'gallery' ? 'default' : 'ghost'}
    64→            size="sm"
    65→            onClick={() => setView('gallery')}
    66→            className="gap-2"
    67→          >
    68→            <History className="w-4 h-4" />
    69→            <span className="hidden sm:inline">المعرض</span>
    70→          </Button>
    71→          <Button
    72→            variant={currentView === 'generate' ? 'default' : 'ghost'}
    73→            size="sm"
    74→            onClick={() => setView('generate')}
    75→            className="gap-2"
    76→          >
    77→            <WandSparkles className="w-4 h-4" />
    78→            <span className="hidden sm:inline">توليد الصور</span>
    79→          </Button>
    80→        </nav>
    81→      </div>
    82→    </header>
    83→  );
    84→}
    85→
    86→/* ─── Footer Component ─── */
    87→function Footer() {
    88→  return (
    89→    <footer className="glass mt-auto">
    90→      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex flex-col sm:flex-row items-center justify-between gap-2 text-sm text-muted-foreground">
    91→        <p>محرر الصور Fouad AI — قوّة الذكاء الاصطناعي بين يديك</p>
    92→        <p>© {new Date().getFullYear()} جميع الحقوق محفوظة</p>
    93→      </div>
    94→    </footer>
    95→  );
    96→}
    97→
    98→/* ─── Upload Area Component ─── */
    99→function UploadArea() {
   100→  const { setOriginalImage, setOriginalFileName, setView, setAnalysis, setEditedImage, setEditError } = useAppStore();
   101→  const [isDragOver, setIsDragOver] = useState(false);
   102→  const [isUploading, setIsUploading] = useState(false);
   103→  const fileInputRef = useRef<HTMLInputElement>(null);
   104→
   105→  const handleFile = useCallback(async (file: File) => {
   106→    if (!file.type.startsWith('image/')) return;
   107→    setIsUploading(true);
   108→    setEditError(null);
   109→    setEditedImage(null);
   110→    setAnalysis(null);
   111→    try {
   112→      const formData = new FormData();
   113→      formData.append('image', file);
   114→
   115→      const res = await fetch('/api/upload', { method: 'POST', body: formData });
   116→      const data = await res.json();
   117→      if (!res.ok) throw new Error(data.error || 'فشل رفع الصورة');
   118→
   119→      setOriginalImage(data.imageUrl);
   120→      setOriginalFileName(file.name);
   121→      setView('editor');
   122→    } catch (err: unknown) {
   123→      const message = err instanceof Error ? err.message : 'حدث خطأ';
   124→      setEditError(message);
   125→    } finally {
   126→      setIsUploading(false);
   127→    }
   128→  }, [setOriginalImage, setOriginalFileName, setView, setEditedImage, setAnalysis, setEditError]);
   129→
   130→  const onDrop = useCallback((e: React.DragEvent) => {
   131→    e.preventDefault();
   132→    setIsDragOver(false);
   133→    const file = e.dataTransfer.files[0];
   134→    if (file) handleFile(file);
   135→  }, [handleFile]);
   136→
   137→  const onDragOver = useCallback((e: React.DragEvent) => {
   138→    e.preventDefault();
   139→    setIsDragOver(true);
   140→  }, []);
   141→
   142→  const onDragLeave = useCallback(() => setIsDragOver(false), []);
   143→
   144→  return (
   145→    <motion.div
   146→      initial={{ opacity: 0, y: 30 }}
   147→      animate={{ opacity: 1, y: 0 }}
   148→      transition={{ duration: 0.6 }}
   149→      className="w-full max-w-2xl mx-auto"
   150→    >
   151→      <div
   152→        onDrop={onDrop}
   153→        onDragOver={onDragOver}
   154→        onDragLeave={onDragLeave}
   155→        onClick={() => fileInputRef.current?.click()}
   156→        className={`
   157→          relative cursor-pointer rounded-2xl border-2 border-dashed p-12 sm:p-16
   158→          transition-all duration-300 text-center
   159→          ${isDragOver
   160→            ? 'upload-area-active border-primary'
   161→            : 'border-muted-foreground/30 hover:border-primary/50 hover:bg-primary/5'
   162→          }
   163→        `}
   164→      >
   165→        <input
   166→          ref={fileInputRef}
   167→          type="file"
   168→          accept="image/*"
   169→          className="hidden"
   170→          onChange={(e) => {
   171→            const file = e.target.files?.[0];
   172→            if (file) handleFile(file);
   173→            e.target.value = '';
   174→          }}
   175→        />
   176→        {isUploading ? (
   177→          <div className="flex flex-col items-center gap-4">
   178→            <Loader2 className="w-12 h-12 text-primary animate-spin" />
   179→            <p className="text-lg text-muted-foreground">جارٍ رفع الصورة...</p>
   180→          </div>
   181→        ) : (
   182→          <div className="flex flex-col items-center gap-4">
   183→            <div className="w-20 h-20 rounded-full bg-primary/10 flex items-center justify-center">
   184→              <Upload className="w-10 h-10 text-primary" />
   185→            </div>
   186→            <div>
   187→              <p className="text-xl font-semibold mb-2">اسحب الصورة هنا أو انقر للاختيار</p>
   188→              <p className="text-muted-foreground text-sm">يدعم: PNG, JPG, WEBP — حتى 10 ميجا</p>
   189→            </div>
   190→          </div>
   191→        )}
   192→      </div>
   193→    </motion.div>
   194→  );
   195→}
   196→
   197→/* ─── Feature Cards ─── */
   198→function FeatureCards() {
   199→  const features = [
   200→    { icon: Sparkles, title: 'تحرير بالذكاء', desc: 'أدوات تعديل ذكية تفهم صورتك وتحسّنها' },
   201→    { icon: Palette, title: 'أنماط فنية', desc: 'حوّل صورك إلى لوحات زيتية أو رسوم كرتونية' },
   202→    { icon: SlidersHorizontal, title: 'مقارنة فورية', desc: 'قارن بين الأصل والنسخة المحرّرة بسهولة' },
   203→    { icon: Download, title: 'تحميل مباشر', desc: 'حمّل الصور المحرّرة بجودة عالية' },
   204→  ];
   205→  return (
   206→    <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 max-w-5xl mx-auto mt-16">
   207→      {features.map((f, i) => (
   208→        <motion.div
   209→          key={f.title}
   210→          initial={{ opacity: 0, y: 20 }}
   211→          animate={{ opacity: 1, y: 0 }}
   212→          transition={{ duration: 0.5, delay: 0.2 + i * 0.1 }}
   213→        >
   214→          <Card className="glass h-full text-center p-4 sm:p-6">
   215→            <CardContent className="p-0 flex flex-col items-center gap-3">
   216→              <div className="w-12 h-12 rounded-xl bg-primary/15 flex items-center justify-center">
   217→                <f.icon className="w-6 h-6 text-primary" />
   218→              </div>
   219→              <h3 className="font-semibold text-sm sm:text-base">{f.title}</h3>
   220→              <p className="text-xs sm:text-sm text-muted-foreground">{f.desc}</p>
   221→            </CardContent>
   222→          </Card>
   223→        </motion.div>
   224→      ))}
   225→    </div>
   226→  );
   227→}
   228→
   229→/* ─── Home View ─── */
   230→function HomeView() {
   231→  return (
   232→    <main className="flex-1 flex flex-col items-center justify-center px-4 py-12">
   233→      <motion.div
   234→        initial={{ opacity: 0, y: -20 }}
   235→        animate={{ opacity: 1, y: 0 }}
   236→        transition={{ duration: 0.5 }}
   237→        className="text-center mb-10"
   238→      >
   239→        <h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-4">
   240→          <span className="gradient-text">محرر الصور Fouad AI</span>
   241→        </h1>
   242→        <p className="text-lg sm:text-xl text-muted-foreground max-w-xl mx-auto">
   243→          ارفع صورتك واختر التأثير المطلوب — وشاهد الذكاء الاصطناعي يُبدع
   244→        </p>
   245→      </motion.div>
   246→      <UploadArea />
   247→      <FeatureCards />
   248→    </main>
   249→  );
   250→}
   251→
   252→/* ─── Before/After Comparison Slider ─── */
   253→function ComparisonSlider({ original, edited }: { original: string; edited: string }) {
   254→  const containerRef = useRef<HTMLDivElement>(null);
   255→  const [position, setPosition] = useState(50);
   256→  const [containerWidth, setContainerWidth] = useState(0);
   257→  const isDragging = useRef(false);
   258→
   259→  useEffect(() => {
   260→    const el = containerRef.current;
   261→    if (!el) return;
   262→    const observer = new ResizeObserver((entries) => {
   263→      for (const entry of entries) {
   264→        setContainerWidth(entry.contentRect.width);
   265→      }
   266→    });
   267→    observer.observe(el);
   268→    return () => observer.disconnect();
   269→  }, []);
   270→
   271→  const updatePosition = useCallback((clientX: number) => {
   272→    if (!containerRef.current) return;
   273→    const rect = containerRef.current.getBoundingClientRect();
   274→    // RTL: position is measured from the right edge
   275→    const x = clientX - rect.left;
   276→    const pct = Math.min(100, Math.max(0, (x / rect.width) * 100));
   277→    setPosition(pct);
   278→  }, []);
   279→
   280→  const handlePointerDown = useCallback((e: React.PointerEvent) => {
   281→    isDragging.current = true;
   282→    (e.target as HTMLElement).setPointerCapture(e.pointerId);
   283→    updatePosition(e.clientX);
   284→  }, [updatePosition]);
   285→
   286→  const handlePointerMove = useCallback((e: React.PointerEvent) => {
   287→    if (!isDragging.current) return;
   288→    updatePosition(e.clientX);
   289→  }, [updatePosition]);
   290→
   291→  const handlePointerUp = useCallback(() => {
   292→    isDragging.current = false;
   293→  }, []);
   294→
   295→  return (
   296→    <div
   297→      ref={containerRef}
   298→      className="comparison-container rounded-xl overflow-hidden bg-black/50 relative w-full"
   299→      style={{ aspectRatio: 'auto' }}
   300→      onPointerDown={handlePointerDown}
   301→      onPointerMove={handlePointerMove}
   302→      onPointerUp={handlePointerUp}
   303→    >
   304→      {/* Edited image (full width, behind) */}
   305→      <img
   306→        src={edited}
   307→        alt="After"
   308→        className="w-full h-auto block"
   309→        draggable={false}
   310→      />
   311→
   312→      {/* Original image (clipped from right in RTL) */}
   313→      <div
   314→        className="absolute inset-0 overflow-hidden"
   315→        style={{ width: `${position}%` }}
   316→      >
   317→        <img
   318→          src={original}
   319→          alt="Before"
   320→          className="w-full h-auto block"
   321→          style={{ width: containerWidth > 0 ? `${containerWidth}px` : '100%' }}
   322→          draggable={false}
   323→        />
   324→      </div>
   325→
   326→      {/* Slider line */}
   327→      <div
   328→        className="comparison-slider-line"
   329→        style={{ left: `${position}%` }}
   330→      >
   331→        <div className="comparison-slider-handle">
   332→          <GripVertical className="w-5 h-5 text-gray-700" />
   333→        </div>
   334→      </div>
   335→
   336→      {/* Labels */}
   337→      <div className="absolute top-3 right-3 bg-black/60 text-white text-xs px-2 py-1 rounded-md">الأصلي</div>
   338→      <div className="absolute top-3 left-3 bg-primary/80 text-white text-xs px-2 py-1 rounded-md">المحرّر</div>
   339→    </div>
   340→  );
   341→}
   342→
   343→/* ─── Editor View ─── */
   344→function EditorView() {
   345→  const {
   346→    originalImage, editedImage, isEditing, editProgress, editError,
   347→    analysis, customPrompt, setCustomPrompt, setEditedImage,
   348→    setEditProgress, setIsEditing, setEditError, setAnalysis,
   349→    setView, resetEditor, projects, setProjects, originalFileName,
   350→  } = useAppStore();
   351→  const [selectedTool, setSelectedTool] = useState<string | null>(null);
   352→  const [lastEditArgs, setLastEditArgs] = useState<{ prompt: string; label: string; toolType: string } | null>(null);
   353→  const [editCount, setEditCount] = useState(0);
   354→  const [isAnalyzing, setIsAnalyzing] = useState(false);
   355→  const fileInputRef = useRef<HTMLInputElement>(null);
   356→
   357→  const handleAnalyze = useCallback(async () => {
   358→    if (!originalImage) return;
   359→    setIsAnalyzing(true);
   360→    try {
   361→      const res = await fetch('/api/analyze', {
   362→        method: 'POST',
   363→        headers: { 'Content-Type': 'application/json' },
   364→        body: JSON.stringify({ imageUrl: originalImage }),
   365→      });
   366→      const data = await res.json();
   367→      if (!res.ok) throw new Error(data.error || 'فشل التحليل');
   368→      setAnalysis(data.analysis);
   369→    } catch (err: unknown) {
   370→      const message = err instanceof Error ? err.message : 'حدث خطأ';
   371→      setEditError(message);
   372→    } finally {
   373→      setIsAnalyzing(false);
   374→    }
   375→  }, [originalImage, setAnalysis, setEditError]);
   376→
   377→  const handleEdit = useCallback(async (prompt: string, label: string, toolType: string) => {
   378→    // Use the last edited image as base for stacking edits
   379→    const baseImage = editedImage || originalImage;
   380→    if (!baseImage) return;
   381→    setLastEditArgs({ prompt, label, toolType });
   382→    setIsEditing(true);
   383→    setEditError(null);
   384→    setEditedImage(null);
   385→    setEditProgress(0);
   386→
   387→    try {
   388→      const res = await fetch('/api/edit', {
   389→        method: 'POST',
   390→        headers: { 'Content-Type': 'application/json' },
   391→        body: JSON.stringify({
   392→          imageUrl: baseImage,
   393→          prompt,
   394→          label,
   395→          toolType,
   396→        }),
   397→      });
   398→
   399→      if (!res.ok) {
   400→        const data = await res.json();
   401→        throw new Error(data.error || 'فشل التعديل');
   402→      }
   403→
   404→      const reader = res.body?.getReader();
   405→      if (!reader) throw new Error('لا يمكن قراءة الاستجابة');
   406→
   407→      const decoder = new TextDecoder();
   408→      let buffer = '';
   409→
   410→      while (true) {
   411→        const { done, value } = await reader.read();
   412→        if (done) break;
   413→
   414→        buffer += decoder.decode(value, { stream: true });
   415→        const lines = buffer.split('\n');
   416→        buffer = lines.pop() || '';
   417→
   418→        for (const line of lines) {
   419→          if (line.startsWith('data: ')) {
   420→            const data = line.slice(6);
   421→            let parsed: Record<string, unknown>;
   422→            try {
   423→              parsed = JSON.parse(data);
   424→            } catch {
   425→              continue; // Skip malformed JSON lines
   426→            }
   427→
   428→            if (parsed.type === 'progress') {
   429→              setEditProgress(parsed.value as number);
   430→            } else if (parsed.type === 'done') {
   431→              setEditedImage(parsed.editedImageUrl as string);
   432→              setEditProgress(100);
   433→              setEditCount((c) => c + 1);
   434→              // Refresh gallery
   435→              try {
   436→                const projectsRes = await fetch('/api/projects');
   437→                if (projectsRes.ok) {
   438→                  const projectsData = await projectsRes.json();
   439→                  setProjects(projectsData);
   440→                }
   441→              } catch { /* ignore gallery refresh failure */ }
   442→            } else if (parsed.type === 'error') {
   443→              throw new Error(parsed.message as string);
   444→            }
   445→          }
   446→        }
   447→      }
   448→    } catch (err: unknown) {
   449→      const message = err instanceof Error ? err.message : 'حدث خطأ أثناء التعديل';
   450→      setEditError(message);
   451→    } finally {
   452→      setIsEditing(false);
   453→      setSelectedTool(null);
   454→    }
   455→  }, [originalImage, editedImage, setIsEditing, setEditError, setEditedImage, setEditProgress, setProjects]);
   456→
   457→  const handleCustomEdit = useCallback(() => {
   458→    if (!customPrompt.trim()) return;
   459→    handleEdit(customPrompt.trim(), 'تعديل مخصص', 'custom');
   460→  }, [customPrompt, handleEdit]);
   461→
   462→  const handleNewImage = useCallback(() => {
   463→    resetEditor();
   464→    setView('home');
   465→  }, [resetEditor, setView]);
   466→
   467→  const handleResetToOriginal = useCallback(() => {
   468→    setEditedImage(null);
   469→    setEditCount(0);
   470→    setEditError(null);
   471→  }, [setEditedImage, setEditError]);
   472→
   473→  const handleReupload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
   474→    const file = e.target.files?.[0];
   475→    if (!file || !file.type.startsWith('image/')) return;
   476→    const formData = new FormData();
   477→    formData.append('image', file);
   478→    try {
   479→      const res = await fetch('/api/upload', { method: 'POST', body: formData });
   480→      const data = await res.json();
   481→      if (!res.ok) throw new Error(data.error);
   482→      useAppStore.getState().setOriginalImage(data.imageUrl);
   483→      useAppStore.getState().setOriginalFileName(file.name);
   484→      useAppStore.getState().setEditedImage(null);
   485→      useAppStore.getState().setAnalysis(null);
   486→    } catch {}
   487→    e.target.value = '';
   488→  }, []);
   489→
   490→  const handleDownload = useCallback(() => {
   491→    if (!editedImage) return;
   492→    const a = document.createElement('a');
   493→    a.href = editedImage;
   494→    const ext = originalFileName?.split('.').pop() || 'png';
   495→    const baseName = originalFileName ? originalFileName.replace(/\.[^.]+$/, '') : 'image';
   496→    a.download = `Fouad-AI-${baseName}.${ext}`;
   497→    a.click();
   498→  }, [editedImage, originalFileName]);
   499→
   500→  return (
   501→    <main className="flex-1 px-4 py-6 max-w-7xl mx-auto w-full">
   502→      {/* Top bar */}
   503→      <div className="flex items-center justify-between mb-6">
   504→        <div className="flex items-center gap-2">
   505→          <Button variant="ghost" onClick={handleNewImage} className="gap-2">
   506→            <ChevronLeft className="w-4 h-4" />
   507→            صورة جديدة
   508→          </Button>
   509→          {editedImage && (
   510→            <Button variant="outline" size="sm" onClick={handleResetToOriginal} className="gap-1.5 text-xs">
   511→              <RotateCcw className="w-3.5 h-3.5" />
   512→              العودة للأصل
   513→            </Button>
   514→          )}
   515→          {editCount > 0 && (
   516→            <span className="text-xs text-muted-foreground bg-muted/50 px-2 py-1 rounded-full">
   517→              {editCount} تعديل{editCount > 1 ? 'ات' : ''}
   518→            </span>
   519→          )}
   520→        </div>
   521→        {editedImage && (
   522→          <Button onClick={handleDownload} className="gap-2">
   523→            <Download className="w-4 h-4" />
   524→            تحميل الصورة
   525→          </Button>
   526→        )}
   527→      </div>
   528→
   529→      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
   530→        {/* Image Preview (2/3 width on desktop) */}
   531→        <div className="lg:col-span-2">
   532→          <Card className="glass overflow-hidden">
   533→            <CardContent className="p-0 relative">
   534→              {/* Image display */}
   535→              <div className="relative min-h-[300px] sm:min-h-[400px] flex items-center justify-center bg-black/30">
   536→                {isEditing && (
   537→                  <div className="absolute inset-0 z-20 flex flex-col items-center justify-center bg-black/50 backdrop-blur-sm">
   538→                    <Loader2 className="w-12 h-12 text-primary animate-spin mb-4" />
   539→                    <p className="text-lg font-semibold mb-2">جارٍ التعديل بالذكاء الاصطناعي...</p>
   540→                    <Progress value={editProgress} className="w-48 h-2" />
   541→                    <p className="text-sm text-muted-foreground mt-2">{editProgress}%</p>
   542→                  </div>
   543→                )}
   544→
   545→                {editedImage ? (
   546→                  <ComparisonSlider original={originalImage!} edited={editedImage} />
   547→                ) : (
   548→                  <img
   549→                    src={originalImage!}
   550→                    alt="Original"
   551→                    className="max-w-full max-h-[70vh] object-contain mx-auto"
   552→                  />
   553→                )}
   554→              </div>
   555→
   556→              {/* Image info bar */}
   557→              <div className="p-3 border-t border-border/50 flex items-center justify-between text-sm text-muted-foreground">
   558→                <span className="truncate max-w-[60%]">{originalFileName || 'صورة'}</span>
   559→                <Button variant="ghost" size="sm" className="gap-1 text-xs h-8" onClick={() => fileInputRef.current?.click()}>
   560→                  <RotateCcw className="w-3 h-3" />
   561→                  تغيير الصورة
   562→                </Button>
   563→                <input ref={fileInputRef} type="file" accept="image/*" className="hidden" onChange={handleReupload} />
   564→              </div>
   565→            </CardContent>
   566→          </Card>
   567→
   568→          {/* Analysis section */}
   569→          <div className="mt-4">
   570→            <Button
   571→              variant="outline"
   572→              onClick={handleAnalyze}
   573→              disabled={isAnalyzing || !originalImage}
   574→              className="w-full gap-2 mb-3"
   575→            >
   576→              {isAnalyzing ? (
   577→                <Loader2 className="w-4 h-4 animate-spin" />
   578→              ) : (
   579→                <Eye className="w-4 h-4" />
   580→              )}
   581→              تحليل الصورة بالذكاء الاصطناعي
   582→            </Button>
   583→            <AnimatePresence>
   584→              {analysis && (
   585→                <motion.div
   586→                  initial={{ opacity: 0, height: 0 }}
   587→                  animate={{ opacity: 1, height: 'auto' }}
   588→                  exit={{ opacity: 0, height: 0 }}
   589→                >
   590→                  <Card className="glass">
   591→                    <CardContent className="p-4">
   592→                      <h3 className="text-sm font-semibold mb-2 flex items-center gap-2">
   593→                        <Eye className="w-4 h-4 text-primary" />
   594→                        نتيجة التحليل
   595→                      </h3>
   596→                      <p className="text-sm text-muted-foreground leading-relaxed whitespace-pre-wrap">{analysis}</p>
   597→                    </CardContent>
   598→                  </Card>
   599→                </motion.div>
   600→              )}
   601→            </AnimatePresence>
   602→          </div>
   603→        </div>
   604→
   605→        {/* Tools Panel (1/3 width on desktop) */}
   606→        <div className="lg:col-span-1 space-y-4">
   607→          {/* Quick Tools */}
   608→          <Card className="glass">
   609→            <CardContent className="p-4">
   610→              <h3 className="font-semibold mb-3 flex items-center gap-2">
   611→                <Wand2 className="w-4 h-4 text-primary" />
   612→                أدوات التحرير السريعة
   613→              </h3>
   614→              <div className="grid grid-cols-2 gap-2">
   615→                {EDIT_TOOLS.map((tool) => {
   616→                  const Icon = tool.icon;
   617→                  const isLoading = isEditing && selectedTool === tool.id;
   618→                  return (
   619→                    <button
   620→                      key={tool.id}
   621→                      onClick={() => {
   622→                        if (isEditing) return;
   623→                        setSelectedTool(tool.id);
   624→                        handleEdit(tool.prompt, tool.label, 'quick-tool');
   625→                      }}
   626→                      disabled={isEditing}
   627→                      className={`
   628→                        tool-card relative flex flex-col items-center gap-2 p-3 rounded-xl
   629→                        border border-border/50 text-center transition-all
   630→                        ${isLoading ? 'ring-2 ring-primary' : 'hover:border-primary/40'}
   631→                        ${isEditing ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
   632→                      `}
   633→                    >
   634→                      <div className={`w-10 h-10 rounded-lg bg-gradient-to-br ${tool.color} flex items-center justify-center`}>
   635→                        {isLoading ? (
   636→                          <Loader2 className="w-5 h-5 text-primary animate-spin" />
   637→                        ) : (
   638→                          <Icon className="w-5 h-5 text-foreground" />
   639→                        )}
   640→                      </div>
   641→                      <span className="text-xs font-medium">{tool.label}</span>
   642→                    </button>
   643→                  );
   644→                })}
   645→              </div>
   646→            </CardContent>
   647→          </Card>
   648→
   649→          {/* Custom Prompt */}
   650→          <Card className="glass">
   651→            <CardContent className="p-4">
   652→              <h3 className="font-semibold mb-3 flex items-center gap-2">
   653→                <Pencil className="w-4 h-4 text-primary" />
   654→                تعديل مخصص
   655→              </h3>
   656→              <Textarea
   657→                value={customPrompt}
   658→                onChange={(e) => setCustomPrompt(e.target.value)}
   659→                placeholder="صِف التعديل الذي تريده... مثال: غيّر الخلفية إلى شاطئ عند الغروب"
   660→                className="min-h-[100px] resize-none mb-3"
   661→                disabled={isEditing}
   662→              />
   663→              <Button
   664→                onClick={handleCustomEdit}
   665→                disabled={isEditing || !customPrompt.trim()}
   666→                className="w-full gap-2"
   667→              >
   668→                {isEditing ? (
   669→                  <Loader2 className="w-4 h-4 animate-spin" />
   670→                ) : (
   671→                  <Sparkles className="w-4 h-4" />
   672→                )}
   673→                تطبيق التعديل
   674→              </Button>
   675→            </CardContent>
   676→          </Card>
   677→
   678→          {/* Error display */}
   679→          <AnimatePresence>
   680→            {editError && (
   681→              <motion.div
   682→                initial={{ opacity: 0, y: 10 }}
   683→                animate={{ opacity: 1, y: 0 }}
   684→                exit={{ opacity: 0, y: -10 }}
   685→              >
   686→                <Card className="border-destructive/50 bg-destructive/10">
   687→                  <CardContent className="p-4 flex items-start gap-3">
   688→                    <X className="w-5 h-5 text-destructive mt-0.5 shrink-0" />
   689→                    <div className="flex-1">
   690→                      <p className="text-sm font-medium text-destructive">حدث خطأ</p>
   691→                      <p className="text-xs text-muted-foreground mt-1">{editError}</p>
   692→                    </div>
   693→                    {lastEditArgs && (
   694→                      <Button
   695→                        variant="outline"
   696→                        size="sm"
   697→                        className="shrink-0 gap-1 text-xs h-8"
   698→                        onClick={() => {
   699→                          setEditError(null);
   700→                          handleEdit(lastEditArgs.prompt, lastEditArgs.label, lastEditArgs.toolType);
   701→                        }}
   702→                      >
   703→                        <RotateCcw className="w-3 h-3" />
   704→                        إعادة المحاولة
   705→                      </Button>
   706→                    )}
   707→                  </CardContent>
   708→                </Card>
   709→              </motion.div>
   710→            )}
   711→          </AnimatePresence>
   712→        </div>
   713→      </div>
   714→    </main>
   715→  );
   716→}
   717→
   718→/* ─── Gallery View ─── */
   719→function GalleryView() {
   720→  const { projects, setProjects, setView, setOriginalImage, setOriginalFileName, setEditedImage, setAnalysis } = useAppStore();
   721→  const [isLoading, setIsLoading] = useState(true);
   722→
   723→  useEffect(() => {
   724→    const loadProjects = async () => {
   725→      try {
   726→        const res = await fetch('/api/projects');
   727→        if (res.ok) {
   728→          const data = await res.json();
   729→          setProjects(data);
   730→        }
   731→      } catch {}
   732→      setIsLoading(false);
   733→    };
   734→    loadProjects();
   735→  }, [setProjects]);
   736→
   737→  const handleDelete = useCallback(async (id: string) => {
   738→    try {
   739→      const res = await fetch(`/api/projects/${id}`, { method: 'DELETE' });
   740→      if (res.ok) {
   741→        setProjects(projects.filter((p) => p.id !== id));
   742→      }
   743→    } catch {}
   744→  }, [projects, setProjects]);
   745→
   746→  const handleOpen = useCallback((project: PhotoProject) => {
   747→    const lastEdit = project.edits?.[project.edits.length - 1];
   748→    if (lastEdit?.editedPath) {
   749→      setOriginalImage(lastEdit.originalPath);
   750→      setEditedImage(lastEdit.editedPath);
   751→      setOriginalFileName(project.title);
   752→      setAnalysis(null);
   753→      setView('editor');
   754→    } else if (lastEdit) {
   755→      setOriginalImage(lastEdit.originalPath);
   756→      setEditedImage(null);
   757→      setOriginalFileName(project.title);
   758→      setAnalysis(null);
   759→      setView('editor');
   760→    }
   761→  }, [setOriginalImage, setEditedImage, setOriginalFileName, setAnalysis, setView]);
   762→
   763→  if (isLoading) {
   764→    return (
   765→      <main className="flex-1 flex items-center justify-center">
   766→        <Loader2 className="w-8 h-8 text-primary animate-spin" />
   767→      </main>
   768→    );
   769→  }
   770→
   771→  return (
   772→    <main className="flex-1 px-4 py-8 max-w-6xl mx-auto w-full">
   773→      <motion.div
   774→        initial={{ opacity: 0, y: -10 }}
   775→        animate={{ opacity: 1, y: 0 }}
   776→        className="text-center mb-8"
   777→      >
   778→        <h2 className="text-3xl font-bold mb-2">
   779→          <span className="gradient-text">المعرض</span>
   780→        </h2>
   781→        <p className="text-muted-foreground">جميع مشاريع تعديل الصور السابقة</p>
   782→      </motion.div>
   783→
   784→      {projects.length === 0 ? (
   785→        <motion.div
   786→          initial={{ opacity: 0 }}
   787→          animate={{ opacity: 1 }}
   788→          className="text-center py-20"
   789→        >
   790→          <div className="w-20 h-20 rounded-full bg-muted/30 flex items-center justify-center mx-auto mb-4">
   791→            <ImageIcon className="w-10 h-10 text-muted-foreground" />
   792→          </div>
   793→          <p className="text-lg text-muted-foreground mb-4">لا توجد مشاريع بعد</p>
   794→          <Button onClick={() => setView('home')} className="gap-2">
   795→            <Upload className="w-4 h-4" />
   796→            ابدأ بتعديل صورة
   797→          </Button>
   798→        </motion.div>
   799→      ) : (
   800→        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
   801→          {projects.map((project, i) => {
   802→            const lastEdit = project.edits?.[project.edits.length - 1];
   803→            const thumbnail = lastEdit?.editedPath || lastEdit?.originalPath || '';
   804→            return (
   805→              <motion.div
   806→                key={project.id}
   807→                initial={{ opacity: 0, y: 20 }}
   808→                animate={{ opacity: 1, y: 0 }}
   809→                transition={{ delay: i * 0.05 }}
   810→              >
   811→                <Card className="glass overflow-hidden group cursor-pointer hover:border-primary/40 transition-all" onClick={() => handleOpen(project)}>
   812→                  <div className="aspect-video bg-black/30 relative overflow-hidden">
   813→                    {thumbnail ? (
   814→                      <img src={thumbnail} alt={project.title} className="w-full h-full object-cover" />
   815→                    ) : (
   816→                      <div className="w-full h-full flex items-center justify-center">
   817→                        <ImageIcon className="w-8 h-8 text-muted-foreground" />
   818→                      </div>
   819→                    )}
   820→                    <div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-colors flex items-center justify-center">
   821→                      <span className="opacity-0 group-hover:opacity-100 transition-opacity bg-white/20 backdrop-blur-sm px-3 py-1.5 rounded-lg text-sm font-medium">
   822→                        فتح المشروع
   823→                      </span>
   824→                    </div>
   825→                  </div>
   826→                  <CardContent className="p-3 flex items-center justify-between">
   827→                    <div>
   828→                      <p className="font-medium text-sm truncate">{project.title}</p>
   829→                      <p className="text-xs text-muted-foreground">
   830→                        {new Date(project.createdAt).toLocaleDateString('ar-EG')}
   831→                        {project.edits?.length ? ` — ${project.edits.length} تعديل` : ''}
   832→                      </p>
   833→                    </div>
   834→                    <Button
   835→                      variant="ghost"
   836→                      size="icon"
   837→                      className="h-8 w-8 text-muted-foreground hover:text-destructive shrink-0"
   838→                      onClick={(e) => {
   839→                        e.stopPropagation();
   840→                        handleDelete(project.id);
   841→                      }}
   842→                    >
   843→                      <Trash2 className="w-4 h-4" />
   844→                    </Button>
   845→                  </CardContent>
   846→                </Card>
   847→              </motion.div>
   848→            );
   849→          })}
   850→        </div>
   851→      )}
   852→    </main>
   853→  );
   854→}
   855→
   856→/* ─── Generate View ─── */
   857→const SIZE_OPTIONS = [
   858→  { id: 'square', label: 'مربع', icon: Square, desc: '1024×1024', color: 'from-primary/20 to-primary/5' },
   859→  { id: 'portrait', label: 'عمودي', icon: RectangleVertical, desc: '864×1152', color: 'from-amber-500/20 to-amber-600/5' },
   860→  { id: 'landscape', label: 'أفقي', icon: Monitor, desc: '1344×768', color: 'from-emerald-500/20 to-emerald-600/5' },
   861→  { id: 'wide', label: 'عريض', icon: Monitor, desc: '1440×720', color: 'from-violet-500/20 to-violet-600/5' },
   862→];
   863→
   864→function GenerateView() {
   865→  const { setOriginalImage, setOriginalFileName, setView, setEditedImage, setAnalysis } = useAppStore();
   866→  const [prompt, setPrompt] = useState('');
   867→  const [selectedSize, setSelectedSize] = useState('square');
   868→  const [isGenerating, setIsGenerating] = useState(false);
   869→  const [progress, setProgress] = useState(0);
   870→  const [progressMsg, setProgressMsg] = useState('');
   871→  const [generatedImage, setGeneratedImage] = useState<string | null>(null);
   872→  const [error, setError] = useState<string | null>(null);
   873→
   874→  const handleGenerate = useCallback(async () => {
   875→    if (!prompt.trim() || isGenerating) return;
   876→    setIsGenerating(true);
   877→    setError(null);
   878→    setGeneratedImage(null);
   879→    setProgress(0);
   880→
   881→    try {
   882→      const res = await fetch('/api/generate', {
   883→        method: 'POST',
   884→        headers: { 'Content-Type': 'application/json' },
   885→        body: JSON.stringify({ prompt: prompt.trim(), sizeId: selectedSize }),
   886→      });
   887→
   888→      const reader = res.body?.getReader();
   889→      if (!reader) throw new Error('لا يمكن قراءة الاستجابة');
   890→
   891→      const decoder = new TextDecoder();
   892→      let buffer = '';
   893→
   894→      while (true) {
   895→        const { done, value } = await reader.read();
   896→        if (done) break;
   897→        buffer += decoder.decode(value, { stream: true });
   898→        const lines = buffer.split('\n');
   899→        buffer = lines.pop() || '';
   900→
   901→        for (const line of lines) {
   902→          if (!line.startsWith('data: ')) continue;
   903→          try {
   904→            const parsed = JSON.parse(line.slice(6));
   905→            if (parsed.type === 'progress') {
   906→              setProgress(parsed.value);
   907→              if (parsed.message) setProgressMsg(parsed.message);
   908→            } else if (parsed.type === 'done') {
   909→              setGeneratedImage(parsed.imageUrl);
   910→              setProgress(100);
   911→            } else if (parsed.type === 'error') {
   912→              throw new Error(parsed.message);
   913→            }
   914→          } catch (e: unknown) {
   915→            if (e instanceof Error && e.message !== 'Unexpected end of JSON input') {
   916→              throw e;
   917→            }
   918→          }
   919→        }
   920→      }
   921→    } catch (err: unknown) {
   922→      setError(err instanceof Error ? err.message : 'حدث خطأ');
   923→    } finally {
   924→      setIsGenerating(false);
   925→    }
   926→  }, [prompt, selectedSize, isGenerating]);
   927→
   928→  const handleSendToEditor = useCallback(() => {
   929→    if (!generatedImage) return;
   930→    setOriginalImage(generatedImage);
   931→    setOriginalFileName('Fouad-AI-generated.png');
   932→    setEditedImage(null);
   933→    setAnalysis(null);
   934→    setView('editor');
   935→  }, [generatedImage, setOriginalImage, setOriginalFileName, setEditedImage, setAnalysis, setView]);
   936→
   937→  const handleDownload = useCallback(() => {
   938→    if (!generatedImage) return;
   939→    const a = document.createElement('a');
   940→    a.href = generatedImage;
   941→    a.download = 'Fouad-AI-generated.png';
   942→    a.click();
   943→  }, [generatedImage]);
   944→
   945→  return (
   946→    <main className="flex-1 px-4 py-6 max-w-5xl mx-auto w-full">
   947→      <motion.div
   948→        initial={{ opacity: 0, y: -10 }}
   949→        animate={{ opacity: 1, y: 0 }}
   950→        className="text-center mb-8"
   951→      >
   952→        <h2 className="text-3xl font-bold mb-2">
   953→          <span className="gradient-text">رسم الصور بالذكاء</span>
   954→        </h2>
   955→        <p className="text-muted-foreground">صِف الصورة التي تريدها وسنرسمها لك</p>
   956→      </motion.div>
   957→
   958→      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
   959→        {/* Left: Input */}
   960→        <div className="space-y-4">
   961→          {/* Prompt */}
   962→          <Card className="glass">
   963→            <CardContent className="p-4">
   964→              <h3 className="font-semibold mb-3 flex items-center gap-2">
   965→                <Pencil className="w-4 h-4 text-primary" />
   966→                وصف الصورة
   967→              </h3>
   968→              <Textarea
   969→                value={prompt}
   970→                onChange={(e) => setPrompt(e.target.value)}
   971→                placeholder="مثال: قطة جميلة تجلس في حديقة مليئة بالزهور عند الغروب..."
   972→                className="min-h-[120px] resize-none mb-3"
   973→                disabled={isGenerating}
   974→              />
   975→              <p className="text-xs text-muted-foreground mb-3">
   976→                يمكنك الكتابة بالعربية أو الإنجليزية
   977→              </p>
   978→
   979→              {/* Size selector */}
   980→              <h4 className="text-sm font-medium mb-2">حجم الصورة</h4>
   981→              <div className="grid grid-cols-4 gap-2">
   982→                {SIZE_OPTIONS.map((s) => {
   983→                  const Icon = s.icon;
   984→                  return (
   985→                    <button
   986→                      key={s.id}
   987→                      onClick={() => setSelectedSize(s.id)}
   988→                      disabled={isGenerating}
   989→                      className={`
   990→                        flex flex-col items-center gap-1.5 p-2.5 rounded-xl border text-center transition-all
   991→                        ${selectedSize === s.id
   992→                          ? 'border-primary bg-primary/10 ring-1 ring-primary/30'
   993→                          : 'border-border/50 hover:border-primary/30'}
   994→                        ${isGenerating ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
   995→                      `}
   996→                    >
   997→                      <Icon className="w-4 h-4 text-foreground" />
   998→                      <span className="text-xs font-medium">{s.label}</span>
   999→                      <span className="text-[10px] text-muted-foreground">{s.desc}</span>
  1000→                    </button>
  1001→                  );
  1002→                })}
  1003→              </div>
  1004→
  1005→              {/* Generate button */}
  1006→              <Button
  1007→                onClick={handleGenerate}
  1008→                disabled={isGenerating || !prompt.trim()}
  1009→                className="w-full gap-2 mt-4"
  1010→                size="lg"
  1011→              >
  1012→                {isGenerating ? (
  1013→                  <Loader2 className="w-5 h-5 animate-spin" />
  1014→                ) : (
  1015→                  <WandSparkles className="w-5 h-5" />
  1016→                )}
  1017→                {isGenerating ? 'جارٍ الرسم...' : 'ارسم الصورة'}
  1018→              </Button>
  1019→            </CardContent>
  1020→          </Card>
  1021→
  1022→          {/* Error */}
  1023→          <AnimatePresence>
  1024→            {error && (
  1025→              <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }}>
  1026→                <Card className="border-destructive/50 bg-destructive/10">
  1027→                  <CardContent className="p-4 flex items-start gap-3">
  1028→                    <X className="w-5 h-5 text-destructive mt-0.5 shrink-0" />
  1029→                    <div>
  1030→                      <p className="text-sm font-medium text-destructive">خطأ</p>
  1031→                      <p className="text-xs text-muted-foreground mt-1">{error}</p>
  1032→                    </div>
  1033→                  </CardContent>
  1034→                </Card>
  1035→              </motion.div>
  1036→            )}
  1037→          </AnimatePresence>
  1038→        </div>
  1039→
  1040→        {/* Right: Result */}
  1041→        <div>
  1042→          <Card className="glass overflow-hidden">
  1043→            <CardContent className="p-0">
  1044→              <div className="relative min-h-[400px] flex items-center justify-center bg-black/30">
  1045→                {isGenerating && (
  1046→                  <div className="absolute inset-0 z-10 flex flex-col items-center justify-center bg-black/50 backdrop-blur-sm">
  1047→                    <div className="relative w-20 h-20 mb-4">
  1048→                      <Loader2 className="w-20 h-20 text-primary animate-spin" />
  1049→                      <div className="absolute inset-0 flex items-center justify-center">
  1050→                        <span className="text-lg font-bold">{progress}%</span>
  1051→                      </div>
  1052→                    </div>
  1053→                    <p className="text-sm font-medium">{progressMsg || 'جارٍ الرسم...'}</p>
  1054→                    <Progress value={progress} className="w-48 h-1.5 mt-3" />
  1055→                  </div>
  1056→                )}
  1057→
  1058→                {generatedImage ? (
  1059→                  <img
  1060→                    src={generatedImage}
  1061→                    alt="Generated"
  1062→                    className="w-full h-auto block"
  1063→                  />
  1064→                ) : !isGenerating ? (
  1065→                  <div className="flex flex-col items-center gap-4 py-16">
  1066→                    <div className="w-20 h-20 rounded-full bg-muted/20 flex items-center justify-center">
  1067→                      <WandSparkles className="w-10 h-10 text-muted-foreground/50" />
  1068→                    </div>
  1069→                    <p className="text-muted-foreground text-center px-4">
  1070→                      الصورة المرسومة ستظهر هنا
  1071→                    </p>
  1072→                  </div>
  1073→                ) : null}
  1074→              </div>
  1075→
  1076→              {/* Action buttons */}
  1077→              {generatedImage && (
  1078→                <div className="p-3 border-t border-border/50 flex items-center gap-2">
  1079→                  <Button onClick={handleSendToEditor} className="flex-1 gap-2" size="sm">
  1080→                    <ArrowRight className="w-4 h-4" />
  1081→                    تعديل الصورة
  1082→                  </Button>
  1083→                  <Button onClick={handleDownload} variant="outline" className="gap-2" size="sm">
  1084→                    <Download className="w-4 h-4" />
  1085→                    تحميل
  1086→                  </Button>
  1087→                </div>
  1088→              )}
  1089→            </CardContent>
  1090→          </Card>
  1091→
  1092→          {/* Example prompts */}
  1093→          {!generatedImage && !isGenerating && (
  1094→            <Card className="glass mt-4">
  1095→              <CardContent className="p-4">
  1096→                <h4 className="text-sm font-medium mb-3 flex items-center gap-2">
  1097→                  <Sparkles className="w-4 h-4 text-primary" />
  1098→                  أفكار للتجربة
  1099→                </h4>
  1100→                <div className="flex flex-wrap gap-2">
  1101→                  {[
  1102→                    'غروب على شاطئ بصخور ملساء',
  1103→                    'مدينة مستقبلية بالليل',
  1104→                    'طائر فيلمنق زاهي الألوان',
  1105→                    'قرية جبلية وسط الضباب',
  1106→                  ].map((example) => (
  1107→                    <button
  1108→                      key={example}
  1109→                      onClick={() => setPrompt(example)}
  1110→                      className="text-xs px-3 py-1.5 rounded-full border border-border/50 hover:border-primary/40 hover:bg-primary/5 transition-all cursor-pointer"
  1111→                    >
  1112→                      {example}
  1113→                    </button>
  1114→                  ))}
  1115→                </div>
  1116→              </CardContent>
  1117→            </Card>
  1118→          )}
  1119→        </div>
  1120→      </div>
  1121→    </main>
  1122→  );
  1123→}
  1124→
  1125→/* ─── Main Client Component ─── */
  1126→export default function HomeClient() {
  1127→  const { currentView, editError, setEditError } = useAppStore();
  1128→
  1129→  // Dismiss errors on click outside
  1130→  useEffect(() => {
  1131→    if (editError) {
  1132→      const timer = setTimeout(() => setEditError(null), 8000);
  1133→      return () => clearTimeout(timer);
  1134→    }
  1135→  }, [editError, setEditError]);
  1136→
  1137→  return (
  1138→    <div className="min-h-screen flex flex-col">
  1139→      <Header />
  1140→      <AnimatePresence mode="wait">
  1141→        {currentView === 'home' && (
  1142→          <motion.div key="home" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1">
  1143→            <HomeView />
  1144→          </motion.div>
  1145→        )}
  1146→        {currentView === 'editor' && (
  1147→          <motion.div key="editor" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1 flex flex-col">
  1148→            <EditorView />
  1149→          </motion.div>
  1150→        )}
  1151→        {currentView === 'gallery' && (
  1152→          <motion.div key="gallery" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1">
  1153→            <GalleryView />
  1154→          </motion.div>
  1155→        )}
  1156→        {currentView === 'generate' && (
  1157→          <motion.div key="generate" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="flex-1 flex flex-col">
  1158→            <GenerateView />
  1159→          </motion.div>
  1160→        )}
  1161→      </AnimatePresence>
  1162→      <Footer />
  1163→    </div>
  1164→  );
  1165→}