// client.jsx — Espace client (suivi, devis, jour J, stockage, parrainage)
const { useState: useC } = React;

const CLIENT = {
  firstName:'Élise', lastName:'Moreau', ref:'LBC-2420',
  from:'Nice', to:'Bordeaux',
  fromAddr:'12 rue Gioffredo, 06000 Nice', toAddr:'8 cours de l\'Intendance, 33000 Bordeaux',
  date:'18 juin 2026', window:'8 h – 12 h',
  rooms:'Maison 4 pièces · ~35 m³', notes:'Jardin avec mobilier extérieur',
  formule:'complete', devis:2750, partner:'Agence Riviera Immobilier',
  advisor:{ name:'Karim, votre conseiller LBC', phone:'04 93 00 12 34' },
  storage:{ active:true, tier:'M', box:'Box M', size:'6 – 10 m²', volume:'≈ le contenu d\'un 2 pièces', site:'Entrepôt LBC sécurisé · Nice Saint-Isidore',
    price:199, since:'18 juin 2026',
    items:['Canapé 3 places','2 fauteuils en cuir','Cartons livres (×8)','Vélo de route','Table basse en verre','Cartons vaisselle (×4)'] },
  referral:{ code:'ELISE50', reward:50, earned:50, pending:50,
    friends:[ { name:'Thomas Bernard', city:'Lyon', status:'A déménagé', earned:50 },
              { name:'Julie Caron', city:'Cannes', status:'Devis en cours', earned:0 } ] },
};
window.CLIENT = CLIENT; // permet à la couche Supabase de remplir le dossier du vrai client connecté

const DEVIS_LINES = [
  { label:'Transport Nice → Bordeaux', sub:'~580 km · camion 35 m³', amount:1450 },
  { label:'Démontage & remontage du mobilier', sub:'lits, armoires, meubles', amount:480 },
  { label:'Emballage & protection', sub:'cartons, couvertures, film', amount:520 },
  { label:'Assurance tous risques', sub:'valeur déclarée couverte', amount:300 },
];
const FORMULE_INCLUS = ['Emballage de vos affaires fourni','Démontage et remontage des meubles','Protection intégrale du mobilier','Transport assuré tous risques','Mise en place dans votre nouveau logement'];
const CLIENT_FORMULE_LABEL = { eco:'Coup de main', standard:'Mains libres', premium:'Mains dans les poches', complete:'Mains dans les poches', simple:'Coup de main' };
const clientFormuleLabel = (f)=> CLIENT_FORMULE_LABEL[f] || 'Formule';
const clientSideStr = (s)=>{ if(!s) return '—'; const et=parseInt(s.etage)||0; return [et===0?'RDC':'Étage '+et, s.ascenseur?('ascenseur'+(s.ascTaille&&s.ascTaille!=='Aucun'?' '+s.ascTaille:'')):'sans ascenseur', (parseInt(s.portage)||0)?('portage '+(parseInt(s.portage)||0)+' m'):''].filter(Boolean).join(' · '); };
const clientTagStr = (arr)=>(arr||[]).map(t=>(t&&t.qty&&t.qty>1)?(t.label+' ×'+t.qty):((t&&t.label)||t)).join(', ');

const BOX_TIERS = [
  { key:'S',  size:'1 – 5 m²',   price:119, vol:'≈ 30 cartons',      desc:'Quelques cartons, un studio en transition.' },
  { key:'M',  size:'6 – 10 m²',  price:199, vol:'≈ 1 camionnette',   desc:'Le contenu d\'un 2 pièces meublé.' },
  { key:'L',  size:'11 – 15 m²', price:299, vol:'≈ 1 camion',        desc:'Un 3 pièces complet, électroménager inclus.', popular:true },
  { key:'XL', size:'16 – 20 m²', price:399, vol:'≈ 1 grand camion',  desc:'Une maison ou des locaux professionnels.' },
];

const CLIENT_STEPS = [
  { key:'recu',     label:'Demande reçue',          sub:'Transmise par votre agence' },
  { key:'contacte', label:'Pris en charge par LBC',  sub:'Un conseiller vous est dédié' },
  { key:'devis',    label:'Devis envoyé',            sub:'À valider de votre côté' },
  { key:'accepte',  label:'Devis accepté',           sub:'Déménagement réservé' },
  { key:'jourj',    label:'Jour du déménagement',    sub:'Notre équipe arrive' },
  { key:'termine',  label:'Emménagement terminé',    sub:'Bienvenue chez vous !' },
];
const reachedIndex = (status) => ({ devis:2, accepte:3, prep:3, jourj:4, termine:6 }[status] ?? 2);
function euroC(n){ return n.toLocaleString('fr-FR')+' €'; }

/* ---- hero : camion qui roule de l'adresse de départ à l'adresse d'arrivée ---- */
function HeroScene({ celebrate, h = 150 }) {
  return (
    <div style={{ position:'relative', height:h }}>
      {/* adresses aux extrémités */}
      <div style={{ position:'absolute', top:0, left:2, maxWidth:'42%' }}>
        <div style={{ display:'flex', alignItems:'center', gap:5, fontSize:10.5, fontWeight:700, letterSpacing:'.07em', textTransform:'uppercase', color:'var(--effectue)' }}>
          <Icon name="pin" size={12} />Départ</div>
        <div style={{ fontSize:12, fontWeight:600, color:'var(--navy)', marginTop:3, lineHeight:1.35 }}>{CLIENT.fromAddr}</div>
      </div>
      <div style={{ position:'absolute', top:0, right:2, maxWidth:'42%', textAlign:'right' }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'flex-end', gap:5, fontSize:10.5, fontWeight:700, letterSpacing:'.07em', textTransform:'uppercase', color:'var(--brand)' }}>
          Arrivée<Icon name="pin" size={12} /></div>
        <div style={{ fontSize:12, fontWeight:600, color:'var(--navy)', marginTop:3, lineHeight:1.35 }}>{CLIENT.toAddr}</div>
      </div>

      {/* route */}
      <div style={{ position:'absolute', left:0, right:0, bottom:24, height:2, background:'rgba(20,56,78,.14)' }} />
      <div style={{ position:'absolute', left:0, right:0, bottom:24, height:2, backgroundImage:'repeating-linear-gradient(90deg, rgba(20,56,78,.28) 0 14px, transparent 14px 30px)' }} />
      {/* bornes départ / arrivée sur la route */}
      <div style={{ position:'absolute', left:'7%', bottom:20, width:10, height:10, borderRadius:'50%', background:'var(--effectue)', border:'2px solid var(--card)', transform:'translateX(-50%)' }} />
      <div style={{ position:'absolute', left:'88%', bottom:20, width:10, height:10, borderRadius:'50%', background:'var(--brand)', border:'2px solid var(--card)', transform:'translateX(-50%)' }} />

      {/* camion animé */}
      <div className="hero-truck" style={{ position:'absolute', bottom:18, transform:'translateX(-50%)' }}>
        <svg width="132" height="80" viewBox="0 0 150 92" fill="none" stroke="var(--navy)" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round">
          <rect x="5" y="20" width="86" height="48" rx="4" fill="#fff" />
          <path d="M91 36 h20 l16 16 v16 h-36 z" fill="rgba(224,65,31,.12)" stroke="var(--brand)" />
          <path d="M96 40 h13 l10 10 h-23 z" fill="#fff" stroke="var(--navy)" strokeWidth="2.2" />
          <path d="M18 36 h46 M18 48 h32" stroke="var(--navy)" strokeWidth="2.2" opacity=".45" />
          <text x="48" y="50" fontFamily="Geist, sans-serif" fontSize="16" fontWeight="800" fill="var(--brand)" stroke="none" textAnchor="middle">*</text>
          <circle className="wheel" cx="32" cy="72" r="10" fill="var(--navy)" /><circle cx="32" cy="72" r="3.6" fill="#fff" />
          <circle className="wheel" cx="110" cy="72" r="10" fill="var(--navy)" /><circle cx="110" cy="72" r="3.6" fill="#fff" />
        </svg>
      </div>

      {celebrate && [...Array(10)].map((_,i)=>(
        <span key={i} style={{ position:'absolute', left:`${15+i*7}%`, top:8, width:7, height:7, borderRadius:2,
          background:['#B63D24','#E0411F','#16965A','#C2992E','#15384E'][i%5], animation:`confetti .9s ${i*0.05}s ease-out both` }} />
      ))}
    </div>
  );
}

