/* ─── Reset & Base ─────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#0a0a0f;
  --bg2:#12121a;
  --bg3:#1a1a2e;
  --surface:#1e1e32;
  --surface2:#252540;
  --border:#2a2a45;
  --text:#e8e8f0;
  --text2:#9898b8;
  --text3:#6868a0;
  --accent:#6366f1;
  --accent2:#818cf8;
  --green:#22c55e;
  --yellow:#eab308;
  --orange:#f97316;
  --red:#ef4444;
  --blue:#3b82f6;
  --pink:#ec4899;
  --purple:#8b5cf6;
  --radius:12px;
  --radius-sm:8px;
  --shadow:0 4px 24px rgba(0,0,0,.4);
  --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}
body.theme-light{
  --bg:#f5f5f8;
  --bg2:#ffffff;
  --bg3:#e8e8f0;
  --surface:#ffffff;
  --surface2:#f0f0f8;
  --border:#d0d0dd;
  --text:#1a1a2e;
  --text2:#505070;
  --text3:#8888a0;
  --shadow:0 4px 24px rgba(0,0,0,.08);
}
body.palette-emerald{--accent:#10b981;--accent2:#34d399}
body.palette-rose{--accent:#e11d48;--accent2:#fb7185}
body.palette-amber{--accent:#d97706;--accent2:#fbbf24}
body.palette-cyan{--accent:#06b6d4;--accent2:#22d3ee}
body.palette-violet{--accent:#7c3aed;--accent2:#a78bfa}
body.palette-pink{--accent:#db2777;--accent2:#f472b6}
html{font-size:14px}
body{
  font-family:var(--font);
  background:var(--bg);
  color:var(--text);
  display:flex;
  height:100vh;
  overflow:hidden;
  line-height:1.5;
}
a{color:var(--accent2);text-decoration:none}
a:hover{text-decoration:underline}

/* ─── Scrollbar ────────────────────────────────────────────── */
::-webkit-scrollbar{width:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
::-webkit-scrollbar-thumb:hover{background:var(--text3)}

/* ─── Animations ──────────────────────────────────────────── */
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes slideIn{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:translateX(0)}}
@keyframes slideUp{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes scaleIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}
.anim-fade{animation:fadeIn .25s ease}
.anim-slide{animation:slideIn .25s ease}
.anim-scale{animation:scaleIn .2s ease}
.spinner{
  display:inline-block;width:20px;height:20px;
  border:2px solid var(--border);border-top-color:var(--accent);
  border-radius:50%;animation:spin .6s linear infinite;
}

/* ─── Sidebar ──────────────────────────────────────────────── */
.sidebar{
  width:170px;min-width:170px;
  background:var(--bg2);
  border-right:1px solid var(--border);
  display:flex;flex-direction:column;overflow:hidden;
  transition:transform .15s ease,margin .15s ease;z-index:100;
}
.sidebar .sidebar-nav{overflow-y:auto;flex:1}
.sidebar .sidebar-nav .sidebar-links{padding:6px 10px;border-top:1px solid var(--border)}
.sidebar-search,.project-list,.sidebar-footer{flex-shrink:0}
.sidebar-header{
  padding:12px 12px 10px;
  border-bottom:1px solid var(--border);
}
.sidebar-header h1{
  font-size:1rem;font-weight:700;
  display:flex;align-items:center;gap:8px;
}
.sidebar-header h1 .logo{
  width:24px;height:24px;
  background:linear-gradient(135deg,var(--accent),var(--accent2));
  border-radius:6px;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;color:#fff;
}
.sidebar-header .sub{
  font-size:.68rem;color:var(--text3);
  margin-top:2px;margin-left:32px;
}
.sidebar-nav{
  padding:10px 10px 6px;
  display:flex;flex-direction:column;gap:2px;
  border-bottom:1px solid var(--border);
}
.nav-btn{
  padding:6px 10px;border:none;
  background:transparent;color:var(--text2);
  font-family:inherit;font-size:.7rem;font-weight:500;
  border-radius:var(--radius-sm);cursor:pointer;
  transition:all .15s;text-align:left;
  display:flex;align-items:center;gap:6px;
}
.nav-btn i{font-size:.8rem}
.nav-btn:hover{background:var(--surface);color:var(--text)}
.nav-btn.active{background:var(--accent);color:#fff;border-left:3px solid var(--text)}
.nav-group{margin-bottom:6px}
.nav-group-header{
  padding:4px 10px;border:none;
  background:transparent;color:var(--text3);
  font-family:inherit;font-size:.68rem;font-weight:600;
  cursor:pointer;transition:all .15s;text-align:left;
  display:flex;align-items:center;gap:5px;
  text-transform:uppercase;letter-spacing:.06em;
}
.nav-group-header:hover{color:var(--text)}
.nav-group-header .chevron{
  margin-left:auto;font-size:.65rem;
  transition:transform .15s ease;
}
.nav-group-header.active .chevron{transform:rotate(90deg)}
.nav-group-content{
  max-height:500px;overflow:hidden;
  transition:max-height .2s ease;
}
.nav-group-content.collapsed{max-height:0}
.sidebar-search{padding:8px 10px}
.sidebar-search input{
  width:100%;
  padding:7px 10px 7px 30px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-sm);color:var(--text);
  font-family:inherit;font-size:.78rem;outline:none;
  transition:border .15s;
}
.sidebar-search input:focus{border-color:var(--accent)}
.sidebar-search input::placeholder{color:var(--text3)}
.sidebar-search .search-wrap{position:relative}
.sidebar-search .search-wrap i{
  position:absolute;left:10px;top:50%;
  transform:translateY(-50%);color:var(--text3)
}
.sidebar-links{padding:6px 10px;border-top:1px solid var(--border)}
.sidebar-links-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text3);margin-bottom:4px}
.sidebar-link{display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:6px;font-size:.7rem;color:var(--text2);text-decoration:none;transition:.15s}
.sidebar-link:hover{background:var(--hover);color:var(--accent);text-decoration:none}
.sidebar-link i{width:16px;text-align:center;font-size:.7rem}
.project-list{flex:1;overflow-y:auto;padding:4px 6px}
.project-item{
  display:flex;align-items:center;gap:8px;
  padding:8px 10px;border-radius:var(--radius-sm);
  cursor:pointer;transition:all .15s;margin-bottom:2px;
}
.project-item:hover{background:var(--surface)}
.project-item.active{background:var(--surface2)}
.project-item .dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
.project-item .info{flex:1;min-width:0}
.project-item .name{
  font-size:.82rem;font-weight:500;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.project-item .meta{
  font-size:.68rem;color:var(--text3);
  display:flex;gap:6px;
}
.project-item .badge{font-size:.62rem;padding:1px 5px;border-radius:4px;font-weight:600}
.badge-active{background:rgba(34,197,94,.15);color:var(--green)}
.badge-paused{background:rgba(234,179,8,.15);color:var(--yellow)}
.badge-completed{background:rgba(99,102,241,.15);color:var(--accent2)}
.badge-archived{background:rgba(104,104,160,.15);color:var(--text3)}
.sidebar-footer{padding:10px;border-top:1px solid var(--border)}
.btn-add-project{
  width:100%;padding:9px;border:1px dashed var(--border);
  background:transparent;color:var(--text2);
  font-family:inherit;font-size:.78rem;font-weight:500;
  border-radius:var(--radius-sm);cursor:pointer;transition:all .15s;
}
.btn-add-project:hover{border-color:var(--accent);color:var(--accent2);background:rgba(99,102,241,.08)}

.hamburger{
  display:none;position:fixed;top:14px;left:14px;z-index:200;
  width:36px;height:36px;border:1px solid var(--border);
  background:var(--surface);color:var(--text2);
  border-radius:8px;cursor:pointer;
  align-items:center;justify-content:center;font-size:1rem;
  transition:all .15s;
}
.hamburger:hover{border-color:var(--accent);color:var(--text)}
.sidebar-backdrop{
  display:none;position:fixed;inset:0;background:rgba(0,0,0,.5);
  z-index:90;
}

/* ─── Main Content ─────────────────────────────────────────── */
.main{flex:1;display:flex;flex-direction:column;overflow:hidden}
.main-header{
  padding:8px 16px 7px;
  border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;
  gap:10px;flex-shrink:0;height:36px;
}
.main-header .title-section{
  display:flex;align-items:center;gap:8px;min-width:0;
}
.main-header .title-section .nav-back{
  width:28px;height:28px;border:1px solid var(--border);
  background:var(--surface);color:var(--text2);
  border-radius:6px;cursor:pointer;display:none;
  align-items:center;justify-content:center;
  font-size:.8rem;flex-shrink:0;transition:all .15s;
}
.main-header .title-section .nav-back:hover{background:var(--surface2);color:var(--text);border-color:var(--accent)}
.main-header .title-section .nav-back.visible{display:flex}
.main-header .title-section .breadcrumbs{
  display:flex;align-items:center;gap:5px;
  font-size:.7rem;color:var(--text3);margin-top:1px;
}
.main-header .title-section .breadcrumbs span{cursor:pointer;transition:color .15s}
.main-header .title-section .breadcrumbs span:hover{color:var(--accent2)}
.main-header .title-section .breadcrumbs .sep{color:var(--border);cursor:default}
.main-header .title-section .breadcrumbs .sep:hover{color:var(--border)}
.main-header .title-nav{display:flex;align-items:center;gap:3px}
.main-header .title-nav button{
  width:28px;height:28px;border:1px solid var(--border);
  background:var(--surface);color:var(--text2);
  border-radius:6px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  font-size:.8rem;transition:all .15s;
}
.main-header .title-nav button:hover{background:var(--surface2);color:var(--text);border-color:var(--accent)}
.main-header h2{font-size:.92rem;font-weight:700;line-height:1.2}
.main-header .actions{display:flex;gap:5px;flex-shrink:0}

/* ─── Buttons ──────────────────────────────────────────────── */
.btn{
  padding:5px 10px;border:none;border-radius:var(--radius-sm);
  font-family:inherit;font-size:.75rem;font-weight:500;
  cursor:pointer;transition:all .15s;
  display:inline-flex;align-items:center;gap:4px;
}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover{filter:brightness(1.15)}
.btn-secondary{background:var(--surface);color:var(--text);border:1px solid var(--border)}
.btn-secondary:hover{background:var(--surface2)}
.btn-danger{background:rgba(239,68,68,.15);color:var(--red)}
.btn-danger:hover{background:rgba(239,68,68,.25)}
.btn-success{background:rgba(34,197,94,.15);color:var(--green)}
.btn-success:hover{background:rgba(34,197,94,.25)}
.btn-warning{background:rgba(234,179,8,.15);color:var(--yellow)}
.btn-warning:hover{background:rgba(234,179,8,.25)}
.btn-sm{padding:3px 6px;font-size:.7rem}
.btn-xs{padding:2px 5px;font-size:.64rem}
.btn-icon{width:24px;height:24px;padding:0;justify-content:center}
.content{flex:1;overflow-y:auto;padding:12px 16px}

/* ─── Dashboard Stats ──────────────────────────────────────── */
.stats-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(160px,1fr));
  gap:10px;margin-bottom:16px;
}
.stat-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);padding:10px 12px;
  transition:all .15s;cursor:pointer;
}
.stat-card:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:0 2px 12px rgba(0,0,0,.2)}
.stat-card .stat-icon{font-size:1.1rem;margin-bottom:3px}
.stat-card .label{
  font-size:.68rem;color:var(--text3);
  font-weight:500;text-transform:uppercase;letter-spacing:.4px;
}
.stat-card .value{font-size:1.5rem;font-weight:700;margin-top:2px}
.stat-card .value.green{color:var(--green)}
.stat-card .value.yellow{color:var(--yellow)}
.stat-card .value.red{color:var(--red)}
.stat-card .value.accent{color:var(--accent2)}
.section-title{
  font-size:.9rem;font-weight:600;margin-bottom:10px;
  color:var(--text2);display:flex;align-items:center;gap:6px;
}

/* ─── Project Grid & Cards (glassmorphisme) ────────────────── */
.project-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(270px,1fr));
  gap:14px;margin-bottom:24px;
}
.project-card{
  background:rgba(30,30,50,.6);
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
  border:1px solid rgba(42,42,69,.5);
  border-radius:var(--radius);padding:18px;
  cursor:pointer;transition:all .25s;
}
body.theme-light .project-card{background:rgba(255,255,255,.7);border:1px solid rgba(208,208,221,.5)}
.project-card:hover{
  border-color:var(--accent);
  transform:translateY(-3px);
  box-shadow:0 8px 32px rgba(0,0,0,.25);
}
.project-card .card-header{
  display:flex;align-items:center;gap:10px;margin-bottom:8px;
}
.project-card .card-header .dot{width:12px;height:12px;border-radius:50%;flex-shrink:0}
.project-card .card-header h3{font-size:.92rem;font-weight:600}
.project-card .card-body{
  font-size:.78rem;color:var(--text2);margin-bottom:10px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.project-card .progress-bar{
  height:4px;background:var(--bg3);border-radius:2px;overflow:hidden;margin-bottom:8px;
}
.project-card .progress-bar .fill{
  height:100%;border-radius:2px;transition:width .5s ease;
}
.project-card .card-footer{
  display:flex;justify-content:space-between;font-size:.68rem;color:var(--text3);
}

/* ─── Doc Grid (glass) ─────────────────────────────────────── */
.doc-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(270px,1fr));
  gap:14px;
}
.doc-card{
  background:rgba(30,30,50,.55);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  border:1px solid rgba(42,42,69,.4);
  border-radius:var(--radius);padding:16px;
  cursor:pointer;transition:all .25s;
}
body.theme-light .doc-card{background:rgba(255,255,255,.65);border:1px solid rgba(208,208,221,.4)}
.doc-card:hover{border-color:var(--accent);transform:translateY(-2px);box-shadow:var(--shadow)}
.doc-card .doc-icon{font-size:1.4rem;color:var(--accent2);margin-bottom:6px}
.doc-card .doc-title{font-size:.88rem;font-weight:600;margin-bottom:4px}
.doc-card .doc-meta{display:flex;gap:6px;flex-wrap:wrap;font-size:.72rem;margin-bottom:4px}
.doc-card .doc-tags{display:flex;gap:3px;flex-wrap:wrap;margin-bottom:6px}
.doc-card .doc-footer{display:flex;justify-content:space-between;font-size:.68rem;color:var(--text3)}
.doc-card .doc-actions{display:flex;gap:3px}
.doc-card .doc-actions button{
  background:none;border:none;color:var(--text3);
  cursor:pointer;padding:2px 4px;border-radius:4px;transition:all .15s;
}
.doc-card .doc-actions button:hover{background:var(--surface2);color:var(--text)}
.doc-viewer{max-width:100%}
.doc-viewer-header{border-bottom:1px solid var(--border);padding-bottom:10px;margin-bottom:10px}
.doc-viewer-body{
  font-size:.82rem;line-height:1.7;color:var(--text2);
  max-height:55vh;overflow-y:auto;
}
.doc-viewer-body h1{font-size:1.25rem;color:var(--text);margin:14px 0 6px}
.doc-viewer-body h2{font-size:1.05rem;color:var(--text);margin:12px 0 5px}
.doc-viewer-body h3{font-size:.95rem;color:var(--text);margin:10px 0 4px}
.doc-viewer-body ul{padding-left:20px;margin:8px 0}
.doc-viewer-body li{margin-bottom:3px}
.doc-viewer-body a{color:var(--accent2)}
.doc-viewer-body strong{color:var(--text)}

