// MIZO Intelligence — shared engine. Every figure is derived from the demo ledger (MIZO_DATA / MIZO_OPS / MIZO_FIN); nothing is typed in twice.
const INTEL_TODAY = '2026-10-28';
const iDays = (d) => Math.round((new Date(d + 'T12:00') - new Date(INTEL_TODAY + 'T12:00')) / 86400000);
const iAdd = (iso, n) => { const d = new Date(iso + 'T12:00'); d.setDate(d.getDate() + n); return d.toISOString().slice(0, 10); };
// supplier delivery rhythm: days until next drop, days that drop must cover
const SUP_RHYTHM = { s1: [1, 5, '2026-10-29'], s2: [1, 2, '2026-10-29'], s3: [2, 4, '2026-10-30'], s4: [2, 4, '2026-10-30'], s5: [5, 7, '2026-11-02'] };
const LOADED_WAGE = 19.8; // average line wage incl. employer costs

function intelUse(recipes) { const u = {}; recipes.forEach((r) => r.lines.forEach((l) => { u[l.ing] = (u[l.ing] || 0) + l.qty * r.sold; })); return u; }

function buildIntel(c) {
  const { L, lang, fmt, D, O, inv, recipes, waste, insightState, target, pos, ops } = c;
  const F = window.MIZO_FIN, invMap = Object.fromEntries(inv.map((i) => [i.id, i]));
  const nm = (id) => (invMap[id] ? invMap[id].name[lang] : id), sup = (id) => D.suppliers.find((s) => s.id === id).name;
  const use = intelUse(recipes), af = O.actualFactor, m = fmt.money0, mm = fmt.money;
  const st = (id) => (insightState[id] === 'done' ? 'resolved' : insightState[id] === 'dismissed' ? 'dismissed' : insightState[id] === 'inv' ? 'investigating' : 'new');
  const leaks = [];
  // 1 supplier prices — saving vs best same-spec quote
  const q = Object.entries(D.quotes).map(([id, qs]) => { const i = invMap[id], best = qs.slice().sort((a, b) => a.p - b.p)[0]; return { id, i, best, save: (i.cost - best.p) * D.monthlyUse[id], rise: (i.cost / i.hist[0] - 1) * 100 }; }).filter((x) => x.save > 0.5).sort((a, b) => b.save - a.save);
  const qSum = q.reduce((s, x) => s + x.save, 0);
  leaks.push({ id: 'feta', cat: 'supplier', ic: 'trend-up', impact: qSum, conf: 'high', prov: 'v', urg: 'week', title: L(`${q.length} ingredients cost more than a same-spec quote`, `${q.length} ingrédients coûtent plus qu’une soumission équivalente`), desc: L(`${q.map((x) => nm(x.id)).join(', ')} rose ${fmt.pct(Math.min(...q.map((x) => x.rise)))}–${fmt.pct(Math.max(...q.map((x) => x.rise)))} in six months. Distribution Gastro QC quotes the same product for less.`, `${q.map((x) => nm(x.id)).join(', ')} : hausse de ${fmt.pct(Math.min(...q.map((x) => x.rise)))} à ${fmt.pct(Math.max(...q.map((x) => x.rise)))} en six mois. Distribution Gastro QC offre le même produit moins cher.`),
    ev: { head: [L('Ingredient', 'Ingrédient'), L('Now', 'Actuel'), L('Best quote', 'Meilleure offre'), L('Use / mo', 'Usage / mois'), L('Saving / mo', 'Économie / mois')], body: q.map((x) => [nm(x.id), mm(x.i.cost), `${mm(x.best.p)} · ${sup(x.best.sup).split(' ')[0]}`, `${fmt.num(D.monthlyUse[x.id])} ${x.i.unit}`, m(x.save)]) },
    calc: L('(current price − best quote) × monthly use, summed', '(prix actuel − meilleure offre) × usage mensuel, additionné'), action: L('Compare and switch', 'Comparer et changer'), to: ['purchasing', 'prices'] });
  // 2 excess inventory — stock above par plus lots that will expire before they're used
  const daily = (id) => ((use[id] || 0) / 30) * (af[id] || 1);
  const over = inv.filter((i) => i.onHand > i.par).map((i) => ({ i, tied: (i.onHand - i.par) * i.cost }));
  const risk = []; const byIng = {}; ops.lots.filter((l) => l.ing).forEach((l) => (byIng[l.ing] = byIng[l.ing] || []).push(l));
  Object.entries(byIng).forEach(([id, ls]) => { let cum = 0; ls.slice().sort((a, b) => a.exp.localeCompare(b.exp)).forEach((l) => { const can = Math.max(0, daily(id) * Math.max(0, iDays(l.exp)) - cum), r = Math.max(0, l.qty - can); cum += l.qty - r; if (r > 0.05 && invMap[id]) risk.push({ l, id, r, v: r * invMap[id].cost }); }); });
  const tied = over.reduce((s, x) => s + x.tied, 0), riskV = risk.reduce((s, x) => s + x.v, 0);
  leaks.push({ id: 'excess', cat: 'excess', ic: 'stack', impact: riskV + tied * 0.02 * 4, once: tied, conf: 'med', prov: 'e', urg: 'week', title: L(`${m(tied)} of stock sits above par`, `${m(tied)} de stock au-dessus du niveau`), desc: L(`${over.length} items are over par${risk.length ? ` and ${risk.length} lot${risk.length > 1 ? 's' : ''} will likely expire before use (${m(riskV)})` : ''}. Lower the next orders rather than discarding.`, `${over.length} articles dépassent le niveau${risk.length ? ` et ${risk.length} lot(s) risquent d’expirer avant usage (${m(riskV)})` : ''}. Réduisez les prochaines commandes.`),
    ev: { head: [L('Item', 'Article'), L('On hand', 'En stock'), L('Par', 'Niveau'), L('Cash tied up', 'Argent immobilisé')], body: [...over.map((x) => [nm(x.i.id), `${fmt.num(x.i.onHand)} ${x.i.unit}`, fmt.num(x.i.par), m(x.tied)]), ...risk.map((x) => [`${nm(x.id)} · ${L('lot', 'lot')} ${x.l.id}`, `${fmt.num(x.l.qty)}`, L('exp. ', 'exp. ') + fmt.date(x.l.exp), L('at risk ', 'à risque ') + m(x.v)])] },
    calc: L('lots at risk of expiry + 2% a week carrying cost on stock above par', 'lots à risque + 2 % par semaine de coût de détention au-dessus du niveau'), action: L('Adjust reorder levels', 'Ajuster les niveaux'), to: ['inventory', 'reorder'] });
  // 3 food waste — logged waste, avoidable reasons only
  const wl = waste.map((w) => ({ ...w, v: invMap[w.ing] ? w.qty * invMap[w.ing].cost : 0 }));
  const wDates = wl.map((w) => w.date).sort(), wSpan = wl.length ? iDays(wDates[wDates.length - 1]) - iDays(wDates[0]) + 1 : 1;
  const wTot = wl.reduce((s, w) => s + w.v, 0), wAvoid = wl.filter((w) => w.reason !== 'dropped').reduce((s, w) => s + w.v, 0);
  const wMonthly = (wTot / wSpan) * 30.4, wAvoidM = (wAvoid / wSpan) * 30.4;
  const wBy = {}; wl.forEach((w) => { wBy[w.ing] = wBy[w.ing] || { q: 0, v: 0, r: {} }; wBy[w.ing].q += w.qty; wBy[w.ing].v += w.v; wBy[w.ing].r[w.reason] = 1; });
  const wRows = Object.entries(wBy).sort((a, b) => b[1].v - a[1].v);
  leaks.push({ id: 'waste', cat: 'waste', ic: 'trash', impact: wAvoidM, conf: 'high', prov: 'v', urg: 'now', title: L(`${m(wMonthly)} a month in logged waste`, `${m(wMonthly)} par mois de pertes consignées`), desc: L(`${m(wTot)} thrown out in ${wSpan} days. ${m(wAvoidM)}/mo is avoidable (over-prep, spoilage, expiry) — potatoes, gyro and feta lead.`, `${m(wTot)} jetés en ${wSpan} jours. ${m(wAvoidM)}/mois est évitable (surproduction, avarie, expiration) — pommes de terre, gyro et feta en tête.`),
    ev: { head: [L('Ingredient', 'Ingrédient'), L('Qty', 'Qté'), L('Reasons', 'Raisons'), L('Cost', 'Coût')], body: wRows.map(([id, x]) => [nm(id), fmt.num(Math.round(x.q * 10) / 10), Object.keys(x.r).map((r) => O.wasteReasons[r][lang]).join(', '), m(x.v)]) },
    calc: L(`avoidable waste ${m(wAvoid)} ÷ ${wSpan} days × 30.4`, `pertes évitables ${m(wAvoid)} ÷ ${wSpan} jours × 30,4`), action: L('Set smaller prep batches', 'Préparer de plus petits lots'), to: ['inventory', 'waste'] });
  // 4 portions — usage above recipe on portioned items
  const portIds = ['chicken', 'pork', 'lamb', 'feta', 'gyro'];
  const port = portIds.map((id) => ({ id, f: af[id], use: use[id], v: (af[id] - 1) * use[id] * invMap[id].cost })).sort((a, b) => b.v - a.v), portM = port.reduce((s, x) => s + x.v, 0);
  leaks.push({ id: 'portion', cat: 'portion', ic: 'scales', impact: portM, conf: 'med', prov: 'e', urg: 'week', title: L(`Portions run ${fmt.pct((port[0].f - 1) * 100)} heavy on ${nm(port[0].id).toLowerCase()}`, `Portions ${fmt.pct((port[0].f - 1) * 100)} trop généreuses : ${nm(port[0].id).toLowerCase()}`), desc: L('Proteins and feta leave the walk-in faster than recipes predict, after logged waste. Scales on the line and a portion chart usually close most of it.', 'Protéines et feta sortent plus vite que prévu par les recettes, après pertes. Une balance sur la ligne règle l’essentiel.'),
    ev: { head: [L('Item', 'Article'), L('Recipe use / mo', 'Usage recette / mois'), L('Actual ÷ recipe', 'Réel ÷ recette'), L('Excess cost / mo', 'Surcoût / mois')], body: port.map((x) => [nm(x.id), `${fmt.num(Math.round(x.use))} ${invMap[x.id].unit}`, fmt.num(x.f), m(x.v)]) },
    calc: L('(actual ÷ recipe − 1) × recipe usage × unit cost', '(réel ÷ recette − 1) × usage recette × coût unitaire'), action: L('Print portion chart', 'Imprimer le guide des portions'), to: ['inventory', 'variance'] });
  // 5 menu pricing — items above target + 3 pts, capped +12% rise
  const orig = Object.fromEntries(D.recipes.map((r) => [r.id, r.price]));
  const pr = recipes.map((r) => ({ r, c: recipeCost(r, invMap) })).filter(({ r, c }) => c.fc > target + 3 && r.price === orig[r.id]).map(({ r, c }) => { const np = Math.floor(r.price * 1.12) - 0.05; return { r, c, np, v: (np - r.price) * r.sold, nfc: (c.total / np) * 100 }; }).filter((x) => x.np > x.r.price);
  if (pr.length) leaks.push({ id: 'lamb', cat: 'pricing', ic: 'tag', impact: pr.reduce((s, x) => s + x.v, 0), conf: 'med', prov: 'e', urg: 'month', title: L(`${pr.map((x) => x.r.name.en).join(', ')} priced below target`, `${pr.map((x) => x.r.name.fr).join(', ')} sous le prix cible`), desc: L(`Food cost is ${pr.map((x) => fmt.pct(x.c.fc)).join(', ')} against your ${target}% target. A ${mm(pr[0].np - pr[0].r.price)} increase brings it to ${fmt.pct(pr[0].nfc)}. Assumes orders hold steady.`, `Coût de ${pr.map((x) => fmt.pct(x.c.fc)).join(', ')} pour une cible de ${target} %. Une hausse de ${mm(pr[0].np - pr[0].r.price)} le ramène à ${fmt.pct(pr[0].nfc)}. Suppose des ventes stables.`),
    ev: { head: [L('Dish', 'Plat'), L('Price', 'Prix'), L('Plate cost', 'Coût'), L('Food cost', 'Coût %'), L('Suggested', 'Suggéré'), L('Gain / mo', 'Gain / mois')], body: pr.map((x) => [x.r.name[lang], mm(x.r.price), mm(x.c.total), fmt.pct(x.c.fc), mm(x.np), m(x.v)]) },
    calc: L('(suggested − current price) × monthly units, no drop in orders assumed', '(prix suggéré − actuel) × unités mensuelles, sans baisse de ventes'), action: L(`Set price to ${mm(pr[0].np)}`, `Fixer à ${mm(pr[0].np)}`), apply: 'price', np: pr[0].np, rid: pr[0].r.id, to: ['menu', 'engineering'] });
  // 6 labour — slow weekday closes
  const oct = F.days.filter((x) => x.d >= '2026-10-01' && !x.partial);
  const dow = [0, 1, 2, 3, 4, 5, 6].map((w) => { const r = oct.filter((x) => x.w === w); const rv = r.reduce((s, x) => s + x.rev, 0), lb = r.reduce((s, x) => s + x.lab, 0); return { w, pct: (lb / rv) * 100, rev: rv / r.length, lab: lb / r.length }; });
  const labHrs = 2 * 3 * 4.33, labM = labHrs * LOADED_WAGE;
  leaks.push({ id: 'labour', cat: 'labour', ic: 'users-three', impact: labM, conf: 'med', prov: 'e', urg: 'week', title: L('Mon–Wed close is over-staffed', 'Fermeture lun.–mer. en sureffectif'), desc: L(`Labour runs ${fmt.pct((dow[0].pct + dow[1].pct + dow[2].pct) / 3)} of sales Mon–Wed vs ${fmt.pct((dow[4].pct + dow[5].pct) / 2)} Fri–Sat. After 8 pm those nights average 4 tickets an hour; sending one closer home at 8 saves about ${fmt.num(Math.round(labHrs))} hours a month.`, `La main-d’œuvre fait ${fmt.pct((dow[0].pct + dow[1].pct + dow[2].pct) / 3)} des ventes lun.–mer. vs ${fmt.pct((dow[4].pct + dow[5].pct) / 2)} ven.–sam. Après 20 h, environ 4 additions à l’heure; libérer un employé à 20 h économise ${fmt.num(Math.round(labHrs))} h par mois.`),
    ev: { head: [L('Day', 'Jour'), L('Avg sales', 'Ventes moy.'), L('Avg labour', 'Main-d’œuvre moy.'), L('Labour %', '% main-d’œuvre')], body: dow.map((x) => [F.WK[x.w][lang === 'fr' ? 1 : 0], m(x.rev), m(x.lab), fmt.pct(x.pct)]) },
    calc: L(`2 h × 3 nights × 4.33 weeks × ${mm(LOADED_WAGE)} loaded wage`, `2 h × 3 soirs × 4,33 semaines × ${mm(LOADED_WAGE)} salaire chargé`), action: L('Adjust schedule', 'Ajuster l’horaire'), to: ['team', 'schedule'] });
  // 7 inventory discrepancies — count variance not explained by portioning
  const full = O.counts.find((x) => x.kind === 'full'), wkPort = (portM * 7) / 30.4, unexp = Math.max(0, Math.abs(full.varc) - wkPort);
  leaks.push({ id: 'count', cat: 'count', ic: 'clipboard-text', impact: (unexp * 30.4) / 7, conf: 'low', prov: 'e', urg: 'month', title: L(`${m(unexp)} a week missing with no explanation`, `${m(unexp)} par semaine manquants sans explication`), desc: L(`The ${fmt.date(full.date)} full count was ${mm(Math.abs(full.varc))} short. Heavy portions explain about ${m(wkPort)}; the rest is unrecorded staff meals, unlogged waste or loss.`, `L’inventaire du ${fmt.date(full.date)} manquait ${mm(Math.abs(full.varc))}. Les portions en expliquent ${m(wkPort)}; le reste : repas employés, pertes non consignées ou vol.`),
    ev: { head: [L('Count', 'Inventaire'), L('By', 'Par'), L('Items', 'Articles'), L('Variance', 'Écart')], body: O.counts.slice(0, 4).map((x) => [fmt.date(x.date) + ' · ' + (x.kind === 'full' ? L('full', 'complet') : L('spot', 'ponctuel')), x.by, fmt.num(x.items), mm(x.varc)]) },
    calc: L(`(|count variance| − weekly portion excess ${m(wkPort)}) × 30.4 ÷ 7`, `(|écart| − surplus de portions hebdo ${m(wkPort)}) × 30,4 ÷ 7`), action: L('Log staff meals', 'Consigner les repas employés'), to: ['inventory', 'counts'] });
  // 8 delivery fees — refunds for errors + low-return marketing
  const dl = O.delivery, refunds = dl.uber.refunds + dl.dd.refunds, mktWaste = dl.uber.mkt * 0.5;
  leaks.push({ id: 'delivery', cat: 'delivery', ic: 'moped', impact: refunds + mktWaste, conf: 'med', prov: 'v', urg: 'week', title: L(`${m(refunds)} in delivery refunds this month`, `${m(refunds)} de remboursements livraison ce mois-ci`), desc: L(`${dl.uber.errors + dl.dd.errors} orders had missing or wrong items. Uber Eats promos cost ${m(dl.uber.mkt)} and about half brought no repeat orders. Commission is ${dl.uber.comm}% on Uber vs ${dl.dd.comm}% on DoorDash.`, `${dl.uber.errors + dl.dd.errors} commandes avec articles manquants ou erronés. Les promos Uber ont coûté ${m(dl.uber.mkt)}, dont environ la moitié sans retour. Commission ${dl.uber.comm} % chez Uber vs ${dl.dd.comm} % chez DoorDash.`),
    ev: { head: [L('Platform', 'Plateforme'), L('Gross', 'Brut'), L('Commission', 'Commission'), L('Promos', 'Promos'), L('Refunds', 'Remb.')], body: [['Uber Eats', dl.uber], ['DoorDash', dl.dd]].map(([n, x]) => [n, m(x.gross), `${x.comm}% · ${m((x.gross * x.comm) / 100)}`, m(x.mkt), m(x.refunds)]) },
    calc: L('refunds (verified payouts) + 50% of Uber promo spend (modelled no-return share)', 'remboursements (versements vérifiés) + 50 % des promos Uber (part modélisée sans retour)'), action: L('Add packing checklist', 'Ajouter une liste d’emballage'), to: ['sales', 'delivery'] });
  // 9 duplicates
  leaks.push({ id: 'dupinv', cat: 'duplicate', ic: 'copy', impact: 0, once: 1206.85, conf: 'high', prov: 'v', urg: 'now', title: L('Invoice DGQ-30417 arrived twice', 'Facture DGQ-30417 reçue deux fois'), desc: L('Distribution Gastro QC emailed the same invoice on Oct 19 and Oct 27 (same number, amount and lines). The first was paid on Oct 21; the copy is queued for payment.', 'Distribution Gastro QC a envoyé la même facture le 19 et le 27 oct. (même numéro, montant et lignes). La première a été payée le 21 oct.; la copie est en file de paiement.'),
    ev: { head: [L('Received', 'Reçue'), L('Number', 'Numéro'), L('Lines', 'Lignes'), L('Amount', 'Montant'), L('Status', 'Statut')], body: [[fmt.date('2026-10-19'), 'DGQ-30417', '9', mm(1206.85), L('Paid Oct 21', 'Payée 21 oct.')], [fmt.date('2026-10-27'), 'DGQ-30417', '9', mm(1206.85), L('Queued', 'En file')]] },
    calc: L('same supplier + invoice number + amount within 30 days', 'même fournisseur + numéro + montant en 30 jours'), action: L('Remove the copy', 'Retirer la copie'), to: ['purchasing', 'invoices'] });
  leaks.push({ id: 'linen', cat: 'duplicate', ic: 't-shirt', impact: 298, conf: 'high', prov: 'v', urg: 'week', title: L('Two linen services billed in October', 'Deux services de lingerie facturés en octobre'), desc: L('Nettoyage Pro ($312) and LinGo ($298) both charged for weekly aprons and towels. One contract is enough.', 'Nettoyage Pro (312 $) et LinGo (298 $) facturent tous deux tabliers et linges. Un seul contrat suffit.'),
    ev: { head: [L('Vendor', 'Fournisseur'), L('Service', 'Service'), L('Oct', 'oct.')], body: [['Nettoyage Pro', L('Aprons, towels · weekly', 'Tabliers, linges · hebdo'), mm(312)], ['LinGo', L('Aprons, towels · weekly', 'Tabliers, linges · hebdo'), mm(298)]] },
    calc: L('the cheaper duplicate contract, monthly', 'le contrat en double le moins cher, par mois'), action: L('Mark LinGo to cancel', 'Annuler LinGo'), to: null });
  // 10 billing discrepancies — from scanned invoices vs PO / receiving
  const disc = [];
  ops.scans.forEach((s) => { s.lines.forEach((l) => { if (l.price > l.poP + 0.001) disc.push([s.inv, `${nm(l.ing)} · ${L('billed', 'facturé')} ${mm(l.price)} vs PO ${mm(l.poP)}`, (l.price - l.poP) * l.qty]); if (l.poQ === 0) disc.push([s.inv, `${nm(l.ing)} · ${L('not on the PO', 'absent du BC')}`, l.qty * l.price]); if (l.recv != null && l.recv < l.qty) disc.push([s.inv, `${nm(l.ing)} · ${L('billed', 'facturé')} ${l.qty}, ${L('received', 'reçu')} ${l.recv}`, (l.qty - l.recv) * l.price]); }); if (s.fee) disc.push([s.inv, `${s.fee.name[lang]} · ${L('not in agreement', 'hors entente')}`, s.fee.v]); });
  const discT = disc.reduce((s, x) => s + x[2], 0);
  leaks.push({ id: 'billing', cat: 'billing', ic: 'receipt-x', impact: discT, once: discT, conf: 'high', prov: 'v', urg: 'now', title: L(`${disc.length} billing errors on this week’s invoices`, `${disc.length} erreurs sur les factures de la semaine`), desc: L(`Invoice lines that don’t match the purchase order or what was received: ${m(discT)}. At this rate it repeats monthly unless invoices are checked on arrival.`, `Lignes qui ne concordent pas avec le bon de commande ou la réception : ${m(discT)}. À ce rythme, cela se répète chaque mois.`),
    ev: { head: [L('Invoice', 'Facture'), L('Issue', 'Problème'), L('Overbilled', 'Surfacturé')], body: disc.map((x) => [x[0], x[1], mm(x[2])]) },
    calc: L('Σ (billed − PO price) × qty + unordered lines + short deliveries + unagreed fees', 'Σ (facturé − prix BC) × qté + lignes non commandées + manques + frais non convenus'), action: L('Request credits', 'Demander des crédits'), to: ['purchasing', 'scan'] });
  leaks.forEach((x) => { x.status = st(x.id); x.score = intelScore(x); });
  const open = leaks.filter((x) => x.status === 'new' || x.status === 'investigating');
  return { leaks, open, openTotal: open.reduce((s, x) => s + x.impact, 0), openOnce: open.reduce((s, x) => s + (x.once && !x.impact ? x.once : 0), 0), use, wMonthly, wAvoidM, wRows, dow, invMap, q, port, pr, F };
}
const CONF_W = { high: 1, med: 0.7, low: 0.4 }, URG_W = { now: 1.3, week: 1.1, month: 1 };
const intelScore = (x) => ((x.impact || 0) + (x.once || 0) / 6) * CONF_W[x.conf] * URG_W[x.urg];

