
const { useState, useEffect, useRef } = React;

function useViewportMatch(breakpoint) {
  const [matches, setMatches] = useState(() =>
    typeof window !== 'undefined' ? window.innerWidth <= breakpoint : false,
  );

  useEffect(() => {
    if (typeof window === 'undefined') return undefined;

    const syncViewport = () => {
      setMatches(window.innerWidth <= breakpoint);
    };

    syncViewport();
    window.addEventListener('resize', syncViewport);
    return () => window.removeEventListener('resize', syncViewport);
  }, [breakpoint]);

  return matches;
}

// ─── API Helper ────────────────────────────────────────────────────────────────
const apiCall = async (url, options = {}) => {
  const userRole = typeof window !== 'undefined' ? localStorage.getItem('eg_role') : null;
  const apiRole = userRole ? userRole.toUpperCase() : null;
  const headers = {
    'Content-Type': 'application/json',
    ...(apiRole && { 'X-User-Role': apiRole }),
    ...(options.headers || {}),
  };
  
  return fetch(url, {
    ...options,
    headers,
  }).then(res => res.json());
};

// ─── Brand Tokens ─────────────────────────────────────────────────────────────
const BRAND = {
  green: { main: '#1B9970', dark: '#136B4D', darker: '#0C4A36', light: '#E8F5F0', muted: '#4A6B5E' },
  purple: { main: '#7C3AED', dark: '#5B21B6', light: '#F3E8FF' },
  amber: { main: '#D4860F', dark: '#A86709', light: '#FEF3DC' },
  blue:  { main: '#2D7DD2', dark: '#1E5FA0', light: '#E3EFF9' },
  red:   { main: '#D94F4F', dark: '#A83030', light: '#FDECEC' },
  bg: '#F5F7F5', card: '#FFFFFF', border: '#DCE5DF',
  text: { primary: '#0E1F18', secondary: '#2D4A3E', muted: '#4A6B5E', light: '#8AAB9E' },
};

const LEVEL = {
  1: { name: 'Operador Inicial',     color: '#7C3AED', dark: '#5B21B6', light: '#F3E8FF' },
  2: { name: 'Operador Certificado', color: '#D4860F', dark: '#7A4800', light: '#FEF3DC' },
  3: { name: 'Avanzado / Analista',  color: '#2D7DD2', dark: '#1E5FA0', light: '#E3EFF9' },
  4: { name: 'Supervisor',           color: '#D94F4F', dark: '#A83030', light: '#FDECEC' },
};

// ─── Course Data ──────────────────────────────────────────────────────────────
const COURSES = [
  { code:'EG101', title:'Introducción a eGuardian',          level:1, dur:'2h', mods:4,  icon:'shield',    desc:'Comprensión del servicio eGuardian, su impacto en la seguridad real y el rol crítico del operador.',    progress:100, grade:95 },
  { code:'EG102', title:'Protocolos de Operación',           level:1, dur:'4h', mods:8,  icon:'checklist', desc:'Procedimientos estándar de operación para central de monitoreo.',          progress:100, grade:88 },
  { code:'EG103', title:'Sistemas CCTV',                     level:1, dur:'5h', mods:10, icon:'camera',    desc:'Principios técnicos de videovigilancia, tipos de cámaras y configuración.',progress:75,  grade:null },
  { code:'EG104', title:'Operación iVMS-4200',               level:1, dur:'6h', mods:12, icon:'monitor',   desc:'Manejo del software de gestión de video Hikvision iVMS-4200.',             progress:40,  grade:null },
  { code:'EG105', title:'Ley 21.659',                        level:1, dur:'3h', mods:5,  icon:'scales',    desc:'Marco legal que regula los servicios de seguridad privada en Chile.',      progress:0,   grade:null },
  { code:'EG106', title:'Comunicación con Fuerzas de Orden', level:1, dur:'3h', mods:6,  icon:'radio',     desc:'Protocolos de coordinación con Carabineros y PDI.',                        progress:0,   grade:null },
  { code:'EG108', title:'Soporte TI Básico',                 level:1, dur:'4h', mods:8,  icon:'wrench',    desc:'Diagnóstico y resolución de problemas técnicos básicos en central.',       progress:0,   grade:null },
  { code:'EG107', title:'Gestión Emocional',                 level:2, dur:'3h', mods:6,  icon:'brain',     desc:'Manejo del estrés y bienestar en turnos de alta vigilancia.',              progress:0,   grade:null },
  { code:'EG201', title:'Análisis y Detección',              level:2, dur:'5h', mods:10, icon:'search',    desc:'Técnicas avanzadas de detección de comportamientos anómalos.',             progress:0,   grade:null },
  { code:'EG202', title:'Uso Avanzado de Cámaras',           level:2, dur:'6h', mods:12, icon:'camera2',   desc:'PTZ, térmicas, panorámicas y configuración avanzada de cámaras.',         progress:0,   grade:null },
  { code:'EG203', title:'Protocolos por Tipo de Cliente',    level:2, dur:'4h', mods:8,  icon:'building',  desc:'Procedimientos diferenciados por sector y tipo de instalación.',           progress:0,   grade:null },
  { code:'EG204', title:'Documentación y Bitácora',          level:2, dur:'3h', mods:6,  icon:'clipboard', desc:'Registro correcto de eventos, incidentes y novedades de turno.',          progress:0,   grade:null },
  { code:'EG403', title:'Atención al Cliente',               level:2, dur:'3h', mods:5,  icon:'headset',   desc:'Comunicación efectiva con clientes y manejo de situaciones críticas.',     progress:0,   grade:null },
  { code:'EG301', title:'Análisis de Patrones',              level:3, dur:'6h', mods:10, icon:'network',   desc:'Reconocimiento de patrones de comportamiento y predicción de incidentes.', progress:0,   grade:null },
  { code:'EG302', title:'Ciberseguridad',                    level:3, dur:'5h', mods:9,  icon:'lock',      desc:'Protección de redes, dispositivos IoT y cámaras IP en instalaciones.',    progress:0,   grade:null },
  { code:'EG303', title:'Iluminación Aplicada',              level:3, dur:'4h', mods:7,  icon:'bulb',      desc:'Principios de iluminación para videovigilancia efectiva.',                 progress:0,   grade:null },
  { code:'EG308', title:'Integración de Sistemas',           level:3, dur:'6h', mods:11, icon:'circuit',   desc:'Control de acceso, alarmas e integración con sistemas VMS.',              progress:0,   grade:null },
  { code:'EG309', title:'IA Aplicada a CCTV',                level:3, dur:'7h', mods:12, icon:'ai',        desc:'Analytics de video, reconocimiento facial y detección inteligente.',      progress:0,   grade:null },
  { code:'EG304', title:'Informes Periciales',               level:4, dur:'5h', mods:8,  icon:'report',    desc:'Elaboración de informes técnicos para uso judicial y pericial.',           progress:0,   grade:null },
  { code:'EG401', title:'Gestión de Equipo y KPIs',          level:4, dur:'6h', mods:10, icon:'team',      desc:'Liderazgo de equipos, métricas de desempeño y procesos de evaluación.',   progress:0,   grade:null },
  { code:'EG402', title:'Diseño de Proyectos',               level:4, dur:'7h', mods:12, icon:'blueprint', desc:'Planificación y diseño de sistemas de seguridad electrónica.',             progress:0,   grade:null },
  { code:'EG405', title:'Ética Profesional',                 level:4, dur:'3h', mods:5,  icon:'ethics',    desc:'Código de conducta, privacidad y responsabilidad en televigilancia.',      progress:0,   grade:null },
];

