/* bundle 4/4 */

/* ╔══ pages-settings.jsx ══╗ */
/* global React, FormPage, FormNav, FormSection, Field, FieldRow,
          Input, Textarea, MoneyInput, DateInput, Select,
          Toggle, RadioGroup, CheckboxGroup, Segmented, FileDrop, ColorSwatch,
          FormFooter, Banner, fmtFCFA */

/* ═══════════════════════════════════════════════════════════════════════
   PARAMÈTRES · 6 sections, tous les patterns du form-kit
   ═══════════════════════════════════════════════════════════════════════ */

const SETTINGS_NAV = [
  { id:"abonnement",    label:"Abonnement",         badge:"Agence" },
  { id:"agence",        label:"Agence" },
  { id:"profil",        label:"Mon profil" },
  { id:"equipe",        label:"Équipe & rôles",     badge:4 },
  { id:"fiscalite",     label:"Fiscalité",          badge:"!" },
  { id:"commissions",   label:"Commissions" },
  { id:"notifications", label:"Notifications" },
  { id:"banques",       label:"Comptes bancaires",  badge:4 },
  { id:"securite",      label:"Sécurité" },
  { id:"api",           label:"API & intégrations" },
];

function SettingsPage() {
  const [section, setSection] = React.useState("abonnement");
  const [dirty, setDirty] = React.useState(false);
  const [saving, setSaving] = React.useState(false);

  // Centralised state — single source of truth for every form section
  const [state, setState] = React.useState({
    // Agence
    agencyName: "BA Immo SARL",
    agencyLegalName: "BA Immobilier Services SARL",
    agencyAddress: "12 Rue Carnot, Plateau, Dakar",
    agencyPhone: "+221 33 821 47 80",
    agencyEmail: "contact@baimmo.sn",
    agencyWebsite: "baimmo.sn",
    agencyLogo: "BA",
    agencyAccent: "#2563EB",
    agencyAbout: "Cabinet de gestion locative spécialisé dans le résidentiel haut de gamme dakarois. Sous gestion : 8 biens, 52 lots, 6 bailleurs.",

    // Profil
    userFirstName: "Seynabou",
    userLastName: "Ndiaye",
    userRole: "DAF",
    userPhone: "+221 77 612 04 18",
    userEmail: "s.ndiaye@baimmo.sn",
    userTimezone: "Africa/Dakar",
    userLang: "fr",
    userTheme: "dark",

    // Fiscalité
    ninea: "005 442 8 K3",
    rccm: "SN DKR 2018 B 9214",
    vatRegime: "reel-normal",
    vatRate: "18",
    vatNumber: "SN18014425",
    fiscalYearStart: "01-01",
    syscohada: true,
    fec: true,

    // Taxes locatives
    tomEnabled: true,
    tomMode: "forfait-lot",       // forfait-lot | pct-loyer
    tomAmount: "6000",            // FCFA / mois / lot si forfait
    tomRate: "1.0",               // % loyer si pct-loyer
    tomBilling: "monthly",        // monthly | quarterly | annual
    tomPassthrough: true,         // répercuté au locataire ?

    tlvEnabled: true,
    tlvScope: "commercial",       // commercial | habitation | tous
    tlvRate: "6",                 // % de la valeur locative annuelle
    tlvBilling: "annual",

    // Branding documents
    brandingPrimary: "#2563EB",
    brandingSecondary: "#0F7A4C",
    brandingMark: true,           // afficher logo en filigrane
    brandingHeader: "BA Immo · 12 Rue Carnot, Plateau, Dakar · NINEA 005 442 8 K3",
    brandingFooter: "Quittance émise via Logestimmo · valeur libératoire après encaissement effectif · article 528 du Code des Obligations Civiles et Commerciales",
    brandingSignatureName: "Seynabou Ndiaye",
    brandingSignatureTitle: "Directrice administrative",
    brandingSignatureFile: null,
    rentTerm: "echu",             // echu | echoir
    rentTermDay: "5",             // jour d'émission de la quittance

    // Commissions
    commissionRateNu: String(Math.round(window.COMMISSION_DEFAULTS.nu * 100)),
    commissionRateMeuble: String(Math.round(window.COMMISSION_DEFAULTS.meuble * 100)),
    commissionBase: "encaisse",
    minCommission: "12000",
    invoiceDay: "5",
    invoiceDelay: "30",
    relanceFlow: ["sms", "email", "whatsapp"],

    // Notifications
    notifPayments: true,
    notifOverdue: true,
    notifLeaseEnding: true,
    notifBankReconciliation: false,
    notifMonthlyReport: true,
    notifChannel: "email-whatsapp",
    notifDailyDigest: true,

    // Sécurité
    twoFactor: true,
    sessionDuration: "30",
    ipRestriction: false,
    auditLog: true,

    // API
    webhookUrl: "https://api.baimmo.sn/webhook/wave",
    apiVersion: "v2",
  });

  const set = (k, v) => { setState(s => ({...s, [k]:v})); setDirty(true); };

  function onSave() {
    setSaving(true);
    setTimeout(() => { setSaving(false); setDirty(false); }, 900);
  }
  function onCancel() { setDirty(false); /* would reset state in a real app */ }

  return (
    <>
      <FormPage
        title="Paramètres"
        subtitle="Configuration de l'agence, comptes utilisateurs, paramètres fiscaux et comptables"
        nav={<FormNav items={SETTINGS_NAV} current={section} onChange={setSection}/>}
      >
        {section === "abonnement"   && <AbonnementSection/>}
        {section === "agence"        && <AgenceSection state={state} set={set}/>}
        {section === "profil"        && <ProfilSection state={state} set={set}/>}
        {section === "equipe"        && <EquipeSection/>}
        {section === "fiscalite"     && <FiscaliteSection state={state} set={set}/>}
        {section === "commissions"   && <CommissionsSection state={state} set={set}/>}
        {section === "notifications" && <NotificationsSection state={state} set={set}/>}
        {section === "banques"       && <BanquesSection/>}
        {section === "securite"      && <SecuriteSection state={state} set={set}/>}
        {section === "api"           && <APISection state={state} set={set}/>}

        <FormFooter dirty={dirty} saving={saving} onSave={onSave} onCancel={onCancel}/>
      </FormPage>
    </>
  );
}

/* ─── AGENCE ─── */
function AgenceSection({ state, set }) {
  return (
    <>
      <FormSection
        title="Identité de l'agence"
        subtitle="Ces informations apparaissent sur les quittances, récépissés et exports comptables remis aux bailleurs et locataires."
        footer={<span>Dernière modification · 12 mars 2026 par K. Diop</span>}
      >
        <FieldRow columns="120px 1fr">
          <Field label="Logo & couleur">
            <div style={{
              width:80, height:80, borderRadius:8,
              background: state.agencyAccent, color:"#fff",
              display:"grid", placeItems:"center",
              fontSize:28, fontWeight:600, letterSpacing:"-0.02em",
            }}>{state.agencyLogo}</div>
            <div style={{marginTop:8}}>
              <ColorSwatch
                value={state.agencyAccent}
                onChange={v=>set("agencyAccent",v)}
                options={["#2563EB","#0F7A4C","#9A2A2A","#7C3AED","#0F766E","#0B1220"]}
              />
            </div>
          </Field>
          <div>
            <Field label="Nom commercial" required>
              <Input value={state.agencyName} onChange={e=>set("agencyName",e.target.value)}/>
            </Field>
            <Field label="Raison sociale" hint="Telle qu'enregistrée au RCCM">
              <Input value={state.agencyLegalName} onChange={e=>set("agencyLegalName",e.target.value)}/>
            </Field>
          </div>
        </FieldRow>

        <Field label="Adresse du siège" required>
          <Input value={state.agencyAddress} onChange={e=>set("agencyAddress",e.target.value)}/>
        </Field>

        <FieldRow>
          <Field label="Téléphone" required>
            <Input value={state.agencyPhone} onChange={e=>set("agencyPhone",e.target.value)} icon="☎"/>
          </Field>
          <Field label="Email de contact" required>
            <Input type="email" value={state.agencyEmail} onChange={e=>set("agencyEmail",e.target.value)} icon="@"/>
          </Field>
        </FieldRow>

        <Field label="Site web" optional>
          <Input value={state.agencyWebsite} onChange={e=>set("agencyWebsite",e.target.value)} icon="↗"/>
        </Field>

        <Field label="Présentation publique" hint="Visible sur la page agence et dans les emails sortants. 1-3 phrases recommandées.">
          <Textarea rows={3} value={state.agencyAbout} onChange={e=>set("agencyAbout",e.target.value)}/>
        </Field>
      </FormSection>

      <BrandingSection state={state} set={set}/>
    </>
  );
}

/* ─── BRANDING DES DOCUMENTS ─── */
function BrandingSection({ state, set }) {
  return (
    <>
      <FormSection
        title="Branding des documents"
        subtitle="Personnalisation des quittances, récépissés, CRG et bordereaux que vous générez. Les modifications s'appliquent à tous les documents émis à partir d'aujourd'hui."
      >
        <FieldRow columns="1fr 1fr">
          <Field label="Couleur principale" hint="Utilisée pour les bandeaux, totaux et accents des documents PDF.">
            <ColorSwatch
              value={state.brandingPrimary}
              onChange={v=>set("brandingPrimary",v)}
              options={["#2563EB","#0F7A4C","#9A2A2A","#7C3AED","#0F766E","#0B1220","#D97757","#1F6E4A"]}
            />
            <div className="mono" style={{fontSize:11, color:"var(--d-ink-4)", marginTop:8}}>{state.brandingPrimary}</div>
          </Field>
          <Field label="Couleur secondaire" hint="Filets, séparateurs et libellés discrets.">
            <ColorSwatch
              value={state.brandingSecondary}
              onChange={v=>set("brandingSecondary",v)}
              options={["#0F7A4C","#5B6577","#7C3AED","#9A2A2A","#2563EB","#E0A74A","#0F766E","#0B1220"]}
            />
            <div className="mono" style={{fontSize:11, color:"var(--d-ink-4)", marginTop:8}}>{state.brandingSecondary}</div>
          </Field>
        </FieldRow>

        <Field
          label="En-tête de document"
          hint="S'affiche en haut de chaque quittance, juste sous le logo. Mentions légales obligatoires : raison sociale, adresse, NINEA.">
          <Textarea rows={2} value={state.brandingHeader} onChange={e=>set("brandingHeader",e.target.value)}/>
        </Field>

        <Field
          label="Pied de page / mentions légales"
          hint="S'affiche au bas de chaque document. Texte court avec article de référence et formule de libération.">
          <Textarea rows={2} value={state.brandingFooter} onChange={e=>set("brandingFooter",e.target.value)}/>
        </Field>

        <Toggle
          label="Filigrane logo en arrière-plan"
          hint="Affiche votre logo en sous-impression sur les documents PDF officiels (anti-falsification visuelle)."
          value={state.brandingMark}
          onChange={v=>set("brandingMark",v)}
        />
      </FormSection>

      <FormSection
        title="Signature électronique"
        subtitle="Signature appliquée automatiquement aux quittances, CRG et récépissés. Valeur juridique conforme à l'article 79 du Code des Obligations OHADA."
      >
        <FieldRow>
          <Field label="Nom du signataire" required>
            <Input value={state.brandingSignatureName} onChange={e=>set("brandingSignatureName",e.target.value)}/>
          </Field>
          <Field label="Qualité / fonction" required>
            <Input value={state.brandingSignatureTitle} onChange={e=>set("brandingSignatureTitle",e.target.value)}/>
          </Field>
        </FieldRow>

        <Field label="Signature scannée" hint="PNG transparent ou SVG · 400×120 px recommandé · 200 ko max.">
          <FileDrop
            label="Glisser votre signature scannée ou cliquer pour parcourir"
            hint="Format PNG/SVG · sera apposée en bas à droite des documents"
            accept="image/png,image/svg+xml"
            files={state.brandingSignatureFile ? [state.brandingSignatureFile] : []}
            onChange={fs=>set("brandingSignatureFile", fs[0] || null)}
          />
        </Field>
      </FormSection>

      <FormSection
        title="Mode de quittancement"
        subtitle="Détermine quand la quittance est émise par rapport à la période de location. Choix structurant pour la comptabilité et la trésorerie."
      >
        <Field label="Période de loyer" required>
          <RadioGroup
            value={state.rentTerm}
            onChange={v=>set("rentTerm",v)}
            options={[
              {
                value:"echoir",
                label:"À terme à échoir",
                description:"Le loyer est dû en début de période — la quittance d'avril est émise le 1er avril. Modèle le plus répandu au Sénégal et en zone OHADA.",
              },
              {
                value:"echu",
                label:"À terme échu",
                description:"Le loyer est dû en fin de période — la quittance d'avril est émise le 30 avril. Utilisé pour les baux commerciaux et certains baux haut-de-gamme.",
              },
            ]}
          />
        </Field>

        <FieldRow>
          <Field label="Jour d'émission" hint={state.rentTerm === "echoir" ? "Du mois en cours" : "Du mois suivant"}>
            <Input value={state.rentTermDay} onChange={e=>set("rentTermDay",e.target.value)} suffix="du mois"/>
          </Field>
          <Field label="Aperçu prochaine quittance">
            <div style={{
              padding:"8px 12px", border:"1px solid var(--d-line)", borderRadius:5,
              background:"var(--d-sunken)", fontSize:12, color:"var(--d-ink-2)",
              fontFamily:"var(--font-mono)",
            }}>
              {state.rentTerm === "echoir"
                ? `Quittance avril 2026 · émise le ${state.rentTermDay} avr 2026`
                : `Quittance avril 2026 · émise le ${state.rentTermDay} mai 2026`}
            </div>
          </Field>
        </FieldRow>
      </FormSection>

      <FormSection
        title="Aperçu quittance"
        subtitle="Rendu en temps réel avec votre branding actuel. Téléchargez un PDF de test pour vérifier le rendu chez vos locataires.">
        <QuittanceBrandingPreview state={state}/>
        <div style={{display:"flex", gap:8, marginTop:14}}>
          <button className="btn btn-secondary" style={{padding:"6px 12px"}} onClick={()=>lgiToast("Quittance de test générée (PDF)","ok")}>↓ Télécharger PDF de test</button>
          <button className="btn btn-ghost" style={{padding:"6px 12px"}} onClick={()=>lgiToast("Exemple envoyé par email","ok")}>Envoyer un exemple par email →</button>
        </div>
      </FormSection>
    </>
  );
}

function QuittanceBrandingPreview({ state }) {
  return (
    <div style={{
      background:"#fff", color:"#0B1220", borderRadius:6, overflow:"hidden",
      border:"1px solid var(--d-line)",
      fontFamily:"var(--font-sans)", fontSize:11,
      maxWidth:560, position:"relative",
    }}>
      {/* Watermark */}
      {state.brandingMark && (
        <div style={{
          position:"absolute", inset:0, display:"grid", placeItems:"center",
          pointerEvents:"none", opacity:0.05, fontSize:120, fontWeight:700,
          color: state.brandingPrimary, letterSpacing:"-0.04em",
        }}>{state.agencyLogo}</div>
      )}

      {/* Colored band */}
      <div style={{
        height:6, background:state.brandingPrimary,
      }}/>

      {/* Header */}
      <div style={{padding:"16px 22px 12px", borderBottom:"1px solid #E4E7EC", display:"flex", justifyContent:"space-between", alignItems:"flex-start", position:"relative"}}>
        <div style={{display:"flex", gap:10, alignItems:"center"}}>
          <div style={{
            width:36, height:36, borderRadius:6,
            background:state.brandingPrimary, color:"#fff",
            display:"grid", placeItems:"center",
            fontSize:14, fontWeight:600,
          }}>{state.agencyLogo}</div>
          <div>
            <div style={{fontSize:13, fontWeight:600, color:"#0B1220"}}>{state.agencyName}</div>
            <div style={{fontSize:10, color:"#5B6577", marginTop:1}}>{state.brandingHeader}</div>
          </div>
        </div>
        <div style={{textAlign:"right"}}>
          <div style={{fontSize:9.5, color:"#8E97A6", textTransform:"uppercase", letterSpacing:"0.08em", fontWeight:600}}>
            Quittance n°
          </div>
          <div style={{fontSize:12, fontFamily:"IBM Plex Mono", color:"#0B1220", marginTop:2}}>QT-2026-04-A203</div>
        </div>
      </div>

      {/* Title band */}
      <div style={{
        padding:"14px 22px",
        background: state.brandingPrimary + "0F",
        borderBottom: `1px solid ${state.brandingSecondary}30`,
        position:"relative",
      }}>
        <div style={{fontSize:9.5, color: state.brandingSecondary, textTransform:"uppercase", letterSpacing:"0.1em", fontWeight:700, marginBottom:3}}>
          Quittance de loyer · {state.rentTerm === "echoir" ? "Terme à échoir" : "Terme échu"}
        </div>
        <div style={{fontSize:17, fontWeight:600, color:"#0B1220", letterSpacing:"-0.01em"}}>
          Loyer · Avril 2026
        </div>
      </div>

      {/* Body */}
      <div style={{padding:"14px 22px", display:"grid", gridTemplateColumns:"1fr 1fr", gap:18, position:"relative"}}>
        <div>
          <div style={{fontSize:9, color:"#8E97A6", textTransform:"uppercase", letterSpacing:"0.08em", marginBottom:4}}>Locataire</div>
          <div style={{fontSize:11.5, fontWeight:500, color:"#0B1220"}}>Mariama Ndiaye</div>
          <div style={{fontSize:10.5, color:"#5B6577", marginTop:1}}>Rés. Teranga · A-203 · Plateau, Dakar</div>
        </div>
        <div>
          <div style={{fontSize:9, color:"#8E97A6", textTransform:"uppercase", letterSpacing:"0.08em", marginBottom:4}}>Bailleur</div>
          <div style={{fontSize:11.5, fontWeight:500, color:"#0B1220"}}>Horizon SCI</div>
          <div style={{fontSize:10.5, color:"#5B6577", marginTop:1}}>Représenté par {state.agencyName}</div>
        </div>
      </div>

      {/* Lines */}
      <div style={{padding:"6px 22px 14px", position:"relative"}}>
        {[
          { k:"Loyer principal", v:"240 000" },
          ...(state.tomEnabled ? [{ k:"Taxe d'enlèvement des ordures ménagères (TOM)", v: state.tomMode === "forfait-lot" ? state.tomAmount : Math.round(240000 * Number(state.tomRate||0)/100).toLocaleString("fr-FR") }] : []),
          { k:"Charges récupérables", v:"15 000" },
        ].map((r, i) => (
          <div key={i} style={{
            display:"flex", justifyContent:"space-between", padding:"6px 0",
            borderBottom:"1px solid #EEF0F3", fontSize:11, color:"#2B3344",
          }}>
            <span>{r.k}</span>
            <span style={{fontFamily:"IBM Plex Mono", fontVariantNumeric:"tabular-nums"}}>{r.v} FCFA</span>
          </div>
        ))}
        <div style={{
          display:"flex", justifyContent:"space-between", padding:"10px 0 0",
          fontSize:13, fontWeight:600, color: state.brandingPrimary,
        }}>
          <span>Total dû</span>
          <span style={{fontFamily:"IBM Plex Mono"}}>
            {(240000 + 15000 + (state.tomEnabled ? (state.tomMode === "forfait-lot" ? Number(state.tomAmount||0) : Math.round(240000 * Number(state.tomRate||0)/100)) : 0)).toLocaleString("fr-FR")} FCFA
          </span>
        </div>
      </div>

      {/* Signature */}
      <div style={{
        display:"flex", justifyContent:"space-between", alignItems:"flex-end",
        padding:"16px 22px 14px", borderTop:"1px solid #E4E7EC", position:"relative",
      }}>
        <div style={{fontSize:9.5, color:"#8E97A6", lineHeight:1.5, maxWidth:260}}>
          {state.brandingFooter}
        </div>
        <div style={{textAlign:"right"}}>
          <div style={{
            fontFamily:"'Brush Script MT', cursive", fontSize:24, color: state.brandingSecondary,
            transform:"rotate(-3deg)", marginBottom:2, fontStyle:"italic",
          }}>{state.brandingSignatureName.split(" ").map(w => w[0]).join("")}</div>
          <div style={{fontSize:10.5, fontWeight:500, color:"#0B1220"}}>{state.brandingSignatureName}</div>
          <div style={{fontSize:9.5, color:"#5B6577"}}>{state.brandingSignatureTitle}</div>
        </div>
      </div>
    </div>
  );
}

/* ─── PROFIL ─── */
function ProfilSection({ state, set }) {
  return (
    <>
      <FormSection title="Mon profil" subtitle="Informations personnelles affichées dans l'application et sur les documents que vous générez.">
        <FieldRow>
          <Field label="Prénom" required>
            <Input value={state.userFirstName} onChange={e=>set("userFirstName",e.target.value)}/>
          </Field>
          <Field label="Nom" required>
            <Input value={state.userLastName} onChange={e=>set("userLastName",e.target.value)}/>
          </Field>
        </FieldRow>
        <Field label="Fonction">
          <Input value={state.userRole} onChange={e=>set("userRole",e.target.value)}/>
        </Field>
        <FieldRow>
          <Field label="Téléphone professionnel">
            <Input value={state.userPhone} onChange={e=>set("userPhone",e.target.value)} icon="☎"/>
          </Field>
          <Field label="Email professionnel" required>
            <Input value={state.userEmail} onChange={e=>set("userEmail",e.target.value)} icon="@"/>
          </Field>
        </FieldRow>
      </FormSection>

      <FormSection title="Préférences" subtitle="Langue, fuseau horaire et apparence.">
        <FieldRow columns="1fr 1fr 1fr">
          <Field label="Langue">
            <Select value={state.userLang} onChange={v=>set("userLang",v)} options={[
              {value:"fr", label:"Français"},
              {value:"en", label:"English"},
              {value:"wo", label:"Wolof"},
            ]}/>
          </Field>
          <Field label="Fuseau horaire">
            <Select value={state.userTimezone} onChange={v=>set("userTimezone",v)} options={[
              "Africa/Dakar","Africa/Abidjan","Europe/Paris","UTC",
            ]}/>
          </Field>
          <Field label="Thème">
            <Segmented value={state.userTheme} onChange={v=>set("userTheme",v)} options={[
              {value:"dark", label:"Sombre"},
              {value:"light", label:"Clair"},
              {value:"auto", label:"Auto"},
            ]}/>
          </Field>
        </FieldRow>
      </FormSection>
    </>
  );
}

/* ─── ÉQUIPE ─── */
function EquipeSection() {
  const members = [
    { name:"K. Diop", role:"Directeur Administratif & Financier", email:"k.diop@baimmo.sn", lastSeen:"il y a 12 min", perms:["admin","compta","facturation"] },
    { name:"S. Ndiaye", role:"Responsable gestion", email:"s.ndiaye@baimmo.sn", lastSeen:"en ligne", perms:["gestion","facturation"] },
    { name:"A. Sarr", role:"Chargé de relances", email:"a.sarr@baimmo.sn", lastSeen:"il y a 1 h", perms:["relances","lecture"] },
    { name:"M. Ba", role:"Comptable cabinet (externe)", email:"m.ba@cabexp.sn", lastSeen:"il y a 3 j", perms:["compta-lecture"] },
  ];
  return (
    <FormSection
      title="Équipe & rôles"
      subtitle="Gérez les utilisateurs ayant accès à l'agence et leurs permissions par module."
      footer={<>
        <span>Plan Pro · jusqu'à 8 utilisateurs · {members.length} actifs</span>
        <button className="btn btn-primary" style={{padding:"5px 12px"}} onClick={()=>lgiToast("Invitation équipe — saisissez un email")}>+ Inviter un membre</button>
      </>}
    >
      <div style={{border:"1px solid var(--d-line)", borderRadius:6}}>
        {members.map((u, i) => (
          <div key={u.email} style={{
            display:"grid", gridTemplateColumns:"36px 1fr auto auto", gap:14,
            padding:"14px 16px", borderBottom: i < members.length - 1 ? "1px solid var(--d-line-2)" : "none",
            alignItems:"center",
          }}>
            <div className="avatar" style={{background:"var(--blue)", color:"#fff"}}>{u.name.split(" ").map(x=>x[0]).join("")}</div>
            <div>
              <div style={{fontSize:12.5, fontWeight:500}}>{u.name}</div>
              <div className="muted" style={{fontSize:11, marginTop:2}}>{u.role} · {u.email}</div>
              <div style={{display:"flex", gap:4, marginTop:6, flexWrap:"wrap"}}>
                {u.perms.map(p => (
                  <span key={p} style={{
                    fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:2,
                    background:"var(--d-elev)", color:"var(--d-ink-3)",
                    letterSpacing:"0.04em", textTransform:"uppercase",
                  }}>{p}</span>
                ))}
              </div>
            </div>
            <span style={{fontSize:11, color: u.lastSeen === "en ligne" ? "var(--pos-d)" : "var(--d-ink-4)", fontFamily:"var(--font-mono)"}}>{u.lastSeen}</span>
            <button className="btn btn-ghost" style={{padding:"4px 8px", fontSize:11.5}} onClick={()=>lgiToast("Réglage des permissions du membre")}>Permissions →</button>
          </div>
        ))}
      </div>
    </FormSection>
  );
}