/* ─── Project Detail ───────────────────────────────────────── */
.detail-header{
  display:flex;align-items:center;gap:14px;margin-bottom:20px;
}
.detail-header .big-dot{width:20px;height:20px;border-radius:50%;flex-shrink:0}
.detail-header .info{flex:1}
.detail-header .info .title-row{display:flex;align-items:center;gap:8px}
.detail-header .info .title-row h2{font-size:1.4rem}
.detail-header .info .title-row .edit-name-btn{
  background:none;border:none;color:var(--text3);cursor:pointer;
  font-size:.8rem;padding:3px;border-radius:4px;transition:all .15s;
}
.detail-header .info .title-row .edit-name-btn:hover{color:var(--accent2);background:var(--surface)}
.detail-header .info .meta{
  display:flex;gap:10px;font-size:.78rem;
  color:var(--text2);margin-top:2px;flex-wrap:wrap;
}
.detail-header .info .meta span{display:flex;align-items:center;gap:4px}

/* ─── Tabs ─────────────────────────────────────────────────── */
.tabs{
  display:flex;gap:3px;margin-bottom:16px;
  border-bottom:1px solid var(--border);padding-bottom:0;
  overflow-x:auto;flex-shrink:0;
}
.tab{
  padding:9px 16px;border:none;background:transparent;
  color:var(--text2);font-family:inherit;font-size:.82rem;
  font-weight:500;cursor:pointer;border-bottom:2px solid transparent;
  transition:all .15s;margin-bottom:-1px;
  white-space:nowrap;display:flex;align-items:center;gap:5px;
}
.tab:hover{color:var(--text)}
.tab.active{color:var(--accent2);border-bottom-color:var(--accent)}
.tab-content{display:none;animation:fadeIn .2s ease}
.tab-content.active{display:block}

/* ─── Kanban Board ─────────────────────────────────────────── */
.kanban{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;min-height:280px}
.kanban-col{
  background:var(--bg2);border:1px solid var(--border);
  border-radius:var(--radius);padding:12px;transition:all .2s;
}
.kanban-col.drag-over{border-color:var(--accent);background:rgba(99,102,241,.08)}
.kanban-col .col-header{
  font-size:.78rem;font-weight:600;color:var(--text2);
  margin-bottom:10px;text-transform:uppercase;letter-spacing:.4px;
  display:flex;align-items:center;justify-content:space-between;
}
.kanban-col .col-header .count{
  background:var(--surface);padding:1px 7px;border-radius:10px;font-size:.68rem;
}
.kanban-item{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:10px;margin-bottom:6px;
  cursor:grab;transition:all .15s;position:relative;
}
.kanban-item:active{cursor:grabbing}
.kanban-item:hover{border-color:var(--accent)}
.kanban-item.dragging{opacity:.4;transform:rotate(2deg)}
.kanban-item.batch-selected{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent)}
.kanban-item .batch-check{
  display:none;position:absolute;top:5px;left:5px;width:16px;height:16px;
  border-radius:4px;border:2px solid var(--text3);background:var(--surface);
  cursor:pointer;align-items:center;justify-content:center;
  font-size:.6rem;color:transparent;transition:all .15s;z-index:2;
}
.kanban-item .batch-check.visible{display:flex}
.kanban-item .batch-check.checked{background:var(--accent);border-color:var(--accent);color:#fff}
.kanban-item .task-header{
  display:flex;justify-content:space-between;align-items:flex-start;gap:5px;
}
.kanban-item .task-title{
  font-size:.82rem;font-weight:500;margin-bottom:4px;flex:1;
}
.kanban-item .task-actions{
  display:flex;gap:1px;opacity:0;transition:opacity .15s;flex-shrink:0;
}
.kanban-item:hover .task-actions{opacity:1}
.kanban-item .task-actions button{
  background:none;border:none;color:var(--text3);cursor:pointer;
  width:20px;height:20px;border-radius:4px;font-size:.68rem;
  display:flex;align-items:center;justify-content:center;transition:all .15s;
}
.kanban-item .task-actions button:hover{background:var(--bg3);color:var(--text)}
.kanban-item .task-meta{display:flex;gap:4px;flex-wrap:wrap;font-size:.68rem}
.kanban-item .task-meta .tag{
  padding:1px 5px;border-radius:4px;background:var(--bg3);color:var(--text3);
}
.priority-low{border-left:3px solid var(--green)}
.priority-medium{border-left:3px solid var(--yellow)}
.priority-high{border-left:3px solid var(--orange)}
.priority-critical{border-left:3px solid var(--red)}
.kanban-item .tag-overdue{color:var(--red);font-weight:600}

/* ─── Notes ────────────────────────────────────────────────── */
.notes-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(250px,1fr));
  gap:12px;
}
.note-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);padding:14px;transition:all .15s;
}
.note-card:hover{border-color:var(--accent)}
.note-card.pinned{border-color:var(--yellow)}
.note-card .note-title{
  font-size:.86rem;font-weight:600;margin-bottom:5px;
  display:flex;align-items:center;gap:5px;
}
.note-card .note-content{
  font-size:.78rem;color:var(--text2);
  white-space:pre-wrap;max-height:110px;overflow-y:auto;
}
.note-card .note-footer{
  margin-top:8px;display:flex;justify-content:space-between;
  font-size:.68rem;color:var(--text3);
}
.note-card .note-footer button{
  background:none;border:none;color:var(--text3);cursor:pointer;
  padding:2px 5px;border-radius:4px;font-size:.72rem;transition:all .15s;
}
.note-card .note-footer button:hover{background:var(--bg3);color:var(--red)}

/* ─── Files ────────────────────────────────────────────────── */
.file-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px}
.file-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);padding:14px;
  display:flex;align-items:center;gap:10px;transition:all .15s;
}
.file-card:hover{border-color:var(--accent)}
.file-card .file-icon{
  width:36px;height:36px;background:var(--bg3);
  border-radius:8px;display:flex;align-items:center;justify-content:center;
  font-size:1.1rem;flex-shrink:0;
}
.file-card .file-info{flex:1;min-width:0}
.file-card .file-info .fname{
  font-size:.82rem;font-weight:500;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.file-card .file-info .fmeta{font-size:.68rem;color:var(--text3);margin-top:1px}
.file-card .file-actions{display:flex;gap:3px}
.file-card .file-actions a,.file-card .file-actions button{
  width:26px;height:26px;border:none;border-radius:5px;
  display:flex;align-items:center;justify-content:center;
  font-size:.78rem;cursor:pointer;transition:all .15s;
}
.file-card .file-actions a{background:var(--bg3);color:var(--accent2);text-decoration:none}
.file-card .file-actions a:hover{background:rgba(99,102,241,.2)}
.file-card .file-actions button{background:transparent;color:var(--text3)}
.file-card .file-actions button:hover{background:var(--bg3);color:var(--red)}
.upload-zone{
  border:2px dashed var(--border);border-radius:var(--radius);
  padding:36px 18px;text-align:center;cursor:pointer;
  transition:all .2s;margin-bottom:16px;
}
.upload-zone:hover,.upload-zone.dragover{border-color:var(--accent);background:rgba(99,102,241,.06)}
.upload-zone i{font-size:1.8rem;color:var(--text3);margin-bottom:6px}
.upload-zone p{font-size:.82rem;color:var(--text2)}
.upload-zone .sub{font-size:.72rem;color:var(--text3);margin-top:3px}

/* ─── Activity ─────────────────────────────────────────────── */
.activity-list{list-style:none}
.activity-item{
  padding:8px 0;border-bottom:1px solid var(--border);
  display:flex;gap:8px;font-size:.78rem;animation:fadeIn .2s ease;
}
.activity-item .time{color:var(--text3);white-space:nowrap;min-width:65px;font-size:.72rem}
.activity-item .act-icon{width:18px;text-align:center;flex-shrink:0;color:var(--accent2);font-size:.72rem}

/* ─── Agent Grid ───────────────────────────────────────────── */
.agent-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:10px;margin-bottom:14px;
}
.agent-card{
  background:var(--bg2);border:1px solid var(--border);
  border-radius:10px;padding:12px;cursor:pointer;
  transition:all .15s;position:relative;
}
.agent-card:hover{border-color:var(--accent);transform:translateY(-1px)}
.agent-card.selected{border-color:var(--accent);background:rgba(99,102,241,.08)}
.agent-card .agent-emoji{font-size:1.5rem;display:block;margin-bottom:4px}
.agent-card .agent-name{font-weight:600;font-size:.82rem}
.agent-card .agent-desc{font-size:.7rem;color:var(--text3);margin-top:3px}
.agent-card .agent-model{font-size:.62rem;color:var(--text3);margin-top:2px}
.agent-card .agent-check{
  position:absolute;top:6px;right:6px;
  width:16px;height:16px;border-radius:50%;
  background:var(--bg3);display:flex;align-items:center;justify-content:center;
  font-size:.5rem;color:var(--text3);
}
.agent-card.selected .agent-check{background:var(--accent);color:#fff}
.agent-exec{margin-top:14px}
.agent-exec-item{
  display:flex;align-items:center;gap:8px;
  padding:7px 10px;background:var(--bg2);border-radius:8px;
  margin-bottom:5px;font-size:.78rem;
}
.agent-exec-item .exec-status{
  width:8px;height:8px;border-radius:50%;flex-shrink:0;
}
.agent-exec-item .exec-status.pending{background:var(--text3)}
.agent-exec-item .exec-status.running{background:var(--yellow);animation:pulse 1s infinite}
.agent-exec-item .exec-status.completed{background:var(--green)}
.agent-exec-item .exec-status.failed{background:var(--red)}
.agent-btn{
  background:var(--accent);color:#fff;border:none;
  padding:5px 12px;border-radius:6px;cursor:pointer;
  font-size:.75rem;transition:all .15s;
}
.agent-btn:hover{filter:brightness(1.1);transform:translateY(-1px)}
.agent-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
.agent-btn-outline{
  background:transparent;color:var(--text);border:1px solid var(--border);
  padding:3px 8px;border-radius:5px;cursor:pointer;font-size:.7rem;
}

/* ─── Inline Edit ──────────────────────────────────────────── */
.inline-edit{
  width:100%;background:var(--bg3);border:1px solid var(--accent);
  border-radius:6px;color:var(--text);font-family:inherit;
  font-size:inherit;padding:5px 8px;outline:none;
}
.inline-edit:focus{box-shadow:0 0 0 3px rgba(99,102,241,.2)}

/* ─── Charts ───────────────────────────────────────────────── */
.chart-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:20px;
}
.chart-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);padding:16px;
}
.chart-card h4{
  font-size:.82rem;font-weight:600;margin-bottom:10px;
  color:var(--text2);display:flex;align-items:center;gap:5px;
}
.chart-card .chart-wrap{position:relative;height:190px}
.chart-card.full{grid-column:1/-1}
.chart-card.full .chart-wrap{height:110px}

/* ─── Modal ────────────────────────────────────────────────── */
.modal-overlay{
  display:none;position:fixed;inset:0;
  background:rgba(0,0,0,.6);
  backdrop-filter:blur(6px);
  -webkit-backdrop-filter:blur(6px);
  z-index:1000;align-items:center;justify-content:center;
  animation:fadeIn .15s ease;
}
.modal-overlay.open{display:flex}
.modal{
  background:var(--bg2);border:1px solid var(--border);
  border-radius:var(--radius);padding:24px;
  width:520px;max-width:90vw;max-height:85vh;
  overflow-y:auto;box-shadow:0 8px 40px rgba(0,0,0,.5);
  animation:scaleIn .2s ease;
}
.modal h3{font-size:1.05rem;font-weight:600;margin-bottom:16px;display:flex;align-items:center;gap:7px}

/* ─── Forms ────────────────────────────────────────────────── */
.form-group{margin-bottom:14px}
.form-group label{
  display:block;font-size:.78rem;font-weight:500;
  color:var(--text2);margin-bottom:5px;
}
.form-group input,.form-group textarea,.form-group select{
  width:100%;padding:9px 10px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius-sm);
  color:var(--text);font-family:inherit;font-size:.82rem;
  outline:none;transition:border .15s;
}
.form-group input:focus,.form-group textarea:focus,.form-group select:focus{border-color:var(--accent)}
.form-group textarea{min-height:70px;resize:vertical}
.form-group select{cursor:pointer}
.form-group .color-picker{display:flex;gap:6px}
.form-group .color-picker .color-opt{
  width:30px;height:30px;border-radius:50%;
  border:2px solid transparent;cursor:pointer;transition:all .15s;
}
.form-group .color-picker .color-opt:hover{transform:scale(1.15)}
.form-group .color-picker .color-opt.selected{border-color:#fff}
.modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}
.form-row{display:flex;gap:10px}
.form-row .form-group{flex:1}

/* ─── Tables ────────────────────────────────────────────────── */
.table-wrap{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);overflow-x:auto;
}
.data-table{width:100%;border-collapse:collapse;font-size:.82rem}
.data-table th{
  text-align:left;padding:10px 12px;font-size:.72rem;
  font-weight:600;text-transform:uppercase;letter-spacing:.04em;
  color:var(--text3);border-bottom:1px solid var(--border);
  white-space:nowrap;background:var(--surface);
}
.data-table td{padding:10px 12px;border-bottom:1px solid var(--border);color:var(--text2)}
.data-table tr:hover td{background:var(--bg3)}
.data-table .mono{font-family:var(--font-mono, monospace);font-size:.78rem}
/* Status badges in tables */
.data-table .badge{font-size:.7rem;padding:2px 8px;border-radius:4px;font-weight:600;white-space:nowrap}
.data-table .badge-paid,.data-table .badge-done{background:rgba(34,197,94,.15);color:var(--green)}
.data-table .badge-pending,.data-table .badge-review{background:rgba(234,179,8,.15);color:var(--yellow)}
.data-table .badge-failed,.data-table .badge-todo{background:rgba(239,68,68,.15);color:var(--red)}
.data-table .badge-refunded{background:rgba(99,102,241,.15);color:var(--accent2)}
.data-table .badge-active,.data-table .badge-done{background:rgba(34,197,94,.15);color:var(--green)}
.data-table .badge-paused,.data-table .badge-review{background:rgba(234,179,8,.15);color:var(--yellow)}
.data-table .badge-cancelled,.data-table .badge-archived{background:rgba(104,104,160,.15);color:var(--text3)}