// ─── Logo ─────────────────────────────────────────────────────────────────────
function Logo({ collapsed = false, dark = true }) {
  const txt = dark ? '#ffffff' : '#0C4A36';
  const sub = dark ? 'rgba(255,255,255,0.55)' : '#4A6B5E';
  return (
    <div style={{ display:'flex', alignItems:'center', gap: collapsed ? 0 : 10, justifyContent: collapsed ? 'center' : 'flex-start' }}>
      <svg width="34" height="38" viewBox="0 0 34 38" fill="none" style={{ flexShrink:0 }}>
        <path d="M17 2L31 7.5V19C31 27 24.5 33.5 17 36C9.5 33.5 3 27 3 19V7.5Z"
              fill={dark ? 'rgba(255,255,255,0.1)' : '#E8F5F0'}
              stroke={dark ? 'rgba(255,255,255,0.75)' : '#136B4D'} strokeWidth="1.5" strokeLinejoin="round"/>
        <path d="M17 2L31 7.5V19C31 27 24.5 33.5 17 36C9.5 33.5 3 27 3 19V7.5Z"
              fill="none" stroke={dark ? 'rgba(255,255,255,0.2)' : 'transparent'} strokeWidth="5" strokeLinejoin="round"/>
        <polyline points="10,19 14.5,24 24,13" fill="none"
                  stroke={dark ? '#ffffff' : '#1B9970'} strokeWidth="2.5"
                  strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      {!collapsed && (
        <div>
          <div style={{ fontFamily:'Space Grotesk,sans-serif', fontWeight:800, fontSize:17, color:txt, lineHeight:1, letterSpacing:'-0.01em' }}>eGuardian</div>
          <div style={{ fontFamily:'Outfit,sans-serif', fontWeight:400, fontSize:10, color:sub, letterSpacing:'0.12em', textTransform:'uppercase', marginTop:3 }}>Academia</div>
        </div>
      )}
    </div>
  );
}