/* ─── FISCALITÉ ─── */
function FiscaliteSection({ state, set }) {
  return (
    <>
      <Banner tone="warn" title="Déclaration TVA mensuelle à transmettre">
        La déclaration de TVA d'avril 2026 doit être télédéclarée à la DGID avant le 15 mai 2026. Montant à reverser estimé : <b style={{color:"var(--d-ink)"}}>{fmtFCFA(213_540)}</b>.
      </Banner>

      <FormSection title="Identifiants fiscaux" subtitle="Informations qui figurent obligatoirement sur les factures et déclarations.">
        <FieldRow>
          <Field label="NINEA" required hint="Numéro d'Identification National des Entreprises et Associations">
            <Input value={state.ninea} onChange={e=>set("ninea",e.target.value)} style={{fontFamily:"var(--font-mono)"}}/>
          </Field>
          <Field label="RCCM" required hint="Registre du Commerce et du Crédit Mobilier">
            <Input value={state.rccm} onChange={e=>set("rccm",e.target.value)} style={{fontFamily:"var(--font-mono)"}}/>
          </Field>
        </FieldRow>
        <Field label="N° identification TVA" optional>
          <Input value={state.vatNumber} onChange={e=>set("vatNumber",e.target.value)} style={{fontFamily:"var(--font-mono)"}}/>
        </Field>
      </FormSection>

      <FormSection title="Régime fiscal" subtitle="Détermine le calcul de la TVA, les obligations déclaratives et le format des exports.">
        <Field label="Régime TVA" required>
          <RadioGroup value={state.vatRegime} onChange={v=>set("vatRegime",v)} options={[
            { value:"reel-normal", label:"Réel normal", description:"TVA collectée déclarée mensuellement · obligatoire au-delà de 100 M FCFA CA" },
            { value:"reel-simplifie", label:"Réel simplifié", description:"Déclaration trimestrielle · CA inférieur à 100 M FCFA" },
            { value:"franchise", label:"Franchise TVA", description:"Pas de TVA collectée · CA inférieur à 50 M FCFA" },
          ]}/>
        </Field>
        <FieldRow>
          <Field label="Taux TVA standard" hint="Sénégal : 18%">
            <Input value={state.vatRate} onChange={e=>set("vatRate",e.target.value)} suffix="%"/>
          </Field>
          <Field label="Début exercice fiscal" hint="JJ-MM · 01-01 = année civile">
            <Input value={state.fiscalYearStart} onChange={e=>set("fiscalYearStart",e.target.value)} style={{fontFamily:"var(--font-mono)"}}/>
          </Field>
        </FieldRow>
      </FormSection>

      <FormSection title="Normes comptables" subtitle="Sortie comptable conforme aux exigences locales et internationales.">
        <Toggle label="SYSCOHADA" hint="Plan comptable applicable au Sénégal et à l'ensemble de l'espace OHADA. Active les codes 1-8 et la structure de balance OHADA dans les exports." value={state.syscohada} onChange={v=>set("syscohada",v)}/>
        <Toggle label="Génération FEC (Fichier des Écritures Comptables)" hint="Format de fichier requis lors des contrôles fiscaux DGID · structure ASCII tabulée." value={state.fec} onChange={v=>set("fec",v)}/>
      </FormSection>

      <FormSection
        title="Taxes locatives"
        subtitle="Taxes ajoutées automatiquement aux quittances ou aux CRG bailleurs selon le régime du bail. Vous pouvez surcharger les valeurs par bien dans la fiche du bien."
        footer={<>
          <span>2 taxes actives · répercutées au locataire pour la TOM, à la charge du bailleur pour la TLV</span>
          <button className="btn btn-ghost" style={{padding:"4px 10px", fontSize:11.5}} onClick={()=>lgiToast("Barème fiscal DGID")}>Voir le barème DGID →</button>
        </>}
      >
        {/* TOM */}
        <div style={{
          padding:"14px 16px", border:"1px solid var(--d-line)", borderRadius:6,
          background:"var(--d-sunken)", marginBottom:14,
        }}>
          <div style={{display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom: state.tomEnabled ? 14 : 0}}>
            <div style={{flex:1}}>
              <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:3}}>
                <span style={{fontSize:13, fontWeight:600, color:"var(--d-ink)"}}>TOM</span>
                <span className="mono" style={{
                  fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:2,
                  background:"var(--d-elev)", color:"var(--d-ink-3)",
                  letterSpacing:"0.04em", textTransform:"uppercase",
                }}>Taxe d'enlèvement des ordures ménagères</span>
              </div>
              <div style={{fontSize:11.5, color:"var(--d-ink-3)", lineHeight:1.5, maxWidth:520}}>
                Taxe municipale due au titre du service de collecte des déchets. Habituellement répercutée au locataire et facturée mensuellement avec le loyer.
              </div>
            </div>
            <Toggle label="" value={state.tomEnabled} onChange={v=>set("tomEnabled",v)}/>
          </div>

          {state.tomEnabled && (
            <>
              <Field label="Mode de calcul">
                <RadioGroup
                  layout="row"
                  value={state.tomMode}
                  onChange={v=>set("tomMode",v)}
                  options={[
                    { value:"forfait-lot", label:"Forfait par lot", description:"Montant fixe / lot / mois · barème municipal de Dakar 2024" },
                    { value:"pct-loyer",   label:"Pourcentage du loyer", description:"Variable selon la valeur locative" },
                  ]}
                />
              </Field>
              <FieldRow columns="1fr 1fr 1fr">
                {state.tomMode === "forfait-lot" ? (
                  <Field label="Montant / lot / mois" required>
                    <MoneyInput value={state.tomAmount} onChange={e=>set("tomAmount",e.target.value)}/>
                  </Field>
                ) : (
                  <Field label="Taux applicable" required>
                    <Input value={state.tomRate} onChange={e=>set("tomRate",e.target.value)} suffix="% du loyer"/>
                  </Field>
                )}
                <Field label="Périodicité de facturation">
                  <Select value={state.tomBilling} onChange={v=>set("tomBilling",v)} options={[
                    {value:"monthly",   label:"Mensuelle (avec le loyer)"},
                    {value:"quarterly", label:"Trimestrielle"},
                    {value:"annual",    label:"Annuelle"},
                  ]}/>
                </Field>
                <Field label="Répercussion">
                  <Segmented
                    value={state.tomPassthrough ? "tenant" : "owner"}
                    onChange={v=>set("tomPassthrough", v === "tenant")}
                    options={[
                      {value:"tenant", label:"Locataire"},
                      {value:"owner",  label:"Bailleur"},
                    ]}
                  />
                </Field>
              </FieldRow>
            </>
          )}
        </div>

        {/* TLV */}
        <div style={{
          padding:"14px 16px", border:"1px solid var(--d-line)", borderRadius:6,
          background:"var(--d-sunken)",
        }}>
          <div style={{display:"flex", justifyContent:"space-between", alignItems:"flex-start", marginBottom: state.tlvEnabled ? 14 : 0}}>
            <div style={{flex:1}}>
              <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:3}}>
                <span style={{fontSize:13, fontWeight:600, color:"var(--d-ink)"}}>TLV</span>
                <span className="mono" style={{
                  fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:2,
                  background:"var(--d-elev)", color:"var(--d-ink-3)",
                  letterSpacing:"0.04em", textTransform:"uppercase",
                }}>Taxe sur la valeur locative</span>
              </div>
              <div style={{fontSize:11.5, color:"var(--d-ink-3)", lineHeight:1.5, maxWidth:520}}>
                Taxe due par le bailleur sur la valeur locative annuelle des locaux donnés en location. Recensée dans le CRG annuel et reportée dans le bordereau de versement.
              </div>
            </div>
            <Toggle label="" value={state.tlvEnabled} onChange={v=>set("tlvEnabled",v)}/>
          </div>

          {state.tlvEnabled && (
            <>
              <Field label="Champ d'application">
                <RadioGroup
                  layout="row"
                  value={state.tlvScope}
                  onChange={v=>set("tlvScope",v)}
                  options={[
                    { value:"commercial",  label:"Baux commerciaux uniquement", description:"Standard · TLV due sur locaux à usage de vente, services, bureaux" },
                    { value:"habitation",  label:"Habitation uniquement",       description:"Si la commune l'impose sur le résidentiel" },
                    { value:"tous",        label:"Tous les baux",               description:"Forcer l'application sur l'ensemble du parc" },
                  ]}
                />
              </Field>
              <FieldRow>
                <Field label="Taux" required hint="Sénégal · 6% sur la valeur locative annuelle (baux commerciaux)">
                  <Input value={state.tlvRate} onChange={e=>set("tlvRate",e.target.value)} suffix="% / an"/>
                </Field>
                <Field label="Périodicité de déclaration">
                  <Select value={state.tlvBilling} onChange={v=>set("tlvBilling",v)} options={[
                    {value:"annual",    label:"Annuelle (recommandé)"},
                    {value:"quarterly", label:"Trimestrielle"},
                    {value:"monthly",   label:"Mensuelle (provision)"},
                  ]}/>
                </Field>
              </FieldRow>
            </>
          )}
        </div>
      </FormSection>
    </>
  );
}

/* ─── COMMISSIONS ─── */
function CommissionsSection({ state, set }) {
  // Met à jour à la fois l'état Paramètres et la source de vérité globale (lue par le formulaire de bail)
  const setRate = (key, globalKey) => (e) => {
    const raw = e.target.value.replace(",", ".").replace(/[^0-9.]/g, "");
    set(key, raw);
    const num = Number(raw);
    if (!isNaN(num)) window.COMMISSION_DEFAULTS[globalKey] = num / 100;
  };
  return (
    <>
      <FormSection title="Commission par défaut selon le type de location" subtitle="Le meublé est généralement commissionné plus haut que le nu (rotation, inventaire, états des lieux plus fréquents). Le taux est pré-rempli à la création d'un bail selon son type, et reste personnalisable par bailleur ou par bien.">
        <FieldRow>
          <Field label="Location nue" required hint="Résidentiel, professionnel, commercial">
            <Input value={state.commissionRateNu} onChange={setRate("commissionRateNu", "nu")} suffix="%"/>
          </Field>
          <Field label="Location meublée" required hint="Bail meublé · inventaire annexé">
            <Input value={state.commissionRateMeuble} onChange={setRate("commissionRateMeuble", "meuble")} suffix="%"/>
          </Field>
          <Field label="Commission minimum / mois">
            <MoneyInput value={state.minCommission} onChange={e=>set("minCommission",e.target.value)}/>
          </Field>
        </FieldRow>
        <Field label="Base de calcul" required>
          <RadioGroup layout="row" value={state.commissionBase} onChange={v=>set("commissionBase",v)} options={[
            { value:"encaisse", label:"Sur encaissé", description:"Recommandé · commission perçue uniquement sur les loyers réellement encaissés" },
            { value:"facture",  label:"Sur facturé", description:"Commission perçue sur les quittances émises, même impayées" },
          ]}/>
        </Field>
      </FormSection>

      <FormSection title="Cycle de facturation" subtitle="Calendrier d'émission des quittances locataires et de versement aux bailleurs.">
        <FieldRow columns="1fr 1fr 1fr">
          <Field label="Jour d'émission" hint="Du mois pour la quittance">
            <Input value={state.invoiceDay} onChange={e=>set("invoiceDay",e.target.value)} suffix="du mois"/>
          </Field>
          <Field label="Échéance loyer" hint="Jours après émission">
            <Input value={state.invoiceDelay} onChange={e=>set("invoiceDelay",e.target.value)} suffix="jours"/>
          </Field>
          <Field label="Versement bailleur">
            <Select value="30" options={[
              {value:"25", label:"Le 25 du mois"},
              {value:"30", label:"Le 30 du mois"},
              {value:"05-suivant", label:"Le 5 du mois suivant"},
            ]}/>
          </Field>
        </FieldRow>
      </FormSection>

      <FormSection title="Workflow de relance" subtitle="Canaux activés et ordre d'envoi pour les locataires en retard. La relance se déclenche automatiquement à J+3.">
        <Field label="Canaux activés" hint="Les canaux sont activés dans l'ordre. Si non-réponse à J+7 → relance suivante.">
          <CheckboxGroup value={state.relanceFlow} onChange={v=>set("relanceFlow",v)} options={[
            { value:"sms",      label:"SMS (J+3)",        description:"Coût : 25 FCFA / message · taux de lecture élevé" },
            { value:"email",    label:"Email (J+5)",      description:"Gratuit · seulement si email locataire renseigné" },
            { value:"whatsapp", label:"WhatsApp (J+7)",   description:"Recommandé · meilleur taux de réponse au Sénégal" },
            { value:"call",     label:"Appel agence (J+14)", description:"Bascule sur un membre de l'équipe (rôle Relances)" },
            { value:"mep",      label:"Mise en demeure (J+30)", description:"Génère un courrier recommandé · 4 500 FCFA" },
          ]}/>
        </Field>
      </FormSection>
    </>
  );
}

/* ─── NOTIFICATIONS ─── */
function NotificationsSection({ state, set }) {
  return (
    <>
      <FormSection title="Canaux de notification" subtitle="Comment voulez-vous recevoir les alertes importantes ?">
        <Field label="Canal préféré">
          <RadioGroup layout="row" value={state.notifChannel} onChange={v=>set("notifChannel",v)} options={[
            { value:"email-only",     label:"Email seulement" },
            { value:"email-whatsapp", label:"Email + WhatsApp" },
            { value:"app-only",       label:"Application seulement" },
          ]}/>
        </Field>
        <Toggle label="Digest quotidien" hint="Récapitulatif des paiements reçus, impayés et alertes envoyé chaque matin à 8h." value={state.notifDailyDigest} onChange={v=>set("notifDailyDigest",v)}/>
      </FormSection>

      <FormSection title="Alertes individuelles" subtitle="Recevoir une notification immédiate pour chaque événement.">
        <Toggle label="Paiement reçu" hint="À chaque encaissement via Wave, Orange Money ou virement bancaire." value={state.notifPayments} onChange={v=>set("notifPayments",v)}/>
        <Toggle label="Loyer impayé" hint="Dès qu'un locataire atteint J+3 sans paiement." value={state.notifOverdue} onChange={v=>set("notifOverdue",v)}/>
        <Toggle label="Bail en fin de période" hint="60 jours avant l'échéance d'un contrat de bail." value={state.notifLeaseEnding} onChange={v=>set("notifLeaseEnding",v)}/>
        <Toggle label="Rapprochement bancaire" hint="Lorsqu'un écart est détecté entre les paiements enregistrés et les relevés." value={state.notifBankReconciliation} onChange={v=>set("notifBankReconciliation",v)}/>
        <Toggle label="Rapport mensuel" hint="Synthèse complète envoyée le 1er de chaque mois." value={state.notifMonthlyReport} onChange={v=>set("notifMonthlyReport",v)}/>
      </FormSection>
    </>
  );
}

/* ─── BANQUES ─── */
function BanquesSection() {
  const accounts = [
    { type:"banque", name:"CBAO · BA Immo · ••• 8841", balance:18_420_000, sync:"il y a 12 min", role:"Compte principal", color:"#0056A6" },
    { type:"mobile", name:"Wave Business",              balance:4_140_000,  sync:"auto · temps réel", role:"Mobile money", color:"#1DC3F8" },
    { type:"mobile", name:"Orange Money · Pro",         balance:2_810_000,  sync:"auto · temps réel", role:"Mobile money", color:"#FF7A00" },
    { type:"caisse", name:"Caisse espèces · siège",     balance:980_000,    sync:"saisie manuelle",   role:"Espèces",      color:"#7B8494" },
  ];
  return (
    <FormSection
      title="Comptes bancaires & mobile money"
      subtitle="Comptes synchronisés pour le rapprochement automatique des paiements."
      footer={<>
        <span>Solde consolidé · {fmtFCFA(accounts.reduce((s,a)=>s+a.balance,0))}</span>
        <button className="btn btn-primary" style={{padding:"5px 12px"}} onClick={()=>lgiToast("Connexion d’un compte bancaire / Mobile Money")}>+ Connecter un compte</button>
      </>}
    >
      <div style={{border:"1px solid var(--d-line)", borderRadius:6}}>
        {accounts.map((a, i) => (
          <div key={i} style={{
            display:"grid", gridTemplateColumns:"40px 1fr auto auto", gap:14,
            padding:"14px 16px", borderBottom: i < accounts.length - 1 ? "1px solid var(--d-line-2)" : "none",
            alignItems:"center",
          }}>
            <div style={{width:40, height:40, borderRadius:6, background:`${a.color}1F`, color:a.color, display:"grid", placeItems:"center", fontSize:11, fontWeight:700, letterSpacing:"0.04em"}}>
              {a.type === "banque" ? "BNK" : a.type === "mobile" ? (a.name.includes("Wave") ? "WV" : "OM") : "ESP"}
            </div>
            <div>
              <div style={{fontSize:12.5, fontWeight:500}}>{a.name}</div>
              <div className="muted" style={{fontSize:11, marginTop:2}}>{a.role} · {a.sync}</div>
            </div>
            <div className="mono" style={{fontSize:13, fontWeight:500}}>{fmtFCFA(a.balance)}</div>
            <button className="btn btn-ghost" style={{padding:"4px 8px", fontSize:11.5}} onClick={()=>lgiToast("Configuration du compte")}>Configurer →</button>
          </div>
        ))}
      </div>
    </FormSection>
  );
}

/* ─── SÉCURITÉ ─── */
function SecuriteSection({ state, set }) {
  return (
    <>
      <FormSection title="Authentification" subtitle="Renforcez l'accès à votre compte.">
        <Toggle label="Double authentification (2FA)" hint="Un code à 6 chiffres vous sera demandé à chaque connexion · application Authy / Google Authenticator." value={state.twoFactor} onChange={v=>set("twoFactor",v)}/>
        <Field label="Durée de session avant déconnexion">
          <Segmented value={state.sessionDuration} onChange={v=>set("sessionDuration",v)} options={[
            {value:"15", label:"15 min"},
            {value:"30", label:"30 min"},
            {value:"60", label:"1 heure"},
            {value:"480", label:"8 heures"},
          ]}/>
        </Field>
        <Toggle label="Restriction par adresse IP" hint="N'autoriser la connexion qu'aux adresses IP explicitement listées (paramètre avancé)." value={state.ipRestriction} onChange={v=>set("ipRestriction",v)}/>
      </FormSection>

      <FormSection title="Mot de passe" subtitle="Dernière modification · 24 février 2026 · il y a 53 jours.">
        <FieldRow>
          <Field label="Mot de passe actuel" required>
            <Input type="password" placeholder="••••••••"/>
          </Field>
          <Field label="Nouveau mot de passe" required hint="12 caractères min · 1 majuscule, 1 chiffre, 1 caractère spécial">
            <Input type="password" placeholder="••••••••"/>
          </Field>
        </FieldRow>
      </FormSection>

      <FormSection title="Journal d'audit" subtitle="Trace toutes les actions sensibles : connexions, créations/suppressions, versements, exports comptables.">
        <Toggle label="Journalisation activée" hint="Recommandé · conservation 24 mois · exportable au format CSV pour les contrôles." value={state.auditLog} onChange={v=>set("auditLog",v)}/>
        <Banner tone="info" title="Activité récente">
          18 connexions ces 7 derniers jours · 3 exports comptables · 1 modification de RIB bailleur. <a style={{color:"var(--blue-d)", textDecoration:"underline", textUnderlineOffset:2}}>Voir le journal complet →</a>
        </Banner>
      </FormSection>
    </>
  );
}

/* ─── API ─── */
function APISection({ state, set }) {
  return (
    <>
      <FormSection title="Webhook entrant" subtitle="URL appelée par Wave et Orange Money lors d'un encaissement pour rapprochement en temps réel.">
        <Field label="URL Webhook" hint="Doit retourner un statut 200 sous 5 secondes. HMAC signature obligatoire.">
          <Input value={state.webhookUrl} onChange={e=>set("webhookUrl",e.target.value)} style={{fontFamily:"var(--font-mono)", fontSize:12}}/>
        </Field>
        <Field label="Version API">
          <Segmented value={state.apiVersion} onChange={v=>set("apiVersion",v)} options={[
            {value:"v1", label:"v1 (legacy)"},
            {value:"v2", label:"v2 (actuelle)"},
            {value:"v3-beta", label:"v3 (beta)"},
          ]}/>
        </Field>
      </FormSection>

      <FormSection title="Clés d'API" subtitle="Authentification pour les intégrations sortantes. Ne partagez jamais ces clés.">
        <Field label="Clé publique">
          <Input value="pk_live_4f2b...c812" readOnly style={{fontFamily:"var(--font-mono)", fontSize:12}}/>
        </Field>
        <Field label="Clé secrète">
          <Input type="password" value="sk_live_••••••••••••••••" readOnly style={{fontFamily:"var(--font-mono)", fontSize:12}}/>
        </Field>
        <div style={{display:"flex", gap:8, marginTop:-4}}>
          <button className="btn btn-secondary" style={{padding:"5px 10px", fontSize:11.5}} onClick={()=>lgiToast("Nouvelles clés API générées","warn")}>Régénérer les clés</button>
          <button className="btn btn-ghost" style={{padding:"5px 10px", fontSize:11.5}} onClick={()=>lgiToast("Documentation API")}>Documentation API →</button>
        </div>
      </FormSection>

      <FormSection title="Intégrations actives" subtitle="Connecteurs tiers vers vos outils.">
        {[
          { name:"Wave Business",     status:"connecté",   since:"depuis le 12 mars 2024", c:"#1DC3F8" },
          { name:"Orange Money Pro",  status:"connecté",   since:"depuis le 04 avril 2024", c:"#FF7A00" },
          { name:"Sage 100",          status:"configuré",  since:"export manuel mensuel", c:"#19A974" },
          { name:"WhatsApp Business", status:"non connecté", since:"requis pour les relances", c:"#25D366" },
        ].map((i, idx) => (
          <div key={i.name} style={{
            display:"grid", gridTemplateColumns:"10px 1fr auto auto", gap:14,
            padding:"12px 0", borderBottom: idx < 3 ? "1px solid var(--d-line-2)" : "none",
            alignItems:"center",
          }}>
            <span style={{width:8, height:8, borderRadius:50, background:i.c}}/>
            <div>
              <div style={{fontSize:12.5, fontWeight:500}}>{i.name}</div>
              <div className="muted" style={{fontSize:11, marginTop:2}}>{i.since}</div>
            </div>
            <span style={{
              fontSize:10.5, fontWeight:600, padding:"2px 8px", borderRadius:3,
              background: i.status === "connecté" ? "rgba(63,181,131,0.12)" : i.status === "configuré" ? "rgba(97,146,255,0.12)" : "rgba(249,115,22,0.12)",
              color: i.status === "connecté" ? "var(--pos-d)" : i.status === "configuré" ? "var(--blue-d)" : "var(--orange)",
              letterSpacing:"0.02em",
            }}>{i.status}</span>
            <button className="btn btn-ghost" style={{padding:"4px 8px", fontSize:11.5}} onClick={()=>lgiToast(i.status === "non connecté" ? "Connexion de l’intégration…" : "Gestion de l’intégration")}>{i.status === "non connecté" ? "Connecter →" : "Gérer →"}</button>
          </div>
        ))}
      </FormSection>
    </>
  );
}