/* ─── Toast ────────────────────────────────────────────────── */
.toast-container{
  position:fixed;bottom:20px;right:20px;z-index:2000;
  display:flex;flex-direction:column;gap:6px;
  pointer-events:none;
}
.toast{
  background:var(--surface2);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:10px 16px;
  font-size:.82rem;color:var(--text);
  display:flex;align-items:center;gap:7px;
  box-shadow:0 4px 20px rgba(0,0,0,.4);
  animation:slideIn .25s ease;
  min-width:240px;pointer-events:auto;
}
.toast.success{border-left:3px solid var(--green)}
.toast.error{border-left:3px solid var(--red)}
.toast.warning{border-left:3px solid var(--yellow)}
.toast.info{border-left:3px solid var(--accent)}

/* ─── Empty State ──────────────────────────────────────────── */
.empty-state{text-align:center;padding:50px 20px;color:var(--text3)}
.empty-state .empty-icon{font-size:2.8rem;margin-bottom:10px}
.empty-state h3{font-size:1.05rem;color:var(--text2);margin-bottom:4px}
.empty-state p{font-size:.82rem}

/* ─── Tags ─────────────────────────────────────────────────── */
.tag{
  display:inline-flex;align-items:center;gap:3px;
  padding:2px 7px;border-radius:4px;
  background:var(--bg3);color:var(--text3);font-size:.68rem;
  font-weight:500;
}
.tag-primary{background:rgba(99,102,241,.15);color:var(--accent2)}
.tag-green{background:rgba(34,197,94,.15);color:var(--green)}
.tag-red{background:rgba(239,68,68,.15);color:var(--red)}
.tag-yellow{background:rgba(234,179,8,.15);color:var(--yellow)}
.tag-orange{background:rgba(249,115,22,.15);color:var(--orange)}

/* ─── Batch Bar ────────────────────────────────────────────── */
.batch-bar{
  display:flex;gap:6px;margin-bottom:10px;
  padding:7px 10px;background:var(--surface);
  border:1px solid var(--accent);border-radius:8px;
  align-items:center;animation:fadeIn .2s ease;
}
.batch-bar span{font-size:.78rem;color:var(--text2)}

/* ─── Timeline Markers ─────────────────────────────────────── */
.timeline-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;margin-top:5px}
.timeline-dot.td-create{background:var(--accent2)}
.timeline-dot.td-update{background:var(--yellow)}
.timeline-dot.td-delete{background:var(--red)}
.timeline-dot.td-complete{background:var(--green)}
.timeline-dot.td-default{background:var(--text3)}

/* ─── Responsive ───────────────────────────────────────────── */
@media(max-width:1200px){.kanban{grid-template-columns:repeat(2,1fr)}}
@media(max-width:900px){.sidebar{width:220px;min-width:220px}}
@media(max-width:768px){
  .sidebar{position:fixed;left:0;top:0;bottom:0;transform:translateX(-100%);z-index:100;width:280px;min-width:280px}
  .sidebar.open{transform:translateX(0)}
  .sidebar-backdrop.open{display:block}
  .hamburger{display:flex}
  .main-header{padding:14px 14px 14px 56px}
  .content{padding:14px}
}
@media(max-width:640px){
  .stats-grid{grid-template-columns:repeat(2,1fr)}
  .kanban{grid-template-columns:1fr}
  .chart-grid{grid-template-columns:1fr}
  .file-list{grid-template-columns:1fr}
  .doc-grid{grid-template-columns:1fr}
  .notes-grid{grid-template-columns:1fr}
  .project-grid{grid-template-columns:1fr}
  .main-header h2{font-size:1.05rem}
  .main-header .actions .btn span{display:none}
  .modal{width:95vw;padding:18px}
  .form-row{flex-direction:column;gap:0}
}
@media(max-width:400px){
  .stats-grid{grid-template-columns:1fr}
  .toast-container{left:10px;right:10px;bottom:10px}
  .toast{min-width:auto}
}
.sidebar-link.disabled:hover{background:transparent;color:var(--text2);cursor:default}
    const styles = [];
    html = html.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, (m, c) => {
      styles.push(c);
      return '';
    });
    
    el.innerHTML = styleTag + html;
    // Re-run any inline scripts
    el.querySelectorAll('script').forEach(s => {
      const ns = document.createElement('script');
      if (s.src) { ns.src = s.src; } 
      else { ns.textContent = s.textContent; }
      document.body.appendChild(ns);
    });
  } catch(e) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p></div>';
  }
}
function switchView(view, fromHistory) {
  state.currentView = view;
  state.currentProject = null;
  document.querySelectorAll('.nav-btn').forEach(b => b.classList.toggle('active', b.dataset.view === view));
  document.getElementById('headerActions').innerHTML = '';
  if (!fromHistory) pushView(view);
  if (view === 'dashboard') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-chart-pie"></i> Vue d\'ensemble';
    renderDashboard();
  } else if (view === 'clients') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-users"></i> Clients — CRM';
    renderClients();
  } else if (view === 'presse') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-newspaper"></i> Revue de presse';
    renderPresse();
  } else if (view === 'marches') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-landmark"></i> Marchés Publics';
    renderMarches();
    // Reset to AO view when clicking Marchés
    if (typeof switchToAOView === 'function') switchToAOView();
  } else if (view === 'marches-reponses') {
    renderMarches();
    setTimeout(function() {
      if (typeof switchToReponsesView === 'function') switchToReponsesView();
    }, 200);
  } else if (view === 'stack') {
      document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-server"></i> Stack Monitor';
      renderStack();
    } else if (view === 'subscriptions') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-receipt"></i> Abonnements SaaS — Suivi des coûts réels';
    renderSubscriptions();
  } else if (view === 'notion') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-brands fa-notion"></i> Notion — Sync & Configuration';
    renderNotion();
  } else if (view === 'ideas') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-lightbulb"></i> Pipeline Idées Produits & Services';
    renderIdeas();
  } else if (view === 'enterprise') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-building"></i> Enterprise — KPIs & Pilotage d\'Entreprise';
    renderEnterprise();

  } else if (view === 'products-manager') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-box"></i> Produits & Services';
    renderStaticPage('products-manager.html');
  } else if (view === 'products') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-shopping-bag"></i> Catalogue';
    renderStaticPage('products.html');
  } else if (view === 'portfolio') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-briefcase"></i> Portfolio';
    renderStaticPage('portfolio.html');
  } else if (view === 'workflows') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-diagram-project"></i> Workflows';
    renderStaticPage('workflows.html');
  } else if (view === 'python-formation') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-code"></i> Formation Python';
    renderStaticPage('python-formation.html');
  } else if (view === 'architecture') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-diagram-project"></i> Architecture IT';
    renderStaticPage('architecture.html');
  } else if (view === 'processes') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-diagram-project"></i> Process Dashboard';
    renderProcessDashboard();
  } else if (view === 'deals-pipeline') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-circle"></i> Pipeline Deals';
    renderDealsPipeline();
  } else if (view === 'branding') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-circle"></i> Branding Studio';
    renderBranding();
  } else if (view === 'documents') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-circle"></i> Documents';
    renderDocuments();
  } else if (view === 'trading') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-chart-line"></i> Trading — Dashboard';
    renderTrading();
  } else if (view === 'pipeline') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-diagram-project"></i> Pipeline de Trading';
    renderPipeline();
  } else if (view === 'trading-smoke') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-check-double"></i> Trading — Smoke Tests';
    renderTradingSmoke();
  } else if (view === 'macro') {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-circle"></i> Macro Radar';
    renderMacro();
  } else {
    document.getElementById('viewTitle').innerHTML = '<i class="fa-solid fa-folder"></i> Tous les projets';
    renderAllProjects();
  }
  document.querySelectorAll('.project-item').forEach(el => el.classList.remove('active'));
  updateNavUI();
  if (window.innerWidth < 768) closeSidebar();
}

// ── Trading Pipeline & Smoke ───────────────────────────────────
function renderPipeline() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<iframe src="/trading-pipeline.html" style="width:100%;height:calc(100vh - 120px);border:none;border-radius:8px;background:var(--bg)"></iframe>';
}

function renderTradingSmoke() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="padding:24px"><h2 style="margin-bottom:16px"><i class="fa-solid fa-check-double"></i> Trading Smoke Tests</h2>'+
    '<div style="display:flex;gap:16px;flex-wrap:wrap;margin-bottom:16px">'+
    '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-rotate"></i></div><div class="label">Dernier run</div><div class="value accent" id="smokeLastRun">—</div></div>'+
    '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-check-circle"></i></div><div class="label">Status</div><div class="value green" id="smokeStatus">—</div></div>'+
    '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-list-check"></i></div><div class="label">Checks OK</div><div class="value accent" id="smokeChecks">—</div></div>'+
    '</div><div style="margin-top:20px"><button class="btn btn-sm" style="background:var(--accent);color:#fff" onclick="runSmokeTest()"><i class="fa-solid fa-play"></i> Lancer Smoke Test</button></div>'+
    '<table id="smokeTable" style="margin-top:16px;width:100%;border-collapse:collapse;display:none"><thead><tr style="text-align:left"><th style="padding:8px;border-bottom:1px solid var(--border)">Check</th><th style="padding:8px;border-bottom:1px solid var(--border)">Status</th><th style="padding:8px;border-bottom:1px solid var(--border)">Détail</th></tr></thead><tbody id="smokeTableBody"></tbody></table>'+
    '<pre id="smokeOutput" style="margin-top:16px;background:var(--surface);padding:16px;border-radius:8px;font-family:JetBrains Mono,monospace;font-size:11px;max-height:400px;overflow:auto;color:var(--text2)">Cliquez sur Lancer pour exécuter…</pre>'+
    '</div>';
}

async function runSmokeTest() {
  const btn = document.querySelector('#contentArea button');
  const out = document.getElementById('smokeOutput');
  const tbl = document.getElementById('smokeTable');
  const tblBody = document.getElementById('smokeTableBody');
  if (btn) btn.disabled = true;
  out.textContent = 'Exécution des checks...';
  tbl.style.display = 'none';

  const auth = localStorage.getItem('dashboardAuth') ? 'Basic ' + localStorage.getItem('dashboardAuth') : '';
  const headers = auth ? { Authorization: auth } : {};

  const checks = [];
  let okCount = 0;
  const endpoints = [
    '/api/trading/v2/portfolio',
    '/api/trading/v2/signals',
    '/api/trading/v2/risk',
    '/api/trading/v2/orders?source=all',
    '/api/trading/v2/pnl-history',
    '/api/trading/v2/health',
    '/api/trading/v2/kill-switch',
    '/api/trading/v2/news'
  ];

  for (const ep of endpoints) {
    try {
      const r = await fetch(ep, { headers });
      const d = await r.json();
      const label = ep.split('/api/trading/v2/')[1].split('?')[0];
      const ok = d.ok === true;
      if (ok) okCount++;
      checks.push({ name: 'endpoint:' + label, ok, detail: ok ? '200 OK' : (d.error || 'failed') });
    } catch (e) {
      checks.push({ name: 'endpoint:' + ep, ok: false, detail: e.message });
    }
  }

  // Allocations check
  try {
    const r = await fetch('/api/trading/v2/portfolio', { headers });
    const d = await r.json();
    const allocSum = Object.values(d.allocations_total || {}).reduce((a, b) => a + b, 0) * 100;
    const ok = Math.abs(allocSum - 100) < 0.5;
    if (ok) okCount++;
    checks.push({ name: 'allocations=100%', ok, detail: allocSum.toFixed(1) + '%' });
  } catch (e) {
    checks.push({ name: 'allocations=100%', ok: false, detail: e.message });
  }

  // Risk exposure check
  try {
    const r = await fetch('/api/trading/v2/risk', { headers });
    const d = await r.json();
    const expSum = Object.values(d.exposure_by_class || {}).reduce((a, b) => a + b, 0) * 100;
    const ok = Math.abs(expSum - 100) < 0.5;
    if (ok) okCount++;
    checks.push({ name: 'risk exposure=100%', ok, detail: expSum.toFixed(1) + '%' });
  } catch (e) {
    checks.push({ name: 'risk exposure=100%', ok: false, detail: e.message });
  }

  // Coherence check
  try {
    const r = await fetch('/api/trading/v2/portfolio', { headers });
    const d = await r.json();
    const ok = d.coherence_ok === true;
    if (ok) okCount++;
    checks.push({ name: 'portfolio coherence', ok, detail: d.coherence_equation || '' });
  } catch (e) {
    checks.push({ name: 'portfolio coherence', ok: false, detail: e.message });
  }

  // Render
  const now = new Date().toLocaleString('fr-FR');
  document.getElementById('smokeLastRun').textContent = now;
  const totalChecks = checks.length;
  const allOk = okCount === totalChecks;
  document.getElementById('smokeStatus').textContent = allOk ? 'OK' : 'FAIL';
  document.getElementById('smokeStatus').className = 'value ' + (allOk ? 'green' : 'red');
  document.getElementById('smokeChecks').textContent = okCount + '/' + totalChecks;

  tblBody.innerHTML = checks.map(c =>
    '<tr><td style="padding:6px 8px">' + (c.ok ? '✅' : '❌') + ' ' + c.name + '</td>' +
    '<td style="padding:6px 8px">' + (c.ok ? 'OK' : 'FAIL') + '</td>' +
    '<td style="padding:6px 8px;color:var(--text2);font-size:11px">' + c.detail + '</td></tr>'
  ).join('');
  tbl.style.display = 'table';
  out.textContent = JSON.stringify({ total: totalChecks, ok: okCount, fail: totalChecks - okCount }, null, 2);

  if (btn) btn.disabled = false;
}

function selectProject(id, fromHistory) {
  state.currentView = 'detail';
  state.currentProject = state.projects.find(p => p.id === id) || null;
  document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
  if (!fromHistory) pushView('detail', id);
  updateNavUI();
  renderProjectDetail(id);
  if (window.innerWidth < 768) closeSidebar();
}

// ═══════════════════════════════════════════════════════════════
// PROJECTS
// ═══════════════════════════════════════════════════════════════
async function loadProjects() {
  try {
    state.projects = await api('/api/projects');
    renderProjectList(state.projects);
  } catch(e) {
    toast('Erreur chargement projets: ' + e.message, 'error');
  }
}

function renderProjectList(projects) {
  const el = document.getElementById('projectList');
  if (!projects.length) {
    el.innerHTML = '<div class="empty-state" style="padding:24px 10px"><p style="font-size:.78rem">Aucun projet</p></div>';
    return;
  }
  el.innerHTML = projects.map(p =>
    '<div class="project-item ' + (state.currentProject?.id === p.id ? 'active' : '') + '" onclick="selectProject(' + p.id + ')">' +
      '<span class="dot" style="background:' + p.color + '"></span>' +
      '<div class="info">' +
        '<div class="name">' + esc(p.name) + '</div>' +
        '<div class="meta"><span>' + (p.progress || 0) + '%</span><span class="badge badge-' + p.status + '">' + p.status + '</span></div>' +
      '</div>' +
    '</div>'
  ).join('');
}

function filterProjects(q) {
  const filtered = state.projects.filter(p => p.name.toLowerCase().includes(q.toLowerCase()));
  renderProjectList(filtered);
}