// ─── Nav Icons ────────────────────────────────────────────────────────────────
const NavIcon = ({ name }) => {
  const icons = {
    dashboard: <><rect x="1.5" y="1.5" width="6" height="6" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><rect x="10.5" y="1.5" width="6" height="6" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><rect x="1.5" y="10.5" width="6" height="6" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><rect x="10.5" y="10.5" width="6" height="6" rx="1.5" stroke="currentColor" strokeWidth="1.5"/></>,
    courses: <><path d="M1 4.5L9 1.5L17 4.5L9 7.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M3.5 7L3.5 13C3.5 13 6 15 9 15C12 15 14.5 13 14.5 13L14.5 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="17" y1="4.5" x2="17" y2="11" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    compliance: <><path d="M9 1.5L15 4V10.5C15 14 12.5 16.5 9 18C5.5 16.5 3 14 3 10.5V4Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><polyline points="6,10 8,12 12,8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></>,
    grades: <><rect x="1" y="10.5" width="3.5" height="6.5" rx="1" stroke="currentColor" strokeWidth="1.5"/><rect x="7.25" y="6" width="3.5" height="11" rx="1" stroke="currentColor" strokeWidth="1.5"/><rect x="13.5" y="1" width="3.5" height="16" rx="1" stroke="currentColor" strokeWidth="1.5"/></>,
    certificates: <><rect x="1.5" y="2.5" width="15" height="10" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><circle cx="9" cy="14.5" r="2.5" stroke="currentColor" strokeWidth="1.5"/><line x1="7" y1="17" x2="11" y2="17" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="4.5" y1="6.5" x2="8" y2="6.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="4.5" y1="9" x2="7" y2="9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    users: <><circle cx="6.5" cy="5.5" r="3.5" stroke="currentColor" strokeWidth="1.5"/><path d="M1 16C1 12.5 3.2 10.5 6.5 10.5C9.8 10.5 12 12.5 12 16" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><circle cx="14" cy="5.5" r="2.5" stroke="currentColor" strokeWidth="1.5"/><path d="M13.5 10.5C15 10.5 17 11.5 17 14" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    reports: <><path d="M4.5 1.5H11.5L16.5 6.5V16.5H1.5V1.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M11.5 1.5V6.5H16.5" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><line x1="5" y1="10" x2="13" y2="10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="5" y1="13" x2="10" y2="13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    settings: <><circle cx="9" cy="9" r="3" stroke="currentColor" strokeWidth="1.5"/><path d="M9 1.5V3.5M9 14.5V16.5M1.5 9H3.5M14.5 9H16.5M3.6 3.6L5 5M13 13L14.4 14.4M14.4 3.6L13 5M5 13L3.6 14.4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    notifications: <><path d="M9 1.5C6 1.5 4.5 3.5 4.5 6.5V12L2.5 13.5H15.5L13.5 12V6.5C13.5 3.5 12 1.5 9 1.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M7 13.5C7 14.6 7.9 15.5 9 15.5C10.1 15.5 11 14.6 11 13.5" stroke="currentColor" strokeWidth="1.5"/></>,
  };
  return (
    <svg width="18" height="18" viewBox="0 0 18 18" fill="none" style={{ flexShrink:0 }}>
      {icons[name] || icons.dashboard}
    </svg>
  );
};

// ─── Sidebar ──────────────────────────────────────────────────────────────────
const NAV = {
  operator:   [['dashboard','Dashboard'],['courses','Mis Cursos'],['grades','Calificaciones'],['certificates','Certificados'],['notifications','Notificaciones']],
  supervisor: [['dashboard','Dashboard'],['compliance','Cumplimiento'],['grades','Calificaciones'],['reports','Reportes'],['notifications','Notificaciones']],
  admin:      [['dashboard','Dashboard'],['users','Usuarios'],['courses','Catálogo'],['grades','Calificaciones'],['reports','Reportes'],['settings','Configuración']],
};

const ROLE_LABEL = { operator:'Operador', supervisor:'Supervisor', admin:'Administrador' };

