'+(searchQuery?'Aucun r\u00e9sultat':'Aucun \u00e9v\u00e9nement cette semaine')+'
';
}
function fES(id){
var s=document.getElementById(id);var c=s.value;
s.innerHTML=''+D.emps.map(function(e){return '';}).join('');
if(c)s.value=c;
}
function openEM(){fES('ee');if(!document.getElementById('ed').value)document.getElementById('ed').value=fd(T);document.getElementById('eovl').classList.add('on');}
function closeEM(){document.getElementById('eovl').classList.remove('on');}
function saveEv(){
var t=document.getElementById('et').value.trim();if(!t)return;
D.events.push({id:D.nid++,title:t,type:document.getElementById('ety').value,date:document.getElementById('ed').value,time:document.getElementById('eh').value,emp:document.getElementById('ee').value});
document.getElementById('et').value='';sv();closeEM();
if(cTab==='cal')rCal();else if(cTab==='dash')rDash();else if(cTab==='rh')rRH();else if(cTab==='soumissions')rSoumissions();
}
function openTM(){fES('te2');document.getElementById('td').value=fd(ad(T,3));document.getElementById('tovl').classList.add('on');}
function closeTM(){document.getElementById('tovl').classList.remove('on');}
function saveTk(){
var t=document.getElementById('tt').value.trim();if(!t)return;
D.tasks.push({id:D.nid++,title:t,cat:document.getElementById('tc2').value,prio:document.getElementById('tp').value,emp:document.getElementById('te2').value,due:document.getElementById('td').value,done:false,subtasks:[],msgs:[]});
document.getElementById('tt').value='';sv();closeTM();rRythme();
}
function addEmp(){
var n=prompt('Nom complet :');if(!n||!n.trim())return;
var r=prompt('R\u00f4le / poste :');
D.emps.push({id:D.nid++,name:n.trim(),role:r||'',c:D.emps.length%ABG.length});
sv();rRH();
}
// ---- SOUMISSIONS ----
var soumStatLabel={envoyee:'Envoy\u00e9e',en_attente:'En attente',acceptee:'Accept\u00e9e \u2713',refusee:'Refus\u00e9e',expiree:'Expir\u00e9e'};
var soumStatClass={envoyee:'p-blu',en_attente:'p-amb',acceptee:'p-grn',refusee:'p-red2',expiree:'b-n'};
function rSoumissions(){
fES('sresp');
var grid=document.getElementById('soum-grid');
if(!D.soumissions||!D.soumissions.length){
grid.innerHTML='
Aucune soumission \u2014 cliquez + Soumission pour commencer.
';
return;
}
D.soumissions.sort(function(a,b){return a.num=0?ABG[D.emps[idx].c%ABG.length]:ABG[0];
var fg=idx>=0?AFG[D.emps[idx].c%AFG.length]:AFG[0];
var sc=soumStatClass[s.statut]||'b-n';
var sl=soumStatLabel[s.statut]||s.statut;
var montant=s.montant?Number(s.montant).toLocaleString('fr-CA',{style:'currency',currency:'CAD',maximumFractionDigits:0}):'';
return '
'+
'
'+
'
'+
'
'+esc(s.num)+'
'+
'
'+esc(s.nom)+'
'+
'
'+
''+sl+''+
'
'+
(s.type?'
'+esc(s.type)+'
':'')+
(montant?'
'+montant+'
':'')+
(s.notes?'
'+esc(s.notes)+'
':'')+
'
'+
(s.exp?'Exp. '+fds(s.exp)+'':'')+
'
'+
(s.resp?'
'+ini(s.resp)+'
'+esc(s.resp)+'
':'')+
'
';
}).join('');
}
function openSM(){
fES('sresp');
var d=new Date(T);d.setDate(d.getDate()+30);
document.getElementById('sexp').value=fd(d);
document.getElementById('sovl').classList.add('on');
}
function closeSM(){document.getElementById('sovl').classList.remove('on');}
function saveSoum(){
var num=document.getElementById('snum').value.trim();
var nom=document.getElementById('snom').value.trim();
if(!num||!nom)return;
if(!D.soumissions)D.soumissions=[];
D.soumissions.push({
id:D.nid++,num:num,nom:nom,
type:document.getElementById('stype').value,
montant:parseFloat(document.getElementById('smontant').value)||0,
statut:document.getElementById('sstat').value,
resp:document.getElementById('sresp').value,
exp:document.getElementById('sexp').value,
notes:document.getElementById('snotes').value.trim()
});
document.getElementById('snum').value='';
document.getElementById('snom').value='';
document.getElementById('smontant').value='';
document.getElementById('snotes').value='';
sv();closeSM();rSoumissions();
}
// ── RECHERCHE GLOBALE ─────────────────────────────────────────────────
var searchQuery = '';
function doSearch(q) {
searchQuery = q.trim().toLowerCase();
var clearBtn = document.getElementById('search-clear');
var countLbl = document.getElementById('search-count');
clearBtn.style.display = searchQuery ? 'inline-block' : 'none';
if(!searchQuery){ countLbl.textContent=''; }
// Rafraîchir l'onglet courant
refreshCurrent();
}
function clearSearch() {
document.getElementById('global-search').value = '';
searchQuery = '';
document.getElementById('search-clear').style.display='none';
document.getElementById('search-count').textContent='';
refreshCurrent();
}
function refreshCurrent() {
if(cTab==='dash')rDash();
else if(cTab==='cal')rCal();
else if(cTab==='rythme')rRythme();
else if(cTab==='commandes')rClient();
else if(cTab==='soumissions')rSoumissions();
else if(cTab==='rh')rRH();
}
function matchSearch(fields) {
if(!searchQuery) return true;
return fields.some(function(f){ return f&&String(f).toLowerCase().indexOf(searchQuery)>=0; });
}
function showCount(n, total) {
var lbl = document.getElementById('search-count');
if(searchQuery) lbl.textContent = n+' / '+total;
else lbl.textContent = '';
}
// doLogout géré par le nouveau système de connexion
// ── CONNEXION ────────────────────────────────────────────────────────────
var LYSTE_USERS = {
mario: 'lyste2026',
karine: 'lyste2026',
felix: 'lyste2026',
fanny: 'lyste2026',
megane: 'lyste2026',
karinep: 'lyste2026',
matiale: 'lyste2026',
benoit: 'lyste2026',
sonia: 'lyste2026'
};
var LYSTE_NOMS = {
mario:'Mario', karine:'Karine L.', felix:'F\u00e9lix',
fanny:'Fanny', megane:'M\u00e9gane', karinep:'Karine P.',
matiale:'Matiale', benoit:'Beno\u00eet', sonia:'Sonia'
};
var _lCurrentUser = null;
// V\u00e9rifier session existante
(function(){
try {
var s = localStorage.getItem('lyste_session');
if(s) {
var sess = JSON.parse(s);
if(sess && sess.expiry > Date.now()) {
_lCurrentUser = {username: sess.username, nom: sess.nom};
ouvrirApp(sess.nom);
}
}
} catch(e) {}
})();
function lLogin() {
var un = document.getElementById('lusername').value;
var pw = document.getElementById('lpassword').value;
var err = document.getElementById('lerr-login');
err.style.display = 'none';
if(!un) {
err.textContent = 'Veuillez s\u00e9lectionner votre nom.';
err.style.display = 'block';
return;
}
if(!pw) {
err.textContent = 'Veuillez entrer votre mot de passe.';
err.style.display = 'block';
return;
}
// V\u00e9rifier mot de passe (localStorage ou par d\u00e9faut)
var mdpSauve = localStorage.getItem('lyste_mp_' + un);
var mdpValide = mdpSauve || LYSTE_USERS[un];
if(!mdpValide || pw !== mdpValide) {
err.textContent = 'Mot de passe incorrect. Essayez lyste2026';
err.style.display = 'block';
document.getElementById('lpassword').value = '';
return;
}
// Connexion r\u00e9ussie
var nom = LYSTE_NOMS[un] || un;
_lCurrentUser = {username: un, nom: nom};
// Sauvegarder session 8h
localStorage.setItem('lyste_session', JSON.stringify({
username: un,
nom: nom,
expiry: Date.now() + (8 * 60 * 60 * 1000)
}));
ouvrirApp(nom);
}
function ouvrirApp(nom) {
document.getElementById('login-screen').style.display = 'none';
document.getElementById('app').style.display = 'block';
var lbl = document.getElementById('current-user-lbl');
if(lbl) lbl.textContent = nom;
rDash();
}
function doLogout() {
localStorage.removeItem('lyste_session');
_lCurrentUser = null;
document.getElementById('login-screen').style.display = 'flex';
document.getElementById('app').style.display = 'none';
document.getElementById('lpassword').value = '';
document.getElementById('lusername').value = '';
document.getElementById('lerr-login').style.display = 'none';
}
function lOuvrirReinit() {
document.getElementById('lscreen-login').style.display = 'none';
document.getElementById('lscreen-reinit').style.display = 'block';
}
function lRetourLogin() {
document.getElementById('lscreen-reinit').style.display = 'none';
document.getElementById('lscreen-login').style.display = 'block';
}
function lConfirmerReinit() {
alert('Contactez votre administrateur pour r\u00e9initialiser votre mot de passe.');
lRetourLogin();
}
function lCheckStrength(){}
function lCheckMatch(){}
function lChangerMotDePasse(){}
function lCreerSession(u){ ouvrirApp(u.nom || u); }
function lOuvrirApp(nom){ ouvrirApp(nom); }
function showResetHint(){ lOuvrirReinit(); }
function togglePwd(){
var i = document.getElementById('lpassword');
i.type = i.type === 'password' ? 'text' : 'password';
}
// ── CONSTANTES PRODUCTION ─────────────────────────────────────────────
var ETAPES_PROD = [
'Document pas prêt','MEP','IMPORT','ACHAT','RÉCEPTION',
'CNC','EDGE','TRIAGE/GOUJON','TM TRAVAUX MANUELS',
'PRÉPARATION','MONTAGE','PORTE','EMBALLAGE','LIVRAISON'
];
// ── DONNÉES RYTHME PROJETS ─────────────────────────────────────────────
// Projets suivis dans le board de production (liés aux commandes)
if(!D.rythmeProjets) D.rythmeProjets = [
{id:'r1',projId:1,etape:'CNC',resp:'Luc Bernard',notes:'',subtasks:[]},
{id:'r2',projId:2,etape:'ACHAT',resp:'Pierre Simon',notes:'',subtasks:[]},
{id:'r3',projId:3,etape:'MONTAGE',resp:'Sophie Martin',notes:'',subtasks:[]},
{id:'r4',projId:4,etape:'EMBALLAGE',resp:'Marie Dubois',notes:'',subtasks:[]},
{id:'r5',projId:5,etape:'MEP',resp:'Emma Leroy',notes:'',subtasks:[]},
{id:'r6',projId:6,etape:'LIVRAISON',resp:'Pierre Simon',notes:'',subtasks:[]}
];
// ── DONNÉES FOCUS ──────────────────────────────────────────────────────
if(!D.focusTasks||!D.focusTasks.length){D.focusTasks=[
{id:'f1',title:'Confirmer livraison 04425',from:'Mario',to:'Marie Dubois',prio:'urgent',due:fd(ad(T,2)),done:false,projId:1,cat:'perso'},
{id:'f2',title:'V\u00e9rifier commande mat\u00e9riaux',from:'Karine L',to:'',prio:'normal',due:fd(ad(T,4)),done:false,projId:2,cat:'perso'},
{id:'f3',title:'Pr\u00e9parer devis 04388',from:'',to:'Mario',prio:'urgent',due:fd(ad(T,1)),done:false,projId:4,cat:'perso'},
{id:'f4',title:'Mise \u00e0 jour plan 04220',from:'Sophie Martin',to:'',prio:'normal',due:fd(ad(T,5)),done:false,projId:3,cat:'perso'},
{id:'f5',title:'Calibrage machine CNC',from:'',to:'',prio:'urgent',due:fd(ad(T,1)),done:false,projId:null,cat:'usine'},
{id:'f6',title:'Inspection ligne de peinture',from:'Luc Bernard',to:'Pierre Simon',prio:'normal',due:fd(ad(T,3)),done:false,projId:null,cat:'usine'},
{id:'f7',title:'Maintenance presse hydraulique',from:'',to:'Luc Bernard',prio:'urgent',due:fd(ad(T,0)),done:false,projId:null,cat:'usine'},
{id:'f8',title:'Rapport mensuel RH',from:'',to:'Emma Leroy',prio:'normal',due:fd(ad(T,4)),done:false,projId:null,cat:'bureau'},
{id:'f9',title:'Proc\u00e9dures qualit\u00e9',from:'Sophie Martin',to:'',prio:'normal',due:fd(ad(T,7)),done:false,projId:null,cat:'bureau'},
{id:'f10',title:'Suivi commande 04550',from:'Marie Dubois',to:'',prio:'urgent',due:fd(ad(T,2)),done:false,projId:2,cat:'commande'}
];}
// ══════════════════════════════════════════════════════════════════════
// RYTHME — Board de production
// ══════════════════════════════════════════════════════════════════════
function rRythme(){
if(!D.rythmeProjets)D.rythmeProjets=[];
var PALETTE=['#c0392b','#2980b9','#27ae60','#e67e22','#8e44ad','#16a085','#d35400','#922b21','#7f8c8d','#2c3e50','#1e8449','#6c3483','#e74c3c','#1a7a54'];
var sel=document.getElementById('rythme-filter');
if(sel){
var cur=sel.value;
sel.innerHTML='';
D.rythmeProjets.forEach(function(rp){
var p=D.projets.find(function(x){return x.id===rp.projId;});
if(p)sel.innerHTML+='';
});
sel.value=cur||'';
}
var filterRId=sel?sel.value:'';
var board=document.getElementById('rythme-board');
if(!board)return;
board.innerHTML='';
ETAPES_PROD.forEach(function(etape,ei){
var col_color=PALETTE[ei%PALETTE.length];
var items=D.rythmeProjets.filter(function(rp){return rp.etape===etape&&(!filterRId||rp.id===filterRId);});
var stats={regulier:0,attention:0,urgence:0,retard:0};
items.forEach(function(rp){
var p=D.projets.find(function(x){return x.id===rp.projId;});
if(!p)return;
if(p.due){
var diff=Math.round((new Date(p.due)-new Date())/864e5);
if(diff<0)stats.retard++;
else if(diff<=3)stats.urgence++;
else if(diff<=7)stats.attention++;
else stats.regulier++;
} else stats.regulier++;
});
var col=document.createElement('div');
col.className='rb-col';
// En-tête coloré
var hd=document.createElement('div');
hd.className='rb-col-hd';
hd.style.background=col_color;
var titleRow=document.createElement('div');
titleRow.className='rb-col-title';
titleRow.style.color='#fff';
var ts=document.createElement('span');
ts.style.cssText='overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
ts.textContent=etape;
var tb=document.createElement('span');
tb.className='rb-total';
tb.textContent=items.length;
titleRow.appendChild(ts); titleRow.appendChild(tb);
hd.appendChild(titleRow);
var attr=document.createElement('div');
attr.className='rb-attr';
attr.textContent='Date livraison';
hd.appendChild(attr);
var statsDiv=document.createElement('div');
statsDiv.className='rb-stats';
if(stats.regulier>0){var b=document.createElement('span');b.className='rb-stat regulier';b.textContent='R\u00e9gulier: '+stats.regulier;statsDiv.appendChild(b);}
if(stats.attention>0){var b=document.createElement('span');b.className='rb-stat attention';b.textContent='Attention: '+stats.attention;statsDiv.appendChild(b);}
if(stats.urgence>0){var b=document.createElement('span');b.className='rb-stat urgence';b.textContent='Urgence: '+stats.urgence;statsDiv.appendChild(b);}
if(stats.retard>0){var b=document.createElement('span');b.className='rb-stat retard';b.textContent='Retard: '+stats.retard;statsDiv.appendChild(b);}
hd.appendChild(statsDiv);
col.appendChild(hd);
// Corps blanc style LYSTÉ
var body=document.createElement('div');
body.className='rb-col-body';
if(!items.length){
var empty=document.createElement('div');
empty.className='rb-empty';
empty.textContent='Aucun projet';
body.appendChild(empty);
} else {
items.forEach(function(rp,ci){
var p=D.projets.find(function(x){return x.id===rp.projId;});
if(!p)return;
var num=(p.nom.split('\u2014')[0]||p.nom).trim();
var diffDays=null,dateClass='ok';
if(p.due){
diffDays=Math.round((new Date(p.due)-new Date())/864e5);
if(diffDays<0)dateClass='late';
else if(diffDays<=7)dateClass='warn';
}
var card=document.createElement('div');
card.className='rb-card'+(rp.docPret===false?' doc-pas-pret':'');
var numRow=document.createElement('div');
numRow.className='rb-card-num';
var ns=document.createElement('span');
ns.textContent='#'+(ci+1)+' '+num;
numRow.appendChild(ns);
if(diffDays!==null){
var db=document.createElement('span');
db.className='rb-card-date '+dateClass;
db.textContent=(diffDays>=0?'+':'')+diffDays+'j';
numRow.appendChild(db);
}
card.appendChild(numRow);
var dateRow=document.createElement('div');
dateRow.style.cssText='font-size:10px;color:#a09880;margin-bottom:4px';
dateRow.textContent='Date livraison: '+(p.due?fds(p.due):'\u2014');
card.appendChild(dateRow);
if(rp.docPret===false){
var db2=document.createElement('span');
db2.className='rb-badge doc';
db2.textContent='\u26a0 Doc PAS PR\u00caT';
card.appendChild(db2);
}
var icons=document.createElement('div');
icons.className='rb-card-icons';
var icoNote=document.createElement('div');
icoNote.className='rb-icon';icoNote.title='Notes';icoNote.textContent='\ud83d\uddd2';
var icoEdit=document.createElement('div');
icoEdit.className='rb-icon';icoEdit.title='\u00c9diter';icoEdit.textContent='\u270f';
icons.appendChild(icoNote);icons.appendChild(icoEdit);
if(rp.resp){
var eo=D.emps.find(function(e){return e.name===rp.resp;});
if(eo){
var av=document.createElement('div');
av.style.cssText='width:22px;height:22px;border-radius:50%;background:'+ABG[eo.c%ABG.length]+';color:'+AFG[eo.c%AFG.length]+';display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;margin-left:auto;flex-shrink:0';
av.title=eo.name;av.textContent=ini(eo.name);
icons.appendChild(av);
}
}
card.appendChild(icons);
(function(pid,rid){card.onclick=function(){openArbo(pid,rid);};icoEdit.onclick=function(e){e.stopPropagation();openArbo(pid,rid);};})(p.id,rp.id);
body.appendChild(card);
});
}
var addBtn=document.createElement('div');
addBtn.className='rb-add-btn';
addBtn.textContent='+ Ajouter un projet';
(function(et){addBtn.onclick=function(){openRythmeProjModalWithEtape(et);};})(etape);
body.appendChild(addBtn);
col.appendChild(body);
board.appendChild(col);
});
}
function openRythmeProjModalWithEtape(etape){
openRythmeProjModal();
setTimeout(function(){
var sel=document.getElementById('rpm-step');
if(sel)sel.value=etape;
},100);
}
// ══════════════════════════════════════════════════════════════════════
// ARBORESCENCE PROJET
// ══════════════════════════════════════════════════════════════════════
var _arboRpId = null;
var _arboProjId = null;
function openArbo(projId, rpId){
_arboProjId=projId;
_arboRpId=rpId;
var p=D.projets.find(function(x){return x.id===projId;});
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===rpId;});
if(!p||!rp)return;
var parts=p.nom.split('\u2014');
document.getElementById('arbo-num').textContent=(parts[0]||p.nom).trim();
document.getElementById('arbo-nom').textContent=parts[1]?parts[1].trim():'';
var statLbl={actif:'Actif',pause:'En pause',termine:'Termin\u00e9'};
document.getElementById('arbo-cat').textContent=(p.type||'')+(p.statut?' \u00b7 '+(statLbl[p.statut]||p.statut):'');
// ── Bulles d'étapes ──
var curIdx=ETAPES_PROD.indexOf(rp.etape);
var stepsDiv=document.getElementById('arbo-steps');
stepsDiv.innerHTML='';
ETAPES_PROD.forEach(function(e,i){
var btn=document.createElement('div');
btn.className='arbo-step '+(i'+e+'';
}).join('');
// ── Infos ──
var dc=dueColor(p.due);
var infoData=[
{l:'Type',v:p.type||'\u2014'},
{l:'Avanc\u00e9',v:(p.pct!=null?p.pct+'%':'\u2014')},
{l:'Responsable',v:p.resp||'\u2014'},
{l:'\u00c9ch\u00e9ance',v:p.due?fds(p.due):'\u2014'},
{l:'Statut',v:statLbl[p.statut]||'\u2014'},
{l:'\u00c9tape',v:rp.etape}
];
var infoGrid=document.getElementById('arbo-infos');
infoGrid.innerHTML='';
infoData.forEach(function(x){
var item=document.createElement('div');
item.className='arbo-info-item';
item.innerHTML='
'+x.l+'
'+esc(x.v)+'
';
infoGrid.appendChild(item);
});
// ── Responsables par poste ──
var respsDiv=document.getElementById('arbo-resps');
respsDiv.innerHTML='';
var grid=document.createElement('div');
grid.style.cssText='display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px';
(D.emps||[]).forEach(function(e){
var item=document.createElement('div');
item.style.cssText='background:#f8f4ed;border-radius:7px;padding:7px 10px;display:flex;align-items:center;gap:7px';
var av=document.createElement('div');
av.style.cssText='width:28px;height:28px;border-radius:50%;background:'+ABG[e.c%ABG.length]+';color:'+AFG[e.c%AFG.length]+';display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0';
av.textContent=ini(e.name);
var info=document.createElement('div');
var nameEl=document.createElement('div');
nameEl.style.cssText='font-size:11px;font-weight:700;color:#1a1714';
nameEl.textContent=e.name.split(' ')[0];
var roleEl=document.createElement('div');
roleEl.style.cssText='font-size:10px;color:#a09880';
roleEl.textContent=e.role;
info.appendChild(nameEl);info.appendChild(roleEl);
item.appendChild(av);item.appendChild(info);
grid.appendChild(item);
});
respsDiv.appendChild(grid);
// ── Notes ──
document.getElementById('arbo-notes-txt').value=rp.notes||'';
// ── Sous-tâches ──
renderArboSubs();
document.getElementById('arbo-overlay').classList.add('on');
}
function closeArbo(){document.getElementById('arbo-overlay').classList.remove('on');_arboRpId=null;_arboProjId=null;}
function setArboStep(etape){
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===_arboRpId;});
if(rp){rp.etape=etape;sv();openArbo(_arboProjId,_arboRpId);}
}
function saveArboStep(){
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===_arboRpId;});
if(rp){rp.etape=document.getElementById('arbo-step-sel').value;sv();
// Refresh steps visuellement
var curIdx=ETAPES_PROD.indexOf(rp.etape);
document.getElementById('arbo-steps').querySelectorAll('.arbo-step').forEach(function(el,i){
el.className='arbo-step '+(iAucune sous-tâche
';return;}
container.innerHTML='';
subs.forEach(function(s){
var row=document.createElement('div');
row.style.cssText='display:flex;align-items:center;gap:7px;padding:5px 0;border-bottom:.5px solid #f2ede4';
var cb=document.createElement('input');
cb.type='checkbox';cb.checked=s.done;
cb.style.cssText='width:13px;height:13px;accent-color:#1a1714';
cb.onchange=function(){togArboSub(s.id);};
var span=document.createElement('span');
span.style.cssText='font-size:12px;color:'+(s.done?'#bdb3a4':'#1a1714')+';flex:1;'+(s.done?'text-decoration:line-through':'');
span.textContent=s.text;
var btn=document.createElement('button');
btn.innerHTML='✕';
btn.style.cssText='border:none;background:transparent;cursor:pointer;color:#c8bfb0;font-size:13px';
btn.onclick=function(){delArboSub(s.id);};
row.appendChild(cb);row.appendChild(span);row.appendChild(btn);
container.appendChild(row);
});
}
function togArboSub(sid){
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===_arboRpId;});
var s=rp&&(rp.subtasks||[]).find(function(x){return x.id===sid;});
if(s){s.done=!s.done;sv();renderArboSubs();}
}
function delArboSub(sid){
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===_arboRpId;});
if(rp){rp.subtasks=(rp.subtasks||[]).filter(function(x){return x.id!==sid;});sv();renderArboSubs();}
}
function addArboSub(){
var inp=document.getElementById('arbo-sub-inp');
var text=inp.value.trim();if(!text)return;
var rp=(D.rythmeProjets||[]).find(function(x){return x.id===_arboRpId;});
if(!rp)return;
if(!rp.subtasks)rp.subtasks=[];
rp.subtasks.push({id:'as'+D.nid++,text:text,done:false});
inp.value='';sv();renderArboSubs();
}
// ══════════════════════════════════════════════════════════════════════
// CLIENT — cartes 2 colonnes avec toutes les infos
// ══════════════════════════════════════════════════════════════════════
function rClient(){
fES('presp');
var statLabel={actif:'Actif',pause:'En pause',termine:'Termin\u00e9'};
var statColor={actif:'#1a7a54',pause:'#c8941a',termine:'#7f8c8d'};
var statClass={actif:'p-grn',pause:'p-amb',termine:'b-n'};
D.projets.sort(function(a,b){return a.nom';
return;
}
fProj.forEach(function(p){
var idx=D.emps.map(function(e){return e.name;}).indexOf(p.resp);
var bg=idx>=0?ABG[D.emps[idx].c%ABG.length]:ABG[0];
var fg=idx>=0?AFG[D.emps[idx].c%AFG.length]:AFG[0];
var pct=Math.min(100,Math.max(0,p.pct||0));
var dc=dueColor(p.due);
var rp=(D.rythmeProjets||[]).find(function(x){return x.projId===p.id;});
var etape=rp?rp.etape:'\u2014';
var parts=p.nom.split('\u2014');
var num=(parts[0]||p.nom).trim();
var nom=parts[1]?parts[1].trim():'';
var accent=statColor[p.statut]||'#1a7a54';
var card=document.createElement('div');
card.className='client-card';
card.style.setProperty('--card-accent',accent);
card.innerHTML=
'