/* ============ ATHARV.OS — Main App ============ */

function App() {
  const [phase, setPhase] = React.useState('boot'); // boot | splash | desktop | shutdown | bsod
  const [windows, setWindows] = React.useState([]);
  const [focused, setFocused] = React.useState(null);
  const [zCounter, setZCounter] = React.useState(100);
  const [startOpen, setStartOpen] = React.useState(false);
  const [tilt, setTilt] = React.useState({ x: 0, y: 0 });
  const [crt, setCrt] = React.useState(false);
  const [mp, setMp] = React.useState({ playing: false, current: null });
  const [notepadText, setNotepadText] = React.useState(D.guitarTab + "\n\n" + D.notes.map(n => `[${n.date}]\n${n.body}\n`).join('\n'));
  const [termHistory, setTermHistory] = React.useState([]);
  const [sudoMode, setSudoMode] = React.useState(false);
  const [muted, setMutedState] = React.useState(() => {
    if (window.soundsApi) return window.soundsApi.isMuted();
    return true;
  });
  const setMuted = React.useCallback((v) => {
    const next = (typeof v === 'function') ? v(muted) : v;
    setMutedState(next);
    if (window.soundsApi) window.soundsApi.setMuted(next);
    if (!next && window.sfx) window.sfx.ding();
  }, [muted]);
  const [volume, setVolume] = React.useState(75);
  React.useEffect(() => {
    window.__atharvMuted = muted;
    if (window.soundsApi) window.soundsApi.setMuted(muted);
  }, [muted]);
  // Listen for mute changes from other surfaces
  React.useEffect(() => {
    const h = (e) => setMutedState(!!(e.detail && e.detail.muted));
    window.addEventListener('atharv-os:mute', h);
    return () => window.removeEventListener('atharv-os:mute', h);
  }, []);
  const [konami, setKonami] = React.useState([]);
  const [matrixOn, setMatrixOn] = React.useState(false);
  const [confetti, setConfetti] = React.useState(false);
  const desktopRef = React.useRef();

  // Tweaks: project icon overrides
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "iconOverrides": {},
    "folderIcons": {},
    "showBevel": true,
    "showTweaks": true
  }/*EDITMODE-END*/;
  const tweaks = (typeof useTweaks === 'function') ? useTweaks(TWEAK_DEFAULTS) : { t: TWEAK_DEFAULTS, setTweak: ()=>{} };
  const t = tweaks.t || tweaks;
  const setTweak = tweaks.setTweak || (()=>{});

  // Load notepad from localStorage
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem('atharv_notepad');
      if (saved) setNotepadText(saved);
    } catch(e){}
  }, []);
  React.useEffect(() => {
    try { localStorage.setItem('atharv_notepad', notepadText); } catch(e){}
  }, [notepadText]);

  // Parallax tilt disabled — fixed scene
  React.useEffect(() => {
    setTilt({ x: 0, y: 0 });
  }, []);

  // Konami code
  React.useEffect(() => {
    const seq = ['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
    const h = (e) => {
      const k = e.key;
      const next = [...konami, k].slice(-10);
      setKonami(next);
      if (next.length === 10 && next.every((c,i)=>c.toLowerCase() === seq[i].toLowerCase())) {
        if (window.sfx) window.sfx.ding();
        triggerKonami();
      }
      if ((e.key === 'r' || e.key === 'R') && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        openApp('run');
      }
    };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [konami]);

  // Custom events
  React.useEffect(() => {
    const onMatrix = () => { setMatrixOn(true); setTimeout(()=>setMatrixOn(false), 6000); };
    const onKon = () => triggerKonami();
    const onClear = () => setTermHistory([]);
    window.addEventListener('atharv:matrix', onMatrix);
    window.addEventListener('atharv:konami', onKon);
    window.addEventListener('atharv:clearterm', onClear);
    return () => {
      window.removeEventListener('atharv:matrix', onMatrix);
      window.removeEventListener('atharv:konami', onKon);
      window.removeEventListener('atharv:clearterm', onClear);
    };
  }, []);

  const triggerKonami = () => {
    setConfetti(true);
    setTimeout(()=>setConfetti(false), 5000);
  };

  /* ========== Window manager ========== */
  const openWindow = (def) => {
    setZCounter(z => z + 1);
    const id = newWinId();
    const win = {
      id, ...def,
      x: def.x || 60 + (windows.length % 6) * 36,
      y: def.y || 50 + (windows.length % 6) * 28,
      w: def.w || 560, h: def.h || 420,
      z: zCounter + 1,
      minimized: false,
      opening: true,
    };
    setWindows(ws => [...ws, win]);
    setFocused(id);
    setTimeout(() => setWindows(ws => ws.map(w => w.id===id ? {...w, opening:false} : w)), 250);
    return id;
  };

  const closeWindow = (id) => {
    setWindows(ws => ws.map(w => w.id===id ? {...w, closing:true} : w));
    setTimeout(() => {
      setWindows(ws => ws.filter(w => w.id !== id));
    }, 280);
  };

  const minimizeWindow = (id) => {
    setWindows(ws => ws.map(w => w.id===id ? {...w, minimizing:true} : w));
    setTimeout(() => {
      setWindows(ws => ws.map(w => w.id===id ? {...w, minimized:true, minimizing:false} : w));
    }, 280);
  };

  const restoreWindow = (id) => {
    setZCounter(z => z+1);
    setWindows(ws => ws.map(w => w.id===id ? {...w, minimized:false, z: zCounter+1, opening:true} : w));
    setFocused(id);
    setTimeout(() => setWindows(ws => ws.map(w => w.id===id ? {...w, opening:false} : w)), 250);
  };

  const focusWindow = (id) => {
    setZCounter(z => z+1);
    setWindows(ws => ws.map(w => w.id===id ? {...w, z: zCounter+1} : w));
    setFocused(id);
  };

  const updateWindow = (id, patch) => {
    setWindows(ws => ws.map(w => w.id===id ? {...w, ...patch} : w));
  };

  /* ========== App opener ========== */
  const openApp = (key, opts = {}) => {
    // Find existing
    const existing = windows.find(w => w.appKey === key);
    if (existing) {
      if (existing.minimized) restoreWindow(existing.id);
      else focusWindow(existing.id);
      return;
    }
    if (window.sfx) window.sfx.click();
    const defs = {
      about: { appKey:'about', title:'About — Atharv Sharma', iconKey:'about', w:560, h:480, content: 'about' },
      mycomputer: { appKey:'mycomputer', title:'My Computer', iconKey:'myComputer', w:600, h:440, content: 'mycomputer' },
      mediaplayer: { appKey:'mediaplayer', title:'Media Player — devarv\u2019s tapes', iconKey:'logo', w:760, h:600, content: 'mediaplayer' },
      photos: { appKey:'photos', title:'Photo Viewer — From the mountains', iconKey:'photos', w:620, h:480, content: 'photos' },
      notepad: { appKey:'notepad', title:'Notes.txt — Notepad', iconKey:'notes', w:520, h:440, content: 'notepad' },
      network: { appKey:'network', title:'Network Neighborhood', iconKey:'network', w:520, h:380, content: 'network' },
      ie: { appKey:'ie', title:'Internet Explorer', iconKey:'ie', w:720, h:540, content: 'ie' },
      readme: { appKey:'readme', title:'README.txt — Notepad', iconKey:'readme', w:480, h:440, content: 'readme' },
      resume: { appKey:'resume', title:'Resume.pdf — Atharv Sharma', iconKey:'pdf', w:760, h:600, content: 'resume' },
      experience: { appKey:'experience', title:'Experience.log — Notepad', iconKey:'experience', w:600, h:520, content: 'experience' },
      skills: { appKey:'skills', title:'Skills — Control Panel', iconKey:'skillsCpl', w:600, h:440, content: 'skills' },
      awards: { appKey:'awards', title:'Awards — Trophy Case', iconKey:'awards', w:560, h:440, content: 'awards' },
      recycle: { appKey:'recycle', title:'Recycle Bin', iconKey:'recycle', w:420, h:300, content: 'recycle' },
      terminal: { appKey:'terminal', title:'MS-DOS Prompt', iconKey:'terminal', w:560, h:380, content: 'terminal' },
      run: { appKey:'run', title:'Run', iconKey:'myComputer', w:380, h:200, content: 'run' },
      welcome: { appKey:'welcome', title:'Welcome to ATHARV.OS', iconKey:'logo', w:520, h:340, content: 'welcome' },
      tip: { appKey:'tip', title:'Tip of the Day', iconKey:'about', w:420, h:220, content: 'tip' },
      solitaire: { appKey:'solitaire', title:'Solitaire', iconKey:'solitaire', w:760, h:580, content: 'solitaire' },
    };
    const def = defs[key];
    if (!def) return;
    openWindow(def);
    // Dispatch global event for Bevel + other listeners
    try { window.dispatchEvent(new CustomEvent('atharv-os:open', { detail: { appKey: key } })); } catch(e) {}
  };

  const openProject = (slug) => {
    const proj = D.projects.find(p => p.slug === slug);
    if (!proj) return;
    const existing = windows.find(w => w.appKey === `project:${slug}`);
    if (existing) {
      if (existing.minimized) restoreWindow(existing.id);
      else focusWindow(existing.id);
      return;
    }
    if (window.sfx) window.sfx.click();
    openWindow({
      appKey: `project:${slug}`,
      title: `${proj.name} — Properties`,
      iconKey: proj.iconKey,
      iconColor: proj.themeColor,
      w: 580, h: 500,
      content: 'project', proj,
    });
    try { window.dispatchEvent(new CustomEvent('atharv-os:open', { detail: { appKey: `project:${slug}` } })); } catch(e) {}
  };

  /* ========== Run command ========== */
  const handleRun = (raw) => {
    const cmd = raw.trim().toLowerCase();
    // close run dialog
    const runWin = windows.find(w => w.appKey === 'run');
    if (runWin) closeWindow(runWin.id);
    if (!cmd) return;
    const map = {
      'about': 'about', 'mycomputer': 'mycomputer', 'media': 'mediaplayer',
      'spotify': 'mediaplayer', 'mediaplayer': 'mediaplayer',
      'photos': 'photos', 'notepad': 'notepad', 'notes': 'notepad',
      'projects': 'mycomputer', 'resume': 'resume', 'cv': 'resume',
      'skills': 'skills', 'experience': 'experience', 'awards': 'awards',
      'network': 'network', 'recycle': 'recycle', 'terminal': 'terminal',
      'cmd': 'terminal', 'bash': 'terminal', 'readme': 'readme',
      'help': 'tip',
      'sol': 'solitaire', 'solitaire': 'solitaire',
    };
    if (map[cmd]) { openApp(map[cmd]); return; }
    if (cmd === 'matrix') { setMatrixOn(true); setTimeout(()=>setMatrixOn(false), 6000); return; }
    if (cmd === 'konami') { triggerKonami(); return; }
    if (cmd === 'sudo' || cmd === 'sudo su') { setSudoMode(true); openApp('terminal'); return; }
    if (cmd === 'whoami') { openApp('about'); return; }
    if (cmd === 'clear' || cmd === 'cls') { setTermHistory([]); return; }
    if (cmd === 'contact' || cmd === 'mail' || cmd === 'email') {
      openApp('ie');
      setTimeout(() => {
        try {
          window.dispatchEvent(new CustomEvent('atharv-os:ie-navigate', {
            detail: { url: 'http://www.atharv.os/contact' }
          }));
        } catch(e) {}
      }, 50);
      return;
    }
    if (cmd === 'hire') {
      window.open(`mailto:${D.identity.email}?subject=Let's%20work%20together`, '_blank');
      return;
    }
    if (cmd === 'bsod') { if (window.sfx) window.sfx.ding(); setPhase('bsod'); setTimeout(()=>setPhase('desktop'), 4500); return; }
    if (cmd === 'shutdown') { handleShutdown(); return; }
    if (cmd === 'crt') { setCrt(c=>!c); return; }
    // Direct project lookup
    const proj = D.projects.find(p => p.slug === cmd || p.name.toLowerCase().includes(cmd));
    if (proj) { openProject(proj.slug); return; }
    // Open as URL
    if (cmd.startsWith('http')) { window.open(raw, '_blank'); return; }
    // Default
    openApp('terminal');
  };

  const handleShutdown = () => {
    if (window.sfx) window.sfx.shutdown();
    setPhase('shutdown');
    setTimeout(() => {
      setPhase('boot');
      setWindows([]);
    }, 2200);
  };

  const addTermLine = (l) => setTermHistory(h => [...h, l]);

  /* ========== Desktop icons ========== */
  const desktopIcons = [
    { key:'mycomputer', label:'My Computer', icon:'myComputer' },
    { key:'about', label:'About', icon:'about' },
    { key:'network', label:'Network Neighborhood', icon:'network' },
    { key:'ie', label:'Internet Explorer', icon:'ie' },
    { key:'mediaplayer', label:'Media Player', icon:'mediaPlayer' },
    { key:'photos', label:'Photos', icon:'photos' },
    { key:'notepad', label:'Notes.txt', icon:'notes' },
    { key:'experience', label:'Experience.log', icon:'experience' },
    { key:'skills', label:'Skills', icon:'skillsCpl' },
    { key:'awards', label:'Awards', icon:'awards' },
    { key:'resume', label:'Resume.pdf', icon:'pdf' },
    { key:'readme', label:'README.txt', icon:'readme' },
    { key:'solitaire', label:'Solitaire', icon:'solitaire' },
    { key:'recycle', label:'Recycle Bin', icon:'recycle' },
  ];
  const [selectedIcon, setSelectedIcon] = React.useState(null);
  const [isMobile, setIsMobile] = React.useState(() =>
    typeof window !== 'undefined' && window.matchMedia
      ? window.matchMedia('(max-width: 900px)').matches : false);
  React.useEffect(() => {
    if (!window.matchMedia) return;
    const mql = window.matchMedia('(max-width: 900px)');
    const handler = (e) => setIsMobile(e.matches);
    if (mql.addEventListener) mql.addEventListener('change', handler);
    else mql.addListener(handler);
    return () => {
      if (mql.removeEventListener) mql.removeEventListener('change', handler);
      else mql.removeListener(handler);
    };
  }, []);

  /* ========== Welcome on first boot ========== */
  const chimedRef = React.useRef(false);
  React.useEffect(() => {
    if (phase === 'desktop' && windows.length === 0) {
      if (!chimedRef.current) {
        chimedRef.current = true;
        if (window.sfx) {
          window.sfx.chime();
          setTimeout(() => window.sfx.tada(), 1400);
        }
      }
      setTimeout(() => openApp('welcome'), 400);
    }
  }, [phase]);

  /* ========== Render content ========== */
  const renderContent = (win) => {
    const c = win.content;
    if (c === 'about') return <AboutContent/>;
    if (c === 'mycomputer') return <MyComputerContent openApp={openApp} openProject={openProject} iconOverrides={t.iconOverrides || {}} folderIcons={t.folderIcons || {}}/>;
    if (c === 'mediaplayer') return <MediaPlayerContent
      playing={mp.playing} setPlaying={(v)=>setMp(m=>({...m, playing: typeof v==='function'?v(m.playing):v}))}
      currentTrack={mp.current} setCurrentTrack={(v)=>setMp(m=>({...m, current:v}))}
    />;
    if (c === 'photos') return <PhotosContent/>;
    if (c === 'notepad') return <NotesContent notepadText={notepadText} setNotepadText={setNotepadText}/>;
    if (c === 'network') return <NetworkContent/>;
    if (c === 'ie') return <IEContent/>;
    if (c === 'readme') return <ReadmeContent/>;
    if (c === 'resume') return <ResumeContent/>;
    if (c === 'experience') return <ExperienceContent/>;
    if (c === 'skills') return <SkillsContent/>;
    if (c === 'awards') return <AwardsContent/>;
    if (c === 'recycle') return <RecycleBinContent/>;
    if (c === 'terminal') return <TerminalContent openApp={openApp} lineHistory={termHistory} addLine={addTermLine} sudoMode={sudoMode}/>;
    if (c === 'run') return <RunDialog onRun={handleRun} onClose={()=>closeWindow(win.id)}/>;
    if (c === 'project') return <ProjectContent proj={win.proj}/>;
    if (c === 'welcome') return <WelcomeContent openApp={openApp} onClose={()=>closeWindow(win.id)}/>;
    if (c === 'tip') return <TipOfTheDay onClose={()=>closeWindow(win.id)}/>;
    if (c === 'solitaire') return <Solitaire onClick={(window.sfx && window.sfx.click) || (()=>{})}/>;
    return <div className="wbody">Unknown content</div>;
  };

  /* ========== Phases ========== */
  if (phase === 'boot') return <BootScreen onDone={()=>setPhase('splash')}/>;
  if (phase === 'splash') return <SplashScreen onDone={()=>setPhase('desktop')}/>;
  if (phase === 'shutdown') return (
    <div className="shutdown-screen">It is now safe to turn off your computer.</div>
  );
  if (phase === 'bsod') return (
    <div className="bsod">
      <h2>ATHARV.OS</h2>
      A fatal exception 0x420B has occurred at 0028:devarv. The current
      application will be terminated.{'\n\n'}
      *  Press any key to terminate the current application.{'\n'}
      *  Press CTRL+ALT+DEL again to restart your computer. You will{'\n'}
         lose any unsaved information in all applications.{'\n\n'}
      (just kidding — desktop will return in a moment)
    </div>
  );

  /* ========== Desktop ========== */
  return (
    <>
      <div className="scene" ref={desktopRef}>
        <div className="stage3d">
          <div className={`desktop ${crt?'crt':''}`}>
            {/* Desktop icons */}
            <div className="dicons">
              {desktopIcons.map(it => (
                <div
                  key={it.key}
                  className={`dicon ${selectedIcon===it.key?'selected':''}`}
                  onClick={()=> {
                    if (isMobile) { it.action ? it.action() : openApp(it.key); }
                    else { setSelectedIcon(it.key); }
                  }}
                  onDoubleClick={()=> it.action ? it.action() : openApp(it.key)}
                >
                  <div dangerouslySetInnerHTML={{__html: ICO[it.icon] ? ICO[it.icon](32) : ''}}/>
                  <div className="lbl">{it.label}</div>
                </div>
              ))}
            </div>
            {/* Now playing widget */}
            <NowPlayingWidget
              playing={mp.playing}
              currentTrack={mp.current}
              onOpen={()=>openApp('mediaplayer')}
              onToggle={()=>setMp(m=>({...m, playing:!m.playing}))}
            />
            {/* Windows */}
            {windows.filter(w => !w.minimized).map(w => (
              <Window
                key={w.id} win={w}
                focused={focused === w.id}
                zIndex={w.z}
                onFocus={focusWindow}
                onClose={closeWindow}
                onMinimize={minimizeWindow}
                onMaximize={()=>{}}
                onUpdate={updateWindow}
              >
                {renderContent(w)}
              </Window>
            ))}
            {/* Click on empty desktop deselects */}
            <div
              style={{position:'absolute', inset:0, zIndex:1}}
              onClick={(e)=>{
                if (e.target === e.currentTarget) setSelectedIcon(null);
              }}
            />
          </div>
        </div>
      </div>

      {/* Matrix overlay */}
      {matrixOn && <MatrixRain onDone={()=>setMatrixOn(false)}/>}
      {/* Confetti */}
      {confetti && <Confetti/>}

      {/* Taskbar (NOT inside 3D — flat for usability) */}
      <div className="taskbar slide-in">
        <button
          className={`startbtn ${startOpen?'open':''}`}
          onMouseDown={(e)=>{ e.stopPropagation(); setStartOpen(o=>!o); }}
        >
          <span className="logo" dangerouslySetInnerHTML={{__html: ICO.startWindowsLogo(16)}}/>
          <span>Start</span>
        </button>
        <div className="tbsep-v"/>
        <div className="tasks">
          {windows.map(w => (
            <button
              key={w.id}
              className={`taskitem ${focused===w.id && !w.minimized ? 'active':''}`}
              onClick={()=>{
                if (w.minimized) restoreWindow(w.id);
                else if (focused === w.id) minimizeWindow(w.id);
                else focusWindow(w.id);
              }}
            >
              <span className="ico16" dangerouslySetInnerHTML={{__html: ICO[w.iconKey] ? ICO[w.iconKey](16, w.iconColor) : ICO.myComputer(16)}}/>
              <span className="lbl">{w.title.split('—')[0].trim()}</span>
            </button>
          ))}
        </div>
        <SystemTray
          muted={muted} setMuted={setMuted}
          volume={volume} setVolume={setVolume}
          mp={mp}
          onOpenMedia={()=>openApp('mediaplayer')}
          onOpenNetwork={()=>openApp('network')}
        />
      </div>

      {startOpen && <StartMenu onSelect={(k)=>{ setStartOpen(false); if (k==='shutdown') handleShutdown(); else openApp(k); }} onClose={()=>setStartOpen(false)}/>}

      {/* === BEVEL — your low-poly mountain pup guide === */}
      {typeof BevelMascot === 'function' && (
        <BevelMascot
          phase={phase}
          windows={windows}
          mpPlaying={mp.playing}
          currentTrack={mp.current}
          visible={t.showBevel !== false}
        />
      )}

      {typeof TweaksPanel === 'function' && (
        <TweaksPanel title="Tweaks — Project Icons">
          {typeof TweakSection === 'function' && typeof TweakToggle === 'function' && (
            <TweakSection title="Bevel — your guide">
              <div style={{fontSize:11, color:'#555', marginBottom:8}}>The low-poly mountain pup who lives in the corner. <i>Click him to pet. Pet 5x for a belly flop.</i></div>
              <TweakToggle
                label="Show Bevel"
                value={t.showBevel !== false}
                onChange={(v) => setTweak('showBevel', v)}
              />
            </TweakSection>
          )}
          <TweakSection title="My Computer › Folders (C:\)">
            <div style={{fontSize:11, color:'#555', marginBottom:8}}>Swap the folder icons for Projects / Awards / Photos / Notes.</div>
            {[
              {key:'projects', label:'Projects'},
              {key:'awards', label:'Awards'},
              {key:'photos', label:'Photos'},
              {key:'notes', label:'Notes'},
            ].map(f => {
              const cur = (t.folderIcons||{})[f.key] || 'folder';
              return (
                <div key={f.key} style={{display:'flex', alignItems:'center', gap:8, marginBottom:6, padding:'4px 6px', background:'#f4f4f4', border:'1px solid #ddd'}}>
                  <div style={{width:24, height:24, flexShrink:0}}
                    dangerouslySetInnerHTML={{__html: (window.ATHARV_ICONS[cur] || window.ATHARV_ICONS.folder)(24)}}/>
                  <div style={{fontSize:11, flex:1, fontWeight:600}}>{f.label}</div>
                  <select
                    value={cur}
                    onChange={e => setTweak('folderIcons', { ...(t.folderIcons||{}), [f.key]: e.target.value })}
                    style={{fontSize:11, fontFamily:'inherit'}}>
                    {['folder','myComputer','network','recycle','ie','pdf','readme','notes','mediaPlayer','photos','about','skillsCpl','experience','awards','myDocs','shield','server','graph','whale','lock','wrench','brain','key','users','doc','iot','terminal','wp','car','floppy'].map(k =>
                      <option key={k} value={k}>{k}</option>
                    )}
                  </select>
                </div>
              );
            })}
            <button
              onClick={() => setTweak('folderIcons', {})}
              style={{marginTop:6, padding:'4px 10px', fontSize:11, fontFamily:'inherit', cursor:'pointer'}}>
              Reset folders
            </button>
          </TweakSection>
          <TweakSection title="My Computer › Projects">
            <div style={{fontSize:11, color:'#555', marginBottom:8}}>Pick a Win95 icon for each project shown inside My Computer.</div>
            {D.projects.map(p => (
              <div key={p.slug} style={{display:'flex', alignItems:'center', gap:8, marginBottom:6, padding:'4px 6px', background:'#f4f4f4', border:'1px solid #ddd'}}>
                <div style={{width:24, height:24, flexShrink:0}}
                  dangerouslySetInnerHTML={{__html: (window.ATHARV_ICONS[(t.iconOverrides||{})[p.slug] || p.iconKey] || (()=>''))(24, p.themeColor)}}/>
                <div style={{fontSize:11, flex:1, fontWeight:600, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{p.name}</div>
                <select
                  value={(t.iconOverrides||{})[p.slug] || p.iconKey}
                  onChange={e => setTweak('iconOverrides', { ...(t.iconOverrides||{}), [p.slug]: e.target.value })}
                  style={{fontSize:11, fontFamily:'inherit'}}>
                  {['shield','server','graph','whale','lock','wrench','brain','key','users','doc','iot','terminal','wp','car','floppy','folder','myComputer','network','recycle','ie','pdf','readme','notes','mediaPlayer','photos','about','skillsCpl','experience','awards'].map(k =>
                    <option key={k} value={k}>{k}</option>
                  )}
                </select>
              </div>
            ))}
            <button
              onClick={() => setTweak('iconOverrides', {})}
              style={{marginTop:6, padding:'4px 10px', fontSize:11, fontFamily:'inherit', cursor:'pointer'}}>
              Reset all to defaults
            </button>
          </TweakSection>
        </TweaksPanel>
      )}
    </>
  );
}

/* ===== Matrix Rain ===== */
function MatrixRain({ onDone }) {
  const canvasRef = React.useRef();
  React.useEffect(() => {
    const c = canvasRef.current;
    if (!c) return;
    c.width = window.innerWidth; c.height = window.innerHeight;
    const ctx = c.getContext('2d');
    const cols = Math.floor(c.width / 14);
    const drops = Array(cols).fill(1);
    const chars = '01ATHARVDEVARVMOUNTAIN日本語'.split('');
    let raf;
    const draw = () => {
      ctx.fillStyle = 'rgba(0,0,0,0.05)';
      ctx.fillRect(0,0,c.width,c.height);
      ctx.fillStyle = '#5cd35c';
      ctx.font = '14px Fixedsys, monospace';
      drops.forEach((y, i) => {
        const ch = chars[Math.floor(Math.random()*chars.length)];
        ctx.fillText(ch, i*14, y*14);
        if (y*14 > c.height && Math.random() > 0.96) drops[i] = 0;
        drops[i]++;
      });
      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(raf);
  }, []);
  return (
    <canvas ref={canvasRef} style={{position:'fixed', inset:0, zIndex:9999, pointerEvents:'none'}}/>
  );
}

/* ===== Confetti ===== */
function Confetti() {
  const canvasRef = React.useRef();
  React.useEffect(() => {
    const c = canvasRef.current;
    if (!c) return;
    c.width = window.innerWidth; c.height = window.innerHeight;
    const ctx = c.getContext('2d');
    const colors = ['#FF6B6B','#FFD700','#5BC0EB','#7E5BB5','#5cd35c','#D69E2E'];
    const parts = Array(180).fill(0).map(()=>({
      x: Math.random()*c.width,
      y: -20 - Math.random()*200,
      vy: 2 + Math.random()*5,
      vx: -2 + Math.random()*4,
      r: 3 + Math.random()*5,
      c: colors[Math.floor(Math.random()*colors.length)],
      a: Math.random()*Math.PI*2,
      va: -0.2 + Math.random()*0.4,
    }));
    let raf;
    const draw = () => {
      ctx.clearRect(0,0,c.width,c.height);
      parts.forEach(p => {
        p.x += p.vx; p.y += p.vy; p.a += p.va;
        ctx.save(); ctx.translate(p.x, p.y); ctx.rotate(p.a);
        ctx.fillStyle = p.c;
        ctx.fillRect(-p.r, -p.r/2, p.r*2, p.r);
        ctx.restore();
      });
      raf = requestAnimationFrame(draw);
    };
    draw();
    return () => cancelAnimationFrame(raf);
  }, []);
  return (
    <canvas ref={canvasRef} className="fx-canvas"/>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