function Sidebar({
  role,
  currentView,
  onNavigate,
  onLogout,
  style = 'dark',
  currentUser = null,
  isMobile = false,
  mobileOpen = false,
  onCloseMobileNav = () => {},
}) {
  const isDark = style === 'dark';
  const bg = isDark ? BRAND.green.darker : '#FFFFFF';
  const activeBg = isDark ? '#136B4D' : '#E8F5F0';
  const activeColor = isDark ? '#ffffff' : BRAND.green.darker;
  const inactiveColor = isDark ? 'rgba(255,255,255,0.55)' : BRAND.text.muted;
  const hoverBg = isDark ? 'rgba(255,255,255,0.06)' : '#F5F7F5';
  const [hovered, setHovered] = useState(null);
  const userName = currentUser?.name || 'Usuario';
  const userInitials = currentUser?.avatarInitials || userName.split(' ').map((part) => part[0]).join('').slice(0, 2).toUpperCase();

  const panel = (
    <div style={{ width:isMobile ? 'min(82vw, 280px)' : 220, background:bg, display:'flex', flexDirection:'column', height:'100%',
      borderRight: isDark ? 'none' : `1.5px solid ${BRAND.border}`, boxShadow:isMobile ? '0 24px 60px rgba(14,31,24,0.28)' : 'none' }}>
      <div style={{ padding:'24px 20px 20px', borderBottom: isDark ? 'rgba(255,255,255,0.08) 1px solid' : `${BRAND.border} 1px solid`, display:'flex', alignItems:'center', justifyContent:'space-between', gap:12 }}>
        <Logo dark={isDark} />
        {isMobile && (
          <button type="button" onClick={onCloseMobileNav}
            style={{ border:'none', background:'transparent', color: isDark ? '#fff' : BRAND.text.muted, cursor:'pointer', padding:4 }}
            aria-label="Cerrar men?">
            <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
              <path d="M4 4L14 14M14 4L4 14" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
            </svg>
          </button>
        )}
      </div>

      <div style={{ padding:'14px 20px 8px' }}>
        <div style={{ fontSize:10, fontWeight:500, letterSpacing:'0.1em', textTransform:'uppercase',
          color: isDark ? 'rgba(255,255,255,0.35)' : BRAND.text.light, fontFamily:'DM Mono,monospace' }}>
          {ROLE_LABEL[role]}
        </div>
      </div>

      <nav style={{ flex:1, padding:'4px 12px', overflowY:'auto' }}>
        {(NAV[role] || []).map(([id, label]) => {
          const active = currentView === id;
          return (
            <button key={id}
              onClick={() => {
                onNavigate(id);
                if (isMobile) onCloseMobileNav();
              }}
              onMouseEnter={() => setHovered(id)}
              onMouseLeave={() => setHovered(null)}
              style={{
                display:'flex', alignItems:'center', gap:10, width:'100%', padding:'9px 10px',
                borderRadius:8, border:'none', cursor:'pointer', textAlign:'left', marginBottom:2,
                background: active ? activeBg : (hovered === id ? hoverBg : 'transparent'),
                color: active ? activeColor : inactiveColor,
                fontFamily:'Outfit,sans-serif', fontWeight: active ? 500 : 400, fontSize:14,
                transition:'all 0.15s', position:'relative',
                borderLeft: active ? `3px solid ${BRAND.green.main}` : '3px solid transparent',
              }}>
              <NavIcon name={id === 'compliance' ? 'compliance' : id === 'certificates' ? 'certificates' : id === 'grades' ? 'grades' : id === 'notifications' ? 'notifications' : id === 'users' ? 'users' : id === 'reports' ? 'reports' : id === 'settings' ? 'settings' : id === 'courses' ? 'courses' : 'dashboard'} />
              {label}
              {id === 'notifications' && (
                <span style={{ marginLeft:'auto', background:BRAND.amber.main, color:'white', fontSize:10, fontWeight:600,
                  padding:'1px 6px', borderRadius:10 }}>3</span>
              )}
            </button>
          );
        })}
      </nav>

      <div style={{ padding:'16px 20px', borderTop: isDark ? '1px solid rgba(255,255,255,0.08)' : `1px solid ${BRAND.border}` }}>
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:12 }}>
          <div style={{ width:32, height:32, borderRadius:'50%', background: BRAND.green.main,
            display:'flex', alignItems:'center', justifyContent:'center',
            color:'white', fontSize:13, fontWeight:600, flexShrink:0 }}>
            {userInitials}
          </div>
          <div>
            <div style={{ fontSize:13, fontWeight:500, color: isDark ? '#fff' : BRAND.text.primary, lineHeight:1.2 }}>
              {userName}
            </div>
            <div style={{ fontSize:11, color: isDark ? 'rgba(255,255,255,0.4)' : BRAND.text.light, marginTop:1 }}>
              {ROLE_LABEL[role]}
            </div>
          </div>
        </div>
        <button onClick={onLogout}
          style={{ width:'100%', padding:'7px 0', borderRadius:6, border:`1px solid ${isDark ? 'rgba(255,255,255,0.15)' : BRAND.border}`,
            background:'transparent', color: isDark ? 'rgba(255,255,255,0.5)' : BRAND.text.muted,
            fontSize:12, cursor:'pointer', fontFamily:'Outfit,sans-serif' }}>
          Cerrar sesi?n
        </button>
      </div>
    </div>
  );

  if (!isMobile) {
    return <div style={{ height:'100vh', flexShrink:0 }}>{panel}</div>;
  }

  return (
    <div style={{ position:'fixed', inset:0, zIndex:1600, pointerEvents: mobileOpen ? 'auto' : 'none' }} aria-hidden={!mobileOpen}>
      <div onClick={onCloseMobileNav}
        style={{ position:'absolute', inset:0, background:'rgba(14,31,24,0.38)', opacity: mobileOpen ? 1 : 0, transition:'opacity 0.2s ease' }}/>
      <div style={{ position:'absolute', inset:'0 auto 0 0', height:'100%', transform: mobileOpen ? 'translateX(0)' : 'translateX(-100%)', transition:'transform 0.24s ease' }}>
        {panel}
      </div>
    </div>
  );
}

// ????????? TopBar ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
const VIEW_TITLE = { dashboard:'Dashboard', courses:'Cat?logo de Cursos', grades:'Calificaciones',
  certificates:'Mis Certificados', notifications:'Notificaciones', compliance:'Cumplimiento del Equipo',
  users:'Gesti?n de Usuarios', reports:'Reportes', settings:'Configuraci?n', 'course-detail':'Detalle del Curso',
  badges:'Logros e Insignias' };

function TopBar({ role, view, onNavigate, isMobile = false, onToggleNav = () => {} }) {
  return (
    <div style={{ minHeight:56, background:'#fff', borderBottom:`1.5px solid ${BRAND.border}`,
      display:'flex', alignItems:'center', padding:isMobile ? '10px 16px' : '0 28px', gap:12, flexShrink:0, flexWrap:'wrap' }}>
      {isMobile && (
        <button type="button" onClick={onToggleNav}
          style={{ border:'1.5px solid #DCE5DF', background:'#fff', borderRadius:10, width:40, height:40, display:'flex', alignItems:'center', justifyContent:'center', color:BRAND.text.primary, cursor:'pointer', flexShrink:0 }}
          aria-label="Abrir men?">
          <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
            <path d="M3 5H15M3 9H15M3 13H15" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/>
          </svg>
        </button>
      )}
      <div style={{ flex:1, minWidth:isMobile ? 160 : 'auto' }}>
        <h1 style={{ fontFamily:'Space Grotesk,sans-serif', fontWeight:700, fontSize:16, color:BRAND.text.primary, margin:0 }}>
          {VIEW_TITLE[view] || view}
        </h1>
      </div>
      <div style={{ display:'flex', alignItems:'center', gap:8, background:BRAND.bg,
        border:`1.5px solid ${BRAND.border}`, borderRadius:8, padding:'6px 12px', width:isMobile ? '100%' : 220, order:isMobile ? 3 : 0, flex:isMobile ? '1 1 100%' : '0 0 auto' }}>
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <circle cx="6" cy="6" r="4.5" stroke={BRAND.text.light} strokeWidth="1.5"/>
          <line x1="9.5" y1="9.5" x2="13" y2="13" stroke={BRAND.text.light} strokeWidth="1.5" strokeLinecap="round"/>
        </svg>
        <input placeholder="Buscar cursos..." style={{ border:'none', background:'transparent', outline:'none',
          fontSize:13, color:BRAND.text.secondary, fontFamily:'Outfit,sans-serif', width:'100%' }}/>
      </div>
      <button onClick={() => onNavigate('notifications')}
        style={{ position:'relative', background:'none', border:'none', cursor:'pointer', color:BRAND.text.muted, padding:4, flexShrink:0 }}>
        <NavIcon name="notifications"/>
        <span style={{ position:'absolute', top:0, right:0, width:8, height:8, background:BRAND.amber.main,
          borderRadius:'50%', border:'2px solid white' }}/>
      </button>
    </div>
  );
}