/* ─── ABONNEMENT & FACTURATION ─── */
function AbonnementSection() {
  const [annual, setAnnual] = React.useState(true);
  const [currentPlan] = React.useState("agence");

  const PLANS = {
    solo:    { name: "Solo",    monthly: 0,      annual: 0,      lots: 20,      users: 1 },
    agence:  { name: "Agence",  monthly: 49000,  annual: 39000,  lots: 200,     users: 5 },
    cabinet: { name: "Cabinet", monthly: 129000, annual: 105000, lots: Infinity, users: Infinity },
  };

  // Live usage — would come from API
  const USAGE = {
    lots: 52,
    users: 3,
    invoicesMonth: 18,
    storageGB: 1.2,
  };

  const plan = PLANS[currentPlan];
  const monthlyAmount = annual ? plan.annual : plan.monthly;
  const lotPct = Math.min(100, Math.round((USAGE.lots / plan.lots) * 100));
  const userPct = Math.min(100, Math.round((USAGE.users / plan.users) * 100));

  const invoices = [
    { id: "FA-2026-04-018", date: "01 avr 2026", period: "Avril 2026",  amount: 39000, status: "payée",     method: "Wave Business" },
    { id: "FA-2026-03-018", date: "01 mar 2026", period: "Mars 2026",   amount: 39000, status: "payée",     method: "Wave Business" },
    { id: "FA-2026-02-018", date: "01 fév 2026", period: "Février 2026",amount: 39000, status: "payée",     method: "Wave Business" },
    { id: "FA-2026-01-018", date: "01 jan 2026", period: "Janvier 2026",amount: 39000, status: "payée",     method: "CBAO virement" },
    { id: "FA-2025-12-018", date: "01 déc 2025", period: "Décembre 2025",amount: 49000, status: "payée",    method: "CBAO virement" },
    { id: "FA-2025-11-018", date: "01 nov 2025", period: "Novembre 2025",amount: 49000, status: "payée",    method: "CBAO virement" },
  ];

  return (
    <>
      {/* CURRENT PLAN BANNER */}
      <section className="panel" style={{padding:0, overflow:"hidden"}}>
        <div style={{
          display:"grid", gridTemplateColumns:"1.4fr 1fr", gap:0,
          background:"linear-gradient(135deg, #0F1729 0%, #0A0E17 100%)",
          borderBottom:"1px solid var(--d-line)",
        }}>
          <div style={{padding:"24px 26px", borderRight:"1px solid var(--d-line)"}}>
            <div style={{display:"flex", alignItems:"center", gap:10, marginBottom:14}}>
              <span style={{
                fontSize:10, fontWeight:700, letterSpacing:"0.12em",
                color:"var(--orange)", textTransform:"uppercase",
              }}>Plan actuel</span>
              <span style={{
                fontSize:9.5, fontWeight:600, padding:"2px 7px", borderRadius:100,
                background:"rgba(63,181,131,0.14)", color:"var(--pos-d)",
                letterSpacing:"0.04em", textTransform:"uppercase",
              }}>Actif</span>
            </div>
            <div style={{display:"flex", alignItems:"baseline", gap:14, marginBottom:8}}>
              <span style={{fontSize:30, fontWeight:600, letterSpacing:"-0.02em", color:"var(--d-ink)"}}>{plan.name}</span>
              <span className="mono" style={{fontSize:22, color:"var(--d-ink)", fontWeight:500, letterSpacing:"-0.02em"}}>
                {fmtFCFA(monthlyAmount)}<span style={{color:"var(--d-ink-3)", fontSize:13, marginLeft:6, fontFamily:"var(--font-sans)"}}>/ mois</span>
              </span>
            </div>
            <div style={{fontSize:12, color:"var(--d-ink-3)", lineHeight:1.55}}>
              Facturation {annual ? "annuelle" : "mensuelle"} · prochaine échéance le <b style={{color:"var(--d-ink-2)"}}>1<sup>er</sup> mai 2026</b> · {fmtFCFA(annual ? monthlyAmount * 12 : monthlyAmount)} prélevés via <b style={{color:"var(--d-ink-2)"}}>Wave Business</b>.
            </div>
          </div>
          <div style={{padding:"24px 26px", display:"flex", flexDirection:"column", justifyContent:"center", gap:10}}>
            <button className="btn btn-primary" style={{justifyContent:"center"}} onClick={()=>lgiToast("Changement de plan")}>Passer au plan supérieur →</button>
            <button className="btn btn-ghost" style={{justifyContent:"center", fontSize:12}} onClick={()=>lgiToast("Devis téléchargé (PDF)","ok")}>Télécharger un devis</button>
            <button className="btn btn-ghost" style={{justifyContent:"center", fontSize:12, color:"var(--d-ink-4)"}} onClick={()=>lgiToast("Demande de résiliation — contactez le support","warn")}>Résilier l'abonnement</button>
          </div>
        </div>

        {/* USAGE BARS */}
        <div style={{display:"grid", gridTemplateColumns:"repeat(4, 1fr)", borderBottom:"1px solid var(--d-line)"}}>
          <UsageStat
            label="Lots gérés"
            value={USAGE.lots}
            limit={plan.lots}
            pct={lotPct}
            sub={`${plan.lots - USAGE.lots} disponibles`}
          />
          <UsageStat
            label="Utilisateurs"
            value={USAGE.users}
            limit={plan.users}
            pct={userPct}
            sub={`${plan.users - USAGE.users} sièges libres`}
          />
          <UsageStat
            label="Quittances · ce mois"
            value={USAGE.invoicesMonth}
            limit={null}
            sub="émises automatiquement"
            mono
          />
          <UsageStat
            label="Stockage"
            value={USAGE.storageGB.toFixed(1) + " Go"}
            limit={null}
            sub="sur 50 Go inclus"
            mono
            noBorder
          />
        </div>
      </section>

      {/* CHANGE PLAN */}
      <FormSection
        title="Changer de plan"
        subtitle="Vous pouvez passer à un plan supérieur immédiatement (proratisation) ou rétrograder à la fin de la période en cours."
      >
        {/* Billing cycle toggle */}
        <div style={{
          display:"flex", justifyContent:"space-between", alignItems:"center",
          padding:"10px 14px", marginBottom:14,
          background:"var(--d-sunken)", border:"1px solid var(--d-line)", borderRadius:6,
        }}>
          <div style={{fontSize:11.5, color:"var(--d-ink-3)"}}>
            Cycle de facturation
          </div>
          <div style={{display:"inline-flex", background:"var(--d-bg)", border:"1px solid var(--d-line)", borderRadius:100, padding:3}}>
            <button onClick={()=>setAnnual(false)} style={{
              padding:"5px 14px", fontSize:11.5, borderRadius:100, fontWeight:500,
              background: !annual ? "var(--d-elev)" : "transparent",
              color: !annual ? "var(--d-ink)" : "var(--d-ink-3)",
            }}>Mensuel</button>
            <button onClick={()=>setAnnual(true)} style={{
              padding:"5px 14px", fontSize:11.5, borderRadius:100, fontWeight:500,
              background: annual ? "var(--d-elev)" : "transparent",
              color: annual ? "var(--d-ink)" : "var(--d-ink-3)",
              display:"inline-flex", alignItems:"center", gap:6,
            }}>
              Annuel
              <span style={{
                fontFamily:"var(--font-mono)", fontSize:9.5, padding:"1px 5px", borderRadius:100,
                background:"rgba(249,115,22,0.18)", color:"var(--orange)", fontWeight:600,
              }}>−20%</span>
            </button>
          </div>
        </div>

        <div style={{display:"grid", gridTemplateColumns:"repeat(3, 1fr)", gap:10}}>
          <PlanCard
            id="solo" plan={PLANS.solo} annual={annual}
            current={currentPlan === "solo"}
            features={["20 lots max", "1 utilisateur", "Quittances PDF", "Wave & OM"]}
          />
          <PlanCard
            id="agence" plan={PLANS.agence} annual={annual}
            current={currentPlan === "agence"} featured
            features={["200 lots, puis 280 FCFA/lot", "5 utilisateurs", "Rapprochement auto", "Bordereaux & CRG", "Export OHADA"]}
          />
          <PlanCard
            id="cabinet" plan={PLANS.cabinet} annual={annual}
            current={currentPlan === "cabinet"}
            features={["Lots illimités", "Utilisateurs illimités", "SSO & API", "SLA 99,9%", "Account manager"]}
          />
        </div>
      </FormSection>

      {/* PAYMENT METHOD */}
      <FormSection
        title="Moyen de paiement"
        subtitle="Utilisé pour le prélèvement automatique de l'abonnement. Vous pouvez en ajouter plusieurs et choisir le défaut."
        footer={<>
          <span>Prochain prélèvement · 1<sup>er</sup> mai 2026 · {fmtFCFA(monthlyAmount)}</span>
          <button className="btn btn-secondary" style={{padding:"5px 12px"}} onClick={()=>lgiToast("Ajout d’un moyen de paiement")}>+ Ajouter un moyen de paiement</button>
        </>}
      >
        <div style={{border:"1px solid var(--d-line)", borderRadius:6}}>
          {[
            { type:"wave",     name:"Wave Business",          detail:"+221 77 612 04 18 · Seynabou Ndiaye", default:true,  c:"#1DC3F8", letters:"WV" },
            { type:"bank",     name:"CBAO virement",          detail:"SN012 01001 ••• 8841 · BA Immo SARL", default:false, c:"#0056A6", letters:"BNK" },
            { type:"card",     name:"Visa ••• 4218",          detail:"Expire 11/2027 · Seynabou Ndiaye",     default:false, c:"#1A1F71", letters:"VISA" },
          ].map((m, i, arr) => (
            <div key={m.type} style={{
              display:"grid", gridTemplateColumns:"44px 1fr auto auto", gap:14,
              padding:"14px 16px",
              borderBottom: i < arr.length - 1 ? "1px solid var(--d-line-2)" : "none",
              alignItems:"center",
            }}>
              <div style={{
                width:44, height:30, borderRadius:4,
                background:`${m.c}1F`, color:m.c,
                display:"grid", placeItems:"center",
                fontSize:10, fontWeight:700, letterSpacing:"0.04em",
              }}>{m.letters}</div>
              <div>
                <div style={{fontSize:12.5, fontWeight:500, display:"flex", alignItems:"center", gap:8}}>
                  {m.name}
                  {m.default && (
                    <span style={{
                      fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:2,
                      background:"rgba(63,181,131,0.12)", color:"var(--pos-d)",
                      letterSpacing:"0.04em", textTransform:"uppercase",
                    }}>Par défaut</span>
                  )}
                </div>
                <div className="muted" style={{fontSize:11, marginTop:2}}>{m.detail}</div>
              </div>
              <button className="btn btn-ghost" style={{padding:"4px 8px", fontSize:11.5, color: m.default ? "var(--d-ink-4)" : "var(--d-ink-3)"}} onClick={()=>!m.default&&lgiToast("Moyen de paiement défini par défaut","ok")}>
                {m.default ? "Défaut" : "Définir par défaut"}
              </button>
              <button className="btn btn-ghost" style={{padding:"4px 8px", fontSize:11.5}} onClick={()=>lgiToast("Modifier le moyen de paiement")}>Modifier →</button>
            </div>
          ))}
        </div>
      </FormSection>

      {/* BILLING DETAILS */}
      <FormSection
        title="Adresse de facturation"
        subtitle="Apparaît sur toutes les factures de Logestimmo qui vous sont émises."
      >
        <FieldRow>
          <Field label="Raison sociale">
            <Input value="BA Immobilier Services SARL" readOnly/>
          </Field>
          <Field label="NINEA">
            <Input value="005 442 8 K3" readOnly style={{fontFamily:"var(--font-mono)"}}/>
          </Field>
        </FieldRow>
        <Field label="Adresse">
          <Input value="12 Rue Carnot, Plateau, BP 2147, Dakar, Sénégal" readOnly/>
        </Field>
        <div style={{display:"flex", gap:8, marginTop:-4}}>
          <button className="btn btn-secondary" style={{padding:"5px 10px", fontSize:11.5}} onClick={()=>lgiToast("Modifier les coordonnées de facturation")}>Modifier</button>
          <span style={{fontSize:11, color:"var(--d-ink-4)", alignSelf:"center"}}>
            Synchronisé depuis l'identité de l'agence
          </span>
        </div>
      </FormSection>

      {/* INVOICES */}
      <FormSection
        title="Factures"
        subtitle="Historique de vos factures Logestimmo. Téléchargeables au format PDF, conformes aux mentions OHADA."
        footer={<>
          <span>{invoices.length} factures · total {fmtFCFA(invoices.reduce((s,i)=>s+i.amount,0))} sur 6 mois</span>
          <button className="btn btn-ghost" style={{padding:"5px 10px", fontSize:11.5}} onClick={()=>lgiToast("Archive ZIP des factures en préparation","ok")}>Exporter tout (ZIP) →</button>
        </>}
      >
        <div style={{border:"1px solid var(--d-line)", borderRadius:6, overflow:"hidden"}}>
          <div style={{
            display:"grid", gridTemplateColumns:"140px 1fr 130px 130px 100px 36px",
            gap:14, padding:"10px 16px",
            background:"var(--d-sunken)", borderBottom:"1px solid var(--d-line)",
            fontSize:10.5, color:"var(--d-ink-4)", textTransform:"uppercase", letterSpacing:"0.08em", fontWeight:600,
          }}>
            <div>N° facture</div>
            <div>Période</div>
            <div>Date</div>
            <div style={{textAlign:"right"}}>Montant</div>
            <div>Statut</div>
            <div/>
          </div>
          {invoices.map((inv, i) => (
            <div key={inv.id} style={{
              display:"grid", gridTemplateColumns:"140px 1fr 130px 130px 100px 36px",
              gap:14, padding:"12px 16px",
              borderBottom: i < invoices.length - 1 ? "1px solid var(--d-line-2)" : "none",
              alignItems:"center", fontSize:12.5,
            }}>
              <div className="mono" style={{color:"var(--d-ink-2)", fontSize:12}}>{inv.id}</div>
              <div>
                <div style={{color:"var(--d-ink)"}}>{inv.period}</div>
                <div className="muted" style={{fontSize:11, marginTop:2}}>Plan Agence · annuel · {inv.method}</div>
              </div>
              <div className="mono" style={{color:"var(--d-ink-3)", fontSize:11.5}}>{inv.date}</div>
              <div className="mono" style={{textAlign:"right", color:"var(--d-ink)", fontVariantNumeric:"tabular-nums"}}>{fmtFCFA(inv.amount)}</div>
              <div>
                <span style={{
                  fontSize:10.5, fontWeight:600, padding:"2px 8px", borderRadius:3,
                  background:"rgba(63,181,131,0.12)", color:"var(--pos-d)",
                  letterSpacing:"0.02em",
                }}>{inv.status}</span>
              </div>
              <button title="Télécharger" style={{
                width:28, height:28, borderRadius:4, border:"1px solid var(--d-line)",
                background:"transparent", color:"var(--d-ink-3)", fontSize:12,
                display:"grid", placeItems:"center", cursor:"pointer",
              }}>↓</button>
            </div>
          ))}
        </div>
      </FormSection>
    </>
  );
}

function UsageStat({ label, value, limit, pct, sub, mono, noBorder }) {
  const over = pct >= 90;
  const warn = pct >= 75 && pct < 90;
  const color = over ? "var(--orange)" : warn ? "var(--warn-d)" : "var(--blue-d)";

  return (
    <div style={{
      padding:"18px 22px",
      borderRight: noBorder ? "none" : "1px solid var(--d-line)",
    }}>
      <div style={{
        fontSize:10.5, color:"var(--d-ink-4)", textTransform:"uppercase",
        letterSpacing:"0.08em", fontWeight:600, marginBottom:8,
      }}>{label}</div>
      <div style={{display:"flex", alignItems:"baseline", gap:6, marginBottom:8}}>
        <span className={mono ? "mono" : ""} style={{
          fontSize:22, fontWeight:500, color:"var(--d-ink)",
          letterSpacing:"-0.02em", fontFamily: mono === false ? undefined : "var(--font-mono)",
        }}>{value}</span>
        {limit != null && limit !== Infinity && (
          <span style={{fontSize:12, color:"var(--d-ink-4)"}}>
            / {limit}
          </span>
        )}
        {limit === Infinity && (
          <span style={{fontSize:12, color:"var(--d-ink-4)"}}>illimité</span>
        )}
      </div>
      {pct != null && limit !== Infinity && (
        <div style={{
          height:3, background:"var(--d-line)", borderRadius:2, overflow:"hidden", marginBottom:6,
        }}>
          <div style={{height:"100%", width:`${pct}%`, background: color, transition:"width 0.3s"}}/>
        </div>
      )}
      <div style={{fontSize:11, color:"var(--d-ink-3)"}}>{sub}</div>
    </div>
  );
}

function PlanCard({ id, plan, annual, current, featured, features }) {
  const price = annual ? plan.annual : plan.monthly;

  return (
    <div style={{
      padding:"18px 18px 16px",
      border: featured ? "1px solid var(--orange)" : "1px solid var(--d-line)",
      borderRadius:6,
      background: featured ? "rgba(249,115,22,0.04)" : "var(--d-panel)",
      position:"relative",
      display:"flex", flexDirection:"column",
    }}>
      {featured && (
        <div style={{
          position:"absolute", top:-8, left:14,
          fontSize:9, fontWeight:700, letterSpacing:"0.12em",
          color:"#fff", background:"var(--orange)",
          padding:"3px 8px", borderRadius:2, textTransform:"uppercase",
        }}>Recommandé</div>
      )}
      <div style={{
        display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:10,
      }}>
        <span style={{fontSize:13, fontWeight:600, color:"var(--d-ink)"}}>{plan.name}</span>
        {current && (
          <span style={{
            fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:2,
            background:"rgba(63,181,131,0.14)", color:"var(--pos-d)",
            letterSpacing:"0.04em", textTransform:"uppercase",
          }}>Plan actuel</span>
        )}
      </div>
      <div style={{marginBottom:14, paddingBottom:14, borderBottom:"1px solid var(--d-line)"}}>
        {price === 0 ? (
          <div className="mono" style={{fontSize:22, fontWeight:500, color:"var(--d-ink)", letterSpacing:"-0.02em"}}>
            Gratuit
          </div>
        ) : (
          <div style={{display:"flex", alignItems:"baseline", gap:5}}>
            <span className="mono" style={{fontSize:22, fontWeight:500, color:"var(--d-ink)", letterSpacing:"-0.02em"}}>
              {fmtFCFA(price)}
            </span>
            <span style={{fontSize:11, color:"var(--d-ink-3)"}}>/ mois</span>
          </div>
        )}
        <div style={{fontSize:11, color:"var(--d-ink-4)", marginTop:4}}>
          {plan.lots === Infinity ? "Lots illimités" : `Jusqu'à ${plan.lots} lots`}
          {" · "}
          {plan.users === Infinity ? "utilisateurs illimités" : `${plan.users} utilisateur${plan.users > 1 ? "s" : ""}`}
        </div>
      </div>
      <ul style={{listStyle:"none", padding:0, margin:0, display:"flex", flexDirection:"column", gap:7, flex:1, marginBottom:14}}>
        {features.map((f, i) => (
          <li key={i} style={{
            fontSize:11.5, color:"var(--d-ink-2)",
            display:"flex", alignItems:"flex-start", gap:8, lineHeight:1.45,
          }}>
            <span className="mono" style={{color:"var(--pos-d)", fontSize:11, fontWeight:600, width:10, flexShrink:0}}>✓</span>
            <span>{f}</span>
          </li>
        ))}
      </ul>
      <button
        disabled={current}
        className={current ? "btn btn-ghost" : featured ? "btn btn-primary" : "btn btn-secondary"}
        style={{
          justifyContent:"center", fontSize:11.5, padding:"7px 12px",
          opacity: current ? 0.6 : 1, cursor: current ? "default" : "pointer",
        }}>
        {current ? "Plan actuel" :
         id === "solo" ? "Rétrograder" :
         id === "cabinet" ? "Demander un devis" :
         "Passer à ce plan"}
      </button>
    </div>
  );
}

Object.assign(window, { SettingsPage });

/* ╚══ end pages-settings.jsx ══╝ */

/* ╔══ pages-superadmin.jsx ══╗ */
/* global React, fmtFCFA, fmtCompact, Spark, Logo */

/* ═══════════════════════════════════════════════════════════════════════
   SUPER ADMIN — Console éditeur Logestimmo
   Vue interne de l'éditeur du SaaS, au-dessus de toutes les agences clientes.
   Sections : Vue d'ensemble · Abonnements · Comptes (agences) · Acquisition
   ═══════════════════════════════════════════════════════════════════════ */

const SA_ACCENT = "#6D5DF6";          // indigo — distingue la console éditeur de l'app agence
const SA_ACCENT_SOFT = "rgba(109,93,246,0.14)";

const SA_PLAN_META = {
  solo:    { label:"Solo",    color:"#7B8494", base:0 },
  agence:  { label:"Agence",  color:"#6D5DF6", base:49000 },
  cabinet: { label:"Cabinet", color:"#C9559C", base:129000 },
};

/* ─── DATA · agences clientes (tenants du SaaS) ─── */
const SA_AGENCIES = [
  { id:"AG-2041", name:"BA Immo",                 city:"Dakar",      plan:"agence",  lots:52,  users:5,  mrr:49000,  status:"actif",    signup:"2024-04-12", lastActive:"il y a 8 min",  spark:[30,34,38,40,44,47,49,49,50,51,52,52] },
  { id:"AG-2090", name:"Téranga Gestion",         city:"Dakar",      plan:"cabinet", lots:430, users:14, mrr:129000, status:"actif",    signup:"2023-11-03", lastActive:"il y a 22 min", spark:[280,300,330,350,360,380,395,405,415,420,425,430] },
  { id:"AG-2113", name:"Cabinet Sow & Associés",  city:"Thiès",      plan:"cabinet", lots:610, users:19, mrr:129000, status:"actif",    signup:"2023-08-21", lastActive:"il y a 1 h",    spark:[420,460,500,520,540,560,575,585,595,600,605,610] },
  { id:"AG-2150", name:"Almadies Property",       city:"Dakar",      plan:"agence",  lots:188, users:5,  mrr:49000,  status:"actif",    signup:"2024-01-30", lastActive:"il y a 3 h",    spark:[120,135,150,160,168,172,176,180,182,184,186,188] },
  { id:"AG-2178", name:"Sahel Habitat",           city:"Saint-Louis",plan:"agence",  lots:244, users:6,  mrr:61320,  status:"actif",    signup:"2024-02-18", lastActive:"il y a 5 h",    spark:[150,170,190,205,215,225,230,235,238,240,242,244] },
  { id:"AG-2203", name:"Keur Gestion Immo",       city:"Dakar",      plan:"agence",  lots:96,  users:3,  mrr:49000,  status:"actif",    signup:"2024-05-09", lastActive:"hier",          spark:[40,52,60,68,74,80,84,88,90,92,94,96] },
  { id:"AG-2241", name:"Ndiaye & Fils Syndic",    city:"Rufisque",   plan:"agence",  lots:172, users:4,  mrr:49000,  status:"actif",    signup:"2024-06-22", lastActive:"il y a 2 j",    spark:[90,105,120,135,145,152,158,162,166,168,170,172] },
  { id:"AG-2278", name:"Abidjan Lagune Immo",     city:"Abidjan",    plan:"cabinet", lots:520, users:16, mrr:129000, status:"actif",    signup:"2023-12-14", lastActive:"il y a 40 min", spark:[350,380,410,440,460,480,490,500,508,514,518,520] },
  { id:"AG-2310", name:"Plateau Résidences",      city:"Abidjan",    plan:"agence",  lots:210, users:5,  mrr:51800,  status:"actif",    signup:"2024-03-27", lastActive:"il y a 6 h",    spark:[140,160,175,188,196,200,204,206,208,209,210,210] },
  { id:"AG-2355", name:"Lomé Habitat Conseil",    city:"Lomé",       plan:"agence",  lots:78,  users:3,  mrr:49000,  status:"essai",    signup:"2026-05-14", lastActive:"il y a 1 h",    spark:[0,0,0,0,0,0,0,0,12,34,58,78], trialEnds:"2026-05-28" },
  { id:"AG-2356", name:"Cocody Premium",          city:"Abidjan",    plan:"cabinet", lots:160, users:7,  mrr:129000, status:"essai",    signup:"2026-05-20", lastActive:"il y a 3 h",    spark:[0,0,0,0,0,0,0,0,0,40,110,160], trialEnds:"2026-06-03" },
  { id:"AG-2361", name:"Mermoz Gestion",          city:"Dakar",      plan:"agence",  lots:64,  users:2,  mrr:49000,  status:"essai",    signup:"2026-05-22", lastActive:"il y a 30 min", spark:[0,0,0,0,0,0,0,0,0,0,30,64], trialEnds:"2026-06-05" },
  { id:"AG-1987", name:"Yoff Immobilier",         city:"Dakar",      plan:"agence",  lots:0,   users:2,  mrr:0,      status:"suspendu", signup:"2023-09-02", lastActive:"il y a 21 j",   spark:[110,108,100,92,80,64,48,30,18,8,2,0] },
  { id:"AG-2024", name:"Diourbel Gestion Locative",city:"Diourbel",  plan:"solo",    lots:18,  users:1,  mrr:0,      status:"actif",    signup:"2025-02-11", lastActive:"il y a 4 j",    spark:[8,10,11,12,13,14,15,16,17,17,18,18] },
  { id:"AG-2402", name:"Saly Resort Rentals",     city:"Mbour",      plan:"solo",    lots:14,  users:1,  mrr:0,      status:"actif",    signup:"2025-08-19", lastActive:"il y a 9 j",    spark:[4,6,7,8,9,10,11,12,12,13,14,14] },
];

/* ─── DATA · acquisition / entonnoir (30 derniers jours) ─── */
const SA_FUNNEL = [
  { step:"Visites site",          value:8420, color:"#525C6E" },
  { step:"Inscriptions essai",    value:612,  color:"#6D5DF6" },
  { step:"Comptes activés",       value:318,  color:"#3F7DDB" },
  { step:"Conversions payant",    value:143,  color:"#3FB583" },
];

const SA_SOURCES = [
  { src:"Recherche Google",   visits:3120, signups:248, color:"#6D5DF6" },
  { src:"Direct / notoriété", visits:1890, signups:142, color:"#3F7DDB" },
  { src:"LinkedIn",           visits:1240, signups:96,  color:"#3FB583" },
  { src:"Référencement / bouche-à-oreille", visits:980, signups:88, color:"#E0A74A" },
  { src:"Meta (FB / IG)",     visits:760,  signups:26,  color:"#C9559C" },
  { src:"Webinaires & salons",visits:430,  signups:12,  color:"#7B8494" },
];

