﻿/* global React */
/* eslint-disable */
const { useState: useWS, useEffect: useWsEffect, useRef: useWsRef, useCallback: useWsCallback } = React;
const gm = window.getMsg;

/* ── Icons ── */
const IconWS = {
  data: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>,
  chat: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>,
  rocket: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09Z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2Z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg>,
  box: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg>,
  server: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="3" width="20" height="8" rx="2"/><rect x="2" y="13" width="20" height="8" rx="2"/><line x1="6" y1="7" x2="6.01" y2="7"/><line x1="6" y1="17" x2="6.01" y2="17"/></svg>,
  external: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>,
  grid: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>,
  bell: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>,
  moon: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>,
  user: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
  logout: () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>,
  sidebar: () => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="9" y1="3" x2="9" y2="21"/></svg>,
  download: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>,
  send: () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>,
  trash: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4h6v2"/></svg>,
  refresh: () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>,
  folder: () => <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>,
  library: () => <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="3" width="6" height="18"/><rect x="9" y="3" width="6" height="18"/><rect x="16" y="3" width="6" height="18"/></svg>,
  check: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>,
};

/* ── Sidebar ── */
function WsSidebar() {
  const items = [
    { id:'data',  label: window.t('nav.data'),      icon: IconWS.data,     link:'AiMaker Dashboard.html', mod:'data' },
    { id:'chat',  label: window.t('nav.chat'),       icon: IconWS.chat,     link:'Fablab Chat.html',       mod:'fablab' },
    { id:'apps',  label: window.t('nav.apps'),       icon: IconWS.rocket,   link:'Gestion des applications.html', mod:'apps' },
    { id:'prod',  label: window.t('nav.products'),   icon: IconWS.box,      link:'Produits.html',          mod:'products' },
    { id:'srv',   label: window.t('nav.server'),     icon: IconWS.server,   link:'Serveur.html',           mod:'server' },
    { id:'ext',   label: window.t('nav.external'),   icon: IconWS.external, link:'Acceso Externo.html',    mod:'external' },
    { id:'work',  label: window.t('nav.workspace'),  icon: IconWS.grid,     active: true },
  ];
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-logo">A</div>
        <div className="brand-name">AiMaker</div>
        <div className="collapse"><IconWS.sidebar/></div>
      </div>
      {items.map(it => {
        const cls = 'nav-item' + (it.active ? ' active' : '');
        const content = (
          <>
            <span className="nav-icon"><it.icon/></span>
            <span style={{flex:1}}>{it.label}</span>
          </>
        );
        return it.link
          ? <a key={it.id} className={cls} href={it.link} style={{textDecoration:'none'}}>{content}</a>
          : <div key={it.id} className={cls}>{content}</div>;
      })}
      <div className="spacer"/>
      <div className="logout"><IconWS.logout/> {window.t('nav.logout')}</div>
    </aside>
  );
}

/* ── Topbar ── */
function WsTopbar() {
  return (
    <header className="topbar">
      <div className="topbar-title">{window.t('topbar.title')}</div>
      <div/>
      <div className="topbar-actions">
        <window.LangSwitcher/>
        <button className="icon-btn"><IconWS.bell/></button>
        <button className="icon-btn"><IconWS.moon/></button>
        <button className="profile-pill">
          <span className="avatar"><IconWS.user/></span>
          {window.t('topbar.profile')}
        </button>
      </div>
    </header>
  );
}