function useIntel() {
  const c = useMizo();
  return React.useMemo(() => buildIntel(c), [c.lang, c.inv, c.recipes, c.waste, c.insightState, c.target, c.pos, c.ops]);
}

const LEAK_CATS = { supplier: ['trend-up', 'Supplier prices', 'Prix fournisseurs'], excess: ['stack', 'Excess inventory', 'Surstock'], waste: ['trash', 'Food waste', 'Pertes alimentaires'], portion: ['scales', 'Portions', 'Portions'], pricing: ['tag', 'Menu pricing', 'Prix du menu'], labour: ['users-three', 'Labour', 'Main-d’œuvre'], count: ['clipboard-text', 'Inventory discrepancies', 'Écarts d’inventaire'], delivery: ['moped', 'Delivery fees', 'Frais de livraison'], duplicate: ['copy', 'Duplicate charges', 'Doublons'], billing: ['receipt-x', 'Billing discrepancies', 'Erreurs de facturation'] };

function Conf({ k }) {
  const { L } = useMizo();
  const m = { high: [L('High confidence', 'Confiance élevée'), 3], med: [L('Medium confidence', 'Confiance moyenne'), 2], low: [L('Low confidence', 'Confiance faible'), 1] }[k];
  return <span className={'conf conf-' + k} title={m[0]}><span className="conf-bars">{[1, 2, 3].map((i) => <i key={i} className={i <= m[1] ? 'on' : ''}></i>)}</span>{m[0]}</span>;
}
function SimTag() {
  const { L } = useMizo();
  return <span className="sim-tag"><Icon n="flask" />{L('Simulated AI · demo data', 'IA simulée · données démo')}</span>;
}
function StatusPill({ s }) {
  const { L } = useMizo();
  const m = { new: ['neutral', L('New', 'Nouveau')], investigating: ['warn', L('Investigating', 'En cours')], resolved: ['pos', L('Resolved', 'Résolu')], dismissed: ['neutral', L('Dismissed', 'Ignoré')] }[s];
  return <Pill tone={m[0]}>{m[1]}</Pill>;
}

Object.assign(window, { INTEL_TODAY, iDays, iAdd, SUP_RHYTHM, LOADED_WAGE, intelUse, buildIntel, intelScore, useIntel, LEAK_CATS, Conf, SimTag, StatusPill, CONF_W, URG_W });
