/* ===== Detail — Fascicolo cantiere (vista B) ===== */
const { useState } = React;

/* ---- subtab: Preventivi ---- */
function TabPreventivi({c, onPatch}){
  const [voce,setVoce]=React.useState(""); const [ditta,setDitta]=React.useState(""); const [dataR,setDataR]=React.useState("");
  const [expandedId,setExpandedId]=React.useState(null);
  const [newImporto,setNewImporto]=React.useState(""); const [newRevNote,setNewRevNote]=React.useState("");

  const todayISO=()=>new Date().toISOString().slice(0,10);
  const isoToLabel=iso=>{if(!iso)return"";const p=iso.split("-");return new Date(+p[0],+p[1]-1,+p[2]).toLocaleDateString('it-IT',{day:'2-digit',month:'short'});};
  const isoToDays=iso=>{if(!iso)return 0;const p=iso.split("-");const t=new Date();t.setHours(0,0,0,0);return Math.round((new Date(+p[0],+p[1]-1,+p[2])-t)/86400000);};

  const add=()=>{
    if(!voce.trim())return;
    const iso=dataR||todayISO();
    onPatch(c.id,x=>({...x,preventivi:[...x.preventivi,{id:Date.now(),voce,ditta:ditta||"—",inviato:{days:isoToDays(iso),label:isoToLabel(iso),iso},stato:"attesa",dataRicezione:null,importo:"",revisioni:[]}]}));
    setVoce("");setDitta("");setDataR("");
  };
  const ricevi=(id)=>{
    const iso=todayISO();
    onPatch(c.id,x=>({...x,preventivi:x.preventivi.map(p=>p.id===id?{...p,stato:"ricevuto",dataRicezione:iso,dataRicezioneLabel:isoToLabel(iso)}:p)}));
  };
  const del=(id)=>onPatch(c.id,x=>({...x,preventivi:x.preventivi.filter(p=>p.id!==id)}));
  const edit=(id,patch)=>onPatch(c.id,x=>({...x,preventivi:x.preventivi.map(p=>p.id===id?{...p,...patch}:p)}));

  const toggleExpand=(id)=>{setExpandedId(v=>v===id?null:id);setNewImporto("");setNewRevNote("");};

  const addRevisione=(pid)=>{
    if(!newImporto.trim())return;
    onPatch(c.id,x=>({...x,preventivi:x.preventivi.map(p=>{
      if(p.id!==pid)return p;
      const revisioni=[...(p.revisioni||[]),{id:Date.now(),n:(p.revisioni||[]).length+1,dataLabel:isoToLabel(todayISO()),importo:newImporto.trim(),note:newRevNote.trim()}];
      return{...p,revisioni,importo:newImporto.trim()};
    })}));
    setNewImporto("");setNewRevNote("");
  };
  const delRevisione=(pid,rid)=>onPatch(c.id,x=>({...x,preventivi:x.preventivi.map(p=>p.id!==pid?p:{...p,revisioni:(p.revisioni||[]).filter(r=>r.id!==rid)})}));

  // inline editable cell
  const Editable=({value,onChange,style})=>{
    const [editing,setEditing]=React.useState(false);
    const [v,setV]=React.useState(value);
    React.useEffect(()=>setV(value),[value]);
    if(editing) return <input autoFocus value={v}
      onChange={e=>setV(e.target.value)}
      onBlur={()=>{setEditing(false);onChange(v);}}
      onKeyDown={e=>{if(e.key==="Enter"){setEditing(false);onChange(v);}if(e.key==="Escape")setEditing(false);}}
      style={{border:"1px solid var(--primary)",borderRadius:6,padding:"4px 8px",fontFamily:"var(--ff)",fontSize:13.5,width:"100%",outline:"none",...style}}/>;
    return <span onClick={()=>setEditing(true)} title="Clicca per modificare"
      style={{cursor:"text",borderRadius:4,padding:"2px 4px",transition:".1s",display:"inline-block",...style}}
      onMouseEnter={e=>e.currentTarget.style.background="var(--card2)"}
      onMouseLeave={e=>e.currentTarget.style.background=""}>{value||<span style={{color:"var(--ink3)"}}>—</span>}</span>;
  };

  const inpStyle={border:"1px solid var(--line)",borderRadius:6,padding:"6px 9px",fontFamily:"var(--ff)",fontSize:13,background:"var(--card)",outline:"none",color:"var(--ink)"};

  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Richieste preventivi</div>
        <span className="badge">{c.preventivi.filter(p=>p.stato==="attesa").length} in attesa</span>
      </div>
      {c.preventivi.length===0
        ? <div className="empty">Nessuna richiesta ancora. Aggiungine una qui sotto.</div>
        : <table className="tbl"><thead><tr>
            <th>Fornitura</th><th>Ditta</th><th>Data richiesta</th><th>Giorni</th><th>Data ricezione</th><th>Importo</th><th></th>
          </tr></thead><tbody>
            {c.preventivi.map(p=>{
              const nRev=(p.revisioni||[]).length;
              const isOpen=expandedId===p.id;
              return (
                <React.Fragment key={p.id}>
                  <tr className={p.stato==="ricevuto"?"recv":""}>
                    <td><b style={{fontWeight:600}}><Editable value={p.voce} onChange={v=>edit(p.id,{voce:v})}/></b></td>
                    <td><Editable value={p.ditta} onChange={v=>edit(p.id,{ditta:v})}/></td>
                    <td>
                      <input type="date" value={p.inviato.iso||""} onChange={e=>{const iso=e.target.value;edit(p.id,{inviato:{days:isoToDays(iso),label:isoToLabel(iso),iso}});}}
                        style={{border:"1px solid var(--line)",borderRadius:6,padding:"3px 7px",fontFamily:"var(--ff)",fontSize:12.5,background:"var(--card)",outline:"none",color:"var(--ink)"}}/>
                    </td>
                    <td>{p.stato==="ricevuto"
                      ? <span className="badge green" style={{fontSize:11}}>ricevuto</span>
                      : <span style={{display:"inline-block",padding:"3px 9px",fontSize:12,fontWeight:700,borderRadius:6,
                          background:Math.abs(p.inviato.days)>=8?"var(--red-soft)":Math.abs(p.inviato.days)>=4?"var(--amber-soft)":"var(--card2)",
                          color:Math.abs(p.inviato.days)>=8?"var(--red)":Math.abs(p.inviato.days)>=4?"#b45309":"var(--ink3)"}}>
                          {p.inviato.days===0?"oggi":Math.abs(p.inviato.days)+" gg"}
                        </span>}
                    </td>
                    <td style={{fontSize:13,color:p.dataRicezione?"#059669":"var(--ink3)",fontWeight:p.dataRicezione?600:400}}>
                      {p.dataRicezioneLabel||"—"}
                    </td>
                    <td>
                      <div style={{display:'flex',alignItems:'center',gap:5}}>
                        <Editable value={p.importo||""} onChange={v=>edit(p.id,{importo:v})}
                          style={{fontWeight:p.importo?700:400,minWidth:50}}/>
                        {p.importo&&<span style={{fontSize:11,color:'var(--ink3)'}}>€</span>}
                        {nRev>1&&<span style={{fontSize:10,fontWeight:700,color:'var(--primary)',background:'var(--primary-soft)',borderRadius:999,padding:'1px 6px'}}>{nRev} rev</span>}
                      </div>
                    </td>
                    <td style={{textAlign:"right",whiteSpace:"nowrap",display:"flex",gap:4,alignItems:"center",justifyContent:"flex-end"}}>
                      {p.stato==="attesa"&&
                        <button className="btn sm primary" onClick={()=>ricevi(p.id)}><Icon name="check" size={13}/> Ricevuto</button>}
                      <button className="btn sm ghost" onClick={()=>toggleExpand(p.id)}
                        style={{color:isOpen?'var(--primary)':'var(--ink3)',fontWeight:isOpen?700:400,padding:"5px 8px",fontSize:11.5}}>
                        {nRev>0?`v${nRev}`:"rev."}
                      </button>
                      <button className="btn sm ghost" onClick={()=>del(p.id)} style={{color:"var(--ink3)",padding:"5px 7px"}}>✕</button>
                    </td>
                  </tr>
                  {isOpen&&(
                    <tr>
                      <td colSpan={7} style={{padding:'10px 16px 14px',background:'var(--primary-soft)',borderBottom:'2px solid var(--line)'}}>
                        <div style={{fontSize:11,fontWeight:700,color:'var(--primary)',textTransform:'uppercase',letterSpacing:'.07em',marginBottom:8}}>
                          Storico revisioni — {p.voce}
                        </div>
                        {nRev===0
                          ? <div style={{fontSize:13,color:'var(--ink3)',marginBottom:10}}>Nessuna revisione ancora.</div>
                          : <div style={{display:'flex',flexDirection:'column',gap:4,marginBottom:10}}>
                              {(p.revisioni||[]).map(r=>(
                                <div key={r.id} style={{display:'flex',gap:12,alignItems:'center',padding:'7px 12px',background:'var(--card)',borderRadius:8,border:'1px solid var(--line)',fontSize:13}}>
                                  <span style={{fontWeight:700,color:'var(--primary)',minWidth:28,flexShrink:0}}>v{r.n}</span>
                                  <span style={{color:'var(--ink3)',fontSize:12,minWidth:52,flexShrink:0}}>{r.dataLabel}</span>
                                  <span style={{fontWeight:700,minWidth:80,flexShrink:0}}>{r.importo?`€ ${r.importo}`:'—'}</span>
                                  <span style={{color:'var(--ink2)',flex:1,fontSize:12.5}}>{r.note||''}</span>
                                  <button className="btn ghost sm" onClick={()=>delRevisione(p.id,r.id)} style={{color:'var(--ink3)',padding:'2px 6px',fontSize:12}}>✕</button>
                                </div>
                              ))}
                            </div>
                        }
                        <div style={{display:'flex',gap:7,alignItems:'center'}}>
                          <span style={{fontSize:11.5,fontWeight:600,color:'var(--ink3)',flexShrink:0,whiteSpace:'nowrap'}}>Nuova revisione</span>
                          <input placeholder="Importo (es. 4.500)" value={newImporto} onChange={e=>setNewImporto(e.target.value)}
                            onKeyDown={e=>e.key==='Enter'&&addRevisione(p.id)} style={{...inpStyle,width:150}}/>
                          <input placeholder="Nota (opzionale)" value={newRevNote} onChange={e=>setNewRevNote(e.target.value)}
                            onKeyDown={e=>e.key==='Enter'&&addRevisione(p.id)} style={{...inpStyle,flex:1}}/>
                          <button className="btn sm primary" onClick={()=>addRevisione(p.id)} disabled={!newImporto.trim()} style={{opacity:newImporto.trim()?1:.5}}>
                            <Icon name="plus" size={13}/> Aggiungi
                          </button>
                        </div>
                      </td>
                    </tr>
                  )}
                </React.Fragment>
              );
            })}
          </tbody></table>}
      <hr className="divider"/>
      <div className="add-row" style={{flexWrap:"wrap"}}>
        <input placeholder="Fornitura (es. macchina clima)" value={voce} onChange={e=>setVoce(e.target.value)} onKeyDown={e=>e.key==="Enter"&&add()} style={{minWidth:200}}/>
        <input placeholder="Ditta" value={ditta} onChange={e=>setDitta(e.target.value)} onKeyDown={e=>e.key==="Enter"&&add()} style={{maxWidth:160}}/>
        <label style={{display:"flex",alignItems:"center",gap:6,fontSize:13,color:"var(--ink3)",whiteSpace:"nowrap"}}>
          Data richiesta
          <input type="date" value={dataR} onChange={e=>setDataR(e.target.value)}
            style={{border:"1px solid var(--line)",borderRadius:8,padding:"8px 10px",fontFamily:"var(--ff)",fontSize:13,background:"var(--card)",outline:"none",color:"var(--ink)"}}/>
        </label>
        <button className="btn primary" onClick={add}><Icon name="plus" size={15}/> Aggiungi</button>
      </div>
    </div>
  );
}