function CourseIconSVG({ icon, x = 0, y = 0, size = 1 }) {
  const stroke = 'white';
  const base = (children) => <g transform={`translate(${x},${y}) scale(${size})`}>{children}</g>;

  switch (icon) {
    case 'shield':
      return base(
        <>
          <path d="M0,-16 L13,-10 L13,1 C13,9 7,16 0,18 C-7,16 -13,9 -13,1 L-13,-10 Z" fill="none" stroke={stroke} strokeWidth="2.2" strokeLinejoin="round"/>
          <polyline points="-6,2 -1,7 9,-6" fill="none" stroke={stroke} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
        </>,
      );
    case 'camera':
    case 'camera2':
      return base(
        <>
          <rect x="-16" y="-10" width="32" height="20" rx="4" fill="none" stroke={stroke} strokeWidth="2.2"/>
          <circle cx="0" cy="0" r="6" fill="none" stroke={stroke} strokeWidth="2"/>
          {icon === 'camera2' ? <path d="M9,-4 L16,-8 L16,8 L9,4" fill="none" stroke={stroke} strokeWidth="2" strokeLinejoin="round"/> : <circle cx="10" cy="-5.5" r="1.6" fill={stroke} opacity="0.85"/>}
        </>,
      );
    case 'monitor':
      return base(
        <>
          <rect x="-18" y="-12" width="36" height="22" rx="3" fill="none" stroke={stroke} strokeWidth="2.2"/>
          <line x1="-7" y1="14" x2="7" y2="14" stroke={stroke} strokeWidth="2" strokeLinecap="round"/>
          <line x1="0" y1="10" x2="0" y2="14" stroke={stroke} strokeWidth="2" strokeLinecap="round"/>
        </>,
      );
    case 'checklist':
    case 'clipboard':
      return base(
        <>
          <rect x="-13" y="-15" width="26" height="30" rx="3" fill="none" stroke={stroke} strokeWidth="2.2"/>
          <line x1="-7" y1="-6" x2="8" y2="-6" stroke={stroke} strokeWidth="1.8" strokeLinecap="round"/>
          <line x1="-7" y1="0" x2="8" y2="0" stroke={stroke} strokeWidth="1.8" strokeLinecap="round"/>
          <line x1="-7" y1="6" x2="4" y2="6" stroke={stroke} strokeWidth="1.8" strokeLinecap="round"/>
        </>,
      );
    default:
      return base(
        <>
          <circle cx="0" cy="0" r="14" fill="none" stroke={stroke} strokeWidth="2.2"/>
          <path d="M-8,6 L0,-8 L8,6 Z" fill="none" stroke={stroke} strokeWidth="2" strokeLinejoin="round"/>
        </>,
      );
  }
}

function CourseThumbnail({ course, onClick, style = {} }) {
  const lv = LEVEL[course.level];
  const [hovered, setHovered] = useState(false);
  const id = `grad-${course.code}`;
  const idBg = `gradbg-${course.code}`;

  return (
    <div onClick={onClick}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{ cursor:'pointer', borderRadius:10, overflow:'hidden',
        boxShadow: hovered ? '0 8px 24px rgba(0,0,0,0.15)' : '0 2px 8px rgba(0,0,0,0.08)',
        transform: hovered ? 'translateY(-2px)' : 'none', transition:'all 0.2s', ...style }}>
      <svg
        width="100%"
        height="126"
        viewBox="0 0 280 126"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        preserveAspectRatio="none"
        style={{ display:'block', width:'100%', height:'126px' }}>
        <defs>
          <linearGradient id={id} x1="0" y1="0" x2="280" y2="126" gradientUnits="userSpaceOnUse">
            <stop offset="0%" stopColor={lv.dark}/>
            <stop offset="100%" stopColor={lv.color}/>
          </linearGradient>
          <radialGradient id={idBg} cx="85%" cy="15%" r="50%">
            <stop offset="0%" stopColor="white" stopOpacity="0.12"/>
            <stop offset="100%" stopColor="white" stopOpacity="0"/>
          </radialGradient>
        </defs>
        {/* Background */}
        <rect width="280" height="126" fill={`url(#${id})`}/>
        <rect width="280" height="126" fill={`url(#${idBg})`}/>
        {/* Subtle dot grid */}
        {[...Array(8)].map((_,r) => [...Array(14)].map((_,c) => (
          <circle key={`${r}-${c}`} cx={10 + c*20} cy={10 + r*16} r="1" fill="white" opacity="0.07"/>
        )))}
        {/* Large bg icon */}
        <g opacity="0.12">
          <CourseIconSVG icon={course.icon} x={214} y={58} size={2.4}/>
        </g>
        {/* Center icon */}
        <CourseIconSVG icon={course.icon} x={140} y={60} size={1.28}/>
        {/* Bottom overlay */}
        <defs>
          <linearGradient id={`bot-${course.code}`} x1="0" y1="70" x2="0" y2="126" gradientUnits="userSpaceOnUse">
            <stop offset="0%" stopColor={lv.dark} stopOpacity="0"/>
            <stop offset="100%" stopColor={lv.dark} stopOpacity="0.85"/>
          </linearGradient>
        </defs>
        <rect width="280" height="126" fill={`url(#bot-${course.code})`}/>
        {/* Course code pill */}
        <rect x="8" y="8" width="48" height="18" rx="9" fill="rgba(0,0,0,0.25)"/>
        <text x="32" y="21" textAnchor="middle" fontFamily="DM Mono,monospace" fontWeight="500" fontSize="10" fill="white" opacity="0.9">{course.code}</text>
        {/* Progress bar if started */}
        {course.progress > 0 && (
          <>
            <rect x="0" y="122" width="280" height="4" fill="rgba(0,0,0,0.3)"/>
            <rect x="0" y="122" width={280 * course.progress / 100} height="4" fill="white" opacity="0.7"/>
          </>
        )}
        {/* Title */}
        <text x="12" y="108" fontFamily="Outfit,sans-serif" fontWeight="600" fontSize="12" fill="white"
              style={{ textShadow:'0 1px 3px rgba(0,0,0,0.4)' }}>{course.title.length > 30 ? course.title.slice(0,28)+'…' : course.title}</text>
        <text x="12" y="120" fontFamily="Outfit,sans-serif" fontWeight="400" fontSize="10" fill="rgba(255,255,255,0.65)">{course.dur} · {course.mods} módulos</text>
      </svg>
    </div>
  );
}