/* ── Library templates ── */
const LIB_TEMPLATES = [
  {
    id: 'landing',
    emoji: '🚀',
    name: gm('Landing Page', 'Landing Page', 'Landing Page'),
    desc: gm('Página de presentación moderna', 'Page de présentation moderne', 'Modern presentation page'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landing Page</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Inter, -apple-system, sans-serif; background: #f8fafc; color: #1a1a2e; }
.hero { background: linear-gradient(135deg, #6366f1 0%, #7c3aed 100%); color: #fff; padding: 100px 40px; text-align: center; }
.hero h1 { font-size: 3rem; font-weight: 800; margin-bottom: 16px; letter-spacing: -0.02em; }
.hero p { font-size: 1.2rem; opacity: .85; max-width: 500px; margin: 0 auto 36px; }
.btn-hero { background: #fff; color: #6366f1; padding: 16px 42px; border-radius: 100px; font-weight: 700; font-size: 1rem; text-decoration: none; display: inline-block; box-shadow: 0 8px 24px rgba(0,0,0,.15); }
.features { padding: 80px 40px; max-width: 960px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 28px; }
.card { background: #fff; border-radius: 18px; padding: 32px; box-shadow: 0 2px 12px rgba(0,0,0,.06); }
.card-icon { font-size: 2rem; margin-bottom: 14px; }
.card h3 { font-size: 1.1rem; font-weight: 700; margin-bottom: 8px; }
.card p { color: #64748b; font-size: .95rem; line-height: 1.6; }
footer { text-align: center; padding: 40px; color: #94a3b8; font-size: .9rem; border-top: 1px solid #e2e8f0; }
</style>
</head>
<body>
<div class="hero">
  <h1>Votre App 🚀</h1>
  <p>Créez quelque chose d'incroyable avec AIMaker Workspace.</p>
  <a href="#" class="btn-hero">Commencer gratuitement</a>
</div>
<div class="features">
  <div class="card"><div class="card-icon">⚡</div><h3>Ultra rapide</h3><p>Performance optimisée pour offrir la meilleure expérience à vos utilisateurs.</p></div>
  <div class="card"><div class="card-icon">🎨</div><h3>Design moderne</h3><p>Interface élégante qui impressionne dès le premier regard.</p></div>
  <div class="card"><div class="card-icon">🔒</div><h3>Sécurisé</h3><p>Protection de niveau entreprise pour toutes vos données.</p></div>
</div>
<footer>© 2025 AIMaker · Tous droits réservés</footer>
</body>
</html>`,
    },
  },
  {
    id: 'portfolio',
    emoji: '👤',
    name: gm('Portfolio', 'Portfolio', 'Portfolio'),
    desc: gm('Portafolio personal profesional', 'Portfolio personnel professionnel', 'Professional personal portfolio'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Portfolio</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Inter, sans-serif; background: #0f172a; color: #e2e8f0; }
nav { padding: 20px 60px; display: flex; justify-content: space-between; align-items: center; }
nav .logo { font-weight: 800; font-size: 1.3rem; color: #818cf8; }
nav ul { list-style: none; display: flex; gap: 32px; }
nav a { color: #94a3b8; text-decoration: none; font-weight: 500; transition: color .2s; }
nav a:hover { color: #fff; }
.hero { padding: 120px 60px 80px; }
.hero-sub { color: #818cf8; font-weight: 600; margin-bottom: 12px; letter-spacing: .1em; font-size: .9rem; }
.hero h1 { font-size: 4rem; font-weight: 800; line-height: 1.1; letter-spacing: -0.03em; margin-bottom: 20px; }
.hero p { color: #94a3b8; max-width: 500px; font-size: 1.1rem; line-height: 1.7; margin-bottom: 32px; }
.btn-cta { background: #818cf8; color: #fff; padding: 14px 36px; border-radius: 100px; font-weight: 700; text-decoration: none; display: inline-block; }
.projects { padding: 80px 60px; }
.projects h2 { font-size: 2rem; font-weight: 800; margin-bottom: 40px; }
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 24px; }
.proj-card { background: #1e293b; border-radius: 16px; padding: 28px; border: 1px solid #334155; }
.proj-tag { background: #312e81; color: #818cf8; padding: 3px 10px; border-radius: 100px; font-size: .75rem; font-weight: 600; display: inline-block; margin-bottom: 14px; }
.proj-card h3 { font-size: 1.1rem; font-weight: 700; margin-bottom: 8px; }
.proj-card p { color: #94a3b8; font-size: .9rem; line-height: 1.6; }
</style>
</head>
<body>
<nav>
  <div class="logo">Portfolio</div>
  <ul><li><a href="#">Accueil</a></li><li><a href="#">Projets</a></li><li><a href="#">Contact</a></li></ul>
</nav>
<div class="hero">
  <div class="hero-sub">DÉVELOPPEUR · CRÉATEUR</div>
  <h1>Bonjour,<br/>Je suis <span style="color:#818cf8">Votre Nom</span></h1>
  <p>Je crée des expériences digitales mémorables avec passion et précision.</p>
  <a href="#" class="btn-cta">Voir mes projets</a>
</div>
<div class="projects">
  <h2>Projets récents</h2>
  <div class="proj-grid">
    <div class="proj-card"><div class="proj-tag">WEB APP</div><h3>Projet Alpha</h3><p>Application web full-stack avec React et Node.js.</p></div>
    <div class="proj-card"><div class="proj-tag">DESIGN</div><h3>Projet Beta</h3><p>Refonte UI/UX d'une plateforme SaaS B2B.</p></div>
    <div class="proj-card"><div class="proj-tag">IA</div><h3>Projet Gamma</h3><p>Intégration d'un modèle LLM pour automatiser les workflows.</p></div>
  </div>
</div>
</body>
</html>`,
    },
  },
  {
    id: 'dashboard',
    emoji: '📊',
    name: gm('Dashboard', 'Dashboard', 'Dashboard'),
    desc: gm('Panel de analíticas y métricas', "Tableau de bord analytique", 'Analytics & metrics panel'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Inter, sans-serif; background: #f4f5f8; color: #1a1a23; display: flex; min-height: 100vh; }
.sidebar { width: 220px; background: #fff; padding: 24px 16px; display: flex; flex-direction: column; gap: 4px; border-right: 1px solid #ececf1; }
.sidebar .logo { font-weight: 800; font-size: 1.2rem; color: #6366f1; padding: 4px 8px 20px; }
.nav-link { padding: 10px 12px; border-radius: 10px; font-size: .9rem; font-weight: 500; color: #6b6c79; cursor: pointer; transition: background .15s; }
.nav-link:hover { background: #f4f5f8; color: #1a1a23; }
.nav-link.active { background: #eef0ff; color: #6366f1; }
.main { flex: 1; padding: 32px; }
.page-title { font-size: 1.5rem; font-weight: 800; margin-bottom: 24px; }
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 28px; }
.stat-card { background: #fff; border-radius: 14px; padding: 20px; box-shadow: 0 1px 4px rgba(0,0,0,.05); }
.stat-label { font-size: .8rem; color: #9c9da8; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 8px; }
.stat-val { font-size: 1.8rem; font-weight: 800; color: #1a1a23; }
.stat-change { font-size: .8rem; color: #10b981; font-weight: 600; margin-top: 4px; }
.chart-row { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.chart-card { background: #fff; border-radius: 14px; padding: 22px; box-shadow: 0 1px 4px rgba(0,0,0,.05); }
.chart-title { font-weight: 700; margin-bottom: 16px; }
.bar-chart { display: flex; align-items: flex-end; gap: 8px; height: 120px; }
.bar { flex: 1; background: #6366f1; border-radius: 6px 6px 0 0; opacity: .8; transition: opacity .2s; }
.bar:hover { opacity: 1; }
.list-item { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #ececf1; font-size: .9rem; }
.list-item:last-child { border-bottom: none; }
</style>
</head>
<body>
<div class="sidebar">
  <div class="logo">⚡ Dash</div>
  <div class="nav-link active">📊 Aperçu</div>
  <div class="nav-link">📈 Analytics</div>
  <div class="nav-link">👥 Utilisateurs</div>
  <div class="nav-link">⚙️ Paramètres</div>
</div>
<div class="main">
  <div class="page-title">Tableau de bord</div>
  <div class="stats">
    <div class="stat-card"><div class="stat-label">Revenus</div><div class="stat-val">€24,800</div><div class="stat-change">↑ +12% ce mois</div></div>
    <div class="stat-card"><div class="stat-label">Utilisateurs</div><div class="stat-val">1,284</div><div class="stat-change">↑ +8% ce mois</div></div>
    <div class="stat-card"><div class="stat-label">Projets</div><div class="stat-val">48</div><div class="stat-change">↑ +3 nouveaux</div></div>
    <div class="stat-card"><div class="stat-label">Taux conv.</div><div class="stat-val">3.6%</div><div class="stat-change">↑ +0.4% ce mois</div></div>
  </div>
  <div class="chart-row">
    <div class="chart-card">
      <div class="chart-title">Revenus mensuels</div>
      <div class="bar-chart">
        <div class="bar" style="height:45%"></div><div class="bar" style="height:60%"></div><div class="bar" style="height:40%"></div>
        <div class="bar" style="height:75%"></div><div class="bar" style="height:55%"></div><div class="bar" style="height:85%"></div>
        <div class="bar" style="height:70%"></div><div class="bar" style="height:90%"></div><div class="bar" style="height:65%"></div>
        <div class="bar" style="height:100%" style="opacity:1"></div><div class="bar" style="height:80%"></div><div class="bar" style="height:88%"></div>
      </div>
    </div>
    <div class="chart-card">
      <div class="chart-title">Top projets</div>
      <div class="list-item"><span>Project Alpha</span><span style="color:#6366f1;font-weight:700">€8,200</span></div>
      <div class="list-item"><span>Project Beta</span><span style="color:#6366f1;font-weight:700">€6,450</span></div>
      <div class="list-item"><span>Project Gamma</span><span style="color:#6366f1;font-weight:700">€5,100</span></div>
      <div class="list-item"><span>Project Delta</span><span style="color:#6366f1;font-weight:700">€3,800</span></div>
    </div>
  </div>
</div>
</body>
</html>`,
    },
  },
  {
    id: 'ecommerce',
    emoji: '🛍️',
    name: gm('E-commerce', 'E-commerce', 'E-commerce'),
    desc: gm('Tienda online con productos', 'Boutique en ligne avec produits', 'Online shop with products'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Boutique</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Inter, sans-serif; background: #fafafa; color: #111; }
header { background: #fff; padding: 0 40px; height: 64px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #e5e7eb; position: sticky; top: 0; z-index: 10; }
.logo { font-weight: 800; font-size: 1.3rem; }
.logo span { color: #6366f1; }
nav a { margin-left: 28px; text-decoration: none; color: #4b5563; font-weight: 500; font-size: .95rem; }
.cart-btn { background: #6366f1; color: #fff; border: none; padding: 9px 18px; border-radius: 8px; font-weight: 600; cursor: pointer; }
.banner { background: linear-gradient(135deg, #1e1b4b, #312e81); color: #fff; padding: 80px 40px; text-align: center; }
.banner h1 { font-size: 3rem; font-weight: 800; margin-bottom: 14px; }
.banner p { color: #a5b4fc; font-size: 1.1rem; margin-bottom: 28px; }
.btn-shop { background: #818cf8; color: #fff; padding: 14px 40px; border-radius: 100px; font-weight: 700; border: none; cursor: pointer; font-size: 1rem; }
.products { padding: 60px 40px; max-width: 1100px; margin: 0 auto; }
.products h2 { font-size: 1.6rem; font-weight: 800; margin-bottom: 28px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 24px; }
.product-card { background: #fff; border-radius: 16px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,.07); transition: transform .2s; cursor: pointer; }
.product-card:hover { transform: translateY(-4px); }
.product-img { height: 180px; display: flex; align-items: center; justify-content: center; font-size: 4rem; }
.product-info { padding: 16px; }
.product-name { font-weight: 700; font-size: .95rem; margin-bottom: 4px; }
.product-cat { color: #9ca3af; font-size: .8rem; margin-bottom: 10px; }
.product-footer { display: flex; justify-content: space-between; align-items: center; }
.price { font-size: 1.15rem; font-weight: 800; color: #6366f1; }
.add-btn { background: #6366f1; color: #fff; border: none; padding: 8px 14px; border-radius: 8px; font-weight: 600; font-size: .85rem; cursor: pointer; }
</style>
</head>
<body>
<header>
  <div class="logo">Shop<span>.</span></div>
  <nav><a href="#">Accueil</a><a href="#">Produits</a><a href="#">À propos</a></nav>
  <button class="cart-btn">🛒 Panier (0)</button>
</header>
<div class="banner">
  <h1>Nouvelle Collection 2025</h1>
  <p>Découvrez les meilleures produits soigneusement sélectionnés pour vous.</p>
  <button class="btn-shop">Explorer la boutique</button>
</div>
<div class="products">
  <h2>Produits populaires</h2>
  <div class="grid">
    <div class="product-card"><div class="product-img" style="background:#fef3c7">🎧</div><div class="product-info"><div class="product-name">Casque Pro XL</div><div class="product-cat">Audio</div><div class="product-footer"><span class="price">€149</span><button class="add-btn">+ Ajouter</button></div></div></div>
    <div class="product-card"><div class="product-img" style="background:#e0f2fe">⌚</div><div class="product-info"><div class="product-name">Montre Smart 3</div><div class="product-cat">Tech</div><div class="product-footer"><span class="price">€299</span><button class="add-btn">+ Ajouter</button></div></div></div>
    <div class="product-card"><div class="product-img" style="background:#fce7f3">👟</div><div class="product-info"><div class="product-name">Sneakers Urban</div><div class="product-cat">Mode</div><div class="product-footer"><span class="price">€89</span><button class="add-btn">+ Ajouter</button></div></div></div>
    <div class="product-card"><div class="product-img" style="background:#dcfce7">🎮</div><div class="product-info"><div class="product-name">Manette Gamer</div><div class="product-cat">Gaming</div><div class="product-footer"><span class="price">€69</span><button class="add-btn">+ Ajouter</button></div></div></div>
  </div>
</div>
</body>
</html>`,
    },
  },
  {
    id: 'blog',
    emoji: '📝',
    name: gm('Blog', 'Blog', 'Blog'),
    desc: gm('Blog editorial con artículos', "Blog éditorial avec articles", 'Editorial blog with articles'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Georgia, 'Times New Roman', serif; background: #fff; color: #111; }
header { border-bottom: 3px solid #111; padding: 24px 60px; display: flex; align-items: center; justify-content: space-between; }
.blog-logo { font-size: 1.8rem; font-weight: 900; letter-spacing: -0.03em; }
header nav a { margin-left: 24px; text-decoration: none; color: #555; font-family: Inter, sans-serif; font-size: .9rem; }
.hero-article { padding: 60px 60px 40px; border-bottom: 1px solid #e5e7eb; display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; }
.hero-tag { background: #111; color: #fff; padding: 3px 10px; font-family: Inter, sans-serif; font-size: .75rem; font-weight: 700; letter-spacing: .1em; display: inline-block; margin-bottom: 16px; }
.hero-article h1 { font-size: 2.6rem; line-height: 1.15; margin-bottom: 16px; }
.hero-article p { color: #555; font-size: 1.1rem; line-height: 1.7; margin-bottom: 20px; }
.read-more { font-family: Inter, sans-serif; font-weight: 700; color: #111; text-decoration: none; border-bottom: 2px solid #111; }
.hero-img { height: 360px; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 4px; display: flex; align-items: center; justify-content: center; font-size: 5rem; }
.articles { padding: 60px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.article-card h3 { font-size: 1.2rem; margin-bottom: 10px; line-height: 1.3; }
.article-card p { color: #666; font-size: .95rem; line-height: 1.65; margin-bottom: 14px; }
.article-meta { font-family: Inter, sans-serif; font-size: .8rem; color: #999; }
.article-thumb { height: 180px; border-radius: 4px; margin-bottom: 16px; display: flex; align-items: center; justify-content: center; font-size: 3rem; }
</style>
</head>
<body>
<header>
  <div class="blog-logo">The Blog</div>
  <nav><a href="#">Accueil</a><a href="#">Articles</a><a href="#">À propos</a><a href="#">Contact</a></nav>
</header>
<div class="hero-article">
  <div>
    <div class="hero-tag">À LA UNE</div>
    <h1>L'IA en 2025 : ce qui change vraiment pour nous</h1>
    <p>Une analyse approfondie des transformations apportées par l'intelligence artificielle dans notre quotidien professionnel et personnel.</p>
    <a href="#" class="read-more">Lire l'article →</a>
  </div>
  <div class="hero-img">🤖</div>
</div>
<div class="articles">
  <div class="article-card"><div class="article-thumb" style="background:#fef9c3">💡</div><h3>10 outils no-code incontournables</h3><p>Notre sélection des meilleurs outils pour créer sans coder en 2025.</p><div class="article-meta">14 mai 2025 · 5 min de lecture</div></div>
  <div class="article-card"><div class="article-thumb" style="background:#ecfdf5">🌿</div><h3>Design durable : tendances 2025</h3><p>Comment le design éco-responsable redéfinit l'expérience utilisateur.</p><div class="article-meta">10 mai 2025 · 7 min de lecture</div></div>
  <div class="article-card"><div class="article-thumb" style="background:#eff6ff">🚀</div><h3>Lancer son produit en 30 jours</h3><p>Guide pratique pour passer de l'idée au lancement en un mois.</p><div class="article-meta">5 mai 2025 · 8 min de lecture</div></div>
</div>
</body>
</html>`,
    },
  },
  {
    id: 'form',
    emoji: '📬',
    name: gm('Formulario', 'Formulaire', 'Contact Form'),
    desc: gm('Formulario de contacto completo', 'Formulaire de contact complet', 'Full contact form'),
    files: {
      'index.html': `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: Inter, sans-serif; background: #f8fafc; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
.container { display: grid; grid-template-columns: 1fr 1fr; gap: 0; max-width: 880px; width: 100%; border-radius: 20px; overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,.12); }
.left { background: linear-gradient(145deg, #6366f1, #7c3aed); color: #fff; padding: 52px 44px; display: flex; flex-direction: column; gap: 32px; }
.left h2 { font-size: 2rem; font-weight: 800; line-height: 1.2; }
.left p { opacity: .85; line-height: 1.65; font-size: .95rem; }
.contact-info { display: flex; flex-direction: column; gap: 16px; }
.info-item { display: flex; align-items: center; gap: 12px; font-size: .9rem; }
.info-icon { width: 36px; height: 36px; border-radius: 10px; background: rgba(255,255,255,.15); display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0; }
.right { background: #fff; padding: 52px 44px; }
.right h3 { font-size: 1.4rem; font-weight: 800; margin-bottom: 28px; color: #111; }
.form-group { margin-bottom: 18px; }
label { display: block; font-size: .85rem; font-weight: 600; color: #374151; margin-bottom: 6px; }
input, textarea, select { width: 100%; padding: 11px 14px; border: 1.5px solid #e5e7eb; border-radius: 10px; font-size: .9rem; font-family: inherit; color: #111; transition: border-color .15s; outline: none; }
input:focus, textarea:focus, select:focus { border-color: #6366f1; }
textarea { resize: vertical; min-height: 110px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.btn-submit { width: 100%; background: #6366f1; color: #fff; border: none; padding: 13px; border-radius: 10px; font-weight: 700; font-size: 1rem; cursor: pointer; margin-top: 8px; transition: opacity .2s; }
.btn-submit:hover { opacity: .88; }
</style>
</head>
<body>
<div class="container">
  <div class="left">
    <div><h2>Contactez-nous</h2></div>
    <p>Nous sommes là pour vous aider. Remplissez le formulaire et nous vous répondrons sous 24h.</p>
    <div class="contact-info">
      <div class="info-item"><div class="info-icon">📧</div><span>hello@votresite.com</span></div>
      <div class="info-item"><div class="info-icon">📞</div><span>+33 1 23 45 67 89</span></div>
      <div class="info-item"><div class="info-icon">📍</div><span>Paris, France</span></div>
    </div>
  </div>
  <div class="right">
    <h3>Envoyer un message</h3>
    <form>
      <div class="form-row">
        <div class="form-group"><label>Prénom</label><input type="text" placeholder="Jean"></div>
        <div class="form-group"><label>Nom</label><input type="text" placeholder="Dupont"></div>
      </div>
      <div class="form-group"><label>Email</label><input type="email" placeholder="jean@exemple.com"></div>
      <div class="form-group"><label>Sujet</label><select><option>Question générale</option><option>Support technique</option><option>Partenariat</option></select></div>
      <div class="form-group"><label>Message</label><textarea placeholder="Votre message..."></textarea></div>
      <button type="submit" class="btn-submit">Envoyer le message ✉️</button>
    </form>
  </div>
</div>
</body>
</html>`,
    },
  },
];

/* ── AI response engine ── */
function generateAIResponse(msg, files) {
  const lower = msg.toLowerCase();
  const hasFiles = Object.keys(files).length > 0;

  // Detect intent
  const wantsLanding   = /landing|hero|accueil|home|presentaci/i.test(msg);
  const wantsNav       = /nav|menu|header|barre|navigation/i.test(msg);
  const wantsColor     = /couleur|color|bleu|blue|rouge|red|vert|green|violet|purple|rose|pink/i.test(msg);
  const wantsButton    = /bouton|button|btn|cta/i.test(msg);
  const wantsFooter    = /footer|pied de page|bas de page/i.test(msg);
  const wantsAnimate   = /anim|transition|effet|effect/i.test(msg);
  const wantsPortfolio = /portfolio|cv|curriculum|skills?/i.test(msg);
  const wantsContact   = /contact|formulaire|form/i.test(msg);
  const wantsDark      = /dark|sombre|nuit|night/i.test(msg);
  const wantsStyle     = /style|css|design/i.test(msg);

  if (!hasFiles) {
    // No files yet — generate a starter
    if (wantsPortfolio) {
      return {
        text: gm(
          '¡Perfecto! He creado un portfolio profesional para ti. Tienes una navegación elegante, una sección hero impactante y una grilla de proyectos. ¡Personalízalo con tus datos! 🎨',
          'Parfait ! J\'ai créé un portfolio professionnel pour vous. Il inclut une navigation élégante, une section hero percutante et une grille de projets. Personnalisez-le avec vos informations ! 🎨',
          'Perfect! I created a professional portfolio for you. It includes elegant navigation, an impactful hero section, and a projects grid. Customize it with your info! 🎨'
        ),
        files: { 'index.html': LIB_TEMPLATES[1].files['index.html'] },
      };
    }
    if (wantsContact) {
      return {
        text: gm(
          '¡Listo! He creado un formulario de contacto moderno con layout en dos columnas. La izquierda muestra la información de contacto y la derecha el formulario. 📬',
          'Voilà ! J\'ai créé un formulaire de contact moderne en deux colonnes. La gauche affiche les infos de contact et la droite le formulaire. 📬',
          'Done! I created a modern two-column contact form. The left shows contact info and the right has the form. 📬'
        ),
        files: { 'index.html': LIB_TEMPLATES[5].files['index.html'] },
      };
    }
    // Default: landing page
    return {
      text: gm(
        '¡He creado tu página de inicio! Tiene un hero con gradiente, sección de características con tarjetas y un footer. Puedes pedirme que modifique los colores, el texto, añada secciones o cualquier otra cosa. 🚀',
        'J\'ai créé votre page d\'accueil ! Elle comprend un hero avec dégradé, une section features avec des cartes et un footer. Vous pouvez me demander de modifier les couleurs, le texte, ajouter des sections, etc. 🚀',
        'I created your homepage! It includes a gradient hero, a features section with cards, and a footer. Ask me to change colors, text, add sections, or anything else. 🚀'
      ),
      files: { 'index.html': LIB_TEMPLATES[0].files['index.html'] },
    };
  }

  // Files exist — modify them
  if (wantsDark) {
    return {
      text: gm(
        'He actualizado el diseño a modo oscuro. Los fondos son ahora de color #0f172a y los textos en tonos claros. ¡Se ve muy profesional! 🌙',
        'J\'ai mis à jour le design en mode sombre. Les fonds sont maintenant en #0f172a avec des textes clairs. Très professionnel ! 🌙',
        'I updated the design to dark mode. Backgrounds are now #0f172a with light text. Looks very professional! 🌙'
      ),
      files: null,
      hint: 'dark',
    };
  }
  if (wantsColor) {
    return {
      text: gm(
        'He actualizado la paleta de colores. Los nuevos tonos dan un aspecto más moderno y vibrante a tu proyecto. 🎨',
        'J\'ai mis à jour la palette de couleurs. Les nouvelles teintes donnent un aspect plus moderne et vibrant à votre projet. 🎨',
        'I updated the color palette. The new tones give a more modern and vibrant look to your project. 🎨'
      ),
      files: null,
    };
  }
  if (wantsNav) {
    return {
      text: gm(
        'He añadido una barra de navegación responsiva con logo, links y un botón CTA. Se vuelve sticky al hacer scroll. 🗂️',
        'J\'ai ajouté une barre de navigation responsive avec logo, liens et un bouton CTA. Elle devient sticky au scroll. 🗂️',
        'I added a responsive navigation bar with logo, links, and a CTA button. It becomes sticky on scroll. 🗂️'
      ),
      files: null,
    };
  }
  if (wantsFooter) {
    return {
      text: gm(
        'He añadido un footer completo con links, redes sociales y copyright. Se adapta perfectamente al diseño existente. 🔻',
        'J\'ai ajouté un footer complet avec des liens, réseaux sociaux et copyright. Il s\'adapte parfaitement au design existant. 🔻',
        'I added a complete footer with links, social networks, and copyright. It fits perfectly with the existing design. 🔻'
      ),
      files: null,
    };
  }
  if (wantsAnimate) {
    return {
      text: gm(
        'He añadido animaciones suaves de entrada (fade + slide). Las tarjetas aparecen con un efecto elegante al cargar la página. ✨',
        'J\'ai ajouté des animations d\'entrée douces (fade + slide). Les cartes apparaissent avec un effet élégant au chargement. ✨',
        'I added smooth entrance animations (fade + slide). Cards appear with an elegant effect on page load. ✨'
      ),
      files: null,
    };
  }

  // Generic response
  return {
    text: gm(
      'He aplicado los cambios que pediste. La estructura sigue siendo sólida y el diseño se mantiene coherente. ¿Qué más quieres ajustar? ✅',
      'J\'ai appliqué les modifications demandées. La structure reste solide et le design cohérent. Que souhaitez-vous ajuster d\'autre ? ✅',
      'I applied the changes you requested. The structure remains solid and the design coherent. What else would you like to adjust? ✅'
    ),
    files: null,
  };
}

/* ── File type → icon ── */
function fileIcon(name) {
  if (name.endsWith('.html')) return '📄';
  if (name.endsWith('.css'))  return '🎨';
  if (name.endsWith('.js'))   return '⚡';
  if (name.endsWith('.jsx'))  return '⚛️';
  if (name.endsWith('.json')) return '📋';
  if (name.endsWith('.md'))   return '📝';
  if (name.endsWith('.png') || name.endsWith('.jpg') || name.endsWith('.svg')) return '🖼️';
  return '📄';
}

/* ── Library Modal ── */
function LibraryModal({ onClose, onSelect }) {
  const [selected, setSelected] = useWS(null);
  return (
    <div className="ws-modal-back" onClick={onClose}>
      <div className="lib-modal" onClick={e => e.stopPropagation()}>
        <div className="ws-modal-title">
          <span>{gm('Importar plantilla', 'Importer un modèle', 'Import a template')}</span>
          <button className="ws-modal-close" onClick={onClose}>×</button>
        </div>
        <p style={{fontSize:13,color:'var(--text-mute)'}}>
          {gm('Elige una plantilla de inicio para tu workspace.','Choisissez un modèle de départ pour votre workspace.','Choose a starter template for your workspace.')}
        </p>
        <div className="lib-grid">
          {LIB_TEMPLATES.map(t => (
            <div key={t.id}
              className={'lib-card' + (selected === t.id ? ' selected' : '')}
              onClick={() => setSelected(t.id)}>
              {selected === t.id && (
                <div style={{position:'absolute',top:8,right:8,width:18,height:18,background:'var(--brand)',borderRadius:'50%',display:'grid',placeItems:'center',color:'#fff'}}>
                  <IconWS.check/>
                </div>
              )}
              <div className="lib-emoji">{t.emoji}</div>
              <div className="lib-name">{t.name}</div>
              <div className="lib-desc">{t.desc}</div>
            </div>
          ))}
        </div>
        <div className="ws-modal-actions">
          <button className="ws-btn-cancel" onClick={onClose}>{window.t('btn.cancel')}</button>
          <button className="ws-btn-create"
            disabled={!selected}
            onClick={() => { const tpl = LIB_TEMPLATES.find(t => t.id === selected); if (tpl) onSelect(tpl); }}>
            {gm('Usar plantilla','Utiliser ce modèle','Use template')}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── New Workspace Modal ── */
function NewWorkspaceModal({ onClose, onCreate, initialFiles }) {
  const [name, setName] = useWS('');
  const [desc, setDesc] = useWS('');
  return (
    <div className="ws-modal-back" onClick={onClose}>
      <div className="ws-modal" onClick={e => e.stopPropagation()}>
        <div className="ws-modal-title">
          <span>{gm('Nuevo Workspace','Nouveau Workspace','New Workspace')}</span>
          <button className="ws-modal-close" onClick={onClose}>×</button>
        </div>
        <div>
          <div className="ws-label">{gm('Nombre','Nom','Name')}</div>
          <input className="ws-input" placeholder="My Project" value={name} onChange={e => setName(e.target.value)} autoFocus/>
        </div>
        <div>
          <div className="ws-label">{gm('Descripción (opcional)','Description (optionnel)','Description (optional)')}</div>
          <textarea className="ws-textarea" placeholder={gm('Descripción de tu proyecto...','Description de votre projet...','Description of your project...')} value={desc} onChange={e => setDesc(e.target.value)}/>
        </div>
        <div className="ws-modal-actions">
          <button className="ws-btn-cancel" onClick={onClose}>{window.t('btn.cancel')}</button>
          <button className="ws-btn-create" disabled={!name.trim()} onClick={() => onCreate(name.trim(), desc.trim(), initialFiles || {})}>
            {gm('Crear','Créer','Create')}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── Workspace Editor ── */
function WorkspaceEditor({ ws, onBack, onUpdate }) {
  const [files, setFiles] = useWS(ws.files || {});
  const [selectedFile, setSelectedFile] = useWS(Object.keys(ws.files || {})[0] || null);
  const [chatMessages, setChatMessages] = useWS(ws.chatMessages || []);
  const [chatInput, setChatInput] = useWS('');
  const [activeTab, setActiveTab] = useWS('code');
  const [isTyping, setIsTyping] = useWS(false);
  const messagesEndRef = useWsRef(null);
  const chatInputRef = useWsRef(null);

  useWsEffect(() => {
    if (messagesEndRef.current) {
      messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  }, [chatMessages, isTyping]);

  // Sync to parent
  useWsEffect(() => {
    onUpdate({ ...ws, files, chatMessages });
  }, [files, chatMessages]);

  function sendMessage() {
    const text = chatInput.trim();
    if (!text || isTyping) return;
    const userMsg = { id: Date.now(), from: 'user', text };
    setChatMessages(prev => [...prev, userMsg]);
    setChatInput('');
    setIsTyping(true);
    window.dispatchEvent(new CustomEvent('aimy:wsChatUsed'));

    setTimeout(() => {
      const response = generateAIResponse(text, files);
      let newFiles = files;
      if (response.files) {
        newFiles = { ...files, ...response.files };
        setFiles(newFiles);
        const firstNew = Object.keys(response.files)[0];
        setSelectedFile(firstNew);
        setActiveTab('code');
        window.dispatchEvent(new CustomEvent('aimy:wsHasFiles'));
      }
      const aiMsg = {
        id: Date.now() + 1,
        from: 'ai',
        text: response.text,
        createdFiles: response.files ? Object.keys(response.files) : [],
      };
      setChatMessages(prev => [...prev, aiMsg]);
      setIsTyping(false);
    }, 1200 + Math.random() * 800);
  }

  function handleKeyDown(e) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendMessage();
    }
  }

  function clearChat() {
    setChatMessages([]);
  }

  const fileCount = Object.keys(files).length;

  function downloadFiles() {
    const entries = Object.entries(files);
    if (entries.length === 0) return;
    // Download first file (or only one)
    const [fname, content] = entries[0];
    const blob = new Blob([content], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fname;
    a.click();
    URL.revokeObjectURL(url);
  }

  const previewSrc = selectedFile && files[selectedFile] ? files[selectedFile] : null;

  return (
    <div className="ws-editor">
      {/* Header */}
      <div className="ws-editor-header">
        <div className="ws-breadcrumb">
          <a className="ws-breadcrumb-link" onClick={onBack}>{gm('Workspaces','Workspaces','Workspaces')}</a>
          <span className="ws-breadcrumb-sep">/</span>
          <div>
            <div className="ws-breadcrumb-current">{ws.name}</div>
            {ws.desc && <div className="ws-editor-name-sub">{ws.desc}</div>}
          </div>
        </div>
        <div className="ws-editor-actions">
          <span className="ws-file-count">
            {fileCount} {fileCount === 1
              ? gm('archivo','fichier','file')
              : gm('archivos','fichiers','files')}
          </span>
          <button className="ws-btn-download" onClick={downloadFiles} disabled={fileCount === 0}>
            <IconWS.download/> {gm('Descargar','Télécharger','Download')}
          </button>
        </div>
      </div>

      {/* Body */}
      <div className="ws-editor-body">
        {/* Left: Chat */}
        <div className="ws-chat-panel" data-tour="ws-chat-panel">
          <div className="ws-chat-header">
            <span>AI Chat</span>
            <div className="ws-chat-header-actions">
              <button className="ws-chat-icon-btn" title={gm('Limpiar chat','Effacer le chat','Clear chat')} onClick={clearChat}>
                <IconWS.trash/>
              </button>
            </div>
          </div>

          <div className="ws-chat-messages">
            {chatMessages.length === 0 && !isTyping && (
              <div className="ws-chat-empty">
                {gm(
                  'Pide a la IA lo que quieres crear. El contexto incluye todos los archivos analizados.',
                  'Demandez à l\'IA ce que vous voulez créer. Le contexte inclut tous les fichiers analysés.',
                  'Ask the AI what you want to create. Context includes all analyzed files.'
                )}
              </div>
            )}
            {chatMessages.map(m => (
              <div key={m.id} className={'ws-msg ' + m.from}>
                <div className="ws-msg-from">
                  {m.from === 'user' ? gm('Tú','Vous','You') : 'DIAS ✨'}
                </div>
                <div className="ws-msg-bubble" dangerouslySetInnerHTML={{__html: m.text}}/>
                {m.createdFiles && m.createdFiles.length > 0 && (
                  <div className="ws-msg-files">
                    {m.createdFiles.map(f => (
                      <span key={f} className="ws-msg-file-tag" onClick={() => { setSelectedFile(f); setActiveTab('code'); }}>
                        {fileIcon(f)} {f}
                      </span>
                    ))}
                  </div>
                )}
              </div>
            ))}
            {isTyping && (
              <div className="ws-msg ai">
                <div className="ws-msg-from">DIAS ✨</div>
                <div className="ws-typing">
                  <div className="ws-typing-dots">
                    <div className="ws-typing-dot"/>
                    <div className="ws-typing-dot"/>
                    <div className="ws-typing-dot"/>
                  </div>
                  <span style={{fontSize:12,color:'var(--text-mute)'}}>
                    {gm('Generando código...','Génération du code...','Generating code...')}
                  </span>
                </div>
              </div>
            )}
            <div ref={messagesEndRef}/>
          </div>

          <div className="ws-chat-input-row">
            <textarea
              ref={chatInputRef}
              className="ws-chat-input"
              placeholder={gm('Pide lo que quieres crear...','Demandez ce que vous souhaitez créer...','Ask what you want to create...')}
              value={chatInput}
              onChange={e => setChatInput(e.target.value)}
              onKeyDown={handleKeyDown}
              rows={1}
            />
            <button className="ws-chat-send" onClick={sendMessage} disabled={!chatInput.trim() || isTyping}>
              <IconWS.send/>
            </button>
          </div>
        </div>

        {/* Right: Code + Preview */}
        <div className="ws-code-panel">
          <div className="ws-tabs" data-tour="ws-code-tabs">
            <button className={'ws-tab' + (activeTab === 'code' ? ' active' : '')} onClick={() => setActiveTab('code')}>
              {gm('Código','Code','Code')}
            </button>
            <button data-tour="ws-preview-tab" className={'ws-tab' + (activeTab === 'preview' ? ' active' : '')} onClick={() => setActiveTab('preview')}>
              {gm('Vista previa','Aperçu','Preview')}
            </button>
          </div>

          {activeTab === 'code' && (
            <div className="ws-code-body">
              {/* Explorer */}
              <div className="ws-explorer" data-tour="ws-explorer">
                <div className="ws-explorer-header">
                  <span>Explorer</span>
                  <button className="ws-explorer-refresh"><IconWS.refresh/></button>
                </div>
                {Object.keys(files).length === 0
                  ? <div className="ws-explorer-empty">{gm('No hay archivos','Aucun fichier','No files yet')}</div>
                  : Object.keys(files).map(f => (
                      <div key={f}
                        className={'ws-file-item' + (selectedFile === f ? ' selected' : '')}
                        onClick={() => setSelectedFile(f)}>
                        <span className="ws-file-icon">{fileIcon(f)}</span>
                        <span>{f}</span>
                      </div>
                    ))
                }
              </div>
              {/* Code editor */}
              <div className="ws-editor-area">
                {!selectedFile || !files[selectedFile]
                  ? <div className="ws-no-file">{gm('Selecciona un archivo para editarlo','Sélectionnez un fichier à éditer','Select a file to edit')}</div>
                  : <>
                      <div className="ws-code-header">
                        <span className="ws-file-icon">{fileIcon(selectedFile)}</span>
                        <span>{selectedFile}</span>
                      </div>
                      <div className="ws-code-content">
                        <pre className="ws-code-pre">{files[selectedFile]}</pre>
                      </div>
                    </>
                }
              </div>
            </div>
          )}

          {activeTab === 'preview' && (
            <div className="ws-preview-panel">
              <div className="ws-preview-bar">
                <div className="ws-preview-dot" style={{background:'#ff5f57'}}/>
                <div className="ws-preview-dot" style={{background:'#febc2e'}}/>
                <div className="ws-preview-dot" style={{background:'#28c840'}}/>
                <div className="ws-preview-url">
                  {gm('Vista previa local','Aperçu local','Local preview')} · {selectedFile || 'index.html'}
                </div>
              </div>
              {previewSrc
                ? <iframe className="ws-preview-iframe" srcDoc={previewSrc} title="preview" sandbox="allow-scripts"/>
                : <div className="ws-preview-empty">
                    <div className="ws-preview-empty-icon">🖼️</div>
                    <p>{gm('Crea un archivo HTML para ver la vista previa','Créez un fichier HTML pour voir l\'aperçu','Create an HTML file to see the preview')}</p>
                  </div>
              }
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

/* ── Workspace List ── */
function WorkspaceList({ workspaces, onOpen, onNew, onLibrary, onDelete }) {
  return (
    <main className="main">
      <div className="ws-panel">
        <div className="ws-header">
          <h1 className="ws-title">{gm('Workspaces','Workspaces','Workspaces')}</h1>
          <div className="ws-header-actions">
            <button className="btn-library" data-tour="ws-library-btn" onClick={onLibrary}>
              <IconWS.library/>
              {gm('Desde Librería','From Library','From Library')}
            </button>
            <button className="btn-ws-new" data-tour="ws-new-btn" onClick={onNew}>
              + {gm('Nuevo Workspace','New Workspace','New Workspace')}
            </button>
          </div>
        </div>

        {workspaces.length === 0 ? (
          <div className="ws-empty">
            <IconWS.folder/>
            <p style={{fontWeight:600,fontSize:15,color:'var(--text-soft)'}}>
              {gm('Ningún workspace todavía','Aucun workspace pour l\'instant','No workspaces yet')}
            </p>
            <p>
              {gm('Crea el primero para empezar.','Créez le premier pour commencer.','Create your first one to get started.')}
            </p>
          </div>
        ) : (
          <div className="ws-grid">
            {workspaces.map(ws => (
              <div key={ws.id} className="ws-card" onClick={() => onOpen(ws)}>
                <button className="ws-card-del" onClick={e => { e.stopPropagation(); onDelete(ws.id); }}>
                  <IconWS.trash/>
                </button>
                <div className="ws-card-icon">🗂️</div>
                <div className="ws-card-name">{ws.name}</div>
                {ws.desc && <div className="ws-card-desc">{ws.desc}</div>}
                <div className="ws-card-meta">
                  {Object.keys(ws.files || {}).length > 0 && (
                    <span className="ws-card-files-badge">
                      {Object.keys(ws.files).length} {gm('archivos','fichiers','files')}
                    </span>
                  )}
                  <span>{new Date(ws.createdAt).toLocaleDateString()}</span>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </main>
  );
}

/* ── Root WorkspaceApp ── */
function WorkspaceApp() {
  const STORAGE_KEY = 'aimaker:workspaces';
  const [workspaces, setWorkspaces] = useWS(() => {
    try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || []; } catch { return []; }
  });
  const [currentWs, setCurrentWs] = useWS(null);
  const [showNew, setShowNew] = useWS(false);
  const [showLib, setShowLib] = useWS(false);
  const [libFiles, setLibFiles] = useWS(null); // files from library selection → pre-fill new modal

  useWsEffect(() => {
    try { localStorage.setItem(STORAGE_KEY, JSON.stringify(workspaces)); } catch {}
  }, [workspaces]);

  function createWs(name, desc, files) {
    const ws = { id: 'ws-' + Date.now(), name, desc, files: files || {}, chatMessages: [], createdAt: Date.now() };
    setWorkspaces(prev => [ws, ...prev]);
    setCurrentWs(ws);
    setShowNew(false);
    setLibFiles(null);
    window.dispatchEvent(new CustomEvent('aimy:wsCreated'));
    if (files && Object.keys(files).length > 0) {
      window.dispatchEvent(new CustomEvent('aimy:wsHasFiles'));
    }
  }

  function updateWs(updated) {
    setWorkspaces(prev => prev.map(w => w.id === updated.id ? updated : w));
    setCurrentWs(updated);
  }

  function deleteWs(id) {
    setWorkspaces(prev => prev.filter(w => w.id !== id));
  }

  function handleLibSelect(template) {
    setShowLib(false);
    setLibFiles(template.files);
    setShowNew(true);
  }

  return (
    <div className="app">
      <WsTopbar/>
      <WsSidebar/>
      {currentWs ? (
        <WorkspaceEditor
          ws={currentWs}
          onBack={() => setCurrentWs(null)}
          onUpdate={updateWs}/>
      ) : (
        <WorkspaceList
          workspaces={workspaces}
          onOpen={ws => setCurrentWs(ws)}
          onNew={() => { setLibFiles(null); setShowNew(true); }}
          onLibrary={() => setShowLib(true)}
          onDelete={deleteWs}/>
      )}

      {showLib && (
        <LibraryModal onClose={() => setShowLib(false)} onSelect={handleLibSelect}/>
      )}
      {showNew && (
        <NewWorkspaceModal
          onClose={() => { setShowNew(false); setLibFiles(null); }}
          onCreate={createWs}
          initialFiles={libFiles}/>
      )}
    </div>
  );
}

window.WorkspaceApp = WorkspaceApp;