// ═══════════════════════════════════════════════════════════════
// DASHBOARD
// ═══════════════════════════════════════════════════════════════
async function renderDashboard() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const s = await api('/api/summary');
    el.innerHTML =
        '<div class="stats-grid anim-fade">' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-rocket"></i></div><div class="label">Projets actifs</div><div class="value accent">' + s.active_projects + '</div></div>' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-check-circle"></i></div><div class="label">Terminés</div><div class="value green">' + s.completed_projects + '</div></div>' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-spinner"></i></div><div class="label">Tâches en cours</div><div class="value yellow">' + s.in_progress_tasks + '</div></div>' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-clock"></i></div><div class="label">Tâches en retard</div><div class="value ' + (s.overdue_tasks > 0 ? 'red' : 'green') + '">' + s.overdue_tasks + '</div></div>' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-list"></i></div><div class="label">À faire</div><div class="value">' + s.todo_tasks + '</div></div>' +
          '<div class="stat-card"><div class="stat-icon"><i class="fa-solid fa-check-double"></i></div><div class="label">Terminées</div><div class="value green">' + s.done_tasks + '</div></div>' +
          '<div class="stat-card" style="cursor:pointer" onclick="switchView(\'presse\')"><div class="stat-icon"><i class="fa-solid fa-newspaper"></i></div><div class="label">Articles récents</div><div class="value accent">' + (s.total_articles || 0) + '</div></div>' +
          '<div class="stat-card" style="cursor:pointer" onclick="switchView(\'sondages\')"><div class="stat-icon"><i class="fa-solid fa-chart-bar"></i></div><div class="label">Sondages</div><div class="value accent">' + (s.total_polls || 0) + '</div></div>' +
        '</div>' +
        // ── Projets (partie fonctionnelle en premier) ──
        '<div class="section-title"><i class="fa-solid fa-folder-open"></i> Projets récents</div>'
        // ── Validations en attente ──
        + (await (async() => {
          try {
            const tasks = await api('/api/tasks?status=review');
            if (!tasks || !tasks.length) return '';
            return '<div class="section-title" style="margin-top:20px"><i class="fa-solid fa-check-circle" style="color:var(--orange)"></i> Validations en attente (' + tasks.length + ')</div>' +
              '<div class="project-grid anim-fade">' +
              tasks.slice(0, 4).map(t =>
                '<div class="project-card" style="border-left:3px solid var(--orange);cursor:pointer" onclick="selectProject(' + t.project_id + ')">' +
                  '<div class="card-header"><h3>' + esc(t.title) + '</h3></div>' +
                  '<div class="card-body">' + esc(t.project_name || '') + '</div>' +
                  '<div class="card-footer"><span class="badge badge-review">🔍 À valider</span></div>' +
                '</div>'
              ).join('') + '</div>';
          } catch(e) { return ''; }
        })()) +
        '<div class="project-grid anim-fade">' +
          (s.projects ? s.projects.map(p =>
            '<div class="project-card" onclick="selectProject(' + p.id + ')" style="animation-delay:' + (Math.random()*0.1) + 's">' +
              '<div class="card-header"><span class="dot" style="background:' + p.color + '"></span><h3>' + esc(p.name) + '</h3></div>' +
              '<div class="card-body">' + esc(p.category) + ' · ' + p.status + '</div>' +
              '<div class="progress-bar"><div class="fill" style="width:' + p.progress + '%;background:' + p.color + '"></div></div>' +
              '<div class="card-footer"><span>' + p.progress + '%</span><span class="badge badge-' + p.status + '">' + p.status + '</span></div>' +
            '</div>'
          ).join('') : '') +
        '</div>' +
        // ── Graphiques (indicateurs après) ──
        '<div class="chart-grid anim-fade">' +
          '<div class="chart-card"><h4><i class="fa-solid fa-list-check"></i> Statut des tâches</h4><div class="chart-wrap"><canvas id="chartStatus"></canvas></div></div>' +
          '<div class="chart-card"><h4><i class="fa-solid fa-flag"></i> Priorités (actives)</h4><div class="chart-wrap"><canvas id="chartPriority"></canvas></div></div>' +
          '<div class="chart-card full"><h4><i class="fa-solid fa-chart-bar"></i> Progression des projets</h4><div class="chart-wrap"><canvas id="chartProgress"></canvas></div></div>' +
          '<div class="chart-card full"><h4><i class="fa-solid fa-chart-line"></i> Tâches terminées (7 jours)</h4><div class="chart-wrap"><canvas id="chartWeekly"></canvas></div></div>' +
        '</div>' +
        (s.recent_activity && s.recent_activity.length ?
        '<div class="section-title"><i class="fa-solid fa-history"></i> Activité récente</div>' +
        '<ul class="activity-list">' +
          s.recent_activity.map(a =>
            '<li class="activity-item">' +
              '<span class="time">' + (a.created_at?.split(' ')[1]?.slice(0,5) || '') + '</span>' +
              '<i class="fa-solid fa-circle" style="color:var(--accent);font-size:.38rem;margin-top:6px"></i>' +
              '<span>' + esc(a.detail) + '</span>' +
              (a.project_name ? '<span class="badge badge-active">' + esc(a.project_name) + '</span>' : '') +
            '</li>'
          ).join('') +
        '</ul>' : '');
    setTimeout(renderCharts, 100);
  } catch(e) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p><br><button class="btn btn-primary" onclick="renderDashboard()">Réessayer</button></div>';
  }
}

// ═══════════════════════════════════════════════════════════════
// CHARTS
// ═══════════════════════════════════════════════════════════════
async function renderCharts() {
  Object.values(chartInstances).forEach(c => { try { c.destroy(); } catch(e) {} });
  chartInstances = {};
  try {
    const data = await api('/api/charts');
    const isDark = !document.body.classList.contains('theme-light');
    const textColor = isDark ? '#9898b8' : '#505070';
    const gridColor = isDark ? '#2a2a45' : '#d0d0dd';
    const accentColor = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#6366f1';
    const accent2Color = getComputedStyle(document.documentElement).getPropertyValue('--accent2').trim() || '#818cf8';

    const sCanvas = document.getElementById('chartStatus');
    if (sCanvas && data.status_distribution) {
      const sLabels = { todo:'À faire', in_progress:'En cours', review:'Revue', done:'Terminé' };
      const sColors = { todo:'#6366f1', in_progress:'#eab308', review:'#f97316', done:'#22c55e' };
      chartInstances.status = new Chart(sCanvas, {
        type: 'doughnut',
        data: {
          labels: Object.keys(data.status_distribution).map(k => sLabels[k] || k),
          datasets: [{ data: Object.values(data.status_distribution), backgroundColor: Object.keys(data.status_distribution).map(k => sColors[k] || accentColor), borderWidth: 0 }]
        },
        options: { responsive: true, maintainAspectRatio: false, cutout: '65%', plugins: { legend: { position: 'bottom', labels: { color: textColor, padding: 10, font: { size: 11 } } } } }
      });
    }

    const pCanvas = document.getElementById('chartPriority');
    if (pCanvas && data.priority_distribution) {
      const pLabels = { low:'Basse', medium:'Moyenne', high:'Haute', critical:'Critique' };
      const pColors = { low:'#22c55e', medium:'#6366f1', high:'#f97316', critical:'#ef4444' };
      chartInstances.priority = new Chart(pCanvas, {
        type: 'doughnut',
        data: {
          labels: Object.keys(data.priority_distribution).map(k => pLabels[k] || k),
          datasets: [{ data: Object.values(data.priority_distribution), backgroundColor: Object.keys(data.priority_distribution).map(k => pColors[k] || accentColor), borderWidth: 0 }]
        },
        options: { responsive: true, maintainAspectRatio: false, cutout: '65%', plugins: { legend: { position: 'bottom', labels: { color: textColor, padding: 10, font: { size: 11 } } } } }
      });
    }

    const prCanvas = document.getElementById('chartProgress');
    if (prCanvas) {
      const projs = data.projects_progress || [];
      chartInstances.progress = new Chart(prCanvas, {
        type: 'bar',
        data: {
          labels: projs.map(p => p.name),
          datasets: [{ label: 'Progression (%)', data: projs.map(p => p.progress), backgroundColor: projs.map(p => p.color || accentColor), borderRadius: 4 }]
        },
        options: { indexAxis: 'y', responsive: true, maintainAspectRatio: false, scales: { x: { max: 100, grid: { color: gridColor }, ticks: { color: textColor, font: { size: 10 } } }, y: { grid: { display: false }, ticks: { color: textColor, font: { size: 10 } } } }, plugins: { legend: { display: false } } }
      });
    }

    const wCanvas = document.getElementById('chartWeekly');
    if (wCanvas) {
      const weekly = data.weekly_completions || [];
      chartInstances.weekly = new Chart(wCanvas, {
        type: 'line',
        data: {
          labels: weekly.map(w => w.day?.slice(5) || '?'),
          datasets: [{ label: 'Tâches terminées', data: weekly.map(w => w.cnt || 0), borderColor: accentColor, backgroundColor: accentColor + '20', fill: true, tension: 0.3, pointBackgroundColor: accentColor, pointRadius: 3 }]
        },
        options: { responsive: true, maintainAspectRatio: false, scales: { x: { grid: { display: false }, ticks: { color: textColor, font: { size: 10 } } }, y: { beginAtZero: true, grid: { color: gridColor }, ticks: { color: textColor, font: { size: 10 }, stepSize: 1 } } }, plugins: { legend: { labels: { color: textColor, font: { size: 10 } } } } }
      });
    }
  } catch(e) {
    console.error('Chart error:', e);
  }
}

// ═══════════════════════════════════════════════════════════════
// ALL PROJECTS VIEW
// ═══════════════════════════════════════════════════════════════
async function renderAllProjects() {
  const el = document.getElementById('contentArea');
  let projects;
  try {
    projects = await api('/api/projects');
  } catch(e) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p></div>';
    return;
  }
  if (!projects.length) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-folder"></i></div><h3>Aucun projet</h3><p>Crée ton premier projet pour commencer</p><br><button class="btn btn-primary" onclick="openModal(\'project\')"><i class="fa-solid fa-plus"></i> Nouveau projet</button></div>';
    return;
  }
  el.innerHTML =
    '<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px">' +
      '<div class="section-title" style="margin-bottom:0"><i class="fa-solid fa-folder"></i> Projets (' + projects.length + ')</div>' +
      '<button class="btn btn-primary btn-sm" onclick="openModal(\'project\')"><i class="fa-solid fa-plus"></i> Nouveau</button>' +
    '</div>' +
    '<div class="project-grid anim-fade">' +
      projects.map(p =>
        '<div class="project-card" onclick="selectProject(' + p.id + ')">' +
          '<div class="card-header"><span class="dot" style="background:' + p.color + '"></span><h3>' + esc(p.name) + '</h3></div>' +
          '<div class="card-body">' + esc(p.description || p.category) + '</div>' +
          '<div class="progress-bar"><div class="fill" style="width:' + p.progress + '%;background:' + p.color + '"></div></div>' +
          '<div class="card-footer"><span>' + p.progress + '%</span><span class="badge badge-' + p.status + '">' + p.status + '</span></div>' +
        '</div>'
      ).join('') +
    '</div>';
}

// ═══════════════════════════════════════════════════════════════
// CLIENTS (CRM)
// ═══════════════════════════════════════════════════════════════
async function renderClients() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  const tabs = [
    { id: 'clients', label: 'Clients', icon: 'fa-users' },
    { id: 'deals', label: 'Affaires', icon: 'fa-handshake' },
    { id: 'opportunities', label: 'Opportunites', icon: 'fa-chart-line' },
    { id: 'contacts', label: 'Contacts', icon: 'fa-address-book' },
    { id: 'invoices', label: 'Factures', icon: 'fa-file-invoice' },
    { id: 'campaigns', label: 'Campagnes', icon: 'fa-bullhorn' },
  ];
  let html = '<div class="tabs">';
  tabs.forEach(t => { html += '<button class="tab ' + (state.crmTab === t.id ? 'active' : '') + '" onclick="state.crmTab=\'' + t.id + '\';renderClients()"><i class="fa-solid ' + t.icon + '"></i> ' + t.label + '</button>'; });
  html += '</div><div class="tab-content active" id="crmTabContent"></div>';
  el.innerHTML = html;
  if (!state.crmTab) state.crmTab = 'clients';
  if (state.crmTab === 'clients') await renderClientsTab();
  else if (state.crmTab === 'deals') await renderDealsTab();
  else if (state.crmTab === 'opportunities') await renderOpportunitiesTab();
  else if (state.crmTab === 'contacts') await renderContactsTab();
  else if (state.crmTab === 'invoices') await renderInvoicesTab();
  else if (state.crmTab === 'campaigns') await renderCampaignsTab();
}

async function renderClientsTab() {
  const el = document.getElementById('crmTabContent');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const clients = await api('/api/crm/clients');
    el.innerHTML = '<div style="margin-bottom:14px;display:flex;gap:8px;align-items:center"><button class="btn btn-primary btn-sm" onclick="openClientModal()"><i class="fa-solid fa-plus"></i> Nouveau client</button><button class="btn btn-secondary btn-sm" onclick="renderClients()"><i class="fa-solid fa-rotate"></i> Actualiser</button></div><div class="section-title"><i class="fa-solid fa-users"></i> Clients (' + clients.length + ')</div><div class="project-grid" style="grid-template-columns:repeat(auto-fill,minmax(300px,1fr))">' +
      clients.map(c => { const sc = c.status === 'client' ? 'var(--green)' : c.status === 'prospect' ? 'var(--yellow)' : 'var(--text3)'; return '<div class="project-card" style="padding:14px"><div style="display:flex;align-items:flex-start;gap:10px"><div style="width:42px;height:42px;border-radius:50%;background:' + sc + '20;display:flex;align-items:center;justify-content:center;color:' + sc + ';font-size:1.2rem"><i class="fa-solid fa-building"></i></div><div style="flex:1;min-width:0"><div style="font-size:.88rem;font-weight:600;margin-bottom:3px">' + esc(c.name) + '</div>' + (c.company ? '<div style="font-size:.78rem;color:var(--text2);margin-bottom:4px"><i class="fa-solid fa-briefcase"></i> ' + esc(c.company) + '</div>' : '') + '<div style="font-size:.72rem;color:var(--text3);display:flex;gap:8px;flex-wrap:wrap">' + (c.email ? '<span><i class="fa-solid fa-envelope"></i> ' + esc(c.email) + '</span>' : '') + (c.phone ? '<span><i class="fa-solid fa-phone"></i> ' + esc(c.phone) + '</span>' : '') + '</div><div style="margin-top:6px"><span class="badge" style="background:' + sc + '20;color:' + sc + '">' + (c.status || 'prospect') + '</span></div></div></div></div>'; }).join('') +
      (clients.length === 0 ? '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-users"></i></div><h3>Aucun client</h3><p>Commencez par ajouter votre premier client</p></div>' : '') + '</div>';
  } catch(e) { el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p></div>'; }
}

