Elnor Repo Reader

Q_WORKSPACE_V4_1 (1).jsx

Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/DOC20 Workspace Redo/Q_WORKSPACE_V4_1 (1).jsx

Short text page d6e05b9d9111. Generated 2026-06-09T01:23:58.539Z from commit dbaa25962edc11ab30e8d4ca1715f9ae5bf77331. Worktree: clean.

Open readable HTML page · Open raw txt · Open path URL

ELNOR REPO READER TEXT MIRROR
Original path: Design Mockups/Archived Mockups/DOC20 Mockups and Design/DOC20 Archived Mockups/DOC20 Workspace Redo/Q_WORKSPACE_V4_1 (1).jsx
Source repo: /Users/OpenClaw1/Elnor/Elnor Specs
Git branch: main
Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331
Generated: 2026-06-09T01:23:58.539Z

---

import { useState, useRef, useCallback, useEffect } from "react";
const font={sans:"'Söhne','Helvetica Neue',-apple-system,BlinkMacSystemFont,sans-serif"};
const R={sm:"6px",md:"10px",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",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={Plus:p=><Ic {...p} d="M12 5v14 M5 12h14"/>,X:p=><Ic {...p} d="M18 6L6 18 M6 6l12 12"/>,Check:p=><Ic {...p} d="M20 6L9 17l-5-5"/>,Pin:p=><Ic {...p} d="M12 17v5 M9 2l.5 5L7 10l1.5 3h7L17 10l-2.5-3L15 2"/>,Spark:p=><Ic {...p} d="M12 2l1.5 4.5L18 8l-4.5 1.5L12 14l-1.5-4.5L6 8l4.5-1.5L12 2z M12 14l1 3 3 1-3 1-1 3-1-3-3-1 3-1 1-3z"/>,MsgCircle:p=><Ic {...p} d="M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z"/>,ChevD:p=><Ic {...p} d="M6 9l6 6 6-6"/>,ChevR:p=><Ic {...p} d="M9 18l6-6-6-6"/>,Search:p=><Ic {...p} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>,Maximize:p=><Ic {...p} d="M8 3H5a2 2 0 00-2 2v3m18 0V5a2 2 0 00-2-2h-3m0 18h3a2 2 0 002-2v-3M3 16v3a2 2 0 002 2h3"/>,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"/>,Copy:p=><Ic {...p} d="M20 9h-9a2 2 0 00-2 2v9a2 2 0 002 2h9a2 2 0 002-2v-9a2 2 0 00-2-2z M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>,Link:p=><Ic {...p} d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71 M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/>,Eye:p=><Ic {...p} d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z M12 9a3 3 0 100 6 3 3 0 000-6z"/>,Edit:p=><Ic {...p} d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7 M18.5 2.5a2.12 2.12 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/>,Undo:p=><Ic {...p} d="M3 7v6h6 M21 17a9 9 0 00-9-9 9 9 0 00-6.69 3L3 13"/>,Redo:p=><Ic {...p} d="M21 7v6h-6 M3 17a9 9 0 019-9 9 9 0 016.69 3L21 13"/>,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"/>,FileText:p=><Ic {...p} d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6 M16 13H8 M16 17H8"/>,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"/>,Settings:p=><Ic {...p} d="M12 15a3 3 0 100-6 3 3 0 000 6z"/>,List:p=><Ic {...p} d="M8 6h13 M8 12h13 M8 18h13 M3 6h.01 M3 12h.01 M3 18h.01"/>,Bell:p=><Ic {...p} d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9 M13.73 21a2 2 0 01-3.46 0"/>,Calendar:p=><Ic {...p} d="M19 4H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2z M16 2v4 M8 2v4 M3 10h18"/>,Mail:p=><Ic {...p} d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z M22 6l-10 7L2 6"/>,Zap:p=><Ic {...p} d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>,Sun:p=><Ic {...p} d="M12 17a5 5 0 100-10 5 5 0 000 10z M12 1v2 M12 21v2 M4.22 4.22l1.42 1.42 M18.36 18.36l1.42 1.42 M1 12h2 M21 12h2"/>,Grip:p=><Ic {...p} d="M9 4h.01M9 9h.01M9 14h.01M9 19h.01M15 4h.01M15 9h.01M15 14h.01M15 19h.01" sw={3}/>,};
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 Btn=({children,primary,ghost,small,onClick,disabled,style:s})=><button onClick={disabled?undefined:onClick} style={{padding:small?"2px 8px":"5px 14px",borderRadius:R.sm,border:primary?"none":ghost?`1.5px solid ${c.border}`:`1px solid ${c.border}`,backgroundColor:primary?(disabled?c.accentBtn+"60":c.accentBtn):"transparent",color:primary?"#fff":c.textSec,fontSize:small?11:12.5,fontWeight:primary?550:450,cursor:disabled?"not-allowed":"pointer",fontFamily:font.sans,display:"flex",alignItems:"center",gap:5,height:small?22:28,opacity:disabled?.5:1,...s}}>{children}</button>;
const Av=({letter,color,size=20})=><div style={{width:size,height:size,borderRadius:R.sm,backgroundColor:color||c.accentBtn,color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:size*.42,fontWeight:700,flexShrink:0}}>{letter}</div>;
const TBtn=({icon,title,active,onClick,label,dropdown})=><button onClick={onClick} title={title} style={{padding:label?"3px 8px":"3px 6px",borderRadius:R.sm,border:`1px solid ${active?c.accentBtn+"40":c.borderLight}`,backgroundColor:active?c.accentBtn+"08":"transparent",cursor:"pointer",display:"flex",alignItems:"center",gap:4,color:active?c.accentBtn:c.textSec,fontFamily:font.sans,fontSize:10.5,fontWeight:active?600:450,height:26}} onMouseEnter={e=>{if(!active)e.currentTarget.style.backgroundColor=c.bgInput}} onMouseLeave={e=>{e.currentTarget.style.backgroundColor=active?c.accentBtn+"08":"transparent"}}>{icon}{label&&<span>{label}</span>}{dropdown&&<I.ChevD size={8}/>}</button>;
const Sep=()=><div style={{width:1,height:18,backgroundColor:c.borderLight,margin:"0 3px",flexShrink:0}}/>;
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.sm,fontSize:12,fontWeight:500,fontFamily:font.sans,zIndex:9999,boxShadow:"0 4px 16px rgba(0,0,0,0.2)"}}>{msg}</div>};
const DItem=({children,onClick,active})=><button onClick={onClick} style={{display:"flex",alignItems:"center",gap:6,width:"100%",padding:"6px 10px",border:"none",cursor:"pointer",backgroundColor:active?c.accentBtn+"08":"transparent",fontSize:11.5,color:c.textPri,textAlign:"left",borderRadius:R.sm,fontFamily:font.sans,fontWeight:active?600:400}} onMouseEnter={e=>{if(!active)e.currentTarget.style.backgroundColor=c.bgInput}} onMouseLeave={e=>{if(!active)e.currentTarget.style.backgroundColor=active?c.accentBtn+"08":"transparent"}}>{children}</button>;