const SA_LANDING_PAGES = [
  { path:"/",                 visits:3980, conv:"2,1%" },
  { path:"/tarifs",           visits:1760, conv:"4,8%" },
  { path:"/fonctionnalites",  visits:1240, conv:"1,6%" },
  { path:"/blog/quittance-numerique", visits:820, conv:"0,9%" },
  { path:"/comparatif-excel", visits:620,  conv:"3,2%" },
];

/* Répartition des visites par pays / navigateur / appareil */
const SA_COUNTRIES = [
  { name:"Sénégal",        flag:"🇸🇳", visits:4210, signups:362 },
  { name:"Côte d'Ivoire",  flag:"🇨🇮", visits:1680, signups:118 },
  { name:"France",         flag:"🇫🇷", visits:920,  signups:41  },
  { name:"Togo",           flag:"🇹🇬", visits:540,  signups:38  },
  { name:"Mali",           flag:"🇲🇱", visits:430,  signups:29  },
  { name:"Bénin",          flag:"🇧🇯", visits:360,  signups:18  },
  { name:"Autres",         flag:"🌍", visits:280,  signups:6   },
];
const SA_BROWSERS = [
  { name:"Chrome",           share:54, color:"#6D5DF6" },
  { name:"Safari",           share:21, color:"#3F7DDB" },
  { name:"Samsung Internet", share:11, color:"#3FB583" },
  { name:"Firefox",          share:7,  color:"#E0A74A" },
  { name:"Edge",             share:4,  color:"#C9559C" },
  { name:"Opera / autres",   share:3,  color:"#7B8494" },
];
const SA_DEVICES = [
  { name:"Mobile",  share:68, color:"#6D5DF6" },
  { name:"Desktop", share:27, color:"#3F7DDB" },
  { name:"Tablette",share:5,  color:"#3FB583" },
];

/* 12 mois — MRR (FCFA) et inscriptions */
const SA_MONTHS = ["Juin","Juil","Août","Sep","Oct","Nov","Déc","Jan","Fév","Mar","Avr","Mai"];
const SA_MRR_SERIES    = [392, 430, 468, 510, 548, 590, 640, 690, 742, 800, 858, 916].map(v=>v*1000);
const SA_SIGNUP_SERIES = [28, 33, 31, 40, 44, 52, 58, 61, 66, 74, 88, 96];
const SA_VISITS_SERIES = [4100,4600,4400,5200,5600,6100,6800,7000,7400,7800,8100,8420];

/* Renouvellements & incidents */
const SA_RENEWALS = [
  { agency:"Téranga Gestion",        plan:"cabinet", amount:129000, due:"2026-06-03", status:"auto" },
  { agency:"Almadies Property",      plan:"agence",  amount:49000,  due:"2026-06-01", status:"auto" },
  { agency:"Abidjan Lagune Immo",    plan:"cabinet", amount:129000, due:"2026-06-14", status:"auto" },
  { agency:"Keur Gestion Immo",      plan:"agence",  amount:49000,  due:"2026-05-30", status:"manuel" },
];
const SA_FAILED = [
  { agency:"Sahel Habitat",     amount:61320, reason:"Wave — solde insuffisant", retries:1, since:"2026-05-26" },
  { agency:"Plateau Résidences",amount:51800, reason:"Carte expirée",            retries:2, since:"2026-05-24" },
];
const SA_PLAN_CHANGES = [
  { agency:"Plateau Résidences", from:"agence",  to:"agence",  note:"+10 lots (210)", when:"il y a 2 j", dir:"up" },
  { agency:"Cocody Premium",     from:"essai",   to:"cabinet", note:"Essai → Cabinet", when:"il y a 4 j", dir:"up" },
  { agency:"Yoff Immobilier",    from:"agence",  to:"suspendu",note:"Impayé 21 j",    when:"il y a 6 j", dir:"down" },
  { agency:"Saly Resort Rentals",from:"essai",   to:"solo",    note:"Essai → Solo (gratuit)", when:"il y a 9 j", dir:"flat" },
];

/* Helpers */
const saMoneyM = v => (v/1_000_000).toFixed(2).replace(".", ",");
const saPct = (a,b) => b ? Math.round((a/b)*100) : 0;

function saStatusChip(status) {
  const map = {
    actif:    { c:"#3FB583", bg:"rgba(63,181,131,0.14)",  t:"Actif" },
    essai:    { c:"#6D5DF6", bg:"rgba(109,93,246,0.14)",   t:"Essai" },
    suspendu: { c:"#E0683F", bg:"rgba(224,104,63,0.14)",   t:"Suspendu" },
  };
  const s = map[status] || map.actif;
  return <span style={{fontSize:10.5, fontWeight:600, padding:"2px 9px", borderRadius:4, background:s.bg, color:s.c, letterSpacing:"0.02em"}}>{s.t}</span>;
}

/* ═══════════════════════════════════════════════════════════════════════
   CONSOLE SHELL
   ═══════════════════════════════════════════════════════════════════════ */
function SuperAdminConsole({ onExit, onOpenAgencyDemo }) {
  const [section, setSection] = React.useState("overview");

  const SECTIONS = [
    ["overview",      "Vue d'ensemble"],
    ["subscriptions", "Abonnements"],
    ["tarification",  "Tarification"],
    ["paiements",     "Paiements", (typeof SAC_PENDING_INIT !== "undefined" ? SAC_PENDING_INIT.length : null)],
    ["accounts",      "Comptes"],
    ["acquisition",   "Acquisition"],
  ];

  const activeAgencies = SA_AGENCIES.filter(a => a.status === "actif").length;
  const trials = SA_AGENCIES.filter(a => a.status === "essai").length;

  return (
    <div className="app" data-density="compact" style={{ ["--sa-accent"]: SA_ACCENT }}>
      {/* Sidebar — console éditeur */}
      <aside className="sb">
        <div className="sb-logo">
          <Logo size={22}/>
          <span className="sb-logo-name">Logestimmo</span>
        </div>

        <div className="sb-agency" style={{borderColor: SA_ACCENT, background: SA_ACCENT_SOFT}}>
          <div className="sb-agency-main">
            <div className="sb-agency-avatar" style={{background: SA_ACCENT, color:"#fff"}}>LS</div>
            <div>
              <div className="sb-agency-name">Console éditeur</div>
              <div className="sb-agency-role">Super Admin · global</div>
            </div>
          </div>
        </div>

        <div className="sb-group">
          <div className="sb-group-label">Pilotage SaaS</div>
          {SECTIONS.map(([id, label, badge]) => (
            <div key={id} className={"sb-item" + (section === id ? " active" : "")} onClick={()=>setSection(id)}
                 style={section === id ? {background: SA_ACCENT_SOFT} : null}>
              <span className="sb-dot" style={section === id ? {background: SA_ACCENT} : null}/>
              <span className="sb-item-label">{label}</span>
              {badge != null && <span className="sb-item-badge" style={{background:"var(--orange)"}}>{badge}</span>}
            </div>
          ))}
        </div>

        <div className="sb-group">
          <div className="sb-group-label">Raccourcis</div>
          <div className="sb-item"><span className="sb-dot"/><span className="sb-item-label">Agences actives</span><span className="sb-item-count">{activeAgencies}</span></div>
          <div className="sb-item"><span className="sb-dot" style={{background:SA_ACCENT}}/><span className="sb-item-label">Essais en cours</span><span className="sb-item-count">{trials}</span></div>
          <div className="sb-item"><span className="sb-dot" style={{background:"var(--orange)"}}/><span className="sb-item-label">Incidents paiement</span><span className="sb-item-badge">{SA_FAILED.length}</span></div>
        </div>

        <div className="sb-bottom">
          <div className="sb-group">
            <div className="sb-item" onClick={onOpenAgencyDemo}><span className="sb-dot"/><span className="sb-item-label">Voir l'app agence →</span></div>
            <div className="sb-item" onClick={onExit}><span className="sb-dot"/><span className="sb-item-label">Quitter la console</span></div>
          </div>
        </div>
      </aside>

      {/* Main */}
      <div className="main">
        <div className="top">
          <div className="crumbs">
            <span className="crumb-link" style={{color: SA_ACCENT}}>Console éditeur</span>
            <span className="crumb-sep">/</span>
            <span className="crumb-now">{SECTIONS.find(s=>s[0]===section)[1]}</span>
          </div>
          <div className="top-right">
            <div className="top-search">
              <span style={{color:"var(--d-ink-4)"}}>⌕</span>
              <input placeholder="Rechercher une agence, un compte…"/>
              <span className="kbd">⌘K</span>
            </div>
            <button className="top-iconbtn"><span>◌</span><span className="top-iconbtn-dot"/></button>
            <div className="avatar sq" style={{background: SA_ACCENT, color:"#fff"}}>LS</div>
          </div>
        </div>

        {section === "overview"      && <SAOverview onOpenAccounts={()=>setSection("accounts")} onOpenAcq={()=>setSection("acquisition")}/>}
        {section === "subscriptions" && <SASubscriptions/>}
        {section === "tarification"  && <SATarification/>}
        {section === "paiements"     && <SAPaiements/>}
        {section === "accounts"      && <SAAccounts onOpenAgencyDemo={onOpenAgencyDemo}/>}
        {section === "acquisition"   && <SAAcquisition/>}

        <div style={{padding:"20px 24px", borderTop:"1px solid var(--d-line)", color:"var(--d-ink-4)", fontSize:11.5, display:"flex", justifyContent:"space-between"}}>
          <span>Logestimmo · Console éditeur · Données démo</span>
          <span style={{display:"flex", gap:16}}>
            <button onClick={onExit} style={{background:"none", border:"none", color:"var(--d-ink-3)", cursor:"pointer", fontSize:11.5}}>← Retour à la présentation</button>
            <span>console v1.0</span>
          </span>
        </div>
      </div>
    </div>
  );
}

/* ═══ Small chart helpers ═══ */
function SABars({ values, labels, color = SA_ACCENT, h = 150, fmt = fmtCompact }) {
  const max = Math.max(...values) * 1.1 || 1;
  const n = values.length;
  return (
    <div style={{display:"flex", alignItems:"flex-end", gap:6, height:h, padding:"0 4px"}}>
      {values.map((v, i) => (
        <div key={i} style={{flex:1, display:"flex", flexDirection:"column", alignItems:"center", gap:6, height:"100%", justifyContent:"flex-end"}}>
          <div style={{fontSize:9.5, fontFamily:"var(--font-mono)", color:"var(--d-ink-3)"}}>{fmt(v)}</div>
          <div style={{width:"100%", maxWidth:30, height:`${(v/max)*100}%`, background: i === n-1 ? color : "color-mix(in srgb, "+color+" 45%, transparent)", borderRadius:"3px 3px 0 0", transition:"height .3s"}}/>
          <div style={{fontSize:9.5, color:"var(--d-ink-4)"}}>{labels[i]}</div>
        </div>
      ))}
    </div>
  );
}