function openClientModal() {
  const m = document.getElementById('modalContent');
  m.innerHTML = '<div class="modal-header"><h3><i class="fa-solid fa-user-plus"></i> Nouveau client</h3><button class="modal-close" onclick="closeModal()">&times;</button></div><div class="modal-body"><div class="form-group"><label>Nom *</label><input id="cName" class="form-input" placeholder="Nom du client"></div><div class="form-group"><label>Entreprise</label><input id="cCompany" class="form-input" placeholder="Nom de l\'entreprise"></div><div class="form-group"><label>Email</label><input id="cEmail" class="form-input" type="email" placeholder="email@exemple.com"></div><div class="form-group"><label>Telephone</label><input id="cPhone" class="form-input" placeholder="+33 6 12 34 56 78"></div><div class="form-group"><label>Statut</label><select id="cStatus" class="form-input"><option value="prospect">Prospect</option><option value="contact">Contact</option><option value="qualified">Qualifie</option><option value="client">Client</option></select></div><div class="form-group"><label>Notes</label><textarea id="cNotes" class="form-input" rows="3"></textarea></div></div><div class="modal-footer"><button class="btn btn-secondary" onclick="closeModal()">Annuler</button><button class="btn btn-primary" onclick="saveClient()"><i class="fa-solid fa-check"></i> Creer</button></div>';
  openModal();
}

async function saveClient() {
  const name = document.getElementById('cName').value.trim();
  if (!name) { toast('Le nom est obligatoire', 'error'); return; }
  try {
    await api('/api/crm/clients', { method: 'POST', body: { name, company: document.getElementById('cCompany').value.trim(), email: document.getElementById('cEmail').value.trim(), phone: document.getElementById('cPhone').value.trim(), status: document.getElementById('cStatus').value, notes: document.getElementById('cNotes').value.trim() } });
    closeModal(); toast('Client cree', 'success'); renderClients();
  } catch(e) { toast('Erreur: ' + e.message, 'error'); }
}

async function renderDealsTab() { renderSubTabPlaceholder('Affaires', 'fa-handshake'); }
async function renderOpportunitiesTab() { renderSubTabPlaceholder('Opportunites', 'fa-chart-line'); }
async function renderContactsTab() { renderSubTabPlaceholder('Contacts', 'fa-address-book'); }
async function renderInvoicesTab() { renderSubTabPlaceholder('Factures', 'fa-file-invoice'); }
async function renderCampaignsTab() { renderSubTabPlaceholder('Campagnes', 'fa-bullhorn'); }

function renderSubTabPlaceholder(title, icon) {
  const el = document.getElementById('crmTabContent');
  el.innerHTML = '<div class="empty-state" style="margin-top:20px"><div class="empty-icon"><i class="fa-solid ' + icon + '"></i></div><h3>' + title + '</h3><p>Module en cours de developpement</p><button class="btn btn-primary btn-sm" onclick="renderClients()"><i class="fa-solid fa-arrow-left"></i> Retour</button></div>';
}

// ═══════════════════════════════════════════════════════════════

// ═══════════════════════════════════════════════════════════════
// PRESSE (ARTICLES)
// ═══════════════════════════════════════════════════════════════
const CATEGORIES = [
  { id: 'all', label: 'Toutes', icon: 'fa-solid fa-newspaper' },
  { id: 'geopolitics', label: 'Géopolitique', icon: 'fa-solid fa-globe' },
  { id: 'elections', label: 'Élections', icon: 'fa-solid fa-vote-yea' },
  { id: 'environment', label: 'Environnement', icon: 'fa-solid fa-leaf' },
  { id: 'tech', label: 'Tech', icon: 'fa-solid fa-microchip' },
  { id: 'finance', label: 'Finance', icon: 'fa-solid fa-chart-line' },
];
let presseCategory = 'all';

async function renderPresse() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const [articles, stats] = await Promise.all([
      api('/api/articles?limit=60&days=5'),
      api('/api/articles/stats'),
    ]);
    const filtered = presseCategory === 'all' ? articles : articles.filter(a => a.category === presseCategory);
    el.innerHTML =
      '<div style="display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap">' +
        CATEGORIES.map(c =>
          '<button class="btn ' + (presseCategory === c.id ? 'btn-primary' : 'btn-secondary') + ' btn-sm" onclick="presseCategory=\'' + c.id + '\';renderPresse()"><i class="' + c.icon + '"></i> ' + c.label + '</button>'
        ).join('') +
      '</div>' +
      '<div class="section-title"><i class="fa-solid fa-newspaper"></i> Articles (' + filtered.length + ')</div>' +
      '<div class="project-grid" style="grid-template-columns:1fr">' +
        filtered.map(a => {
          const cat = CATEGORIES.find(c => c.id === a.category) || { icon: 'fa-solid fa-newspaper', label: a.category };
          const flag = a.lang === 'fr' ? '🇫🇷' : '🇬🇧';
          return '<div class="project-card" style="padding:14px;cursor:pointer" onclick="window.open(\'' + esc(a.url) + '\',\'_blank\')">' +
            '<div style="display:flex;align-items:flex-start;gap:10px">' +
              '<span style="font-size:1.1rem;width:28px;text-align:center"><i class="' + cat.icon + '"></i></span>' +
              '<div style="flex:1;min-width:0">' +
                '<div style="font-size:.86rem;font-weight:600;margin-bottom:3px">' +
                  '<a href="' + esc(a.url) + '" target="_blank" style="color:var(--text);text-decoration:none" onmouseover="this.style.color=\'var(--accent2)\'" onmouseout="this.style.color=\'var(--text)\'">' + esc(a.title) + '</a>' +
                '</div>' +
                (a.summary ? '<div style="font-size:.78rem;color:var(--text2);margin-bottom:4px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">' + esc(a.summary) + '</div>' : '') +
                '<div style="font-size:.72rem;color:var(--text3);display:flex;gap:8px;flex-wrap:wrap">' +
                  '<span>' + flag + ' ' + esc(a.source) + '</span>' +
                  '<span><i class="fa-solid fa-calendar"></i> ' + (a.published || '').slice(0,10) + '</span>' +
                  (a.author ? '<span><i class="fa-solid fa-user-pen"></i> ' + esc(a.author) + '</span>' : '') +
                '</div>' +
              '</div>' +
            '</div>' +
          '</div>';
        }).join('') +
        (filtered.length === 0 ? '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-newspaper"></i></div><h3>Aucun article</h3><p>Les articles apparaîtront après la prochaine agrégation</p></div>' : '') +
      '</div>';
  } catch(e) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p></div>';
  }
}

// ═══════════════════════════════════════════════════════════════
// SONDAGES (PRÉSIDENTIELLE 2027)
// ═══════════════════════════════════════════════════════════════
let sondageInstituteFilter = 'all';
let sondageChart = null;

async function renderSondages() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const [polls, institutes, summary] = await Promise.all([
      api('/api/polls?limit=100'),
      api('/api/polls/institutes'),
      api('/api/summary'),
    ]);

    const institutesById = {};
    institutes.forEach(i => { institutesById[i.id] = i; });

    // Filter by institute
    const filtered = sondageInstituteFilter === 'all'
      ? polls
      : polls.filter(p => p.institute_id === sondageInstituteFilter);

    // Build institute filter buttons
    const buttons = institutes.map(i =>
      '<button class="btn ' + (sondageInstituteFilter === i.id ? 'btn-primary' : 'btn-secondary') + ' btn-sm" onclick="sondageInstituteFilter=' + i.id + ';renderSondages()"><i class="fa-solid fa-building"></i> ' + esc(i.short_name || i.name) + '</button>'
    ).join('');

    // Build HTML
    let html =
      '<div style="display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap;align-items:center">' +
        '<button class="btn ' + (sondageInstituteFilter === 'all' ? 'btn-primary' : 'btn-secondary') + ' btn-sm" onclick="sondageInstituteFilter=\'all\';renderSondages()"><i class="fa-solid fa-newspaper"></i> Tous</button>' +
        buttons +
        '<span style="flex:1"></span>' +
        '<button class="btn btn-secondary btn-sm" onclick="scrapePolls()"><i class="fa-solid fa-cloud-arrow-down"></i> Scraper</button>' +
      '</div>' +
      '<div class="section-title"><i class="fa-solid fa-chart-bar"></i> Intentions de vote (' + filtered.length + ' sondages)</div>' +
      // Chart
      '<div class="card" style="margin-bottom:16px;padding:16px">' +
        '<canvas id="pollsChart" height="200"></canvas>' +
      '</div>' +
      // Polls list
      '<div class="project-grid" style="grid-template-columns:1fr">';

    // Group polls by date for chart
    const chartData = buildChartData(filtered);

    // Render each poll
    for (const p of filtered) {
      const inst = institutesById[p.institute_id] || {};
      const results = p.results || [];
      results.sort((a, b) => (a.position || 999) - (b.position || 999));

      html +=
        '<div class="project-card" style="padding:14px">' +
          '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">' +
            '<span class="badge badge-' + (inst.short_name || 'info') + '" style="background:var(--accent2);color:#fff;padding:2px 8px;border-radius:4px;font-size:.75rem">' + esc(inst.short_name || p.institute_name || '?') + '</span>' +
            '<span style="font-size:.85rem;font-weight:600">' + p.date + '</span>' +
            (p.sample_size ? '<span style="font-size:.75rem;color:var(--text3)">(' + p.sample_size + ' pers.)</span>' : '') +
            '<span style="flex:1"></span>' +
            '<span style="font-size:.72rem;color:var(--text3)"><i class="fa-solid fa-users"></i> ' + results.length + ' candidats</span>' +
          '</div>';

      // Results table
      if (results.length > 0) {
        html += '<table style="width:100%;font-size:.82rem;border-collapse:collapse">' +
          '<thead><tr style="border-bottom:1px solid var(--border)">' +
            '<th style="padding:4px 6px;text-align:left;color:var(--text2)">#</th>' +
            '<th style="padding:4px 6px;text-align:left;color:var(--text2)">Candidat</th>' +
            '<th style="padding:4px 6px;text-align:right;color:var(--text2)">%</th>' +
            '<th style="padding:4px 6px;width:120px"></th>' +
          '</tr></thead><tbody>';

        const maxPct = Math.max(...results.map(r => r.percentage), 1);
        for (const r of results) {
          const pctWidth = (r.percentage / maxPct) * 100;
          html += '<tr style="border-bottom:1px solid var(--border-light)">' +
            '<td style="padding:3px 6px;color:var(--text3);width:24px">' + (r.position || '-') + '</td>' +
            '<td style="padding:3px 6px;font-weight:500">' + esc(r.candidate_name) + '</td>' +
            '<td style="padding:3px 6px;text-align:right;font-weight:600;color:var(--accent2)">' + r.percentage.toFixed(1) + '%</td>' +
            '<td style="padding:3px 6px"><div style="height:6px;background:var(--bg2);border-radius:3px;overflow:hidden"><div style="height:100%;width:' + pctWidth + '%;background:var(--accent2);border-radius:3px;transition:width .3s"></div></div></td>' +
          '</tr>';
        }
        html += '</tbody></table>';
      }

      if (p.source_url) {
        html += '<div style="margin-top:6px;font-size:.72rem"><a href="' + esc(p.source_url) + '" target="_blank" style="color:var(--text3)"><i class="fa-solid fa-link"></i> Source</a></div>';
      }
      html += '</div>';
    }

    html +=
      (filtered.length === 0 ? '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-chart-bar"></i></div><h3>Aucun sondage</h3><p>Utilisez le bouton "Scraper" pour collecter les derniers sondages</p></div>' : '') +
      '</div>';

    el.innerHTML = html;

    // Render chart
    if (chartData.labels.length > 0) {
      renderPollsChart(chartData);
    }
  } catch(e) {
    el.innerHTML = '<div class="empty-state"><div class="empty-icon"><i class="fa-solid fa-triangle-exclamation"></i></div><h3>Erreur</h3><p>' + esc(e.message) + '</p></div>';
  }
}

function buildChartData(polls) {
  // Group by candidate across polls
  const candidateTrends = {};
  const dates = [];

  // Sort polls by date
  const sorted = [...polls].sort((a, b) => a.date.localeCompare(b.date));

  for (const p of sorted) {
    const dateKey = p.date.slice(0, 10);
    if (!dates.includes(dateKey)) dates.push(dateKey);
    const results = p.results || [];
    for (const r of results) {
      if (!candidateTrends[r.candidate_name]) candidateTrends[r.candidate_name] = {};
      candidateTrends[r.candidate_name][dateKey] = r.percentage;
    }
  }

  // Take top candidates (5 max)
  const candidates = Object.keys(candidateTrends)
    .map(c => ({ name: c, maxPct: Math.max(...Object.values(candidateTrends[c]), 0) }))
    .sort((a, b) => b.maxPct - a.maxPct)
    .slice(0, 5)
    .map(c => c.name);

  const colors = ['#6366f1', '#ef4444', '#22c55e', '#f59e0b', '#ec4899', '#06b6d4', '#a855f7'];

  const datasets = candidates.map((c, i) => ({
    label: c,
    data: dates.map(d => candidateTrends[c][d] || null),
    borderColor: colors[i % colors.length],
    backgroundColor: colors[i % colors.length] + '22',
    borderWidth: 2,
    pointRadius: 3,
    tension: 0.3,
    spanGaps: true,
  }));

  return { labels: dates, datasets };
}

function renderPollsChart(chartData) {
  const ctx = document.getElementById('pollsChart');
  if (!ctx) return;
  if (sondageChart) { sondageChart.destroy(); }

  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
  const textColor = isDark ? '#a0aec0' : '#64748b';
  const gridColor = isDark ? '#2d3748' : '#e2e8f0';

  sondageChart = new Chart(ctx, {
    type: 'line',
    data: { labels: chartData.labels, datasets: chartData.datasets },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: { position: 'top', labels: { color: textColor, font: { size: 11 } } },
        tooltip: { mode: 'index', intersect: false }
      },
      scales: {
        x: { ticks: { color: textColor, font: { size: 10 } }, grid: { color: gridColor } },
        y: { ticks: { color: textColor, font: { size: 10 }, callback: v => v + '%' }, grid: { color: gridColor }, min: 0 }
      }
    }
  });
}

async function scrapePolls() {
  const el = document.getElementById('contentArea');
  el.innerHTML += '<div id="scrapeStatus" style="position:fixed;bottom:20px;right:20px;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:10px 16px;z-index:999;box-shadow:0 4px 12px rgba(0,0,0,.2);font-size:.85rem">🔄 Scraping en cours...</div>';
  try {
    const res = await api('/api/polls/scrape', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Scraper-Key': 'dashboard_scraper_2027_key' },
      body: JSON.stringify({ dry_run: false, days: 30 }),
    });
    const status = document.getElementById('scrapeStatus');
    if (res && res.ok) {
      status.innerHTML = '✅ Scraping terminé ! <span style="font-size:.72rem">Rafraîchissez la page</span>';
      status.style.borderColor = '#22c55e';
    } else {
      status.innerHTML = '❌ Erreur: ' + (res?.error || 'Inconnue');
      status.style.borderColor = '#ef4444';
    }
    setTimeout(() => { const s = document.getElementById('scrapeStatus'); if (s) s.remove(); }, 5000);
  } catch(e) {
    const status = document.getElementById('scrapeStatus');
    if (status) { status.innerHTML = '❌ ' + esc(e.message); status.style.borderColor = '#ef4444'; }
    setTimeout(() => { const s = document.getElementById('scrapeStatus'); if (s) s.remove(); }, 5000);
  }
  // Refresh polls
  setTimeout(() => renderSondages(), 3000);
}