const agents=[{name:"Elnor",color:c.agentAv,letter:"E"}];

// ═══ BLOCK DATA ═══
const initBlocks=[
  {id:"b0",type:"bar",icon:"mail",title:"📧 Email from Sparacino received — Narayanan agreement redline",time:"2:15 PM",accent:c.accentBtn},
  {id:"b1",type:"text",content:"Quick note: need to confirm with Danny that he's available for the May trial week before filing the expert disclosure. Call him today."},
  {id:"b2",type:"tasks",title:"To Do",collapsed:false,tasks:[
    {id:"t1",text:"Draft expert disclosure for Christensen",done:false,due:"Apr 4",link:"Expert Depo Prep",sub:[{id:"s1",text:"Pull Christensen CV",done:true},{id:"s2",text:"List opinions to be offered",done:false},{id:"s3",text:"Identify documents reviewed",done:false}]},
    {id:"t2",text:"Review Henderson MSJ brief — Elnor's tracked changes",done:false,due:"Mar 20",link:"Henderson Discovery Priorities"},
    {id:"t3",text:"Respond to Sparacino re: Narayanan agreement",done:false,due:"Mar 19"},
    {id:"t4",text:"Follow up: opposing counsel on discovery extension",done:false,due:"Mar 19"},
    {id:"t5",text:"Review Quark patent analysis — new filings",done:false,link:"Quark Patent Analysis"},
    {id:"t6",text:"File Folb trial exhibit list",done:true,due:"Mar 17"},
  ]},
  {id:"b3",type:"thread",collapsed:false,contextQuote:"opposing counsel on discovery extension",messages:[
    {id:"m1",author:"You",color:c.accentBtn,body:"@Elnor draft a response declining the extension, cite the scheduling order deadline and the prejudice from further delay",time:"45m"},
    {id:"m2",author:"Elnor",color:c.agentAv,body:"Draft ready. Key points: scheduling order set discovery cutoff March 28, extension would prejudice plaintiff's expert disclosure timeline, defendant has had 4 months to complete discovery. Want me to open it in a new note or paste below?",time:"40m"},
  ]},
  {id:"b4",type:"text",content:"Call with Sparacino re: Narayanan — need to confirm NY vs CA choice of law for the restrictive covenant. NY probably governs but CA may void it entirely under Bus & Prof Code § 16600."},
  {id:"b5",type:"feed",title:"Activity Brief",collapsed:false,sections:[
    {key:"elnor",icon:"spark",label:"Elnor",items:[
      {text:"Reviewed 3 Henderson depo transcripts — flagged 2 citation issues in Chen depo",time:"5h"},
      {text:"Updated Quark patent landscape — 4 new filings",time:"4h"},
      {text:"Scanned SEC filings — no new Henderson-relevant 10-K amendments",time:"3h"},
    ]},
    {key:"calendar",icon:"calendar",label:"Deadlines",items:[
      {text:"Expert disclosure deadline — Folb v. City of LA",time:"47d",accent:c.error},
      {text:"Henderson MSJ response due",time:"12d",accent:c.warn},
      {text:"Danny Christensen engagement call",time:"Tomorrow 2pm"},
    ]},
    {key:"email",icon:"mail",label:"Email",items:[
      {text:"Sparacino — Narayanan agreement redline",time:"Yesterday"},
      {text:"Opposing counsel — discovery extension request",time:"2d",accent:c.warn},
    ]},
    {key:"system",icon:"bell",label:"System",items:[
      {text:"OneDrive sync paused — re-auth needed",time:"6h",accent:c.warn},
      {text:"DOC15 red-team review completed — 3 findings flagged",time:"2h",accent:c.green},
    ]},
  ]},
  {id:"b6",type:"text",content:""},
];

const feedIcons={spark:<I.Spark size={11} color={c.agentAv}/>,calendar:<I.Calendar size={11} color={c.error}/>,mail:<I.Mail size={11} color={c.accentBtn}/>,bell:<I.Bell size={11} color={c.warn}/>,zap:<I.Zap size={11} color={c.green}/>};

