Q_BROWSER_R13 (DOC20).jsx
Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/Q_BROWSER_R13 (DOC20).jsx
ELNOR REPO READER TEXT MIRROR
Original path: Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/Q_BROWSER_R13 (DOC20).jsx
Source repo: /Users/OpenClaw1/Elnor/Elnor Specs
Git branch: main
Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331
Generated: 2026-06-09T01:23:58.539Z
---
import { useState, useRef, useEffect, useMemo } from "react";
const font={sans:"'Söhne','Helvetica Neue',-apple-system,BlinkMacSystemFont,sans-serif"};
const R={sm:"6px",md:"10px",lg:"14px",full:"9999px"};
const c={bgApp:"#F8F8F6",bgPanel:"#FFFFFF",bgPanelAlt:"#F9FAFB",bgCard:"#FFFFFF",bgInput:"#EFF1F3",bgSidebar:"#131820",textPri:"#1A1D21",textSec:"#5E6570",textTer:"#8B919A",accentBtn:"#31588c",warn:"#D97706",error:"#B04040",border:"#E0E2E5",borderLight:"#ECEEF0",green:"#2E8B57",neutral:"#6B7280",agentAv:"#a1a7aa",borderDark:"#263040"};
const Ic=({d,size=18,color,sw=1.75})=><svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color||"currentColor"} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round"><path d={d}/></svg>;
const I={Search:p=><Ic {...p} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>,Plus:p=><Ic {...p} d="M12 5v14 M5 12h14"/>,ChevR:p=><Ic {...p} d="M9 18l6-6-6-6"/>,ChevD:p=><Ic {...p} d="M6 9l6 6 6-6"/>,Pin:p=><Ic {...p} d="M12 17v5 M9 2l.5 5L7 10l1.5 3h7L17 10l-2.5-3L15 2"/>,Folder:p=><Ic {...p} d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2v11z"/>,File:p=><Ic {...p} d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6"/>,X:p=><Ic {...p} d="M18 6L6 18 M6 6l12 12"/>,Check:p=><Ic {...p} d="M20 6L9 17l-5-5"/>,Save:p=><Ic {...p} d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z M17 21v-8H7v8 M7 3v5h8"/>,Trash:p=><Ic {...p} d="M3 6h18 M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/>,};
const Dot=({color,size=8})=><span style={{display:"inline-flex",width:size,height:size,flexShrink:0}}><span style={{display:"block",width:size,height:size,borderRadius:"50%",backgroundColor:color}}/></span>;
const Toast=({msg,onDone})=>{useEffect(()=>{const t=setTimeout(onDone,2200);return()=>clearTimeout(t)},[onDone]);return <div style={{position:"fixed",bottom:24,left:"50%",transform:"translateX(-50%)",backgroundColor:c.textPri,color:"#fff",padding:"8px 18px",borderRadius:R.md,fontSize:12,fontWeight:500,fontFamily:font.sans,zIndex:9999,boxShadow:"0 4px 16px rgba(0,0,0,0.2)"}}>{msg}</div>};
const typeColors={Note:c.accentBtn,Chat:c.green,Doc:c.textTer,Task:c.warn,Artifact:"#8B5CF6",Prompt:"#D97706",Preset:c.neutral,Skill:c.neutral,Agent:"#5B5F97"};
const projects=[{id:1,name:"Henderson v. DataCorp",color:"#31588c"},{id:2,name:"Quark Research",color:"#2E8B57"},{id:3,name:"Internal Ops",color:"#8B7355"}];
const collections=[{name:"Priority",color:"#B04040"},{name:"Research",color:"#2E8B57"},{name:"Draft",color:"#D97706"},{name:"Archive",color:"#6B7280"},{name:"Urgent",color:"#9E5E5E"},{name:"Reference",color:"#5B5F97"}];
const scopeFams=["Collection","Project","Bucket","Places","Folders","Saved Views"];
const typeChips=["Document","Chat","Preset","Skill","Task","Agent","Overlay","Note","Artifact","Prompt"];
const sortOptions=["Modified","Alphabetical","Type","Created","Running"];
const savedViews=[{id:"sv1",name:"Current",sys:true},{id:"sv2",name:"Recent",sys:true},{id:"sv3",name:"No Project",sys:true}];
const initFolders=[{id:"f1",title:"Henderson Case",parent:null},{id:"f2",title:"Privilege Issues",parent:"f1"},{id:"f3",title:"Motion Practice",parent:"f1"},{id:"f4",title:"Quark Patents",parent:null},{id:"f5",title:"Reference Materials",parent:null}];
const initPlaces=[{id:"p1",title:"Henderson Case Files",path:"~/OneDrive-schallfirm/Henderson",status:"ok"},{id:"p2",title:"Firm Templates",path:"~/OneDrive-schallfirm/Templates",status:"ok"},{id:"p3",title:"Local Research",path:"~/Documents/Research",status:"ok"},{id:"p4",title:"Archived Cases",path:"/Volumes/External/Cases",status:"missing"}];
const placeContents={root:[{name:"Expert_Reports",isFolder:true},{name:"Exhibits",isFolder:true},{name:"Correspondence",isFolder:true},{name:"Henderson_Complaint.pdf",type:"PDF",size:"2.4 MB",mod:"1d"},{name:"Privilege_Log_v4.docx",type:"DOCX",size:"340 KB",mod:"3h"},{name:".DS_Store",type:"System",size:"4 KB",mod:"1d",dimmed:true}],Expert_Reports:[{name:"Dr_Smith_Report.pdf",type:"PDF",size:"1.2 MB",mod:"1w"},{name:"Valuation_Analysis.xlsx",type:"XLSX",size:"890 KB",mod:"2w"}],Exhibits:[{name:"Exhibit_A.pdf",type:"PDF",size:"3.1 MB",mod:"3d"},{name:"Exhibit_B.pdf",type:"PDF",size:"1.8 MB",mod:"3d"},{name:"Photos",isFolder:true}],Correspondence:[{name:"Letter_Mar15.docx",type:"DOCX",size:"45 KB",mod:"1d"}],Photos:[{name:"scene_01.jpg",type:"JPG",size:"4.2 MB",mod:"2w"}]};
const allItems=[
{type:"Note",title:"Henderson Discovery Priorities",time:"2h",pin:true,proj:1,cols:["Priority"]},
{type:"Note",title:"Weekly Task List",time:"4h",pin:true,proj:1,cols:[]},
{type:"Chat",title:"Henderson discovery analysis",time:"2m",unread:true,proj:1,cols:["Priority"]},
{type:"Artifact",title:"Motion for Summary Judgment Brief",time:"10m",proj:1,cols:[]},
{type:"Doc",title:"Henderson_Complaint.pdf",time:"1d",proj:1,cols:["Reference"]},
{type:"Note",title:"Quark Patent Analysis",time:"1d",proj:2,cols:["Research"]},
{type:"Task",title:"Review batch #4",time:"2h",proj:1,st:"running",cols:[]},
{type:"Chat",title:"Quark patent search",time:"1h",proj:2,cols:["Research"]},
{type:"Artifact",title:"Henderson Timeline Analysis",time:"2h",proj:1,cols:[]},
{type:"Doc",title:"Patent_US20240001.pdf",time:"2d",proj:2,cols:[]},
{type:"Note",title:"Judge Chen Conference Notes",time:"3d",proj:1,cols:[]},
{type:"Task",title:"Draft motion response",time:"4h",proj:1,st:"waiting",cols:["Priority"]},
{type:"Artifact",title:"Privilege Log Summary v3",time:"3d",proj:1,cols:[]},
{type:"Prompt",title:"Discovery Review Template",time:"1w",proj:null,cols:[]},
{type:"Preset",title:"Standard Review Preset",time:"1w",proj:null,cols:[]},
{type:"Doc",title:"Standing_Orders.md",time:"3d",proj:null,cols:["Reference"]},
];
const timeVal=t=>{if(t.includes("m"))return parseInt(t);if(t.includes("h"))return parseInt(t)*60;if(t.includes("d"))return parseInt(t)*1440;if(t.includes("w"))return parseInt(t)*10080;return 99999};
export default function BrowserV4(){
const [activeScope,setActiveScope]=useState(null);
const [activeProjIdx,setActiveProjIdx]=useState(0);const [noProject,setNoProject]=useState(false);
const [activeTypes,setActiveTypes]=useState(new Set());
const [selectedCollections,setSelectedCollections]=useState(new Set());
const [splitterPos,setSplitterPos]=useState(120);
const [browserWidth,setBrowserWidth]=useState(290);
const [selectedIdx,setSelectedIdx]=useState(null);
const [folders,setFolders]=useState(initFolders);
const [expandedFolders,setExpandedFolders]=useState(new Set(["f1"]));
const [activeFolder,setActiveFolder]=useState(null);
const [places,setPlaces]=useState(initPlaces);
const [activePlace,setActivePlace]=useState(null);const [placePath,setPlacePath]=useState([]);
const [searchMode,setSearchMode]=useState("this_view");
const [sortKey,setSortKey]=useState("Modified");const [sortDrop,setSortDrop]=useState(false);
const [newFolderMode,setNewFolderMode]=useState(null);const [newFolderName,setNewFolderName]=useState("");
const [hoverFolder,setHoverFolder]=useState(null);const [hoverPlace,setHoverPlace]=useState(null);
const [toast,setToast]=useState(null);
const [activeSavedView,setActiveSavedView]=useState(null);
const [saveViewMode,setSaveViewMode]=useState(false);const [saveViewName,setSaveViewName]=useState("");
const [hoverSavedView,setHoverSavedView]=useState(null);const [userSavedViews,setUserSavedViews]=useState([]);
const [saveFromBar,setSaveFromBar]=useState(false);
const [deletingFolder,setDeletingFolder]=useState(null);
const [removingPlace,setRemovingPlace]=useState(null);
// FOLDER OVERLAY — independent of scope
const [folderOverlay,setFolderOverlay]=useState(false);
const [dropTarget,setDropTarget]=useState(null);
const [dragItem,setDragItem]=useState(null);
const nfRef=useRef(null);
const flash=msg=>setToast(msg);
const toggleType=t=>{const s=new Set(activeTypes);s.has(t)?s.delete(t):s.add(t);setActiveTypes(s)};
const toggleCollection=name=>{const s=new Set(selectedCollections);s.has(name)?s.delete(name):s.add(name);setSelectedCollections(s)};
const toggleFolder=id=>{const s=new Set(expandedFolders);s.has(id)?s.delete(id):s.add(id);setExpandedFolders(s)};
const selectScope=s=>{if(activeScope===s){setActiveScope(null);setActiveFolder(null);setActivePlace(null);setPlacePath([]);setNoProject(false);setActiveSavedView(null)}else{setActiveScope(s);setActiveFolder(null);setActivePlace(null);setPlacePath([]);setNoProject(false);setActiveSavedView(null)}};
const createFolder=parent=>{if(!newFolderName.trim())return;setFolders(p=>[...p,{id:"f"+(p.length+10),title:newFolderName.trim(),parent}]);if(parent){const s=new Set(expandedFolders);s.add(parent);setExpandedFolders(s)}setNewFolderMode(null);setNewFolderName("");flash("Folder created")};
const deleteFolder=id=>{setFolders(p=>p.filter(f=>f.id!==id&&f.parent!==id));setDeletingFolder(null);if(activeFolder===id)setActiveFolder(null);flash("Folder deleted — items unfiled")};
const removePlace=id=>{setPlaces(p=>p.filter(x=>x.id!==id));setRemovingPlace(null);if(activePlace!==null&&places[activePlace]?.id===id){setActivePlace(null);setPlacePath([])}flash("Place removed")};
const filtered=useMemo(()=>{
let items=[...allItems];
if(activeScope==="Project"&&!noProject)items=items.filter(it=>it.proj===projects[activeProjIdx].id);
if(activeScope==="Project"&&noProject)items=items.filter(it=>it.proj===null);
if(selectedCollections.size>0)items=items.filter(it=>[...selectedCollections].every(col=>it.cols?.includes(col)));
if(activeTypes.size>0)items=items.filter(it=>activeTypes.has(it.type));
if(sortKey==="Alphabetical")items.sort((a,b)=>a.title.localeCompare(b.title));
else if(sortKey==="Type")items.sort((a,b)=>a.type.localeCompare(b.type));
else if(sortKey==="Running")items.sort((a,b)=>(b.st==="running"?1:0)-(a.st==="running"?1:0));
else items.sort((a,b)=>timeVal(a.time)-timeVal(b.time));
const pinned=items.filter(x=>x.pin);const unpinned=items.filter(x=>!x.pin);
return [...pinned,...unpinned];
},[activeScope,activeProjIdx,noProject,selectedCollections,activeTypes,sortKey]);
const currentPlaceFiles=()=>{const key=placePath.length?placePath[placePath.length-1]:"root";return placeContents[key]||[{name:"(empty)",dimmed:true,type:"—",size:"—",mod:"—"}]};
// Folder tree renderer (shared between Folders scope and overlay)
const renderFolderTree=(parentId,depth,isOverlay=false)=>folders.filter(f=>f.parent===parentId).map(f=>{
const hasChildren=folders.some(ch=>ch.parent===f.id);const isExp=expandedFolders.has(f.id);
const isActive=!isOverlay&&activeFolder===f.id;const isDrop=dropTarget===f.id;const isHover=hoverFolder===f.id;
const isDeleting=deletingFolder===f.id;
return <div key={f.id}>
<div onClick={()=>{if(isOverlay)return;setActiveFolder(isActive?null:f.id)}}
onMouseEnter={()=>setHoverFolder(f.id)} onMouseLeave={()=>setHoverFolder(null)}
onDragOver={e=>{e.preventDefault();setDropTarget(f.id)}} onDragLeave={()=>setDropTarget(null)}
onDrop={e=>{e.preventDefault();setDropTarget(null);if(dragItem)flash(`Added "${dragItem}" to ${f.title}`)}}
style={{display:"flex",alignItems:"center",gap:3,padding:isOverlay?"2px 6px":"3px 8px",paddingLeft:(isOverlay?6:8)+depth*(isOverlay?12:14),borderRadius:R.sm,cursor:isOverlay?"default":"pointer",backgroundColor:isDrop?c.accentBtn+"20":isActive?c.accentBtn+"10":"transparent",fontSize:isOverlay?10.5:11.5,fontWeight:isActive?600:400,color:isActive?c.accentBtn:c.textSec,border:isDrop?`1px dashed ${c.accentBtn}`:"1px solid transparent",transition:"all .1s"}}>
{hasChildren?<span onClick={e=>{e.stopPropagation();toggleFolder(f.id)}} style={{display:"flex",width:10}}>{isExp?<I.ChevD size={9} color={c.textTer}/>:<I.ChevR size={9} color={c.textTer}/>}</span>:<span style={{width:10}}/>}
<I.Folder size={isOverlay?10:12} color={isActive?c.accentBtn:depth===0?c.warn:c.textTer}/>
<span style={{flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{f.title}</span>
{isHover&&!isOverlay&&!isDeleting&&<>
<span onClick={e=>{e.stopPropagation();setNewFolderMode({parent:f.id});setNewFolderName("");setTimeout(()=>nfRef.current?.focus(),50)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Add subfolder"><I.Plus size={9}/></span>
<span onClick={e=>{e.stopPropagation();setDeletingFolder(f.id)}} style={{cursor:"pointer",display:"flex",color:c.textTer}} title="Delete folder"><I.Trash size={9}/></span>
</>}
{isDeleting&&<span style={{display:"flex",gap:3,fontSize:9}} onClick={e=>e.stopPropagation()}>
<span style={{color:c.error,fontWeight:600}}>Delete?</span>
<span style={{color:c.error,cursor:"pointer",fontWeight:700,textDecoration:"underline"}} onClick={()=>deleteFolder(f.id)}>Yes</span>
<span style={{color:c.textTer,cursor:"pointer"}} onClick={()=>setDeletingFolder(null)}>No</span>
</span>}
</div>
{isExp&&hasChildren&&renderFolderTree(f.id,depth+1,isOverlay)}
{!isOverlay&&newFolderMode&&newFolderMode.parent===f.id&&<div style={{display:"flex",alignItems:"center",gap:4,padding:"3px 8px",paddingLeft:8+(depth+1)*14}}><I.Folder size={10} color={c.textTer}/><input ref={nfRef} value={newFolderName} onChange={e=>setNewFolderName(e.target.value)} placeholder="Subfolder…" onKeyDown={e=>{if(e.key==="Enter")createFolder(f.id);if(e.key==="Escape"){setNewFolderMode(null);setNewFolderName("")}}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/></div>}
</div>;
});
return (
<div style={{display:"flex",width:"100%",height:"100vh",fontFamily:font.sans,color:c.textPri,backgroundColor:c.bgApp}} onClick={()=>setSortDrop(false)}>
<style>{`*{box-sizing:border-box;margin:0;padding:0}::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:transparent;border-radius:2px}*:hover::-webkit-scrollbar-thumb{background:#d1d5db}`}</style>
{toast&&<Toast msg={toast} onDone={()=>setToast(null)}/>}
<div style={{width:52,flexShrink:0,backgroundColor:c.bgSidebar,borderRight:`1px solid ${c.borderDark}`,display:"flex",flexDirection:"column",alignItems:"center",paddingTop:14}}>
<div style={{width:28,height:28,borderRadius:R.sm,backgroundColor:c.accentBtn,color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:12,fontWeight:700}}>Q</div>
</div>
<div style={{width:browserWidth,flexShrink:0,backgroundColor:c.bgPanel,borderRight:`1px solid ${c.border}`,display:"flex",flexDirection:"column",overflow:"hidden",position:"relative"}}>
{/* Search */}
<div style={{padding:"6px 8px",borderBottom:`1px solid ${c.borderLight}`}}>
<div style={{display:"flex",alignItems:"center",gap:5,padding:"5px 8px",borderRadius:R.sm,backgroundColor:c.bgInput,border:`1px solid ${c.borderLight}`}}>
<I.Search size={12} color={c.textTer}/><input placeholder="Search…" style={{flex:1,border:"none",backgroundColor:"transparent",fontSize:11.5,fontFamily:font.sans,color:c.textPri,outline:"none"}}/>
<button style={{padding:"1px 6px",borderRadius:3,border:`1px solid ${searchMode==="this_view"?c.accentBtn+"50":c.borderLight}`,backgroundColor:searchMode==="this_view"?c.accentBtn+"08":"transparent",fontSize:8.5,fontWeight:500,color:searchMode==="this_view"?c.accentBtn:c.textTer,cursor:"pointer",fontFamily:font.sans}} onClick={()=>setSearchMode(s=>s==="this_view"?"everywhere":"this_view")}>{searchMode==="this_view"?"This View":"Everywhere"}</button>
</div>
</div>
{/* Collections */}
<div style={{display:"flex",alignItems:"center",gap:5,padding:"5px 8px",borderBottom:`1px solid ${c.borderLight}`}}>
<button onClick={()=>flash("Create collection…")} style={{width:18,height:18,borderRadius:"50%",border:`1.5px dashed ${c.border}`,backgroundColor:"transparent",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}><I.Plus size={9} color={c.textTer}/></button>
{collections.map(col=>{const sel=selectedCollections.has(col.name);return <button key={col.name} title={`${col.name}${sel?" (active)":""}`} onClick={()=>toggleCollection(col.name)} style={{width:18,height:18,borderRadius:"50%",backgroundColor:col.color,border:sel?`2px solid ${c.textPri}`:"2px solid transparent",cursor:"pointer",flexShrink:0,opacity:sel?1:.6,transform:sel?"scale(1.1)":"scale(1)",transition:"all .15s"}}/>})}
{selectedCollections.size>0&&<button onClick={()=>setSelectedCollections(new Set())} style={{border:"none",backgroundColor:"transparent",cursor:"pointer",color:c.textTer,fontSize:9,fontFamily:font.sans}}>clear</button>}
</div>
{/* Scope chips + folder overlay toggle */}
<div style={{display:"flex",flexWrap:"wrap",gap:2,padding:"5px 8px",borderBottom:`1px solid ${c.borderLight}`,alignItems:"center"}}>
{scopeFams.map(s=><button key={s} onClick={()=>selectScope(s)} style={{padding:"2px 8px",borderRadius:3,border:`1px solid ${activeScope===s?c.accentBtn+"60":c.borderLight}`,backgroundColor:activeScope===s?c.accentBtn+"10":"transparent",fontSize:10,fontWeight:activeScope===s?600:400,color:activeScope===s?c.accentBtn:c.textTer,cursor:"pointer",fontFamily:font.sans,height:20}}>{s}</button>)}
<div style={{flex:1}}/>
<button onClick={()=>setFolderOverlay(!folderOverlay)} title="Show folders overlay (drag items here)" style={{padding:"2px 7px",borderRadius:3,border:`1px dashed ${folderOverlay?c.accentBtn:c.border}`,backgroundColor:folderOverlay?c.accentBtn+"10":"transparent",fontSize:9.5,fontWeight:folderOverlay?600:400,color:folderOverlay?c.accentBtn:c.textTer,cursor:"pointer",fontFamily:font.sans,height:20,display:"flex",alignItems:"center",gap:3}}><I.Folder size={9}/>Folders</button>
</div>
{/* Scope detail */}
<div style={{height:splitterPos,flexShrink:0,overflowY:"auto",borderBottom:`1px solid ${c.borderLight}`}}>
{activeScope===null&&<div style={{padding:12,fontSize:11,color:c.textTer,fontStyle:"italic"}}>No scope — showing all items</div>}
{activeScope==="Project"&&<div style={{padding:"3px 4px"}}>
{projects.map((p,i)=><button key={p.id} onClick={()=>{setActiveProjIdx(i);setNoProject(false)}} style={{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"4px 8px",borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:!noProject&&activeProjIdx===i?c.accentBtn+"10":"transparent",fontFamily:font.sans,textAlign:"left"}}><span style={{width:7,height:7,borderRadius:"50%",backgroundColor:p.color,flexShrink:0}}/><span style={{fontSize:11.5,fontWeight:!noProject&&activeProjIdx===i?600:400,color:!noProject&&activeProjIdx===i?c.textPri:c.textSec,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{p.name}</span></button>)}
<button onClick={()=>setNoProject(true)} style={{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"4px 8px",border:"none",cursor:"pointer",backgroundColor:noProject?c.accentBtn+"10":"transparent",fontFamily:font.sans,borderRadius:R.sm}}><span style={{width:7,height:7,borderRadius:"50%",border:`1px dashed ${noProject?c.accentBtn:c.textTer}`,flexShrink:0}}/><span style={{fontSize:11,color:noProject?c.accentBtn:c.textTer,fontWeight:noProject?600:400}}>No Project</span></button>
</div>}
{activeScope==="Folders"&&<div style={{padding:"3px 4px"}}>
<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"2px 8px 6px"}}><span style={{fontSize:10,fontWeight:600,color:c.textTer,textTransform:"uppercase",letterSpacing:".06em"}}>Folders</span><button onClick={()=>{setNewFolderMode({parent:null});setNewFolderName("");setTimeout(()=>nfRef.current?.focus(),50)}} style={{padding:"1px 6px",borderRadius:R.sm,border:`1px solid ${c.border}`,backgroundColor:"transparent",cursor:"pointer",fontSize:9,color:c.accentBtn,fontFamily:font.sans,display:"flex",alignItems:"center",gap:2}}><I.Plus size={8}/>New</button></div>
{newFolderMode&&newFolderMode.parent===null&&<div style={{display:"flex",alignItems:"center",gap:4,padding:"3px 8px",marginBottom:4}}><I.Folder size={11} color={c.warn}/><input ref={nfRef} value={newFolderName} onChange={e=>setNewFolderName(e.target.value)} placeholder="Folder name…" onKeyDown={e=>{if(e.key==="Enter")createFolder(null);if(e.key==="Escape"){setNewFolderMode(null);setNewFolderName("")}}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/></div>}
{renderFolderTree(null,0,false)}
</div>}
{activeScope==="Places"&&<div style={{padding:"3px 4px"}}>
<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"2px 8px 6px"}}><span style={{fontSize:10,fontWeight:600,color:c.textTer,textTransform:"uppercase",letterSpacing:".06em"}}>Places</span><button onClick={()=>flash("Opening Finder…")} style={{padding:"1px 6px",borderRadius:R.sm,border:`1px solid ${c.border}`,backgroundColor:"transparent",cursor:"pointer",fontSize:9,color:c.accentBtn,fontFamily:font.sans,display:"flex",alignItems:"center",gap:2}}><I.Plus size={8}/>Add</button></div>
{places.map((p,i)=><div key={p.id} onMouseEnter={()=>setHoverPlace(p.id)} onMouseLeave={()=>setHoverPlace(null)} style={{display:"flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:R.sm,cursor:"pointer",backgroundColor:activePlace===i?c.accentBtn+"10":"transparent",opacity:p.status==="missing"?.5:1}}>
<div onClick={()=>{setActivePlace(i);setPlacePath([])}} style={{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0}}>
<I.Folder size={12} color={activePlace===i?c.accentBtn:c.textTer}/>
<div style={{flex:1,minWidth:0}}><div style={{fontSize:11.5,fontWeight:activePlace===i?600:400,color:activePlace===i?c.accentBtn:c.textSec,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{p.title}</div><div style={{fontSize:9,color:c.textTer,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{p.path}</div></div>
</div>
{hoverPlace===p.id&&removingPlace!==p.id&&<span onClick={()=>setRemovingPlace(p.id)} style={{cursor:"pointer",display:"flex",color:c.textTer,flexShrink:0}} title="Remove place"><I.X size={10}/></span>}
{removingPlace===p.id&&<span style={{display:"flex",gap:3,fontSize:9,flexShrink:0}} onClick={e=>e.stopPropagation()}>
<span style={{color:c.error,fontWeight:600}}>Remove?</span>
<span style={{color:c.error,cursor:"pointer",fontWeight:700,textDecoration:"underline"}} onClick={()=>removePlace(p.id)}>Yes</span>
<span style={{color:c.textTer,cursor:"pointer"}} onClick={()=>setRemovingPlace(null)}>No</span>
</span>}
{removingPlace!==p.id&&hoverPlace!==p.id&&<span style={{fontSize:8,padding:"1px 5px",borderRadius:R.full,backgroundColor:p.status==="ok"?c.green+"15":c.error+"15",color:p.status==="ok"?c.green:c.error,fontWeight:600,flexShrink:0}}>{p.status}</span>}
</div>)}
</div>}
{activeScope==="Saved Views"&&<div style={{padding:"3px 4px"}}>
<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"2px 8px 6px"}}><span style={{fontSize:10,fontWeight:600,color:c.textTer,textTransform:"uppercase",letterSpacing:".06em"}}>Saved Views</span><button onClick={()=>{setSaveViewMode(true);setSaveViewName("")}} style={{padding:"1px 6px",borderRadius:R.sm,border:`1px solid ${c.border}`,backgroundColor:"transparent",cursor:"pointer",fontSize:9,color:c.accentBtn,fontFamily:font.sans,display:"flex",alignItems:"center",gap:2}}><I.Save size={8}/>Save</button></div>
{saveViewMode&&<div style={{margin:"0 8px 6px",display:"flex",gap:3}}><input value={saveViewName} onChange={e=>setSaveViewName(e.target.value)} placeholder="View name…" autoFocus onKeyDown={e=>{if(e.key==="Enter"&&saveViewName.trim()){setUserSavedViews(p=>[...p,{id:"usv"+p.length,name:saveViewName.trim()}]);flash(`"${saveViewName}" saved`);setSaveViewMode(false)}if(e.key==="Escape")setSaveViewMode(false)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/><button onClick={()=>setSaveViewMode(false)} style={{padding:"1px 6px",border:`1px solid ${c.border}`,borderRadius:3,backgroundColor:"transparent",cursor:"pointer",fontSize:9,color:c.textTer,fontFamily:font.sans}}>Cancel</button></div>}
{savedViews.map(sv=><button key={sv.id} onClick={()=>setActiveSavedView(activeSavedView===sv.id?null:sv.id)} style={{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"4px 8px",borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:activeSavedView===sv.id?c.accentBtn+"10":"transparent",fontFamily:font.sans,textAlign:"left"}}><span style={{fontSize:11.5,fontWeight:activeSavedView===sv.id?600:400,color:activeSavedView===sv.id?c.accentBtn:c.textSec,flex:1}}>{sv.name}</span><span style={{fontSize:8,color:c.textTer,padding:"1px 4px",borderRadius:2,backgroundColor:c.bgInput}}>built-in</span></button>)}
{userSavedViews.map(sv=><div key={sv.id} onMouseEnter={()=>setHoverSavedView(sv.id)} onMouseLeave={()=>setHoverSavedView(null)} style={{display:"flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:R.sm,cursor:"pointer",backgroundColor:activeSavedView===sv.id?c.accentBtn+"10":"transparent"}}><span onClick={()=>setActiveSavedView(activeSavedView===sv.id?null:sv.id)} style={{fontSize:11.5,fontWeight:activeSavedView===sv.id?600:400,color:activeSavedView===sv.id?c.accentBtn:c.textSec,flex:1}}>{sv.name}</span>{hoverSavedView===sv.id&&<><span onClick={()=>flash("Rename…")} style={{fontSize:9,color:c.textTer,cursor:"pointer"}}>rename</span><span onClick={()=>{setUserSavedViews(p=>p.filter(v=>v.id!==sv.id));flash("Deleted")}} style={{fontSize:9,color:c.error,cursor:"pointer"}}>delete</span></>}</div>)}
</div>}
{activeScope&&!["Project","Folders","Places","Saved Views"].includes(activeScope)&&<div style={{padding:12,fontSize:11,color:c.textTer,fontStyle:"italic"}}>{activeScope}…</div>}
</div>
{/* Splitter */}
<div style={{height:4,cursor:"row-resize",backgroundColor:c.borderLight,flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center"}} onMouseDown={e=>{const sY=e.clientY,sP=splitterPos;const m=ev=>setSplitterPos(Math.max(60,Math.min(250,sP+(ev.clientY-sY))));const u=()=>{document.removeEventListener("mousemove",m);document.removeEventListener("mouseup",u)};document.addEventListener("mousemove",m);document.addEventListener("mouseup",u)}}><div style={{width:20,height:2,borderRadius:1,backgroundColor:c.textTer,opacity:.25}}/></div>
{/* ═══ FOLDER OVERLAY — persistent across scopes ═══ */}
{folderOverlay&&activeScope!=="Folders"&&<div style={{maxHeight:90,overflowY:"auto",borderBottom:`1px solid ${c.accentBtn}30`,backgroundColor:c.accentBtn+"04",padding:"3px 0",flexShrink:0}}>
<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"1px 8px 3px"}}><span style={{fontSize:9,fontWeight:600,color:c.accentBtn,textTransform:"uppercase",letterSpacing:".06em"}}>Drag items to folders</span><button onClick={()=>setFolderOverlay(false)} style={{border:"none",backgroundColor:"transparent",cursor:"pointer",display:"flex",color:c.textTer}}><I.X size={9}/></button></div>
{renderFolderTree(null,0,true)}
</div>}
{/* Type chips */}
<div style={{display:"flex",flexWrap:"wrap",gap:2,padding:"4px 8px",borderBottom:`1px solid ${c.borderLight}`}}>
{typeChips.map(t=><button key={t} onClick={()=>toggleType(t)} style={{padding:"1px 6px",borderRadius:3,border:`1px solid ${activeTypes.has(t)?c.accentBtn+"50":c.borderLight}`,backgroundColor:activeTypes.has(t)?c.accentBtn+"10":"transparent",fontSize:9.5,fontWeight:activeTypes.has(t)?600:400,color:activeTypes.has(t)?c.accentBtn:c.textTer,cursor:"pointer",fontFamily:font.sans,height:18}}>{t}</button>)}
{activeTypes.size>0&&<button onClick={()=>setActiveTypes(new Set())} style={{padding:"1px 6px",borderRadius:3,border:"none",cursor:"pointer",fontSize:9,color:c.textTer,fontFamily:font.sans,height:18}}>clear</button>}
</div>
{/* Filter/Sort bar + save view */}
<div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"3px 8px",borderBottom:`1px solid ${c.borderLight}`,fontSize:9.5,color:c.textTer}}>
<span>{activeScope==="Places"&&activePlace!==null?currentPlaceFiles().length:filtered.length} items</span>
<div style={{display:"flex",alignItems:"center",gap:6}}>
<button onClick={()=>{setSaveFromBar(true);setSaveViewName("")}} title="Save view" style={{padding:2,border:"none",cursor:"pointer",backgroundColor:"transparent",display:"flex",color:c.textTer}} onMouseEnter={e=>e.currentTarget.style.color=c.accentBtn} onMouseLeave={e=>e.currentTarget.style.color=c.textTer}><I.Save size={11}/></button>
<div style={{position:"relative"}}><span style={{cursor:"pointer"}} onClick={e=>{e.stopPropagation();setSortDrop(!sortDrop)}}>{sortKey} ▾</span>
{sortDrop&&<div onClick={e=>e.stopPropagation()} style={{position:"absolute",top:16,right:0,backgroundColor:c.bgCard,border:`1px solid ${c.border}`,borderRadius:R.sm,boxShadow:"0 4px 12px rgba(0,0,0,0.1)",zIndex:50,minWidth:120,padding:3}}>
{sortOptions.map(s=><button key={s} onClick={()=>{setSortKey(s);setSortDrop(false)}} style={{display:"block",width:"100%",padding:"5px 10px",border:"none",cursor:"pointer",backgroundColor:s===sortKey?c.accentBtn+"08":"transparent",fontSize:11,color:s===sortKey?c.accentBtn:c.textPri,textAlign:"left",borderRadius:R.sm,fontFamily:font.sans,fontWeight:s===sortKey?600:400}}>{s}{s===sortKey&&" ✓"}</button>)}
</div>}</div>
</div>
</div>
{saveFromBar&&<div style={{display:"flex",alignItems:"center",gap:4,padding:"4px 8px",borderBottom:`1px solid ${c.borderLight}`,backgroundColor:c.accentBtn+"06"}}>
<I.Save size={10} color={c.accentBtn}/><input value={saveViewName} onChange={e=>setSaveViewName(e.target.value)} placeholder="View name…" autoFocus onKeyDown={e=>{if(e.key==="Enter"&&saveViewName.trim()){setUserSavedViews(p=>[...p,{id:"usv"+p.length,name:saveViewName.trim()}]);flash(`"${saveViewName}" saved`);setSaveFromBar(false)}if(e.key==="Escape")setSaveFromBar(false)}} style={{flex:1,border:`1px solid ${c.accentBtn}40`,borderRadius:3,padding:"2px 6px",fontSize:11,fontFamily:font.sans,outline:"none",backgroundColor:c.bgCard}}/>
<button onClick={()=>{if(saveViewName.trim()){setUserSavedViews(p=>[...p,{id:"usv"+p.length,name:saveViewName.trim()}]);flash(`Saved`)}setSaveFromBar(false)}} style={{padding:"2px 8px",borderRadius:R.sm,border:"none",backgroundColor:c.accentBtn,color:"#fff",cursor:"pointer",fontSize:10,fontFamily:font.sans}}>Save</button>
<button onClick={()=>setSaveFromBar(false)} style={{padding:"2px 6px",borderRadius:R.sm,border:`1px solid ${c.border}`,backgroundColor:"transparent",cursor:"pointer",fontSize:10,color:c.textTer,fontFamily:font.sans}}>Cancel</button>
</div>}
{/* Results */}
<div style={{flex:1,overflowY:"auto"}}>
{activeScope==="Places"&&activePlace!==null?<div>
<div style={{display:"flex",alignItems:"center",gap:4,padding:"6px 8px",borderBottom:`1px solid ${c.borderLight}`,fontSize:10,color:c.textTer,flexWrap:"wrap"}}>
<span style={{cursor:"pointer",color:c.accentBtn,fontWeight:600,fontSize:11}} onClick={()=>setPlacePath([])}>← {places[activePlace]?.title}</span>
{placePath.map((p,i)=><span key={i} style={{display:"flex",alignItems:"center",gap:3}}><span>/</span><span style={{cursor:"pointer",color:i===placePath.length-1?c.textPri:c.accentBtn,fontWeight:i===placePath.length-1?600:400}} onClick={()=>setPlacePath(placePath.slice(0,i+1))}>{p}</span></span>)}
</div>
{currentPlaceFiles().filter(f=>f.isFolder).map((f,i)=><div key={"d"+i} onClick={()=>setPlacePath([...placePath,f.name])} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 8px",height:34,borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer",backgroundColor:c.bgPanelAlt+"80"}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.accentBtn+"06"} onMouseLeave={e=>e.currentTarget.style.backgroundColor=c.bgPanelAlt+"80"}><I.Folder size={13} color={c.warn}/><span style={{flex:1,fontSize:12,fontWeight:600}}>{f.name}</span><I.ChevR size={10} color={c.textTer}/></div>)}
{currentPlaceFiles().filter(f=>!f.isFolder).map((f,i)=><div key={"f"+i} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 8px",height:32,borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer",opacity:f.dimmed?.35:1}}><I.File size={12} color={c.textTer}/><span style={{flex:1,fontSize:11.5,fontWeight:450,color:c.textSec,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{f.name}</span><span style={{fontSize:8,padding:"1px 5px",borderRadius:3,backgroundColor:c.bgInput,color:c.textTer}}>{f.type}</span><span style={{fontSize:8.5,color:c.textTer,minWidth:40,textAlign:"right"}}>{f.size}</span><span style={{fontSize:9,color:c.textTer}}>{f.mod}</span></div>)}
</div>
:<>{filtered.map((item,i)=><div key={i}
draggable onDragStart={()=>setDragItem(item.title)} onDragEnd={()=>setDragItem(null)}
onClick={()=>setSelectedIdx(i)} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 8px",height:32,borderBottom:`1px solid ${c.borderLight}`,cursor:folderOverlay?"grab":"pointer",backgroundColor:selectedIdx===i?c.accentBtn+"08":"transparent"}} onMouseEnter={e=>{if(selectedIdx!==i)e.currentTarget.style.backgroundColor=c.bgPanelAlt}} onMouseLeave={e=>{if(selectedIdx!==i)e.currentTarget.style.backgroundColor="transparent"}}>
{item.pin&&<I.Pin size={8} color={c.warn}/>}
{item.unread&&<Dot color={c.accentBtn} size={4}/>}
<span style={{flex:1,minWidth:0,fontSize:11.5,fontWeight:item.unread?600:450,color:c.textPri,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{item.title}</span>
{item.st&&<span style={{fontSize:8.5,fontWeight:600,color:item.st==="running"?c.accentBtn:c.warn,textTransform:"uppercase",flexShrink:0}}>{item.st}</span>}
<span style={{fontSize:8.5,fontWeight:600,color:typeColors[item.type]||c.textTer,textTransform:"uppercase",letterSpacing:".03em",flexShrink:0,minWidth:28,textAlign:"right"}}>{item.type}</span>
<span style={{fontSize:9,color:c.textTer,flexShrink:0,minWidth:18,textAlign:"right"}}>{item.time}</span>
</div>)}
{filtered.length===0&&<div style={{padding:16,fontSize:11,color:c.textTer,textAlign:"center",fontStyle:"italic"}}>No items match</div>}
</>}
</div>
{/* Browser footer */}
<div style={{padding:"3px 8px",borderTop:`1px solid ${c.borderLight}`,fontSize:9,color:c.textTer,display:"flex",gap:4,flexWrap:"wrap",flexShrink:0}}>
{activeScope?<span>{activeScope}</span>:<span>All</span>}
{activeScope==="Project"&&!noProject&&<span>· {projects[activeProjIdx].name}</span>}
{activeScope==="Project"&&noProject&&<span>· No Project</span>}
{selectedCollections.size>0&&<span>· {[...selectedCollections].join(", ")}</span>}
{activeTypes.size>0&&<span>· {[...activeTypes].join(", ")}</span>}
{folderOverlay&&<span style={{color:c.accentBtn}}>· 📁 Folders</span>}
<span style={{marginLeft:"auto"}}>{sortKey}</span>
</div>
<div style={{position:"absolute",top:0,right:0,width:4,height:"100%",cursor:"col-resize"}} onMouseDown={e=>{const sX=e.clientX,sW=browserWidth;const m=ev=>setBrowserWidth(Math.max(200,Math.min(450,sW+(ev.clientX-sX))));const u=()=>{document.removeEventListener("mousemove",m);document.removeEventListener("mouseup",u)};document.addEventListener("mousemove",m);document.addEventListener("mouseup",u)}}/>
</div>
<div style={{flex:1,display:"flex",flexDirection:"column"}}>
<div style={{padding:"12px 16px",borderBottom:`1px solid ${c.border}`,backgroundColor:c.bgPanel}}><span style={{fontSize:15,fontWeight:700}}>Browser R1.3</span></div>
<div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",padding:32}}>
<div style={{maxWidth:460,fontSize:12.5,color:c.textSec,lineHeight:1.7}}>
<p style={{marginBottom:8}}>• <strong>Folder overlay</strong> — click the dashed "📁 Folders" button at the end of the scope chip row. A compact folder tree appears above the type chips. Drag items from the results list onto folders. Works in any scope — Project, search, type filters all stay active while the overlay is visible. Click X to hide.</p>
<p style={{marginBottom:8}}>• <strong>Remove places</strong> — hover a place in Places scope → X icon appears. Click → "Remove? Yes/No" inline confirmation. Files aren't deleted, just the alias is removed.</p>
<p style={{marginBottom:8}}>• <strong>Delete folders</strong> — hover a folder in Folders scope → trash icon appears (next to the + subfolder icon). Click → "Delete? Yes/No" confirmation. Items inside become unfiled. Subfolders are also deleted.</p>
<p style={{marginBottom:8}}>• <strong>Drag to folder</strong> — when folder overlay is active, result items show a grab cursor. Drag onto a folder name — it highlights with a dashed blue border. Drop to assign. Toast confirms.</p>
<p>• All previous features: scope deselection, sort, collections, save view from anywhere, Prompt/Artifact types.</p>
</div>
</div>
</div>
</div>
);
}