// ─── DonutChart ───────────────────────────────────────────────────────────────
function DonutChart({ value = 0, color, size = 96, label, sublabel }) {
  const r = 36, cx = size/2, cy = size/2;
  const circ = 2 * Math.PI * r;
  const dash = (value / 100) * circ;
  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:4 }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={BRAND.border} strokeWidth="7"/>
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={color} strokeWidth="7"
          strokeDasharray={`${dash} ${circ - dash}`}
          strokeDashoffset={circ / 4}
          strokeLinecap="round"/>
        <text x={cx} y={cy - 4} textAnchor="middle" fontFamily='Space Grotesk,sans-serif' fontWeight="800"
          fontSize="18" fill={BRAND.text.primary}>{value}%</text>
        {sublabel && <text x={cx} y={cy + 13} textAnchor="middle" fontFamily="Outfit,sans-serif"
          fontSize="9" fill={BRAND.text.light}>{sublabel}</text>}
      </svg>
      {label && <div style={{ fontSize:11, color:BRAND.text.muted, textAlign:'center', fontWeight:500 }}>{label}</div>}
    </div>
  );
}

// ─── Progress Bar ─────────────────────────────────────────────────────────────
function ProgressBar({ value, color, height = 8 }) {
  return (
    <div style={{ background:BRAND.border, borderRadius:height, height, overflow:'hidden', width:'100%' }}>
      <div style={{ width:`${value}%`, height:'100%', borderRadius:height,
        background:`linear-gradient(90deg, ${color}CC, ${color})`, transition:'width 0.6s ease' }}/>
    </div>
  );
}

// ─── Card ─────────────────────────────────────────────────────────────────────
function Card({ children, style = {}, onClick }) {
  return (
    <div onClick={onClick}
      style={{ background:BRAND.card, border:`1.5px solid ${BRAND.border}`,
        borderRadius:12, boxShadow:'0 2px 8px rgba(14,31,24,0.05)', ...style }}>
      {children}
    </div>
  );
}

// ─── Level Badge ──────────────────────────────────────────────────────────────
function LevelBadge({ level, unlocked = false, size = 'md' }) {
  const lv = LEVEL[level];
  const sz = size === 'lg' ? 72 : 52;
  const fontSize = size === 'lg' ? 20 : 15;
  const alpha = unlocked ? '1' : '0.3';
  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:6 }}>
      <svg width={sz} height={sz} viewBox="0 0 72 72" fill="none" opacity={unlocked ? 1 : 0.4}>
        <polygon points="36,4 64,18 64,54 36,68 8,54 8,18"
          fill={unlocked ? lv.light : '#F0F0F0'} stroke={unlocked ? lv.color : '#CCC'} strokeWidth="2.5"/>
        <text x="36" y="42" textAnchor="middle" fontFamily='Space Grotesk,sans-serif'
          fontWeight="800" fontSize="18" fill={unlocked ? lv.color : '#AAA'}>
          NV{level}
        </text>
      </svg>
      <div style={{ fontSize:11, fontWeight:500, color: unlocked ? lv.color : BRAND.text.light, textAlign:'center', maxWidth:80 }}>
        {lv.name}
      </div>
    </div>
  );
}