// ═══════════════════════════════════════════════════════════════
// MEMOIRE — RAG (Mémoire vectorielle)
// ═══════════════════════════════════════════════════════════════

async function renderMemoire() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const stats = await api('/api/rag/stats');
    let html = `
    <div style="padding:20px;max-width:1100px;margin:0 auto">
      <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:20px">
        <div class="stat-card"><div class="stat-value">${stats.chunks}</div><div class="stat-label">Chunks indexés</div></div>
        <div class="stat-card"><div class="stat-value">${stats.documents}</div><div class="stat-label">Documents</div></div>
        <div class="stat-card"><div class="stat-value" style="font-size:.85rem">${stats.model}</div><div class="stat-label">Modèle embedding</div></div>
      </div>

      <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px">
        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:12px"><i class="fa-solid fa-search"></i> Recherche sémantique</h3>
          <div style="display:flex;gap:8px;margin-bottom:10px">
            <input type="text" id="ragQuery" placeholder="Rechercher dans les documents..." style="flex:1;padding:10px 14px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);font-size:.9rem">
            <button onclick="doRagSearch()" class="btn-primary" style="padding:10px 18px"><i class="fa-solid fa-search"></i></button>
          </div>
          <div id="ragQueryResults"></div>
          <button onclick="doRagSearch()" class="btn-secondary" style="width:100%;margin-top:8px">Rechercher</button>
        </div>

        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:12px"><i class="fa-solid fa-robot"></i> Question au LLM + RAG</h3>
          <div style="display:flex;gap:8px;margin-bottom:10px">
            <input type="text" id="ragQuestion" placeholder="Pose une question sur tes documents..." style="flex:1;padding:10px 14px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);font-size:.9rem">
            <button onclick="doRagAnswer()" class="btn-primary" style="padding:10px 18px"><i class="fa-solid fa-paper-plane"></i></button>
          </div>
          <div id="ragAnswerResult"></div>
        </div>
      </div>

      <div id="ragResultsDetail" style="display:none"></div>
    </div>`;
    el.innerHTML = html;
    // Enter key listeners
    document.getElementById('ragQuery').addEventListener('keydown', e => { if (e.key === 'Enter') doRagSearch(); });
    document.getElementById('ragQuestion').addEventListener('keydown', e => { if (e.key === 'Enter') doRagAnswer(); });
  } catch(e) {
    el.innerHTML = '<div class="card" style="padding:40px;text-align:center;color:var(--red)"><i class="fa-solid fa-triangle-exclamation" style="font-size:2rem;margin-bottom:12px"></i><p>Erreur RAG : ' + esc(e.message) + '</p></div>';
  }
}

async function doRagSearch() {
  const q = document.getElementById('ragQuery').value.trim();
  const resultsEl = document.getElementById('ragQueryResults');
  const detailEl = document.getElementById('ragResultsDetail');
  if (!q) { resultsEl.innerHTML = '<p style="color:var(--text3);font-size:.85rem">Entrez un terme de recherche</p>'; return; }
  resultsEl.innerHTML = '<div class="spinner" style="margin:20px auto"></div>';
  try {
    const data = await api('/api/rag/query', { method: 'POST', body: { query: q, n_results: 8 } });
    if (!data.ok || !data.results.length) {
      resultsEl.innerHTML = '<p style="color:var(--text3);font-size:.85rem">Aucun résultat</p>';
      detailEl.style.display = 'none';
      return;
    }
    resultsEl.innerHTML = '<p style="font-size:.8rem;color:var(--text3);margin-bottom:8px">' + data.results.length + ' résultat(s)</p>';
    let r = data.results.map((h, i) =>
      '<div class="result-item" style="padding:10px;margin-bottom:6px;border-radius:8px;background:var(--surface);border:1px solid var(--border);font-size:.85rem;cursor:pointer" onclick="toggleRagDetail(' + i + ')">' +
        '<div style="display:flex;justify-content:space-between;align-items:center">' +
          '<strong>' + esc(h.metadata.title) + '</strong>' +
          '<span class="badge" style="background:var(--accent);padding:2px 8px;border-radius:20px;font-size:.7rem">' + (h.score * 100).toFixed(0) + '%</span>' +
        '</div>' +
        '<div style="color:var(--text2);margin-top:4px;font-size:.8rem">' + esc(h.text.substring(0, 150)) + '…</div>' +
      '</div>'
    ).join('');
    resultsEl.innerHTML += r;

    // Detail panel
    detailEl.style.display = 'block';
    detailEl.innerHTML = '<h3 style="margin-bottom:10px">Détails des résultats</h3>' +
      data.results.map((h, i) =>
        '<div id="ragDetail_' + i + '" style="display:none;padding:14px;margin-bottom:8px;border-radius:8px;background:var(--bg2);border:1px solid var(--border)">' +
          '<div style="display:flex;justify-content:space-between;margin-bottom:6px">' +
            '<strong>' + esc(h.metadata.title) + '</strong>' +
            '<span style="color:var(--text3);font-size:.8rem">doc #' + h.metadata.doc_id + ' · ' + esc(h.metadata.category) + '</span>' +
          '</div>' +
          '<pre style="white-space:pre-wrap;font-family:var(--font);font-size:.82rem;color:var(--text2);line-height:1.5">' + esc(h.text) + '</pre>' +
        '</div>'
      ).join('');
  } catch(e) {
    resultsEl.innerHTML = '<p style="color:var(--red);font-size:.85rem">Erreur : ' + esc(e.message) + '</p>';
  }
}

let ragAnswerInProgress = false;

async function doRagAnswer() {
  if (ragAnswerInProgress) return;
  const q = document.getElementById('ragQuestion').value.trim();
  const resultEl = document.getElementById('ragAnswerResult');
  if (!q) { resultEl.innerHTML = '<p style="color:var(--text3);font-size:.85rem">Pose une question</p>'; return; }
  ragAnswerInProgress = true;
  resultEl.innerHTML = '<div class="spinner" style="margin:20px auto"></div><p style="text-align:center;color:var(--text3);font-size:.85rem">Consultation du LLM local…</p>';
  try {
    const data = await api('/api/rag/answer', { method: 'POST', body: { question: q, n_results: 5 }, timeout: 120000 });
    if (!data.ok) {
      resultEl.innerHTML = '<p style="color:var(--red)">Erreur : ' + esc(data.error) + '</p>';
      ragAnswerInProgress = false;
      return;
    }
    resultEl.innerHTML =
      '<div class="answer-card" style="padding:16px;border-radius:10px;background:var(--surface);border:1px solid var(--accent);margin-bottom:10px">' +
        '<div style="font-size:.9rem;line-height:1.6;color:var(--text)">' + esc(data.answer) + '</div>' +
      '</div>' +
      '<div style="font-size:.8rem;color:var(--text3)">Sources : ' +
        data.sources.map(s => '<span class="badge" style="background:var(--bg3);padding:2px 8px;margin:2px;border-radius:20px;font-size:.75rem" title="Score: ' + (s.score * 100).toFixed(0) + '%">' + esc(s.title) + '</span>').join('') +
      '</div>' +
      '<button onclick="document.getElementById(\'ragQuestion\').value=\'\';document.getElementById(\'ragAnswerResult\').innerHTML=\'\'" class="btn-link" style="margin-top:10px;font-size:.8rem"><i class="fa-solid fa-eraser"></i> Nouvelle question</button>';
  } catch(e) {
    resultEl.innerHTML = '<p style="color:var(--red);font-size:.85rem">Erreur : ' + esc(e.message) + '</p>';
  }
  ragAnswerInProgress = false;
}

function toggleRagDetail(i) {
  const el = document.getElementById('ragDetail_' + i);
  if (el) el.style.display = el.style.display === 'none' ? 'block' : 'none';
}

