/* global React */
const { useState, useEffect, useRef, useMemo } = React;

/* -------------------------------------------------------------
   MONGOLIE — shared components + data + icons
------------------------------------------------------------- */

// ================= ICONS (inline SVG, minimal) =================
const Icon = {
  menu:   (p) => <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><path d="M3 6h18M3 12h18M3 18h18"/></svg>,
  close:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M6 6l12 12M18 6l-12 12"/></svg>,
  chev:   (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M9 6l6 6-6 6"/></svg>,
  chevD:  (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M6 9l6 6 6-6"/></svg>,
  arrow:  (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  sword:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M14 3l7 1-1 7-9 9-5-5 9-9z"/><path d="M7 17l-3 3M9 19l-2 2"/></svg>,
  pick:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 8l10-4-6 10"/><path d="M12 8l-6 10L2 22l4-4 10-6"/></svg>,
  axe:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M13 4a7 7 0 017 7l-5-1-3-3 1-3z"/><path d="M10 10L3 21"/></svg>,
  wheat:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 22V8"/><path d="M6 10c2 0 4 2 4 4M18 10c-2 0-4 2-4 4M6 6c2 0 4 2 4 4M18 6c-2 0-4 2-4 4M6 14c2 0 4 2 4 4M18 14c-2 0-4 2-4 4"/></svg>,
  bow:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 20L20 4"/><path d="M4 8a12 12 0 0012 12"/><path d="M8 4h-4v4"/></svg>,
  home:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" strokeLinecap="round" {...p}><path d="M3 11l9-7 9 7v9a1 1 0 01-1 1h-5v-6h-6v6H4a1 1 0 01-1-1v-9z"/></svg>,
  gear:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 00.3 1.8l.1.1a2 2 0 11-2.8 2.8l-.1-.1a1.7 1.7 0 00-1.8-.3 1.7 1.7 0 00-1 1.5V21a2 2 0 01-4 0v-.1a1.7 1.7 0 00-1-1.5 1.7 1.7 0 00-1.8.3l-.1.1a2 2 0 11-2.8-2.8l.1-.1a1.7 1.7 0 00.3-1.8 1.7 1.7 0 00-1.5-1H3a2 2 0 010-4h.1a1.7 1.7 0 001.5-1 1.7 1.7 0 00-.3-1.8l-.1-.1a2 2 0 112.8-2.8l.1.1a1.7 1.7 0 001.8.3H9a1.7 1.7 0 001-1.5V3a2 2 0 014 0v.1a1.7 1.7 0 001 1.5 1.7 1.7 0 001.8-.3l.1-.1a2 2 0 112.8 2.8l-.1.1a1.7 1.7 0 00-.3 1.8V9a1.7 1.7 0 001.5 1H21a2 2 0 010 4h-.1a1.7 1.7 0 00-1.5 1z"/></svg>,
  star:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" {...p}><path d="M12 2l3 7 7 .7-5.3 4.8 1.6 7L12 17.8 5.7 21.5l1.6-7L2 9.7 9 9l3-7z"/></svg>,
  trophy: (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" strokeLinecap="round" {...p}><path d="M8 21h8M12 17v4M7 4h10v5a5 5 0 01-10 0V4z"/><path d="M7 6H4v2a3 3 0 003 3M17 6h3v2a3 3 0 01-3 3"/></svg>,
  users:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg>,
  map:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" {...p}><path d="M1 6v15l7-3 8 3 7-3V3l-7 3-8-3-7 3z"/><path d="M8 3v15M16 6v15"/></svg>,
  book:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" {...p}><path d="M4 19.5A2.5 2.5 0 016.5 17H20V4a1 1 0 00-1-1H6.5A2.5 2.5 0 004 5.5v14z"/><path d="M4 19.5A2.5 2.5 0 006.5 22H20"/></svg>,
  calendar: (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" {...p}><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>,
  flame:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" {...p}><path d="M12 2s4 4.5 4 9a4 4 0 11-8 0c0-1 .3-2 .7-2.8A4 4 0 019 13c0-3 3-5 3-11z"/></svg>,
  plus:   (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" {...p}><path d="M12 5v14M5 12h14"/></svg>,
  edit:   (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinejoin="round" {...p}><path d="M14 4l6 6-12 12H2v-6l12-12z"/></svg>,
  trash:  (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2M6 6l1 14a2 2 0 002 2h6a2 2 0 002-2l1-14"/></svg>,
  search: (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>,
  bell:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" {...p}><path d="M18 16v-5a6 6 0 10-12 0v5l-2 2h16l-2-2z"/><path d="M10 21a2 2 0 004 0"/></svg>,
  coin:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" {...p}><circle cx="12" cy="12" r="10" fill="#d39b36"/><circle cx="12" cy="12" r="7" fill="none" stroke="#4a3408" strokeWidth="1.5"/><text x="12" y="16" textAnchor="middle" fontSize="10" fill="#4a3408" fontFamily="var(--font-display)" fontWeight="700">M</text></svg>,
  check:  (p) => <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12l5 5 9-11"/></svg>,
  shield: (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" {...p}><path d="M12 2l9 4v6c0 5-4 9-9 10-5-1-9-5-9-10V6l9-4z"/></svg>,
  diamond:(p) => <svg viewBox="0 0 24 24" width="18" height="18" {...p}><path d="M12 2l10 8-10 12L2 10z" fill="#4d87e8" stroke="#143574" strokeWidth="1"/><path d="M12 2l4 8-4 12-4-12z" fill="#8fb3f0" stroke="#143574" strokeWidth="0.8"/></svg>,
  cube:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" {...p}><path d="M12 2L2 7v10l10 5 10-5V7L12 2z" fill="#6b4c10" stroke="#2b1e08" strokeWidth="1"/><path d="M2 7l10 5 10-5" fill="none" stroke="#2b1e08" strokeWidth="1"/><path d="M12 12v10" stroke="#2b1e08" strokeWidth="1"/></svg>,
  discord:(p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" {...p}><path d="M19.3 5.3A17 17 0 0015.3 4l-.2.4a14 14 0 00-6.2 0L8.7 4a17 17 0 00-4 1.3 18.5 18.5 0 00-3.2 12.3A17 17 0 006.7 20l.9-1.5a11 11 0 01-1.8-.9 7 7 0 001-.6 11 11 0 0010.4 0 7 7 0 001 .6c-.6.3-1.2.6-1.8.9l.9 1.5a17 17 0 005.2-2.4 18.4 18.4 0 00-3.2-12.3zM9.3 15.3c-1 0-1.9-1-1.9-2.1 0-1.2.9-2.2 1.9-2.2 1.1 0 2 1 1.9 2.2 0 1.2-.8 2.1-1.9 2.1zm5.4 0c-1 0-1.9-1-1.9-2.1 0-1.2.9-2.2 1.9-2.2 1.1 0 2 1 1.9 2.2 0 1.2-.8 2.1-1.9 2.1z"/></svg>,
  mail:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" {...p}><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M2 7l10 7 10-7"/></svg>,

  // ── NG essentials (outils, armes, défense, ressources, tech) ──
  shovel:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 21l7-7"/><path d="M14 6l4 4-7 7-4-4 7-7z"/><path d="M14 2l6 6-2 2-6-6z"/></svg>,
  hammer:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M13 3l7 4-5 5-7-4z"/><path d="M11 8l-8 12 3 1 9-10"/></svg>,
  armor:   (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 2l6 2v8c0 5-3 9-6 10-3-1-6-5-6-10V4z"/><path d="M6 9h12"/><path d="M12 2v20"/></svg>,
  potion:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M9 3h6"/><path d="M10 3v5c-2 1-4 4-4 7 0 3 3 6 6 6s6-3 6-6c0-3-2-6-4-7V3"/><circle cx="12" cy="15" r="2" fill="currentColor" opacity="0.25" stroke="none"/></svg>,
  scroll:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 3h11a3 3 0 013 3v12a3 3 0 01-3 3H8a3 3 0 01-3-3V3z"/><path d="M5 3a3 3 0 00-3 3v1h3"/><path d="M19 21a3 3 0 003-3v-1h-3"/><path d="M8 8h7M8 12h7M8 16h5"/></svg>,
  food:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 13c0-5 4-8 8-8s8 3 8 8c0 2-1 4-3 5H7c-2-1-3-3-3-5z"/><path d="M7 12c1-1 2-1 3 0M14 12c1-1 2-1 3 0"/><path d="M5 18h14"/></svg>,
  wood:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="8" width="18" height="8" rx="2"/><circle cx="7" cy="12" r="2"/><path d="M7 10v4M5 12h4" opacity="0.6"/></svg>,
  rocket:  (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 2c3 2 5 6 5 10v6l-5 4-5-4v-6c0-4 2-8 5-10z"/><circle cx="12" cy="10" r="1.8"/><path d="M7 15l-3 5 4-1M17 15l3 5-4-1"/></svg>,
  missile: (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 12h12l5-4v8l-5-4"/><path d="M5 12L3 9M5 12L3 15"/><path d="M8 12v-4M8 12v4"/></svg>,

  // ── Theme toggle ──────────────────────────────────────────
  sun:     (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" {...p}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>,
  moon:    (p) => <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>,
};

// ── Liste d'icônes "items NG" — utilisée par les pickers dans Admin/Economy ──
// Regroupée par catégorie pour faciliter le choix. Pas une liste fourre-tout.
window.ITEM_ICONS = [
  // Ressources
  'cube', 'diamond', 'wood', 'wheat', 'food',
  // Outils
  'pick', 'axe', 'shovel', 'hammer',
  // Armes
  'sword', 'bow',
  // Défense
  'shield', 'armor',
  // Tech NG (fusée, missile, machine)
  'gear', 'rocket', 'missile',
  // RP / événementiel
  'potion', 'scroll', 'book', 'flame',
  // Méta / monnaie / récompense
  'coin', 'trophy', 'star',
];

// ================= MOTIFS =================
function GankylMark({ size = 28, color = 'currentColor' }) {
  // Stylized Mongol "Soyombo"-inspired original mark (sun+moon+flame trio abstracted as nested chevrons)
  return (
    <svg viewBox="0 0 64 64" width={size} height={size} aria-hidden>
      <g fill="none" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
        <path d="M32 6 L48 18 L32 30 L16 18 Z"/>
        <path d="M32 14 L40 20 L32 26 L24 20 Z"/>
        <path d="M14 34 h36"/>
        <path d="M14 40 h36"/>
        <circle cx="32" cy="50" r="6"/>
        <path d="M26 56 l6 -2 6 2"/>
      </g>
    </svg>
  );
}

function MongolBorder({ height = 14, color, style }) {
  const c = color || 'var(--mg-gold-600)';
  return (
    <svg viewBox="0 0 120 14" preserveAspectRatio="none" width="100%" height={height} style={{display:'block', opacity:'var(--motif-opacity)', ...style}}>
      <defs>
        <pattern id="knot" x="0" y="0" width="24" height="14" patternUnits="userSpaceOnUse">
          <path d="M2 7 q4 -5 8 0 q4 5 8 0 q4 -5 8 0" fill="none" stroke={c} strokeWidth="1.2"/>
          <circle cx="6" cy="7" r="1" fill={c}/>
          <circle cx="18" cy="7" r="1" fill={c}/>
        </pattern>
      </defs>
      <rect width="120" height="14" fill="url(#knot)"/>
    </svg>
  );
}

function CornerOrnament({ size = 40, color, corner = 'tl' }) {
  const c = color || 'var(--mg-gold-600)';
  const transforms = { tl: '', tr: 'scaleX(-1)', bl: 'scaleY(-1)', br: 'scale(-1,-1)' };
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} style={{transform: transforms[corner], opacity: 'var(--motif-opacity)'}} aria-hidden>
      <g fill="none" stroke={c} strokeWidth="1.4" strokeLinecap="round">
        <path d="M4 4h12"/>
        <path d="M4 4v12"/>
        <path d="M4 18 q0 -8 8 -8 q4 0 4 4 q0 2 -2 2"/>
        <circle cx="7" cy="7" r="1.2" fill={c}/>
      </g>
    </svg>
  );
}

// ================= MINECRAFT AVATAR =================
// Style simplifié pixel-art (forme standard à la Steve) peint avec les VRAIES
// couleurs du skin du joueur, extraites par pixel-sampling du texture NG.
//
// Processus (aucune IA, aucun traitement d'image complexe) :
//   1. Load `/api/skin/{pseudo}` (proxy serveur qui sert skins.nationsglory.fr)
//   2. Canvas.getImageData() pour sampler 4 pixels connus du format .mcskin :
//        - cheveux  : (10, 1)    → top du head
//        - peau     : (12, 12)   → face/joue
//        - shirt    : (24, 24)   → torse front
//        - pantalon : (6, 24)    → jambe front
//   3. Redessine la forme simplifiée SVG avec ces couleurs
//
// Fallback : si le skin n'est pas chargeable → palette générée depuis le hash
// du pseudo (style original du prototype Claude Design).
// Petit helper : assombrit / éclaircit une couleur rgb() ou #hex.
function shadeRgb(color, pct) {
  // pct : -1 (full black) à +1 (full white)
  let r, g, b;
  const m1 = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i.exec(color || '');
  if (m1) { r = +m1[1]; g = +m1[2]; b = +m1[3]; }
  else {
    const hex = String(color || '').replace('#', '');
    if (hex.length === 6) {
      r = parseInt(hex.slice(0,2), 16);
      g = parseInt(hex.slice(2,4), 16);
      b = parseInt(hex.slice(4,6), 16);
    } else return color;
  }
  const fn = pct < 0 ? (c) => Math.round(c * (1 + pct)) : (c) => Math.round(c + (255 - c) * pct);
  const clamp = x => Math.max(0, Math.min(255, fn(x)));
  return `rgb(${clamp(r)},${clamp(g)},${clamp(b)})`;
}

function MCAvatar({ name = 'Batukhan', size = 80, seed, style3d = true, armor = null }) {
  const [extracted, setExtracted] = useState(null);

  useEffect(() => {
    if (!name) return;
    let cancelled = false;
    const img = new Image();
    img.crossOrigin = 'anonymous';

    img.onload = () => {
      if (cancelled) return;
      try {
        const canvas = document.createElement('canvas');
        canvas.width  = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext('2d', { willReadFrequently: true });
        ctx.drawImage(img, 0, 0);

        const at = (x, y, fallback) => {
          try {
            const d = ctx.getImageData(x, y, 1, 1).data;
            if (d[3] < 128) return fallback;             // pixel transparent
            return `rgb(${d[0]},${d[1]},${d[2]})`;
          } catch { return fallback; }
        };

        setExtracted({
          hair:  at(10, 1,  '#3a2b1f'),
          skin:  at(12, 12, '#e0b79b'),
          shirt: at(24, 24, '#4682B4'),
          pants: at(6,  24, '#3a3f52'),
        });
      } catch (e) {
        // CORS tainted canvas → on laisse le fallback procédural s'appliquer
        console.warn('[MCAvatar] skin extraction failed:', e.message);
      }
    };
    img.onerror = () => { /* skin introuvable → fallback */ };
    img.src = `/api/skin/${encodeURIComponent(name)}`;

    return () => { cancelled = true; };
  }, [name]);

  // Couleurs : extraites du vrai skin si dispo, sinon dérivées du hash.
  let hair, skin, shirt, pants, accent;
  if (extracted) {
    hair   = extracted.hair;
    skin   = extracted.skin;
    shirt  = extracted.shirt;
    pants  = extracted.pants;
    accent = extracted.shirt;
  } else {
    const hash = (seed || name || 'x').split('').reduce((a, c) => a + c.charCodeAt(0), 0);
    const hues = [200, 28, 170, 260, 10, 120, 340, 55];
    const h = hues[hash % hues.length];
    skin   = `oklch(0.74 0.08 ${(h + 30) % 360})`;
    hair   = `oklch(0.28 0.06 ${(h + 220) % 360})`;
    shirt  = `oklch(0.55 0.12 ${h})`;
    pants  = `oklch(0.35 0.08 ${(h + 40) % 360})`;
    accent = `oklch(0.75 0.12 ${(h + 50) % 360})`;
  }

  const pixel = (px, py, fill, w = 1, hh = 1) =>
    <rect x={px} y={py} width={w} height={hh} fill={fill} shapeRendering="crispEdges" />;

  // Palette de l'armure équipée (si présente)
  const armorMid   = armor?.theme || null;
  const armorDark  = armorMid ? shadeRgb(armorMid, -0.25) : null;
  const armorLight = armorMid ? shadeRgb(armorMid, +0.20) : null;

  return (
    <svg viewBox="0 0 16 24" width={size} height={size * 1.5} style={{imageRendering:'pixelated', filter: style3d ? 'drop-shadow(2px 3px 0 rgba(0,0,0,.15))' : 'none'}} aria-hidden>
      {/* head */}
      {pixel(4, 1, hair, 8, 2)}
      {pixel(4, 3, skin, 8, 5)}
      {pixel(5, 4, '#222', 1, 1)}
      {pixel(10, 4, '#222', 1, 1)}
      {pixel(7, 6, '#844', 2, 1)}
      {pixel(4, 2, hair, 1, 3)}
      {pixel(11, 2, hair, 1, 3)}

      {/* ── CASQUE (helmet) par-dessus les cheveux ── */}
      {armor && (<>
        {pixel(3, 0, armorMid, 10, 1)}
        {pixel(3, 1, armorDark, 1, 2)}
        {pixel(12, 1, armorDark, 1, 2)}
        {pixel(4, 1, armorMid, 8, 2)}
        {pixel(3, 3, armorDark, 10, 1)}
      </>)}

      {/* body */}
      {pixel(4, 9, shirt, 8, 7)}
      {pixel(3, 10, accent, 1, 5)}
      {pixel(12, 10, accent, 1, 5)}

      {/* ── PLASTRON (chestplate) par-dessus la shirt ── */}
      {armor && (<>
        {pixel(4, 9, armorMid, 8, 5)}
        {pixel(3, 10, armorDark, 1, 5)}
        {pixel(12, 10, armorDark, 1, 5)}
        {pixel(7, 10, armorLight, 2, 3)}
        {pixel(4, 9, armorLight, 8, 1)}
      </>)}

      {/* gold belt (Mongolie) */}
      {pixel(4, 14, '#d39b36', 8, 1)}

      {/* legs */}
      {pixel(4, 16, pants, 8, 7)}

      {/* ── JAMBIÈRES (leggings) par-dessus les pants ── */}
      {armor && (<>
        {pixel(4, 15, armorMid, 8, 5)}
        {pixel(4, 15, armorDark, 1, 5)}
        {pixel(11, 15, armorDark, 1, 5)}
        {pixel(7, 16, armorDark, 2, 4)}
      </>)}

      {/* ── BOTTES (boots) ── */}
      {armor
        ? <>
            {pixel(4, 20, armorDark, 3, 2)}
            {pixel(9, 20, armorDark, 3, 2)}
            {pixel(4, 22, '#111', 3, 1)}
            {pixel(9, 22, '#111', 3, 1)}
          </>
        : <>
            {pixel(4, 22, '#222', 3, 1)}
            {pixel(9, 22, '#222', 3, 1)}
          </>
      }
    </svg>
  );
}

// ================= THEME TOGGLE (light/dark) =================
// Helpers exposés globalement pour que tous les composants puissent toggle
// et se synchroniser via window event 'mg:theme'.
function getTheme() {
  try {
    const t = JSON.parse(localStorage.getItem('mg:tweaks') || '{}');
    return t.theme === 'dark' ? 'dark' : 'light';
  } catch { return 'light'; }
}

function applyTheme(theme) {
  document.documentElement.setAttribute('data-theme', theme);
  let t = {};
  try { t = JSON.parse(localStorage.getItem('mg:tweaks') || '{}') || {}; } catch {}
  t.theme = theme;
  localStorage.setItem('mg:tweaks', JSON.stringify(t));
  window.dispatchEvent(new CustomEvent('mg:theme', { detail: theme }));
}

function useTheme() {
  const [theme, setTheme] = useState(getTheme);
  useEffect(() => {
    const handler = (e) => setTheme(e.detail);
    window.addEventListener('mg:theme', handler);
    return () => window.removeEventListener('mg:theme', handler);
  }, []);
  const toggle = () => applyTheme(theme === 'dark' ? 'light' : 'dark');
  return [theme, toggle];
}

// Bouton toggle réutilisable partout
function ThemeToggle({ compact }) {
  const [theme, toggle] = useTheme();
  const isDark = theme === 'dark';
  return (
    <button
      className={compact ? 'mg-icon-btn' : 'btn btn-ghost btn-sm'}
      onClick={toggle}
      title={isDark ? 'Passer en mode clair' : 'Passer en mode sombre'}
      aria-label="Basculer le thème"
    >
      {isDark ? <Icon.sun/> : <Icon.moon/>}
      {!compact && <span>{isDark ? 'Clair' : 'Sombre'}</span>}
    </button>
  );
}

// Variante "mg-side-link" (utilisée dans l'AppShell sidebar)
function ThemeSideButton() {
  const [theme, toggle] = useTheme();
  const isDark = theme === 'dark';
  return (
    <button className="mg-side-link" onClick={toggle}>
      {isDark ? <Icon.sun/> : <Icon.moon/>}
      <span>Thème : {isDark ? 'Sombre' : 'Clair'}</span>
    </button>
  );
}

// ================= THEME / TWEAKS state =================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "fontPairing": "syne-inter",
  "accentHue": 38,
  "motifDensity": 0.9,
  "radiusScale": 1.0,
  "goldIntensity": "balanced"
}/*EDITMODE-END*/;

function useTweaks() {
  const [tweaks, setTweaks] = useState(() => {
    try {
      const saved = JSON.parse(localStorage.getItem('mg:tweaks'));
      return { ...TWEAK_DEFAULTS, ...(saved || {}) };
    } catch { return TWEAK_DEFAULTS; }
  });
  useEffect(() => {
    localStorage.setItem('mg:tweaks', JSON.stringify(tweaks));
    const root = document.documentElement;
    root.setAttribute('data-theme', tweaks.theme);
    root.style.setProperty('--motif-opacity', tweaks.motifDensity);
    root.style.setProperty('--radius-scale', tweaks.radiusScale);

    const pairings = {
      'syne-inter':        ["'Syne'", "'Inter'"],
      'fraunces-dmsans':   ["'Fraunces'", "'DM Sans'"],
      'unifraktur-inter':  ["'Cormorant Garamond'", "'Inter'"],
    };
    const [disp, sans] = pairings[tweaks.fontPairing] || pairings['syne-inter'];
    root.style.setProperty('--font-display', `${disp}, Georgia, serif`);
    root.style.setProperty('--font-sans', `${sans}, ui-sans-serif, system-ui, sans-serif`);

    // gold intensity tuning
    if (tweaks.goldIntensity === 'rare') {
      root.style.setProperty('--accent', 'var(--mg-gold-700)');
    } else if (tweaks.goldIntensity === 'bold') {
      root.style.setProperty('--accent', 'var(--mg-gold-500)');
    } else {
      root.style.setProperty('--accent', 'var(--mg-gold-600)');
    }
  }, [tweaks]);
  return [tweaks, setTweaks];
}

// ================= ROUTER (hash-based) =================
function useRoute() {
  const [route, setRoute] = useState(() => (location.hash || '#/').slice(2) || '');
  useEffect(() => {
    const onChange = () => setRoute((location.hash || '#/').slice(2) || '');
    window.addEventListener('hashchange', onChange);
    return () => window.removeEventListener('hashchange', onChange);
  }, []);
  return [route, (r) => { location.hash = '#/' + r; }];
}

function Link({ to, children, className, style, onClick }) {
  return <a href={'#/' + to} className={className} style={style} onClick={onClick}>{children}</a>;
}

// ================= NAV =================
function TopNav({ current, user, onSignOut, onSignIn, onSwitchAccount }) {
  const items = [
    { to: '', label: 'Accueil' },
    { to: 'about', label: 'À propos' },
    { to: 'gallery', label: 'Galerie' },
    { to: 'rules', label: 'Règles' },
    { to: 'join', label: 'Rejoindre' },
  ];
  const loggedInItems = [
    { to: 'dashboard', label: 'Tableau de bord' },
    { to: 'quests', label: 'Quêtes' },
    { to: 'projects', label: 'Shop pays' },
    { to: 'leaderboard', label: 'Classement' },
    { to: 'profile/' + (user?.slug || 'me'), label: 'Profil' },
  ];
  const adminItems = [
    { to: 'admin/quests', label: 'Admin · Quêtes' },
  ];
  // Seul un membre de Mongolie voit la nav "app".
  // Un user loggé mais dans un autre pays (ou aucun) reste sur la nav publique.
  const isMongolieMember = user && user.nation === 'Mongolie';
  const navItems = isMongolieMember
    ? [...loggedInItems, ...(user.role === 'admin' ? adminItems : [])]
    : items;
  const isActive = (to) => current === to || (to && current.startsWith(to + '/')) || (to === '' && current === '');

  return (
    <header className="mg-topnav">
      <div className="container mg-topnav-inner">
        <Link to="" className="mg-brand">
          <GankylMark size={28} color="var(--accent)" />
          <div>
            <div className="mg-brand-name">MONGOLIE</div>
            <div className="mg-brand-sub">ᠮᠣᠩᠭᠣᠯ · NG Blue</div>
          </div>
        </Link>
        <nav className="mg-nav">
          {navItems.map(i => (
            <Link key={i.to} to={i.to} className={'mg-nav-link' + (isActive(i.to) ? ' active' : '')}>{i.label}</Link>
          ))}
        </nav>
        <div className="row gap-2">
          <ThemeToggle compact/>
          {user ? (
            isMongolieMember ? (
              <>
                <button className="mg-icon-btn" title="Notifications"><Icon.bell/><span className="mg-dot"/></button>
                <Link to={'profile/' + user.slug} className="mg-user-chip">
                  <div className="mg-user-avatar"><MCAvatar name={user.name} size={28}/></div>
                  <div className="stack">
                    <span className="mg-user-name">{user.name}</span>
                    <span className="mg-user-role">{user.rankLabel || (user.role === 'admin' ? '◆ Officier' : 'Membre')}</span>
                  </div>
                </Link>
              </>
            ) : (
              // Loggé mais pas dans Mongolie → identité + déco + switch de compte
              <>
                <div className="mg-user-chip" style={{opacity:0.85, cursor:'default'}}>
                  <div className="mg-user-avatar"><MCAvatar name={user.name} size={28}/></div>
                  <div className="stack">
                    <span className="mg-user-name">{user.name}</span>
                    <span className="mg-user-role">
                      {user.nation ? 'Pays : ' + user.nation : 'Sans pays'}
                    </span>
                  </div>
                </div>
                <button
                  className="btn btn-ghost btn-sm"
                  onClick={onSwitchAccount}
                  title="Se déconnecter côté NationsGlory pour pouvoir te connecter avec un autre compte"
                >Changer de compte NG</button>
                <button className="btn btn-ghost btn-sm" onClick={onSignOut}>Déconnexion</button>
              </>
            )
          ) : (
            <>
              <button className="btn btn-ghost btn-sm" onClick={onSignIn}>Se connecter</button>
              <Link to="join" className="btn btn-gold btn-sm">Rejoindre</Link>
            </>
          )}
        </div>
      </div>
      <MongolBorder height={8} />
    </header>
  );
}

// ================= MEMBER SIDEBAR (dashboard / app shell) =================
function AppShell({ user, route, children, onSignOut, onSwitchAccount }) {
  const memberNav = [
    { to: 'dashboard',  label: 'Tableau de bord', icon: Icon.home },
    { to: 'arene',      label: 'Arène',           icon: Icon.flame },
    { to: 'quests',     label: 'Quêtes',          icon: Icon.sword },
    { to: 'projects',   label: 'Shop pays',       icon: Icon.cube },
    { to: 'wallet',     label: 'Mon Togrog',      icon: Icon.coin },
    { to: 'bazar',      label: 'Bazar',           icon: Icon.diamond },
    { to: 'leaderboard',label: 'Classement',      icon: Icon.trophy },
    { to: 'community',  label: 'Communauté',      icon: Icon.users },
    { to: 'profile/' + user.slug, label: 'Mon profil', icon: Icon.shield },
  ];
  const adminNav = [
    { to: 'admin/quests',   label: 'Gestion quêtes',   icon: Icon.edit },
    { to: 'admin/projects', label: 'Gestion projets',  icon: Icon.gear },
    { to: 'admin/rewards',  label: 'Récompenses',      icon: Icon.coin },
    { to: 'admin/members',  label: 'Membres',          icon: Icon.users },
    { to: 'admin/reports',  label: 'Rapports Staff',   icon: Icon.book },
  ];
  const isActive = (to) => route === to || route.startsWith(to + '/');

  return (
    <div className="mg-shell">
      <aside className="mg-sidebar">
        <Link to="" className="mg-brand mg-brand-side">
          <GankylMark size={26} color="var(--accent)" />
          <div>
            <div className="mg-brand-name">MONGOLIE</div>
            <div className="mg-brand-sub">Saison IV · ᠮᠣᠩᠭᠣᠯ</div>
          </div>
        </Link>
        <div className="mg-side-section">
          <div className="mg-side-label">Membre</div>
          {memberNav.map(i => (
            <Link key={i.to} to={i.to} className={'mg-side-link' + (isActive(i.to) ? ' active' : '')}>
              <i.icon/><span>{i.label}</span>
            </Link>
          ))}
        </div>
        {user.role === 'admin' && (
          <div className="mg-side-section">
            <div className="mg-side-label">Administration</div>
            {adminNav.map(i => (
              <Link key={i.to} to={i.to} className={'mg-side-link admin' + (isActive(i.to) ? ' active' : '')}>
                <i.icon/><span>{i.label}</span>
              </Link>
            ))}
          </div>
        )}
        <div className="mg-side-foot">
          <div className="mg-status-live">
            <span className="mg-pulse"/>
            <div className="stack">
              <span style={{fontWeight:600, fontSize:13}}>42 en ligne</span>
              <span style={{fontSize:11, color:'var(--ink-mute)'}}>NG Blue · Puissance 9 420</span>
            </div>
          </div>
          <ThemeSideButton/>
          <button className="mg-side-link" onClick={onSwitchAccount} title="Logout + ouvre NG pour pouvoir switcher de compte">
            <Icon.users/><span>Changer de compte NG</span>
          </button>
          <button className="mg-side-link" onClick={onSignOut}>
            <Icon.close/><span>Déconnexion</span>
          </button>
        </div>
      </aside>
      <main className="mg-main">
        <header className="mg-appbar">
          <div className="mg-crumbs">
            <Icon.home/>
            <Icon.chev/>
            <span className="mg-crumb">{route.replace(/\//g, ' › ') || 'dashboard'}</span>
          </div>
          <div className="row gap-3">
            <div className="mg-search">
              <Icon.search/><input placeholder="Rechercher quête, membre, projet…" />
              <kbd>⌘K</kbd>
            </div>
            <button className="mg-icon-btn" title="Événements"><Icon.calendar/></button>
            <button className="mg-icon-btn" title="Notifications"><Icon.bell/><span className="mg-dot"/></button>
            <div className="mg-user-chip">
              <div className="mg-user-avatar"><MCAvatar name={user.name} size={28}/></div>
              <div className="stack">
                <span className="mg-user-name">{user.name}</span>
                <span className="mg-user-role">{user.rankLabel || (user.role === 'admin' ? '◆ Officier' : 'Membre')}</span>
              </div>
            </div>
          </div>
        </header>
        <div className="mg-main-scroll">{children}</div>
      </main>
    </div>
  );
}

// ================= DATA =================
const DATA = {
  quests: [
    { id: 'q1', title: 'Le Grand Tumulus de Diamants', cat: 'Mine', diff: 'Épique', progress: 64, xp: 420, reward: '15 diamants · 300 MG', desc: 'Extraire et livrer 100 diamants pour la construction du Hôtel Diplomatique.', deadline: '3j', participants: 8, color:'blue' },
    { id: 'q2', title: 'Patrouille de la steppe Est', cat: 'PVP', diff: 'Normal', progress: 20, xp: 150, reward: '80 MG', desc: 'Défendre les frontières contre les incursions. 3 captures requises.', deadline: '1j', participants: 12, color:'red' },
    { id: 'q3', title: 'Cérémonie du bois sacré', cat: 'Build', diff: 'Facile', progress: 100, xp: 80, reward: '40 MG · Badge', desc: 'Construire un pavillon traditionnel dans la zone RP.', deadline: '—', participants: 4, color:'green' },
    { id: 'q4', title: 'Semis d\'automne', cat: 'Ferme', diff: 'Facile', progress: 55, xp: 90, reward: '120 MG', desc: 'Planter 5 champs de blé pour l\'entreprise agricole.', deadline: '5j', participants: 22, color:'gold' },
    { id: 'q5', title: 'Chasse aux loups des steppes', cat: 'Chasse', diff: 'Normal', progress: 10, xp: 200, reward: '2 cuirs · 120 MG', desc: 'Traquer les meutes menaçant les frontières.', deadline: '2j', participants: 6, color:'red' },
    { id: 'q6', title: 'Cartographie du Nord', cat: 'Explorer', diff: 'Épique', progress: 0, xp: 500, reward: 'Titre « Voyageur » · 400 MG', desc: 'Explorer et cartographier les 3 régions du Nord glacé.', deadline: '7j', participants: 2, color:'blue' },
  ],
  projects: [
    { id: 'p1', title: 'Hôtel Diplomatique · HD', lead: 'Batukhan', deadline: '12 Mai', desc: 'Construction du siège diplomatique. Pierre, verre, diamants, marbre.', needs: [
      { item: 'Diamant', have: 64, need: 100, icon: 'diamond' },
      { item: 'Pierre taillée', have: 1200, need: 2000, icon: 'cube' },
      { item: 'Verre', have: 450, need: 800, icon: 'diamond' },
      { item: 'Or', have: 30, need: 60, icon: 'coin' },
    ]},
    { id: 'p2', title: 'Remparts de la capitale', lead: 'Temüjin', deadline: '28 Avril', desc: 'Fortifications face aux voisins de l\'Est.', needs: [
      { item: 'Obsidienne', have: 200, need: 500, icon: 'cube' },
      { item: 'Pierre', have: 4200, need: 6000, icon: 'cube' },
    ]},
    { id: 'p3', title: 'Ferme coopérative Nord', lead: 'Sarantuya', deadline: 'Ouvert', desc: 'Entreprise agricole — revenus redistribués aux recrues.', needs: [
      { item: 'Graines', have: 800, need: 1000, icon: 'cube' },
      { item: 'Os (farine)', have: 210, need: 400, icon: 'cube' },
    ]},
  ],
  leaders: [
    { rank: 1, name: 'Batukhan',  contrib: 12840, quests: 48, role: 'Chef',      badge: '◆' },
    { rank: 2, name: 'Temüjin',   contrib: 11220, quests: 41, role: 'Officier',  badge: '◆' },
    { rank: 3, name: 'Sarantuya', contrib: 9870,  quests: 52, role: 'Officier',  badge: '◆' },
    { rank: 4, name: 'Oyuun',     contrib: 7640,  quests: 36, role: 'Membre',    badge: '' },
    { rank: 5, name: 'Ganzorig',  contrib: 6920,  quests: 31, role: 'Membre',    badge: '' },
    { rank: 6, name: 'Altantsetseg', contrib: 5610, quests: 28, role: 'Membre',    badge: '' },
    { rank: 7, name: 'Chinggis',  contrib: 4830,  quests: 22, role: 'Membre',    badge: '' },
    { rank: 8, name: 'Nomin',     contrib: 3740,  quests: 19, role: 'Recrue',    badge: '' },
    { rank: 9, name: 'Erdene',    contrib: 3220,  quests: 17, role: 'Recrue',    badge: '' },
    { rank:10, name: 'Tsatsral',  contrib: 2410,  quests: 12, role: 'Recrue',    badge: '' },
  ],
  skills: [
    { key: 'mine', label: 'Mineur',       level: 34, xp: 68, max: 100, icon: Icon.pick },
    { key: 'wood', label: 'Bûcheron',     level: 22, xp: 40, max: 100, icon: Icon.axe },
    { key: 'farm', label: 'Agriculteur',  level: 18, xp: 75, max: 100, icon: Icon.wheat },
    { key: 'hunt', label: 'Chasseur',     level: 12, xp: 22, max: 100, icon: Icon.bow },
    { key: 'build',label: 'Bâtisseur',    level: 28, xp: 55, max: 100, icon: Icon.home },
    { key: 'eng', label: 'Ingénieur',     level:  9, xp: 12, max: 100, icon: Icon.gear },
  ],
  events: [
    { date: '26 Avr', title: 'Tournoi PVP inter-pays',    kind: 'PVP',   icon: Icon.sword },
    { date: '29 Avr', title: 'Session ONU',                kind: 'Diplo', icon: Icon.shield },
    { date: '03 Mai', title: 'Formation Mineur – Niv. 10', kind: 'Form.', icon: Icon.pick },
    { date: '07 Mai', title: 'Build Competition · Yourtes',kind: 'Build', icon: Icon.home },
  ],
};

// ================= REUSABLE =================
function StatTile({ label, value, unit, accent }) {
  return (
    <div className={'mg-stat ' + (accent || '')}>
      <div className="mg-stat-val">{value}<span className="mg-stat-unit">{unit}</span></div>
      <div className="mg-stat-label">{label}</div>
    </div>
  );
}

function QuestCard({ q, compact, onOpen }) {
  const color = { blue:'var(--mg-blue-600)', red:'var(--mg-danger)', green:'var(--mg-success)', gold:'var(--mg-gold-600)' }[q.color] || 'var(--mg-blue-600)';
  const IconCat = { Mine: Icon.pick, PVP: Icon.sword, Build: Icon.home, Ferme: Icon.wheat, Chasse: Icon.bow, Explorer: Icon.map }[q.cat] || Icon.star;
  return (
    <article className="mg-quest" onClick={onOpen} style={{cursor: onOpen ? 'pointer' : 'default'}}>
      <div className="mg-quest-strip" style={{background: color}}/>
      <div className="mg-quest-body">
        <div className="row gap-2" style={{justifyContent:'space-between', alignItems:'flex-start'}}>
          <div className="row gap-2">
            <span className="mg-quest-cat" style={{color}}><IconCat/> {q.cat}</span>
            <span className="badge badge-dark">{q.diff}</span>
          </div>
          <span className="pixel" style={{fontSize:16, color:'var(--mg-gold-700)'}}>+{q.xp} XP</span>
        </div>
        <h3 className="mg-quest-title">{q.title}</h3>
        {!compact && <p className="soft" style={{fontSize:14}}>{q.desc}</p>}
        <div className="progress thick"><div className="bar" style={{width: q.progress + '%', background: color}}/></div>
        <div className="row gap-3" style={{justifyContent:'space-between', fontSize:12, color:'var(--ink-mute)'}}>
          <span><Icon.users style={{verticalAlign:'-4px', marginRight:4}}/> {q.participants} participants</span>
          <span>Échéance <b style={{color:'var(--ink)'}}>{q.deadline}</b></span>
          <span><Icon.coin style={{verticalAlign:'-4px', marginRight:4}}/> {q.reward}</span>
        </div>
      </div>
    </article>
  );
}

function ProjectCard({ p, onOpen }) {
  const total = p.needs.reduce((a,n)=>a+n.need,0);
  const have = p.needs.reduce((a,n)=>a+n.have,0);
  const pct = Math.round(have/total*100);
  return (
    <article className="mg-project" onClick={onOpen} style={{cursor: onOpen ? 'pointer' : 'default'}}>
      <header className="mg-project-head">
        <div>
          <div className="eyebrow">Projet pays · Échéance {p.deadline}</div>
          <h3 style={{marginTop:6}}>{p.title}</h3>
        </div>
        <span className="mg-pct-chip">{pct}%</span>
      </header>
      <p className="soft" style={{fontSize:14}}>{p.desc}</p>
      <div className="mg-needs">
        {p.needs.map((n, i) => {
          const npct = Math.round(n.have/n.need*100);
          const IconN = Icon[n.icon] || Icon.cube;
          return (
            <div key={i} className="mg-need">
              <div className="row gap-2" style={{justifyContent:'space-between'}}>
                <span className="row gap-2"><IconN/> <b>{n.item}</b></span>
                <span className="mono" style={{fontSize:13}}>{n.have}<span style={{color:'var(--ink-mute)'}}> / {n.need}</span></span>
              </div>
              <div className="progress gold"><div className="bar" style={{width: npct + '%'}}/></div>
            </div>
          );
        })}
      </div>
      <footer className="row gap-3" style={{justifyContent:'space-between', marginTop:12}}>
        <div className="row gap-2">
          <div className="mg-user-avatar sm"><MCAvatar name={p.lead} size={22}/></div>
          <span style={{fontSize:13}}>Menée par <b>{p.lead}</b></span>
        </div>
        <button className="btn btn-gold btn-sm">Contribuer <Icon.arrow/></button>
      </footer>
    </article>
  );
}

// ================= TWEAKS PANEL =================
function TweaksPanel({ tweaks, setTweaks, open, onClose }) {
  if (!open) return null;
  const set = (k, v) => setTweaks(t => ({ ...t, [k]: v }));
  return (
    <div className="mg-tweaks">
      <div className="row gap-2" style={{justifyContent:'space-between', marginBottom:12}}>
        <h3 style={{fontSize:18}}>Tweaks</h3>
        <button className="mg-icon-btn" onClick={onClose}><Icon.close/></button>
      </div>
      <div className="stack gap-4">
        <div>
          <label className="mg-tw-label">Thème</label>
          <div className="mg-tw-seg">
            {['light','dark'].map(v => (
              <button key={v} className={tweaks.theme === v ? 'active' : ''} onClick={() => set('theme', v)}>{v === 'light' ? 'Jour' : 'Nuit'}</button>
            ))}
          </div>
        </div>
        <div>
          <label className="mg-tw-label">Typographie</label>
          <div className="mg-tw-seg vert">
            <button className={tweaks.fontPairing==='syne-inter'?'active':''} onClick={()=>set('fontPairing','syne-inter')}><span className="display" style={{fontSize:18}}>Syne</span> <span style={{opacity:.6}}>+ Inter</span></button>
            <button className={tweaks.fontPairing==='fraunces-dmsans'?'active':''} onClick={()=>set('fontPairing','fraunces-dmsans')}><span className="display" style={{fontSize:18, fontFamily:"'Fraunces'"}}>Fraunces</span> <span style={{opacity:.6}}>+ DM Sans</span></button>
            <button className={tweaks.fontPairing==='unifraktur-inter'?'active':''} onClick={()=>set('fontPairing','unifraktur-inter')}><span className="display" style={{fontSize:20, fontFamily:"'Cormorant Garamond'", fontStyle:'italic'}}>Cormorant</span> <span style={{opacity:.6}}>+ Inter</span></button>
          </div>
        </div>
        <div>
          <label className="mg-tw-label">Intensité or</label>
          <div className="mg-tw-seg">
            {[['rare','Rare'],['balanced','Équilibré'],['bold','Généreux']].map(([v,l]) => (
              <button key={v} className={tweaks.goldIntensity === v ? 'active' : ''} onClick={() => set('goldIntensity', v)}>{l}</button>
            ))}
          </div>
        </div>
        <div>
          <label className="mg-tw-label">Densité motifs mongols · {Math.round(tweaks.motifDensity*100)}%</label>
          <input type="range" min="0" max="1" step="0.05" value={tweaks.motifDensity} onChange={e=>set('motifDensity', parseFloat(e.target.value))} className="mg-tw-range"/>
        </div>
        <div>
          <label className="mg-tw-label">Arrondis · {tweaks.radiusScale.toFixed(1)}×</label>
          <input type="range" min="0" max="1.6" step="0.1" value={tweaks.radiusScale} onChange={e=>set('radiusScale', parseFloat(e.target.value))} className="mg-tw-range"/>
        </div>
      </div>
    </div>
  );
}

// Export
Object.assign(window, { Icon, GankylMark, MongolBorder, CornerOrnament, MCAvatar, useTweaks, useRoute, Link, TopNav, AppShell, DATA, StatTile, QuestCard, ProjectCard, TweaksPanel, TWEAK_DEFAULTS, useTheme, applyTheme, getTheme, ThemeToggle, ThemeSideButton });