/* ---- subtab: Sopralluogo ---- */
function TabSopralluogo({c, onPatch}){
  const done=c.sopralluogo.filter(s=>s.done).length, tot=c.sopralluogo.length;
  const toggle=(id)=>onPatch(c.id,x=>({...x,sopralluogo:x.sopralluogo.map(s=>s.id===id?{...s,done:!s.done}:s)}));
  const setNote=(id,v)=>onPatch(c.id,x=>({...x,sopralluogo:x.sopralluogo.map(s=>s.id===id?{...s,note:v}:s)}));
  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Checklist sopralluogo</div>
        <div style={{display:"flex",alignItems:"center",gap:12,minWidth:200}}>
          <div className="prog" style={{flex:1}}><i style={{width:(done/tot*100)+"%"}}></i></div>
          <span className="badge olive">{done}/{tot}</span>
        </div>
      </div>
      <div className="chk-grid">
        {c.sopralluogo.map(s=>(
          <div key={s.id} className={"chk-item"+(s.done?" on":"")}>
            <div className="num" onClick={()=>toggle(s.id)} style={{cursor:"pointer"}}>{s.done?<Icon name="check" size={14}/>:s.id+1}</div>
            <div className="ci-body">
              <b style={{cursor:"pointer"}} onClick={()=>toggle(s.id)}>{s.t}</b>
              <input className="note" placeholder="annota… (es. h 2.80, presente, da verificare)"
                value={s.note} onChange={e=>setNote(s.id,e.target.value)}/>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---- subtab: Consegne ---- */
function TabConsegne({c, onPatch}){
  const [cosa,setCosa]=React.useState(""); const [forn,setForn]=React.useState(""); const [dataS,setDataS]=React.useState(""); const [chi,setChi]=React.useState("nostra");
  const [editOrdId,setEditOrdId]=React.useState(null);
  const [editDataId,setEditDataId]=React.useState(null);

  const todayISO=()=>new Date().toISOString().slice(0,10);
  const fmtISO=iso=>{if(!iso)return"—";const p=iso.split("-");return new Date(+p[0],+p[1]-1,+p[2]).toLocaleDateString('it-IT',{day:'2-digit',month:'short'});};
  const isOrd=d=>d.ordinatoIl&&d.ordinatoIl!=="—";
  const isCons=d=>d.consegnato||d.stato==="consegnato";

  const add=()=>{
    if(!cosa.trim())return;
    let days=99,label="da definire",ts=undefined;
    if(dataS){const p=dataS.split("-");const td=new Date(+p[0],+p[1]-1,+p[2]);const today=new Date();today.setHours(0,0,0,0);days=Math.round((td-today)/86400000);label=td.toLocaleDateString('it-IT',{day:'2-digit',month:'short'});ts=td.getTime();}
    onPatch(c.id,x=>({...x,consegne:[...x.consegne,{id:Date.now(),cosa,forn:forn||"—",data:{days,label,ts},stato:"da ordinare",chi,ordinatoIl:null}]}));
    setCosa("");setForn("");setDataS("");setChi("nostra");
  };

  const setOrdinato=(id,iso)=>{
    setEditOrdId(null);
    if(!iso)return;
    onPatch(c.id,x=>({...x,consegne:x.consegne.map(d=>d.id===id?{...d,ordinatoIl:iso,stato:d.stato==="da ordinare"?"ordinato":d.stato}:d)}));
  };

  const setDataPrev=(id,iso)=>{
    setEditDataId(null);
    if(!iso)return;
    const p=iso.split("-");const td=new Date(+p[0],+p[1]-1,+p[2]);const today=new Date();today.setHours(0,0,0,0);
    onPatch(c.id,x=>({...x,consegne:x.consegne.map(d=>d.id===id?{...d,data:{days:Math.round((td-today)/86400000),label:td.toLocaleDateString('it-IT',{day:'2-digit',month:'short'}),ts:td.getTime()}}:d)}));
  };

  const toggleConsegnato=id=>onPatch(c.id,x=>({...x,consegne:x.consegne.map(d=>{
    if(d.id!==id)return d;
    const was=isCons(d);
    return{...d,consegnato:!was,stato:!was?"consegnato":"ordinato",consegnataIl:!was?todayISO():null};
  })}));
  const editField=(id,patch)=>onPatch(c.id,x=>({...x,consegne:x.consegne.map(d=>d.id===id?{...d,...patch}:d)}));
  const del=(id)=>onPatch(c.id,x=>({...x,consegne:x.consegne.filter(d=>d.id!==id)}));

  const dateInputStyle={border:"1px solid var(--line-2)",borderRadius:6,padding:"3px 7px",fontFamily:"var(--ff)",fontSize:13,outline:"none",background:"var(--card)"};
  const editableLabelStyle={cursor:"pointer",borderBottom:"1px dashed var(--ink-3)"};

  return (
    <div className="card panel fade">
      <div className="phead"><div className="sec-title">Consegne & ordini</div>
        <span className="badge">{c.consegne.filter(d=>!isCons(d)).length} aperti</span></div>
      {c.consegne.length===0
        ? <div className="empty">Nessuna consegna ancora. Aggiungine una qui sotto.</div>
        : <table className="tbl"><thead><tr>
            <th>Fornitura</th><th>Fornitore</th><th style={{textAlign:"center"}}>Origine</th><th style={{textAlign:"center"}}>Ordinato il</th><th style={{textAlign:"center"}}>Data prevista</th><th style={{textAlign:"center"}}>Consegnato</th><th style={{textAlign:"center"}}>Consegnata il</th><th></th>
          </tr></thead>
          <tbody>{c.consegne.map(d=>{
            const ord=isOrd(d), cons=isCons(d);
            const dataISO=d.data.ts?new Date(d.data.ts).toISOString().slice(0,10):"";
            return (
            <tr key={d.id} className={cons?"recv":""} style={cons?{}:ord?{background:"rgba(16,185,129,0.05)"}:{}}>
              <td><b style={{fontWeight:600}}><EditableInline value={d.cosa} onSave={v=>editField(d.id,{cosa:v})} spanStyle={{fontWeight:600,cursor:'text',borderBottom:'1px dashed var(--ink-3)'}}/></b></td>
              <td><EditableInline value={d.forn} placeholder="—" onSave={v=>editField(d.id,{forn:v})} spanStyle={{cursor:'text',borderBottom:'1px dashed var(--ink-3)'}}/></td>
              <td style={{textAlign:"center"}}><span className="badge" style={{fontSize:11}}>{d.chi==="cliente"?"cliente":"nostra"}</span></td>
              <td style={{textAlign:"center"}}>
                {editOrdId===d.id
                  ? <input type="date" autoFocus defaultValue={ord?d.ordinatoIl:todayISO()}
                      onBlur={e=>setOrdinato(d.id,e.target.value)}
                      onKeyDown={e=>{if(e.key==="Enter")e.target.blur();if(e.key==="Escape")setEditOrdId(null);}}
                      style={dateInputStyle}/>
                  : ord
                    ? <span onClick={()=>setEditOrdId(d.id)} title="Clicca per modificare" style={{fontSize:13,...editableLabelStyle}}>{fmtISO(d.ordinatoIl)}</span>
                    : <button className="btn sm ghost" onClick={()=>setOrdinato(d.id,todayISO())} onContextMenu={e=>{e.preventDefault();setEditOrdId(d.id);}} style={{fontSize:12}}>Ordina</button>
                }
              </td>
              <td style={{textAlign:"center"}}>
                {editDataId===d.id
                  ? <input type="date" autoFocus defaultValue={dataISO}
                      onBlur={e=>setDataPrev(d.id,e.target.value)}
                      onKeyDown={e=>{if(e.key==="Enter")e.target.blur();if(e.key==="Escape")setEditDataId(null);}}
                      style={dateInputStyle}/>
                  : <span onClick={()=>setEditDataId(d.id)} title="Clicca per modificare" style={editableLabelStyle}>
                      {d.data.label} <span className="dim" style={{fontSize:12}}>· {fmtDays(d.data.days)}</span>
                    </span>
                }
              </td>
              <td style={{textAlign:"center"}}>
                <input type="checkbox" checked={cons} onChange={()=>toggleConsegnato(d.id)}
                  style={{width:16,height:16,cursor:"pointer",accentColor:"var(--green)"}}/>
              </td>
              <td style={{textAlign:"center",fontSize:13,color:cons?"var(--ink)":"var(--ink-3)"}}>
                {cons&&d.consegnataIl ? fmtISO(d.consegnataIl) : "—"}
              </td>
              <td style={{textAlign:"right"}}>
                <button className="btn sm ghost" onClick={()=>del(d.id)} style={{color:"var(--ink3)",padding:"4px 7px"}}>✕</button>
              </td>
            </tr>);
          })}</tbody></table>}
      <hr className="divider"/>
      <div className="add-row" style={{flexWrap:"wrap"}}>
        <input placeholder="Fornitura (es. scaffali magazzino)" value={cosa} onChange={e=>setCosa(e.target.value)} onKeyDown={e=>e.key==="Enter"&&add()} style={{minWidth:180}}/>
        <input placeholder="Fornitore" value={forn} onChange={e=>setForn(e.target.value)} style={{maxWidth:150}}/>
        <input type="date" value={dataS} onChange={e=>setDataS(e.target.value)} style={{maxWidth:150,border:"1px solid var(--line-2)",borderRadius:10,padding:"9px 11px",fontFamily:"inherit",fontSize:14,background:"var(--card)",outline:"none"}}/>
        <select value={chi} onChange={e=>setChi(e.target.value)} style={{border:"1px solid var(--line-2)",borderRadius:10,padding:"9px 11px",fontFamily:"var(--ff)",fontSize:14,background:"var(--card)",color:"var(--ink)",outline:"none",maxWidth:120}}>
          <option value="nostra">nostra</option>
          <option value="cliente">cliente</option>
        </select>
        <button className="btn primary" onClick={add}><Icon name="plus" size={15}/> Aggiungi</button>
      </div>
    </div>
  );
}


/* ---- subtab: Cronoprogramma ---- */
function TabCrono({c, onPatch, rubrica, onSaveDitta, onAddLavorazione}){
  const parseIT=str=>{
    if(!str)return null;
    const p=str.split('/');
    if(p.length!==3)return null;
    const dt=new Date(+p[2],+p[1]-1,+p[0]);
    return isNaN(dt.getTime())?null:dt;
  };
  // usa data locale invece di UTC per evitare sfasamento timezone
  const localISO=d=>`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;

  const [addingLav,setAddingLav]=useState(null);
  const [showDittaPicker,setShowDittaPicker]=useState(false);
  const [weekIdx,setWeekIdx]=useState(()=>{
    const s=parseIT(c.info?.dataInizio), e=parseIT(c.info?.dataFine);
    if(!s||!e)return 0;
    const todayStr=localISO(new Date());
    const days=[]; const cur=new Date(s);
    while(cur<=e){days.push(localISO(cur));cur.setDate(cur.getDate()+1);}
    const wks=[]; let wk=[];
    days.forEach(iso=>{const isM=new Date(iso).getDay()===1;if(wk.length===0||isM){if(wk.length)wks.push(wk);wk=[iso];}else wk.push(iso);});
    if(wk.length)wks.push(wk);
    const idx=wks.findIndex(w=>w.includes(todayStr));
    return Math.max(0,idx>=0?idx:0);
  });

  const ditte=c.ditte||[];
  const cronoDays=c.cronoDays||{};
  const allLav=[...new Set(ditte.flatMap(d=>d.lavorazioni||(d.lavoro?[d.lavoro]:[])))];
  const todayISO=localISO(new Date());

  const start=parseIT(c.info?.dataInizio);
  const end=parseIT(c.info?.dataFine);

  const dayRange=React.useMemo(()=>{
    const s=parseIT(c.info?.dataInizio), e=parseIT(c.info?.dataFine);
    if(!s||!e)return[];
    // estende fino alla domenica della settimana di consegna
    const end=new Date(e);
    const dow=end.getDay(); // 0=dom, 1=lun…
    if(dow!==0) end.setDate(end.getDate()+(7-dow));
    const days=[]; const cur=new Date(s);
    while(cur<=end){days.push(localISO(cur));cur.setDate(cur.getDate()+1);}
    return days;
  },[c.info?.dataInizio,c.info?.dataFine]);

  const weeks=React.useMemo(()=>{
    const wks=[]; let cur=[];
    dayRange.forEach(iso=>{
      const isMonday=new Date(iso).getDay()===1;
      if(cur.length===0||isMonday){if(cur.length)wks.push(cur);cur=[iso];}
      else cur.push(iso);
    });
    if(cur.length)wks.push(cur);
    return wks;
  },[dayRange]);

  const cronoData=calcCronoProgress(c);
  const getProgress=lav=>cronoData.find(r=>r.lav===lav)||{done:0,total:0,pct:0};

  const toggleDay=(lav,iso)=>{
    const days=cronoDays[lav]||[];
    const next=days.includes(iso)?days.filter(d=>d!==iso):[...days,iso].sort();
    onPatch(c.id,x=>({...x,cronoDays:{...(x.cronoDays||{}),[lav]:next}}));
  };

  const handlePickDitta=({ditta,lavorazioni})=>{
    onPatch(c.id,x=>({...x,ditte:[...(x.ditte||[]),{id:Date.now(),rubricaId:ditta.id,nome:ditta.nome,ref:ditta.ref||'',tel:ditta.tel||'',lavorazioni}]}));
    setShowDittaPicker(false);
  };
  const updDitta=(id,patch)=>onPatch(c.id,x=>({...x,ditte:(x.ditte||[]).map(d=>d.id===id?{...d,...patch}:d)}));
  const delDitta=id=>onPatch(c.id,x=>({...x,ditte:(x.ditte||[]).filter(d=>d.id!==id)}));
  const addLavFromList=(id,nome)=>{
    const ditta=ditte.find(d=>d.id===id); if(!ditta)return;
    updDitta(id,{lavorazioni:[...(ditta.lavorazioni||[]),nome]});
  };
  const removeLav=(id,lav)=>{
    const ditta=ditte.find(d=>d.id===id); if(!ditta)return;
    updDitta(id,{lavorazioni:(ditta.lavorazioni||[]).filter(l=>l!==lav)});
  };

  const DOW=['L','M','M','G','V','S','D'];
  const CW=26;
  const esStyle={cursor:'pointer',borderBottom:'1px dashed var(--ink-3)',fontSize:13};

  return (
    <div className="col fade">

      {/* ── Sezione 1: Ditte ── */}
      <div className="card panel">
        <div className="phead">
          <div className="sec-title">Ditte & lavorazioni</div>
          <span className="badge">{ditte.length} {ditte.length===1?'ditta':'ditte'}</span>
        </div>
        {ditte.length===0
          ?<div className="empty">Nessuna ditta aggiunta. Usa il form qui sotto.</div>
          :<table className="tbl"><thead><tr>
              <th>Nome ditta</th><th>Referente</th><th>Telefono</th><th>Lavorazioni</th><th></th>
            </tr></thead>
            <tbody>{ditte.map(d=>(
              <tr key={d.id}>
                <td><EditableInline value={d.nome} onSave={v=>updDitta(d.id,{nome:v})} spanStyle={{fontWeight:600,...esStyle}}/></td>
                <td><EditableInline value={d.ref||''} placeholder="—" onSave={v=>updDitta(d.id,{ref:v})} spanStyle={esStyle}/></td>
                <td><EditableInline value={d.tel||''} placeholder="—" onSave={v=>updDitta(d.id,{tel:v})} spanStyle={esStyle}/></td>
                <td>
                  <div style={{display:'flex',flexWrap:'wrap',gap:4,alignItems:'center'}}>
                    {(d.lavorazioni||[]).map(lav=>(
                      <span key={lav} className="badge" style={{fontSize:11,display:'inline-flex',alignItems:'center',gap:3}}>
                        {lav}
                        <span onClick={()=>removeLav(d.id,lav)} style={{cursor:'pointer',opacity:.5,fontSize:13,lineHeight:1}}>×</span>
                      </span>
                    ))}
                    {addingLav===d.id
                      ?<InlineLavSelect
                          lavorazioni={rubrica?.lavorazioni||[]}
                          used={d.lavorazioni||[]}
                          onSelect={v=>{ addLavFromList(d.id,v); setAddingLav(null); }}
                          onAddNew={async nome=>{ const l=await onAddLavorazione(nome); addLavFromList(d.id,l.nome); setAddingLav(null); }}
                          onClose={()=>setAddingLav(null)}
                        />
                      :<button className="btn sm ghost" onClick={()=>setAddingLav(d.id)} style={{fontSize:12}}>+ Lavorazione</button>
                    }
                  </div>
                </td>
                <td><button className="btn sm ghost" onClick={()=>delDitta(d.id)} style={{color:'var(--red)',fontSize:12}}>Rimuovi</button></td>
              </tr>
            ))}</tbody>
          </table>
        }
        <hr className="divider"/>
        <div style={{display:'flex',alignItems:'center',gap:12,padding:'2px 0'}}>
          <button className="btn primary" onClick={()=>setShowDittaPicker(true)} disabled={!rubrica}>
            <Icon name="plus" size={15}/> Aggiungi da rubrica
          </button>
          {!rubrica&&<span style={{fontSize:13,color:'var(--ink3)'}}>Caricamento rubrica…</span>}
        </div>
        {showDittaPicker&&rubrica&&(
          <DittaPickerModal
            rubrica={rubrica}
            onSaveDitta={onSaveDitta}
            onAddLavorazione={onAddLavorazione}
            onPick={handlePickDitta}
            onClose={()=>setShowDittaPicker(false)}
          />
        )}
      </div>

      {/* ── Sezione 2: Gantt ── */}
      {allLav.length>0&&(
        <div className="card panel">
          {(!start||!end)
            ?<><div className="phead"><div className="sec-title">Cronoprogramma</div></div>
               <div className="empty">Imposta le date di inizio e fine cantiere per visualizzare il cronoprogramma.</div></>
            :(()=>{
              const safeIdx=Math.min(weekIdx,weeks.length-1);
              const wk=weeks[safeIdx]||[];
              const wkFirst=new Date(wk[0]);
              const wkLast=new Date(wk[wk.length-1]);
              const fmtWk=d=>d.toLocaleDateString('it-IT',{day:'2-digit',month:'short'});
              const wkLabel=`${fmtWk(wkFirst)} – ${fmtWk(wkLast)}`;
              const LAV_COLORS=['#bd5d2e','#4a7a9b','#7f8a4a','#c79233','#7a5c8a','#3a8a6a','#c4556a','#5a6a9a'];
              const gridCols=`160px repeat(${wk.length},1fr) 88px`;
              const dNames=['Lun','Mar','Mer','Gio','Ven','Sab','Dom'];
              const mNames=['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic'];
              return (<>
                {/* header: title a sx, nav centrato */}
                <div style={{display:'flex',alignItems:'center',marginBottom:16}}>
                  <div className="sec-title" style={{flex:1}}>Cronoprogramma</div>
                  <div style={{display:'flex',alignItems:'center',gap:10}}>
                    <button className="btn ghost sm" onClick={()=>setWeekIdx(i=>Math.max(0,i-1))} disabled={safeIdx===0} style={{fontSize:16,lineHeight:1,padding:'2px 10px'}}>‹</button>
                    <span style={{fontSize:13,fontWeight:600,minWidth:130,textAlign:'center'}}>{wkLabel}</span>
                    <button className="btn ghost sm" onClick={()=>setWeekIdx(i=>Math.min(weeks.length-1,i+1))} disabled={safeIdx===weeks.length-1} style={{fontSize:16,lineHeight:1,padding:'2px 10px'}}>›</button>
                  </div>
                  <div style={{flex:1}}/>
                </div>
                {/* intestazione giorni */}
                <table style={{width:'100%',borderCollapse:'collapse',tableLayout:'fixed'}}>
                  <colgroup>
                    <col style={{width:160}}/>
                    {wk.map((_,i)=><col key={i}/>)}
                    <col style={{width:88}}/>
                  </colgroup>
                  <thead>
                    <tr>
                      <th style={{padding:'0 0 8px'}}/>
                      {wk.map(iso=>{
                        const dow=new Date(iso).getDay(), mb=dow===0?6:dow-1;
                        const isT=iso===todayISO, isWk=mb>=5;
                        const d=new Date(iso);
                        return (
                          <th key={iso} style={{padding:'0 2px 8px',textAlign:'center',fontWeight:'normal'}}>
                            <div style={{fontSize:13,fontWeight:600,color:isT?'var(--primary)':isWk?'#e07a6a':'var(--ink-2)'}}>{dNames[mb]}</div>
                            <div style={{fontSize:12,color:isT?'var(--primary)':isWk?'#e07a6a':'var(--ink-3)'}}>{d.getDate()} {mNames[d.getMonth()]}</div>
                          </th>
                        );
                      })}
                      <th style={{padding:'0 0 8px',textAlign:'center',fontSize:11,fontWeight:600,color:'var(--ink-2)'}}></th>
                    </tr>
                  </thead>
                  <tbody>
                    {allLav.map((lav,lavIdx)=>{
                      const color=LAV_COLORS[lavIdx%LAV_COLORS.length];
                      const selDays=cronoDays[lav]||[];
                      const prog=getProgress(lav);
                      return (
                        <tr key={lav} style={{borderTop:'1px solid rgba(0,0,0,0.06)'}}>
                          <td style={{padding:'12px 10px 12px 0',fontSize:13,fontWeight:500,
                            whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis',verticalAlign:'middle'}}>
                            <span style={{display:'inline-flex',alignItems:'center',gap:6}}>
                              <span style={{width:8,height:8,borderRadius:'50%',background:color,display:'inline-block',flexShrink:0}}/>
                              {lav}
                            </span>
                          </td>
                          {wk.map(iso=>{
                            const sel=selDays.includes(iso);
                            const isT=iso===todayISO;
                            const dow=new Date(iso).getDay(), mb=dow===0?6:dow-1;
                            const isWk=mb>=5;
                            return (
                              <td key={iso} onClick={()=>toggleDay(lav,iso)}
                                style={{padding:'8px 2px',textAlign:'center',verticalAlign:'middle',cursor:'pointer'}}>
                                <div style={{width:26,height:26,borderRadius:7,margin:'0 auto',position:'relative',
                                  border:`1.5px solid ${sel?color:'var(--line-2)'}`,
                                  background:sel?color+'1a':isWk?'rgba(0,0,0,0.03)':'transparent'}}>
                                  {sel&&<div style={{position:'absolute',inset:0,display:'flex',alignItems:'center',justifyContent:'center'}}>
                                    <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
                                      <path d="M2 6.5L5 9.5L11 3.5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                                    </svg>
                                  </div>}
                                </div>
                              </td>
                            );
                          })}
                          <td style={{padding:'8px',textAlign:'center',verticalAlign:'middle'}}>
                            <div style={{fontWeight:700,fontSize:16,color:prog.pct===100?'var(--green)':'var(--ink)',lineHeight:1.1}}>
                              {prog.pct}%
                            </div>
                            <div style={{margin:'4px auto',height:3,borderRadius:2,background:'var(--line-2)',overflow:'hidden',width:56}}>
                              {prog.pct>0&&<div style={{height:'100%',width:prog.pct+'%',borderRadius:2,
                                background:prog.pct===100?'var(--green)':'var(--primary)'}}/>}
                            </div>
                            <div style={{fontSize:12,color:'var(--ink-3)',marginTop:3,opacity:prog.total>0?1:0}}>
                              ({prog.done}/{prog.total})
                            </div>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </>);
            })()
          }
        </div>
      )}
    </div>
  );
}

/* ---- NoteAddForm — form inline espandibile ---- */
function NoteAddForm({onAdd}){
  const [open,setOpen]=React.useState(false);
  const [t,setT]=React.useState(""); const [v,setV]=React.useState("");
  const save=()=>{ if(!t.trim()&&!v.trim())return; onAdd(t.trim()||"Nota",v.trim()); setT("");setV("");setOpen(false); };
  if(!open) return (
    <button className="btn ghost" onClick={()=>setOpen(true)} style={{alignSelf:"flex-start",color:"var(--terra)",marginTop:4}}>
      <Icon name="plus" size={15}/> Aggiungi nota
    </button>
  );
  return (
    <div style={{marginTop:8,background:"var(--ocra-soft)",border:"1px solid #e7d29a",borderRadius:12,padding:"13px 14px",display:"flex",flexDirection:"column",gap:9}}>
      <input placeholder="Titolo (es. Accesso, Transpallet…)" value={t} onChange={e=>setT(e.target.value)}
        autoFocus
        style={{border:"none",borderBottom:"1.5px solid #d4b87a",background:"none",fontFamily:"var(--ff)",fontWeight:700,fontSize:14,color:"var(--ink)",outline:"none",padding:"2px 0"}}/>
      <textarea placeholder="Testo della nota…" value={v} onChange={e=>setV(e.target.value)} rows={3}
        style={{border:"none",background:"none",fontFamily:"var(--ff)",fontSize:13.5,color:"var(--ink)",outline:"none",resize:"vertical",padding:"2px 0",lineHeight:1.5}}/>
      <div style={{display:"flex",gap:8,justifyContent:"flex-end"}}>
        <button className="btn sm ghost" onClick={()=>{setOpen(false);setT("");setV("");}}>Annulla</button>
        <button className="btn sm primary" onClick={save}><Icon name="check" size={13}/> Salva</button>
      </div>
    </div>
  );
}

function TabTodoNote({c, onPatch}){
  const [nt,setNt]=React.useState(""); const [nu,setNu]=React.useState(false); const [nd,setNd]=React.useState("");
  const toggle=(id)=>onPatch(c.id,x=>({...x,todos:x.todos.map(t=>t.id===id?{...t,done:!t.done}:t)}));
  const delTodo=(id)=>onPatch(c.id,x=>({...x,todos:x.todos.filter(t=>t.id!==id)}));
  const addTodo=()=>{
    if(!nt.trim())return;
    let due=null;
    if(nd){const p=nd.split("-");const td=new Date(+p[0],+p[1]-1,+p[2]);const today=new Date();today.setHours(0,0,0,0);const days=Math.round((td-today)/86400000);const label=td.toLocaleDateString('it-IT',{day:'2-digit',month:'short'});due={days,label};}
    onPatch(c.id,x=>({...x,todos:[...x.todos,{id:Date.now(),t:nt,due,done:false,urgent:nu}]}));
    setNt(""); setNu(false); setNd("");
  };
  const delNote=(id)=>onPatch(c.id,x=>({...x,note:(x.note||[]).filter(n=>n.id!==id)}));
  const open=c.todos.filter(t=>!t.done);
  return (
    <div className="row fade" style={{alignItems:"flex-start"}}>
      <div className="card panel" style={{flex:1.4}}>
        <div className="phead"><div className="sec-title">Cose da fare</div><span className="badge">{open.length} aperte</span></div>
        <div className="list">
          {c.todos.map(t=>(
            <div key={t.id} className={"li"+(t.done?" done":"")}>
              <div className={"chk"+(t.done?" on":t.urgent?" due":"")} onClick={()=>toggle(t.id)}>{t.done&&<Icon name="check" size={13}/>}</div>
              <div className="txt">{t.t}
                {(t.due||t.urgent)&&<div className="when" style={{marginTop:3,display:"flex",gap:7}}>
                  {t.urgent&&<span className="badge clay" style={{fontSize:10.5}}>urgente</span>}
                  {t.due&&<span className="dim">entro {t.due.label}</span>}</div>}
              </div>
              <button className="btn ghost sm" onClick={()=>delTodo(t.id)} style={{color:"var(--ink3)",padding:"4px 7px",opacity:.5,marginLeft:"auto",flexShrink:0}} title="Elimina">✕</button>
            </div>
          ))}
        </div>
        <div className="col" style={{gap:8,marginTop:4}}>
          <div className="add-row">
            <input placeholder="Aggiungi una cosa da fare…" value={nt} onChange={e=>setNt(e.target.value)} onKeyDown={e=>e.key==="Enter"&&addTodo()}/>
            <button className="btn primary" onClick={addTodo}><Icon name="plus" size={15}/></button>
          </div>
          <div style={{display:"flex",gap:10,alignItems:"center",paddingLeft:2}}>
            <input type="date" value={nd} onChange={e=>setNd(e.target.value)}
              style={{border:"1px solid var(--line-2)",borderRadius:9,padding:"7px 10px",fontFamily:"inherit",fontSize:13,background:"var(--card)",outline:"none",color:"var(--ink)",maxWidth:148}}/>
            <label style={{display:"flex",alignItems:"center",gap:7,cursor:"pointer",fontSize:13.5,fontWeight:600,color:nu?"var(--clay)":"var(--ink-2)",userSelect:"none"}}>
              <span style={{width:18,height:18,borderRadius:5,border:"2px solid "+(nu?"var(--clay)":"var(--line-2)"),background:nu?"var(--clay-soft)":"transparent",display:"grid",placeItems:"center",transition:".12s"}}
                onClick={()=>setNu(v=>!v)}>
                {nu&&<Icon name="check" size={11} style={{color:"var(--clay)"}}/>}
              </span>
              Urgente
            </label>
          </div>
        </div>
      </div>
      <div className="card panel" style={{flex:1}}>
        <div className="phead"><div className="sec-title">Note di cantiere</div><Icon name="pin" size={17} style={{color:"var(--ocra)"}}/></div>
        <div className="list">
          {(c.note||[]).map(n=>(
            <div key={n.id} className="li" style={{alignItems:"flex-start"}}>
              <Icon name="pin" size={15} style={{color:"var(--ocra)",marginTop:2,flex:"0 0 auto"}}/>
              <div className="txt">
                <b style={{fontWeight:600,fontSize:13.5}}>{n.t}</b>
                <div className="dim" style={{fontSize:13,marginTop:2}}>{n.v}</div>
              </div>
              <button className="btn ghost sm" onClick={()=>delNote(n.id)} style={{color:"var(--ink-3)",fontSize:13,padding:"4px 7px"}}>✕</button>
            </div>
          ))}
          {(c.note||[]).length===0&&<div className="empty">Nessuna nota</div>}
        </div>
        <NoteAddForm onAdd={(t,v)=>{ onPatch(c.id,x=>({...x,note:[...(x.note||[]),{id:Date.now(),t,v}]})); }}/>
      </div>
    </div>
  );
}

/* ---- subtab: Impianti speciali ---- */
const IMPIANTI = [
  "EVAC",
  "Rivelazione fumi / IRAI",
  "Estrazione fumi",
  "Sprinkler",
  "NASPO",
  "Serrande tagliafuoco",
  "Serranda",
  "Infisso",
  "Allarme antintrusione",
  "Videosorveglianza",
  "Lastra A1",
  "Pareti REI",
  "Insegna",
  "Insegna a bandiera",
  "Impianto idrico",
  "Carotature",
];

function TabImpiantiSpeciali({c, onPatch}){
  const stato = c.impiantiStato||{};
  // default "no"; click toggles "no" ↔ "si"
  const toggle=(id)=>onPatch(c.id,x=>{
    const cur=(x.impiantiStato||{})[id];
    const next=cur==="si"?"no":"si";
    return {...x,impiantiStato:{...(x.impiantiStato||{}),[id]:next}};
  });
  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Impianti speciali</div>
        <div className="dim" style={{fontSize:12.5}}>Clicca per attivare/disattivare</div>
      </div>
      <div className="chk-grid">
        {IMPIANTI.map(imp=>{
          const v=stato[imp]||"no";
          return (
            <div key={imp} onClick={()=>toggle(imp)}
              style={{display:"flex",alignItems:"center",gap:12,padding:"12px 14px",border:"1.5px solid "+(v==="si"?"var(--primary)":"var(--line)"),borderRadius:10,cursor:"pointer",background:v==="si"?"var(--primary-soft)":"var(--card)",transition:".13s",userSelect:"none"}}>
              <div style={{flex:1,fontWeight:600,fontSize:13.5,color:v==="si"?"var(--ink)":"var(--ink3)"}}>{imp}</div>
              {v==="si"
                ? <span style={{background:"var(--primary)",color:"#fff",borderRadius:999,padding:"3px 11px",fontSize:12,fontWeight:700}}>Serve</span>
                : <span style={{background:"var(--card2)",color:"var(--ink3)",border:"1px solid var(--line2)",borderRadius:999,padding:"3px 11px",fontSize:12,fontWeight:600}}>Non serve</span>}
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---- subtab: Progetti ---- */
// mapping impianto → progetto aggiuntivo da richiedere
const IMPIANTO_PROGETTO = {
  "EVAC":                    "Progetto antincendio / EVAC",
  "Rivelazione fumi / IRAI": "Progetto antincendio / EVAC",
  "Estrazione fumi":         "Progetto estrazione fumi",
  "Sprinkler":               "Progetto antincendio / EVAC",
  "NASPO":                   "Progetto antincendio / EVAC",
};

function TabProgetti({c, onPatch}){
  const impiantiOn = Object.entries(c.impiantiStato||{}).filter(([,v])=>v==="si").map(([k])=>k);
  // deduplicated extra projects from impianti
  const extra = [...new Set(impiantiOn.map(k=>IMPIANTO_PROGETTO[k]).filter(Boolean))];

  // always show: Progetto Clima, Progetto Elettrico + extras
  const always = ["Progetto Clima","Progetto Elettrico"];
  const allProj = [...always, ...extra.filter(e=>!always.includes(e))];

  const stato  = c.progettiStato2||{};   // {[nome]: {origine:"cliente"|"progettista"|null, done:bool}}
  // mapping progetto → chiave in datiStato
  const PROJ_TO_DATO = {"Progetto Clima":"clima","Progetto Elettrico":"elettrico"};

  const setP=(nome,patch)=>onPatch(c.id,x=>{
    const newPS = {...(x.progettiStato2||{}),[nome]:{...(x.progettiStato2||{})[nome],...patch}};
    const datoKey = PROJ_TO_DATO[nome];
    // se viene impostata dataRicezione, spunta anche la voce corrispondente in datiStato
    const newDS = datoKey && patch.dataRicezione
      ? {...(x.datiStato||{}),[datoKey]:true}
      : (x.datiStato||{});
    return {...x, progettiStato2:newPS, datiStato:newDS};
  });

  const done=allProj.filter(p=>stato[p]?.done).length;
  const originColors={cliente:{bg:"var(--green-soft)",c:"#059669",label:"Cliente"},progettista:{bg:"var(--primary-soft)",c:"var(--primary)",label:"Progettista"},null:{bg:"var(--card2)",c:"var(--ink3)",label:"Origine?"}};

  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Progetti</div>
        <div style={{display:"flex",alignItems:"center",gap:10,minWidth:180}}>
          <div className="prog" style={{flex:1}}><i style={{width:allProj.length?(done/allProj.length*100)+"%":"0%"}}></i></div>
          <span className="badge green">{done}/{allProj.length}</span>
        </div>
      </div>
      {extra.length>0&&<div className="dim" style={{fontSize:12}}>
        <Icon name="info" size={13} style={{verticalAlign:"middle",marginRight:5}}/>
        {extra.length} progett{extra.length===1?"o aggiunto":"i aggiunti"} automaticamente dagli impianti attivi
      </div>}
      <div className="list">
        {allProj.map(nome=>{
          const s=stato[nome]||{};
          const orig=s.origine||null;
          const om=originColors[orig]||originColors[null];
          return (
            <div key={nome} className={"li"+(s.done?" done":"")} style={{gap:10,alignItems:"center"}}>
              <div className={"chk"+(s.done?" on":"")} onClick={()=>setP(nome,{done:!s.done})}>
                {s.done&&<Icon name="check" size={13}/>}
              </div>
              <div className="txt"><b style={{fontWeight:600}}>{nome}</b>
                <div style={{display:"flex",gap:12,marginTop:5,flexWrap:"wrap",alignItems:"center"}}>
                  {orig==="progettista"&&(
                    <input placeholder="Progettista / studio incaricato…"
                      value={s.progettista||""}
                      onChange={e=>setP(nome,{progettista:e.target.value})}
                      style={{border:"1px solid var(--line)",borderRadius:6,padding:"4px 9px",fontFamily:"var(--ff)",fontSize:12.5,fontWeight:600,background:"var(--primary-soft)",outline:"none",color:"var(--primary)",width:220,borderColor:"var(--primary)"}}/>
                  )}
                  <label style={{display:"flex",alignItems:"center",gap:5,fontSize:12,color:"var(--ink3)"}}>
                    <span>Richiesto il</span>
                    <input type="date" value={s.dataRichiesta||""} onChange={e=>setP(nome,{dataRichiesta:e.target.value})}
                      style={{border:"1px solid var(--line)",borderRadius:6,padding:"3px 7px",fontFamily:"var(--ff)",fontSize:12,background:"var(--card)",outline:"none",color:"var(--ink)",cursor:"pointer"}}/>
                  </label>
                  <label style={{display:"flex",alignItems:"center",gap:5,fontSize:12,color:"var(--ink3)"}}>
                    <span>Ricevuto il</span>
                    <input type="date" value={s.dataRicezione||""} onChange={e=>{const v=e.target.value;setP(nome,{dataRicezione:v,done:!!v});}}
                      style={{border:"1px solid var(--line)",borderRadius:6,padding:"3px 7px",fontFamily:"var(--ff)",fontSize:12,background:s.dataRicezione?"var(--green-soft)":"var(--card)",outline:"none",color:s.dataRicezione?"#059669":"var(--ink)",cursor:"pointer",borderColor:s.dataRicezione?"var(--green-border)":"var(--line)"}}/>
                  </label>
                </div>
              </div>
              {/* origine selector */}
              <div style={{display:"flex",gap:4,flexShrink:0}}>
                {["cliente","progettista"].map(o=>(
                  <button key={o} onClick={()=>setP(nome,{origine:orig===o?null:o})}
                    style={{padding:"3px 10px",borderRadius:999,fontSize:12,fontWeight:600,cursor:"pointer",border:"1.5px solid "+(orig===o?originColors[o].c:"var(--line)"),background:orig===o?originColors[o].bg:"var(--card)",color:orig===o?originColors[o].c:"var(--ink3)",transition:".12s"}}>
                    {o.charAt(0).toUpperCase()+o.slice(1)}
                  </button>
                ))}
              </div>
              {!s.done&&<span className="badge amber" style={{fontSize:10.5,whiteSpace:"nowrap"}}>in attesa</span>}
            </div>
          );
        })}
      </div>
      {extra.length===0&&impiantiOn.length===0&&(
        <div className="dim" style={{fontSize:12.5,marginTop:4}}>
          <Icon name="info" size={13} style={{verticalAlign:"middle",marginRight:5}}/>
          Attiva gli impianti nel tab "Impianti speciali" per aggiungere i progetti corrispondenti
        </div>
      )}
    </div>
  );
}

/* ---- subtab: Dati ---- */
const DATI_STANDARD = [
  {id:"date",       label:"Date chiave",                        optional:false},
  {id:"manuale",    label:"Manuale dei Vincoli",                optional:true,  note:"Verificare se richiesto per questa tipologia"},
  {id:"fluidi",     label:"Temperature fluidi impianto ad acqua", optional:true,  note:"Solo se impianto idronico"},
  {id:"arch",       label:"Progetto architettonico",            optional:false},
  {id:"dwg",        label:"DWG",                               optional:false},
  {id:"clima",      label:"Progetto Clima",                     optional:false},
  {id:"elettrico",  label:"Progetto Elettrico",                 optional:false},
  {id:"foto",       label:"Foto unità attuale",                 optional:false},
  {id:"magazzino",  label:"Progetto magazzino",                 optional:true},
  {id:"pilotage",   label:"Contatti Pilotage",                 optional:false},
];

function TabDati({c, onPatch}){
  // merge standard list with per-cantiere state
  const stato = c.datiStato||{};
  const toggle=(id)=>onPatch(c.id,x=>({...x,datiStato:{...(x.datiStato||{}),[id]:!(x.datiStato||{})[id]}}));
  const done = DATI_STANDARD.filter(d=>stato[d.id]).length;
  return (
    <div className="col fade">
      <div className="card panel">
        <div className="phead">
          <div className="sec-title">Dati</div>
          <div style={{display:"flex",alignItems:"center",gap:10,minWidth:180}}>
            <div className="prog" style={{flex:1}}><i style={{width:(done/DATI_STANDARD.length*100)+"%"}}></i></div>
            <span className="badge green">{done}/{DATI_STANDARD.length}</span>
          </div>
        </div>
        <div className="list">
          {DATI_STANDARD.map(d=>(
            <div key={d.id} className={"li"+(stato[d.id]?" done":"")}>
              <div className={"chk"+(stato[d.id]?" on":"")} onClick={()=>toggle(d.id)}>{stato[d.id]&&<Icon name="check" size={13}/>}</div>
              <div className="txt" style={{display:"flex",alignItems:"center",gap:10}}>
                <b style={{fontWeight:600}}>{d.label}</b>
                {d.note&&<span className="dim" style={{fontSize:12}}>{d.note}</span>}
              </div>
              {d.optional&&<span className="badge slate" style={{fontSize:10.5,marginLeft:"auto"}}>facoltativo</span>}
              {!stato[d.id]&&!d.optional&&<span className="badge amber" style={{fontSize:10.5}}>in attesa</span>}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ---- subtab: Documenti cantiere ---- */
function TabDocumenti({c, onPatch}){
  const [newT,setNewT]=React.useState(""); const [newN,setNewN]=React.useState("");
  const docs = c.documenti||[];
  const done = docs.filter(d=>d.done).length;
  const toggle=(id)=>onPatch(c.id,x=>({...x,documenti:(x.documenti||[]).map(d=>d.id===id?{...d,done:!d.done}:d)}));
  const add=()=>{
    if(!newT.trim())return;
    onPatch(c.id,x=>({...x,documenti:[...(x.documenti||[]),{id:Date.now(),t:newT,done:false,note:newN}]}));
    setNewT(""); setNewN("");
  };
  const del=(id)=>onPatch(c.id,x=>({...x,documenti:(x.documenti||[]).filter(d=>d.id!==id)}));

  // group: da fare / completati
  const aperti=docs.filter(d=>!d.done);
  const completati=docs.filter(d=>d.done);

  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Documenti di cantiere</div>
        <div style={{display:"flex",alignItems:"center",gap:12,minWidth:200}}>
          <div className="prog" style={{flex:1}}><i style={{width:docs.length?(done/docs.length*100)+"%":"0%"}}></i></div>
          <span className="badge olive">{done}/{docs.length}</span>
        </div>
      </div>

      {aperti.length>0&&<>
        <div className="eyebrow" style={{marginBottom:4}}>Da produrre / ricevere</div>
        <div className="list">
          {aperti.map(d=>(
            <div key={d.id} className="li">
              <div className="chk due" onClick={()=>toggle(d.id)}></div>
              <div className="txt">
                <b style={{fontWeight:600}}>{d.t}</b>
                {d.note&&<div className="dim" style={{fontSize:12.5,marginTop:2}}>{d.note}</div>}
              </div>
              <button className="btn ghost sm" onClick={()=>del(d.id)} style={{color:"var(--ink-3)",fontSize:13,padding:"4px 7px"}}>✕</button>
            </div>
          ))}
        </div>
      </>}

      {completati.length>0&&<>
        <div className="eyebrow" style={{marginTop:8,marginBottom:4}}>Completati</div>
        <div className="list">
          {completati.map(d=>(
            <div key={d.id} className="li done">
              <div className="chk on" onClick={()=>toggle(d.id)}><Icon name="check" size={13}/></div>
              <div className="txt">
                {d.t}
                {d.note&&<div className="dim" style={{fontSize:12.5,marginTop:2}}>{d.note}</div>}
              </div>
              <button className="btn ghost sm" onClick={()=>del(d.id)} style={{color:"var(--ink-3)",fontSize:13,padding:"4px 7px"}}>✕</button>
            </div>
          ))}
        </div>
      </>}

      {docs.length===0&&<div className="empty">Nessun documento ancora. Aggiungine uno qui sotto.</div>}

      <hr className="divider"/>
      <div className="add-row">
        <input placeholder="Documento (es. DICO impianto, POS ditta…)" value={newT} onChange={e=>setNewT(e.target.value)} onKeyDown={e=>e.key==="Enter"&&add()}/>
        <input placeholder="Note (es. ditta, riferimento)" value={newN} onChange={e=>setNewN(e.target.value)} onKeyDown={e=>e.key==="Enter"&&add()} style={{maxWidth:220}}/>
        <button className="btn primary" onClick={add}><Icon name="plus" size={15}/> Aggiungi</button>
      </div>
    </div>
  );
}

/* ---- subtab: Diario cantiere ---- */
function TabDiario({c, onPatch}){
  const [t,setT]=React.useState(""); const [v,setV]=React.useState("");
  const diario=(c.diario||[]).slice().sort((a,b)=>b.ts-a.ts);

  const todayInfo=()=>{
    const d=new Date();
    return{ts:d.getTime(),
      dateLabel:d.toLocaleDateString('it-IT',{day:'2-digit',month:'long',year:'numeric'}),
      dayLabel:d.toLocaleDateString('it-IT',{weekday:'long'})};
  };

  const add=()=>{
    if(!v.trim())return;
    const{ts,dateLabel,dayLabel}=todayInfo();
    onPatch(c.id,x=>({...x,diario:[...(x.diario||[]),{id:Date.now(),ts,dateLabel,dayLabel,t:t.trim()||null,v:v.trim()}]}));
    setT("");setV("");
  };
  const del=(id)=>onPatch(c.id,x=>({...x,diario:(x.diario||[]).filter(e=>e.id!==id)}));
  const capFirst=s=>s?s.charAt(0).toUpperCase()+s.slice(1):s;

  return (
    <div className="card panel fade">
      <div className="phead">
        <div className="sec-title">Diario cantiere</div>
        <span className="badge">{diario.length} {diario.length===1?"voce":"voci"}</span>
      </div>
      {diario.length===0&&<div className="empty">Nessuna voce ancora. Tieni traccia di eventi, problemi o decisioni.</div>}
      <div className="col" style={{gap:8}}>
        {diario.map(e=>(
          <div key={e.id} style={{display:'flex',gap:14,alignItems:'flex-start',padding:'12px 14px',background:'var(--card2)',borderRadius:10,border:'1px solid var(--line)'}}>
            <div style={{flex:'0 0 auto',minWidth:72,textAlign:'center'}}>
              <div style={{fontSize:10.5,fontWeight:700,textTransform:'capitalize',color:'var(--ink3)',letterSpacing:'.02em',marginBottom:2}}>{capFirst(e.dayLabel)}</div>
              <div style={{fontSize:12,fontWeight:600,color:'var(--ink2)',lineHeight:1.4}}>{e.dateLabel}</div>
            </div>
            <div style={{flex:1,minWidth:0}}>
              {e.t&&<div style={{fontWeight:700,fontSize:13.5,marginBottom:4}}>{e.t}</div>}
              <div style={{fontSize:13.5,color:'var(--ink2)',lineHeight:1.55,whiteSpace:'pre-wrap'}}>{e.v}</div>
            </div>
            <button className="btn ghost sm" onClick={()=>del(e.id)} style={{color:'var(--ink3)',padding:'4px 7px',flexShrink:0}}>✕</button>
          </div>
        ))}
      </div>
      <hr className="divider"/>
      <div style={{display:'flex',flexDirection:'column',gap:8}}>
        <input placeholder="Titolo voce (opzionale — es. Problema tracce, Visita DL, Accordo con ditta…)"
          value={t} onChange={e=>setT(e.target.value)}
          style={{border:'1px solid var(--line)',borderRadius:'var(--r-sm)',padding:'9px 12px',fontFamily:'var(--ff)',fontSize:13.5,background:'var(--card)',outline:'none',color:'var(--ink)'}}/>
        <textarea placeholder="Descrivi l'evento, la decisione o il problema…"
          value={v} onChange={e=>setV(e.target.value)} rows={3}
          onKeyDown={e=>{if((e.ctrlKey||e.metaKey)&&e.key==='Enter')add();}}
          style={{border:'1px solid var(--line)',borderRadius:'var(--r-sm)',padding:'9px 12px',fontFamily:'var(--ff)',fontSize:13.5,background:'var(--card)',outline:'none',color:'var(--ink)',resize:'vertical',lineHeight:1.5}}/>
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center'}}>
          <span style={{fontSize:12,color:'var(--ink3)'}}>La data viene salvata automaticamente · Ctrl+Enter per aggiungere</span>
          <button className="btn primary" onClick={add} disabled={!v.trim()} style={{opacity:v.trim()?1:.5}}>
            <Icon name="plus" size={15}/> Aggiungi voce
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---- subtab: Calendario appuntamenti ---- */
function TabCalendario({c, onPatch}){
  const [cur,setCur]=React.useState(()=>{const d=new Date();d.setDate(1);return d;});
  const [newT,setNewT]=React.useState(""); const [newN,setNewN]=React.useState(""); const [newD,setNewD]=React.useState(""); const [newOra,setNewOra]=React.useState("");

  // mini calendar
  const y=cur.getFullYear(), m=cur.getMonth();
  const firstDow=new Date(y,m,1).getDay();
  const startOff=firstDow===0?6:firstDow-1; // Mon-based
  const daysInMonth=new Date(y,m+1,0).getDate();
  const cells=Array.from({length:Math.ceil((startOff+daysInMonth)/7)*7},(_,i)=>{
    const dn=i-startOff+1; return (dn>=1&&dn<=daysInMonth)?dn:null;
  });
  const today=new Date(); today.setHours(0,0,0,0);
  const mLabel=cur.toLocaleDateString('it-IT',{month:'long',year:'numeric'});
  const prevM=()=>{const d=new Date(cur);d.setMonth(d.getMonth()-1);setCur(d);};
  const nextM=()=>{const d=new Date(cur);d.setMonth(d.getMonth()+1);setCur(d);};

  // collect all events: appuntamenti + consegne importanti
  const allEventi=[
    ...(c.appuntamenti||[]).map(a=>({...a,kind:"appuntamento"})),
    ...(c.consegne||[]).filter(d=>d.stato!=="consegnato").map(d=>({id:'c'+d.id,t:d.cosa,data:d.data,note:d.forn,kind:"consegna"})),
  ].sort((a,b)=>a.data.days-b.data.days);

  // days that have events this month, split by kind
  const appDays=new Set(), consDays=new Set();
  allEventi.forEach(e=>{
    const d=new Date(e.data.ts);
    if(d.getFullYear()===y&&d.getMonth()===m){
      if(e.kind==="appuntamento") appDays.add(d.getDate());
      if(e.kind==="consegna") consDays.add(d.getDate());
    }
  });

  const kindMeta={consegna:{col:"var(--orange)",bg:"var(--orange-soft)"},appuntamento:{col:"var(--slate)",bg:"var(--slate-soft)"}};

  const addApp=()=>{
    if(!newT.trim()||!newD) return;
    const p=newD.split("-"); const days=Math.round((new Date(+p[0],+p[1]-1,+p[2])-today)/86400000);
    const label=new Date(+p[0],+p[1]-1,+p[2]).toLocaleDateString('it-IT',{day:'2-digit',month:'short'});
    onPatch(c.id,x=>({...x,appuntamenti:[...(x.appuntamenti||[]),{id:Date.now(),t:newT,data:{days,label},note:newN,ora:newOra||null}]}));
    setNewT("");setNewN("");setNewD("");setNewOra("");
  };
  const delApp=(id)=>onPatch(c.id,x=>({...x,appuntamenti:(x.appuntamenti||[]).filter(a=>a.id!==id)}));

  return (
    <div className="row fade" style={{alignItems:"flex-start",gap:18}}>
      {/* mini calendar */}
      <div className="card" style={{flex:"0 0 260px",padding:16}}>
        <div className="between" style={{marginBottom:12}}>
          <button className="btn ghost sm" onClick={prevM}>‹</button>
          <span style={{fontFamily:"var(--fd)",fontWeight:700,fontSize:16,textTransform:"capitalize"}}>{mLabel}</span>
          <button className="btn ghost sm" onClick={nextM}>›</button>
        </div>
        <div style={{display:"grid",gridTemplateColumns:"repeat(7,1fr)",gap:2,textAlign:"center"}}>
          {["L","M","M","G","V","S","D"].map((d,i)=><div key={i} style={{fontSize:11,fontWeight:700,color:"var(--ink-3)",padding:"4px 0"}}>{d}</div>)}
          {cells.map((dn,i)=>{
            if(!dn) return <div key={i}></div>;
            const isT=new Date(y,m,dn).getTime()===today.getTime();
            const hasApp=appDays.has(dn), hasCons=consDays.has(dn);
            const dotAlpha=isT?"rgba(255,255,255,0.8)":null;
            return (
              <div key={i} style={{padding:"5px 3px",borderRadius:8,background:isT?"var(--terra)":"transparent",color:isT?"#fff":"var(--ink)",fontWeight:isT?700:400,fontSize:13.5,position:"relative",cursor:"default"}}>
                {dn}
                {(hasApp||hasCons)&&<span style={{position:"absolute",bottom:2,left:"50%",transform:"translateX(-50%)",display:"flex",gap:2}}>
                  {hasApp&&<span style={{width:4,height:4,borderRadius:"50%",background:dotAlpha||"var(--ink-3)",display:"inline-block"}}></span>}
                  {hasCons&&<span style={{width:4,height:4,borderRadius:"50%",background:dotAlpha||"var(--orange)",display:"inline-block"}}></span>}
                </span>}
              </div>
            );
          })}
        </div>
      </div>

      {/* agenda list */}
      <div className="col" style={{flex:1}}>
        <div className="card panel">
          <div className="phead">
            <div className="sec-title">Agenda appuntamenti</div>
            <button className="btn sm primary" onClick={()=>document.getElementById('cal-add').scrollIntoView&&document.getElementById('cal-add').focus()}><Icon name="plus" size={14}/> Aggiungi</button>
          </div>
          <div className="list">
            {allEventi.length===0&&<div className="empty">Nessun appuntamento</div>}
            {allEventi.map(e=>{
              const m2=kindMeta[e.kind]||{col:"var(--ink-2)",bg:"var(--paper-2)"};
              return (
                <div key={e.id} className="li" style={{alignItems:"center"}}>
                  <div style={{flex:"0 0 54px",textAlign:"center",borderRadius:10,background:m2.bg,color:m2.col,padding:"5px 4px",lineHeight:1.1}}>
                    <div style={{fontFamily:"var(--fd)",fontWeight:700,fontSize:19}}>{e.data.days===0?"oggi":e.data.days<0?Math.abs(e.data.days):e.data.days}</div>
                    {e.data.days!==0&&<div style={{fontSize:10,fontWeight:500}}>{e.data.days<0?"gg fa":"giorni"}</div>}
                  </div>
                  <div className="txt" style={{marginLeft:4}}>
                    <b style={{fontWeight:600}}>{e.t}</b>
                    <div className="dim" style={{fontSize:12,marginTop:2,display:"flex",gap:8,alignItems:"center"}}>
                      <span style={{background:m2.bg,color:m2.col,borderRadius:999,padding:"1px 7px",fontSize:11,fontWeight:600}}>{e.kind}</span>
                      {e.note&&<span>{e.note}</span>}
                      <span>{e.data.label}{e.ora&&<> · <b style={{fontWeight:600}}>{e.ora}</b></>}</span>
                    </div>
                  </div>
                  {e.kind==="appuntamento"&&<button className="btn ghost sm" onClick={()=>delApp(e.id)} style={{color:"var(--ink-3)",fontSize:13}}>✕</button>}
                </div>
              );
            })}
          </div>
          <hr className="divider"/>
          <div className="add-row">
            <input id="cal-add" placeholder="Titolo appuntamento…" value={newT} onChange={e=>setNewT(e.target.value)} onKeyDown={e=>e.key==="Enter"&&addApp()}/>
            <input placeholder="Note (es. ditta, referente)" value={newN} onChange={e=>setNewN(e.target.value)} style={{maxWidth:180}}/>
            <input type="date" value={newD} onChange={e=>setNewD(e.target.value)} style={{maxWidth:150,border:"1px solid var(--line-2)",borderRadius:10,padding:"9px 11px",fontFamily:"inherit",fontSize:14,background:"var(--card)",outline:"none"}}/>
            <input type="time" value={newOra} onChange={e=>setNewOra(e.target.value)} placeholder="Ora" style={{maxWidth:110,border:"1px solid var(--line-2)",borderRadius:10,padding:"9px 11px",fontFamily:"inherit",fontSize:14,background:"var(--card)",outline:"none"}}/>
            <button className="btn primary" onClick={addApp}><Icon name="plus" size={15}/></button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---- subtab: Panoramica (cantiere attivo) ---- */
function TabPanoramica({c, onPatch}){
  const today = new Date(); today.setHours(0,0,0,0);
  const dow = today.getDay();
  const daysToMon = dow===0?6:dow-1;
  const monday = new Date(today); monday.setDate(today.getDate()-daysToMon);
  const weekDays = Array.from({length:7},(_,i)=>{const d=new Date(monday);d.setDate(monday.getDate()+i);return d;});
  const dowLabels=["Lun","Mar","Mer","Gio","Ven","Sab","Dom"];
  const fmt=d=>d.toLocaleDateString('it-IT',{day:'2-digit',month:'short'});
  const isToday=d=>{const t=new Date();return d.getDate()===t.getDate()&&d.getMonth()===t.getMonth();};

  // ditte presenti questa settimana: da cronoDays reali
  const weekISO=weekDays.map(d=>d.toISOString().slice(0,10));
  const cronoDays=c.cronoDays||{};
  const ditteAttive=(()=>{
    const ditte=c.ditte||[];
    const allLav=[...new Set(ditte.flatMap(d=>d.lavorazioni||(d.lavoro?[d.lavoro]:[])))];
    return allLav.map((lav,i)=>{
      const ditta=ditte.find(d=>(d.lavorazioni||[]).includes(lav));
      const days=cronoDays[lav]||[];
      const giorni=weekISO.map((iso,idx)=>days.includes(iso)?idx:-1).filter(x=>x>=0);
      return{id:i,nome:ditta?.nome||'—',lavoro:lav,giorni};
    }).filter(d=>d.giorni.length>0);
  })();

  // prossime consegne + appuntamenti entro 7 gg (no urgenti/todo)
  const eventi=[];
  (c.consegne||[]).forEach(d=>{if(d.data.days>=0&&d.data.days<=7&&d.stato!=="consegnato") eventi.push({id:'c'+d.id,nome:d.cosa,sub:d.forn,days:d.data.days,label:d.data.label,kind:"consegna"});});
  (c.appuntamenti||[]).forEach(a=>{if(a.data.days>=0&&a.data.days<=7) eventi.push({id:'a'+a.id,nome:a.t,sub:a.note,days:a.data.days,label:a.data.label,ora:a.ora||null,kind:"appuntamento"});});
  eventi.sort((a,b)=>a.days-b.days);
  const kindMeta={consegna:{col:"var(--terra)",bg:"var(--terra-soft)",label:"consegna"},appuntamento:{col:"var(--slate)",bg:"var(--slate-soft)",label:"appuntamento"}};

  const urgenti=(c.todos||[]).filter(t=>t.urgent&&!t.done);
  const toggleTodo=(tid)=>onPatch(c.id,x=>({...x,todos:x.todos.map(t=>t.id===tid?{...t,done:!t.done}:t)}));

  return (
    <div className="col fade">
      {/* 1 — prossime consegne/appuntamenti */}
      <div className="card panel">
        <div className="phead">
          <div className="eyebrow" style={{letterSpacing:".09em"}}>Prossime consegne e appuntamenti — entro 7 giorni</div>
        </div>
        {eventi.length===0
          ? <div className="empty">Niente in scadenza nei prossimi 7 giorni</div>
          : <div className="list">{eventi.map(e=>{
              const m=kindMeta[e.kind]||kindMeta.consegna;
              return (
                <div key={e.id} className="li" style={{alignItems:"center"}}>
                  <span style={{width:10,height:10,borderRadius:"50%",background:m.col,flex:"0 0 10px",marginTop:0}}></span>
                  <div className="txt">
                    <b style={{fontWeight:600}}>{e.nome}</b>
                    {e.sub&&<div className="dim" style={{fontSize:12.5}}>{e.sub}</div>}
                  </div>
                  <div style={{textAlign:"right",fontSize:13,fontWeight:600,whiteSpace:"nowrap",color:m.col}}>
                    {e.label}{e.ora&&<> · {e.ora}</>} · {fmtDays(e.days)}
                  </div>
                </div>
              );
            })}</div>}
      </div>

      {/* 2 — cose da fare urgenti */}
      <div className="card panel">
        <div className="phead">
          <div className="eyebrow" style={{letterSpacing:".09em"}}>Cose da fare — urgenti</div>
          <span className="badge clay">{urgenti.length}</span>
        </div>
        <div className="list">
          {urgenti.length===0&&<div className="empty">Nessuna urgenza 🎉</div>}
          {urgenti.map(t=>(
            <div key={t.id} className="li">
              <div className={"chk due"} onClick={()=>toggleTodo(t.id)}></div>
              <div className="txt"><b style={{fontWeight:600}}>{t.t}</b></div>
              {t.due&&<span className={"badge"+(t.due.days<=3?" clay":"")} style={{fontSize:11,marginLeft:"auto",alignSelf:"center",whiteSpace:"nowrap"}}>entro {t.due.label}</span>}
            </div>
          ))}
        </div>
      </div>

      {/* 3 — ditte presenti settimana */}
      <div className="card panel">
        <div className="eyebrow" style={{letterSpacing:".09em",marginBottom:12}}>Ditte presenti questa settimana</div>
        <div style={{overflowX:"auto"}}>
          <table className="ditte-cal">
            <thead><tr>
              <th style={{width:160}}>Ditta</th>
              {weekDays.map((d,i)=>(
                <th key={i} className={isToday(d)?"today":""}>
                  {dowLabels[i]}<br/><span className="dim" style={{fontSize:11,fontWeight:400}}>{fmt(d)}</span>
                </th>
              ))}
            </tr></thead>
            <tbody>{(ditteAttive).map(d=>(
              <tr key={d.id}>
                <td><b style={{fontWeight:600,fontSize:13.5}}>{d.nome}</b><div className="dim" style={{fontSize:11.5}}>{d.lavoro}</div></td>
                {weekDays.map((_,i)=>(
                  <td key={i} className={"cal-cell"+(isToday(weekDays[i])?" today":"")} style={{textAlign:"center"}}>
                    {d.giorni.includes(i)&&<span className="cal-chk">✓</span>}
                  </td>
                ))}
              </tr>
            ))}</tbody>
          </table>
        </div>
      </div>

      {/* 4 — cronoprogramma */}
      {(()=>{
        const cronoData=calcCronoProgress(c);
        if(!cronoData.length)return null;
        return (
          <div className="card panel">
            <div className="eyebrow" style={{letterSpacing:".09em",marginBottom:12}}>Avanzamento generale</div>
            <div className="gantt">
              {cronoData.map((g,i)=>{
                const barC=g.pct===100?"var(--green)":g.pct>0?"var(--primary)":"var(--line2)";
                const valC=g.pct===100?"var(--green)":g.pct>0?"var(--primary)":"var(--ink3)";
                const sub=`${g.total} gg${g.ditta?' · '+g.ditta.nome:''}`;
                return (
                  <div key={i} className="grow-item">
                    <div className="gname">{g.lav}<small>{sub}</small></div>
                    <div className="track"><i style={{width:Math.max(g.pct,g.pct>0?3:0)+"%",background:barC}}></i></div>
                    <div style={{textAlign:"right",fontWeight:700,fontSize:13,color:valC}}>{g.pct}%</div>
                  </div>
                );
              })}
            </div>
          </div>
        );
      })()}
    </div>
  );
}

/* ---- PrintSummary — riepilogo A4 per stampa/PDF ---- */
function PrintSummary({c}){
  const nf=c.info||{};
  const today=new Date();
  const localISO=d=>`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
  const todayISO=localISO(today);
  const printDate=`${String(today.getDate()).padStart(2,'0')}/${String(today.getMonth()+1).padStart(2,'0')}`;

  // Prossimi 7 giorni
  const DOW=['Dom','Lun','Mar','Mer','Gio','Ven','Sab'];
  const next7=Array.from({length:7},(_,i)=>{
    const d=new Date(today); d.setDate(d.getDate()+i);
    return{iso:localISO(d),d,dow:d.getDay(),label:`${d.getDate()}/${d.getMonth()+1}`};
  });

  // Ditte/lavorazioni attive nei prossimi 7 giorni (da cronoDays)
  const cronoDays=c.cronoDays||{};
  const ditte=c.ditte||[];
  const allLav=[...new Set(ditte.flatMap(d=>d.lavorazioni||(d.lavoro?[d.lavoro]:[])))];
  const settimana=allLav.map(lav=>{
    const ditta=ditte.find(d=>(d.lavorazioni||[]).includes(lav));
    const days=cronoDays[lav]||[];
    const giorni=next7.map(n=>days.includes(n.iso));
    return{lav,dittaNome:ditta?.nome||'—',giorni,hasAny:giorni.some(Boolean)};
  }).filter(r=>r.hasAny);

  // Consegne prossimi 7 giorni
  const consegne7=(c.consegne||[])
    .filter(d=>d.stato!=="consegnato"&&d.data.days>=0&&d.data.days<=7)
    .sort((a,b)=>a.data.days-b.data.days);

  // Appuntamenti prossimi 7 giorni
  const app7=(c.appuntamenti||[])
    .filter(a=>a.data.days>=0&&a.data.days<=7)
    .sort((a,b)=>a.data.days-b.data.days);

  // Todos: urgenti prima, poi per scadenza
  const todos=(c.todos||[]).filter(t=>!t.done).sort((a,b)=>{
    if(a.urgent&&!b.urgent)return -1;
    if(!a.urgent&&b.urgent)return 1;
    return(a.due?.days??999)-(b.due?.days??999);
  });

  const note=c.note||[];

  // Superfici
  const parseM2=s=>{if(!s)return null;const n=parseFloat(String(s).replace(',','.'));return isNaN(n)?null:n;};
  const vv=parseM2(nf.supVendita),vm=parseM2(nf.supMagazzino);
  const totale=vv!==null&&vm!==null?(vv+vm)+' m²':null;

  // Stili condivisi
  const secTitle={fontSize:8.5,fontWeight:700,textTransform:'uppercase',letterSpacing:'.09em',
    color:'#555',borderBottom:'1.5px solid #d1d5db',paddingBottom:3,marginBottom:5,marginTop:13};
  const tdBase={padding:'3px 0',verticalAlign:'middle',fontSize:10.5,borderBottom:'1px solid #f3f4f6'};
  const chkStyle={width:11,height:11,borderRadius:2.5,border:'1.5px solid #ccc',display:'inline-block',verticalAlign:'middle',flexShrink:0};
  const tag=(bg,col,txt)=><span style={{fontSize:8,fontWeight:700,background:bg,color:col,borderRadius:3,padding:'1px 5px',whiteSpace:'nowrap'}}>{txt}</span>;

  return (
    <div className="print-summary">

      {/* ── Header (2 righe) ── */}
      <div style={{marginBottom:10,paddingBottom:8,borderBottom:'2px solid #111'}}>
        <div style={{fontSize:18,fontWeight:700,lineHeight:1.2,color:'#111'}}>
          {c.insegna||c.nome}
          <span style={{fontWeight:400,fontSize:13,color:'#777',marginLeft:10}}>— {printDate}</span>
        </div>
        {(nf.supVendita||nf.supMagazzino)&&(
          <div style={{fontSize:11,color:'#333',marginTop:5,display:'flex',gap:16,flexWrap:'wrap'}}>
            {nf.supVendita&&<span><span style={{color:'#888',marginRight:4}}>Area vendita</span><b style={{fontWeight:700}}>{nf.supVendita}</b></span>}
            {nf.supMagazzino&&<span><span style={{color:'#888',marginRight:4}}>Magazzino</span><b style={{fontWeight:700}}>{nf.supMagazzino}</b></span>}
            {totale&&<span><span style={{color:'#888',marginRight:4}}>Totale</span><b style={{fontWeight:700}}>{totale}</b></span>}
          </div>
        )}
      </div>

      {/* ── Crono: ditte in cantiere prossimi 7 giorni ── */}
      {settimana.length>0&&(<>
        <div style={secTitle}>Ditte in cantiere — prossimi 7 giorni</div>
        <table style={{width:'100%',borderCollapse:'collapse',fontSize:10}}>
          <thead>
            <tr>
              <th style={{textAlign:'left',padding:'2px 6px 4px 0',fontWeight:600,color:'#555',fontSize:8.5,width:'30%'}}>Lavorazione · Ditta</th>
              {next7.map(n=>(
                <th key={n.iso} style={{textAlign:'center',padding:'0 2px 4px',fontWeight:600,fontSize:8.5,width:`${70/7}%`,color:'#666'}}>
                  <div style={{fontWeight:600}}>{DOW[n.dow].slice(0,3)}</div>
                  <div style={{fontWeight:700,color:'#333'}}>{n.label}</div>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {settimana.map(r=>(
              <tr key={r.lav} style={{borderTop:'1px solid #f3f4f6'}}>
                <td style={{padding:'4px 6px 4px 0',verticalAlign:'middle'}}>
                  <div style={{fontWeight:600,fontSize:10.5}}>{r.lav}</div>
                  <div style={{fontSize:8.5,color:'#888'}}>{r.dittaNome}</div>
                </td>
                {r.giorni.map((on,i)=>(
                  <td key={i} style={{textAlign:'center',padding:'3px 2px',verticalAlign:'middle'}}>
                    {on&&<div style={{width:16,height:16,borderRadius:4,border:`2px solid ${c.color}`,margin:'0 auto',display:'flex',alignItems:'center',justifyContent:'center'}}>
                      <svg width="10" height="10" viewBox="0 0 12 12" fill="none"><path d="M2 6l3 3 5-5" stroke={c.color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    </div>}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </>)}

      {/* ── Consegne e appuntamenti prossimi 7 giorni ── */}
      {(consegne7.length>0||app7.length>0)&&(<>
        <div style={secTitle}>Consegne e appuntamenti — prossimi 7 giorni</div>
        <table style={{width:'100%',borderCollapse:'collapse'}}>
          <tbody>
            {consegne7.map(d=>(
              <tr key={'c'+d.id}>
                <td style={{...tdBase,width:'45%',paddingRight:8}}>
                  <span style={{fontWeight:600,fontSize:10.5}}>{d.cosa}</span>
                  {d.forn!=='—'&&<span style={{color:'#777',fontSize:9.5,marginLeft:6}}>{d.forn}</span>}
                </td>
                <td style={{...tdBase,fontSize:10,color:'#555',paddingRight:8}}>{d.data.label}{d.data.days===0?' — oggi':d.data.days===1?' — domani':''}</td>
                <td style={{...tdBase,textAlign:'right'}}>{tag('#fff7ed','#c2410c','consegna')}</td>
              </tr>
            ))}
            {app7.map(a=>(
              <tr key={'a'+a.id}>
                <td style={{...tdBase,width:'45%',paddingRight:8}}>
                  <span style={{fontWeight:600,fontSize:10.5}}>{a.t}</span>
                  {a.note&&<span style={{color:'#777',fontSize:9.5,marginLeft:6}}>{a.note}</span>}
                </td>
                <td style={{...tdBase,fontSize:10,color:'#555',paddingRight:8}}>{a.data.label}{a.ora?` · ${a.ora}`:''}{a.data.days===0?' — oggi':a.data.days===1?' — domani':''}</td>
                <td style={{...tdBase,textAlign:'right'}}>{tag('#f1f5f9','#475569','appuntamento')}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </>)}

      {/* ── Cose da fare ── */}
      {todos.length>0&&(<>
        <div style={secTitle}>Cose da fare — {todos.filter(t=>t.urgent).length} urgenti · {todos.length} totali</div>
        <table style={{width:'100%',borderCollapse:'collapse'}}>
          <tbody>
            {todos.map(t=>(
              <tr key={t.id}>
                <td style={{...tdBase,width:18,paddingRight:7}}>
                  <span style={{...chkStyle,borderColor:t.urgent?'#ef4444':'#ccc'}}></span>
                </td>
                <td style={{...tdBase,fontWeight:t.urgent?700:400,color:t.urgent?'#111':'#333'}}>
                  {t.t}
                  {t.urgent&&<span style={{fontSize:8,fontWeight:700,background:'#fef2f2',color:'#ef4444',borderRadius:3,padding:'1px 5px',marginLeft:6}}>urgente</span>}
                </td>
                <td style={{...tdBase,textAlign:'right',fontSize:9.5,color:'#888',whiteSpace:'nowrap'}}>
                  {t.due?`entro ${t.due.label}`:''}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </>)}

      {/* ── Note di cantiere ── */}
      {note.length>0&&(<>
        <div style={secTitle}>Note di cantiere</div>
        {note.map(n=>(
          <div key={n.id} style={{padding:'4px 0',borderBottom:'1px solid #f3f4f6',fontSize:10.5}}>
            <span style={{fontWeight:700}}>{n.t}</span>
            {n.v&&<span style={{color:'#555',marginLeft:8}}>{n.v}</span>}
          </div>
        ))}
      </>)}

    </div>
  );
}

/* ---- EditableDate — click-to-edit date field (dd/mm/yyyy) ---- */
function EditableDate({value, onSave}){
  const [editing,setEditing]=React.useState(false);
  const toISO=s=>{if(!s||s==='—')return'';const p=s.split('/');return p.length===3?`${p[2]}-${p[1]}-${p[0]}`:'';}
  const toIT=iso=>{if(!iso)return'';const p=iso.split('-');return`${p[2]}/${p[1]}/${p[0]}`;}
  const baseStyle={fontFamily:'var(--ff)',fontWeight:700,fontSize:15,border:'none',borderBottom:'2px solid var(--primary)',background:'none',outline:'none',color:'var(--ink)',padding:'2px 0',width:120};
  if(editing) return <input type="date" autoFocus defaultValue={toISO(value)}
    onBlur={e=>{setEditing(false);if(e.target.value)onSave(toIT(e.target.value));}}
    onKeyDown={e=>{if(e.key==='Escape')setEditing(false);if(e.key==='Enter')e.target.blur();}}
    style={baseStyle}/>;
  return <span onClick={()=>setEditing(true)} title="Clicca per modificare"
    style={{fontWeight:700,fontSize:15,cursor:'text',borderBottom:'1px dashed var(--ink-3)',color:value&&value!=='—'?'var(--ink)':'var(--ink3)'}}>
    {value||'—'}
  </span>;
}

/* ---- EditableInline — click-to-edit span ---- */
function EditableInline({value, placeholder="—", onSave, inputStyle={}, spanStyle={}}){
  const [editing,setEditing]=React.useState(false);
  const [v,setV]=React.useState(value);
  React.useEffect(()=>setV(value),[value]);
  if(editing) return <input autoFocus value={v}
    onChange={e=>setV(e.target.value)}
    onBlur={()=>{setEditing(false);onSave(v);}}
    onKeyDown={e=>{if(e.key==="Enter"){setEditing(false);onSave(v);}if(e.key==="Escape")setEditing(false);}}
    style={inputStyle}/>;
  return <span onClick={()=>setEditing(true)} title="Clicca per modificare"
    style={{...spanStyle}}>{value||<span style={{color:"var(--ink3)",fontWeight:400,fontSize:14}}>{placeholder}</span>}</span>;
}

/* ---- Detail shell ---- */
const DetailView = ({data, currentId, onOpen, onBack, onPatch, onDelete, onArchive, rubrica, onSaveDitta, onAddLavorazione}) => {
  const c = data.cantieri.find(x=>x.id===currentId);
  const [tab,setTab]=useState(()=> c?.fase==="cantiere" ? "panoramica" : "dati");
  React.useEffect(()=>{ setTab(c?.fase==="cantiere" ? "panoramica" : "dati"); },[currentId]);
  if(!c) return null;

  const cantiereTabs = [
    {id:"panoramica",  label:"Panoramica",    icon:"eye"},
    {id:"diario",      label:"Diario",        icon:"chat"},
    {id:"calendario", label:"Calendario",    icon:"cal"},
    {id:"crono",      label:"Cronoprogramma", icon:"chart"},
    {id:"consegne",   label:"Consegne",       icon:"truck", cnt:c.consegne.filter(d=>d.stato!=="consegnato").length||null},
    {id:"todo",       label:"To-do & Note",   icon:"check", cnt:c.todos.filter(t=>!t.done).length||null},
    {id:"documenti",  label:"Documenti",     icon:"doc", cnt:(c.documenti||[]).filter(d=>!d.done).length||null},
  ];
  const prevTabs = [
    {id:"dati",           label:"Dati",               icon:"folder"},
    {id:"sopralluogo",    label:"Sopralluogo",         icon:"list", cnt:c.sopralluogo.filter(s=>s.done).length+"/"+c.sopralluogo.length},
    {id:"impianti",      label:"Impianti speciali",   icon:"settings"},
    {id:"progetti",      label:"Progetti",            icon:"doc"},
    {id:"preventivi",    label:"Preventivi",          icon:"chart", cnt:c.preventivi.filter(p=>p.stato==="attesa").length||null},
  ];
  const tabs = c.fase==="cantiere" ? cantiereTabs : prevTabs;

  const dl2=c.nextDeadline;
  const dlC=dl2.gara?"var(--red)":dl2.in.days<=3?"var(--red)":dl2.in.days<=7?"var(--amber)":"var(--green)";
  const dlBg=dl2.gara?"var(--red-soft)":dl2.in.days<=3?"var(--red-soft)":dl2.in.days<=7?"var(--amber-soft)":"var(--green-soft)";
  const dlBo=dl2.gara?"var(--red-border)":dl2.in.days<=3?"var(--red-border)":dl2.in.days<=7?"var(--amber-border)":"var(--green-border)";
  const todayIT=()=>{const d=new Date();return`${String(d.getDate()).padStart(2,'0')}/${String(d.getMonth()+1).padStart(2,'0')}/${d.getFullYear()}`;};
  const isConsegnato=!!c.consegnatoIl;

  const patchIdentity=(field,val)=>onPatch(c.id,x=>{
    const insegna=field==='insegna'?(val.trim()||x.insegna||x.nome):(x.insegna||x.nome);
    const place=field==='place'?(val.trim()||'—'):x.place;
    const glyph=insegna.split(/\s+/).map(w=>w[0]).join('').toUpperCase().slice(0,2)||'??';
    const nome=insegna+(place!=='—'?' — '+place:'');
    return{...x,insegna,place,nome,glyph};
  });
  const hInpStyle={fontFamily:'var(--ff)',fontWeight:700,fontSize:'inherit',border:'none',borderBottom:'2px solid var(--primary)',background:'none',outline:'none',color:'var(--ink)',padding:'2px 0',minWidth:80,maxWidth:400};
  const hSpStyle={cursor:'text',borderBottom:'1px dashed transparent'};
  const subInpStyle={fontFamily:'var(--ff)',fontWeight:400,fontSize:'inherit',border:'none',borderBottom:'1px solid var(--primary)',background:'none',outline:'none',color:'var(--ink)',padding:'1px 0',minWidth:60,maxWidth:320};
  const subSpStyle={cursor:'text',borderBottom:'1px dashed transparent'};

  const wsHead = (
    <div className="ws-head">
      <div style={{display:"flex",gap:15,alignItems:"flex-start"}}>
        <Glyph c={c.color} glyph={c.glyph} size={46} r={11} fs={18}/>
        <div className="ws-title">
          <h2><EditableInline value={c.insegna||c.nome} placeholder="Nome" onSave={v=>patchIdentity('insegna',v)} spanStyle={hSpStyle} inputStyle={hInpStyle}/></h2>
          <div className="sub"><Icon name="pin" size={13}/><EditableInline value={c.place==='—'?'':c.place} placeholder="Via / struttura" onSave={v=>patchIdentity('place',v)} spanStyle={subSpStyle} inputStyle={subInpStyle}/> <FaseBadge c={c}/>
            {c.tipo==="gara" && c.garaStart && <span className="dim">· gara aperta {fmtDays(c.garaStart.days)}</span>}</div>
        </div>
      </div>
      <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:8}}>
        {isConsegnato
          ? <div style={{display:"flex",alignItems:"center",gap:7,background:"var(--green-soft)",color:"var(--green)",borderRadius:999,padding:"8px 16px",fontWeight:700,fontSize:13.5,border:"1.5px solid var(--green-border)"}}>
              <Icon name="check" size={14}/>Consegnato il {c.consegnatoIl}
              <span onClick={()=>onPatch(c.id,x=>({...x,consegnatoIl:null}))} style={{marginLeft:4,opacity:.5,cursor:'pointer',fontSize:15,fontWeight:400}}>×</span>
            </div>
          : <div style={{display:"flex",alignItems:"center",gap:7,background:dlBg,color:dlC,borderRadius:999,padding:"8px 16px",fontWeight:700,fontSize:13.5,whiteSpace:"nowrap",border:"1.5px solid "+dlBo}}>
              <Icon name="clock" size={14}/>
              {dl2.in.days<=1?fmtDays(dl2.in.days):dl2.in.days+" gg alla consegna"}
            </div>
        }
        <div style={{display:"flex",alignItems:"center",gap:2}}>
          {!isConsegnato&&
            <button className="btn ghost sm" onClick={()=>onPatch(c.id,x=>({...x,consegnatoIl:todayIT()}))} style={{fontWeight:600}}>
              <Icon name="check" size={13}/>Segna consegnato
            </button>}
          {c.archived
            ? <button className="btn ghost sm" onClick={()=>onArchive&&onArchive(c.id)} style={{color:'var(--primary)'}}>
                <Icon name="archive" size={13}/>Ripristina
              </button>
            : <button className="btn ghost sm" onClick={()=>onArchive&&onArchive(c.id)} style={{color:'var(--ink3)'}}>
                <Icon name="archive" size={13}/>Archivia
              </button>}
          <button className="btn ghost sm" onClick={()=>{if(window.confirm('Eliminare definitivamente?'))onDelete(c.id);}}
            style={{color:'var(--red)'}}>
            Elimina
          </button>
        </div>
      </div>
    </div>
  );

  const subtabBar = (
    <div className="subtabs">
      {tabs.map(t=>(
        <div key={t.id} className={"subtab"+(tab===t.id?" active":"")} onClick={()=>setTab(t.id)}>
          <Icon name={t.icon} size={15}/>{t.label}{t.cnt&&<span className="cnt">{t.cnt}</span>}
        </div>
      ))}
    </div>
  );

  const tabContent = (<>
    {tab==="panoramica"   && <TabPanoramica c={c} onPatch={onPatch}/>}
    {tab==="diario"       && <TabDiario c={c} onPatch={onPatch}/>}
    {tab==="impianti"     && <TabImpiantiSpeciali c={c} onPatch={onPatch}/>}
    {tab==="progetti"      && <TabProgetti c={c} onPatch={onPatch}/>}
    {tab==="calendario"  && <TabCalendario c={c} onPatch={onPatch}/>}
    {tab==="documenti"   && <TabDocumenti c={c} onPatch={onPatch}/>}
    {tab==="dati"        && <TabDati c={c} onPatch={onPatch}/>}
    {tab==="sopralluogo" && <TabSopralluogo c={c} onPatch={onPatch}/>}
    {tab==="preventivi"  && <TabPreventivi c={c} onPatch={onPatch}/>}
    {tab==="crono"       && <TabCrono c={c} onPatch={onPatch} rubrica={rubrica} onSaveDitta={onSaveDitta} onAddLavorazione={onAddLavorazione}/>}
    {tab==="consegne"    && <TabConsegne c={c} onPatch={onPatch}/>}
    {tab==="todo"        && <TabTodoNote c={c} onPatch={onPatch}/>}
  </>);

  /* ---- Cantiere attivo: full width + info strip ---- */
  if(c.fase==="cantiere"){
    const nf = c.info||{};
    const setInfoC=(key,val)=>onPatch(c.id,x=>{
      const info={...(x.info||{}),[key]:val};
      const patch={info};
      if(key==='dataFine'){
        const days=daysUntilStr(val);
        if(days!==null){
          const p=val.split('/');
          const ts=new Date(+p[2],+p[1]-1,+p[0]).getTime();
          const label=new Date(ts).toLocaleDateString('it-IT',{day:'2-digit',month:'short'});
          patch.nextDeadline={label:'Consegna cantiere',in:{ts,label,days},gara:false};
        }
      }
      return{...x,...patch};
    });
    const daysLeft = daysUntilStr(nf.dataFine);
    const wsHeadCantiere = (
      <div className="ws-head">
        <div style={{display:"flex",gap:15,alignItems:"flex-start"}}>
          <Glyph c={c.color} glyph={c.glyph} size={52} r={13} fs={20}/>
          <div className="ws-title">
            <h2><EditableInline value={c.insegna||c.nome} placeholder="Nome" onSave={v=>patchIdentity('insegna',v)} spanStyle={hSpStyle} inputStyle={hInpStyle}/></h2>
            <div className="sub"><Icon name="pin" size={14}/><EditableInline value={c.place==='—'?'':c.place} placeholder="Via / struttura" onSave={v=>patchIdentity('place',v)} spanStyle={subSpStyle} inputStyle={subInpStyle}/> <FaseBadge c={c}/></div>
          </div>
        </div>
        {(()=>{
          const pc = daysLeft===null?"var(--ink3)":daysLeft>14?"var(--green)":daysLeft>7?"var(--amber)":"var(--red)";
          const bg = daysLeft===null?"var(--card2)":daysLeft>14?"var(--green-soft)":daysLeft>7?"var(--amber-soft)":"var(--red-soft)";
          const bo = daysLeft===null?"var(--line)":daysLeft>14?"var(--green-border)":daysLeft>7?"var(--amber-border)":"var(--red-border)";
          return (
            <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:8}}>
              <div style={{display:"flex",alignItems:"center",gap:7,background:bg,color:pc,borderRadius:999,padding:"8px 16px",fontWeight:700,fontSize:14,whiteSpace:"nowrap",border:"1.5px solid "+bo}}>
                <Icon name="clock" size={14}/>
                {daysLeft===null?"—":daysLeft<=1?fmtDays(daysLeft):daysLeft+" gg alla consegna"}
              </div>
              <div style={{display:"flex",alignItems:"center",gap:2}}>
                <button className="btn ghost sm print-btn" onClick={()=>window.print()} style={{color:'var(--ink2)'}}>
                  <Icon name="doc" size={13}/>Stampa PDF
                </button>
                {c.archived
                  ? <button className="btn ghost sm" onClick={()=>onArchive&&onArchive(c.id)} style={{color:'var(--primary)'}}>
                      <Icon name="archive" size={13}/>Ripristina
                    </button>
                  : <button className="btn ghost sm" onClick={()=>onArchive&&onArchive(c.id)} style={{color:'var(--ink3)'}}>
                      <Icon name="archive" size={13}/>Archivia
                    </button>}
                <button className="btn ghost sm" onClick={()=>{if(window.confirm('Eliminare definitivamente?'))onDelete(c.id);}}
                  style={{color:'var(--red)'}}>
                  Elimina
                </button>
              </div>
            </div>
          );
        })()}
      </div>
    );
    return (
      <div className="page fade">
        <button className="back" onClick={onBack}><Icon name="arrowL" size={16}/> Tutti i cantieri</button>
        <div className="workspace" style={{marginTop:10}}>
          {wsHeadCantiere}
          {/* info strip */}
          {(()=>{
            const parseM2C=s=>{if(!s)return null;const n=parseFloat(String(s).replace(',','.'));return isNaN(n)?null:n;};
            const vvC=parseM2C(nf.supVendita),vmC=parseM2C(nf.supMagazzino);
            const totC=(vvC!==null&&vmC!==null)?(vvC+vmC)+' m²':null;
            const iSp={fontFamily:'var(--ff)',fontWeight:700,fontSize:15,border:'none',borderBottom:'2px solid var(--primary)',background:'none',outline:'none',width:80,color:'var(--ink)',padding:'2px 0'};
            const sSp={fontWeight:700,fontSize:15,cursor:'text',borderBottom:'1px dashed var(--ink-3)'};
            return (
              <div className="info-strip card" style={{gridTemplateColumns:'repeat(6,1fr)'}}>
                <div className="info-field"><span className="if-label">Inizio cantiere</span><EditableDate value={nf.dataInizio||''} onSave={v=>setInfoC('dataInizio',v)}/></div>
                <div className="info-field"><span className="if-label">Data consegna</span><EditableDate value={nf.dataFine||''} onSave={v=>setInfoC('dataFine',v)}/></div>
                <div className="info-field"><span className="if-label">Sup. vendita</span><EditableInline value={nf.supVendita||''} placeholder="—" onSave={v=>setInfoC('supVendita',v)} spanStyle={sSp} inputStyle={iSp}/></div>
                <div className="info-field"><span className="if-label">Sup. magazzino</span><EditableInline value={nf.supMagazzino||''} placeholder="—" onSave={v=>setInfoC('supMagazzino',v)} spanStyle={sSp} inputStyle={iSp}/></div>
                <div className="info-field"><span className="if-label">Sup. totale</span><span style={{fontWeight:700,fontSize:15,color:totC?'var(--ink)':'var(--ink3)'}}>{totC||'—'}</span></div>
                <div className="info-field"><span className="if-label">Progettista</span><EditableInline value={nf.progettista||''} placeholder="—" onSave={v=>setInfoC('progettista',v)} spanStyle={sSp} inputStyle={{...iSp,width:140}}/></div>
              </div>
            );
          })()}
          {subtabBar}
          {tabContent}
          <PrintSummary c={c}/>
        </div>
      </div>
    );
  }

  const sup = c.info||{};
  const setInfoP=(key,val)=>onPatch(c.id,x=>{
    const info={...(x.info||{}),[key]:val};
    const patch={info};
    if(key==='dataFine'){
      const days=daysUntilStr(val);
      if(days!==null){
        const p=val.split('/');
        const ts=new Date(+p[2],+p[1]-1,+p[0]).getTime();
        const label=new Date(ts).toLocaleDateString('it-IT',{day:'2-digit',month:'short'});
        const dlLabel=x.tipo==='gara'?'GARA — consegna preventivo':'Consegna preventivo';
        patch.nextDeadline={label:dlLabel,in:{ts,label,days},gara:x.tipo==='gara'};
      }
    }
    return{...x,...patch};
  });
  const parseM2=(s)=>{if(!s)return null;const n=parseFloat(String(s).replace(',','.'));return isNaN(n)?null:n;};
  const totaleP=(()=>{const vv=parseM2(sup.supVendita),vm=parseM2(sup.supMagazzino);return(vv!==null&&vm!==null)?(vv+vm)+' m²':null;})();
  const iSpP={fontFamily:'var(--ff)',fontWeight:700,fontSize:15,border:'none',borderBottom:'2px solid var(--primary)',background:'none',outline:'none',width:80,color:'var(--ink)',padding:'2px 0'};
  const sSpP={fontWeight:700,fontSize:15,cursor:'text',borderBottom:'1px dashed var(--ink-3)'};

  return (
    <div className="page fade">
      <button className="back" onClick={onBack}><Icon name="arrowL" size={16}/> Tutti i cantieri</button>
      <div className="workspace">
        {wsHead}
        {/* info strip */}
        <div className="info-strip card" style={{gridTemplateColumns:'repeat(6,1fr)'}}>
          <div className="info-field"><span className="if-label">Arrivo preventivo</span><EditableDate value={sup.dataInizio||''} onSave={v=>setInfoP('dataInizio',v)}/></div>
          <div className="info-field"><span className="if-label">Data consegna</span><EditableDate value={sup.dataFine||''} onSave={v=>setInfoP('dataFine',v)}/></div>
          <div className="info-field"><span className="if-label">Sup. vendita</span><EditableInline value={sup.supVendita||''} placeholder="—" onSave={v=>setInfoP('supVendita',v)} spanStyle={sSpP} inputStyle={iSpP}/></div>
          <div className="info-field"><span className="if-label">Sup. magazzino</span><EditableInline value={sup.supMagazzino||''} placeholder="—" onSave={v=>setInfoP('supMagazzino',v)} spanStyle={sSpP} inputStyle={iSpP}/></div>
          <div className="info-field"><span className="if-label">Sup. totale</span><span style={{fontWeight:700,fontSize:15,color:totaleP?'var(--ink)':'var(--ink3)'}}>{totaleP||'—'}</span></div>
          <div className="info-field"><span className="if-label">Progettista</span><EditableInline value={sup.progettista||''} placeholder="—" onSave={v=>setInfoP('progettista',v)} spanStyle={sSpP} inputStyle={{...iSpP,width:140}}/></div>
        </div>
        {subtabBar}
        {tabContent}
      </div>
    </div>
  );
};
window.DetailView = DetailView;