// ═══════════════════════════════════════════════════════════════
// PAPERCLIP — BUSINESS OS
// ═══════════════════════════════════════════════════════════════
async function renderPaperclip() {
  const el = document.getElementById('contentArea');
  el.innerHTML = '<div style="text-align:center;padding:40px;color:var(--text3)"><div class="spinner"></div></div>';
  try {
    const [teamsResp, membersResp, missionsResp, profilesResp] = await Promise.all([
      api('/api/paperclip/teams'),
      api('/api/paperclip/members'),
      api('/api/paperclip/missions'),
      api('/api/profiles')
    ]);
    const teams = teamsResp.teams || [];
    const members = membersResp.members || [];
    const missions = missionsResp.missions || [];
    const profiles = profilesResp.profiles || [];
    allProfiles = profiles; // Store globally for modals

    let html = `
    <div style="padding:20px;max-width:1400px;margin:0 auto">
      <!-- Stats Cards -->
      <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:20px">
        <div class="stat-card">
          <div class="stat-value">${teams.length}</div>
          <div class="stat-label"><i class="fa-solid fa-users"></i> Équipes</div>
        </div>
        <div class="stat-card">
          <div class="stat-value">${members.length}</div>
          <div class="stat-label"><i class="fa-solid fa-user"></i> Membres</div>
        </div>
        <div class="stat-card">
          <div class="stat-value">${missions.length}</div>
          <div class="stat-label"><i class="fa-solid fa-clipboard-list"></i> Missions</div>
        </div>
        <div class="stat-card">
          <div class="stat-value">${missions.filter(m => m.status === 'active').length}</div>
          <div class="stat-label"><i class="fa-solid fa-fire"></i> Actives</div>
        </div>
      </div>

      <!-- Sync Button Row -->
      <div style="margin-bottom:20px;display:flex;justify-content:flex-end">
        <button onclick="syncFromITOrg()" class="btn-primary" style="padding:10px 20px">
          <i class="fa-solid fa-sync"></i> Synchroniser depuis IT_ORG_DATA.json
        </button>
      </div>

      <!-- Create Forms Row -->
      <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px">
        <!-- Create Team Form -->
        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:16px"><i class="fa-solid fa-users"></i> Créer une équipe</h3>
          <div style="display:flex;flex-direction:column;gap:10px">
            <input type="text" id="newTeamName" placeholder="Nom de l'équipe" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
            <textarea id="newTeamDescription" placeholder="Description" rows="3" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);resize:vertical"></textarea>
            <div style="display:flex;gap:8px;align-items:center">
              <label style="color:var(--text2);font-size:.9rem">Couleur:</label>
              <input type="color" id="newTeamColor" value="#6366f1" style="width:50px;height:35px;border:none;border-radius:6px;cursor:pointer">
              <button onclick="createTeam()" class="btn-primary" style="margin-left:auto;padding:10px 20px"><i class="fa-solid fa-plus"></i> Créer</button>
            </div>
          </div>
        </div>

        <!-- Create Mission Form -->
        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:16px"><i class="fa-solid fa-clipboard-list"></i> Créer une mission</h3>
          <div style="display:flex;flex-direction:column;gap:10px">
            <input type="text" id="newMissionTitle" placeholder="Titre de la mission" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
            <textarea id="newMissionBrief" placeholder="Brief / Description" rows="2" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);resize:vertical"></textarea>
            <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px">
              <select id="newMissionTeam" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
                <option value="">Sélectionner équipe</option>
                ${teams.map(t => '<option value="' + t.id + '">' + esc(t.name) + '</option>').join('')}
              </select>
              <select id="newMissionPriority" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
                <option value="low">Basse</option>
                <option value="medium" selected>Moyenne</option>
                <option value="high">Haute</option>
                <option value="critical">Critique</option>
              </select>
              <input type="date" id="newMissionDeadline" style="padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
            </div>
            <button onclick="createMission()" class="btn-primary" style="padding:10px 20px"><i class="fa-solid fa-plus"></i> Créer mission</button>
          </div>
        </div>
      </div>

      <!-- Teams & Missions Row -->
      <div style="display:grid;grid-template-columns:1fr 2fr;gap:16px;margin-bottom:20px">
        <!-- Teams List -->
        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:16px"><i class="fa-solid fa-users"></i> Équipes</h3>
          <div id="teamsList">
            ${teams.length === 0 ? '<p style="color:var(--text3);font-size:.9rem;text-align:center;padding:20px">Aucune équipe</p>' : 
              teams.map(t => `
                <div class="team-item" style="padding:12px;margin-bottom:10px;border-radius:8px;background:var(--surface);border:1px solid var(--border);">
                  <div style="display:flex;align-items:center;gap:10px">
                    <span style="width:12px;height:12px;border-radius:50%;background:${t.color}"></span>
                    <div style="flex:1;cursor:pointer" onclick="filterMissionsByTeam(${t.id})">
                      <div style="font-weight:600;color:var(--text)">${esc(t.name)}</div>
                      <div style="font-size:.8rem;color:var(--text3)">${esc(t.description || '')}</div>
                    </div>
                    <button onclick="editTeam(${t.id})" class="btn-link" style="color:var(--accent2);padding:6px" title="Modifier"><i class="fa-solid fa-edit"></i></button>
                    <button onclick="deleteTeam(${t.id})" class="btn-link" style="color:var(--red);padding:6px" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
                  </div>
                </div>
              `).join('')
            }
          </div>
        </div>

        <!-- Missions List -->
        <div class="card" style="padding:20px">
          <h3 style="margin-bottom:16px"><i class="fa-solid fa-clipboard-list"></i> Missions</h3>
          <div id="missionsList">
            ${missions.length === 0 ? '<p style="color:var(--text3);font-size:.9rem;text-align:center;padding:20px">Aucune mission</p>' :
              missions.map(m => {
                const team = teams.find(t => t.id === m.team_id);
                const priorityColors = {low: '#10b981', medium: '#3b82f6', high: '#f59e0b', critical: '#ef4444'};
                const statusBadge = m.status === 'active' ? 'badge-active' : m.status === 'completed' ? 'badge-draft' : 'badge';
                return `
                  <div class="mission-item" style="padding:14px;margin-bottom:10px;border-radius:8px;background:var(--surface);border:1px solid var(--border);cursor:pointer" onclick="showMissionDetail(${m.id})">
                    <div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:8px">
                      <div style="flex:1">
                        <div style="font-weight:600;color:var(--text);margin-bottom:4px">${esc(m.title)}</div>
                        <div style="font-size:.85rem;color:var(--text2);line-height:1.4">${esc((m.brief || '').substring(0, 120))}${(m.brief || '').length > 120 ? '…' : ''}</div>
                      </div>
                      <button onclick="event.stopPropagation();deleteMission(${m.id})" class="btn-link" style="color:var(--red);padding:6px" title="Supprimer"><i class="fa-solid fa-trash"></i></button>
                    </div>
                    <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
                      <span class="${statusBadge}" style="font-size:.75rem">${m.status}</span>
                      <span class="badge" style="background:${priorityColors[m.priority]};font-size:.75rem">${m.priority}</span>
                      ${team ? '<span class="badge" style="background:' + team.color + ';font-size:.75rem">' + esc(team.name) + '</span>' : ''}
                      ${m.deadline ? '<span style="font-size:.75rem;color:var(--text3)"><i class="fa-solid fa-calendar"></i> ' + m.deadline + '</span>' : ''}
                    </div>
                  </div>
                `;
              }).join('')
            }
          </div>
        </div>
      </div>

      <!-- Members Section -->
      <div class="card" style="padding:20px;margin-bottom:20px">
        <h3 style="margin-bottom:16px"><i class="fa-solid fa-user"></i> Membres</h3>
        
        <!-- Add Member Form -->
        <div style="display:flex;gap:8px;margin-bottom:16px;padding:12px;background:var(--bg2);border-radius:8px">
          <input type="text" id="newMemberName" placeholder="Nom complet" style="flex:1;padding:8px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text)">
          <input type="text" id="newMemberRole" placeholder="Rôle" style="flex:1;padding:8px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text)">
          <select id="newMemberTeam" style="flex:1;padding:8px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text)">
            <option value="">Équipe</option>
            ${teams.map(t => '<option value="' + t.id + '">' + esc(t.name) + '</option>').join('')}
          </select>
          <input type="text" id="newMemberSkills" placeholder="Compétences (séparées par virgule)" style="flex:2;padding:8px;border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--text)">
          <button onclick="createMember()" class="btn-primary" style="padding:8px 16px"><i class="fa-solid fa-plus"></i></button>
        </div>

        <!-- Members Table -->
        <div style="overflow-x:auto">
          ${members.length === 0 ? '<p style="color:var(--text3);font-size:.9rem;text-align:center;padding:20px">Aucun membre</p>' :
            '<table style="width:100%;border-collapse:collapse">' +
              '<thead><tr style="border-bottom:2px solid var(--border)">' +
                '<th style="text-align:left;padding:10px;color:var(--text2);font-size:.85rem">Nom</th>' +
                '<th style="text-align:left;padding:10px;color:var(--text2);font-size:.85rem">Rôle</th>' +
                '<th style="text-align:left;padding:10px;color:var(--text2);font-size:.85rem">Équipe</th>' +
                '<th style="text-align:left;padding:10px;color:var(--text2);font-size:.85rem">Compétences</th>' +
                '<th style="text-align:center;padding:10px;color:var(--text2);font-size:.85rem">Action</th>' +
              '</tr></thead>' +
              '<tbody>' +
                members.map(m => {
                  const team = teams.find(t => t.id === m.team_id);
                  return '<tr style="border-bottom:1px solid var(--border)">' +
                    '<td style="padding:10px;color:var(--text);font-weight:500">' + esc(m.name) + '</td>' +
                    '<td style="padding:10px;color:var(--text2)">' + esc(m.role || '-') + '</td>' +
                    '<td style="padding:10px">' + (team ? '<span class="badge" style="background:' + team.color + ';font-size:.75rem">' + esc(team.name) + '</span>' : '-') + '</td>' +
                    '<td style="padding:10px;color:var(--text3);font-size:.85rem">' + esc((m.skills || []).join(', ') || '-') + '</td>' +
                    '<td style="padding:10px;text-align:center">' +
                      '<button onclick="editMember(' + m.id + ')" class="btn-link" style="color:var(--accent2);margin-right:6px" title="Modifier"><i class="fa-solid fa-edit"></i></button>' +
                      '<button onclick="deleteMember(' + m.id + ')" class="btn-link" style="color:var(--red)" title="Supprimer"><i class="fa-solid fa-trash"></i></button>' +
                    '</td>' +
                  '</tr>';
                }).join('') +
              '</tbody>' +
            '</table>'
          }
        </div>
      </div>

      <!-- Profiles LLM Section -->
      <div class="card" style="padding:20px;margin-bottom:20px">
        <h3 style="margin-bottom:16px"><i class="fa-solid fa-robot"></i> Profiles LLM</h3>
        
        <button onclick="openProfileModal()" class="btn-primary" style="margin-bottom:16px">
          <i class="fa-solid fa-plus"></i> Nouveau Profile
        </button>
        
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:12px">
          ${profiles.length === 0 ? 
            '<p style="color:var(--text3);font-size:.9rem;text-align:center;padding:20px;grid-column:1/-1">Aucun profile</p>' :
            profiles.map(p => `
              <div class="card" style="padding:16px;background:var(--surface);border:1px solid var(--border);position:relative">
                ${p.is_default === 1 ? '<span class="badge" style="position:absolute;top:8px;right:8px;background:var(--primary);color:white">Défaut</span>' : ''}
                ${p.provider === 'external' ? '<span class="badge" style="position:absolute;top:8px;right:${p.is_default === 1 ? 70 : 8}px;background:var(--orange);color:white">🌐 Externe</span>' : ''}
                <div style="margin-bottom:10px">
                  <div style="font-weight:600;color:var(--text);font-size:1.05rem;margin-bottom:4px">
                    ${esc(p.name)}
                  </div>
                  <div style="font-size:.85rem;color:var(--text3)">
                    <i class="fa-solid fa-brain"></i> ${esc(p.llm_model)} 
                    <span style="margin-left:8px"><i class="fa-solid fa-server"></i> ${esc(p.provider)}</span>
                  </div>
                </div>
                
                <div style="font-size:.8rem;color:var(--text2);margin-bottom:10px;line-height:1.4">
                  <div><strong>Température:</strong> ${p.temperature}</div>
                  <div><strong>Max tokens:</strong> ${p.max_tokens}</div>
                  ${p.prompt_technique && p.prompt_technique !== 'standard' ? '<div><strong>Technique:</strong> ' + esc(p.prompt_technique) + '</div>' : ''}
                  ${p.response_format && p.response_format !== 'text' ? '<div><strong>Format:</strong> ' + esc(p.response_format) + '</div>' : ''}
                  ${p.system_prompt ? '<div style="margin-top:6px"><strong>Prompt système:</strong> ' + esc(p.system_prompt.substring(0, 80)) + (p.system_prompt.length > 80 ? '…' : '') + '</div>' : ''}
                </div>
                
                <div style="display:flex;gap:6px;flex-wrap:wrap">
                  <button onclick="editProfile(${p.id})" class="btn-link" style="padding:6px 10px;font-size:.8rem">
                    <i class="fa-solid fa-edit"></i> Modifier
                  </button>
                  ${p.is_default === 0 ? `
                    <button onclick="setDefaultProfile(${p.id})" class="btn-link" style="padding:6px 10px;font-size:.8rem">
                      <i class="fa-solid fa-star"></i> Défaut
                    </button>
                    <button onclick="deleteProfile(${p.id})" class="btn-link" style="color:var(--red);padding:6px 10px;font-size:.8rem">
                      <i class="fa-solid fa-trash"></i> Supprimer
                    </button>
                  ` : ''}
                </div>
              </div>
            `).join('')
          }
        </div>
      </div>

      <!-- Workflow Templates Section -->
      <div class="card" style="padding:20px">
        <h3 style="margin-bottom:16px"><i class="fa-solid fa-diagram-project"></i> Workflow Templates</h3>
        <p style="color:var(--text3);font-size:.9rem;margin-bottom:12px">Modèles de workflow pour automatiser vos processus métier.</p>
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px">
          <div class="workflow-template" style="padding:16px;border-radius:8px;background:var(--surface);border:1px solid var(--border)">
            <div style="font-weight:600;color:var(--text);margin-bottom:6px"><i class="fa-solid fa-rocket"></i> Lancement Projet</div>
            <div style="font-size:.85rem;color:var(--text2);margin-bottom:10px">Kickoff → Brief → Équipe → Milestones</div>
            <button class="btn-secondary" style="width:100%;padding:8px;font-size:.85rem">Utiliser</button>
          </div>
          <div class="workflow-template" style="padding:16px;border-radius:8px;background:var(--surface);border:1px solid var(--border)">
            <div style="font-weight:600;color:var(--text);margin-bottom:6px"><i class="fa-solid fa-code"></i> Sprint Dev</div>
            <div style="font-size:.85rem;color:var(--text2);margin-bottom:10px">Planning → Dev → Review → Deploy</div>
            <button class="btn-secondary" style="width:100%;padding:8px;font-size:.85rem">Utiliser</button>
          </div>
          <div class="workflow-template" style="padding:16px;border-radius:8px;background:var(--surface);border:1px solid var(--border)">
            <div style="font-weight:600;color:var(--text);margin-bottom:6px"><i class="fa-solid fa-bullhorn"></i> Campagne Marketing</div>
            <div style="font-size:.85rem;color:var(--text2);margin-bottom:10px">Stratégie → Création → Publication → Analyse</div>
            <button class="btn-secondary" style="width:100%;padding:8px;font-size:.85rem">Utiliser</button>
          </div>
          <div class="workflow-template" style="padding:16px;border-radius:8px;background:var(--surface);border:1px solid var(--border)">
            <div style="font-weight:600;color:var(--text);margin-bottom:6px"><i class="fa-solid fa-users-gear"></i> Onboarding</div>
            <div style="font-size:.85rem;color:var(--text2);margin-bottom:10px">Accueil → Formation → Intégration → Suivi</div>
            <button class="btn-secondary" style="width:100%;padding:8px;font-size:.85rem">Utiliser</button>
          </div>
        </div>
      </div>
    </div>`;
    
    el.innerHTML = html;
  } catch(e) {
    el.innerHTML = '<div class="card" style="padding:40px;text-align:center;color:var(--red)"><i class="fa-solid fa-triangle-exclamation" style="font-size:2rem;margin-bottom:12px"></i><p>Erreur Paperclip : ' + esc(e.message) + '</p></div>';
  }
}