// ═══ MAIN ═══
export default function WorkspaceV4_1(){
  const idC=useRef(500);const nid=()=>"x"+(++idC.current);
  const [browserOpen,setBrowserOpen]=useState(true);
  const [noteListOpen,setNoteListOpen]=useState(true);
  const [commentsOpen,setCommentsOpen]=useState(false);
  const [rightTab,setRightTab]=useState("comments");
  const [findBar,setFindBar]=useState(false);
  const [fullScreen,setFullScreen]=useState(false);
  const [openDrop,setOpenDrop]=useState(null);
  const [toast,setToast]=useState(null);
  const [blocks,setBlocks]=useState(initBlocks);
  const [expandedTask,setExpandedTask]=useState(null);
  const [threadReplyId,setThreadReplyId]=useState(null);
  const [threadReplyText,setThreadReplyText]=useState("");
  const [newTaskText,setNewTaskText]=useState("");
  const [newSubText,setNewSubText]=useState({});// keyed by taskId
  const [inserterAt,setInserterAt]=useState(null); // index where + was clicked
  const [bubbleMenu,setBubbleMenu]=useState(null);
  const [collapsedFeeds,setCollapsedFeeds]=useState(new Set());
  const editorRef=useRef(null);
  const agent=agents[0];const flash=msg=>setToast(msg);

  const toggleBlock=(id,field="collapsed")=>setBlocks(p=>p.map(b=>b.id===id?{...b,[field]:!b[field]}:b));
  const toggleTask=(blockId,taskId)=>setBlocks(p=>p.map(b=>b.id===blockId?{...b,tasks:b.tasks.map(t=>t.id===taskId?{...t,done:!t.done}:t)}:b));
  const toggleSub=(blockId,taskId,subId)=>setBlocks(p=>p.map(b=>b.id===blockId?{...b,tasks:b.tasks.map(t=>t.id===taskId?{...t,sub:t.sub.map(s=>s.id===subId?{...s,done:!s.done}:s)}:t)}:b));
  const dismissAlert=id=>setBlocks(p=>p.filter(b=>b.id!==id));
  const addThreadReply=(blockId)=>{if(!threadReplyText.trim())return;setBlocks(p=>p.map(b=>b.id===blockId?{...b,messages:[...b.messages,{id:nid(),author:"You",color:c.accentBtn,body:threadReplyText.trim(),time:"now"}]}:b));setThreadReplyId(null);setThreadReplyText("")};
  const toggleFeedSection=key=>{const s=new Set(collapsedFeeds);s.has(key)?s.delete(key):s.add(key);setCollapsedFeeds(s)};
  const insertBlock=(idx,type)=>{const newId=nid();let block;
    if(type==="tasks")block={id:newId,type:"tasks",title:"New Task List",collapsed:false,tasks:[]};
    else if(type==="feed")block={id:newId,type:"feed",title:"New Feed",collapsed:false,sections:[{key:"custom",icon:"spark",label:"Custom",items:[]}]};
    else if(type==="thread")block={id:newId,type:"thread",collapsed:false,contextQuote:"",messages:[{id:nid(),author:"You",color:c.accentBtn,body:"@Elnor ",time:"now"}]};
    else if(type==="bar")block={id:newId,type:"bar",icon:"bell",title:"New notice — click Elnor to configure",accent:c.warn};
    else block={id:newId,type:"text",content:""};
    setBlocks(p=>{const n=[...p];n.splice(idx,0,block);return n});setInserterAt(null);flash(`${type} block added`)};

  const handleMouseUp=useCallback(e=>{if(e.target.closest("[data-bubble]"))return;const sel=window.getSelection();if(!sel||sel.isCollapsed||!sel.toString().trim()){setBubbleMenu(null);return}const text=sel.toString().trim();if(text.length<3)return;const rect=sel.getRangeAt(0).getBoundingClientRect();const er=editorRef.current?.getBoundingClientRect();if(!er)return;setBubbleMenu({x:rect.left-er.left+rect.width/2,y:rect.top-er.top-8,text})},[]);
  const dismissBubble=()=>{setBubbleMenu(null);window.getSelection()?.removeAllRanges()};

  // ─── Block Inserter ───
  const BlockInserter=({idx})=>{
    const [hover,setHover]=useState(false);
    return <div style={{position:"relative",height:hover||inserterAt===idx?20:8,display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",transition:"height 0.1s"}} onMouseEnter={()=>setHover(true)} onMouseLeave={()=>{if(inserterAt!==idx)setHover(false)}}>
      {(hover||inserterAt===idx)&&<><div style={{position:"absolute",left:0,right:0,top:"50%",height:1,backgroundColor:c.accentBtn+"30"}}/><button onClick={()=>setInserterAt(inserterAt===idx?null:idx)} style={{position:"relative",zIndex:2,width:20,height:20,borderRadius:"50%",border:`1.5px solid ${c.accentBtn}40`,backgroundColor:c.bgCard,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 4px rgba(0,0,0,0.08)"}}><I.Plus size={11} color={c.accentBtn}/></button></>}
      {inserterAt===idx&&<div style={{position:"absolute",top:22,left:"50%",transform:"translateX(-50%)",backgroundColor:c.bgCard,border:`1px solid ${c.border}`,borderRadius:R.sm,boxShadow:"0 6px 20px rgba(0,0,0,0.12)",zIndex:100,padding:4,minWidth:160}}>
        <DItem onClick={()=>insertBlock(idx,"text")}><I.FileText size={12} color={c.textTer}/>Text</DItem>
        <DItem onClick={()=>insertBlock(idx,"tasks")}><I.List size={12} color={c.warn}/>Task List</DItem>
        <DItem onClick={()=>insertBlock(idx,"feed")}><I.Spark size={12} color={c.agentAv}/>Activity Feed</DItem>
        <DItem onClick={()=>insertBlock(idx,"thread")}><I.MsgCircle size={12} color={c.accentBtn}/>@Elnor Thread</DItem>
        <DItem onClick={()=>insertBlock(idx,"bar")}><I.Bell size={12} color={c.warn}/>Notice / Alert Bar</DItem>
      </div>}
    </div>;
  };

  // ─── Drag Handle ───
  const DragHandle=()=><div style={{position:"absolute",left:-20,top:4,width:14,height:20,display:"flex",alignItems:"center",justifyContent:"center",cursor:"grab",opacity:0.25,borderRadius:2}} onMouseEnter={e=>e.currentTarget.style.opacity=0.6} onMouseLeave={e=>e.currentTarget.style.opacity=0.25}><I.Grip size={12} color={c.textTer}/></div>;

  // ─── Module Header Bar (for collapsed state) ───
  const ModuleBar=({block,icon,count,extra})=><div onClick={()=>toggleBlock(block.id)} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 10px",borderRadius:R.sm,border:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt,cursor:"pointer",position:"relative"}} onMouseEnter={e=>e.currentTarget.style.borderColor=c.accentBtn+"30"} onMouseLeave={e=>e.currentTarget.style.borderColor=c.borderLight}>
    <DragHandle/>
    <div style={{transform:block.collapsed?"none":"rotate(90deg)",transition:"transform 0.1s"}}><I.ChevR size={10} color={c.textTer}/></div>
    {icon}
    <span style={{fontSize:12,fontWeight:650,color:c.textPri}}>{block.title}</span>
    {count!==undefined&&<span style={{fontSize:9.5,color:c.textTer,backgroundColor:c.bgInput,padding:"1px 6px",borderRadius:3}}>{count}</span>}
    {extra}
    <span style={{flex:1}}/>
    <button onClick={e=>{e.stopPropagation();flash(`Configure "${block.title}"…`)}} style={{border:"none",background:"none",cursor:"pointer",padding:1,display:"flex",color:c.textTer}}><I.Settings size={11}/></button>
  </div>;

  // ─── Render blocks ───
  const renderBlock=(block,idx)=>{
    // CONFIGURABLE BAR — generic block with Ask Elnor to configure/update
    if(block.type==="bar") return <div key={block.id} style={{display:"flex",alignItems:"center",gap:8,padding:"7px 12px",borderRadius:R.sm,border:`1px solid ${block.accent||c.accentBtn}30`,backgroundColor:(block.accent||c.accentBtn)+"06",marginBottom:4,position:"relative"}}>
      <DragHandle/>
      {block.icon==="mail"&&<I.Mail size={13} color={c.accentBtn}/>}
      {block.icon==="bell"&&<I.Bell size={13} color={c.warn}/>}
      {block.icon==="zap"&&<I.Zap size={13} color={c.green}/>}
      {block.icon==="calendar"&&<I.Calendar size={13} color={c.error}/>}
      {!block.icon&&<Dot color={block.accent||c.accentBtn} size={6}/>}
      <span style={{flex:1,fontSize:13,color:c.textPri,lineHeight:1.4}}>{block.title}</span>
      {block.time&&<span style={{fontSize:10,color:c.textTer,flexShrink:0}}>{block.time}</span>}
      <button onClick={()=>flash(`Opening chat with reference to block:${block.id} — Elnor can update this bar per your instructions`)} title="Ask Elnor about this block" style={{padding:"2px 7px",borderRadius:R.sm,border:`1px solid ${c.agentAv}40`,backgroundColor:c.agentAv+"10",cursor:"pointer",display:"flex",alignItems:"center",gap:3,fontSize:10,fontFamily:font.sans,color:c.agentAv,fontWeight:600}}><I.Spark size={10}/>Elnor</button>
      <button onClick={()=>dismissAlert(block.id)} title="Dismiss" style={{border:"none",background:"none",cursor:"pointer",padding:1,display:"flex",color:c.textTer}}><I.X size={12}/></button>
    </div>;

    // TEXT
    if(block.type==="text") return <div key={block.id} style={{position:"relative",marginBottom:2}}>
      <DragHandle/>
      <p contentEditable suppressContentEditableWarning style={{fontSize:14,lineHeight:1.75,color:block.content?c.textSec:c.textTer,outline:"none",minHeight:24,padding:"2px 0"}} onBlur={e=>setBlocks(p=>p.map(b=>b.id===block.id?{...b,content:e.target.textContent}:b))}>{block.content||"Type here… @Elnor to ask, /slash for commands"}</p>
    </div>;

    // TASKS
    if(block.type==="tasks"){
      const active=block.tasks.filter(t=>!t.done);const done=block.tasks.filter(t=>t.done);
      if(block.collapsed) return <div key={block.id} style={{marginBottom:4}}><ModuleBar block={block} icon={<I.List size={13} color={c.warn}/>} count={`${active.length} open`}/></div>;
      return <div key={block.id} style={{marginBottom:4,borderRadius:R.sm,border:`1px solid ${c.borderLight}`,overflow:"hidden",position:"relative"}}>
        <DragHandle/>
        <div onClick={()=>toggleBlock(block.id)} style={{display:"flex",alignItems:"center",gap:6,padding:"7px 10px",backgroundColor:c.bgPanelAlt,cursor:"pointer",borderBottom:`1px solid ${c.borderLight}`}}>
          <I.ChevD size={10} color={c.textTer}/><I.List size={12} color={c.warn}/>
          <span style={{fontSize:12.5,fontWeight:700,flex:1}}>{block.title}</span>
          <span style={{fontSize:9.5,color:c.textTer,backgroundColor:c.bgInput,padding:"1px 6px",borderRadius:3}}>{active.length} open</span>
          <button onClick={e=>{e.stopPropagation();flash(`Configure "${block.title}"…`)}} style={{border:"none",background:"none",cursor:"pointer",padding:1,display:"flex",color:c.textTer}}><I.Settings size={11}/></button>
        </div>
        <div style={{padding:"4px 8px"}}>
          {active.map(task=><div key={task.id}>
            <div style={{display:"flex",alignItems:"center",gap:8,padding:"5px 4px",cursor:"pointer"}} onClick={()=>setExpandedTask(expandedTask===task.id?null:task.id)}>
              <input type="checkbox" checked={false} onChange={()=>toggleTask(block.id,task.id)} onClick={e=>e.stopPropagation()} style={{width:15,height:15,accentColor:c.accentBtn,flexShrink:0}}/>
              <span style={{flex:1,fontSize:13.5,lineHeight:1.45,color:c.textPri}}>{task.text}</span>
              <div style={{display:"flex",gap:5,alignItems:"center",flexShrink:0}}>
                {task.due&&<span style={{fontSize:10,color:c.textTer}}>{task.due}</span>}
                {task.link&&<span style={{fontSize:10,color:c.accentBtn,cursor:"pointer",display:"flex",alignItems:"center",gap:2}} onClick={e=>{e.stopPropagation();flash(`Open "${task.link}"`)}}><I.Link size={9}/>Note</span>}
                {task.sub?.length>0&&<span style={{fontSize:10,color:c.textTer}}>{task.sub.filter(s=>s.done).length}/{task.sub.length}</span>}
              </div>
            </div>
            {expandedTask===task.id&&task.sub?.length>0&&<div style={{padding:"2px 0 6px 28px"}}>
              {task.sub.map(s=><div key={s.id} style={{display:"flex",alignItems:"center",gap:6,padding:"3px 0"}}>
                <input type="checkbox" checked={s.done} onChange={()=>toggleSub(block.id,task.id,s.id)} style={{width:13,height:13,accentColor:c.accentBtn}}/>
                <span style={{fontSize:12.5,color:s.done?c.textTer:c.textSec,textDecoration:s.done?"line-through":"none"}}>{s.text}</span>
              </div>)}
              <div style={{display:"flex",gap:4,marginTop:4}}>
                <Btn small ghost onClick={()=>flash("@Elnor…")}><I.Spark size={9} color={c.agentAv}/>@Elnor</Btn>
                <Btn small ghost><I.Plus size={9}/>Subtask</Btn>
                <Btn small ghost onClick={()=>flash(task.link?`Open "${task.link}"`:"Link note…")}><I.Link size={9}/>{task.link?"Open":"Link"}</Btn>
              </div>
            </div>}
          </div>)}
          {/* Add task */}
          <div style={{display:"flex",alignItems:"center",gap:8,padding:"4px 4px",opacity:0.5}}>
            <input type="checkbox" disabled style={{width:15,height:15}}/>
            <span contentEditable suppressContentEditableWarning style={{flex:1,fontSize:13,color:c.textTer,outline:"none"}} onFocus={e=>{if(e.target.textContent==="Add task…")e.target.textContent=""}} onBlur={e=>{if(!e.target.textContent.trim())e.target.textContent="Add task…"}}>Add task…</span>
          </div>
          {done.length>0&&<details style={{padding:"2px 4px 4px"}}><summary style={{fontSize:10,fontWeight:600,color:c.textTer,cursor:"pointer",padding:"4px 0"}}>Done ({done.length})</summary>
            {done.map(t=><div key={t.id} style={{display:"flex",alignItems:"center",gap:8,padding:"3px 4px",opacity:.4}}>
              <input type="checkbox" checked onChange={()=>toggleTask(block.id,t.id)} style={{width:14,height:14,accentColor:c.accentBtn}}/>
              <span style={{fontSize:12.5,textDecoration:"line-through",color:c.textTer}}>{t.text}</span>
            </div>)}
          </details>}
        </div>
      </div>;
    }

    // FEED
    if(block.type==="feed"){
      const totalItems=block.sections.reduce((a,s)=>a+s.items.length,0);
      if(block.collapsed) return <div key={block.id} style={{marginBottom:4}}><ModuleBar block={block} icon={<I.Spark size={13} color={c.agentAv}/>} count={`${totalItems} items`} extra={<span style={{fontSize:9,color:c.green,fontWeight:600}}>● live</span>}/></div>;
      return <div key={block.id} style={{marginBottom:4,borderRadius:R.sm,border:`1px solid ${c.borderLight}`,overflow:"hidden",position:"relative"}}>
        <DragHandle/>
        <div onClick={()=>toggleBlock(block.id)} style={{display:"flex",alignItems:"center",gap:6,padding:"7px 10px",backgroundColor:c.bgPanelAlt,cursor:"pointer",borderBottom:`1px solid ${c.borderLight}`}}>
          <I.ChevD size={10} color={c.textTer}/><I.Spark size={12} color={c.agentAv}/>
          <span style={{fontSize:12.5,fontWeight:700,flex:1}}>{block.title}</span>
          <span style={{fontSize:9,color:c.green,fontWeight:600}}>● auto-updating</span>
          <span style={{fontSize:9.5,color:c.textTer,backgroundColor:c.bgInput,padding:"1px 6px",borderRadius:3}}>{totalItems}</span>
          <button onClick={e=>{e.stopPropagation();flash(`Configure "${block.title}"…`)}} style={{border:"none",background:"none",cursor:"pointer",padding:1,display:"flex",color:c.textTer}}><I.Settings size={11}/></button>
        </div>
        <div style={{maxHeight:280,overflowY:"auto",padding:"6px 8px"}}>
          {block.sections.map(sec=><div key={sec.key} style={{marginBottom:4}}>
            <div onClick={()=>toggleFeedSection(sec.key)} style={{display:"flex",alignItems:"center",gap:5,padding:"3px 4px",cursor:"pointer"}}>
              <div style={{transform:collapsedFeeds.has(sec.key)?"none":"rotate(90deg)",transition:"transform 0.1s"}}><I.ChevR size={8} color={c.textTer}/></div>
              {feedIcons[sec.icon]||<I.Spark size={11}/>}
              <span style={{fontSize:11.5,fontWeight:700,color:c.textSec}}>{sec.label}</span>
              <span style={{fontSize:9,color:c.textTer}}>({sec.items.length})</span>
            </div>
            {!collapsedFeeds.has(sec.key)&&sec.items.map((item,i)=><div key={i} style={{display:"flex",alignItems:"flex-start",gap:6,padding:"4px 4px 4px 22px"}}>
              <span style={{color:c.textTer,fontSize:10,marginTop:2,flexShrink:0}}>▹</span>
              {item.accent&&<Dot color={item.accent} size={5}/>}
              <span style={{flex:1,fontSize:12.5,color:c.textSec,lineHeight:1.45}}>{item.text}</span>
              <span style={{fontSize:9.5,color:c.textTer,flexShrink:0,whiteSpace:"nowrap"}}>{item.time}</span>
            </div>)}
          </div>)}
        </div>
      </div>;
    }

    // THREAD
    if(block.type==="thread"){
      if(block.collapsed) return <div key={block.id} style={{marginBottom:4}}>
        <div onClick={()=>toggleBlock(block.id)} style={{display:"flex",alignItems:"center",gap:6,padding:"6px 10px",borderRadius:R.sm,border:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt,cursor:"pointer",position:"relative"}} onMouseEnter={e=>e.currentTarget.style.borderColor=c.accentBtn+"30"} onMouseLeave={e=>e.currentTarget.style.borderColor=c.borderLight}>
          <DragHandle/><I.ChevR size={10} color={c.textTer}/><Av letter="E" color={c.agentAv} size={16}/>
          <span style={{fontSize:11.5,color:c.textSec,flex:1}}><strong style={{color:c.agentAv}}>Elnor</strong> · {block.messages.length} messages</span>
          <span style={{fontSize:9.5,color:c.textTer}}>{block.messages[block.messages.length-1]?.time}</span>
        </div>
      </div>;
      return <div key={block.id} style={{marginBottom:4,borderRadius:R.sm,border:`1px solid ${c.accentBtn}20`,backgroundColor:c.accentBtn+"03",overflow:"hidden",position:"relative"}}>
        <DragHandle/>
        <div onClick={()=>toggleBlock(block.id)} style={{padding:"5px 12px",display:"flex",alignItems:"center",gap:6,cursor:"pointer",backgroundColor:c.accentBtn+"06",borderBottom:`1px solid ${c.accentBtn}15`}}>
          <I.ChevD size={10} color={c.accentBtn}/><I.MsgCircle size={11} color={c.accentBtn}/>
          <span style={{fontSize:10.5,fontWeight:600,color:c.accentBtn,flex:1}}>Thread · {block.messages.length}</span>
          {block.contextQuote&&<span style={{fontSize:9,color:c.textTer,fontStyle:"italic"}}>re: "{block.contextQuote}"</span>}
        </div>
        {block.messages.map((msg,i)=><div key={msg.id} style={{padding:"7px 14px",borderBottom:i<block.messages.length-1?`1px solid ${c.borderLight}`:"none",backgroundColor:msg.author==="You"?"transparent":c.agentAv+"06"}}>
          <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:3}}>
            <Av letter={msg.author[0]} color={msg.color} size={16}/>
            <span style={{fontSize:11,fontWeight:650,color:msg.color}}>{msg.author}</span>
            <span style={{fontSize:9,color:c.textTer}}>{msg.time}</span>
            {msg.author==="You"&&<><span style={{fontSize:9,color:c.textTer,cursor:"pointer",marginLeft:"auto"}}>edit</span><span style={{fontSize:9,color:c.error+"80",cursor:"pointer"}}>delete</span></>}
          </div>
          <div style={{fontSize:12.5,lineHeight:1.55,color:c.textSec,paddingLeft:22}}>{msg.body}</div>
        </div>)}
        {threadReplyId===block.id?<div style={{padding:"7px 14px",borderTop:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}>
          <textarea value={threadReplyText} onChange={e=>setThreadReplyText(e.target.value)} placeholder="Reply… @Elnor" autoFocus onKeyDown={e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();addThreadReply(block.id)}}} style={{width:"100%",padding:"6px 8px",borderRadius:R.sm,border:`1px solid ${c.border}`,fontSize:12,fontFamily:font.sans,outline:"none",minHeight:36,resize:"vertical"}}/>
          <div style={{display:"flex",gap:4,marginTop:4}}><Btn small primary onClick={()=>addThreadReply(block.id)} disabled={!threadReplyText.trim()}>Send</Btn><Btn small ghost onClick={()=>{setThreadReplyId(null);setThreadReplyText("")}}>Cancel</Btn></div>
        </div>:<div style={{padding:"5px 14px",borderTop:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}>
          <div onClick={()=>{setThreadReplyId(block.id);setThreadReplyText("")}} style={{display:"flex",alignItems:"center",gap:5,padding:"4px 8px",borderRadius:R.sm,border:`1px solid ${c.border}`,backgroundColor:c.bgCard,cursor:"text"}}><I.Plus size={10} color={c.textTer}/><span style={{fontSize:11,color:c.textTer}}>Reply… @Elnor</span></div>
        </div>}
      </div>;
    }
    return null;
  };

  return (
    <div style={{display:"flex",width:"100%",height:"100vh",fontFamily:font.sans,color:c.textPri,backgroundColor:c.bgApp}} onClick={()=>{setOpenDrop(null);setInserterAt(null)}}>
      <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}::selection{background:${c.accentBtn}22}details>summary{list-style:none}details>summary::-webkit-details-marker{display:none}`}</style>
      {toast&&<Toast msg={toast} onDone={()=>setToast(null)}/>}

      {/* SIDEBAR RAIL */}
      <div style={{width:44,flexShrink:0,backgroundColor:c.bgSidebar,borderRight:`1px solid ${c.borderDark}`,display:"flex",flexDirection:"column",alignItems:"center",paddingTop:10,gap:6}}>
        <div style={{width:26,height:26,borderRadius:R.sm,backgroundColor:c.accentBtn,color:"#fff",display:"flex",alignItems:"center",justifyContent:"center",fontSize:11,fontWeight:700,marginBottom:6}}>Q</div>
        <button onClick={()=>setBrowserOpen(!browserOpen)} title="Browser (⌘B)" style={{width:28,height:28,borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:browserOpen?"#ffffff18":"transparent",color:browserOpen?"#fff":"#777",display:"flex",alignItems:"center",justifyContent:"center"}}><I.Search size={15}/></button>
        <button onClick={()=>setNoteListOpen(!noteListOpen)} title="Notes" style={{width:28,height:28,borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:noteListOpen?"#ffffff18":"transparent",color:noteListOpen?"#fff":"#777",display:"flex",alignItems:"center",justifyContent:"center"}}><I.FileText size={15}/></button>
        <button onClick={()=>setCommentsOpen(!commentsOpen)} title="Comments" style={{width:28,height:28,borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:commentsOpen?"#ffffff18":"transparent",color:commentsOpen?"#fff":"#777",display:"flex",alignItems:"center",justifyContent:"center"}}><I.MsgCircle size={15}/></button>
      </div>

      {/* BROWSER placeholder */}
      {browserOpen&&<div style={{width:260,flexShrink:0,backgroundColor:c.bgPanel,borderRight:`1px solid ${c.border}`,display:"flex",flexDirection:"column"}}>
        <div style={{padding:"10px 12px",borderBottom:`1px solid ${c.borderLight}`,display:"flex",alignItems:"center",justifyContent:"space-between"}}><span style={{fontSize:12,fontWeight:650}}>Browser</span><button onClick={()=>setBrowserOpen(false)} style={{border:"none",background:"none",cursor:"pointer",display:"flex",color:c.textTer}}><I.X size={12}/></button></div>
        <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",padding:20}}><div style={{textAlign:"center",fontSize:11,color:c.textTer,fontStyle:"italic",lineHeight:1.6}}>Q_BROWSER_R13.jsx<br/>plugs in here<br/><span style={{fontSize:10}}>260px · collapsible</span></div></div>
      </div>}

      {/* NOTES SIDEBAR placeholder */}
      {noteListOpen&&!fullScreen&&<div style={{width:220,flexShrink:0,backgroundColor:c.bgPanel,borderRight:`1px solid ${c.border}`,display:"flex",flexDirection:"column"}}>
        <div style={{padding:"8px 10px",borderBottom:`1px solid ${c.borderLight}`,display:"flex",alignItems:"center",justifyContent:"space-between"}}><span style={{fontSize:12.5,fontWeight:650}}>Notes</span><button onClick={()=>setNoteListOpen(false)} style={{border:"none",background:"none",cursor:"pointer",display:"flex",color:c.textTer}}><I.X size={12}/></button></div>
        <div style={{flex:1,overflowY:"auto"}}>
          {/* Pinned Today */}
          <div style={{padding:"7px 10px",borderBottom:`1px solid ${c.borderLight}`,borderLeft:`2px solid ${c.accentBtn}`,backgroundColor:c.accentBtn+"06"}}>
            <div style={{display:"flex",alignItems:"center",gap:3,marginBottom:2}}><I.Pin size={8} color={c.warn}/><I.Sun size={10} color={c.warn}/><span style={{fontSize:12,fontWeight:600}}>Today — Wed, Mar 18</span></div>
            <div style={{fontSize:9.5,color:c.textTer}}>just now · 5 tasks · live</div>
          </div>
          <div style={{padding:"4px 8px",borderBottom:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}><div style={{display:"flex",alignItems:"center",gap:4}}><I.ChevD size={9} color={c.textTer}/><I.Folder size={11} color={c.warn}/><span style={{fontSize:11.5,fontWeight:600}}>To-Do Lists</span></div></div>
          {["Henderson Tasks","Weekly Review"].map((n,i)=><div key={i} style={{padding:"6px 10px 6px 28px",borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer"}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.bgInput} onMouseLeave={e=>e.currentTarget.style.backgroundColor="transparent"}><div style={{fontSize:11.5}}>{n}</div><div style={{fontSize:9.5,color:c.textTer}}>{["1d","3d"][i]}</div></div>)}
          <div style={{padding:"4px 8px",borderBottom:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}><div style={{display:"flex",alignItems:"center",gap:4}}><I.ChevR size={9} color={c.textTer}/><I.Folder size={11} color={c.textTer}/><span style={{fontSize:11.5,fontWeight:600}}>Daily Notes</span><span style={{fontSize:9,color:c.textTer}}>14</span></div></div>
          <div style={{padding:"4px 8px",borderBottom:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}><div style={{display:"flex",alignItems:"center",gap:4}}><I.ChevD size={9} color={c.textTer}/><I.Folder size={11} color={c.warn}/><span style={{fontSize:11.5,fontWeight:600}}>Henderson Case</span></div></div>
          {["Henderson Discovery Priorities","Judge Chen Notes","Privilege Checklist"].map((n,i)=><div key={i} style={{padding:"6px 10px 6px 28px",borderBottom:`1px solid ${c.borderLight}`,cursor:"pointer"}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.bgInput} onMouseLeave={e=>e.currentTarget.style.backgroundColor="transparent"}><div style={{fontSize:11.5}}>{n}</div><div style={{fontSize:9.5,color:c.textTer}}>{["2h","3d","1d"][i]}{i===0&&" · 💬2"}</div></div>)}
        </div>
        <div style={{padding:"3px 8px",borderTop:`1px solid ${c.borderLight}`,fontSize:9,color:c.textTer}}>12 notes · Modified</div>
      </div>}

      {/* MAIN WORKSPACE */}
      <div style={{flex:1,display:"flex",flexDirection:"column",overflow:"hidden"}}>
        {/* Toolbar (from Q_NOTES_FULL) */}
        <div style={{display:"flex",alignItems:"center",gap:3,padding:"4px 10px",borderBottom:`1px solid ${c.border}`,backgroundColor:c.bgPanel,flexWrap:"wrap"}}>
          <select style={{padding:"2px 4px",borderRadius:3,border:`1px solid ${c.borderLight}`,fontSize:10.5,fontFamily:font.sans,color:c.textSec,backgroundColor:"transparent",height:24}}><option>Paragraph</option><option>H1</option><option>H2</option></select>
          <TBtn icon={<span style={{fontWeight:700,fontSize:12}}>B</span>}/><TBtn icon={<span style={{fontStyle:"italic",fontSize:12}}>I</span>}/><TBtn icon={<span style={{textDecoration:"underline",fontSize:12}}>U</span>}/>
          <Sep/><TBtn icon={<I.Undo size={13}/>}/><TBtn icon={<I.Redo size={13}/>}/>
          <Sep/><TBtn icon={<I.Copy size={13}/>} title="Copy" onClick={()=>flash("Copied")}/>
          <div style={{position:"relative"}}><TBtn icon={<I.Save size={13}/>} label="Save As…" dropdown onClick={e=>{e.stopPropagation();setOpenDrop(openDrop==="save"?null:"save")}}/>
            {openDrop==="save"&&<div onClick={e=>e.stopPropagation()} style={{position:"absolute",top:28,left:0,backgroundColor:c.bgCard,border:`1px solid ${c.border}`,borderRadius:R.sm,boxShadow:"0 8px 24px rgba(0,0,0,0.12)",zIndex:999,minWidth:180,padding:4}}>
              <DItem onClick={()=>{flash("Export MD");setOpenDrop(null)}}>Export as Markdown</DItem>
              <DItem onClick={()=>{flash("Export DOCX");setOpenDrop(null)}}>Export as DOCX</DItem>
              <DItem onClick={()=>{flash("Export PDF");setOpenDrop(null)}}>Export as PDF</DItem>
              <div style={{borderTop:`1px solid ${c.borderLight}`,margin:"2px 0"}}/>
              <DItem onClick={()=>{flash("Save as Prompt");setOpenDrop(null)}}>Save as Prompt</DItem>
            </div>}</div>
          <TBtn icon={<I.Link size={13}/>} label="Ref" onClick={()=>flash("Ref copied")}/>
          <Sep/><TBtn icon={<I.Search size={13}/>} active={findBar} onClick={()=>setFindBar(!findBar)}/><TBtn icon={<I.Maximize size={13}/>} active={fullScreen} onClick={()=>setFullScreen(!fullScreen)}/>
          <Sep/><TBtn icon={<I.MsgCircle size={13}/>} label="2" active={commentsOpen&&rightTab==="comments"} onClick={()=>{if(commentsOpen&&rightTab==="comments")setCommentsOpen(false);else{setCommentsOpen(true);setRightTab("comments")}}}/>
          <Sep/><TBtn icon={<I.Eye size={13}/>} label="Markup" active/>
          <TBtn icon={<I.Edit size={13}/>} label="0 ▾"/>
          <div style={{flex:1}}/><span style={{fontSize:10,color:c.green,fontWeight:500}}>Saved just now</span>
          <Sep/><button onClick={()=>{if(commentsOpen&&rightTab==="send")setCommentsOpen(false);else{setCommentsOpen(true);setRightTab("send")}}} style={{padding:"3px 10px",borderRadius:R.sm,border:`1px solid ${c.accentBtn}40`,backgroundColor:(commentsOpen&&rightTab==="send")?c.accentBtn:c.accentBtn+"08",cursor:"pointer",display:"flex",alignItems:"center",gap:4,color:(commentsOpen&&rightTab==="send")?"#fff":c.accentBtn,fontFamily:font.sans,fontSize:10.5,fontWeight:600,height:26}}><I.Spark size={12}/>Send to Agent</button>
        </div>
        {findBar&&<div style={{display:"flex",alignItems:"center",gap:6,padding:"5px 12px",borderBottom:`1px solid ${c.borderLight}`,backgroundColor:c.bgPanelAlt}}><I.Search size={12} color={c.textTer}/><input placeholder="Find…" autoFocus style={{flex:1,border:"none",backgroundColor:"transparent",fontSize:12,fontFamily:font.sans,outline:"none",maxWidth:250}}/><span style={{fontSize:10,color:c.textTer}}>0/0</span><button onClick={()=>setFindBar(false)} style={{padding:2,border:"none",cursor:"pointer",backgroundColor:"transparent",display:"flex",color:c.textTer}}><I.X size={12}/></button></div>}

        {/* CONTENT */}
        <div style={{flex:1,display:"flex",overflow:"hidden"}}>
          <div style={{flex:1,display:"flex",flexDirection:"column",overflow:"hidden",minWidth:0}}>
            <div ref={editorRef} style={{flex:1,overflowY:"auto",padding:"16px 32px 60px",position:"relative",userSelect:"text"}} onMouseUp={handleMouseUp} onMouseDown={e=>{if(bubbleMenu&&!e.target.closest("[data-bubble]"))setBubbleMenu(null)}}>

              {/* Title */}
              <div style={{display:"flex",alignItems:"center",gap:8,marginBottom:3}}>
                <I.Sun size={20} color={c.warn}/>
                <div style={{fontSize:22,fontWeight:700}} contentEditable suppressContentEditableWarning>Today — Wednesday, March 18</div>
              </div>
              <div style={{fontSize:10.5,color:c.textTer,marginBottom:16,display:"flex",alignItems:"center",gap:4}}>
                <I.Pin size={9} color={c.warn}/> Pinned · Auto-updating · Configurable modules
                <button onClick={()=>flash("Configure workspace template…")} style={{border:`1px solid ${c.borderLight}`,borderRadius:3,backgroundColor:"transparent",cursor:"pointer",padding:"1px 6px",fontSize:9,color:c.textTer,fontFamily:font.sans,display:"flex",alignItems:"center",gap:2,marginLeft:4}}><I.Settings size={9}/>Configure</button>
              </div>

              {/* Render all blocks with inserters between them */}
              {blocks.map((block,idx)=><div key={block.id}>
                <BlockInserter idx={idx}/>
                {renderBlock(block,idx)}
              </div>)}
              <BlockInserter idx={blocks.length}/>

              {/* Slash command hint */}
              <div style={{marginTop:20,padding:"8px 12px",borderRadius:R.sm,border:`1px dashed ${c.borderLight}`,backgroundColor:c.bgPanelAlt,display:"flex",alignItems:"center",gap:8}}>
                <I.Plus size={12} color={c.accentBtn}/>
                <span style={{fontSize:11,color:c.textTer}}>Hover between blocks to insert · Type <strong style={{color:c.accentBtn}}>/todo</strong> <strong style={{color:c.accentBtn}}>/feed</strong> <strong style={{color:c.accentBtn}}>/thread</strong> · Type <strong style={{color:c.accentBtn}}>@Elnor</strong> anywhere</span>
              </div>

              {/* Bubble menu */}
              {bubbleMenu&&<div data-bubble="1" style={{position:"absolute",left:Math.max(10,Math.min(bubbleMenu.x-140,(editorRef.current?.clientWidth||500)-300)),top:bubbleMenu.y-44,backgroundColor:c.bgCard,border:`1px solid ${c.border}`,borderRadius:R.sm,boxShadow:"0 4px 16px rgba(0,0,0,0.12)",padding:"4px 6px",display:"flex",gap:2,zIndex:100,alignItems:"center"}}>
                <button onClick={()=>{flash("Comment…");dismissBubble()}} style={{padding:"5px 10px",borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:c.accentBtn,color:"#fff",fontSize:11,fontWeight:600,fontFamily:font.sans,display:"flex",alignItems:"center",gap:4}}><I.MsgCircle size={11}/>Comment</button><Sep/>
                <div style={{display:"flex",alignItems:"center",gap:2,padding:"2px 6px",borderRadius:R.sm,border:`1px solid ${c.borderLight}`,cursor:"pointer"}}><Dot color={agent.color} size={6}/><span style={{fontSize:10,fontWeight:500}}>{agent.name}</span></div>
                <button onClick={()=>{flash(`Ask ${agent.name} inline…`);dismissBubble()}} style={{padding:"5px 8px",borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:"transparent",color:c.textSec,fontSize:11,fontFamily:font.sans,display:"flex",alignItems:"center",gap:3}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.bgInput} onMouseLeave={e=>e.currentTarget.style.backgroundColor="transparent"}><I.Spark size={11}/>Ask inline</button>
                {["Rewrite","Expand","Shorten"].map(a=><button key={a} onClick={()=>{flash(`${agent.name}: ${a}…`);dismissBubble()}} style={{padding:"5px 8px",borderRadius:R.sm,border:"none",cursor:"pointer",backgroundColor:"transparent",color:c.textSec,fontSize:11,fontFamily:font.sans}} onMouseEnter={e=>e.currentTarget.style.backgroundColor=c.bgInput} onMouseLeave={e=>e.currentTarget.style.backgroundColor="transparent"}>{a}</button>)}
                <button onClick={dismissBubble} style={{padding:3,border:"none",cursor:"pointer",backgroundColor:"transparent",color:c.textTer,display:"flex"}}><I.X size={11}/></button>
              </div>}
            </div>
          </div>

          {/* COMMENTS PANEL placeholder */}
          {commentsOpen&&!fullScreen&&<div style={{width:rightTab==="send"?290:260,flexShrink:0,borderLeft:`1px solid ${c.border}`,display:"flex",flexDirection:"column",backgroundColor:c.bgPanelAlt}}>
            <div style={{display:"flex",borderBottom:`1px solid ${c.borderLight}`,flexShrink:0}}>
              <button onClick={()=>setRightTab("comments")} style={{flex:1,padding:"7px 0",border:"none",cursor:"pointer",backgroundColor:rightTab==="comments"?c.bgPanelAlt:c.bgInput,color:rightTab==="comments"?c.accentBtn:c.textTer,fontSize:10.5,fontWeight:rightTab==="comments"?650:450,fontFamily:font.sans,borderBottom:rightTab==="comments"?`2px solid ${c.accentBtn}`:"2px solid transparent",display:"flex",alignItems:"center",justifyContent:"center",gap:3}}><I.MsgCircle size={10}/>Comments</button>
              <button onClick={()=>setRightTab("send")} style={{flex:1,padding:"7px 0",border:"none",cursor:"pointer",backgroundColor:rightTab==="send"?c.bgPanel:c.bgInput,color:rightTab==="send"?c.accentBtn:c.textTer,fontSize:10.5,fontWeight:rightTab==="send"?650:450,fontFamily:font.sans,borderBottom:rightTab==="send"?`2px solid ${c.accentBtn}`:"2px solid transparent",display:"flex",alignItems:"center",justifyContent:"center",gap:3}}><I.Spark size={10}/>Send to Agent</button>
              <button onClick={()=>setCommentsOpen(false)} style={{width:26,border:"none",cursor:"pointer",backgroundColor:"transparent",display:"flex",alignItems:"center",justifyContent:"center",color:c.textTer}}><I.X size={11}/></button>
            </div>
            <div style={{flex:1,display:"flex",alignItems:"center",justifyContent:"center",padding:16}}>
              <div style={{textAlign:"center",fontSize:11,color:c.textTer,fontStyle:"italic",lineHeight:1.6}}>Comments + Send to Agent<br/>from Q_NOTES_FULL.jsx<br/>plugs in here<br/><span style={{fontSize:10}}>@mention support in specs</span></div>
            </div>
          </div>}
        </div>
      </div>

      {/* CHAT INDICATOR */}
      <div style={{width:40,borderLeft:`1px solid ${c.border}`,backgroundColor:c.bgPanel,display:"flex",flexDirection:"column",alignItems:"center",paddingTop:12,gap:8,flexShrink:0}}>
        <div style={{writingMode:"vertical-rl",fontSize:10,fontWeight:600,color:c.accentBtn,letterSpacing:".05em",cursor:"pointer",padding:"8px 4px"}}>CHAT →</div>
        <Dot color={c.green} size={6}/><div style={{fontSize:8,color:c.textTer,writingMode:"vertical-rl"}}>Henderson</div>
      </div>
    </div>
  );
}