function SADonut({ segments, size = 132, thickness = 18, centerLabel, centerSub }) {
  const total = segments.reduce((s,x)=>s+x.value, 0) || 1;
  const r = (size - thickness) / 2;
  const C = 2 * Math.PI * r;
  let acc = 0;
  return (
    <div style={{display:"flex", alignItems:"center", gap:18}}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{flexShrink:0}}>
        <g transform={`rotate(-90 ${size/2} ${size/2})`}>
          {segments.map((s, i) => {
            const frac = s.value / total;
            const dash = frac * C;
            const el = <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={s.color} strokeWidth={thickness}
              strokeDasharray={`${dash} ${C-dash}`} strokeDashoffset={-acc*C}/>;
            acc += frac;
            return el;
          })}
        </g>
        <text x="50%" y="47%" textAnchor="middle" style={{fontSize:20, fontWeight:700, fill:"var(--d-ink)", fontFamily:"var(--font-mono)"}}>{centerLabel}</text>
        <text x="50%" y="60%" textAnchor="middle" style={{fontSize:10, fill:"var(--d-ink-4)"}}>{centerSub}</text>
      </svg>
      <div style={{display:"flex", flexDirection:"column", gap:8}}>
        {segments.map((s,i) => (
          <div key={i} style={{display:"flex", alignItems:"center", gap:8, fontSize:12}}>
            <span style={{width:10, height:10, borderRadius:3, background:s.color, flexShrink:0}}/>
            <span style={{color:"var(--d-ink-2)", minWidth:64}}>{s.label}</span>
            <span className="mono" style={{color:"var(--d-ink)", fontWeight:600}}>{s.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ═══ SECTION · Vue d'ensemble ═══ */
function SAOverview({ onOpenAccounts, onOpenAcq }) {
  const mrr = SA_MRR_SERIES[SA_MRR_SERIES.length-1];
  const mrrPrev = SA_MRR_SERIES[SA_MRR_SERIES.length-2];
  const growth = (((mrr-mrrPrev)/mrrPrev)*100).toFixed(1).replace(".",",");
  const arr = mrr * 12;
  const active = SA_AGENCIES.filter(a=>a.status==="actif").length;
  const trials = SA_AGENCIES.filter(a=>a.status==="essai").length;
  const convRate = saPct(SA_FUNNEL[3].value, SA_FUNNEL[1].value);

  const planSeg = ["solo","agence","cabinet"].map(p => ({
    label: SA_PLAN_META[p].label,
    value: SA_AGENCIES.filter(a=>a.plan===p && a.status!=="suspendu").length,
    color: SA_PLAN_META[p].color,
  }));

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Vue d'ensemble</h1>
          <div className="page-sub">{SA_AGENCIES.length} comptes · {active} actifs · {trials} en essai · mai 2026</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost" onClick={()=>lgiToast("Export des indicateurs SaaS (.csv)","ok")}>Exporter</button>
          <button className="btn btn-primary" style={{background:SA_ACCENT, borderColor:SA_ACCENT}} onClick={()=>lgiToast("Rapport mensuel généré","ok")}>Rapport mensuel</button>
        </div>
      </div>

      <div className="kpis">
        <div className="kpi primary" style={{borderColor:"rgba(109,93,246,0.3)"}}>
          <div className="kpi-label"><span>MRR</span><span style={{color:"var(--d-ink-4)", fontWeight:400, textTransform:"none", letterSpacing:0}}>Revenu mensuel récurrent</span></div>
          <div className="kpi-value num">{saMoneyM(mrr)}<span className="kpi-unit">M FCFA</span></div>
          <div className="kpi-meta"><span className="delta pos">▲ {growth}%</span><span>vs avril</span></div>
          <div className="kpi-spark"><Spark values={SA_MRR_SERIES} color={SA_ACCENT}/></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>ARR projeté</span></div>
          <div className="kpi-value num">{Math.round(arr/1_000_000)}<span className="kpi-unit">M FCFA</span></div>
          <div className="kpi-meta"><span>MRR × 12</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>Agences actives</span></div>
          <div className="kpi-value num">{active}<span className="kpi-unit">/ {SA_AGENCIES.length}</span></div>
          <div className="kpi-meta"><span className="delta pos">▲ 3</span><span>ce mois</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>Conversion essai → payant</span></div>
          <div className="kpi-value num" style={{color:SA_ACCENT}}>{convRate}<span className="kpi-unit">%</span></div>
          <div className="kpi-meta"><span className="delta pos">▲ 2,4 pt</span><span>30 j</span></div>
        </div>
      </div>

      <div className="grid-2">
        <div className="panel">
          <div className="panel-head">
            <div><h3 className="panel-title">Croissance du MRR</h3><div className="panel-sub">12 derniers mois · FCFA</div></div>
            <span className="chip pos">+134% sur 12 mois</span>
          </div>
          <div style={{padding:"18px 18px 14px"}}>
            <SABars values={SA_MRR_SERIES} labels={SA_MONTHS} color={SA_ACCENT}/>
          </div>
        </div>

        <div className="panel">
          <div className="panel-head">
            <div><h3 className="panel-title">Répartition par plan</h3><div className="panel-sub">Comptes actifs & en essai</div></div>
          </div>
          <div style={{padding:"22px 20px"}}>
            <SADonut segments={planSeg} centerLabel={planSeg.reduce((s,x)=>s+x.value,0)} centerSub="comptes"/>
          </div>
        </div>
      </div>

      <div className="grid-2">
        <div className="panel">
          <div className="panel-head">
            <div><h3 className="panel-title">Entonnoir d'acquisition</h3><div className="panel-sub">30 derniers jours</div></div>
            <button className="btn btn-ghost" style={{padding:"4px 10px", fontSize:11.5}} onClick={onOpenAcq}>Détail →</button>
          </div>
          <div style={{padding:"16px 20px"}}>
            <SAFunnelMini/>
          </div>
        </div>

        <div className="panel">
          <div className="panel-head">
            <div><h3 className="panel-title">Incidents de paiement</h3><div className="panel-sub">À traiter</div></div>
            <span className="chip warn">{SA_FAILED.length}</span>
          </div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Agence</th><th>Motif</th><th className="right">Montant</th><th className="right">Relances</th></tr></thead>
              <tbody>
                {SA_FAILED.map((f,i)=>(
                  <tr key={i}>
                    <td style={{fontWeight:500}}>{f.agency}</td>
                    <td className="muted" style={{fontSize:12}}>{f.reason}</td>
                    <td className="right mono">{fmtFCFA(f.amount)}</td>
                    <td className="right mono">{f.retries}</td>
                  </tr>
                ))}
                {SA_RENEWALS.filter(r=>r.status==="manuel").map((r,i)=>(
                  <tr key={"r"+i}>
                    <td style={{fontWeight:500}}>{r.agency}</td>
                    <td className="muted" style={{fontSize:12}}>Renouvellement manuel · {r.due}</td>
                    <td className="right mono">{fmtFCFA(r.amount)}</td>
                    <td className="right mono">—</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  );
}

function SAFunnelMini() {
  const top = SA_FUNNEL[0].value;
  return (
    <div style={{display:"flex", flexDirection:"column", gap:8}}>
      {SA_FUNNEL.map((f, i) => {
        const pctOfTop = (f.value/top)*100;
        const pctOfPrev = i === 0 ? 100 : saPct(f.value, SA_FUNNEL[i-1].value);
        return (
          <div key={i}>
            <div style={{display:"flex", justifyContent:"space-between", fontSize:12, marginBottom:4}}>
              <span style={{color:"var(--d-ink-2)"}}>{f.step}</span>
              <span className="mono" style={{color:"var(--d-ink)", fontWeight:600}}>{f.value.toLocaleString("fr-FR")} <span style={{color:"var(--d-ink-4)", fontWeight:400}}>· {pctOfPrev}%</span></span>
            </div>
            <div style={{height:18, background:"var(--d-sunken)", borderRadius:4, overflow:"hidden"}}>
              <div style={{height:"100%", width:`${pctOfTop}%`, background:f.color, borderRadius:4, transition:"width .3s"}}/>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ═══ SECTION · Abonnements ═══ */
function SASubscriptions() {
  const plans = ["solo","agence","cabinet"].map(p => {
    const accts = SA_AGENCIES.filter(a => a.plan === p && a.status !== "suspendu");
    const mrr = accts.reduce((s,a)=>s+a.mrr, 0);
    return { id:p, ...SA_PLAN_META[p], count: accts.length, mrr };
  });
  const totalMrr = plans.reduce((s,p)=>s+p.mrr, 0);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Abonnements</h1>
          <div className="page-sub">MRR total {saMoneyM(totalMrr)} M FCFA · {SA_AGENCIES.filter(a=>a.status!=="suspendu").length} comptes facturables</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost" onClick={()=>lgiToast("Ouvrez l’onglet Tarification")}>Grille tarifaire</button>
          <button className="btn btn-primary" style={{background:SA_ACCENT, borderColor:SA_ACCENT}} onClick={()=>lgiToast("Création d’un abonnement personnalisé")}>+ Créer un abonnement</button>
        </div>
      </div>

      {/* Plan cards */}
      <div className="kpis" style={{gridTemplateColumns:"repeat(3,1fr)"}}>
        {plans.map(p => (
          <div key={p.id} className="kpi" style={{borderColor: p.id==="agence" ? "rgba(109,93,246,0.3)" : undefined}}>
            <div className="kpi-label">
              <span style={{display:"inline-flex", alignItems:"center", gap:7}}>
                <span style={{width:9, height:9, borderRadius:3, background:p.color}}/>{p.label}
              </span>
              <span style={{color:"var(--d-ink-4)", fontWeight:400, textTransform:"none", letterSpacing:0}}>{p.base===0?"Gratuit":fmtFCFA(p.base)+"/mois"}</span>
            </div>
            <div className="kpi-value num">{p.count}<span className="kpi-unit">comptes</span></div>
            <div className="kpi-meta">
              <span className="mono" style={{color: p.mrr>0 ? "var(--pos-d)" : "var(--d-ink-4)"}}>{p.mrr>0 ? fmtCompact(p.mrr)+" FCFA MRR" : "0 MRR"}</span>
              <span>{totalMrr>0 ? saPct(p.mrr, totalMrr) : 0}% du MRR</span>
            </div>
          </div>
        ))}
      </div>

      <div className="grid-2">
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Renouvellements à venir</h3><div className="panel-sub">30 prochains jours</div></div></div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Agence</th><th>Plan</th><th className="right">Montant</th><th>Échéance</th><th>Mode</th></tr></thead>
              <tbody>
                {SA_RENEWALS.map((r,i)=>(
                  <tr key={i}>
                    <td style={{fontWeight:500}}>{r.agency}</td>
                    <td><span style={{fontSize:11, color:SA_PLAN_META[r.plan].color, fontWeight:600}}>{SA_PLAN_META[r.plan].label}</span></td>
                    <td className="right mono">{fmtFCFA(r.amount)}</td>
                    <td className="mono muted" style={{fontSize:11.5}}>{r.due}</td>
                    <td>{r.status==="auto" ? <span className="chip pos">automatique</span> : <span className="chip warn">manuel</span>}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Changements de plan récents</h3><div className="panel-sub">Upgrades, downgrades, churn</div></div></div>
          <div>
            {SA_PLAN_CHANGES.map((c,i)=>{
              const arrow = c.dir==="up" ? "▲" : c.dir==="down" ? "▼" : "→";
              const col = c.dir==="up" ? "var(--pos-d)" : c.dir==="down" ? "var(--neg-d)" : "var(--d-ink-4)";
              return (
                <div key={i} style={{display:"flex", justifyContent:"space-between", alignItems:"center", gap:12, padding:"11px 18px", borderBottom: i<SA_PLAN_CHANGES.length-1?"1px solid var(--d-line-2)":"none"}}>
                  <div style={{minWidth:0}}>
                    <div style={{fontSize:12.5, fontWeight:500, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{c.agency}</div>
                    <div className="muted" style={{fontSize:11, marginTop:1, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{c.note}</div>
                  </div>
                  <div style={{textAlign:"right", flexShrink:0, whiteSpace:"nowrap"}}>
                    <div style={{fontSize:12, color:col, fontWeight:600}}>{arrow} {SA_PLAN_META[c.to]?.label || c.to}</div>
                    <div className="muted" style={{fontSize:10.5, marginTop:1}}>{c.when}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ═══ SECTION · Comptes (agences) ═══ */
function SAAccounts({ onOpenAgencyDemo }) {
  const [tab, setTab] = React.useState("all");
  const [q, setQ] = React.useState("");

  const filtered = SA_AGENCIES.filter(a => {
    if (tab !== "all" && a.status !== tab) return false;
    if (q && !`${a.name} ${a.city} ${a.id}`.toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  const tabs = [
    ["all","Tous",SA_AGENCIES.length],
    ["actif","Actifs",SA_AGENCIES.filter(a=>a.status==="actif").length],
    ["essai","En essai",SA_AGENCIES.filter(a=>a.status==="essai").length],
    ["suspendu","Suspendus",SA_AGENCIES.filter(a=>a.status==="suspendu").length],
  ];

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Comptes</h1>
          <div className="page-sub">{SA_AGENCIES.length} agences clientes · {SA_AGENCIES.reduce((s,a)=>s+a.lots,0).toLocaleString("fr-FR")} lots gérés au total</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost" onClick={()=>lgiToast("Export des comptes agences (.csv)","ok")}>Exporter CSV</button>
          <button className="btn btn-primary" style={{background:SA_ACCENT, borderColor:SA_ACCENT}} onClick={()=>lgiToast("Invitation d’une nouvelle agence")}>+ Inviter une agence</button>
        </div>
      </div>

      <div className="tabs">
        {tabs.map(([k,l,n])=>(
          <button key={k} className={"tab"+(tab===k?" active":"")} onClick={()=>setTab(k)}>{l} <span className="tab-count">{n}</span></button>
        ))}
      </div>

      <div className="panel">
        <div className="filter-bar" style={{borderTop:"none"}}>
          <div className="top-search" style={{width:280, background:"var(--d-panel)"}}>
            <span style={{color:"var(--d-ink-4)"}}>⌕</span>
            <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Agence, ville, ID…"/>
          </div>
          <div className="filter-spacer"/>
          <span className="muted mono" style={{fontSize:11}}>{filtered.length} / {SA_AGENCIES.length} comptes</span>
        </div>
        <div className="table-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>Agence</th>
                <th>Plan</th>
                <th className="right">Lots</th>
                <th className="right">Util.</th>
                <th className="right">MRR</th>
                <th>Croissance lots</th>
                <th>Statut</th>
                <th>Inscrit le</th>
                <th>Activité</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(a => (
                <tr key={a.id} onClick={a.name==="BA Immo" ? onOpenAgencyDemo : undefined} style={a.name==="BA Immo"?{cursor:"pointer"}:null}>
                  <td>
                    <div style={{display:"flex", alignItems:"center", gap:10}}>
                      <div className="avatar" style={{background: a.status==="suspendu"?"var(--d-elev)":SA_PLAN_META[a.plan].color, color:"#fff"}}>{a.name.split(" ").map(w=>w[0]).slice(0,2).join("")}</div>
                      <div>
                        <div style={{fontWeight:500, display:"flex", alignItems:"center", gap:8}}>
                          {a.name}
                          {a.name==="BA Immo" && <span style={{fontSize:9.5, fontWeight:600, padding:"1px 6px", borderRadius:3, background:SA_ACCENT_SOFT, color:SA_ACCENT}}>démo</span>}
                        </div>
                        <div className="muted mono" style={{fontSize:11}}>{a.city} · {a.id}</div>
                      </div>
                    </div>
                  </td>
                  <td><span style={{fontSize:11, fontWeight:600, color:SA_PLAN_META[a.plan].color}}>{SA_PLAN_META[a.plan].label}</span></td>
                  <td className="right mono">{a.lots}</td>
                  <td className="right mono">{a.users}</td>
                  <td className="right mono" style={{color: a.mrr>0?"var(--d-ink)":"var(--d-ink-4)", fontWeight: a.mrr>0?500:400}}>{a.mrr>0?fmtFCFA(a.mrr):"—"}</td>
                  <td><Spark values={a.spark} color={a.status==="suspendu"?"var(--neg-d)":SA_PLAN_META[a.plan].color} w={64} h={20}/></td>
                  <td>{a.status==="essai" && a.trialEnds ? <span title={"Fin d'essai "+a.trialEnds}>{saStatusChip(a.status)}</span> : saStatusChip(a.status)}</td>
                  <td className="mono muted" style={{fontSize:11.5}}>{a.signup}</td>
                  <td className="muted" style={{fontSize:11.5}}>{a.lastActive}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

/* ═══ SECTION · Acquisition ═══ */
function SAAcquisition() {
  const [period, setPeriod] = React.useState("30j");
  const totalVisits = SA_FUNNEL[0].value;
  const totalSignups = SA_FUNNEL[1].value;
  const visitToSignup = (saPct(totalSignups, totalVisits)).toFixed(1);
  const trialToPaid = saPct(SA_FUNNEL[3].value, SA_FUNNEL[1].value);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Acquisition</h1>
          <div className="page-sub">Trafic, sources et conversion · 30 derniers jours</div>
        </div>
        <div className="page-actions">
          {[["7j","7 j"],["30j","30 j"],["12m","12 mois"]].map(([k,l])=>(
            <button key={k} className={"btn "+(period===k?"btn-secondary":"btn-ghost")} onClick={()=>setPeriod(k)}>{l}</button>
          ))}
        </div>
      </div>

      <div className="kpis">
        <div className="kpi primary" style={{borderColor:"rgba(109,93,246,0.3)"}}>
          <div className="kpi-label"><span>Visites</span><span style={{color:"var(--d-ink-4)", fontWeight:400, textTransform:"none", letterSpacing:0}}>site & landing</span></div>
          <div className="kpi-value num">{(totalVisits/1000).toFixed(1).replace(".",",")}<span className="kpi-unit">k</span></div>
          <div className="kpi-meta"><span className="delta pos">▲ 4,1%</span><span>vs 30 j préc.</span></div>
          <div className="kpi-spark"><Spark values={SA_VISITS_SERIES} color={SA_ACCENT}/></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>Inscriptions essai</span></div>
          <div className="kpi-value num">{totalSignups}</div>
          <div className="kpi-meta"><span className="delta pos">▲ 9%</span><span>{visitToSignup}% des visites</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>Conversion visite → essai</span></div>
          <div className="kpi-value num">{visitToSignup}<span className="kpi-unit">%</span></div>
          <div className="kpi-meta"><span>moyenne secteur ~3%</span></div>
        </div>
        <div className="kpi">
          <div className="kpi-label"><span>Conversion essai → payant</span></div>
          <div className="kpi-value num" style={{color:SA_ACCENT}}>{trialToPaid}<span className="kpi-unit">%</span></div>
          <div className="kpi-meta"><span className="delta pos">▲ 2,4 pt</span><span>143 conversions</span></div>
        </div>
      </div>

      <div className="grid-2">
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Entonnoir de conversion</h3><div className="panel-sub">De la visite au compte payant</div></div></div>
          <div style={{padding:"18px 20px"}}><SAFunnelMini/></div>
        </div>
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Inscriptions / mois</h3><div className="panel-sub">12 derniers mois</div></div></div>
          <div style={{padding:"18px 18px 14px"}}>
            <SABars values={SA_SIGNUP_SERIES} labels={SA_MONTHS} color="#3F7DDB" fmt={v=>v}/>
          </div>
        </div>
      </div>

      <div className="grid-2">
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Sources de trafic</h3><div className="panel-sub">Visites & inscriptions par canal</div></div></div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Canal</th><th className="right">Visites</th><th className="right">Inscriptions</th><th className="right">Taux</th></tr></thead>
              <tbody>
                {SA_SOURCES.map((s,i)=>(
                  <tr key={i}>
                    <td><span style={{display:"inline-flex", alignItems:"center", gap:8}}><span style={{width:9, height:9, borderRadius:3, background:s.color}}/>{s.src}</span></td>
                    <td className="right mono">{s.visits.toLocaleString("fr-FR")}</td>
                    <td className="right mono">{s.signups}</td>
                    <td className="right mono" style={{color: saPct(s.signups,s.visits)>=7?"var(--pos-d)":"var(--d-ink-3)"}}>{(s.signups/s.visits*100).toFixed(1).replace(".",",")}%</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Pages d'atterrissage</h3><div className="panel-sub">Top pages par trafic</div></div></div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Page</th><th className="right">Visites</th><th className="right">Conversion</th></tr></thead>
              <tbody>
                {SA_LANDING_PAGES.map((p,i)=>(
                  <tr key={i}>
                    <td className="mono" style={{color:SA_ACCENT, fontSize:12}}>{p.path}</td>
                    <td className="right mono">{p.visits.toLocaleString("fr-FR")}</td>
                    <td className="right mono" style={{color:"var(--pos-d)"}}>{p.conv}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <div className="grid-2">
        {/* Par pays */}
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Visites par pays</h3><div className="panel-sub">Trafic & inscriptions · 30 j</div></div></div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Pays</th><th>Part du trafic</th><th className="right">Visites</th><th className="right">Inscr.</th></tr></thead>
              <tbody>
                {(() => {
                  const totV = SA_COUNTRIES.reduce((s,c)=>s+c.visits,0);
                  return SA_COUNTRIES.map((c,i)=>{
                    const pct = Math.round((c.visits/totV)*100);
                    return (
                      <tr key={i}>
                        <td><span style={{display:"inline-flex", alignItems:"center", gap:8}}><span style={{fontSize:14}}>{c.flag}</span>{c.name}</span></td>
                        <td style={{minWidth:120}}>
                          <div style={{display:"flex", alignItems:"center", gap:8}}>
                            <div style={{flex:1, height:6, background:"var(--d-sunken)", borderRadius:3, overflow:"hidden"}}>
                              <div style={{height:"100%", width:`${pct}%`, background:SA_ACCENT}}/>
                            </div>
                            <span className="mono" style={{fontSize:10.5, color:"var(--d-ink-3)", minWidth:30, textAlign:"right"}}>{pct}%</span>
                          </div>
                        </td>
                        <td className="right mono">{c.visits.toLocaleString("fr-FR")}</td>
                        <td className="right mono" style={{color:"var(--d-ink-2)"}}>{c.signups}</td>
                      </tr>
                    );
                  });
                })()}
              </tbody>
            </table>
          </div>
        </div>

        {/* Navigateur & appareil */}
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Navigateur & appareil</h3><div className="panel-sub">Répartition des sessions</div></div></div>
          <div style={{padding:"18px 20px", display:"flex", flexDirection:"column", gap:18}}>
            <div>
              <div style={{fontSize:10.5, textTransform:"uppercase", letterSpacing:"0.06em", color:"var(--d-ink-4)", fontWeight:600, marginBottom:10}}>Navigateur</div>
              <SAStackBar items={SA_BROWSERS}/>
            </div>
            <div>
              <div style={{fontSize:10.5, textTransform:"uppercase", letterSpacing:"0.06em", color:"var(--d-ink-4)", fontWeight:600, marginBottom:10}}>Appareil</div>
              <SAStackBar items={SA_DEVICES}/>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* Barre empilée + légende (part en %) */
function SAStackBar({ items }) {
  return (
    <div>
      <div style={{display:"flex", height:16, borderRadius:4, overflow:"hidden", border:"1px solid var(--d-line-2)"}}>
        {items.map((it,i)=>(
          <div key={i} title={`${it.name} · ${it.share}%`} style={{width:`${it.share}%`, background:it.color}}/>
        ))}
      </div>
      <div style={{display:"flex", flexWrap:"wrap", gap:"6px 16px", marginTop:10}}>
        {items.map((it,i)=>(
          <span key={i} style={{display:"inline-flex", alignItems:"center", gap:6, fontSize:11.5, color:"var(--d-ink-2)"}}>
            <span style={{width:9, height:9, borderRadius:2, background:it.color}}/>{it.name}
            <span className="mono" style={{color:"var(--d-ink-3)"}}>{it.share}%</span>
          </span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { SuperAdminConsole });

/* ╚══ end pages-superadmin.jsx ══╝ */

/* ╔══ pages-superadmin-config.jsx ══╗ */
/* global React, fmtFCFA, fmtCompact, FormSection, Field, FieldRow, Input, Textarea,
          MoneyInput, Select, Segmented, Toggle, Banner, SA_PLAN_META */

/* ═══════════════════════════════════════════════════════════════════════
   SUPER ADMIN · CONFIG — Tarification (plans, codes promo, personnalisés)
   et Paiements (validation manuelle Wave / Orange Money).
   Dépend de pages-superadmin.jsx (SA_ACCENT, SA_PLAN_META) — même scope global.
   ═══════════════════════════════════════════════════════════════════════ */

const SAC_ACCENT = "#6D5DF6";
const SAC_ACCENT_SOFT = "rgba(109,93,246,0.14)";

/* ─── Données initiales (mock, mutées en mémoire via useState) ─── */
const SAC_PLANS_INIT = [
  { id:"solo",    label:"Solo",    monthly:0,      annual:0,      lotLimit:20,  users:1,  overage:0,   trialDays:0,  active:true,
    features:["Encaissement Wave & Orange Money","Quittances PDF illimitées","Tableau de bord temps réel","1 utilisateur"] },
  { id:"agence",  label:"Agence",  monthly:49000,  annual:39000,  lotLimit:200, users:5,  overage:280, trialDays:14, active:true,
    features:["Rapprochement Wave/OM automatique","Bordereaux & CRG bailleurs","Espace bailleur en ligne","Export OHADA · CNSS · DGID","Support prioritaire J+1"] },
  { id:"cabinet", label:"Cabinet", monthly:129000, annual:105000, lotLimit:0,   users:0,  overage:0,   trialDays:14, active:true,
    features:["Lots & utilisateurs illimités","Multi-agences, multi-bailleurs","SSO, rôles avancés, audit log","API & intégrations Sage / Ciel","SLA contractuel 99,9 %","Account manager dédié"] },
];

const SAC_PROMO_INIT = [
  { code:"LANCEMENT25",   type:"percent", value:25,    plans:["agence","cabinet"], maxUses:100, used:38,  expires:"2026-06-30", status:"actif" },
  { code:"3MOISOFFERTS",  type:"months",  value:3,     plans:["agence"],           maxUses:50,  used:12,  expires:"2026-07-31", status:"actif" },
  { code:"PARTENAIRE50",  type:"percent", value:50,    plans:["agence","cabinet"], maxUses:20,  used:7,   expires:"2026-12-31", status:"actif" },
  { code:"SALON2025",     type:"fixed",   value:20000, plans:["agence"],           maxUses:200, used:200, expires:"2025-12-15", status:"épuisé" },
  { code:"NOEL24",        type:"percent", value:30,    plans:["agence","cabinet"], maxUses:100, used:64,  expires:"2025-01-15", status:"expiré" },
];

const SAC_CUSTOM_INIT = [
  { id:"CUS-01", agency:"Cabinet Sow & Associés", price:180000, lotLimit:"Illimité", users:25, validUntil:"2027-08-21", note:"Tarif multi-villes négocié (Thiès, Dakar, Saint-Louis)" },
  { id:"CUS-02", agency:"Abidjan Lagune Immo",    price:110000, lotLimit:"600",      users:20, validUntil:"2026-12-14", note:"Remise fidélité 15% — renouvellement annuel" },
];

const SAC_PENDING_INIT = [
  { id:"PAY-7741", agency:"Mermoz Gestion",        plan:"agence", amount:49000, method:"Wave",         ref:"WV-2026-0518-8841", submitted:"2026-05-27 14:22", proof:true,  note:"Essai → payant · timeout API au paiement" },
  { id:"PAY-7740", agency:"Lomé Habitat Conseil",  plan:"agence", amount:49000, method:"Orange Money", ref:"OM-778812441",      submitted:"2026-05-27 09:10", proof:true,  note:"Paiement reçu, webhook non reçu" },
  { id:"PAY-7738", agency:"Keur Gestion Immo",     plan:"agence", amount:49000, method:"Wave",         ref:"WV-2026-0526-1190", submitted:"2026-05-26 18:47", proof:false, note:"Capture manquante — à vérifier avec l'agence" },
  { id:"PAY-7735", agency:"Cocody Premium",        plan:"cabinet",amount:129000,method:"Virement",     ref:"VIR-CI-0099821",    submitted:"2026-05-25 16:05", proof:true,  note:"Virement bancaire reçu, rapprochement à confirmer" },
];

const SAC_PROMO_TYPE_LABEL = { percent:"% de remise", fixed:"Montant fixe", months:"Mois offerts" };
function sacPromoValue(p) {
  if (p.type === "percent") return `−${p.value}%`;
  if (p.type === "fixed")   return `−${fmtFCFA(p.value)}`;
  return `${p.value} mois offerts`;
}
function sacPromoChip(status) {
  const m = { actif:["#3FB583","rgba(63,181,131,0.14)"], "épuisé":["#E0A74A","rgba(224,167,74,0.14)"], "expiré":["#7B8494","rgba(123,132,148,0.14)"] };
  const [c,bg] = m[status] || m.actif;
  return <span style={{fontSize:10.5, fontWeight:600, padding:"2px 9px", borderRadius:4, background:bg, color:c}}>{status}</span>;
}

/* ═══ Modal shell réutilisable ═══ */
function SACModal({ title, eyebrow, onClose, children, footer, width = 640 }) {
  React.useEffect(() => {
    const onKey = e => { if (e.key === "Escape") onClose?.(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <>
      <div onClick={onClose} style={{position:"fixed", inset:0, background:"rgba(8,12,20,0.6)", zIndex:200, backdropFilter:"blur(3px)"}}/>
      <div role="dialog" style={{
        position:"fixed", left:"50%", top:"8vh", transform:"translateX(-50%)", zIndex:201,
        width:`min(${width}px, 92vw)`, maxHeight:"84vh", background:"var(--d-bg)",
        border:"1px solid var(--d-line)", borderRadius:10, display:"flex", flexDirection:"column",
        overflow:"hidden", boxShadow:"0 30px 80px -20px rgba(0,0,0,0.6)", animation:"baill-pop 180ms ease-out",
      }}>
        <header style={{padding:"16px 22px", borderBottom:"1px solid var(--d-line)", display:"flex", alignItems:"center", justifyContent:"space-between", background:"var(--d-panel)"}}>
          <div>
            {eyebrow && <div style={{fontSize:10.5, fontWeight:700, letterSpacing:"0.12em", color:"var(--d-ink-4)", textTransform:"uppercase", marginBottom:3}}>{eyebrow}</div>}
            <div style={{fontSize:16, fontWeight:600, color:"var(--d-ink)"}}>{title}</div>
          </div>
          <button onClick={onClose} style={{width:32, height:32, borderRadius:6, color:"var(--d-ink-3)", fontSize:18, display:"grid", placeItems:"center", background:"transparent", border:"1px solid var(--d-line)", cursor:"pointer"}}>×</button>
        </header>
        <div style={{overflow:"auto", padding:"20px 24px"}}>{children}</div>
        {footer && <footer style={{padding:"14px 22px", borderTop:"1px solid var(--d-line)", background:"var(--d-panel)", display:"flex", justifyContent:"flex-end", gap:8}}>{footer}</footer>}
      </div>
    </>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SECTION · TARIFICATION
   ═══════════════════════════════════════════════════════════════════════ */
function SATarification() {
  const [tab, setTab] = React.useState("plans");
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Tarification</h1>
          <div className="page-sub">Plans, limites, codes promo et abonnements personnalisés</div>
        </div>
      </div>
      <div className="tabs">
        {[["plans","Plans & limites"],["promo","Codes promo"],["custom","Abonnements personnalisés"]].map(([k,l])=>(
          <button key={k} className={"tab"+(tab===k?" active":"")} onClick={()=>setTab(k)}>{l}</button>
        ))}
      </div>
      {tab === "plans"  && <SACPlans/>}
      {tab === "promo"  && <SACPromo/>}
      {tab === "custom" && <SACCustom/>}
    </div>
  );
}

/* ─── Plans & limites ─── */
function SACPlans() {
  const [plans, setPlans] = React.useState(SAC_PLANS_INIT);
  const [editing, setEditing] = React.useState(null); // plan object being edited

  const save = (updated) => {
    setPlans(ps => ps.map(p => p.id === updated.id ? updated : p));
    setEditing(null);
  };

  return (
    <>
      <Banner tone="info" title="Configuration des offres">
        Ces réglages pilotent la grille tarifaire publique et les limites appliquées à chaque compte (lots, utilisateurs, dépassement). La modification d'un prix n'affecte que les nouveaux abonnements et les renouvellements.
      </Banner>

      <div style={{display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:14}}>
        {plans.map(p => {
          const meta = SA_PLAN_META[p.id] || {};
          return (
            <div key={p.id} className="panel" style={{borderColor: p.id==="agence"?"rgba(109,93,246,0.3)":undefined}}>
              <div style={{padding:"16px 18px", borderBottom:"1px solid var(--d-line-2)"}}>
                <div style={{display:"flex", justifyContent:"space-between", alignItems:"center"}}>
                  <div style={{display:"flex", alignItems:"center", gap:8}}>
                    <span style={{width:10, height:10, borderRadius:3, background: meta.color || SAC_ACCENT}}/>
                    <span style={{fontSize:14, fontWeight:600}}>{p.label}</span>
                  </div>
                  {!p.active && <span style={{fontSize:10, color:"var(--d-ink-4)"}}>masqué</span>}
                </div>
                <div style={{marginTop:10, display:"flex", alignItems:"baseline", gap:6}}>
                  <span className="mono" style={{fontSize:22, fontWeight:700}}>{p.monthly===0?"Gratuit":fmtFCFA(p.monthly)}</span>
                  {p.monthly>0 && <span style={{fontSize:11, color:"var(--d-ink-4)"}}>/ mois</span>}
                </div>
                {p.monthly>0 && <div style={{fontSize:11, color:"var(--d-ink-4)", marginTop:2}}>ou {fmtFCFA(p.annual)}/mois en annuel</div>}
              </div>
              <div style={{padding:"6px 0"}}>
                {[
                  ["Lots inclus", p.lotLimit===0 ? "Illimités" : p.lotLimit],
                  ["Utilisateurs", p.users===0 ? "Illimités" : p.users],
                  ["Dépassement", p.overage>0 ? `${fmtFCFA(p.overage)}/lot` : "—"],
                  ["Essai", p.trialDays>0 ? `${p.trialDays} jours` : "—"],
                ].map(([k,v],i)=>(
                  <div key={i} style={{display:"flex", justifyContent:"space-between", padding:"7px 18px", fontSize:12, borderBottom:"1px solid var(--d-line-2)"}}>
                    <span className="muted">{k}</span><span className="mono" style={{fontWeight:500}}>{v}</span>
                  </div>
                ))}
                <div style={{padding:"10px 18px"}}>
                  <div style={{fontSize:10, textTransform:"uppercase", letterSpacing:"0.06em", color:"var(--d-ink-4)", fontWeight:600, marginBottom:6}}>Fonctionnalités ({p.features.length})</div>
                  <div style={{display:"flex", flexDirection:"column", gap:4}}>
                    {p.features.slice(0,4).map((f,i)=>(
                      <div key={i} style={{fontSize:11.5, color:"var(--d-ink-2)", display:"flex", gap:6}}><span style={{color:meta.color||SAC_ACCENT}}>✓</span>{f}</div>
                    ))}
                    {p.features.length>4 && <div style={{fontSize:11, color:"var(--d-ink-4)"}}>+ {p.features.length-4} autres</div>}
                  </div>
                </div>
              </div>
              <div style={{padding:"12px 18px", borderTop:"1px solid var(--d-line)", display:"flex", gap:8}}>
                <button className="btn btn-secondary" style={{flex:1}} onClick={()=>setEditing(p)}>Configurer</button>
              </div>
            </div>
          );
        })}
      </div>

      {editing && <SACPlanModal plan={editing} onClose={()=>setEditing(null)} onSave={save}/>}
    </>
  );
}

function SACPlanModal({ plan, onClose, onSave }) {
  const [f, setF] = React.useState({ ...plan, featuresText: plan.features.join("\n") });
  const set = (k,v) => setF(s=>({...s,[k]:v}));
  const num = v => Number(String(v).replace(/[^0-9]/g,"")) || 0;
  return (
    <SACModal eyebrow="Configurer le plan" title={f.label} onClose={onClose} width={620}
      footer={<>
        <button className="btn btn-ghost" onClick={onClose}>Annuler</button>
        <button className="btn btn-primary" style={{background:SAC_ACCENT, borderColor:SAC_ACCENT}}
          onClick={()=>onSave({ ...f, features: f.featuresText.split("\n").map(s=>s.trim()).filter(Boolean) })}>Enregistrer</button>
      </>}>
      <FormSection title="Tarifs" subtitle="Prix affichés en FCFA. Le tarif annuel est le prix mensuel facturé à l'année.">
        <FieldRow>
          <Field label="Prix mensuel"><MoneyInput value={f.monthly} onChange={e=>set("monthly", num(e.target.value))}/></Field>
          <Field label="Prix mensuel en annuel"><MoneyInput value={f.annual} onChange={e=>set("annual", num(e.target.value))}/></Field>
        </FieldRow>
      </FormSection>
      <FormSection title="Limites" subtitle="0 = illimité. Le dépassement s'applique au-delà du nombre de lots inclus.">
        <FieldRow columns="1fr 1fr 1fr">
          <Field label="Lots inclus" hint="0 = illimité"><Input value={f.lotLimit} onChange={e=>set("lotLimit", num(e.target.value))} style={{fontFamily:"var(--font-mono)", textAlign:"right"}}/></Field>
          <Field label="Utilisateurs" hint="0 = illimité"><Input value={f.users} onChange={e=>set("users", num(e.target.value))} style={{fontFamily:"var(--font-mono)", textAlign:"right"}}/></Field>
          <Field label="Essai (jours)"><Input value={f.trialDays} onChange={e=>set("trialDays", num(e.target.value))} style={{fontFamily:"var(--font-mono)", textAlign:"right"}}/></Field>
        </FieldRow>
        <Field label="Coût du lot supplémentaire" hint="Au-delà des lots inclus"><MoneyInput value={f.overage} onChange={e=>set("overage", num(e.target.value))}/></Field>
      </FormSection>
      <FormSection title="Fonctionnalités" subtitle="Une fonctionnalité par ligne. Affichées sur la page tarifaire.">
        <Field label="Liste"><Textarea rows={6} value={f.featuresText} onChange={e=>set("featuresText", e.target.value)}/></Field>
        <Field label="Visibilité"><Segmented value={f.active?"on":"off"} onChange={v=>set("active", v==="on")} options={[{value:"on",label:"Plan visible"},{value:"off",label:"Masqué"}]}/></Field>
      </FormSection>
    </SACModal>
  );
}

/* ─── Codes promo ─── */
function SACPromo() {
  const [codes, setCodes] = React.useState(SAC_PROMO_INIT);
  const [modal, setModal] = React.useState(null); // {mode, code}

  const upsert = (c) => {
    setCodes(cs => {
      const i = cs.findIndex(x => x.code === c.code);
      if (i >= 0) { const next = cs.slice(); next[i] = c; return next; }
      return [c, ...cs];
    });
    setModal(null);
  };
  const toggle = (code) => setCodes(cs => cs.map(c => c.code===code ? {...c, status: c.status==="actif"?"expiré":"actif"} : c));

  return (
    <>
      <div className="panel">
        <div className="panel-head">
          <div><h3 className="panel-title">Codes promotionnels</h3><div className="panel-sub">{codes.filter(c=>c.status==="actif").length} actifs · {codes.length} au total</div></div>
          <button className="btn btn-primary" style={{padding:"5px 12px", fontSize:11.5, background:SAC_ACCENT, borderColor:SAC_ACCENT}} onClick={()=>setModal({mode:"create"})}>+ Créer un code</button>
        </div>
        <div className="table-wrap">
          <table className="tbl">
            <thead><tr><th>Code</th><th>Avantage</th><th>Plans</th><th className="right">Utilisations</th><th>Expire</th><th>Statut</th><th style={{width:90}}></th></tr></thead>
            <tbody>
              {codes.map(c=>(
                <tr key={c.code}>
                  <td className="mono" style={{fontWeight:600, color:SAC_ACCENT}}>{c.code}</td>
                  <td style={{fontWeight:500}}>{sacPromoValue(c)}<span className="muted" style={{fontSize:11, marginLeft:6}}>{SAC_PROMO_TYPE_LABEL[c.type]}</span></td>
                  <td className="muted" style={{fontSize:11.5}}>{c.plans.map(p=>SA_PLAN_META[p]?.label||p).join(", ")}</td>
                  <td className="right mono">
                    {c.used} / {c.maxUses}
                    <div style={{height:3, background:"var(--d-sunken)", borderRadius:2, marginTop:3, overflow:"hidden"}}>
                      <div style={{height:"100%", width:`${Math.min(100,(c.used/c.maxUses)*100)}%`, background: c.used>=c.maxUses?"var(--orange)":SAC_ACCENT}}/>
                    </div>
                  </td>
                  <td className="mono muted" style={{fontSize:11.5}}>{c.expires}</td>
                  <td>{sacPromoChip(c.status)}</td>
                  <td style={{textAlign:"right"}}>
                    <button onClick={()=>setModal({mode:"edit", code:c})} title="Modifier" style={{width:26,height:26,borderRadius:5,border:"1px solid var(--d-line)",background:"transparent",color:"var(--d-ink-3)",cursor:"pointer",fontSize:12,marginRight:4}}>✎</button>
                    <button onClick={()=>toggle(c.code)} title="Activer / désactiver" style={{width:26,height:26,borderRadius:5,border:"1px solid var(--d-line)",background:"transparent",color:"var(--d-ink-3)",cursor:"pointer",fontSize:11}}>⏻</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      {modal && <SACPromoModal mode={modal.mode} initial={modal.code} onClose={()=>setModal(null)} onSave={upsert}/>}
    </>
  );
}

function SACPromoModal({ mode, initial, onClose, onSave }) {
  const [f, setF] = React.useState(initial || { code:"", type:"percent", value:10, plans:["agence"], maxUses:100, used:0, expires:"2026-12-31", status:"actif" });
  const set = (k,v)=>setF(s=>({...s,[k]:v}));
  const togglePlan = (p)=>setF(s=>({...s, plans: s.plans.includes(p)?s.plans.filter(x=>x!==p):[...s.plans,p]}));
  const num = v => Number(String(v).replace(/[^0-9]/g,"")) || 0;
  const valid = f.code.trim() && f.plans.length && f.value>0;
  return (
    <SACModal eyebrow={mode==="edit"?"Modifier le code":"Nouveau code promo"} title={f.code||"Code promo"} onClose={onClose}
      footer={<>
        <button className="btn btn-ghost" onClick={onClose}>Annuler</button>
        <button className="btn btn-primary" disabled={!valid} style={{background:SAC_ACCENT, borderColor:SAC_ACCENT, opacity:valid?1:0.5, cursor:valid?"pointer":"not-allowed"}} onClick={()=>onSave(f)}>{mode==="edit"?"Enregistrer":"Créer le code"}</button>
      </>}>
      <FormSection title="Code" subtitle="Saisi par l'agence à la souscription.">
        <Field label="Code" required><Input value={f.code} onChange={e=>set("code", e.target.value.toUpperCase().replace(/\s/g,""))} placeholder="LANCEMENT25" style={{fontFamily:"var(--font-mono)", textTransform:"uppercase"}} readOnly={mode==="edit"}/></Field>
      </FormSection>
      <FormSection title="Avantage" subtitle="Type de remise accordée.">
        <Field label="Type"><Segmented value={f.type} onChange={v=>set("type",v)} options={[{value:"percent",label:"% remise"},{value:"fixed",label:"Montant fixe"},{value:"months",label:"Mois offerts"}]}/></Field>
        <Field label={f.type==="percent"?"Pourcentage":f.type==="fixed"?"Montant (FCFA)":"Nombre de mois"}>
          {f.type==="fixed"
            ? <MoneyInput value={f.value} onChange={e=>set("value", num(e.target.value))}/>
            : <Input value={f.value} onChange={e=>set("value", num(e.target.value))} suffix={f.type==="percent"?"%":"mois"} style={{fontFamily:"var(--font-mono)", textAlign:"right", maxWidth:160}}/>}
        </Field>
      </FormSection>
      <FormSection title="Application" subtitle="Plans éligibles, quota et expiration.">
        <Field label="Plans éligibles" required>
          <div style={{display:"flex", gap:8}}>
            {["solo","agence","cabinet"].map(p=>{
              const on=f.plans.includes(p);
              return <button key={p} onClick={()=>togglePlan(p)} style={{padding:"6px 14px", borderRadius:5, cursor:"pointer", fontSize:12, fontWeight:on?600:400, border:"1px solid "+(on?SAC_ACCENT:"var(--d-line)"), background:on?SAC_ACCENT_SOFT:"var(--d-panel)", color:on?SAC_ACCENT:"var(--d-ink-2)"}}>{on?"✓ ":""}{SA_PLAN_META[p]?.label||p}</button>;
            })}
          </div>
        </Field>
        <FieldRow>
          <Field label="Nombre max d'utilisations"><Input value={f.maxUses} onChange={e=>set("maxUses", num(e.target.value))} style={{fontFamily:"var(--font-mono)", textAlign:"right"}}/></Field>
          <Field label="Date d'expiration"><Input type="date" value={f.expires} onChange={e=>set("expires", e.target.value)} style={{fontFamily:"var(--font-mono)"}}/></Field>
        </FieldRow>
      </FormSection>
    </SACModal>
  );
}

/* ─── Abonnements personnalisés ─── */
function SACCustom() {
  const [items, setItems] = React.useState(SAC_CUSTOM_INIT);
  const [modal, setModal] = React.useState(null);
  const upsert = (c) => {
    setItems(xs => {
      const i = xs.findIndex(x => x.id === c.id);
      if (i>=0){ const n=xs.slice(); n[i]=c; return n; }
      return [...xs, {...c, id:"CUS-"+String(Date.now()).slice(-4)}];
    });
    setModal(null);
  };
  return (
    <>
      <Banner tone="info" title="Tarifs négociés sur mesure">
        Pour les cabinets et gros comptes hors grille standard : prix, limites et durée d'engagement spécifiques. Un abonnement personnalisé prime sur le plan public de l'agence.
      </Banner>
      <div className="panel">
        <div className="panel-head">
          <div><h3 className="panel-title">Abonnements personnalisés</h3><div className="panel-sub">{items.length} contrats sur mesure</div></div>
          <button className="btn btn-primary" style={{padding:"5px 12px", fontSize:11.5, background:SAC_ACCENT, borderColor:SAC_ACCENT}} onClick={()=>setModal({})}>+ Créer un tarif sur mesure</button>
        </div>
        <div className="table-wrap">
          <table className="tbl">
            <thead><tr><th>Agence</th><th className="right">Prix / mois</th><th className="right">Lots</th><th className="right">Util.</th><th>Valide jusqu'au</th><th>Note</th><th style={{width:44}}></th></tr></thead>
            <tbody>
              {items.map(c=>(
                <tr key={c.id}>
                  <td style={{fontWeight:500}}>{c.agency}</td>
                  <td className="right mono" style={{fontWeight:600}}>{fmtFCFA(c.price)}</td>
                  <td className="right mono">{c.lotLimit}</td>
                  <td className="right mono">{c.users}</td>
                  <td className="mono muted" style={{fontSize:11.5}}>{c.validUntil}</td>
                  <td className="muted" style={{fontSize:11.5, maxWidth:240}}>{c.note}</td>
                  <td style={{textAlign:"right"}}><button onClick={()=>setModal(c)} style={{width:26,height:26,borderRadius:5,border:"1px solid var(--d-line)",background:"transparent",color:"var(--d-ink-3)",cursor:"pointer",fontSize:12}}>✎</button></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      {modal && <SACCustomModal initial={modal.id?modal:null} onClose={()=>setModal(null)} onSave={upsert}/>}
    </>
  );
}

function SACCustomModal({ initial, onClose, onSave }) {
  const [f, setF] = React.useState(initial || { id:"", agency:"", price:150000, lotLimit:"Illimité", users:10, validUntil:"2027-12-31", note:"" });
  const set = (k,v)=>setF(s=>({...s,[k]:v}));
  const num = v => Number(String(v).replace(/[^0-9]/g,"")) || 0;
  const valid = f.agency.trim() && f.price>0;
  return (
    <SACModal eyebrow={initial?"Modifier le tarif":"Tarif sur mesure"} title={f.agency||"Nouvel abonnement personnalisé"} onClose={onClose}
      footer={<>
        <button className="btn btn-ghost" onClick={onClose}>Annuler</button>
        <button className="btn btn-primary" disabled={!valid} style={{background:SAC_ACCENT, borderColor:SAC_ACCENT, opacity:valid?1:0.5, cursor:valid?"pointer":"not-allowed"}} onClick={()=>onSave(f)}>{initial?"Enregistrer":"Créer"}</button>
      </>}>
      <FormSection title="Contrat" subtitle="Conditions négociées avec l'agence.">
        <Field label="Agence" required><Input value={f.agency} onChange={e=>set("agency", e.target.value)} placeholder="Nom de l'agence"/></Field>
        <FieldRow columns="1fr 1fr 1fr">
          <Field label="Prix / mois" required><MoneyInput value={f.price} onChange={e=>set("price", num(e.target.value))}/></Field>
          <Field label="Lots" hint="Nombre ou « Illimité »"><Input value={f.lotLimit} onChange={e=>set("lotLimit", e.target.value)}/></Field>
          <Field label="Utilisateurs"><Input value={f.users} onChange={e=>set("users", num(e.target.value))} style={{fontFamily:"var(--font-mono)", textAlign:"right"}}/></Field>
        </FieldRow>
        <Field label="Valide jusqu'au"><Input type="date" value={f.validUntil} onChange={e=>set("validUntil", e.target.value)} style={{fontFamily:"var(--font-mono)"}}/></Field>
        <Field label="Note interne"><Textarea rows={2} value={f.note} onChange={e=>set("note", e.target.value)} placeholder="Conditions, remise, contexte commercial…"/></Field>
      </FormSection>
    </SACModal>
  );
}

/* ═══════════════════════════════════════════════════════════════════════
   SECTION · PAIEMENTS — validation manuelle Wave / OM / virement
   ═══════════════════════════════════════════════════════════════════════ */
function SAPaiements() {
  const [pending, setPending] = React.useState(SAC_PENDING_INIT);
  const [processed, setProcessed] = React.useState([]);

  const act = (id, status) => {
    setPending(ps => {
      const item = ps.find(p => p.id === id);
      if (item) setProcessed(pr => [{ ...item, status, at:"à l'instant" }, ...pr]);
      return ps.filter(p => p.id !== id);
    });
  };

  const totalPending = pending.reduce((s,p)=>s+p.amount, 0);
  const methodColor = m => m==="Wave" ? "#1DC3F8" : m==="Orange Money" ? "#FF7900" : "#7B8494";

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Paiements à valider</h1>
          <div className="page-sub">{pending.length} en attente · {fmtCompact(totalPending)} FCFA · validation manuelle</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost">Journal des transactions</button>
        </div>
      </div>

      <Banner tone="warn" title="Pourquoi cette file ?">
        Quand un paiement Wave / Orange Money / virement est bien reçu mais que l'API ou le webhook n'a pas confirmé automatiquement, le compte reste « en attente ». Validez ici manuellement après vérification de la référence de transaction pour activer l'abonnement.
      </Banner>

      {pending.length === 0 ? (
        <div className="panel" style={{padding:"40px", textAlign:"center", color:"var(--d-ink-3)"}}>
          ✓ Aucun paiement en attente de validation.
        </div>
      ) : (
        <div style={{display:"flex", flexDirection:"column", gap:10}}>
          {pending.map(p => (
            <div key={p.id} className="panel" style={{padding:"16px 18px"}}>
              <div style={{display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:16, flexWrap:"wrap"}}>
                <div style={{display:"flex", gap:14, alignItems:"flex-start", minWidth:0}}>
                  <div style={{width:42, height:42, borderRadius:8, display:"grid", placeItems:"center", background:"color-mix(in srgb, "+methodColor(p.method)+" 18%, transparent)", color:methodColor(p.method), fontWeight:700, fontSize:11, flexShrink:0, textAlign:"center", lineHeight:1.1}}>
                    {p.method==="Wave"?"Wave":p.method==="Orange Money"?"OM":"VIR"}
                  </div>
                  <div style={{minWidth:0}}>
                    <div style={{fontSize:13.5, fontWeight:600, display:"flex", alignItems:"center", gap:8, flexWrap:"wrap"}}>
                      {p.agency}
                      <span style={{fontSize:11, color:SA_PLAN_META[p.plan]?.color, fontWeight:600}}>{SA_PLAN_META[p.plan]?.label}</span>
                      {!p.proof && <span style={{fontSize:9.5, fontWeight:600, padding:"1px 7px", borderRadius:3, background:"rgba(224,104,63,0.15)", color:"#E0683F"}}>preuve manquante</span>}
                    </div>
                    <div className="muted" style={{fontSize:11.5, marginTop:3}}>{p.note}</div>
                    <div style={{display:"flex", gap:14, marginTop:8, fontSize:11.5, color:"var(--d-ink-3)", flexWrap:"wrap"}}>
                      <span>Réf. <span className="mono" style={{color:"var(--d-ink-2)"}}>{p.ref}</span></span>
                      <span>Méthode <b style={{color:methodColor(p.method)}}>{p.method}</b></span>
                      <span>Soumis le <span className="mono">{p.submitted}</span></span>
                      <span className="mono">{p.id}</span>
                    </div>
                  </div>
                </div>
                <div style={{display:"flex", flexDirection:"column", alignItems:"flex-end", gap:8}}>
                  <div className="mono" style={{fontSize:16, fontWeight:700}}>{fmtFCFA(p.amount)}</div>
                  <div style={{display:"flex", gap:8}}>
                    {p.proof && <button className="btn btn-ghost" style={{padding:"5px 10px", fontSize:11.5}}>Voir la preuve</button>}
                    <button className="btn btn-secondary" style={{padding:"5px 12px", fontSize:11.5}} onClick={()=>act(p.id,"rejeté")}>Rejeter</button>
                    <button className="btn btn-primary" style={{padding:"5px 14px", fontSize:11.5, background:"#3FB583", borderColor:"#3FB583"}} onClick={()=>act(p.id,"validé")}>Valider le paiement</button>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {processed.length > 0 && (
        <div className="panel">
          <div className="panel-head"><div><h3 className="panel-title">Traités récemment</h3><div className="panel-sub">{processed.length} ce session</div></div></div>
          <div className="table-wrap">
            <table className="tbl">
              <thead><tr><th>Agence</th><th>Réf.</th><th className="right">Montant</th><th>Décision</th><th>Quand</th></tr></thead>
              <tbody>
                {processed.map((p,i)=>(
                  <tr key={i}>
                    <td style={{fontWeight:500}}>{p.agency}</td>
                    <td className="mono muted" style={{fontSize:11.5}}>{p.ref}</td>
                    <td className="right mono">{fmtFCFA(p.amount)}</td>
                    <td>{p.status==="validé" ? <span className="chip pos">validé</span> : <span className="chip neg">rejeté</span>}</td>
                    <td className="muted" style={{fontSize:11.5}}>{p.at}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SATarification, SAPaiements });

/* ╚══ end pages-superadmin-config.jsx ══╝ */

/* ╔══ lima.jsx ══╗ */
/* global React */

/* ═══════════════════════════════════════════════════════════════════════
   LIMA — Assistante Logestimmo
   Aide à l'utilisation du produit + accompagnement juridique immobilier
   (Code des Obligations OHADA, COCC sénégalais, baux, fiscalité locative)
   ═══════════════════════════════════════════════════════════════════════ */

const LIMA_SYSTEM_PROMPT = `Tu es LIMA, l'assistante intelligente de Logestimmo — une plateforme de gestion locative pour agences immobilières d'Afrique de l'Ouest (Sénégal, Côte d'Ivoire, Togo, Bénin, Cameroun, Mali).

Tu as deux missions :

1) AIDE À L'UTILISATION
Aider l'utilisateur (gestionnaire d'agence, bailleur) à naviguer dans Logestimmo. Tu connais les sections :
- Tableau de bord, Trésorerie, Rapports
- Biens, Bailleurs, Locataires, Baux, Charges & travaux
- Paiements, Quittances, Impayés, CRG, Versements, Récépissés
- Compta bailleurs, Trop-perçus, Compta agence, Export comptable
- Paramètres (Abonnement, Agence, Fiscalité TOM/TLV/TVA, Commissions, Notifications, Banques, Sécurité, API)

2) ACCOMPAGNEMENT JURIDIQUE IMMOBILIER
Tu maîtrises :
- COCC sénégalais (Code des Obligations Civiles et Commerciales) : baux d'habitation, baux à usage professionnel, loyers, dépôt de garantie, expulsion
- OHADA : AUDCG (bail commercial), Acte Uniforme sur les voies d'exécution, AUDSP (procédures simplifiées)
- Fiscalité locative au Sénégal : TVA sur loyers commerciaux (18%), TOM municipale (Taxe d'ordures ménagères), TLV (Taxe sur la valeur locative), retenue à la source, déclaration DGID
- Procédures : mise en demeure, sommation de payer, résiliation, expulsion par décision de justice
- Réglementation Wave/Orange Money et obligations BCEAO

Style :
- Concise, structurée, en français.
- Utilise des listes et des étapes numérotées quand pertinent.
- Cite les articles précis quand tu les connais (ex: "article 544 du COCC").
- Pour les questions juridiques, termine toujours par : « Information fournie à titre indicatif. Pour une situation spécifique, consultez un notaire ou un avocat. »
- Si la question concerne Logestimmo et que tu ne connais pas une fonctionnalité précise, dis-le et propose de contacter le support.
- N'invente jamais d'articles de loi.`;

const LIMA_STARTERS = [
  {
    cat: "Utilisation",
    icon: "▢",
    items: [
      "Comment générer un CRG mensuel pour un bailleur ?",
      "Où voir mes locataires en retard de paiement ?",
      "Comment importer mes baux depuis Excel ?",
      "Configurer la relance WhatsApp à J+7",
    ],
  },
  {
    cat: "Juridique",
    icon: "§",
    items: [
      "Quel délai légal pour une mise en demeure au Sénégal ?",
      "Le bailleur peut-il augmenter le loyer en cours de bail ?",
      "Procédure d'expulsion pour impayés en zone OHADA",
      "Quelles mentions obligatoires sur un bail d'habitation ?",
    ],
  },
  {
    cat: "Fiscalité",
    icon: "%",
    items: [
      "Comment calculer la TOM pour un lot à Dakar ?",
      "TVA sur loyers commerciaux : qui la déclare ?",
      "Différence entre TLV et taxe foncière",
      "Calendrier des déclarations DGID 2026",
    ],
  },
];

/* ─── Markdown ultra-léger pour les réponses ─── */
function renderMD(text) {
  if (!text) return null;
  const lines = text.split("\n");
  const blocks = [];
  let listBuf = [];
  let listType = null;
  const flushList = () => {
    if (listBuf.length) {
      blocks.push({ type: listType, items: listBuf });
      listBuf = [];
      listType = null;
    }
  };
  lines.forEach((raw) => {
    const line = raw.replace(/\s+$/, "");
    if (!line.trim()) { flushList(); blocks.push({ type: "br" }); return; }
    let m;
    if ((m = line.match(/^\s*[-•]\s+(.+)$/))) {
      if (listType && listType !== "ul") flushList();
      listType = "ul"; listBuf.push(m[1]); return;
    }
    if ((m = line.match(/^\s*\d+[.)]\s+(.+)$/))) {
      if (listType && listType !== "ol") flushList();
      listType = "ol"; listBuf.push(m[1]); return;
    }
    if ((m = line.match(/^(#{1,3})\s+(.+)$/))) {
      flushList();
      blocks.push({ type: "h", level: m[1].length, text: m[2] }); return;
    }
    flushList();
    blocks.push({ type: "p", text: line });
  });
  flushList();

  const inline = (s) => {
    // **bold** and *italic* and `code`
    const parts = [];
    let i = 0, key = 0;
    const re = /(\*\*([^*]+)\*\*|`([^`]+)`)/g;
    let m;
    while ((m = re.exec(s))) {
      if (m.index > i) parts.push(s.slice(i, m.index));
      if (m[2]) parts.push(<b key={"b" + key++}>{m[2]}</b>);
      else if (m[3]) parts.push(<code key={"c" + key++} style={{fontFamily:"var(--font-mono)", fontSize:"0.92em", background:"var(--d-elev)", padding:"1px 5px", borderRadius:3}}>{m[3]}</code>);
      i = m.index + m[0].length;
    }
    if (i < s.length) parts.push(s.slice(i));
    return parts.length ? parts : s;
  };

  return blocks.map((b, idx) => {
    if (b.type === "br") return <div key={idx} style={{height: 6}}/>;
    if (b.type === "h") {
      const Tag = "div";
      return <Tag key={idx} style={{
        fontSize: b.level === 1 ? 14 : 13, fontWeight: 600,
        color: "var(--d-ink)", marginTop: idx === 0 ? 0 : 10, marginBottom: 4,
      }}>{inline(b.text)}</Tag>;
    }
    if (b.type === "ul") {
      return (
        <ul key={idx} style={{margin:"4px 0 8px", padding:"0 0 0 6px", listStyle:"none"}}>
          {b.items.map((it, i) => (
            <li key={i} style={{display:"flex", gap:8, padding:"2px 0", fontSize:12.5, color:"var(--d-ink-2)", lineHeight:1.55}}>
              <span style={{color:"var(--blue-d)", fontWeight:600, flexShrink:0, marginTop:1}}>·</span>
              <span>{inline(it)}</span>
            </li>
          ))}
        </ul>
      );
    }
    if (b.type === "ol") {
      return (
        <ol key={idx} style={{margin:"4px 0 8px", padding:"0 0 0 4px", listStyle:"none", counterReset:"li"}}>
          {b.items.map((it, i) => (
            <li key={i} style={{
              display:"flex", gap:10, padding:"2px 0", fontSize:12.5,
              color:"var(--d-ink-2)", lineHeight:1.55,
            }}>
              <span className="mono" style={{
                color:"var(--d-ink-4)", flexShrink:0, fontSize:11, minWidth:14,
                fontVariantNumeric:"tabular-nums",
              }}>{String(i+1).padStart(2,"0")}</span>
              <span>{inline(it)}</span>
            </li>
          ))}
        </ol>
      );
    }
    return (
      <p key={idx} style={{margin:"3px 0", fontSize:12.5, lineHeight:1.6, color:"var(--d-ink-2)"}}>
        {inline(b.text)}
      </p>
    );
  });
}

/* ─── Logo LIMA ─── */
function LimaMark({ size = 22, animate = false }) {
  return (
    <span style={{
      width:size, height:size, borderRadius: size * 0.28,
      background:"linear-gradient(135deg, #7C3AED 0%, #2563EB 60%, #3FB583 120%)",
      display:"grid", placeItems:"center", flexShrink:0,
      boxShadow: animate ? "0 0 0 0 rgba(124,58,237,0.45)" : "none",
      animation: animate ? "lima-pulse 1.4s ease-out infinite" : "none",
      position:"relative",
    }}>
      <svg width={size * 0.5} height={size * 0.5} viewBox="0 0 24 24" fill="none">
        <path d="M12 2L14.5 9.5L22 12L14.5 14.5L12 22L9.5 14.5L2 12L9.5 9.5L12 2Z"
              fill="white" opacity="0.95"/>
      </svg>
    </span>
  );
}

/* ─── Floating launcher ─── */
function LimaLauncher({ onClick, unread }) {
  return (
    <button onClick={onClick} title="LIMA · Assistante" style={{
      position:"fixed", right:22, bottom:22, zIndex:90,
      width:52, height:52, borderRadius:26,
      background:"linear-gradient(135deg, #1A1029 0%, #0A0E17 100%)",
      border:"1px solid #2A1F4A",
      boxShadow:"0 12px 32px -6px rgba(124,58,237,0.45), 0 0 0 1px rgba(124,58,237,0.2)",
      display:"grid", placeItems:"center", cursor:"pointer",
      transition:"transform 160ms ease",
    }}
    onMouseEnter={e=>e.currentTarget.style.transform="translateY(-2px)"}
    onMouseLeave={e=>e.currentTarget.style.transform="translateY(0)"}>
      <LimaMark size={28} animate/>
      {unread > 0 && (
        <span style={{
          position:"absolute", top:-2, right:-2, minWidth:18, height:18, padding:"0 5px",
          borderRadius:9, background:"var(--orange)", color:"#fff",
          fontSize:10, fontWeight:700, display:"grid", placeItems:"center",
          border:"2px solid var(--d-bg)",
        }}>{unread}</span>
      )}
    </button>
  );
}

/* ─── Topbar shortcut ─── */
function LimaTopbarBtn({ onClick }) {
  return (
    <button onClick={onClick} title="Ouvrir LIMA · ⌘L" style={{
      display:"inline-flex", alignItems:"center", gap:7,
      padding:"5px 10px 5px 7px", borderRadius:5,
      background:"linear-gradient(135deg, rgba(124,58,237,0.12) 0%, rgba(37,99,235,0.08) 100%)",
      border:"1px solid rgba(124,58,237,0.25)",
      color:"var(--d-ink-2)", fontSize:11.5, fontWeight:500,
      cursor:"pointer", transition:"background 160ms ease",
    }}
    onMouseEnter={e=>e.currentTarget.style.background="linear-gradient(135deg, rgba(124,58,237,0.20) 0%, rgba(37,99,235,0.14) 100%)"}
    onMouseLeave={e=>e.currentTarget.style.background="linear-gradient(135deg, rgba(124,58,237,0.12) 0%, rgba(37,99,235,0.08) 100%)"}>
      <LimaMark size={16}/>
      <span>Demander à LIMA</span>
      <span className="kbd" style={{marginLeft:4}}>⌘L</span>
    </button>
  );
}

/* ─── Panel ─── */
// Démo : réponses fictives de LIMA (aucun appel IA réel)
function limaDemoReply(q) {
  const s = (q || "").toLowerCase();
  const note = "\n\n— Réponse d'exemple (démo). Dans l'application, LIMA répond à partir de vos vraies données.";
  if (/quittance|reçu|recu/.test(s)) return "Pour émettre une quittance, va dans **Quittances → Générer le lot du mois** : Logestimmo crée une quittance par bail actif, l'horodate et l'archive automatiquement. Tu peux aussi la générer à l'unité, prorata inclus." + note;
  if (/impay|relance|retard|recouvr/.test(s)) return "Depuis **Impayés**, tu lances une relance en un clic. La chaîne va de la relance amiable WhatsApp (J+7) à la mise en demeure, en gardant une trace conforme au COCC pour un éventuel dossier." + note;
  if (/ohada|juridiqu|\bloi\b|bail|contrat|cocc|clause/.test(s)) return "En zone OHADA, le bail d'habitation relève surtout du droit national (au Sénégal, le COCC) ; le bail commercial suit l'Acte uniforme. Une clause de résiliation mal rédigée peut être requalifiée par le juge. ⚠️ Réponse illustrative, pas un conseil juridique." + note;
  if (/commission|honorair|taux/.test(s)) return "Par défaut, la commission de gestion est de **8% pour le nu** et **11% pour le meublé**, surchargeable par bien ou par bail. Elle s'applique sur les loyers encaissés pour calculer le net propriétaire." + note;
  if (/versement|revers|crg|bordereau|net propri/.test(s)) return "Le **net propriétaire** = loyers encaissés − commission − charges récupérables. Tu génères le bordereau de versement (ou le CRG mensuel) depuis **Versements** / **CRG**, prêt à partager et archiver." + note;
  if (/wave|orange money|mobile money|paiement|encaiss/.test(s)) return "Les paiements Wave et Orange Money sont rapprochés automatiquement et liés au bon locataire ; les espèces se saisissent en quelques secondes avec reçu. Tout est tracé dans **Paiements**." + note;
  return "Je suis **LIMA**, l'assistante de Logestimmo : aide à l'utilisation du produit et questions de droit immobilier OHADA. Demande-moi par exemple « comment générer les quittances du mois ? » ou « que faire en cas d'impayé ? »." + note;
}

function LimaPanel({ open, onClose, contextRoute }) {
  const [messages, setMessages] = React.useState([]);
  const [input, setInput] = React.useState("");
  const [loading, setLoading] = React.useState(false);
  const [mode, setMode] = React.useState("auto"); // auto | usage | legal
  const scrollRef = React.useRef(null);
  const inputRef = React.useRef(null);

  React.useEffect(() => {
    if (open && scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages, open]);

  React.useEffect(() => {
    if (open) setTimeout(() => inputRef.current?.focus(), 250);
  }, [open]);

  async function send(text) {
    const content = (text || input).trim();
    if (!content || loading) return;
    const next = [...messages, { role: "user", content }];
    setMessages(next);
    setInput("");
    setLoading(true);
    // Démo : réponses fictives, pas d'appel IA réel
    await new Promise(r => setTimeout(r, 650));
    setMessages([...next, { role: "assistant", content: limaDemoReply(content) }]);
    setLoading(false);
  }

  function reset() {
    setMessages([]);
    setInput("");
  }

  if (!open) return null;

  return (
    <>
      {/* Backdrop */}
      <div onClick={onClose} style={{
        position:"fixed", inset:0, background:"rgba(8,12,20,0.5)", zIndex:100,
        backdropFilter:"blur(2px)",
      }}/>

      {/* Panel */}
      <aside style={{
        position:"fixed", right:0, top:0, bottom:0, width:440, zIndex:101,
        background:"var(--d-bg)", borderLeft:"1px solid var(--d-line)",
        display:"flex", flexDirection:"column",
        boxShadow:"-20px 0 60px -20px rgba(0,0,0,0.5)",
        animation:"lima-slide 220ms ease-out",
      }}>
        {/* Header */}
        <header style={{
          padding:"14px 18px", borderBottom:"1px solid var(--d-line)",
          display:"flex", alignItems:"center", justifyContent:"space-between",
          background:"linear-gradient(180deg, rgba(124,58,237,0.06), transparent)",
        }}>
          <div style={{display:"flex", alignItems:"center", gap:10}}>
            <LimaMark size={28}/>
            <div>
              <div style={{display:"flex", alignItems:"center", gap:8}}>
                <span style={{fontSize:14, fontWeight:600, color:"var(--d-ink)", letterSpacing:"-0.01em"}}>LIMA</span>
                <span style={{
                  fontSize:9, fontWeight:600, padding:"1px 6px", borderRadius:100,
                  background:"rgba(63,181,131,0.14)", color:"var(--pos-d)",
                  letterSpacing:"0.04em", textTransform:"uppercase",
                }}>En ligne</span>
              </div>
              <div style={{fontSize:11, color:"var(--d-ink-4)", marginTop:1}}>
                Assistante Logestimmo · Aide produit & juridique immobilier
              </div>
            </div>
          </div>
          <div style={{display:"flex", gap:4}}>
            {messages.length > 0 && (
              <button onClick={reset} title="Nouvelle conversation" style={{
                width:30, height:30, borderRadius:5, color:"var(--d-ink-3)",
                fontSize:14, display:"grid", placeItems:"center",
                background:"transparent", cursor:"pointer",
              }}>↻</button>
            )}
            <button onClick={onClose} title="Fermer · Esc" style={{
              width:30, height:30, borderRadius:5, color:"var(--d-ink-3)",
              fontSize:18, display:"grid", placeItems:"center",
              background:"transparent", cursor:"pointer",
            }}>×</button>
          </div>
        </header>

        {/* Mode segmented */}
        <div style={{padding:"10px 18px 0", display:"flex", gap:6}}>
          {[
            {v:"auto",  l:"Auto"},
            {v:"usage", l:"Aide produit"},
            {v:"legal", l:"Juridique"},
          ].map(o => (
            <button key={o.v} onClick={()=>setMode(o.v)} style={{
              padding:"5px 11px", borderRadius:100, fontSize:11,
              fontWeight: mode === o.v ? 600 : 500,
              background: mode === o.v ? "var(--d-elev)" : "transparent",
              border: "1px solid " + (mode === o.v ? "var(--d-line)" : "transparent"),
              color: mode === o.v ? "var(--d-ink)" : "var(--d-ink-3)",
              cursor:"pointer",
            }}>{o.l}</button>
          ))}
        </div>

        {/* Body */}
        <div ref={scrollRef} style={{
          flex:1, overflow:"auto", padding:"18px",
          display:"flex", flexDirection:"column", gap:14,
        }}>
          <div style={{fontSize:11.5, color:"var(--d-ink-3)", background:"rgba(124,58,237,0.08)", border:"1px solid var(--d-line)", borderRadius:8, padding:"9px 12px", lineHeight:1.45}}>
            LIMA est présentée ici <b style={{color:"var(--d-ink-2)"}}>à titre d'exemple</b> — ses réponses sont fictives. Dans l'application, elle répond à partir de vos vraies données.
          </div>
          {messages.length === 0 && (
            <LimaStarter onPick={(q) => send(q)} contextRoute={contextRoute}/>
          )}
          {messages.map((m, i) => (
            <LimaMessage key={i} role={m.role} content={m.content} error={m.error}/>
          ))}
          {loading && <LimaTyping/>}
        </div>

        {/* Composer */}
        <div style={{
          padding:"12px 18px 16px", borderTop:"1px solid var(--d-line)",
          background:"var(--d-panel)",
        }}>
          <div style={{
            display:"flex", alignItems:"flex-end", gap:8,
            background:"var(--d-sunken)", border:"1px solid var(--d-line)",
            borderRadius:8, padding:"8px 10px",
          }}>
            <textarea
              ref={inputRef}
              value={input}
              onChange={e=>setInput(e.target.value)}
              onKeyDown={e=>{ if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); } }}
              placeholder={mode === "legal" ? "Posez votre question juridique…" : mode === "usage" ? "Que voulez-vous faire dans Logestimmo ?" : "Comment puis-je vous aider ?"}
              rows={1}
              style={{
                flex:1, resize:"none", background:"transparent", border:"none",
                color:"var(--d-ink)", fontSize:13, fontFamily:"var(--font-sans)",
                outline:"none", maxHeight:120, lineHeight:1.5,
              }}
            />
            <button onClick={()=>send()} disabled={!input.trim() || loading} style={{
              width:30, height:30, borderRadius:5,
              background: input.trim() && !loading ? "linear-gradient(135deg, #7C3AED 0%, #2563EB 100%)" : "var(--d-elev)",
              color: input.trim() && !loading ? "#fff" : "var(--d-ink-4)",
              display:"grid", placeItems:"center", cursor: input.trim() ? "pointer" : "default",
              transition:"all 120ms ease", flexShrink:0,
              fontSize:13, fontWeight:600,
            }}>↑</button>
          </div>
          <div style={{
            display:"flex", justifyContent:"space-between", alignItems:"center",
            marginTop:8, fontSize:10.5, color:"var(--d-ink-4)",
          }}>
            <span>Entrée pour envoyer · Maj+Entrée pour aller à la ligne</span>
            <span style={{display:"flex", alignItems:"center", gap:4}}>
              <span style={{width:6, height:6, borderRadius:50, background:"var(--pos-d)"}}/>
              Conversation privée
            </span>
          </div>
        </div>
      </aside>

      <style>{`
        @keyframes lima-slide {
          from { transform: translateX(20px); opacity: 0; }
          to { transform: translateX(0); opacity: 1; }
        }
        @keyframes lima-pulse {
          0%   { box-shadow: 0 0 0 0 rgba(124,58,237,0.45); }
          70%  { box-shadow: 0 0 0 14px rgba(124,58,237,0); }
          100% { box-shadow: 0 0 0 0 rgba(124,58,237,0); }
        }
        @keyframes lima-dot {
          0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
          30% { transform: translateY(-3px); opacity: 1; }
        }
      `}</style>
    </>
  );
}

function LimaStarter({ onPick, contextRoute }) {
  const contextLabel = {
    overview: "Tableau de bord",
    invoices: "Quittances",
    overdue: "Impayés",
    leases: "Baux",
    crg: "CRG",
    disbursements: "Versements",
    settings: "Paramètres",
  }[contextRoute];

  return (
    <div style={{paddingTop:8}}>
      <div style={{
        display:"flex", alignItems:"flex-start", gap:12, marginBottom:24,
        padding:"16px 16px", borderRadius:8,
        background:"linear-gradient(135deg, rgba(124,58,237,0.10) 0%, rgba(37,99,235,0.06) 100%)",
        border:"1px solid rgba(124,58,237,0.18)",
      }}>
        <LimaMark size={32}/>
        <div>
          <div style={{fontSize:13, fontWeight:600, color:"var(--d-ink)", marginBottom:4}}>
            Bonjour, je suis LIMA.
          </div>
          <div style={{fontSize:12, color:"var(--d-ink-2)", lineHeight:1.55}}>
            Je vous aide à utiliser Logestimmo et je réponds à vos questions juridiques en immobilier
            (COCC, OHADA, fiscalité locative).{contextLabel && (
              <> Vous êtes sur <b style={{color:"var(--d-ink)"}}>{contextLabel}</b> — je peux vous expliquer cette page.</>
            )}
          </div>
        </div>
      </div>

      {LIMA_STARTERS.map((g, gi) => (
        <div key={g.cat} style={{marginBottom: gi < LIMA_STARTERS.length - 1 ? 18 : 0}}>
          <div style={{
            display:"flex", alignItems:"center", gap:8, marginBottom:8,
            fontSize:10.5, fontWeight:700, textTransform:"uppercase", letterSpacing:"0.1em",
            color:"var(--d-ink-4)",
          }}>
            <span className="mono" style={{
              width:18, height:18, borderRadius:4, background:"var(--d-elev)",
              color:"var(--d-ink-2)", display:"grid", placeItems:"center", fontSize:11,
            }}>{g.icon}</span>
            {g.cat}
          </div>
          <div style={{display:"flex", flexDirection:"column", gap:5}}>
            {g.items.map(q => (
              <button key={q} onClick={()=>onPick(q)} style={{
                textAlign:"left", padding:"9px 12px", borderRadius:6,
                background:"var(--d-panel)", border:"1px solid var(--d-line)",
                color:"var(--d-ink-2)", fontSize:12, lineHeight:1.4,
                cursor:"pointer", transition:"all 120ms ease",
              }}
              onMouseEnter={e=>{e.currentTarget.style.background="var(--d-elev)"; e.currentTarget.style.borderColor="rgba(124,58,237,0.35)";}}
              onMouseLeave={e=>{e.currentTarget.style.background="var(--d-panel)"; e.currentTarget.style.borderColor="var(--d-line)";}}>
                {q}
              </button>
            ))}
          </div>
        </div>
      ))}

      <div style={{
        marginTop:22, padding:"10px 12px", borderRadius:6,
        background:"var(--d-sunken)", border:"1px dashed var(--d-line)",
        fontSize:10.5, color:"var(--d-ink-4)", lineHeight:1.55,
      }}>
        Information juridique à titre indicatif. Pour une situation spécifique, consultez un
        notaire ou un avocat.
      </div>
    </div>
  );
}

function LimaMessage({ role, content, error }) {
  if (role === "user") {
    return (
      <div style={{display:"flex", justifyContent:"flex-end"}}>
        <div style={{
          maxWidth:"86%", padding:"10px 14px",
          background:"linear-gradient(135deg, #2C2049 0%, #1F2A4F 100%)",
          border:"1px solid rgba(124,58,237,0.25)",
          borderRadius:"12px 12px 4px 12px",
          fontSize:12.5, color:"var(--d-ink)", lineHeight:1.5,
        }}>
          {content}
        </div>
      </div>
    );
  }
  return (
    <div style={{display:"flex", gap:10, alignItems:"flex-start"}}>
      <LimaMark size={22}/>
      <div style={{
        maxWidth:"88%", padding:"10px 14px",
        background:"var(--d-panel)", border:"1px solid " + (error ? "rgba(241,106,99,0.3)" : "var(--d-line)"),
        borderRadius:"12px 12px 12px 4px",
        color: error ? "var(--neg-d)" : "var(--d-ink-2)",
        fontSize:12.5, lineHeight:1.5,
      }}>
        {renderMD(content)}
      </div>
    </div>
  );
}

function LimaTyping() {
  return (
    <div style={{display:"flex", gap:10, alignItems:"flex-start"}}>
      <LimaMark size={22}/>
      <div style={{
        padding:"12px 16px", background:"var(--d-panel)",
        border:"1px solid var(--d-line)", borderRadius:"12px 12px 12px 4px",
        display:"flex", gap:5,
      }}>
        {[0, 1, 2].map(i => (
          <span key={i} style={{
            width:6, height:6, borderRadius:50, background:"var(--blue-d)",
            animation:"lima-dot 1.2s ease-in-out infinite",
            animationDelay: `${i * 0.15}s`,
          }}/>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { LimaLauncher, LimaPanel, LimaTopbarBtn, LimaMark });

/* ╚══ end lima.jsx ══╝ */

/* ╔══ landing-pricing.jsx ══╗ */
/* global React */

function PricingSection({ onEnterApp }) {
  const [annual, setAnnual] = React.useState(true);
  const [openFaq, setOpenFaq] = React.useState(0);

  // Monthly base prices in FCFA
  const PRICES = {
    agence:    { monthly: 49000,  annual: 39000  }, // -20% on annual
    cabinet:   { monthly: 129000, annual: 105000 },
  };

  function fmt(n) { return n.toLocaleString("fr-FR").replace(/\u202f|\s/g, " "); }

  const tiers = [
    {
      id: "solo",
      name: "Solo",
      tagline: "Bailleurs individuels",
      price: 0,
      priceLabel: "Gratuit",
      priceSub: "à vie, jusqu'à 20 lots",
      cta: "Démarrer gratuitement",
      ctaStyle: "ghost",
      features: [
        { v: true, t: "Jusqu'à 20 lots gérés" },
        { v: true, t: "1 utilisateur" },
        { v: true, t: "Encaissement Wave & Orange Money" },
        { v: true, t: "Quittances PDF illimitées" },
        { v: true, t: "Tableau de bord temps réel" },
        { v: false, t: "Rapprochement automatique" },
        { v: false, t: "Bordereaux & CRG bailleurs" },
        { v: false, t: "Export comptable OHADA" },
      ],
    },
    {
      id: "agence",
      name: "Agence",
      tagline: "Petites et moyennes agences",
      price: annual ? PRICES.agence.annual : PRICES.agence.monthly,
      priceLabel: fmt(annual ? PRICES.agence.annual : PRICES.agence.monthly),
      priceSub: "FCFA / mois · jusqu'à 200 lots",
      cta: "Essayer 14 jours",
      ctaStyle: "primary",
      featured: true,
      badge: "Le plus choisi",
      footnote: "+ 280 FCFA / lot supplémentaire au-delà de 200",
      features: [
        { v: true, t: "Jusqu'à 200 lots, puis au lot" },
        { v: true, t: "5 utilisateurs inclus" },
        { v: true, t: "Tous les moyens de paiement" },
        { v: true, t: "Rapprochement Wave / OM automatique" },
        { v: true, t: "Bordereaux & CRG bailleurs" },
        { v: true, t: "Espace bailleur en ligne" },
        { v: true, t: "Export OHADA · CNSS · DGID" },
        { v: true, t: "Support prioritaire J+1" },
      ],
    },
    {
      id: "cabinet",
      name: "Cabinet",
      tagline: "Multi-agences & syndics",
      price: annual ? PRICES.cabinet.annual : PRICES.cabinet.monthly,
      priceLabel: fmt(annual ? PRICES.cabinet.annual : PRICES.cabinet.monthly),
      priceSub: "FCFA / mois · à partir de",
      cta: "Parler à un conseiller",
      ctaStyle: "secondary",
      footnote: "Lots illimités · facturation sur mesure",
      features: [
        { v: true, t: "Lots & utilisateurs illimités" },
        { v: true, t: "Multi-agences, multi-bailleurs" },
        { v: true, t: "SSO, rôles avancés, audit log" },
        { v: true, t: "API & intégrations Sage / Ciel" },
        { v: true, t: "SLA contractuel 99,9 %" },
        { v: true, t: "Account manager dédié" },
        { v: true, t: "Formation sur site (Dakar, Abidjan, Lomé)" },
        { v: true, t: "Hébergement régional optionnel" },
      ],
    },
  ];

  const faqs = [
    {
      q: "Logestimmo prélève-t-il une commission sur les loyers ?",
      a: "Non. Logestimmo ne détient et ne prélève aucun fonds. Les loyers sont versés directement sur vos comptes ou vos wallets. Vous payez uniquement l'abonnement.",
    },
    {
      q: "Y a-t-il un engagement de durée ?",
      a: "Aucun. Vous résiliez à tout moment depuis votre espace. Si vous payez à l'année, le solde non utilisé reste créditable sur le mois suivant.",
    },
    {
      q: "Que se passe-t-il quand je dépasse mon nombre de lots ?",
      a: "Sur le plan Agence, les lots au-delà de 200 sont facturés 280 FCFA / lot / mois — sans changer de plan. Au-delà de 500 lots, nous passons automatiquement votre compte sur un devis Cabinet.",
    },
    {
      q: "Comment migrer depuis Excel ou un cahier ?",
      a: "Nous importons vos lots, baux et bailleurs depuis un fichier Excel ou un export comptable. La migration prend 1 à 3 jours selon le volume. Un onboarding sur site est inclus dès le plan Agence.",
    },
    {
      q: "Quels modes de paiement acceptez-vous pour l'abonnement ?",
      a: "Wave, Orange Money, virement bancaire en FCFA, carte bancaire internationale. Facturation mensuelle ou annuelle, en français, conforme aux mentions OHADA.",
    },
    {
      q: "Mes données restent-elles en Afrique de l'Ouest ?",
      a: "Par défaut, les données sont hébergées à Paris (Tier IV, conforme RGPD). Sur le plan Cabinet, un hébergement régional à Dakar ou Abidjan est disponible en option.",
    },
  ];

  return (
    <section id="tarifs" className="pricing">
      {/* Header */}
      <div className="pricing-header">
        <div className="pricing-header-left">
          <div className="pricing-eyebrow">Abonnement</div>
          <h2 className="pricing-title">Un tarif clair.<br/>Adapté à votre parc.</h2>
        </div>
        <div className="pricing-header-right">
          <p className="pricing-lede">
            Tarification en FCFA. Pas de commission sur vos loyers. Sans engagement — vous changez de plan ou résiliez à tout moment.
          </p>
          <div className="pricing-toggle" role="tablist">
            <button
              role="tab"
              aria-selected={!annual}
              className={"pricing-toggle-btn " + (!annual ? "is-active" : "")}
              onClick={() => setAnnual(false)}
            >Mensuel</button>
            <button
              role="tab"
              aria-selected={annual}
              className={"pricing-toggle-btn " + (annual ? "is-active" : "")}
              onClick={() => setAnnual(true)}
            >
              Annuel
              <span className="pricing-toggle-save">−20%</span>
            </button>
          </div>
        </div>
      </div>

      {/* Cards */}
      <div className="pricing-grid">
        {tiers.map(t => (
          <div key={t.id} className={"pricing-card" + (t.featured ? " is-featured" : "")}>
            {t.badge && <div className="pricing-badge">{t.badge}</div>}

            <div className="pricing-card-head">
              <div className="pricing-card-name">{t.name}</div>
              <div className="pricing-card-tagline">{t.tagline}</div>
            </div>

            <div className="pricing-card-price">
              {t.price === 0 ? (
                <>
                  <div className="pricing-price-main">{t.priceLabel}</div>
                  <div className="pricing-price-sub">{t.priceSub}</div>
                </>
              ) : (
                <>
                  <div className="pricing-price-main">
                    <span className="pricing-price-num">{t.priceLabel}</span>
                    <span className="pricing-price-unit">FCFA</span>
                  </div>
                  <div className="pricing-price-sub">
                    {t.priceSub.replace(/^FCFA · /, "")}
                    {annual && t.id !== "solo" && (
                      <span className="pricing-price-billed"> · facturé annuellement</span>
                    )}
                  </div>
                </>
              )}
            </div>

            <button
              className={
                t.ctaStyle === "primary" ? "l-btn-primary pricing-cta" :
                t.ctaStyle === "secondary" ? "l-btn-secondary pricing-cta" :
                "l-btn-ghost pricing-cta pricing-cta-ghost"
              }
              onClick={onEnterApp}
            >
              {t.cta}{t.ctaStyle !== "ghost" && <span>→</span>}
            </button>

            <ul className="pricing-features">
              {t.features.map((f, i) => (
                <li key={i} className={f.v ? "is-on" : "is-off"}>
                  <span className="pricing-feat-icon" aria-hidden="true">
                    {f.v ? "✓" : "—"}
                  </span>
                  <span>{f.t}</span>
                </li>
              ))}
            </ul>

            {t.footnote && <div className="pricing-foot">{t.footnote}</div>}
          </div>
        ))}
      </div>

      {/* Trust strip */}
      <div className="pricing-trust">
        <div className="pricing-trust-item">
          <div className="pricing-trust-k">0 %</div>
          <div className="pricing-trust-v">commission sur vos loyers</div>
        </div>
        <div className="pricing-trust-sep" />
        <div className="pricing-trust-item">
          <div className="pricing-trust-k">14 j</div>
          <div className="pricing-trust-v">d'essai sur le plan Agence, sans carte</div>
        </div>
        <div className="pricing-trust-sep" />
        <div className="pricing-trust-item">
          <div className="pricing-trust-k">1–3 j</div>
          <div className="pricing-trust-v">migration depuis Excel ou un cahier</div>
        </div>
        <div className="pricing-trust-sep" />
        <div className="pricing-trust-item">
          <div className="pricing-trust-k">FCFA</div>
          <div className="pricing-trust-v">paiement Wave, OM, virement ou carte</div>
        </div>
      </div>

      {/* FAQ */}
      <div className="pricing-faq">
        <div className="pricing-faq-left">
          <div className="pricing-eyebrow">Questions fréquentes</div>
          <h3 className="pricing-faq-title">Avant de souscrire.</h3>
          <p className="pricing-faq-sub">
            Une question plus spécifique ? Notre équipe répond sous 1 jour ouvré, en français.
          </p>
          <button className="l-btn-secondary" style={{marginTop: 20}}>Écrire à l'équipe →</button>
        </div>
        <div className="pricing-faq-list">
          {faqs.map((f, i) => (
            <div key={i} className={"pricing-faq-item" + (openFaq === i ? " is-open" : "")}>
              <button className="pricing-faq-q" onClick={() => setOpenFaq(openFaq === i ? -1 : i)}>
                <span>{f.q}</span>
                <span className="pricing-faq-toggle" aria-hidden="true">{openFaq === i ? "−" : "+"}</span>
              </button>
              {openFaq === i && <div className="pricing-faq-a">{f.a}</div>}
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { PricingSection });

/* ╚══ end landing-pricing.jsx ══╝ */

/* ╔══ landing.jsx ══╗ */
/* global React, Logo */

function Landing({ onEnterApp, onLogin, onSignup, onBlog }) {
  return (
    <div className="landing">

      {/* NAV */}
      <nav className="nav">
        <div className="nav-logo"><Logo size={26} /><span>Logestimmo</span></div>
        <div className="nav-links">
          <a className="nav-link">Produit</a>
          <a className="nav-link">Solutions</a>
          <a className="nav-link" href="#tarifs">Tarifs</a>
          <a className="nav-link" onClick={onBlog}>Blog</a>
          <a className="nav-link">Contact</a>
        </div>
        <div className="nav-right">
          <button className="l-btn-ghost" onClick={onLogin}>Se connecter</button>
          <button className="l-btn-primary" onClick={onEnterApp}>Voir la démo →</button>
        </div>
      </nav>

      {/* HERO */}
      <section className="hero2">
        <div className="hero2-text">
          <h1 className="hero2-title">
            Encaissez vos loyers.<br />
            Suivez tout.<br />
            <span className="accent">Sans tableur.</span>
          </h1>
          <div className="hero2-tagline">Plus de cahier, plus d'Excel, plus de pertes d'information.</div>
          <div className="hero2-side">
            <p className="hero2-sub">
              Espèces, Mobile Money, virements — chaque paiement est enregistré, rapproché et visible en temps réel. Vous savez exactement qui a payé, quand, et ce qu'il reste à encaisser.
            </p>
            <div className="hero2-checks">
              <div className="hero2-check"><span className="hero2-check-icon">✔</span>Les fonds restent sur vos comptes</div>
              <div className="hero2-check"><span className="hero2-check-icon">✔</span>Aucune saisie manuelle</div>
              <div className="hero2-check"><span className="hero2-check-icon">✔</span>Conforme aux pratiques OHADA</div>
            </div>
            <div className="hero2-actions">
              <button className="l-btn-primary" onClick={onSignup||onEnterApp}>Essayer gratuitement</button>
              <button className="l-btn-ghost" style={{ color: "var(--ink-3)" }} onClick={onEnterApp}>Voir la démo →</button>
            </div>
          </div>
        </div>

        <div className="hero2-frame-wrap">
          <div className="hero-frame">
            <div className="hero-frame-chrome">
              <div className="hfc-dots"><span className="hfc-dot" /><span className="hfc-dot" /><span className="hfc-dot" /></div>
              <div className="hfc-addr">app.logestimmo.sn · avril 2026</div>
              <div style={{ width: 40 }} />
            </div>
            <div className="hf-body">
              <div className="hf-eyebrow">Encaissé · avril 2026</div>
              <div className="hf-big">11 730 000<span className="unit">FCFA</span></div>
              <div className="hf-deltarow">
                <span className="pos">▲ 4,2%</span>
                <span>vs mars · sur 12 690 000 attendus</span>
              </div>
              <div className="hf-minichart">
                <svg viewBox="0 0 400 60" width="100%" height="60" style={{ display: "block" }}>
                  <defs>
                    <linearGradient id="heroArea" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="#2563EB" stopOpacity="0.35" />
                      <stop offset="100%" stopColor="#2563EB" stopOpacity="0" />
                    </linearGradient>
                  </defs>
                  <path d="M0 45 L36 40 L72 44 L108 36 L144 32 L180 34 L216 28 L252 24 L288 22 L324 26 L360 18 L400 20 L400 60 L0 60 Z" fill="url(#heroArea)" />
                  <path d="M0 45 L36 40 L72 44 L108 36 L144 32 L180 34 L216 28 L252 24 L288 22 L324 26 L360 18 L400 20" stroke="#6192FF" strokeWidth="1.8" fill="none" />
                </svg>
              </div>
              <div className="hf-row">
                <div>
                  <div className="hf-row-name">Mariama Ndiaye</div>
                  <div className="hf-row-sub">Rés. Teranga · A-203 · Wave</div>
                </div>
                <div className="hf-row-amt">240 000<div className="alt"><span className="hf-tag pay">encaissé</span></div></div>
              </div>
              <div className="hf-row">
                <div>
                  <div className="hf-row-name">Cheikh T. Diagne</div>
                  <div className="hf-row-sub">Imm. Point E · B-101 · 7 j retard</div>
                </div>
                <div className="hf-row-amt">280 000<div className="alt"><span className="hf-tag late">en retard</span></div></div>
              </div>
              <div className="hf-row">
                <div>
                  <div className="hf-row-name">Bineta Diouf</div>
                  <div className="hf-row-sub">Rés. Plateau · 5 · attente</div>
                </div>
                <div className="hf-row-amt">225 000<div className="alt"><span className="hf-tag wait">à venir</span></div></div>
              </div>
            </div>
            <div className="hero-callout">
              <div className="hero-callout-label">Impayés détectés</div>
              <div className="hero-callout-body">3 loyers non réglés depuis plus de 30 jours</div>
              <div className="hero-callout-meta">Rés. Teranga · relance J+3</div>
            </div>
          </div>
        </div>
      </section>

      {/* POSITIONING LINE */}
      <div className="positioning-line">
        <div className="positioning-inner">
          Pensé pour les bailleurs et agences immobilières d'Afrique de l'Ouest.
          <span className="positioning-sep">·</span>
          Commencez seul. Structurez votre gestion. Passez à l'échelle.
        </div>
      </div>

      {/* CITIES BAND */}
      <div className="cities-band">
        <div className="cities-inner">
          <span className="cities-label">Agences actives à</span>
          <div className="cities-list">
            {["Dakar", "Abidjan", "Lomé", "Cotonou", "Douala", "Bamako", "Conakry"].map((c) =>
            <span key={c} className="cities-city">{c}</span>
            )}
          </div>
        </div>
      </div>

      {/* HOW IT WORKS — éditorial */}
      <section className="hiw2">
        <div className="hiw2-header">
          <div className="hiw2-eyebrow">Fonctionnement</div>
          <h2 className="hiw2-title">Trois étapes.<br />Zéro perte d'information.</h2>
        </div>
        <div className="hiw2-steps">
          <div className="hiw2-step">
            <div className="hiw2-num">01</div>
            <div className="hiw2-step-body">
              <div className="hiw2-step-title">Le locataire paie</div>
              <p className="hiw2-step-desc">Espèces au bureau, Wave, Orange Money ou virement bancaire.</p>
              <div className="hiw2-pills">
                <span className="hiw2-pill esp">ESPÈCES</span>
                <span className="hiw2-pill wave">WAVE</span>
                <span className="hiw2-pill om">ORANGE MONEY</span>
                <span className="hiw2-pill vir">VIREMENT</span>
              </div>
            </div>
          </div>
          <div className="hiw2-step">
            <div className="hiw2-num">02</div>
            <div className="hiw2-step-body">
              <div className="hiw2-step-title">Logestimmo enregistre automatiquement chaque paiement</div>
              <p className="hiw2-step-desc">Espèces saisies en quelques secondes. Wave et Orange Money rapprochés automatiquement. Chaque paiement lié au locataire et à sa quittance.</p>
              <div className="hiw2-match">
                <div className="hiw2-match-col">
                  <div className="hiw2-match-label">Paiement Wave</div>
                  <div className="hiw2-match-val">240 000 FCFA</div>
                  <div className="hiw2-match-meta">18 avr · 10:42</div>
                </div>
                <div className="hiw2-match-link">↔</div>
                <div className="hiw2-match-col">
                  <div className="hiw2-match-label">M. Ndiaye</div>
                  <div className="hiw2-match-val">Rés. Teranga</div>
                  <div className="hiw2-match-meta">A-203 · Loyer avr.</div>
                </div>
              </div>
            </div>
          </div>
          <div className="hiw2-step">
            <div className="hiw2-num">03</div>
            <div className="hiw2-step-body">
              <div className="hiw2-step-title">Vous gardez le contrôle</div>
              <p className="hiw2-step-desc">Statut des loyers en temps réel, relances programmées, quittances générées, export comptable.</p>
              <div className="hiw2-outputs">
                <div className="hiw2-output">Quittance générée</div>
                <div className="hiw2-output">Vous suivez et relancez en 1 clic</div>
                <div className="hiw2-output">Export OHADA</div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* PRODUCT — features */}
      <section className="feats">

        {/* 01 — ENCAISSEMENT */}
        <div className="feat2">
          <div className="feat2-bg-num">01</div>
          <div className="feat2-content">
            <div className="feat2-text">
              <div className="feat2-label">Encaissement</div>
              <h3 className="feat2-title">Peu importe comment ils paient.<br/>Vous gardez le contrôle.</h3>
              <p className="feat2-desc">Espèces, Wave, Orange Money, virement — Logestimmo trace tout dans un seul endroit, sans ambiguïté et sans perte d'information.</p>
              <ul className="feat2-list">
                <li>Espèces saisies en quelques secondes · reçu généré</li>
                <li>Wave et Orange Money rapprochés automatiquement</li>
                <li>Historique complet de tous les encaissements</li>
              </ul>
            </div>
            <div className="feat2-visual">
              <div className="vis-kpi-label">Encaissements tracés · avril</div>
              <div className="vis-big">11,73<span className="unit">M FCFA</span></div>
              <div className="vis-subrow"><span className="tag">▲ 4,2%</span><span>15 / 18 quittances encaissées</span></div>
              <div className="vis-mm">
                <div className="vis-mm-row">
                  <div className="vis-mm-badge wave">WAVE</div>
                  <div><div className="vis-mm-name">M. Ndiaye, O. Sy, F. Kane</div><div className="vis-mm-sub">Rapprochement automatique · 18 avr 10:42</div></div>
                  <div className="vis-mm-amt">790 000</div>
                </div>
                <div className="vis-mm-row">
                  <div className="vis-mm-badge om">OM</div>
                  <div><div className="vis-mm-name">N. Thiam, P. Diop</div><div className="vis-mm-sub">Rapprochement automatique · 18 avr 09:15</div></div>
                  <div className="vis-mm-amt">550 000</div>
                </div>
                <div className="vis-mm-row">
                  <div className="vis-mm-badge esp">ESP</div>
                  <div><div className="vis-mm-name">A. Sall · Rés. Plateau B-04</div><div className="vis-mm-sub">Saisie manuelle · 17 avr · reçu émis</div></div>
                  <div className="vis-mm-amt">350 000</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* 02 — IMPAYÉS */}
        <div className="feat2 alt">
          <div className="feat2-bg-num">02</div>
          <div className="feat2-content">
            <div className="feat2-text">
              <div className="feat2-label">Impayés</div>
              <h3 className="feat2-title">Détectez les retards<br />avant qu'ils coûtent cher.</h3>
              <p className="feat2-desc">Suivi des loyers dès J+1, relances automatiques et historique complet. Aucun locataire ne passe entre les mailles du filet.</p>
              <ul className="feat2-list">
                <li>Statut de chaque locataire mis à jour en temps réel</li>
                <li>Relance rapide via WhatsApp</li>
                <li>Dossier contentieux prêt en 1 clic</li>
              </ul>
            </div>
            <div className="feat2-visual">
              <div className="vis-overdue-header">
                <span className="vis-overdue-title">Impayés · Rés. Teranga</span>
                <span className="vis-overdue-badge">3 locataires</span>
              </div>
              <div className="vis-list-row"><div><div className="n">Moussa Fall · C-304</div><div className="s">42 jours · 2 mensualités</div></div><div /><div className="amt" style={{ color: "var(--orange)" }}>440 000</div></div>
              <div className="vis-list-row"><div><div className="n">Cheikh T. Diagne · B-101</div><div className="s">7 jours · 1 mensualité</div></div><div /><div className="amt" style={{ color: "var(--orange)" }}>280 000</div></div>
              <div className="vis-list-row"><div><div className="n">Bineta Diouf · Plateau 5</div><div className="s">3 jours · 1 mensualité</div></div><div /><div className="amt" style={{ color: "var(--warn-d)" }}>225 000</div></div>
              <div className="vis-overdue-action">
                <span>Relance J+3 programmée · 2 locataires</span>
                <span className="vis-overdue-link">Voir le dossier →</span>
              </div>
            </div>
          </div>
        </div>

        {/* 03 — REVERSEMENT */}
        <div className="feat2">
          <div className="feat2-bg-num">03</div>
          <div className="feat2-content">
            <div className="feat2-text">
              <div className="feat2-label">Reversement</div>
              <h3 className="feat2-title">Le net propriétaire,<br />calculé sans erreur.</h3>
              <p className="feat2-desc">Logestimmo calcule automatiquement commissions, charges et montants à reverser. Vous générez un bordereau clair, prêt à être partagé ou archivé.</p>
              <ul className="feat2-list">
                <li>Bordereaux conformes OHADA</li>
                <li>Signature électronique à valeur légale</li>
                <li>Archivage 10 ans · export CNSS / DGID</li>
              </ul>
            </div>
            <div className="feat2-visual">
              <div className="vis-doc">
                <div className="vis-doc-head">
                  <div>
                    <div className="vis-doc-title">Bordereau de versement</div>
                    <div style={{ color: "var(--d-ink-3)", fontSize: 11, marginTop: 2 }}>Horizon SCI · avril 2026</div>
                  </div>
                  <div className="vis-doc-id">BV-2026-04-018</div>
                </div>
                <div className="vis-doc-row"><div className="k">Loyers bruts</div><div className="v">4 230 000 FCFA</div></div>
                <div className="vis-doc-row"><div className="k">Commission 8,0 %</div><div className="v">− 338 400 FCFA</div></div>
                <div className="vis-doc-row"><div className="k">Charges</div><div className="v">− 145 000 FCFA</div></div>
                <div className="vis-doc-row"><div className="k">Retenue TOB</div><div className="v">− 135 360 FCFA</div></div>
                <div className="vis-doc-row"><div className="k" style={{ color: "var(--d-ink-2)", fontWeight: 600 }}>Net à verser</div><div className="v" style={{ color: "var(--pos-d)", fontWeight: 600 }}>3 611 240 FCFA</div></div>
                <div className="vis-doc-sig">
                  <div className="vis-doc-stamp">SIGNÉ<br />18 AVR<br />2026</div>
                  <div className="vis-doc-stamp-meta">Signé par <b style={{ color: "var(--d-ink)" }}>Seynabou Niang</b><br />Directrice · BA Immo<br />Émis vers CBAO · il y a 1 h 23 min</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* STATS BAND */}
      <div className="stats2-band">
        <div className="stats2-inner">
          <div className="stats2-item">
            <div className="stats2-val">2,1 Md</div>
            <div className="stats2-label">FCFA de loyers suivis</div>
          </div>
          <div className="stats2-sep" />
          <div className="stats2-item">
            <div className="stats2-val">420+</div>
            <div className="stats2-label">Agences actives</div>
          </div>
          <div className="stats2-sep" />
          <div className="stats2-item">
            <div className="stats2-val">14 000+</div>
            <div className="stats2-label">Quittances générées par mois</div>
          </div>
          <div className="stats2-sep" />
          <div className="stats2-item">
            <div className="stats2-val orange">+34%</div>
            <div className="stats2-label">Taux de recouvrement moyen après 6 mois</div>
          </div>
        </div>
      </div>

      {/* MANIFESTO — crédibilité + sécurité fusionnées */}
      <section className="manifesto">
        <div className="manifesto-inner">
          <div className="manifesto-left">
            <div className="manifesto-eyebrow">Fiabilité &amp; traçabilité</div>
            <h2 className="manifesto-title">
              Logestimmo<br />
              ne détient<br />
              aucun fonds.
            </h2>
            <p className="manifesto-desc">
              Les paiements sont effectués directement entre vos locataires et vos comptes. Logestimmo enregistre, structure et sécurise les données — sans jamais détenir l'argent.
            </p>
          </div>
          <div className="manifesto-right">
            <div className="manifesto-audit">
              <div className="manifesto-audit-head">
                <span>Historique de paiement · Lot A-203</span>
                <span className="manifesto-audit-badge">Immuable</span>
              </div>
              <div className="manifesto-audit-row">
                <span className="mono manifesto-date">18 avr 2026</span>
                <span className="manifesto-event">Paiement Wave · 240 000 FCFA</span>
                <span className="manifesto-status ok">Rapproché</span>
              </div>
              <div className="manifesto-audit-row">
                <span className="mono manifesto-date">18 avr 2026</span>
                <span className="manifesto-event">Quittance émise · QT-2026-04-A203</span>
                <span className="manifesto-status ok">Générée</span>
              </div>
              <div className="manifesto-audit-row">
                <span className="mono manifesto-date">18 mar 2026</span>
                <span className="manifesto-event">Paiement Wave · 240 000 FCFA</span>
                <span className="manifesto-status ok">Rapproché</span>
              </div>
              <div className="manifesto-audit-row">
                <span className="mono manifesto-date">18 fév 2026</span>
                <span className="manifesto-event">Paiement Wave · 240 000 FCFA</span>
                <span className="manifesto-status ok">Rapproché</span>
              </div>
            </div>
            <div className="manifesto-pillars">
              <div className="manifesto-pillar">
                <div className="manifesto-pillar-title">Données tracées</div>
                <div className="manifesto-pillar-desc">Chaque paiement, horodaté et lié à son contrat. Aucune modification silencieuse.</div>
              </div>
              <div className="manifesto-pillar">
                <div className="manifesto-pillar-title">Export OHADA</div>
                <div className="manifesto-pillar-desc">Grand livre, journaux, bilans. Format SYSCOHADA révisé, prêt pour l'audit.</div>
              </div>
              <div className="manifesto-pillar">
                <div className="manifesto-pillar-title">Cohérence contrats</div>
                <div className="manifesto-pillar-desc">Paiements vérifiés contre les baux en cours. Toute anomalie remonte immédiatement.</div>
              </div>
              <div className="manifesto-pillar">
                <div className="manifesto-pillar-title">Archivage 10 ans</div>
                <div className="manifesto-pillar-desc">Documents opposables, signatures électroniques, historique complet consultable.</div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* USE CASE — épuré */}
      <section className="usecase2">
        <div className="usecase2-inner">
          <div className="usecase2-header">
            <div className="usecase2-eyebrow">Cas concret</div>
            <h2 className="usecase2-title">BA Immo, Dakar.<br />198 lots. Avant et après.</h2>
          </div>
          <div className="usecase2-cols">
            <div className="usecase2-col">
              <div className="usecase2-col-label before">Avant</div>
              <div className="usecase2-items">
                <div className="usecase2-item">Excel mis à jour manuellement chaque mois</div>
                <div className="usecase2-item">Rapprochements à la main · 3–4 jours</div>
                <div className="usecase2-item">Clôture le 12–15 du mois suivant</div>
                <div className="usecase2-item">Propriétaires relancés par téléphone</div>
              </div>
            </div>
            <div className="usecase2-arrow">→</div>
            <div className="usecase2-col">
              <div className="usecase2-col-label after">Après</div>
              <div className="usecase2-items">
                <div className="usecase2-item">Paiements rapprochés automatiquement</div>
                <div className="usecase2-item">Taux de recouvrement visible le 1er du mois</div>
                <div className="usecase2-item usecase2-item-highlight">Clôture mensuelle en 1 jour au lieu de plusieurs</div>
                <div className="usecase2-item usecase2-item-highlight">100 % des loyers visibles en temps réel</div>
                <div className="usecase2-item">Bordereau propriétaire émis le même jour</div>
                <div className="usecase2-item">Accès propriétaire en ligne en autonomie</div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* VOICES */}
      <section className="voices">
        <div className="voices-inner">
          <div className="voices-header">
            <div className="voices-eyebrow">Terrain</div>
            <h2 className="voices-title">Des équipes qui ont remplacé leur tableur.</h2>
          </div>
          <div className="quotes2">
            <div className="quote2">
              <div className="quote2-stat">−3 semaines</div>
              <div className="quote2-body">Avant, nous clôturions le mois le 15. Depuis Logestimmo, nous clôturons le 1er, et nos propriétaires reçoivent leur bordereau le même jour.</div>
              <div className="quote2-author">
                <div className="quote2-avatar">SN</div>
                <div><div className="quote2-name">Abdoulaye BA</div><div className="quote2-role">Directeur · BA Immo, Dakar</div></div>
              </div>
            </div>
            <div className="quote2">
              <div className="quote2-stat">94 % recouvré</div>
              <div className="quote2-body">Les relances automatiques sur Wave et Orange Money ont tout changé. Nos locataires paient avant J+7 dans 94 % des cas — contre 62 % avant.</div>
              <div className="quote2-author">
                <div className="quote2-avatar" style={{ background: "var(--orange)" }}>KC</div>
                <div><div className="quote2-name">Kouassi Coulibaly</div><div className="quote2-role">Gérant · Cité Lagune, Abidjan</div></div>
              </div>
            </div>
            <div className="quote2">
              <div className="quote2-stat">+68 lots</div>
              <div className="quote2-body">Nous sommes passés de 42 à 110 lots sans embaucher. Logestimmo nous a permis de grandir. Les propriétaires voient leurs chiffres en temps réel.</div>
              <div className="quote2-author">
                <div className="quote2-avatar" style={{ background: "#1F6E4A" }}>AM</div>
                <div><div className="quote2-name">Aminata Mbow</div><div className="quote2-role">Associée · Teranga Gestion, Lomé</div></div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* PRICING */}
      <PricingSection onEnterApp={onEnterApp} />

      {/* CTA FINAL */}
      <section className="cta2">
        <div className="cta2-inner">
          <h2 className="cta2-title">Arrêtez de gérer<br />vos loyers dans un tableur.</h2>
          <div className="cta2-actions">
            <button className="l-btn-primary" onClick={onEnterApp} style={{ padding: "14px 28px", fontSize: 14 }}>Voir comment ça marche →</button>
            <button className="l-btn-ghost" style={{ color: "rgba(255,255,255,0.45)", fontSize: 14, padding: "14px 0" }} onClick={onSignup||onEnterApp}>Essayer gratuitement</button>
          </div>
          <div className="cta2-note">Gratuit jusqu'à 20 lots · installation en 1 journée · conforme OHADA</div>
        </div>
      </section>

      {/* FOOTER */}
      <footer className="footer">
        <div className="footer-inner">
          <div>
            <div className="nav-logo" style={{ marginBottom: 16 }}><Logo size={24} /><span>Logestimmo</span></div>
            <div style={{ color: "var(--ink-3)", fontSize: 13, maxWidth: 300, lineHeight: 1.55 }}>
              Suivi locatif pour agences et syndics d'Afrique de l'Ouest. Aucune détention de fonds.
            </div>
          </div>
          <div>
            <div className="footer-col-title">Produit</div>
            <a className="footer-link">Tableau de bord</a>
            <a className="footer-link">Encaissement</a>
            <a className="footer-link">Versements</a>
            <a className="footer-link">Rapports</a>
          </div>
          <div>
            <div className="footer-col-title">Entreprise</div>
            <a className="footer-link">À propos</a>
            <a className="footer-link">Tarifs</a>
            <a className="footer-link">Partenaires</a>
            <a className="footer-link">Contact</a>
          </div>
          <div>
            <div className="footer-col-title">Ressources</div>
            <a className="footer-link">Documentation</a>
            <a className="footer-link">Statut</a>
            <a className="footer-link">Droit OHADA</a>
            <a className="footer-link">Support</a>
          </div>
        </div>
        <div className="footer-bottom">
          <div>© 2026 Logestimmo SAS · RC Dakar 2024-B-12 847</div>
          <div>Dakar · Abidjan · Lomé</div>
        </div>
      </footer>
    </div>);

}

Object.assign(window, { Landing });
/* ╚══ end landing.jsx ══╝ */