async function createTeam() {
  const name = document.getElementById('newTeamName').value.trim();
  const description = document.getElementById('newTeamDescription').value.trim();
  const color = document.getElementById('newTeamColor').value;
  if (!name) {
    toast('Le nom de l\'équipe est requis', 'error');
    return;
  }
  try {
    await api('/api/paperclip/teams', {
      method: 'POST',
      body: { name, description, color }
    });
    toast('Équipe créée', 'success');
    document.getElementById('newTeamName').value = '';
    document.getElementById('newTeamDescription').value = '';
    document.getElementById('newTeamColor').value = '#6366f1';
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function deleteTeam(id) {
  if (!confirm('Supprimer cette équipe ?')) return;
  try {
    await api('/api/paperclip/teams/' + id, { method: 'DELETE' });
    toast('Équipe supprimée', 'success');
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function editTeam(id) {
  try {
    const [teamsResp, profilesResp] = await Promise.all([
      api('/api/paperclip/teams'),
      api('/api/profiles')
    ]);
    const teams = teamsResp.teams || [];
    const profiles = profilesResp.profiles || [];
    const team = teams.find(t => t.id === id);
    if (!team) {
      toast('Équipe introuvable', 'error');
      return;
    }

    const modal = document.createElement('div');
    modal.id = 'editTeamModal';
    modal.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;z-index:10000';
    modal.innerHTML = `
      <div class="card" style="max-width:500px;width:90%;padding:30px;position:relative">
        <button onclick="document.getElementById('editTeamModal').remove()" style="position:absolute;top:15px;right:15px;background:none;border:none;color:var(--text3);font-size:1.5rem;cursor:pointer;padding:5px">&times;</button>
        
        <h2 style="margin-bottom:20px;color:var(--text)"><i class="fa-solid fa-edit"></i> Modifier l'équipe</h2>
        
        <div style="display:flex;flex-direction:column;gap:14px">
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Nom</label>
            <input type="text" id="editTeamName" value="${esc(team.name)}" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
          
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Description</label>
            <textarea id="editTeamDescription" rows="3" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);resize:vertical">${esc(team.description || '')}</textarea>
          </div>
          
          <div style="display:flex;gap:12px;align-items:center">
            <div style="flex:1">
              <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Couleur</label>
              <input type="color" id="editTeamColor" value="${team.color}" style="width:100%;height:40px;border:none;border-radius:8px;cursor:pointer">
            </div>
            <div style="flex:1">
              <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Profil LLM</label>
              <select id="editTeamProfile" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
                <option value="">Aucun</option>
                ${profiles.map(p => '<option value="' + p.id + '"' + (p.id === team.profile_id ? ' selected' : '') + '>' + esc(p.name) + '</option>').join('')}
              </select>
            </div>
          </div>
        </div>
        
        <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:24px;padding-top:20px;border-top:1px solid var(--border)">
          <button onclick="document.getElementById('editTeamModal').remove()" class="btn-secondary">Annuler</button>
          <button onclick="saveTeamEdit(${id})" class="btn-primary"><i class="fa-solid fa-save"></i> Enregistrer</button>
        </div>
      </div>
    `;
    document.body.appendChild(modal);
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function saveTeamEdit(id) {
  const name = document.getElementById('editTeamName').value.trim();
  const description = document.getElementById('editTeamDescription').value.trim();
  const color = document.getElementById('editTeamColor').value;
  const profileVal = document.getElementById('editTeamProfile').value;
  const profile_id = profileVal ? parseInt(profileVal) : null;
  
  if (!name) {
    toast('Le nom est requis', 'error');
    return;
  }
  
  try {
    await api('/api/paperclip/teams/' + id, {
      method: 'PUT',
      body: { name, description, color, profile_id }
    });
    toast('Équipe mise à jour', 'success');
    document.getElementById('editTeamModal').remove();
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function createMission() {
  const title = document.getElementById('newMissionTitle').value.trim();
  const brief = document.getElementById('newMissionBrief').value.trim();
  const team_id = document.getElementById('newMissionTeam').value;
  const priority = document.getElementById('newMissionPriority').value;
  const deadline = document.getElementById('newMissionDeadline').value;
  if (!title) {
    toast('Le titre de la mission est requis', 'error');
    return;
  }
  try {
    await api('/api/paperclip/missions', {
      method: 'POST',
      body: {
        title,
        brief,
        team_id: team_id ? parseInt(team_id) : null,
        priority,
        deadline: deadline || null,
        status: 'active'
      }
    });
    toast('Mission créée', 'success');
    document.getElementById('newMissionTitle').value = '';
    document.getElementById('newMissionBrief').value = '';
    document.getElementById('newMissionTeam').value = '';
    document.getElementById('newMissionPriority').value = 'medium';
    document.getElementById('newMissionDeadline').value = '';
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function deleteMission(id) {
  if (!confirm('Supprimer cette mission ?')) return;
  try {
    await api('/api/paperclip/missions/' + id, { method: 'DELETE' });
    toast('Mission supprimée', 'success');
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function createMember() {
  const name = document.getElementById('newMemberName').value.trim();
  const role = document.getElementById('newMemberRole').value.trim();
  const team_id = document.getElementById('newMemberTeam').value;
  const skillsInput = document.getElementById('newMemberSkills').value.trim();
  const skills = skillsInput ? skillsInput.split(',').map(s => s.trim()).filter(s => s) : [];
  if (!name) {
    toast('Le nom du membre est requis', 'error');
    return;
  }
  try {
    await api('/api/paperclip/members', {
      method: 'POST',
      body: {
        name,
        role,
        team_id: team_id ? parseInt(team_id) : null,
        skills
      }
    });
    toast('Membre ajouté', 'success');
    document.getElementById('newMemberName').value = '';
    document.getElementById('newMemberRole').value = '';
    document.getElementById('newMemberTeam').value = '';
    document.getElementById('newMemberSkills').value = '';
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function deleteMember(id) {
  if (!confirm('Supprimer ce membre ?')) return;
  try {
    await api('/api/paperclip/members/' + id, { method: 'DELETE' });
    toast('Membre supprimé', 'success');
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function editMember(id) {
  try {
    const [membersResp, teamsResp, profilesResp] = await Promise.all([
      api('/api/paperclip/members'),
      api('/api/paperclip/teams'),
      api('/api/profiles')
    ]);
    const members = membersResp.members || [];
    const teams = teamsResp.teams || [];
    const profiles = profilesResp.profiles || [];
    const member = members.find(m => m.id === id);
    if (!member) {
      toast('Membre introuvable', 'error');
      return;
    }

    const modal = document.createElement('div');
    modal.id = 'editMemberModal';
    modal.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;z-index:10000';
    modal.innerHTML = `
      <div class="card" style="max-width:500px;width:90%;padding:30px;position:relative">
        <button onclick="document.getElementById('editMemberModal').remove()" style="position:absolute;top:15px;right:15px;background:none;border:none;color:var(--text3);font-size:1.5rem;cursor:pointer;padding:5px">&times;</button>
        
        <h2 style="margin-bottom:20px;color:var(--text)"><i class="fa-solid fa-user-edit"></i> Modifier le membre</h2>
        
        <div style="display:flex;flex-direction:column;gap:14px">
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Nom</label>
            <input type="text" id="editMemberName" value="${esc(member.name)}" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
          
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Rôle</label>
            <input type="text" id="editMemberRole" value="${esc(member.role || '')}" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
          
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Email</label>
            <input type="email" id="editMemberEmail" value="${esc(member.email || '')}" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
          
          <div style="display:flex;gap:12px">
            <div style="flex:1">
              <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Équipe</label>
              <select id="editMemberTeam" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
                <option value="">Aucune équipe</option>
                ${teams.map(t => '<option value="' + t.id + '"' + (t.id === member.team_id ? ' selected' : '') + '>' + esc(t.name) + '</option>').join('')}
              </select>
            </div>
            <div style="flex:1">
              <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Profil LLM</label>
              <select id="editMemberProfile" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
                <option value="">Aucun</option>
                ${profiles.map(p => '<option value="' + p.id + '"' + (p.id === member.profile_id ? ' selected' : '') + '>' + esc(p.name) + '</option>').join('')}
              </select>
            </div>
          </div>
          
          <div>
            <label style="display:block;margin-bottom:6px;font-size:.9rem;color:var(--text2)">Compétences (séparées par virgule)</label>
            <input type="text" id="editMemberSkills" value="${esc((member.skills || []).join(', '))}" style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
        </div>
        
        <div style="display:flex;gap:10px;justify-content:flex-end;margin-top:24px;padding-top:20px;border-top:1px solid var(--border)">
          <button onclick="document.getElementById('editMemberModal').remove()" class="btn-secondary">Annuler</button>
          <button onclick="saveMemberEdit(${id})" class="btn-primary"><i class="fa-solid fa-save"></i> Enregistrer</button>
        </div>
      </div>
    `;
    document.body.appendChild(modal);
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function saveMemberEdit(id) {
  const name = document.getElementById('editMemberName').value.trim();
  const role = document.getElementById('editMemberRole').value.trim();
  const email = document.getElementById('editMemberEmail').value.trim();
  const teamVal = document.getElementById('editMemberTeam').value;
  const profileVal = document.getElementById('editMemberProfile').value;
  const skillsInput = document.getElementById('editMemberSkills').value.trim();
  
  const team_id = teamVal ? parseInt(teamVal) : null;
  const profile_id = profileVal ? parseInt(profileVal) : null;
  const skills = skillsInput ? skillsInput.split(',').map(s => s.trim()).filter(s => s) : [];
  
  if (!name) {
    toast('Le nom est requis', 'error');
    return;
  }
  
  try {
    await api('/api/paperclip/members/' + id, {
      method: 'PUT',
      body: { name, role, email, team_id, profile_id, skills }
    });
    toast('Membre mis à jour', 'success');
    document.getElementById('editMemberModal').remove();
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function syncFromITOrg() {
  if (!confirm('Synchroniser les équipes et membres depuis IT_ORG_DATA.json ? Ceci créera ou mettra à jour les données existantes.')) return;
  
  try {
    toast('Synchronisation en cours...', 'info');
    const result = await api('/api/paperclip/sync', { method: 'POST' });
    
    if (result.ok && result.stats) {
      const stats = result.stats;
      const msg = `Synchronisation réussie!\n` +
        `Équipes créées: ${stats.teams_created}, mises à jour: ${stats.teams_updated}\n` +
        `Membres créés: ${stats.members_created}, mis à jour: ${stats.members_updated}`;
      toast(msg, 'success');
      renderPaperclip();
    } else {
      toast('Erreur de synchronisation', 'error');
    }
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function showMissionDetail(id) {
  try {
    const mission = await api('/api/paperclip/missions/' + id);
    const [teamsResp, membersResp] = await Promise.all([
      api('/api/paperclip/teams'),
      api('/api/paperclip/members')
    ]);
    const teams = teamsResp.teams || [];
    const members = membersResp.members || [];
    const team = teams.find(t => t.id === mission.team_id);
    const teamMembers = members.filter(m => m.team_id === mission.team_id);
    
    const priorityColors = {low: '#10b981', medium: '#3b82f6', high: '#f59e0b', critical: '#ef4444'};
    const statusOptions = ['active', 'paused', 'completed', 'archived'];
    
    const modal = document.createElement('div');
    modal.id = 'missionDetailModal';
    modal.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;z-index:10000';
    modal.innerHTML = `
      <div class="card" style="max-width:700px;width:90%;max-height:90vh;overflow-y:auto;padding:30px;position:relative">
        <button onclick="document.getElementById('missionDetailModal').remove()" style="position:absolute;top:15px;right:15px;background:none;border:none;color:var(--text3);font-size:1.5rem;cursor:pointer;padding:5px">&times;</button>
        
        <h2 style="margin-bottom:20px;color:var(--text)"><i class="fa-solid fa-clipboard-list"></i> ${esc(mission.title)}</h2>
        
        <div style="margin-bottom:20px">
          <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px">
            <span class="badge" style="background:${priorityColors[mission.priority]}">${mission.priority}</span>
            <span class="badge ${mission.status === 'active' ? 'badge-active' : 'badge-draft'}">${mission.status}</span>
            ${team ? '<span class="badge" style="background:' + team.color + '">' + esc(team.name) + '</span>' : ''}
            ${mission.deadline ? '<span class="badge" style="background:var(--text3)"><i class="fa-solid fa-calendar"></i> ' + mission.deadline + '</span>' : ''}
          </div>
        </div>

        <div style="margin-bottom:20px">
          <h4 style="color:var(--text2);margin-bottom:8px">Brief</h4>
          <p style="color:var(--text);line-height:1.6">${esc(mission.brief || 'Pas de description')}</p>
        </div>

        ${teamMembers.length > 0 ? `
        <div style="margin-bottom:20px">
          <h4 style="color:var(--text2);margin-bottom:8px">Membres de l'équipe</h4>
          <div style="display:flex;flex-direction:column;gap:8px">
            ${teamMembers.map(m => 
              '<div style="padding:10px;background:var(--surface);border-radius:6px;display:flex;justify-content:space-between;align-items:center">' +
                '<div><strong style="color:var(--text)">' + esc(m.name) + '</strong><span style="color:var(--text3);font-size:.85rem;margin-left:8px">' + esc(m.role || '') + '</span></div>' +
                '<div style="font-size:.8rem;color:var(--text3)">' + esc((m.skills || []).join(', ') || '') + '</div>' +
              '</div>'
            ).join('')}
          </div>
        </div>
        ` : ''}

        <div style="margin-bottom:20px">
          <h4 style="color:var(--text2);margin-bottom:8px">Changer le statut</h4>
          <div style="display:flex;gap:8px;flex-wrap:wrap">
            ${statusOptions.map(status => 
              '<button onclick="toggleMissionStatus(' + mission.id + ', \'' + status + '\')" class="btn-secondary" style="padding:8px 16px;font-size:.85rem">' + status + '</button>'
            ).join('')}
          </div>
        </div>

        <div style="display:flex;gap:8px;justify-content:flex-end;padding-top:16px;border-top:1px solid var(--border)">
          <button onclick="document.getElementById('missionDetailModal').remove()" class="btn-secondary">Fermer</button>
          <button onclick="deleteMission(${mission.id});document.getElementById('missionDetailModal').remove()" class="btn-danger"><i class="fa-solid fa-trash"></i> Supprimer</button>
        </div>
      </div>
    `;
    document.body.appendChild(modal);
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

async function toggleMissionStatus(id, status) {
  try {
    await api('/api/paperclip/missions/' + id, {
      method: 'PUT',
      body: { status }
    });
    toast('Statut mis à jour', 'success');
    document.getElementById('missionDetailModal').remove();
    renderPaperclip();
  } catch(e) {
    toast('Erreur : ' + e.message, 'error');
  }
}

function filterMissionsByTeam(teamId) {
  toast('Filtrage par équipe #' + teamId + ' (fonctionnalité à implémenter)', 'info');
}

// ═══════════════════════════════════════════════════════════════
// LLM PROFILES
// ═══════════════════════════════════════════════════════════════

function openProfileModal(profileId = null) {
  const profile = profileId ? allProfiles.find(p => p.id === profileId) : null;
  const isEdit = !!profile;
  
  const modalContent = `
    <div style="padding:20px">
      <h2 style="margin-bottom:20px">${isEdit ? 'Modifier le Profile' : 'Nouveau Profile LLM'}</h2>
      
      <div style="display:flex;flex-direction:column;gap:12px">
        <div>
          <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Nom</label>
          <input type="text" id="profileModalName" value="${isEdit ? esc(profile.name) : ''}" 
                 placeholder="Ex: Assistant Marketing" 
                 style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
        </div>
        
        <div>
          <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Modèle LLM</label>
          <input type="text" id="profileModalModel" value="${isEdit ? esc(profile.llm_model) : 'qwen2.5-7b'}" 
                 placeholder="Ex: qwen2.5-7b, gpt-4" 
                 style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
        </div>
        
        <div>
          <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Fournisseur</label>
          <select id="profileModalProvider" 
                  style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
            <option value="local" ${isEdit && profile.provider === 'local' ? 'selected' : ''}>Local (LM Studio / Ollama)</option>
            <option value="openrouter" ${isEdit && profile.provider === 'openrouter' ? 'selected' : ''}>OpenRouter</option>
            <option value="openai" ${isEdit && profile.provider === 'openai' ? 'selected' : ''}>OpenAI</option>
            <option value="anthropic" ${isEdit && profile.provider === 'anthropic' ? 'selected' : ''}>Anthropic</option>
            <option value="external" ${isEdit && profile.provider === 'external' ? 'selected' : ''}>Externe (Agents)</option>
          </select>
        </div>
        
        <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">
          <div>
            <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Température (0-1)</label>
            <input type="number" id="profileModalTemp" value="${isEdit ? profile.temperature : 0.7}" 
                   min="0" max="1" step="0.1" 
                   style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
          <div>
            <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Max Tokens</label>
            <input type="number" id="profileModalTokens" value="${isEdit ? profile.max_tokens : 2048}" 
                   min="256" max="8192" step="256" 
                   style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
          </div>
        </div>
        
        <div>
          <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Technique de Prompt</label>
          <select id="profileModalTechnique" onchange="togglePromptFields()" 
                  style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text)">
            <option value="standard" ${isEdit && profile.prompt_technique === 'standard' ? 'selected' : ''}>Standard</option>
            <option value="cot" ${isEdit && profile.prompt_technique === 'cot' ? 'selected' : ''}>Chain-of-Thought (CoT)</option>
            <option value="loop" ${isEdit && profile.prompt_technique === 'loop' ? 'selected' : ''}>Loop (Itératif)</option>
            <option value="few_shot" ${isEdit && profile.prompt_technique === 'few_shot' ? 'selected' : ''}>Few-Shot</option>
            <option value="react" ${isEdit && profile.prompt_technique === 'react' ? 'selected' : ''}>ReAct</option>
          </select>
        </div>
        
        <div id="promptTemplateField" style="display:none">
          <label style="display:block;margin-bottom:4px;font-size:.9rem;color:var(--text2)">Template de Prompt (Jinja-like)</label>
          <textarea id="profileModalTemplate" rows="3" placeholder="Ex: {{task}} | Contexte: {{context}}" 
                    style="width:100%;padding:10px;border-radius:8px;border:1px solid var(--border);background:var(--bg2);color:var(--text);resize:vertical">${isEdit ? esc(profile.prompt_template || '') : ''}</textarea>
          <small style="color:var(--text3);font-size:.75rem">Variables: {{task}}, {{context}}, {{history}}</small>
        </div>
        
      </div>
    </div>
    <div style="display:flex;gap:8px;justify-content:flex-end;margin-top:16px">
      <button class="btn-secondary" onclick="closeModal()">Annuler</button>
      <button class="btn-primary" onclick="saveProfile()">Enregistrer</button>
    </div>
  </div>`;
  
  renderModal(modalContent);
}

// ═══════════════════════════════════════════════════════════════
// INIT
// ═══════════════════════════════════════════════════════════════
async function init() {
  // TEST: vérifier que le JS s'exécute
  const testEl = document.getElementById('contentArea');
  if (testEl) testEl.innerHTML = '<div style="padding:40px;text-align:center"><h2>JS chargé !</h2><p>Attendez...</p></div>';
  
  loadTheme();
  initNavGroups();
  
  try { await loadProjects(); } catch(e) { toast('Erreur chargement projets', 'error'); }
  renderDashboard();
  updateNavUI();
  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && navIndex > 0 && !document.querySelector('.modal-overlay.open')) goBack();
    if (e.key === 'Escape' && document.querySelector('.modal-overlay.open')) closeModal();
    if (e.key === 'h' && !e.ctrlKey && !e.metaKey && !e.altKey) {
      const active = document.activeElement;
      if (!active || (active.tagName !== 'INPUT' && active.tagName !== 'TEXTAREA')) goHome();
    }
    if (e.key === 'n' && !e.ctrlKey && !e.metaKey) {
      if (!document.querySelector('.modal-overlay.open')) openModal('project');
    }
  });
}

init();
</script>

</body>
</html>