// ─── Achievement Badge ────────────────────────────────────────────────────────
function AchievementBadge({ type, earned = false }) {
  const badges = {
    'nv1':     { label:'Nivel 1 Completado', color: BRAND.green.main, icon:'graduation', sub:'7 cursos' },
    'nv2':     { label:'Nivel 2 Completado', color: BRAND.amber.main, icon:'star',       sub:'6 cursos' },
    'nv3':     { label:'Nivel 3 Completado', color: BRAND.blue.main,  icon:'microscope', sub:'5 cursos' },
    'nv4':     { label:'Nivel 4 Completado', color: BRAND.red.main,   icon:'trophy',     sub:'4 cursos' },
    'week1':   { label:'Primera Semana',     color: '#8B5CF6',        icon:'rocket',     sub:'7 días activo' },
    'streak14':{ label:'Racha de 14 días',   color: '#F59E0B',        icon:'fire',       sub:'14 días seguidos' },
    'certs5':  { label:'5 Certificados',     color: '#0D9488',        icon:'scroll',     sub:'5 logros' },
    'top':     { label:'Mejor del Mes',      color: '#DC2626',        icon:'crown',      sub:'Top operador' },
  };
  const b = badges[type] || badges['nv1'];
  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:8, opacity: earned ? 1 : 0.32 }}>
      <div style={{ width:68, height:68, borderRadius:'50%', border:`2.5px solid ${b.color}`,
        background: earned ? `${b.color}14` : '#F0F2F0',
        display:'flex', alignItems:'center', justifyContent:'center',
        boxShadow: earned ? `0 4px 20px ${b.color}28` : 'none' }}>
        <Icon name={b.icon} size={28} color={earned ? b.color : '#B0BDB8'}/>
      </div>
      <div style={{ textAlign:'center' }}>
        <div style={{ fontSize:12, fontWeight:600, color: earned ? BRAND.text.primary : BRAND.text.light }}>{b.label}</div>
        <div style={{ fontSize:10, color:BRAND.text.light }}>{b.sub}</div>
      </div>
    </div>
  );
}