function ClientTimeline({ status }) {
  const reached = reachedIndex(status);
  return (
    <div>
      {CLIENT_STEPS.map((s,i)=>{
        const state = i < reached ? 'done' : (i === reached ? 'current' : 'todo');
        const last = i===CLIENT_STEPS.length-1;
        return (
          <div key={s.key} style={{ display:'flex', gap:14, position:'relative', paddingBottom: last?0:18 }}>
            {!last && <div style={{ position:'absolute', left:13, top:28, bottom:0, width:2, background: state==='done'?'var(--effectue)':'var(--border)' }} />}
            <div style={{ width:28, height:28, borderRadius:'50%', flexShrink:0, zIndex:1, display:'flex', alignItems:'center', justifyContent:'center',
              background: state==='done'?'var(--effectue)':(state==='current'?'rgba(199,122,10,.14)':'var(--bg)'),
              border: state==='todo'?'2px solid var(--border-2)':(state==='current'?'2px solid var(--accepte)':'none'), color:'#fff' }} className={state==='current'?'ring-pulse':''}>
              {state==='done' && <Icon name="check" size={15} stroke={2.6} />}
              {state==='current' && <span style={{ width:8, height:8, borderRadius:'50%', background:'var(--accepte)' }} />}
            </div>
            <div style={{ paddingTop:3 }}>
              <div style={{ fontSize:14.5, fontWeight: state==='todo'?500:600, color: state==='todo'?'var(--faint)':'var(--ink)' }}>{s.label}</div>
              <div style={{ fontSize:12.5, color:'var(--muted)', marginTop:1 }}>{s.sub}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

const grid2 = (wide)=>({ display:'grid', gridTemplateColumns: wide?'1fr 1fr':'1fr', gap:16, alignItems:'start' });

function PaymentSummary({ payment, soldePaid, paySolde }) {
  const deposit = Math.round(CLIENT.devis*0.3), solde = CLIENT.devis - deposit;
  const depositPaid = payment==='carte';
  const paidTotal = (depositPaid?deposit:0) + (soldePaid?solde:0);
  return (
    <div className="card card-pad">
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:14 }}>
        <span style={{ fontSize:15, fontWeight:600, color:'var(--ink)' }}>Paiement</span>
        <span className="tnum" style={{ fontSize:12.5, fontWeight:600, color: soldePaid?'var(--effectue)':'var(--muted)' }}>{euroC(paidTotal)} / {euroC(CLIENT.devis)}</span>
      </div>
      <ProgressBar value={paidTotal} max={CLIENT.devis} color={soldePaid?'var(--effectue)':'var(--brand)'} height={7} />
      <div style={{ marginTop:14 }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'10px 0', borderBottom:'1px solid var(--border)' }}>
          <div><div style={{ fontSize:13.5, fontWeight:500, color:'var(--ink)' }}>Acompte <span style={{ color:'var(--muted)' }}>(30 %)</span></div>
            <div className="tnum" style={{ fontSize:12, color:'var(--muted)', marginTop:1 }}>{euroC(deposit)}</div></div>
          <span className={'badge '+(depositPaid?'b-effectue':'b-accepte')}>{depositPaid?<><Icon name="check" size={12} stroke={2.4} />Réglé</>:'Virement en attente'}</span>
        </div>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'10px 0' }}>
          <div><div style={{ fontSize:13.5, fontWeight:500, color:'var(--ink)' }}>Solde</div>
            <div className="tnum" style={{ fontSize:12, color:'var(--muted)', marginTop:1 }}>{euroC(solde)}</div></div>
          <span className={'badge '+(soldePaid?'b-effectue':'b-recu')}>{soldePaid?<><Icon name="check" size={12} stroke={2.4} />Réglé</>:`À régler · ${CLIENT.date}`}</span>
        </div>
      </div>
      {!soldePaid && <button className="btn btn-ghost btn-block" style={{ height:44, marginTop:10 }} onClick={paySolde}><Icon name="euroCircle" size={16} />Payer le solde · {euroC(solde)}</button>}
    </div>
  );
}

function DocumentsCard({ openDoc, reserved, hasStorage }) {
  const docs = [
    { k:'client-devis', icon:'fileText', t:'Devis', d:'Votre estimation détaillée' },
    reserved && { k:'client-invoice', icon:'receipt', t:'Facture déménagement', d:'Acompte et solde' },
    reserved && { k:'attestation', icon:'shield', t:'Attestation d\'assurance', d:'Couverture tous risques' },
    hasStorage && { k:'storage-invoice', icon:'package', t:'Facture stockage', d:'Loyer mensuel du box' },
  ].filter(Boolean);
  return (
    <div className="card" style={{ overflow:'hidden' }}>
      <div style={{ padding:'15px 18px', borderBottom:'1px solid var(--border)' }}><span style={{ fontSize:15, fontWeight:600, color:'var(--ink)' }}>Mes documents</span></div>
      {docs.map((d,i)=>(
        <div key={d.k} onClick={()=>openDoc&&openDoc(d.k)} style={{ display:'flex', alignItems:'center', gap:13, padding:'13px 18px', borderBottom: i<docs.length-1?'1px solid var(--border)':'none', cursor:'pointer' }}
          onMouseEnter={e=>e.currentTarget.style.background='var(--hover)'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
          <span style={{ width:36, height:36, borderRadius:9, background:'var(--bg)', color:'var(--navy)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}><Icon name={d.icon} size={18} /></span>
          <div style={{ flex:1, minWidth:0 }}><div style={{ fontSize:14, fontWeight:600, color:'var(--ink)' }}>{d.t}</div><div style={{ fontSize:12.5, color:'var(--muted)' }}>{d.d}</div></div>
          <Icon name="download" size={17} style={{ color:'var(--faint)' }} />
        </div>
      ))}
    </div>
  );
}

function ClientChat({ showToast }) {
  const [msgs, setMsgs] = useC([{ who:'them', text:`Bonjour ${CLIENT.firstName}, je suis Karim, votre conseiller LBC. Une question sur votre déménagement ?`, time:'09:12' }]);
  const [draft, setDraft] = useC('');
  const send = (t)=>{ const m=(t||draft).trim(); if(!m) return; setMsgs(x=>[...x,{who:'me',text:m,time:'à l\'instant'}]); setDraft(''); showToast&&showToast('Message envoyé à votre conseiller');
    setTimeout(()=>setMsgs(x=>[...x,{who:'them',text:'Bien noté ! Je reviens vers vous très vite.',time:'à l\'instant'}]),1300); };
  return (
    <div className="card card-pad">
      <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:14 }}>
        <img src="assets/mascot.png" alt="" width={36} height={36} style={{ borderRadius:'50%' }} />
        <div><div style={{ fontSize:14.5, fontWeight:600, color:'var(--ink)' }}>Karim · conseiller LBC</div><div style={{ fontSize:12, color:'var(--effectue)', display:'flex', alignItems:'center', gap:5 }}><span style={{ width:6, height:6, borderRadius:'50%', background:'var(--effectue)' }} />En ligne</div></div>
      </div>
      <div className="scroll" style={{ display:'flex', flexDirection:'column', gap:10, maxHeight:240, overflowY:'auto', padding:'2px 2px 6px' }}>
        {msgs.map((m,i)=>(
          <div key={i} style={{ display:'flex', flexDirection:'column', alignItems: m.who==='me'?'flex-end':'flex-start', gap:3 }}>
            <div className={'msg '+(m.who==='me'?'msg-me':'msg-them')}>{m.text}</div>
            <span style={{ fontSize:10.5, color:'var(--faint)', padding:'0 4px' }}>{m.time}</span>
          </div>
        ))}
      </div>
      <div style={{ display:'flex', gap:9, marginTop:14 }}>
        <input className="input" value={draft} onChange={e=>setDraft(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter') send(); }} placeholder="Écrire un message…" style={{ flex:1, height:42 }} />
        <button className="btn btn-primary" style={{ width:46, padding:0 }} onClick={()=>send()}><Icon name="arrowR" size={18} /></button>
      </div>
    </div>
  );
}

/* ============== SUIVI ============== */
function ClientSuivi({ status, go, wide, payment, soldePaid, paySolde, openDoc }) {
  const pending = status==='devis';
  const headline = pending ? 'Votre devis est prêt 🎉' : (status==='accepte'||status==='prep') ? 'C\'est réservé !' : status==='jourj' ? 'C\'est le grand jour !' : 'Déménagement terminé';
  const reservedSub = payment==='virement' ? `Créneau du ${CLIENT.date} pré-réservé — en attente de votre virement.` : `Acompte réglé · rendez-vous le ${CLIENT.date}. Tout est calé.`;
  const subline = pending ? 'Consultez votre estimation et réservez en un clic.' : (status==='accepte'||status==='prep') ? reservedSub : status==='jourj' ? 'Notre équipe est en route vers vous.' : 'Nous vous souhaitons un bel emménagement.';
  const hero = (
    <div style={{ background:'var(--cream)', borderRadius:20, padding:'18px 22px 0', overflow:'hidden', border:'1px solid var(--cream-dim)' }}>
      <div style={{ fontSize:11.5, fontWeight:600, letterSpacing:'.06em', textTransform:'uppercase', color:'var(--brand)' }}>Votre déménagement</div>
      <h2 style={{ fontSize:22, fontWeight:600, color:'var(--navy)', margin:'6px 0 4px', letterSpacing:'-.01em' }}>{headline}</h2>
      <p style={{ fontSize:13.5, color:'var(--ink-2)', margin:0, lineHeight:1.5 }}>{subline}</p>
      <HeroScene celebrate={status==='accepte'} />
    </div>
  );
  const summary = (
    <>
      <div style={{ display:'flex', gap:12 }}>
        <div className="card" style={{ flex:1, padding:'14px 16px' }}><div className="card-label" style={{ marginBottom:8 }}>Trajet</div><Route from={CLIENT.from} to={CLIENT.to} strong /></div>
        <div className="card" style={{ flex:1, padding:'14px 16px' }}><div className="card-label" style={{ marginBottom:8 }}>Date prévue</div><div style={{ fontSize:14.5, fontWeight:600, color:'var(--ink)' }}>{CLIENT.date}</div></div>
      </div>
      {pending && <button className="btn btn-primary btn-lg btn-block" onClick={()=>go('devis')}><Icon name="fileText" size={18} />Voir mon devis{(CLIENT.devis||0)>0?' · '+euroC(CLIENT.devis):''}</button>}
      {(status==='accepte'||status==='prep') && (
        <div className="card" style={{ padding:'13px 16px', display:'flex', alignItems:'center', gap:12, background: payment==='virement'?'#FCF3DF':'var(--effectue-bg)', border:'1px solid '+(payment==='virement'?'#F0DcB0':'#BFE6CF') }}>
          <span style={{ color: payment==='virement'?'var(--accepte)':'var(--effectue)', display:'flex', flexShrink:0 }}><Icon name={payment==='virement'?'clock':'check'} size={19} stroke={2.2} /></span>
          <div style={{ fontSize:13, color: payment==='virement'?'#7A5410':'#0F6B43', fontWeight:500, lineHeight:1.45 }}>
            {payment==='virement' ? `Virement de ${euroC(Math.round(CLIENT.devis*0.3))} en attente de réception. Votre créneau est pré-réservé.` : `Acompte de ${euroC(Math.round(CLIENT.devis*0.3))} réglé — solde de ${euroC(CLIENT.devis-Math.round(CLIENT.devis*0.3))} le jour J.`}</div>
        </div>
      )}
      <div className="card" style={{ padding:'14px 16px', display:'flex', alignItems:'center', gap:13 }}>
        <img src="assets/mascot.png" alt="" width={44} height={44} style={{ borderRadius:'50%', flexShrink:0 }} />
        <div style={{ flex:1, minWidth:0 }}><div style={{ fontSize:13.5, fontWeight:600, color:'var(--ink)' }}>{CLIENT.advisor.name}</div><div style={{ fontSize:12.5, color:'var(--muted)' }}>Une question ? Il vous répond.</div></div>
        <a href={'tel:'+CLIENT.advisor.phone.replace(/\s/g,'')} className="btn btn-ghost btn-sm" style={{ height:38 }}><Icon name="phone" size={15} />Appeler</a>
      </div>
      {(status==='accepte'||status==='prep'||status==='jourj') && <PaymentSummary payment={payment} soldePaid={soldePaid} paySolde={paySolde} />}
      <DocumentsCard openDoc={openDoc} reserved={status!=='devis'} hasStorage={CLIENT.storage.active} />
    </>
  );
  const timeline = (
    <div className="card card-pad">
      <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)', marginBottom:16 }}>Suivi en temps réel</div>
      <ClientTimeline status={status} />
    </div>
  );
  if (wide) return (
    <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
      {hero}
      <div style={grid2(true)}>
        <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{summary}</div>
        {timeline}
      </div>
    </div>
  );
  return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{hero}{summary}{timeline}</div>;
}

/* ============== DEVIS ============== */
function ClientDevis({ status, accept, wide, payment, openDoc, go }) {
  const accepted = status!=='devis';
  const deposit = Math.round(CLIENT.devis*0.3);
  const hasPrice = (CLIENT.devis||0) > 0;
  const inv = CLIENT.inventaire || [];
  const Row = ({l, v})=> (v? <div style={{ display:'flex', justifyContent:'space-between', gap:12, padding:'11px 0', borderBottom:'1px solid var(--border)' }}><span style={{ fontSize:13, color:'var(--muted)' }}>{l}</span><span style={{ fontSize:13.5, fontWeight:600, color:'var(--ink)', textAlign:'right' }}>{v}</span></div> : null);
  const left = (
    <>
      <div className="card" style={{ overflow:'hidden' }}>
        <div style={{ background:'var(--navy)', color:'var(--cream)', padding:'20px 22px 18px', position:'relative', overflow:'hidden' }}>
          <div style={{ position:'absolute', top:-30, right:-20, width:140, height:140, borderRadius:'50%', background:'radial-gradient(circle, rgba(224,65,31,.2), transparent 65%)' }} />
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', position:'relative' }}>
            <div><div style={{ fontSize:11.5, fontWeight:600, letterSpacing:'.06em', textTransform:'uppercase', opacity:.7 }}>Devis estimatif</div>
              <span style={{ display:'inline-block', marginTop:8, fontSize:13, fontWeight:600, padding:'3px 10px', borderRadius:999, background:'rgba(245,239,227,.14)' }}>Formule {clientFormuleLabel(CLIENT.formule)}</span></div>
            <span className="mono" style={{ fontSize:12, opacity:.6 }}>{CLIENT.ref}</span>
          </div>
          {hasPrice
            ? <><div className="tnum" style={{ fontSize:34, fontWeight:700, marginTop:14, letterSpacing:'-.02em', position:'relative' }}>{euroC(CLIENT.devis)}</div>
                <div style={{ fontSize:12.5, opacity:.7, position:'relative' }}>tout compris · sans engagement</div></>
            : <><div style={{ fontSize:19, fontWeight:700, marginTop:14, position:'relative' }}>Devis en cours de préparation</div>
                <div style={{ fontSize:12.5, opacity:.7, position:'relative' }}>Votre conseiller LBC finalise votre prix sous 24 h.</div></>}
        </div>
        <div style={{ padding:'6px 20px 10px' }}>
          <Row l="Volume estimé" v={CLIENT.volume?CLIENT.volume+' m³':''} />
          <Row l="Cartons" v={CLIENT.cartons?String(CLIENT.cartons):''} />
          <Row l="Distance" v={CLIENT.km?CLIENT.km+' km':''} />
          <Row l="Date souhaitée" v={[CLIENT.date, CLIENT.flexibilite].filter(Boolean).join(' · ')} />
          <Row l="Départ" v={[CLIENT.fromAddr, clientSideStr(CLIENT.dep)].filter(Boolean).join(' — ')} />
          <Row l="Arrivée" v={[CLIENT.toAddr, clientSideStr(CLIENT.arr)].filter(Boolean).join(' — ')} />
          <Row l="Objets fragiles" v={clientTagStr(CLIENT.fragiles)} />
          <Row l="À démonter / remonter" v={clientTagStr(CLIENT.demonter)} />
          {hasPrice && <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding:'14px 0 4px' }}>
            <span style={{ fontSize:15, fontWeight:600, color:'var(--ink)' }}>Total estimé</span>
            <span className="tnum" style={{ fontSize:18, fontWeight:700, color:'var(--brand)' }}>{euroC(CLIENT.devis)}</span>
          </div>}
        </div>
      </div>
      {inv.length > 0 && (
        <div className="card" style={{ overflow:'hidden' }}>
          <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--border)', fontSize:14, fontWeight:600, color:'var(--ink)' }}>📦 Votre inventaire ({inv.length})</div>
          <div style={{ padding:'4px 18px 10px' }}>
            {inv.map((it,i)=>(
              <div key={i} style={{ display:'flex', justifyContent:'space-between', gap:12, padding:'9px 0', borderBottom:i<inv.length-1?'1px solid var(--border)':'none' }}>
                <div><span style={{ fontSize:13.5, color:'var(--ink)' }}>{it.meuble||'—'}</span> <span style={{ fontSize:12, color:'var(--muted)' }}>· {it.piece||''}</span></div>
                <span className="tnum" style={{ fontSize:13.5, fontWeight:600, color:'var(--ink)' }}>×{it.quantite||1}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </>
  );
  const right = (
    <>
      <div className="card card-pad">
        <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)', marginBottom:14 }}>Ce qui est inclus</div>
        <div style={{ display:'flex', flexDirection:'column', gap:11 }}>
          {FORMULE_INCLUS.map((t,i)=>(
            <div key={i} style={{ display:'flex', gap:10, alignItems:'center', fontSize:13.5, color:'var(--ink-2)' }}>
              <span style={{ width:22, height:22, borderRadius:'50%', background:'var(--effectue-bg)', color:'var(--effectue)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}><Icon name="check" size={13} stroke={2.6} /></span>{t}</div>
          ))}
        </div>
      </div>
      {accepted ? (
        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
        <div className="card" style={{ padding:'16px 18px', display:'flex', alignItems:'center', gap:12, background: payment==='virement'?'#FCF3DF':'var(--effectue-bg)', border:'1px solid '+(payment==='virement'?'#F0DcB0':'#BFE6CF') }}>
          <span style={{ color: payment==='virement'?'var(--accepte)':'var(--effectue)', display:'flex' }}><Icon name={payment==='virement'?'clock':'check'} size={22} stroke={2.4} /></span>
          <div style={{ fontSize:13.5, color: payment==='virement'?'#7A5410':'#0F6B43', fontWeight:500 }}>
            {payment==='virement' ? `Virement de ${euroC(deposit)} en attente — créneau du ${CLIENT.date} pré-réservé.` : `Acompte de ${euroC(deposit)} réglé — réservé pour le ${CLIENT.date}.`}</div>
        </div>
        <button className="btn btn-ghost btn-block" style={{ height:46 }} onClick={()=>openDoc&&openDoc('client-invoice')}><Icon name="receipt" size={17} />Télécharger la facture (PDF)</button>
        </div>
      ) : (
        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
          <button className="btn btn-primary btn-lg btn-block" onClick={accept}><Icon name="check" size={18} />Accepter & réserver · acompte {euroC(deposit)}</button>
          <button className="btn btn-ghost btn-block" style={{ height:46 }} onClick={()=>go&&go('aide')}><Icon name="headset" size={16} />Poser une question</button>
          <p style={{ fontSize:11.5, color:'var(--faint)', textAlign:'center', margin:'2px 0 0' }}>Acompte de 30 % pour réserver · solde le jour du déménagement</p>
        </div>
      )}
    </>
  );
  if (wide) return <div style={grid2(true)}><div style={{ display:'flex', flexDirection:'column', gap:16 }}>{left}</div><div style={{ display:'flex', flexDirection:'column', gap:16 }}>{right}</div></div>;
  return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{left}{right}</div>;
}

/* ============== JOUR J ============== */
function Check(){
  const [on,setOn]=useC(false);
  return <span onClick={()=>setOn(o=>!o)} style={{ width:22, height:22, borderRadius:7, flexShrink:0, marginTop:1, display:'flex', alignItems:'center', justifyContent:'center', background: on?'var(--brand)':'var(--bg)', border: on?'none':'1.5px solid var(--border-2)', color:'#fff', transition:'.14s' }}>{on && <Icon name="check" size={13} stroke={3} />}</span>;
}
function ClientJourJ({ status, wide, payment, soldePaid, paySolde, showToast }) {
  const reserved = status!=='devis';
  const [editD, setEditD] = useC(false);
  const [nd, setNd] = useC('');
  const infoCard = (
    <div className="card" style={{ overflow:'hidden' }}>
      <div style={{ background:'var(--cream)', padding:'18px 22px', borderBottom:'1px solid var(--cream-dim)' }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:12 }}>
          <div>
            <div className="card-label" style={{ color:'var(--brand)' }}>Jour du déménagement</div>
            <div style={{ fontSize:22, fontWeight:700, color:'var(--navy)', marginTop:4 }}>{CLIENT.date}</div>
            <div style={{ fontSize:13.5, color:'var(--ink-2)', marginTop:2 }}>Arrivée de l'équipe : {CLIENT.window}</div>
          </div>
          {reserved && <button onClick={()=>setEditD(v=>!v)} style={{ fontSize:13, fontWeight:600, color:'var(--brand)', display:'flex', alignItems:'center', gap:5, flexShrink:0 }}><Icon name="calendar" size={15} />Modifier</button>}
        </div>
        {editD && (
          <div className="fade-in" style={{ marginTop:14, background:'#fff', border:'1px solid var(--cream-dim)', borderRadius:12, padding:'14px' }}>
            <div style={{ fontSize:13, color:'var(--ink-2)', marginBottom:9 }}>Nouvelle date souhaitée <span style={{ color:'var(--muted)' }}>(modifiable jusqu'à J-7)</span> :</div>
            <div style={{ display:'flex', gap:9 }}>
              <input className="input" type="date" value={nd} onChange={e=>setNd(e.target.value)} style={{ flex:1 }} />
              <button className="btn btn-primary" disabled={!nd} style={{ opacity:nd?1:.5 }} onClick={()=>{ setEditD(false); setNd(''); showToast&&showToast('Demande de modification envoyée — votre conseiller confirme sous 24h'); }}>Demander</button>
            </div>
          </div>
        )}
      </div>
      <div style={{ padding:'4px 20px' }}>
        {[['pin','Départ',CLIENT.fromAddr],['pin','Arrivée',CLIENT.toAddr],['package','Volume',CLIENT.rooms],['fileText','Notes',CLIENT.notes]].map(([ic,k,v],i)=>(
          <div key={i} style={{ display:'flex', gap:12, padding:'13px 0', borderBottom: i<3?'1px solid var(--border)':'none' }}>
            <span style={{ color:'var(--faint)', display:'flex', marginTop:1 }}><Icon name={ic} size={17} /></span>
            <div><div style={{ fontSize:12, color:'var(--muted)' }}>{k}</div><div style={{ fontSize:13.5, fontWeight:500, color:'var(--ink)', marginTop:2 }}>{v}</div></div>
          </div>
        ))}
      </div>
    </div>
  );
  const checklist = (
    <div className="card card-pad">
      <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)', marginBottom:6 }}>Pour bien préparer le jour J</div>
      <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
        {['Libérez les accès et réservez une place pour le camion','Videz et dégivrez votre réfrigérateur la veille','Mettez de côté vos objets de valeur et papiers importants','Prévoyez un carton « première nuit » à portée de main'].map((t,i)=>(
          <label key={i} style={{ display:'flex', gap:11, alignItems:'flex-start', padding:'10px 0', borderBottom: i<3?'1px solid var(--border)':'none', cursor:'pointer' }}><Check /><span style={{ fontSize:13.5, color:'var(--ink-2)', lineHeight:1.45 }}>{t}</span></label>
        ))}
      </div>
    </div>
  );
  const warn = !reserved && <div className="card" style={{ padding:'16px 18px', display:'flex', gap:12, alignItems:'center', background:'#FCF3DF', border:'1px solid #F0DcB0' }}><Icon name="clock" size={20} style={{ color:'var(--accepte)', flexShrink:0 }} /><div style={{ fontSize:13, color:'#7A5410' }}>Acceptez votre devis pour confirmer la date.</div></div>;
  if (wide) return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{warn}<div style={grid2(true)}>{infoCard}<div style={{ display:'flex', flexDirection:'column', gap:16 }}>{reserved && <PaymentSummary payment={payment} soldePaid={soldePaid} paySolde={paySolde} />}{checklist}</div></div></div>;
  return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{warn}{infoCard}{reserved && <PaymentSummary payment={payment} soldePaid={soldePaid} paySolde={paySolde} />}{checklist}</div>;
}

/* ============== STOCKAGE (géré par LBC, pas de self-stockage) ============== */
function BoxTiers({ currentTier, showToast, wide }) {
  const [confirm, setConfirm] = useC(null); // box en attente de confirmation
  const [done, setDone] = useC(false);
  const [startDate, setStartDate] = useC('');
  const [months, setMonths] = useC(3);     // nombre de mois (libre)
  const [libre, setLibre] = useC(false);   // durée indéterminée
  const dureeLabel = libre ? 'Sans durée fixe' : (months+' mois');
  const valider = () => {
    setDone(true);
    const dStr = startDate ? new Date(startDate+'T00:00:00').toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'}) : 'date à définir';
    // enregistre la réservation dans la base partagée -> visible côté admin (Stockage)
    if(window.LBC_INT && window.LBC_INT.addBoxReservation){
      window.LBC_INT.addBoxReservation({
        client: ((CLIENT.firstName||'')+' '+(CLIENT.lastName||'')).trim() || 'Client',
        clientEmail: (window.LBC_SB && window.LBC_SB.user && window.LBC_SB.user.email) || '',
        tier: confirm.key, size: confirm.size, price: confirm.price,
        startDate: startDate||'', months: libre?null:months, libre: !!libre,
        moveId: CLIENT.ref||''
      });
    }
    showToast && showToast(`Box ${confirm.key} réservé (dès le ${dStr}, ${dureeLabel}) — votre conseiller vous recontacte`);
  };
  const fermer = () => { setConfirm(null); setDone(false); setStartDate(''); setMonths(3); setLibre(false); };
  return (
    <div className="card card-pad">
      <h3 className="serif" style={{ fontSize:23, fontWeight:700, color:'var(--navy)', margin:'0 0 2px', letterSpacing:'-.01em' }}>Quatre tailles de box</h3>
      <p className="serif" style={{ fontSize:15.5, fontStyle:'italic', color:'var(--muted)', margin:'0 0 18px' }}>Un tarif clair, tout compris.</p>
      <div style={{ display:'grid', gridTemplateColumns: wide?'repeat(2,1fr)':'1fr', gap:14 }}>
        {BOX_TIERS.map(t=>{
          const current = t.key===currentTier;
          return (
            <div key={t.key} style={{ position:'relative', border:'1px solid '+(current?'var(--brand)':'var(--border-2)'), borderRadius:14,
              padding:'18px 18px 16px', background: current?'rgba(182,61,36,.03)':'var(--card)', display:'flex', flexDirection:'column' }}>
              {t.popular && !current && <span style={{ position:'absolute', top:-10, left:16, display:'inline-flex', alignItems:'center', gap:5, background:'var(--brand)', color:'#fff', fontSize:10, fontWeight:700, letterSpacing:'.05em', textTransform:'uppercase', padding:'3px 9px', borderRadius:999 }}><Icon name="star" size={10} />Le plus demandé</span>}
              {current && <span style={{ position:'absolute', top:-10, left:16, background:'var(--navy)', color:'var(--cream)', fontSize:10, fontWeight:700, letterSpacing:'.05em', textTransform:'uppercase', padding:'3px 9px', borderRadius:999 }}>Votre box</span>}
              <div className="serif" style={{ fontSize:34, fontWeight:700, color:'var(--navy)', lineHeight:1 }}>{t.key}</div>
              <div className="card-label" style={{ marginTop:8 }}>{t.size}</div>
              <div style={{ display:'flex', alignItems:'baseline', gap:5, marginTop:10 }}>
                <span className="tnum" style={{ fontSize:24, fontWeight:700, color:'var(--brand)' }}>{euroC(t.price)}</span>
                <span style={{ fontSize:12.5, color:'var(--muted)' }}>/ mois</span>
              </div>
              <div style={{ fontSize:12, color:'var(--faint)', marginTop:8 }}>{t.vol}</div>
              <div style={{ fontSize:12.5, color:'var(--ink-2)', marginTop:6, lineHeight:1.45, flex:1 }}>{t.desc}</div>
              <button className={current?'btn btn-ghost btn-sm':'btn btn-primary btn-sm'} disabled={current}
                style={{ marginTop:14, height:40, opacity: current?.6:1, cursor: current?'default':'pointer' }}
                onClick={()=> !current && setConfirm(t)}>
                {current ? 'Box actuel' : 'Réserver ce box'}</button>
            </div>
          );
        })}
      </div>
      <p style={{ fontSize:11.5, color:'var(--faint)', textAlign:'center', margin:'16px 0 0' }}>Sans engagement de durée · résiliable à tout moment avec 30 j de préavis</p>

      {confirm && (
        <div onMouseDown={e=>{ if(e.target===e.currentTarget) fermer(); }} style={{ position:'fixed', inset:0, zIndex:1000, background:'rgba(11,31,43,.5)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 }}>
          <div onMouseDown={e=>e.stopPropagation()} style={{ width:'min(440px,100%)', background:'var(--card)', borderRadius:16, boxShadow:'var(--shadow-pop)', overflow:'hidden' }}>
            {!done ? (<>
              <div style={{ padding:'20px 22px 0' }}>
                <div style={{ fontSize:17, fontWeight:700, color:'var(--ink)' }}>Confirmer votre réservation</div>
                <p style={{ fontSize:13, color:'var(--muted)', marginTop:4, lineHeight:1.5 }}>Vérifiez les détails avant d'envoyer votre demande. Aucun engagement, rien n'est débité maintenant.</p>
              </div>
              <div style={{ margin:'16px 22px', padding:'14px 16px', borderRadius:12, background:'var(--bg)', border:'1px solid var(--border)' }}>
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                  <div className="serif" style={{ fontSize:26, fontWeight:700, color:'var(--navy)' }}>Box {confirm.key}</div>
                  <div style={{ textAlign:'right' }}><span className="tnum" style={{ fontSize:20, fontWeight:700, color:'var(--brand)' }}>{euroC(confirm.price)}</span><span style={{ fontSize:12, color:'var(--muted)' }}> / mois</span></div>
                </div>
                <div style={{ fontSize:12.5, color:'var(--ink-2)', marginTop:6 }}>{confirm.size} · {confirm.vol}</div>
                <div style={{ fontSize:12.5, color:'var(--muted)', marginTop:4, lineHeight:1.45 }}>{confirm.desc}</div>
              </div>
              <div style={{ padding:'0 22px', display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 }}>
                <div>
                  <label style={{ fontSize:12, fontWeight:600, color:'var(--ink-2)', display:'block', marginBottom:5 }}>À partir de quelle date ?</label>
                  <input type="date" value={startDate} onChange={e=>setStartDate(e.target.value)} style={{ width:'100%', height:40, padding:'0 12px', borderRadius:10, border:'1px solid var(--border-2)', background:'var(--card)', color:'var(--ink)', fontSize:13.5 }} />
                </div>
                <div>
                  <label style={{ fontSize:12, fontWeight:600, color:'var(--ink-2)', display:'block', marginBottom:5 }}>Pour combien de temps ?</label>
                  <div style={{ display:'flex', alignItems:'center', gap:6, opacity: libre?.4:1 }}>
                    <button type="button" disabled={libre} onClick={()=>setMonths(m=>Math.max(1,m-1))} style={{ width:36, height:40, borderRadius:10, border:'1px solid var(--border-2)', background:'var(--card)', color:'var(--ink-2)', fontSize:18, cursor: libre?'default':'pointer' }}>−</button>
                    <div style={{ flex:1, height:40, borderRadius:10, border:'1px solid var(--border-2)', background:'var(--card)', display:'flex', alignItems:'center', justifyContent:'center', gap:5 }}>
                      <input type="number" min="1" disabled={libre} value={libre?'':months} onChange={e=>setMonths(Math.max(1,parseInt(e.target.value)||1))} style={{ width:36, textAlign:'right', border:'none', background:'transparent', color:'var(--ink)', fontSize:14, fontWeight:600 }} />
                      <span style={{ fontSize:13, color:'var(--muted)' }}>mois</span>
                    </div>
                    <button type="button" disabled={libre} onClick={()=>setMonths(m=>m+1)} style={{ width:36, height:40, borderRadius:10, border:'1px solid var(--border-2)', background:'var(--card)', color:'var(--ink-2)', fontSize:18, cursor: libre?'default':'pointer' }}>+</button>
                  </div>
                </div>
              </div>
              <label style={{ display:'flex', alignItems:'center', gap:9, margin:'12px 22px 0', fontSize:13, color:'var(--ink-2)', cursor:'pointer' }}>
                <input type="checkbox" checked={libre} onChange={e=>setLibre(e.target.checked)} />Durée indéterminée (sans engagement)</label>
              {!libre && <div style={{ margin:'12px 22px 0', padding:'10px 14px', borderRadius:10, background:'rgba(37,99,235,.07)', display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                <span style={{ fontSize:12.5, color:'var(--ink-2)' }}>Coût estimé ({months} mois)</span>
                <span className="tnum" style={{ fontSize:15, fontWeight:700, color:'var(--navy)' }}>{euroC(confirm.price*months)}</span>
              </div>}
              <div style={{ padding:'18px 22px 20px', display:'flex', gap:10, justifyContent:'flex-end' }}>
                <button className="btn btn-ghost btn-sm" onClick={fermer}>Annuler</button>
                <button className="btn btn-primary btn-sm" onClick={valider}><Icon name="check" size={15} />Confirmer la réservation</button>
              </div>
            </>) : (<>
              <div style={{ padding:'30px 24px', textAlign:'center' }}>
                <div style={{ width:54, height:54, borderRadius:'50%', background:'var(--effectue-bg)', color:'var(--effectue)', display:'flex', alignItems:'center', justifyContent:'center', margin:'0 auto' }}><Icon name="check" size={28} stroke={2.6} /></div>
                <div style={{ fontSize:17, fontWeight:700, color:'var(--ink)', marginTop:14 }}>Demande envoyée !</div>
                <p style={{ fontSize:13.5, color:'var(--ink-2)', marginTop:8, lineHeight:1.5 }}>Votre demande pour le <b>Box {confirm.key}</b>{startDate?<> à partir du <b>{new Date(startDate+'T00:00:00').toLocaleDateString('fr-FR',{day:'numeric',month:'long',year:'numeric'})}</b></>:''} ({dureeLabel.toLowerCase()}) est bien reçue. Votre conseiller LBC vous recontacte sous 24 h pour planifier le dépôt de vos affaires.</p>
                <button className="btn btn-primary btn-block" style={{ marginTop:18, height:44 }} onClick={fermer}>Parfait, merci</button>
              </div>
            </>)}
          </div>
        </div>
      )}
    </div>
  );
}

function ClientStockage({ wide, showToast, openDoc, requestRetrieval, boxApi }) {
  const s = CLIENT.storage;
  if (!s.active) return (
    <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
      <div className="card card-pad" style={{ textAlign:'center', background:'var(--cream)', border:'1px solid var(--cream-dim)' }}>
        <div style={{ fontSize:17, fontWeight:600, color:'var(--navy)' }}>Besoin de stocker vos affaires ?</div>
        <p style={{ fontSize:13.5, color:'var(--ink-2)', maxWidth:420, margin:'8px auto 0', lineHeight:1.5 }}>Nous gardons vos biens dans notre entrepôt sécurisé. Vous récupérez tout en une fois, le jour de votre choix.</p>
      </div>
      <BoxTiers currentTier={null} showToast={showToast} wide={wide} />
    </div>
  );
  const hero = (
    <div className="card" style={{ overflow:'hidden' }}>
      <div style={{ background:'var(--navy)', color:'var(--cream)', padding:'20px 22px', position:'relative', overflow:'hidden' }}>
        <div style={{ position:'absolute', top:-30, right:-20, width:150, height:150, borderRadius:'50%', background:'radial-gradient(circle, rgba(224,65,31,.18), transparent 65%)' }} />
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', position:'relative' }}>
          <div>
            <div style={{ fontSize:11.5, fontWeight:600, letterSpacing:'.06em', textTransform:'uppercase', opacity:.7 }}>Votre stockage</div>
            <div style={{ display:'flex', alignItems:'baseline', gap:10, marginTop:6, flexWrap:'wrap' }}>
              <span className="serif" style={{ fontSize:30, fontWeight:700, whiteSpace:'nowrap', lineHeight:1 }}>{s.box}</span>
              <span style={{ fontSize:13, opacity:.8, whiteSpace:'nowrap' }}>{s.size}</span>
            </div>
            <div style={{ fontSize:13, opacity:.78, marginTop:3 }}>{s.volume}</div>
          </div>
          <span style={{ display:'inline-flex', alignItems:'center', gap:6, fontSize:12, fontWeight:600, padding:'4px 11px', borderRadius:999, background:'var(--effectue-bg)', color:'var(--effectue)' }}><span style={{ width:7, height:7, borderRadius:'50%', background:'var(--effectue)' }} />Stocké</span>
        </div>
        <div style={{ display:'flex', gap:26, marginTop:18, position:'relative', flexWrap:'wrap' }}>
          <div><div style={{ fontSize:11, opacity:.65 }}>Loyer mensuel</div><div className="tnum" style={{ fontSize:18, fontWeight:700 }}>{euroC(s.price)}</div></div>
          <div><div style={{ fontSize:11, opacity:.65 }}>Depuis</div><div style={{ fontSize:15, fontWeight:600, marginTop:2 }}>{s.since}</div></div>
          {s.nextBill && <div><div style={{ fontSize:11, opacity:.65 }}>Prochain prélèvement</div><div style={{ fontSize:15, fontWeight:600, marginTop:2 }}>{new Date(s.nextBill+'T00:00:00').toLocaleDateString('fr-FR',{day:'numeric',month:'long'})}</div></div>}
        </div>
      </div>
    </div>
  );
  const managed = (
    <div className="card card-pad">
      <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)', marginBottom:6 }}>Stockage géré par LBC</div>
      <p style={{ fontSize:13, color:'var(--muted)', margin:'0 0 14px', lineHeight:1.5 }}>Pas de self-stockage : vos affaires restent à l'abri dans notre entrepôt sécurisé jusqu'à la récupération.</p>
      {[['shield','Entrepôt sécurisé',s.site+' · surveillance 24/7'],['package','Conservation intégrale','Vos biens sont scellés et inventoriés à l\'entrée'],['truck','Récupération sur demande','Nous vous livrons ou organisons un rendez-vous, en une fois']].map(([ic,t,d],i)=>(
        <div key={i} style={{ display:'flex', gap:12, padding:'11px 0', borderBottom: i<2?'1px solid var(--border)':'none' }}>
          <span style={{ width:34, height:34, borderRadius:9, background:'var(--bg)', color:'var(--navy)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}><Icon name={ic} size={17} /></span>
          <div><div style={{ fontSize:13.5, fontWeight:600, color:'var(--ink)' }}>{t}</div><div style={{ fontSize:12.5, color:'var(--muted)', marginTop:1, lineHeight:1.45 }}>{d}</div></div>
        </div>
      ))}
      <div style={{ marginTop:14, padding:'12px 14px', borderRadius:11, background:'rgba(37,99,235,.07)' }}>
        <div style={{ fontSize:12.5, fontWeight:700, color:'#2563EB' }}>💳 Facturation automatique</div>
        <div style={{ fontSize:12.5, color:'var(--ink-2)', marginTop:4, lineHeight:1.5 }}>{euroC(s.price)} / mois, prélevé automatiquement{s.startDate?(' le '+new Date(s.startDate+'T00:00:00').getDate()+' de chaque mois'):''}.{s.nextBill?(' Prochain : '+new Date(s.nextBill+'T00:00:00').toLocaleDateString('fr-FR',{day:'numeric',month:'long'})+'.'):''} Sans engagement, résiliable avec 30 j de préavis.</div>
      </div>
      <button className="btn btn-primary btn-block" style={{ marginTop:14, height:46 }} onClick={requestRetrieval}><Icon name="truck" size={17} />Demander la récupération</button>
      <button className="btn btn-ghost btn-block" style={{ marginTop:9, height:44 }} onClick={()=>openDoc&&openDoc('storage-invoice')}><Icon name="receipt" size={16} />Facture du mois (PDF)</button>
    </div>
  );
  const inventory = <BoxOverview boxName={s.box} items={boxApi.items} capacity={8} editable={false} />;
  if (wide) return (
    <div style={{ display:'flex', flexDirection:'column', gap:16 }}>
      {hero}
      <div style={grid2(true)}>{managed}{inventory}</div>
      <BoxTiers currentTier={s.tier} showToast={showToast} wide={wide} />
    </div>
  );
  return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{hero}{managed}{inventory}<BoxTiers currentTier={s.tier} showToast={showToast} wide={wide} /></div>;
}

/* ============== PARRAINAGE ============== */
function ClientParrainage({ wide, showToast }) {
  const r = CLIENT.referral;
  const [copied,setCopied]=useC(false);
  const copy = ()=>{ navigator.clipboard?.writeText(r.code).catch(()=>{}); setCopied(true); showToast&&showToast('Code de parrainage copié'); setTimeout(()=>setCopied(false),1800); };
  const hero = (
    <div style={{ background:'linear-gradient(135deg,#C24527,#B63D24 55%,#8E2E18)', borderRadius:20, padding:'24px 24px 22px', color:'#fff', position:'relative', overflow:'hidden' }}>
      <div style={{ position:'absolute', top:-30, right:-20, width:160, height:160, borderRadius:'50%', background:'radial-gradient(circle, rgba(255,255,255,.16), transparent 65%)' }} />
      <div style={{ position:'relative' }}>
        <span style={{ display:'inline-flex', alignItems:'center', gap:7, fontSize:12, fontWeight:600, padding:'4px 11px', borderRadius:999, background:'rgba(255,255,255,.16)' }}><Icon name="gift" size={14} />Parrainage</span>
        <h2 style={{ fontSize:24, fontWeight:700, margin:'14px 0 6px', letterSpacing:'-.01em' }}>Parrainez, gagnez {euroC(r.reward)}</h2>
        <p style={{ fontSize:13.5, opacity:.92, margin:0, lineHeight:1.5, maxWidth:340 }}>Vos proches déménagent ? Offrez-leur {euroC(r.reward)} de réduction — et recevez {euroC(r.reward)} dès qu'ils déménagent avec LBC.</p>
      </div>
    </div>
  );
  const codeCard = (
    <div className="card card-pad">
      <div style={{ fontSize:13, color:'var(--muted)', marginBottom:8 }}>Votre code de parrainage</div>
      <div style={{ display:'flex', gap:10 }}>
        <div className="mono" style={{ flex:1, display:'flex', alignItems:'center', justifyContent:'center', fontSize:22, fontWeight:700, letterSpacing:'.14em', color:'var(--navy)', background:'var(--cream)', border:'1px dashed var(--brand)', borderRadius:12, padding:'12px 0' }}>{r.code}</div>
        <button className="btn btn-primary" style={{ width:52, padding:0 }} onClick={copy}><Icon name={copied?'check':'copy'} size={18} /></button>
      </div>
      <div style={{ display:'flex', gap:9, marginTop:12 }}>
        <button className="btn btn-ghost btn-block btn-sm" style={{ height:42 }} onClick={()=>showToast&&showToast('Lien d\'invitation partagé')}><Icon name="mail" size={15} />Inviter par email</button>
        <button className="btn btn-ghost btn-block btn-sm" style={{ height:42 }} onClick={()=>showToast&&showToast('Lien copié pour partage')}><Icon name="external" size={15} />Partager le lien</button>
      </div>
    </div>
  );
  const how = (
    <div className="card card-pad">
      <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)', marginBottom:14 }}>Comment ça marche</div>
      {[['Partagez votre code','Envoyez-le à un proche qui déménage.'],['Il déménage avec LBC','Il bénéficie de '+euroC(r.reward)+' de réduction.'],['Vous êtes récompensé','Vous recevez '+euroC(r.reward)+' de crédit.']].map(([t,d],i)=>(
        <div key={i} style={{ display:'flex', gap:13, marginBottom: i<2?14:0 }}>
          <span style={{ width:28, height:28, borderRadius:'50%', background:'var(--navy)', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontWeight:700, fontSize:13, flexShrink:0 }}>{i+1}</span>
          <div><div style={{ fontSize:14, fontWeight:600, color:'var(--ink)' }}>{t}</div><div style={{ fontSize:12.5, color:'var(--muted)', marginTop:1 }}>{d}</div></div>
        </div>
      ))}
    </div>
  );
  const friends = (
    <div className="card" style={{ overflow:'hidden' }}>
      <div style={{ padding:'16px 18px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'center' }}>
        <span style={{ fontSize:15, fontWeight:600, color:'var(--ink)' }}>Mes filleuls</span>
        <span style={{ fontSize:13, fontWeight:600, color:'var(--effectue)' }}>{euroC(r.earned)} gagnés</span>
      </div>
      {r.friends.map((f,i)=>(
        <div key={i} style={{ display:'flex', alignItems:'center', gap:12, padding:'13px 18px', borderBottom: i<r.friends.length-1?'1px solid var(--border)':'none' }}>
          <Avatar initials={f.name.split(' ').map(x=>x[0]).join('')} size={34} color="var(--navy)" />
          <div style={{ flex:1, minWidth:0 }}><div style={{ fontSize:14, fontWeight:600, color:'var(--ink)' }}>{f.name}</div><div style={{ fontSize:12.5, color:'var(--muted)' }}>{f.city}</div></div>
          {f.earned>0 ? <span className="badge b-effectue"><Icon name="check" size={12} stroke={2.4} />+{euroC(f.earned)}</span> : <span className="badge b-accepte">{f.status}</span>}
        </div>
      ))}
    </div>
  );
  if (wide) return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{hero}<div style={grid2(true)}><div style={{ display:'flex', flexDirection:'column', gap:16 }}>{codeCard}{how}</div>{friends}</div></div>;
  return <div style={{ display:'flex', flexDirection:'column', gap:16 }}>{hero}{codeCard}{how}{friends}</div>;
}

/* ============== AIDE ============== */
function ClientAide({ showToast }){
  const faqs = [
    ['Puis-je modifier la date ?','Oui, jusqu\'à 7 jours avant le déménagement, contactez votre conseiller.'],
    ['Quand dois-je payer ?','Aucun prélèvement avant le jour J. Le solde est réglé à la livraison.'],
    ['Que se passe-t-il en cas de casse ?','La Formule Complète inclut une assurance tous risques sur la valeur déclarée.'],
    ['Comment fonctionne le stockage ?','Vous accédez à votre box 7j/7 avec votre code. Le loyer est mensuel, sans engagement.'],
  ];
  const [open,setOpen]=useC(0);
  const [msg,setMsg]=useC(''); const [sent,setSent]=useC(false); const [busy,setBusy]=useC(false);
  const ownerEmail = (window.LBC_INT && window.LBC_INT.store.db.settings && window.LBC_INT.store.db.settings.email) || 'contact@lbcdemenagement.com';
  const phone = (CLIENT.advisor && CLIENT.advisor.phone) || '';
  const advisor = (CLIENT.advisor && CLIENT.advisor.name) || 'LBC Déménagement';
  const send=()=>{ if(!msg.trim()){ return; } setBusy(true);
    try{
      fetch('https://formsubmit.co/ajax/'+ownerEmail, { method:'POST', headers:{ 'Content-Type':'application/json', 'Accept':'application/json' },
        body: JSON.stringify({ _subject:'💬 Message client — '+((CLIENT.firstName||'')+' '+(CLIENT.lastName||'')).trim(), _template:'table',
          'Client':((CLIENT.firstName||'')+' '+(CLIENT.lastName||'')).trim()||'—', 'Dossier':CLIENT.ref||'—', 'Trajet':(CLIENT.from||'?')+' → '+(CLIENT.to||'?'), 'Message':msg }) })
      .then(()=>{ setSent(true); setBusy(false); showToast && showToast('Message envoyé'); }, ()=>{ setBusy(false); showToast && showToast('Envoi impossible, réessayez ou appelez-nous'); });
    }catch(e){ setBusy(false); }
  };
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:16, maxWidth:620, margin:'0 auto' }}>
      {/* Appel direct — le plus simple */}
      <div className="card" style={{ padding:'20px 22px', display:'flex', alignItems:'center', gap:16, background:'var(--navy)', color:'var(--cream)' }}>
        <img src="assets/mascot.png" alt="" width={50} height={50} style={{ borderRadius:'50%' }} />
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontSize:16, fontWeight:700 }}>Une question ? Appelez-nous</div>
          <div style={{ fontSize:12.5, opacity:.8, marginTop:2 }}>{advisor} vous répond directement{phone?' · '+phone:''}.</div>
        </div>
        {phone && <a href={'tel:'+phone.replace(/\s/g,'')} className="btn btn-sm" style={{ background:'var(--brand)', color:'#fff', height:42, fontSize:14, padding:'0 18px' }}><Icon name="phone" size={16} />Appeler</a>}
      </div>

      {/* Message -> arrive directement dans la boîte mail LBC */}
      <div className="card card-pad">
        <div style={{ fontSize:15, fontWeight:600, color:'var(--ink)' }}>Ou écrivez-nous</div>
        <p style={{ fontSize:12.5, color:'var(--muted)', margin:'4px 0 12px' }}>Votre message arrive directement chez nous. <b>Réponse rapide</b>, par téléphone ou email.</p>
        {sent ? (
          <div style={{ display:'flex', alignItems:'center', gap:12, padding:'16px 18px', borderRadius:12, background:'var(--effectue-bg)', border:'1px solid #BFE6CF' }}>
            <span style={{ color:'var(--effectue)', display:'flex' }}><Icon name="check" size={22} stroke={2.4} /></span>
            <div style={{ fontSize:13.5, color:'#0F6B43' }}>Message envoyé ! On vous recontacte très vite{CLIENT.firstName?', '+CLIENT.firstName:''}.</div>
          </div>
        ) : (<>
          <textarea value={msg} onChange={e=>setMsg(e.target.value)} placeholder="Votre question, une précision sur le déménagement…" style={{ width:'100%', minHeight:110, padding:'12px 14px', borderRadius:11, border:'1px solid var(--border-2)', background:'var(--card)', color:'var(--ink)', fontSize:13.5, resize:'vertical' }} />
          <button className="btn btn-primary btn-block" style={{ height:46, marginTop:12 }} disabled={busy||!msg.trim()} onClick={send}><Icon name="mail" size={16} />{busy?'Envoi…':'Envoyer le message'}</button>
        </>)}
      </div>
      <div className="card" style={{ overflow:'hidden' }}>
        {faqs.map(([q,a],i)=>(
          <div key={i} style={{ borderBottom: i<faqs.length-1?'1px solid var(--border)':'none' }}>
            <button onClick={()=>setOpen(o=>o===i?-1:i)} style={{ width:'100%', display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, padding:'15px 18px', textAlign:'left' }}>
              <span style={{ fontSize:14, fontWeight:500, color:'var(--ink)' }}>{q}</span>
              <Icon name="chevronD" size={16} style={{ color:'var(--faint)', flexShrink:0, transform: open===i?'rotate(180deg)':'none', transition:'.18s' }} />
            </button>
            {open===i && <div className="fade-in" style={{ padding:'0 18px 16px', fontSize:13.5, color:'var(--muted)', lineHeight:1.55 }}>{a}</div>}
          </div>
        ))}
      </div>
    </div>
  );
}

/* ============== SHELL ============== */
const CLIENT_NAV = [
  { key:'suivi', label:'Suivi', icon:'truck' },
  { key:'devis', label:'Devis', icon:'fileText' },
  { key:'jourj', label:'Jour J', icon:'calendar' },
  { key:'stockage', label:'Stockage', icon:'package' },
  { key:'parrainage', label:'Parrainage', icon:'gift' },
];
const CLIENT_TITLES = { suivi:'Suivi de votre déménagement', devis:'Votre devis', jourj:'Le jour J', stockage:'Votre stockage', parrainage:'Parrainage', aide:'Aide & contact' };

function ClientBody({ screen, go, status, accept, wide, showToast, payment, paySolde, soldePaid, openDoc, requestRetrieval, boxApi, chatApi }) {
  switch(screen){
    case 'devis': return <ClientDevis status={status} accept={accept} wide={wide} payment={payment} openDoc={openDoc} go={go} />;
    case 'jourj': return <ClientJourJ status={status} wide={wide} payment={payment} soldePaid={soldePaid} paySolde={paySolde} showToast={showToast} />;
    case 'stockage': return <ClientStockage wide={wide} showToast={showToast} openDoc={openDoc} requestRetrieval={requestRetrieval} boxApi={boxApi} />;
    case 'parrainage': return <ClientParrainage wide={wide} showToast={showToast} />;
    case 'aide': return <ClientAide showToast={showToast} chatApi={chatApi} />;
    default: return <ClientSuivi status={status} go={go} wide={wide} payment={payment} soldePaid={soldePaid} paySolde={paySolde} openDoc={openDoc} />;
  }
}

function ClientApp({ screen, go, status, accept, mobile, showToast, payment, paySolde, soldePaid, openDoc, requestRetrieval, boxApi, chatApi }) {
  if (!mobile) {
    // DESKTOP — full web page
    return (
      <div style={{ height:'100%', display:'flex', flexDirection:'column', background:'var(--bg)' }}>
        <header style={{ flexShrink:0, height:64, background:'rgba(255,255,255,.9)', backdropFilter:'blur(8px)', borderBottom:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'space-between', padding:'0 32px', position:'sticky', top:0, zIndex:20 }}>
          <div style={{ display:'flex', alignItems:'center', gap:28 }}>
            <Logo size={20} showSub={false} color="var(--navy)" />
            <nav style={{ display:'flex', gap:4 }}>
              {CLIENT_NAV.map(n=>{
                const active = screen===n.key;
                return <button key={n.key} onClick={()=>go(n.key)} style={{ display:'flex', alignItems:'center', gap:7, fontSize:13.5, fontWeight:500, padding:'8px 13px', borderRadius:9, color: active?'var(--brand)':'var(--ink-2)', background: active?'rgba(182,61,36,.08)':'transparent', transition:'.14s' }}><Icon name={n.icon} size={16} />{n.label}</button>;
              })}
            </nav>
          </div>
          <div style={{ display:'flex', alignItems:'center', gap:14 }}>
            <button onClick={()=>go('aide')} style={{ display:'flex', alignItems:'center', gap:7, fontSize:13, fontWeight:500, color: screen==='aide'?'var(--brand)':'var(--ink-2)' }}><Icon name="headset" size={17} />Aide</button>
            <div style={{ width:1, height:22, background:'var(--border-2)' }} />
            <span style={{ fontSize:13, fontWeight:500, color:'var(--ink-2)' }}>Bonjour {CLIENT.firstName}</span>
            <Avatar initials={((CLIENT.firstName||'')[0]||'')+((CLIENT.lastName||'')[0]||'')} size={34} color="var(--navy)" />
          </div>
        </header>
        <main className="scroll" style={{ flex:1, overflowY:'auto', padding:'30px 32px 56px' }}>
          <div style={{ maxWidth:860, margin:'0 auto' }} key={screen}>
            <div className="fade-in">
              <h1 className="page-title" style={{ marginBottom:20 }}>{CLIENT_TITLES[screen]}</h1>
              <ClientBody screen={screen} go={go} status={status} accept={accept} wide showToast={showToast} payment={payment} paySolde={paySolde} soldePaid={soldePaid} openDoc={openDoc} requestRetrieval={requestRetrieval} boxApi={boxApi} chatApi={chatApi} />
            </div>
          </div>
        </main>
      </div>
    );
  }
  // MOBILE — phone with bottom nav
  return (
    <div style={{ height:'100%', display:'flex', flexDirection:'column', background:'var(--bg)' }}>
      <header style={{ flexShrink:0, background:'#fff', borderBottom:'1px solid var(--border)', paddingTop:48, paddingBottom:13, paddingLeft:18, paddingRight:18, display:'flex', alignItems:'center', justifyContent:'space-between' }}>
        <Logo size={18} showSub={false} color="var(--navy)" />
        <div style={{ display:'flex', alignItems:'center', gap:12 }}>
          <button onClick={()=>go('aide')} style={{ color: screen==='aide'?'var(--brand)':'var(--ink-2)', display:'flex' }}><Icon name="headset" size={20} /></button>
          <span style={{ fontSize:12.5, fontWeight:600, color:'var(--ink-2)' }}>Bonjour {CLIENT.firstName}</span>
          <Avatar initials={((CLIENT.firstName||'')[0]||'')+((CLIENT.lastName||'')[0]||'')} size={30} color="var(--navy)" />
        </div>
      </header>
      <div className="scroll" style={{ flex:1, overflowY:'auto', padding:'18px 16px 26px' }} key={screen}>
        <div className="fade-in"><ClientBody screen={screen} go={go} status={status} accept={accept} wide={false} showToast={showToast} payment={payment} paySolde={paySolde} soldePaid={soldePaid} openDoc={openDoc} requestRetrieval={requestRetrieval} boxApi={boxApi} chatApi={chatApi} /></div>
      </div>
      <div style={{ flexShrink:0, background:'rgba(255,255,255,.96)', backdropFilter:'blur(10px)', borderTop:'1px solid var(--border)', display:'flex', alignItems:'center', justifyContent:'space-around', padding:'8px 4px 26px' }}>
        {CLIENT_NAV.map(n=>{
          const active = screen===n.key;
          return <button key={n.key} onClick={()=>go(n.key)} style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:4, padding:'4px 8px', color: active?'var(--brand)':'var(--faint)', minWidth:50 }}><Icon name={n.icon} size={20} stroke={active?2.2:1.8} /><span style={{ fontSize:10, fontWeight: active?600:500 }}>{n.label}</span></button>;
        })}
      </div>
    </div>
  );
}

Object.assign(window, { ClientApp, CLIENT, CLIENT_DEVIS_LINES: DEVIS_LINES, CLIENT_INCLUS: FORMULE_INCLUS });