// ─── Icon System ──────────────────────────────────────────────────────────────
function Icon({ name, size = 16, style = {}, color }) {
  const s = { color, ...style };
  const p = {
    check:        <polyline points="2,9 6,13 14,4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>,
    'check-circle':<><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.5"/><polyline points="4.5,8.5 6.5,10.5 11.5,5.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></>,
    play:         <><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.5"/><polygon points="6.5,5.5 12,8 6.5,10.5" fill="currentColor"/></>,
    clock:        <><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.5"/><path d="M8 4.5V8.5L10.5 10" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></>,
    star:         <polygon points="8,1.5 10.2,6.2 15.5,6.5 11.5,10.1 12.8,15.5 8,12.5 3.2,15.5 4.5,10.1 0.5,6.5 5.8,6.2" fill="currentColor"/>,
    'star-outline':<polygon points="8,1.5 10.2,6.2 15.5,6.5 11.5,10.1 12.8,15.5 8,12.5 3.2,15.5 4.5,10.1 0.5,6.5 5.8,6.2" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/>,
    user:         <><circle cx="8" cy="5.5" r="3.5" stroke="currentColor" strokeWidth="1.5"/><path d="M1.5 15.5C1.5 12 4.2 10 8 10C11.8 10 14.5 12 14.5 15.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    users:        <><circle cx="5.5" cy="5.5" r="3" stroke="currentColor" strokeWidth="1.4"/><path d="M1 14C1 11 3 9.5 5.5 9.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/><circle cx="11" cy="5.5" r="2.5" stroke="currentColor" strokeWidth="1.3"/><path d="M10 9.5C12.3 9.5 15 11 15 14" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></>,
    book:         <><path d="M8,2.5 V13.5 M2,2.5 H8V13.5H2C2,13.5 1,13 1,11.5V4C1,2.5 2,2.5 2,2.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M8,2.5 H14C14,2.5 15,2.5 15,4V11.5C15,13 14,13.5 14,13.5H8" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></>,
    award:        <><circle cx="8" cy="6.5" r="4.5" stroke="currentColor" strokeWidth="1.5"/><path d="M5.2,10.2 L3.5,15.5L8,13L12.5,15.5L10.8,10.2" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></>,
    'bar-chart':  <><rect x="1.5" y="9.5" width="3" height="5" rx="0.8" stroke="currentColor" strokeWidth="1.5"/><rect x="6.5" y="5.5" width="3" height="9" rx="0.8" stroke="currentColor" strokeWidth="1.5"/><rect x="11.5" y="1.5" width="3" height="13" rx="0.8" stroke="currentColor" strokeWidth="1.5"/></>,
    'trending-up':<><polyline points="1,12 5,7 9,10 15,3" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/><polyline points="11,3 15,3 15,7" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></>,
    alert:        <><path d="M8,1.5 L14.5,13.5H1.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><line x1="8" y1="6" x2="8" y2="10" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/><circle cx="8" cy="12.3" r="0.8" fill="currentColor"/></>,
    fire:         <path d="M8,14.5C5,14.5 2.5,12 2.5,9C2.5,7 3.5,5.5 5,4.5C5,6 5.8,6.5 6.5,5.5C6.5,3.5 5.5,2 7.5,1C7.5,3 9,4 9.5,5.5C10.5,4.5 10.5,3 11,2C13,3.5 13.5,5.5 13.5,8C13.5,11.5 11,14.5 8,14.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/>,
    document:     <><path d="M3,1.5H10L13.5,5V14.5H3Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M10,1.5V5H13.5" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><line x1="5.5" y1="8" x2="11" y2="8" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><line x1="5.5" y1="10.5" x2="9" y2="10.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></>,
    download:     <><path d="M8,1.5V10.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/><path d="M4,7.5L8,11.5L12,7.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/><line x1="2" y1="14" x2="14" y2="14" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></>,
    info:         <><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.5"/><line x1="8" y1="7.5" x2="8" y2="11.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/><circle cx="8" cy="5.3" r="0.9" fill="currentColor"/></>,
    graduation:   <><path d="M8,1.5 L15,5.5L8,9.5L1,5.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M4,7.5V12.5C4,12.5 5.8,14.5 8,14.5C10.2,14.5 12,12.5 12,12.5V7.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="15" y1="5.5" x2="15" y2="10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    rocket:       <><path d="M8,13C8,13 5,10.5 5,6.5C5,3.5 8,1 8,1C8,1 11,3.5 11,6.5C11,10.5 8,13 8,13Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><circle cx="8" cy="6.5" r="1.5" fill="currentColor"/><path d="M5,9.5L2.5,12L2.5,14L4.5,13.5" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/><path d="M11,9.5L13.5,12L13.5,14L11.5,13.5" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round"/></>,
    crown:        <><path d="M1.5,13H14.5M2,12.5L3,5L6.5,9L8,2.5L9.5,9L13,5L14,12.5H2Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></>,
    trophy:       <><path d="M4.5,1.5H11.5V8C11.5,10.5 10,12 8,12C6,12 4.5,10.5 4.5,8Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M4.5,4H2V7C2,8.5 3,9.5 4.5,9" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M11.5,4H14V7C14,8.5 13,9.5 11.5,9" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><line x1="8" y1="12" x2="8" y2="14" stroke="currentColor" strokeWidth="1.5"/><line x1="5" y1="14.5" x2="11" y2="14.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/></>,
    microscope:   <><circle cx="9" cy="5" r="3.5" stroke="currentColor" strokeWidth="1.5"/><line x1="9" y1="8.5" x2="9" y2="12" stroke="currentColor" strokeWidth="1.5"/><path d="M5,14.5H13" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"/><line x1="7" y1="12" x2="11" y2="12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="3" y1="7" x2="6" y2="5.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></>,
    scroll:       <><rect x="4" y="1.5" width="8" height="13" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><line x1="6.5" y1="5.5" x2="9.5" y2="5.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><line x1="6.5" y1="8" x2="9.5" y2="8" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><line x1="6.5" y1="10.5" x2="8.5" y2="10.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></>,
    share:        <><circle cx="13" cy="3" r="2" stroke="currentColor" strokeWidth="1.5"/><circle cx="3" cy="8" r="2" stroke="currentColor" strokeWidth="1.5"/><circle cx="13" cy="13" r="2" stroke="currentColor" strokeWidth="1.5"/><line x1="5" y1="7" x2="11" y2="4" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/><line x1="5" y1="9" x2="11" y2="12" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></>,
    plus:         <><line x1="8" y1="2" x2="8" y2="14" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/><line x1="2" y1="8" x2="14" y2="8" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></>,
    calendar:     <><rect x="1.5" y="2.5" width="13" height="13" rx="1.5" stroke="currentColor" strokeWidth="1.5"/><line x1="1.5" y1="6.5" x2="14.5" y2="6.5" stroke="currentColor" strokeWidth="1.3"/><line x1="5" y1="1" x2="5" y2="4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><line x1="11" y1="1" x2="11" y2="4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/><circle cx="5.5" cy="10" r="0.8" fill="currentColor"/><circle cx="8" cy="10" r="0.8" fill="currentColor"/><circle cx="10.5" cy="10" r="0.8" fill="currentColor"/></>,
    pdf:          <><path d="M3,1.5H9.5L13.5,5.5V14.5H3Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M9.5,1.5V5.5H13.5" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><text x="5" y="12.5" fontFamily="DM Mono" fontSize="4.5" fill="currentColor" fontWeight="500" stroke="none">PDF</text></>,
    eye:          <><path d="M1,8C3,4 5,3 8,3C11,3 13,4 15,8C13,12 11,13 8,13C5,13 3,12 1,8Z" stroke="currentColor" strokeWidth="1.5"/><circle cx="8" cy="8" r="2.5" stroke="currentColor" strokeWidth="1.5"/></>,
    'chart-pie':  <><path d="M8,2V8H14C14,11.3 11.3,14 8,14C4.7,14 2,11.3 2,8C2,4.7 4.7,2 8,2Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/><path d="M8,2C11.3,2 14,4.7 14,8H8V2Z" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" style={s}>
      {p[name] || p.document}
    </svg>
  );
}

// ─── Stat Card ────────────────────────────────────────────────────────────────
function StatCard({ label, value, sub, color, icon }) {
  return (
    <Card style={{ padding:'18px 20px', flex:1 }}>
      <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', gap:8 }}>
        <div>
          <div style={{ fontSize:11, color:BRAND.text.muted, fontWeight:500, letterSpacing:'0.04em', textTransform:'uppercase', marginBottom:6 }}>{label}</div>
          <div style={{ fontFamily:'Space Grotesk,sans-serif', fontWeight:800, fontSize:28, color:BRAND.text.primary, lineHeight:1 }}>{value}</div>
          {sub && <div style={{ fontSize:12, color:BRAND.text.light, marginTop:4 }}>{sub}</div>}
        </div>
        {color && icon && (
          <div style={{ width:38, height:38, borderRadius:10, background:`${color}18`,
            display:'flex', alignItems:'center', justifyContent:'center', color, flexShrink:0 }}>
            <Icon name={icon} size={18}/>
          </div>
        )}
      </div>
    </Card>
  );
}

Object.assign(window, { BRAND, LEVEL, COURSES, Logo, NavIcon, Icon, Sidebar, TopBar, CourseThumbnail, CourseIconSVG, DonutChart, ProgressBar, Card, LevelBadge, AchievementBadge, StatCard, useViewportMatch });

