// Primus IQ — Project detail, Library, Apps, Search, Add Sources modal

const extColors = {
  pdf:  '#B23A48',
  xlsx: '#2E6F40',
  pptx: '#C76A23',
  docx: '#2A5A9E',
  png:  '#7A4FB3',
  jpg:  '#7A4FB3',
  mp4:  '#1F4A6B',
  txt:  '#666666',
};

const PRACTICES = [
  'Public Policy Realization',
  'Sector Potential Realization',
  'Impact Realization',
  'Economic Potential Realization',
  'Data & Digital Strategy',
  'Transaction Realization',
];

const UPLOADED_SEED = [
  { id: 'u1', name: 'Sector Outlook · KSA fintech.pdf',  size: '8.6 MB',  ext: 'pdf',  conf: 'public',   practice: 'Sector Potential Realization', added: '12 May' },
  { id: 'u2', name: 'Acme Financial Model v4.xlsx',      size: '4.2 MB',  ext: 'xlsx', conf: 'strict',   practice: 'Transaction Realization',       added: '10 May' },
  { id: 'u3', name: 'Pitch Storyline draft.pptx',        size: '12.0 MB', ext: 'pptx', conf: 'internal', practice: 'Sector Potential Realization', added: '08 May' },
  { id: 'u4', name: 'CFO interview · transcript.docx',   size: '180 KB',  ext: 'docx', conf: 'client',   practice: 'Sector Potential Realization', added: '04 May' },
  { id: 'u5', name: 'Cost Build · Phase 1.xlsx',         size: '2.4 MB',  ext: 'xlsx', conf: 'client',   practice: 'Transaction Realization',       added: '02 May' },
];

// ──────────────────────────────────────────────────────────────────────────────
// Project Detail — 50/50 split. LEFT = upload sources. RIGHT = files queue.
// ──────────────────────────────────────────────────────────────────────────────
const ScreenProjectDetail = ({ setRoute, openTagging, openSharePoint, openTextInput, openUrlInput, openInvite, openEditProject, uploadedFiles, removeFile, downloadFile, activeProject, projectMembers }) => {
  const [dragHover, setDragHover] = React.useState(false);
  const [pendingCount, setPendingCount] = React.useState(0);
  const [tab, setTab] = React.useState('chats');             // 'chats' | 'sources'
  const [chats, setChats] = React.useState([]);              // local chat sessions
  const [activeChat, setActiveChat] = React.useState(null);  // currently open chat
  const [composerVal, setComposerVal] = React.useState('');
  const [composerFocused, setComposerFocused] = React.useState(false);
  const [filter, setFilter] = React.useState('');

  const projectName = activeProject?.name || 'Project';
  const projectPractice = activeProject?.practice || '';

  const fq = filter.trim().toLowerCase();
  const filteredChats = fq ? chats.filter(c => `${c.title || ''} ${c.preview || ''}`.toLowerCase().includes(fq)) : chats;
  const filteredFiles = fq ? uploadedFiles.filter(f => (f.name || '').toLowerCase().includes(fq)) : uploadedFiles;

  React.useEffect(() => {
    if (!activeProject?.id) return;
    PrimusAPI.listJoinRequests(activeProject.id)
      .then(data => setPendingCount((data || []).length))
      .catch(() => setPendingCount(0));
  }, [activeProject?.id]);

  // Reset chats when active project changes
  React.useEffect(() => { setChats([]); setActiveChat(null); }, [activeProject?.id]);

  const submitComposer = () => {
    const q = composerVal.trim();
    if (!q) return;
    const id = 'c-' + Date.now();
    const newChat = {
      id,
      title: q.length > 60 ? q.slice(0, 60) + '…' : q,
      preview: q,
      updated: 'just now',
      messages: [{ role: 'user', text: q }],
    };
    setChats(prev => [newChat, ...prev]);
    setComposerVal('');
    setActiveChat(newChat);
    setTab('chats');
  };

  // ── Full-screen chat view (opened from this project) ──
  if (activeChat) {
    return (
      <ProjectChatView
        chat={activeChat}
        projectName={projectName}
        onBack={() => setActiveChat(null)}
        onSend={(text) => {
          setActiveChat(prev => ({ ...prev, messages: [...(prev.messages || []), { role: 'user', text }] }));
          setChats(prev => prev.map(c => c.id === activeChat.id ? { ...c, preview: text, updated: 'just now' } : c));
        }}
      />
    );
  }

  return (
    <div style={{ ...contentArea, overflowY: 'auto' }}>
      <div style={{ padding: '32px 40px 32px', maxWidth: 1440, margin: '0 auto', display: 'flex', flexDirection: 'column' }}>
        {/* Crumb */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--mute)', marginBottom: 14 }}>
          <button onClick={() => setRoute('projects')} style={crumbBtn}>Projects</button>
          <span>/</span>
          <span style={{ color: 'var(--ink)', fontWeight: 500 }}>{projectName}</span>
        </div>

        {/* Header */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 24, marginBottom: 22 }}>
          <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
            <div style={{
              width: 52, height: 52, borderRadius: 13,
              background: 'var(--maroon)', color: 'white',
              display: 'grid', placeItems: 'center',
              boxShadow: '0 8px 20px rgba(122,28,28,0.2)',
            }}>
              <PIcon name="folder" size={22} color="white" />
            </div>
            <div>
              <h1 className="serif" style={{ fontSize: 24, fontWeight: 500, margin: 0, letterSpacing: '-0.02em', lineHeight: 1.1 }}>{projectName}</h1>
              <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6, display: 'flex', alignItems: 'center', gap: 10 }}>
                {projectPractice && <span className="tag-pill">{projectPractice}</span>}
                <span>· {uploadedFiles.length} files</span>
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {projectMembers && projectMembers.length > 0 && (
              <div style={{ display: 'flex' }}>
                {projectMembers.slice(0, 3).map((m, i) => (
                  <div key={m.user_id} className="avatar" style={{ marginLeft: i ? -7 : 0, width: 28, height: 28, fontSize: 11 }}>
                    {(m.full_name || '?')[0].toUpperCase()}
                  </div>
                ))}
                {projectMembers.length > 3 && (
                  <div className="avatar muted" style={{ marginLeft: -7, width: 28, height: 28, fontSize: 10 }}>+{projectMembers.length - 3}</div>
                )}
              </div>
            )}
            <button className="btn-primary" onClick={openInvite} style={{ position: 'relative' }}>
              <PIcon name="plus" size={14} color="white" /> Invite
              {pendingCount > 0 && (
                <span style={{
                  position: 'absolute', top: -5, right: -5,
                  width: 16, height: 16, borderRadius: 8,
                  background: 'white', color: 'var(--maroon)',
                  fontSize: 10, fontWeight: 700,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  border: '1.5px solid var(--maroon)',
                }}>{pendingCount}</span>
              )}
            </button>
            <button className="btn-ghost" style={{ width: 40, justifyContent: 'center' }} onClick={openEditProject}>
              <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>
            </button>
          </div>
        </div>

        {/* TOP ROW: New chat composer (left) + Add sources (right) — sized to content */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, marginBottom: 18 }}>
          {/* LEFT: New chat in <project> */}
          <div style={panelCard}>
            <div style={panelHeader}>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>New chat in {projectName}</div>
                <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2 }}>Ask anything — this project's files are referenced automatically.</div>
              </div>
            </div>
            <div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div style={{
                background: 'var(--bg-card)', borderRadius: 14,
                border: `1px solid ${composerFocused ? 'var(--maroon-20)' : 'var(--line-2)'}`,
                boxShadow: composerFocused ? '0 0 0 4px var(--maroon-06)' : 'none',
                transition: 'all 0.15s',
                padding: '12px 12px 10px 14px',
              }}>
                <textarea
                  value={composerVal}
                  onChange={e => setComposerVal(e.target.value)}
                  onFocus={() => setComposerFocused(true)}
                  onBlur={() => setComposerFocused(false)}
                  onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submitComposer(); } }}
                  rows={3}
                  placeholder={`Ask Primus IQ about ${projectName}…`}
                  style={{
                    width: '100%', border: 'none', resize: 'none',
                    fontFamily: 'inherit', fontSize: 14, color: 'var(--ink)',
                    background: 'transparent', lineHeight: 1.5, padding: '2px 0',
                    outline: 'none',
                  }}
                />
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                  <button onClick={() => openTagging([])} title="Attach files" style={pdComposerIconBtn}>
                    <PIcon name="plus" size={14} color="var(--ink-2)" />
                  </button>
                  <button style={pdComposerChip}>
                    <span style={{ width: 6, height: 6, borderRadius: 3, background: 'var(--maroon)' }} />
                    Primus IQ
                  </button>
                  <div style={{ flex: 1 }} />
                  <button
                    onClick={submitComposer}
                    disabled={!composerVal.trim()}
                    style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: composerVal.trim() ? 'var(--maroon)' : 'var(--bg-soft)',
                      color: composerVal.trim() ? 'white' : 'var(--mute-2)',
                      border: 'none', cursor: composerVal.trim() ? 'pointer' : 'default',
                      display: 'grid', placeItems: 'center', transition: 'all 0.15s',
                    }}>
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                      <path d="M8 12V4M4 8l4-4 4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  </button>
                </div>
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                {['Summarize the latest doc', 'Compare these proposals', 'Draft a status memo'].map(s => (
                  <button key={s} onClick={() => setComposerVal(s)} style={pdChip}>{s}</button>
                ))}
              </div>
            </div>
          </div>

          {/* RIGHT: dropzone + source quick-buttons */}
          <div style={panelCard}>
            <div style={panelHeader}>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>Add to this project</div>
                <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2 }}>Upload or connect a source. You'll set confidentiality and practice next.</div>
              </div>
            </div>
            <div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
              <label
                onDragEnter={e => { e.preventDefault(); setDragHover(true); }}
                onDragOver={e => { e.preventDefault(); setDragHover(true); }}
                onDragLeave={() => setDragHover(false)}
                onDrop={e => { e.preventDefault(); setDragHover(false); openTagging(Array.from(e.dataTransfer.files)); }}
                style={{
                  height: 150, borderRadius: 14,
                  border: `1.5px dashed ${dragHover ? 'var(--maroon)' : 'var(--line-2)'}`,
                  background: dragHover ? 'var(--maroon-wash)' : 'var(--bg-soft)',
                  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
                  cursor: 'pointer', transition: 'all 0.15s', gap: 8, padding: 16, textAlign: 'center',
                  position: 'relative',
                }}>
                <input type="file" multiple onChange={e => { openTagging(Array.from(e.target.files)); e.target.value = ''; }} style={{
                  position: 'absolute', inset: 0, opacity: 0, cursor: 'pointer',
                }}/>
                <div style={{
                  width: 40, height: 40, borderRadius: 11,
                  background: 'white', border: '1px solid var(--line)',
                  display: 'grid', placeItems: 'center', boxShadow: 'var(--shadow-xs)',
                }}>
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                    <path d="M12 16V5M7 10l5-5 5 5" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
                    <path d="M4 16v2.5A1.5 1.5 0 0 0 5.5 20h13a1.5 1.5 0 0 0 1.5-1.5V16" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round"/>
                  </svg>
                </div>
                <div>
                  <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>Drop files here</div>
                  <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 3 }}>
                    or <span style={{ color: 'var(--maroon)', fontWeight: 600 }}>click to browse</span>
                  </div>
                </div>
                <div style={{ fontSize: 11, color: 'var(--mute-2)' }}>
                  PDF, DOCX, PPTX, XLSX, MP4, images · 100 MB each
                </div>
              </label>

              <div>
                <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--mute)', letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 10 }}>
                  Or add from
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
                  <SourceBtn icon={<UploadIcon/>} label="Upload" onClick={() => {
                    const inp = document.createElement('input');
                    inp.type = 'file'; inp.multiple = true;
                    inp.onchange = e => openTagging(Array.from(e.target.files));
                    inp.click();
                  }}/>
                  <SourceBtn icon={<TextIcon/>}        label="Text input" onClick={() => openTextInput && openTextInput()}/>
                  <SourceBtn icon={<UrlIcon/>}         label="URL"        onClick={() => openUrlInput && openUrlInput()}/>
                  <SourceBtn icon={<SharepointIcon/>}  label="SharePoint" onClick={() => openSharePoint && openSharePoint()}/>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* TABS + LIST PANEL — fills remaining height */}
        <div style={{ minHeight: 360, display: 'flex', flexDirection: 'column' }}>
          <div style={{ display: 'flex', gap: 4, marginBottom: 12, alignItems: 'center' }}>
            <PdTab active={tab === 'chats'}   onClick={() => setTab('chats')}   count={chats.length}>Chats</PdTab>
            <PdTab active={tab === 'sources'} onClick={() => setTab('sources')} count={uploadedFiles.length}>Sources</PdTab>
            <div style={{ flex: 1 }} />
            <div className="search-input" style={{ width: 260, height: 34 }}>
              <PIcon name="search" size={14} color="var(--mute)" />
              <input
                value={filter}
                onChange={e => setFilter(e.target.value)}
                placeholder={tab === 'chats' ? 'Filter chats' : 'Filter files'}
              />
              {filter && (
                <button onClick={() => setFilter('')} title="Clear" style={{
                  background: 'transparent', border: 'none', cursor: 'pointer',
                  color: 'var(--mute)', padding: 0, display: 'grid', placeItems: 'center',
                  width: 18, height: 18,
                }}>
                  <svg width="12" height="12" viewBox="0 0 16 16" fill="none">
                    <path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
                  </svg>
                </button>
              )}
            </div>
          </div>

          <div style={{ ...panelCard, flex: 1, minHeight: 320 }}>
            {tab === 'chats' ? (
              <div style={{ padding: '8px 10px 12px', flex: 1, overflow: 'auto' }}>
                {filteredChats.length === 0 ? (
                  <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                    <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>{chats.length === 0 ? 'No chats yet' : 'No chats match your search'}</div>
                    <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>
                      {chats.length === 0
                        ? <>Chats in <span style={{ color: 'var(--ink-2)', fontWeight: 500 }}>{projectName}</span> will live here.</>
                        : <>Try a different term.</>}
                    </div>
                  </div>
                ) : filteredChats.map(c => (
                  <button key={c.id} onClick={() => setActiveChat(c)} style={pdChatRow}
                    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <div style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: 'var(--maroon-wash)', display: 'grid', placeItems: 'center', flexShrink: 0,
                    }}>
                      <PIcon name="chat" size={14} color="var(--maroon)" />
                    </div>
                    <div style={{ flex: 1, minWidth: 0, textAlign: 'left' }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.title}</div>
                      <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.preview}</div>
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--mute-2)', flexShrink: 0 }}>{c.updated}</div>
                  </button>
                ))}
              </div>
            ) : (
              <React.Fragment>
                <div style={{ padding: '6px 10px 12px', flex: 1, overflow: 'auto', display: 'flex', flexDirection: 'column' }}>
                  {uploadedFiles.length === 0 ? (
                    <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>No files yet</div>
                      <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>Drop or pick a source on the right to begin.</div>
                    </div>
                  ) : filteredFiles.length === 0 ? (
                    <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>No files match your search</div>
                      <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>Try a different term.</div>
                    </div>
                  ) : filteredFiles.map(f => (
                    <FileRow key={f.id} f={f}
                      onRemove={() => removeFile(f.id)}
                      onDownload={downloadFile ? () => downloadFile(f.id) : null}
                    />
                  ))}
                </div>
                <div style={{
                  padding: '10px 18px', borderTop: '1px solid var(--line)',
                  fontSize: 12, color: 'var(--mute)',
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                }}>
                  <span>{fq ? `${filteredFiles.length} of ${uploadedFiles.length}` : uploadedFiles.length} files in this project</span>
                </div>
              </React.Fragment>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

const panelCard = {
  background: 'white', border: '1px solid var(--line)', borderRadius: 16,
  display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0,
};
const panelHeader = {
  padding: '14px 20px', borderBottom: '1px solid var(--line)',
  display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
};

// ── Project Detail — supporting bits ──────────────────────────────────────────
const PdTab = ({ active, onClick, children, count }) => (
  <button onClick={onClick} style={{
    padding: '8px 14px', borderRadius: 999,
    background: active ? 'var(--bg-soft)' : 'transparent',
    border: '1px solid', borderColor: active ? 'var(--line-2)' : 'transparent',
    fontSize: 13, fontWeight: active ? 600 : 500,
    color: active ? 'var(--ink)' : 'var(--mute)',
    cursor: 'pointer', fontFamily: 'inherit',
    transition: 'all 0.15s',
    display: 'inline-flex', alignItems: 'center', gap: 6,
  }}>
    {children}
    <span style={{ color: active ? 'var(--mute)' : 'var(--mute-2)', fontWeight: 500, fontSize: 12 }}>· {count}</span>
  </button>
);

const pdComposerIconBtn = {
  width: 28, height: 28, borderRadius: 7,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'grid', placeItems: 'center',
};
const pdComposerChip = {
  height: 28, padding: '0 10px', borderRadius: 7,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6,
  fontSize: 12, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
};
const pdChip = {
  padding: '6px 12px', borderRadius: 999,
  background: 'var(--bg-card)', border: '1px solid var(--line)',
  fontSize: 12, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
  cursor: 'pointer',
};
const pdChatRow = {
  display: 'flex', alignItems: 'center', gap: 12,
  padding: '12px 14px', borderRadius: 10,
  background: 'transparent', border: 'none', cursor: 'pointer',
  width: '100%', fontFamily: 'inherit',
  transition: 'background 0.15s',
};

// ── Full-screen chat view, opened from inside a project ──────────────────────
const ProjectChatView = ({ chat, projectName, onBack, onSend }) => {
  const [val, setVal] = React.useState('');
  const [focused, setFocused] = React.useState(false);
  const scrollRef = React.useRef(null);
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [chat?.messages?.length]);

  const send = () => {
    const t = val.trim();
    if (!t) return;
    onSend(t);
    setVal('');
  };

  return (
    <div style={contentArea}>
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
        {/* Header: back arrow + project crumb signalling the chat origin */}
        <div style={{
          padding: '16px 32px', borderBottom: '1px solid var(--line)',
          display: 'flex', alignItems: 'center', gap: 14, background: 'var(--bg)',
        }}>
          <button onClick={onBack} title="Back to project" style={{
            width: 34, height: 34, borderRadius: 9,
            background: 'var(--bg-soft)', border: '1px solid var(--line)',
            cursor: 'pointer', display: 'grid', placeItems: 'center', flexShrink: 0,
          }}>
            <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
              <path d="M10 12L6 8l4-4" stroke="var(--ink)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>

          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '6px 12px', borderRadius: 999,
            background: 'var(--maroon-wash)', border: '1px solid var(--maroon-20)',
            cursor: 'pointer',
          }}
            onClick={onBack}
            title={`Chat opened from ${projectName}`}
          >
            <PIcon name="folder" size={13} color="var(--maroon)" />
            <span style={{ fontSize: 12, color: 'var(--maroon)', fontWeight: 600 }}>From {projectName}</span>
          </div>

          <div style={{ fontSize: 14, color: 'var(--ink)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
            {chat.title}
          </div>
        </div>

        {/* Messages */}
        <div ref={scrollRef} style={{ flex: 1, overflow: 'auto', padding: '28px 0' }}>
          <div style={{ maxWidth: 760, margin: '0 auto', padding: '0 32px', display: 'flex', flexDirection: 'column', gap: 14 }}>
            {(chat.messages || []).map((m, i) => (
              <div key={i} style={{
                alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
                maxWidth: '82%',
                background: m.role === 'user' ? 'var(--maroon)' : 'var(--bg-card)',
                color: m.role === 'user' ? 'white' : 'var(--ink)',
                padding: '12px 16px', borderRadius: 14,
                border: m.role === 'user' ? 'none' : '1px solid var(--line)',
                fontSize: 14, lineHeight: 1.55, whiteSpace: 'pre-wrap',
              }}>{m.text}</div>
            ))}
            {(chat.messages || []).length === 1 && (
              <div style={{ alignSelf: 'flex-start', maxWidth: '82%', color: 'var(--mute)', fontSize: 13, padding: '4px 4px', fontStyle: 'italic' }}>
                Primus IQ is offline in this preview — responses won't generate. UI shell only.
              </div>
            )}
          </div>
        </div>

        {/* Composer */}
        <div style={{ padding: '0 0 24px' }}>
          <div style={{ maxWidth: 760, margin: '0 auto', padding: '0 32px' }}>
            <div style={{
              background: 'var(--bg-card)', borderRadius: 16,
              border: `1px solid ${focused ? 'var(--maroon-20)' : 'var(--line-2)'}`,
              boxShadow: focused ? '0 0 0 4px var(--maroon-06)' : '0 2px 10px rgba(60,30,20,0.04)',
              transition: 'all 0.15s',
              padding: '12px 12px 10px 16px',
            }}>
              <textarea
                value={val}
                onChange={e => setVal(e.target.value)}
                onFocus={() => setFocused(true)}
                onBlur={() => setFocused(false)}
                onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
                rows={2}
                placeholder={`Reply in ${projectName}`}
                style={{
                  width: '100%', border: 'none', resize: 'none',
                  fontFamily: 'inherit', fontSize: 15, color: 'var(--ink)',
                  background: 'transparent', lineHeight: 1.5, padding: '2px 0', outline: 'none',
                }}
              />
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                <div style={{ flex: 1 }} />
                <button onClick={send} disabled={!val.trim()} style={{
                  width: 34, height: 34, borderRadius: 10,
                  background: val.trim() ? 'var(--maroon)' : 'var(--bg-soft)',
                  color: val.trim() ? 'white' : 'var(--mute-2)',
                  border: 'none', cursor: val.trim() ? 'pointer' : 'default',
                  display: 'grid', placeItems: 'center',
                }}>
                  <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                    <path d="M8 12V4M4 8l4-4 4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

const FileRow = ({ f, onRemove, onDownload }) => {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const menuRef = React.useRef(null);

  React.useEffect(() => {
    if (!menuOpen) return;
    const handler = (e) => {
      if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [menuOpen]);

  return (
    <div style={{
      padding: '10px 12px', borderRadius: 10, display: 'flex', alignItems: 'center', gap: 12,
      cursor: 'pointer', transition: 'background 0.15s',
    }}
    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      <FileBadge ext={f.ext} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {f.name}
        </div>
        <div style={{ fontSize: 11, color: 'var(--mute)', marginTop: 3, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
          <span>{f.size}</span>
          <span>·</span>
          <span>{f.added || 'just now'}</span>
          {f.practice && (
            <>
              <span>·</span>
              <span style={{ color: 'var(--ink-2)' }}>{f.practice}</span>
            </>
          )}
        </div>
      </div>
      {f.conf && <span className={`conf ${f.conf}`}>{f.conf}</span>}
      <div ref={menuRef} style={{ position: 'relative' }}>
        <button onClick={(e) => { e.stopPropagation(); setMenuOpen(o => !o); }} style={{
          width: 28, height: 28, borderRadius: 7, background: 'transparent', border: 'none',
          cursor: 'pointer', color: 'var(--mute)', display: 'grid', placeItems: 'center',
        }}
        onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-soft)'; e.currentTarget.style.color = 'var(--ink)'; }}
        onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--mute)'; }}
        >
          <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>
        </button>
        {menuOpen && (
          <div style={{
            position: 'absolute', right: 0, top: '100%', marginTop: 4, width: 140,
            background: 'white', border: '1px solid var(--line-2)', borderRadius: 10,
            boxShadow: '0 8px 24px rgba(26,22,20,0.12)', zIndex: 30, overflow: 'hidden',
          }}>
            {onDownload && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onDownload(); }} style={fileMenuItemStyle}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M8 3v8M4 8l4 4 4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M3 13h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
                Download
              </button>
            )}
            {onRemove && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onRemove(); }} style={{ ...fileMenuItemStyle, color: 'var(--maroon)' }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M3 5h10M6 5V3h4v2M7 8v4M9 8v4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M5 5l.5 8h5l.5-8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Delete
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

const FileBadge = ({ ext, size = 'sm' }) => {
  const dims = size === 'lg' ? { w: 48, h: 56, fs: 11 } : { w: 32, h: 38, fs: 9 };
  return (
    <div style={{
      width: dims.w, height: dims.h, borderRadius: 5,
      background: extColors[ext] || '#888', color: 'white',
      display: 'grid', placeItems: 'center',
      fontSize: dims.fs, fontWeight: 700, flexShrink: 0,
      letterSpacing: '0.04em',
    }}>{(ext || 'doc').toUpperCase()}</div>
  );
};

const crumbBtn = {
  background: 'transparent', border: 'none', cursor: 'pointer',
  fontSize: 13, fontFamily: 'inherit', color: 'var(--mute)', padding: 0,
};

// ──────────────────────────────────────────────────────────────────────────────
// Add Sources Modal — used by Library
// ──────────────────────────────────────────────────────────────────────────────
const AddSourcesModal = ({ open, onClose, onFilesSelected, onSharePoint, onTextInput, onUrlInput, sourceContext = 'library' }) => {
  const [dragHover, setDragHover] = React.useState(false);
  if (!open) return null;
  const subtitle = sourceContext === 'library'
    ? 'Add to the firm-wide Library — everything is searchable across projects.'
    : 'Add to this project. Files only chat inside this project unless you share them.';

  const handleFiles = (files) => {
    onClose();
    onFilesSelected(files);
  };

  return (
    <ModalShell onClose={onClose} width={620} title="Add sources" subtitle={subtitle} headerBorder={false}>
      <div style={{ padding: '8px 24px 24px' }}>
        <label
          onDragEnter={e => { e.preventDefault(); setDragHover(true); }}
          onDragOver={e => { e.preventDefault(); setDragHover(true); }}
          onDragLeave={() => setDragHover(false)}
          onDrop={e => { e.preventDefault(); setDragHover(false); handleFiles(Array.from(e.dataTransfer.files)); }}
          style={{
            height: 240, borderRadius: 14,
            border: `1.5px dashed ${dragHover ? 'var(--maroon)' : 'var(--line-2)'}`,
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
            cursor: 'pointer', transition: 'all 0.15s',
            background: dragHover ? 'var(--maroon-wash)' : 'var(--bg-soft)',
            position: 'relative',
          }}
        >
          <input type="file" multiple onChange={e => handleFiles(Array.from(e.target.files))} style={{
            position: 'absolute', inset: 0, opacity: 0, cursor: 'pointer',
          }}/>
          <div style={{
            width: 48, height: 48, borderRadius: 12,
            background: 'white', border: '1px solid var(--line)',
            display: 'grid', placeItems: 'center',
            marginBottom: 12, boxShadow: 'var(--shadow-xs)',
          }}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
              <path d="M12 16V5M7 10l5-5 5 5" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
              <path d="M4 16v2.5A1.5 1.5 0 0 0 5.5 20h13a1.5 1.5 0 0 0 1.5-1.5V16" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round"/>
            </svg>
          </div>
          <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)', marginBottom: 4 }}>Drop files here, or click to browse</div>
          <div style={{ fontSize: 12, color: 'var(--mute)' }}>PDF, DOCX, PPTX, XLSX, MP4, images · up to 50 files</div>
        </label>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginTop: 14 }}>
          <SourceBtn icon={<UploadIcon/>} label="Upload" onClick={() => {
            const inp = document.createElement('input');
            inp.type = 'file'; inp.multiple = true;
            inp.onchange = e => handleFiles(Array.from(e.target.files));
            inp.click();
          }}/>
          <SourceBtn icon={<TextIcon/>}       label="Text input" onClick={() => { onClose(); onTextInput && onTextInput(); }}/>
          <SourceBtn icon={<UrlIcon/>}        label="URL"        onClick={() => { onClose(); onUrlInput && onUrlInput(); }}/>
          <SourceBtn icon={<SharepointIcon/>} label="SharePoint" onClick={() => { onClose(); onSharePoint && onSharePoint(); }}/>
        </div>

        <div style={{
          marginTop: 14, padding: '10px 12px', borderRadius: 9,
          background: 'var(--maroon-wash)', border: '1px solid var(--maroon-10)',
          fontSize: 12, color: 'var(--ink-2)', display: 'flex', gap: 8, alignItems: 'center',
        }}>
          <span style={{ color: 'var(--maroon)', fontWeight: 600 }}>Next:</span>
          You'll set Confidentiality status and Practice for each file before it's saved.
        </div>
      </div>
    </ModalShell>
  );
};

const SourceBtn = ({ icon, label, onClick }) => (
  <button onClick={onClick} style={{
    padding: '10px 8px', borderRadius: 10,
    background: 'white', border: '1px solid var(--line-2)',
    cursor: 'pointer', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5,
    fontFamily: 'inherit', transition: 'all 0.15s',
  }}
  onMouseEnter={e => { e.currentTarget.style.borderColor = 'var(--maroon-20)'; e.currentTarget.style.background = 'var(--maroon-wash)'; }}
  onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--line-2)';    e.currentTarget.style.background = 'white'; }}
  >
    {icon}
    <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink)' }}>{label}</span>
  </button>
);

const UploadIcon = () => (
  <svg width="18" height="18" viewBox="0 0 22 22" fill="none">
    <path d="M11 14V4M6.5 8.5L11 4l4.5 4.5" stroke="var(--maroon)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
    <path d="M4 14v3a1.5 1.5 0 0 0 1.5 1.5h11A1.5 1.5 0 0 0 18 17v-3" stroke="var(--maroon)" strokeWidth="1.6" strokeLinecap="round"/>
  </svg>
);
const TextIcon = () => (
  <svg width="18" height="18" viewBox="0 0 22 22" fill="none">
    <rect x="3.5" y="3.5" width="15" height="15" rx="2.5" stroke="var(--maroon)" strokeWidth="1.6"/>
    <path d="M7 8h8M7 11h8M7 14h5" stroke="var(--maroon)" strokeWidth="1.6" strokeLinecap="round"/>
  </svg>
);
const UrlIcon = () => (
  <svg width="18" height="18" viewBox="0 0 22 22" fill="none">
    <path d="M9 13a3.5 3.5 0 0 0 5 0l2.5-2.5a3.5 3.5 0 0 0-5-5L10 7"
          stroke="var(--maroon)" strokeWidth="1.6" strokeLinecap="round"/>
    <path d="M13 9a3.5 3.5 0 0 0-5 0l-2.5 2.5a3.5 3.5 0 0 0 5 5L12 15"
          stroke="var(--maroon)" strokeWidth="1.6" strokeLinecap="round"/>
  </svg>
);
const SharepointIcon = () => (
  <svg width="18" height="18" viewBox="0 0 22 22" fill="none">
    <path d="M11 3a8 8 0 0 1 0 16M11 3v16M3 11a8 8 0 0 0 16 0M3 11a8 8 0 0 1 16 0" stroke="var(--maroon)" strokeWidth="1.4"/>
  </svg>
);

// ──────────────────────────────────────────────────────────────────────────────
// LIBRARY
// ──────────────────────────────────────────────────────────────────────────────
const LIB_FILES = [
  { name: 'Public Policy Whitepaper 2026.pdf', ext: 'pdf',  size: '6.2 MB',  modified: '12 May 2026', conf: 'public',   practice: 'Public Policy Realization' },
  { name: 'GCC Fintech Sector Map.png',         ext: 'png',  size: '2.1 MB',  modified: '10 May 2026', conf: 'internal', practice: 'Sector Potential Realization' },
  { name: 'Sector Outlook · KSA.pptx',          ext: 'pptx', size: '14.8 MB', modified: '08 May 2026', conf: 'internal', practice: 'Sector Potential Realization' },
  { name: 'TCFD Compliance Matrix.xlsx',        ext: 'xlsx', size: '3.4 MB',  modified: '04 May 2026', conf: 'public',   practice: 'Economic Potential Realization' },
  { name: 'Renewables Capex 2026.pdf',          ext: 'pdf',  size: '4.8 MB',  modified: '30 Apr 2026', conf: 'public',   practice: 'Economic Potential Realization' },
  { name: 'CFO interview transcript.docx',      ext: 'docx', size: '180 KB',  modified: '22 Apr 2026', conf: 'client',   practice: 'Sector Potential Realization' },
  { name: 'Cost build · Phase 1.xlsx',          ext: 'xlsx', size: '2.4 MB',  modified: '18 Apr 2026', conf: 'client',   practice: 'Transaction Realization' },
];

const adaptLibraryFile = (f) => {
  const ext = (f.file_name || '').split('.').pop().toLowerCase() || 'doc';
  const bytes = f.file_size || 0;
  const size = bytes < 1024 ? `${bytes} B` : bytes < 1048576 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1048576).toFixed(1)} MB`;
  return {
    id: f.id,
    name: f.file_name || f.name || '',
    ext,
    size: size || '',
    modified: f.uploaded_at ? new Date(f.uploaded_at).toLocaleDateString('en-IN', { day: 'numeric', month: 'short', year: 'numeric' }) : '—',
    conf: f.confidentiality || 'internal',
    practice: (f.tags && f.tags.length > 0) ? f.tags[0] : '',
  };
};

const ScreenLibrary = ({ openAddSources, libraryFiles, onDeleteFile, onDownloadFile }) => {
  const [filter, setFilter] = React.useState('all');
  const [q, setQ] = React.useState('');

  const sourceFiles = (libraryFiles && libraryFiles.length > 0) ? libraryFiles.map(adaptLibraryFile) : [];

  const filtered = sourceFiles.filter(f =>
    (filter === 'all'
      || (filter === 'images' && (f.ext === 'png' || f.ext === 'jpg'))
      || (filter === 'docs'   && (f.ext === 'pdf' || f.ext === 'docx'))
      || (filter === 'sheets' && f.ext === 'xlsx')
      || (filter === 'decks'  && f.ext === 'pptx')
    ) && (!q || f.name.toLowerCase().includes(q.toLowerCase()))
  );

  return (
    <div style={contentArea}>
      <div style={{ padding: '40px 48px 40px', maxWidth: 1280, margin: '0 auto' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 28 }}>
          <div>
            <h1 className="serif" style={{ fontSize: 28, fontWeight: 500, margin: 0, letterSpacing: '-0.02em' }}>Library</h1>
            <p style={{ fontSize: 13, color: 'var(--mute)', margin: '6px 0 0' }}>
              Firm-wide knowledge base — searchable across every chat.
            </p>
          </div>
          <button className="btn-primary" onClick={openAddSources}>
            <PIcon name="plus" size={14} color="white" /> Add sources
          </button>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 18 }}>
          <div style={{ display: 'flex', gap: 4, background: 'var(--bg-soft)', padding: 4, borderRadius: 10, border: '1px solid var(--line)' }}>
            {[
              { id: 'all',    l: 'All',    n: sourceFiles.length },
              { id: 'docs',   l: 'Docs',   n: sourceFiles.filter(f => f.ext === 'pdf' || f.ext === 'docx').length },
              { id: 'decks',  l: 'Decks',  n: sourceFiles.filter(f => f.ext === 'pptx').length },
              { id: 'sheets', l: 'Sheets', n: sourceFiles.filter(f => f.ext === 'xlsx').length },
              { id: 'images', l: 'Images', n: sourceFiles.filter(f => f.ext === 'png' || f.ext === 'jpg').length },
            ].map(t => (
              <button key={t.id} onClick={() => setFilter(t.id)} style={{
                padding: '7px 14px', borderRadius: 7,
                background: filter === t.id ? 'white' : 'transparent',
                border: 'none', cursor: 'pointer',
                fontSize: 13, fontWeight: filter === t.id ? 600 : 500,
                color: filter === t.id ? 'var(--ink)' : 'var(--mute)',
                fontFamily: 'inherit',
                boxShadow: filter === t.id ? 'var(--shadow-xs)' : 'none',
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}>
                {t.l}
                <span style={{ fontSize: 11, color: 'var(--mute-2)', fontWeight: 500 }}>{t.n}</span>
              </button>
            ))}
          </div>
          <div style={{ flex: 1 }} />
          <div className="search-input" style={{ width: 260, height: 36 }}>
            <PIcon name="search" size={16} color="var(--mute)" />
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search library"/>
          </div>
        </div>

        {sourceFiles.length === 0 && !q && (
          <div style={{
            padding: '60px 20px', borderRadius: 14, background: 'white',
            border: '1px dashed var(--line-2)', textAlign: 'center',
            fontSize: 14, color: 'var(--mute)',
          }}>
            No files in the library yet.{' '}
            <button onClick={openAddSources} style={{ background: 'none', border: 'none', color: 'var(--maroon)', fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', fontSize: 14 }}>
              Add your first source.
            </button>
          </div>
        )}

        {sourceFiles.length > 0 && (
        <div style={{ background: 'white', borderRadius: 14, border: '1px solid var(--line)', overflow: 'hidden' }}>
          <div style={{
            display: 'grid', gridTemplateColumns: '1fr 180px 160px 40px',
            padding: '12px 18px', fontSize: 11, color: 'var(--mute)', fontWeight: 600,
            letterSpacing: '0.06em', textTransform: 'uppercase',
            borderBottom: '1px solid var(--line)', background: 'var(--bg-soft)',
          }}>
            <div>Name</div>
            <div>Confidentiality</div>
            <div>Modified</div>
            <div></div>
          </div>
          {filtered.length === 0 && (
            <div style={{ padding: '24px 18px', fontSize: 13, color: 'var(--mute)', textAlign: 'center' }}>
              No files match your filter.
            </div>
          )}
          {filtered.map((f, i) => (
            <LibraryFileRow
              key={f.id || i}
              f={f}
              isLast={i === filtered.length - 1}
              onDownload={onDownloadFile ? () => onDownloadFile(f.id) : null}
              onDelete={onDeleteFile ? () => onDeleteFile(f.id) : null}
            />
          ))}
        </div>
        )}
      </div>
    </div>
  );
};

// ──────────────────────────────────────────────────────────────────────────────
// APPS
// ──────────────────────────────────────────────────────────────────────────────
const APPS = [
  { id: 'prima',   name: 'PRIMA',     blurb: 'Deep market & literature research engine — searches projects, library, and the firm knowledge graph.', accent: '#7A1C1C' },
  { id: 'rfp',     name: 'RFP Maker', blurb: 'Drafts proposals, cost calculators and storylines from prior winning bids and project artefacts.',     accent: '#876200' },
  { id: 'climate', name: 'ClimateIQ', blurb: 'Sustainability disclosures, scope mapping, TCFD & CSRD drafting, greenwashing-risk scoring.',          accent: '#2E6F40' },
];

const ScreenApplications = ({ setRoute }) => (
  <div style={contentArea}>
    <div style={{ padding: '40px 48px 40px', maxWidth: 1280, margin: '0 auto' }}>
      <div style={{ marginBottom: 28 }}>
        <h1 className="serif" style={{ fontSize: 28, fontWeight: 500, margin: 0, letterSpacing: '-0.02em' }}>Applications</h1>
        <p style={{ fontSize: 13, color: 'var(--mute)', margin: '6px 0 0' }}>
          Domain engines that chat with your projects, the library, and the firm's knowledge graph.
        </p>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16 }}>
        {APPS.map(app => (
          <div key={app.id} onClick={() => setRoute(`app-${app.id}`)} style={{
            padding: 22, borderRadius: 16,
            background: 'white', border: '1px solid var(--line)',
            cursor: 'pointer', transition: 'all 0.18s',
            display: 'flex', flexDirection: 'column', gap: 16,
          }}
          onMouseEnter={e => { e.currentTarget.style.boxShadow = '0 10px 24px rgba(60,30,20,0.08)'; e.currentTarget.style.borderColor = app.accent + '30'; e.currentTarget.style.transform = 'translateY(-2px)'; }}
          onMouseLeave={e => { e.currentTarget.style.boxShadow = 'none'; e.currentTarget.style.borderColor = 'var(--line)'; e.currentTarget.style.transform = 'translateY(0)'; }}
          >
            <div style={{
              width: 44, height: 44, borderRadius: 12,
              background: app.accent + '14', color: app.accent,
              display: 'grid', placeItems: 'center',
            }}>
              <AppIcon id={app.id} color={app.accent}/>
            </div>
            <div>
              <h3 style={{ fontSize: 18, fontWeight: 600, margin: 0, color: 'var(--ink)' }}>{app.name}</h3>
              <p style={{ fontSize: 13, lineHeight: 1.5, color: 'var(--mute)', margin: '6px 0 0' }}>{app.blurb}</p>
            </div>
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, color: app.accent, fontWeight: 600 }}>
              Open {app.name}
              <svg width="12" height="12" viewBox="0 0 12 12"><path d="M2 6h8M7 2l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" fill="none"/></svg>
            </div>
          </div>
        ))}
      </div>
    </div>
  </div>
);

const AppIcon = ({ id, color }) => (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
    {id === 'prima'   && <><circle cx="11" cy="11" r="6.5" stroke={color} strokeWidth="1.6"/><path d="M20 20l-3.5-3.5" stroke={color} strokeWidth="1.6" strokeLinecap="round"/></>}
    {id === 'rfp'     && <><path d="M5 4h10l4 4v12a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Z" stroke={color} strokeWidth="1.6"/><path d="M14 4v5h5M8 13h8M8 16h5" stroke={color} strokeWidth="1.6"/></>}
    {id === 'climate' && <><path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7l8-4Z" stroke={color} strokeWidth="1.6"/><path d="M8.5 12l2.5 2.5L15.5 9.5" stroke={color} strokeWidth="1.6" strokeLinecap="round"/></>}
  </svg>
);

const ScreenAppDetail = ({ appId, setRoute }) => {
  const app = APPS.find(a => a.id === appId) || APPS[0];
  return (
    <div style={contentArea}>
      <div style={{ padding: '40px 48px 40px', maxWidth: 1200, margin: '0 auto' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--mute)', marginBottom: 22 }}>
          <button onClick={() => setRoute('apps')} style={crumbBtn}>Applications</button>
          <span>/</span>
          <span style={{ color: 'var(--ink)', fontWeight: 500 }}>{app.name}</span>
        </div>

        <div style={{
          padding: 28, borderRadius: 18,
          background: `linear-gradient(135deg, ${app.accent}0C 0%, transparent 70%)`,
          border: `1px solid ${app.accent}25`,
          display: 'flex', alignItems: 'center', gap: 20, marginBottom: 24,
        }}>
          <div style={{
            width: 56, height: 56, borderRadius: 14,
            background: app.accent, color: 'white',
            display: 'grid', placeItems: 'center',
          }}>
            <AppIcon id={app.id} color="white" />
          </div>
          <div style={{ flex: 1 }}>
            <h2 className="serif" style={{ fontSize: 22, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>{app.name}</h2>
            <p style={{ fontSize: 13, color: 'var(--mute)', margin: '4px 0 0', maxWidth: 540, lineHeight: 1.5 }}>{app.blurb}</p>
          </div>
          <button className="btn-primary" onClick={() => setRoute('chat')}>Start a new chat →</button>
        </div>

        <div style={{ fontSize: 11, color: 'var(--mute)', fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 12 }}>
          Recent {app.name} chats
        </div>
        <div style={{ background: 'white', borderRadius: 14, border: '1px solid var(--line)', overflow: 'hidden' }}>
          {[
            { t: 'GCC fintech IPO scan · 2021–2026', when: '2h ago' },
            { t: 'Renewables capex benchmarking',     when: '1d ago' },
            { t: 'TCFD gap analysis · portfolio co.', when: '4d ago' },
          ].map((c, i, arr) => (
            <div key={c.t} style={{
              padding: '12px 18px', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              borderBottom: i < arr.length - 1 ? '1px solid var(--line)' : 'none', cursor: 'pointer',
              transition: 'background 0.12s',
            }}
            onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
            onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
            >
              <span style={{ fontSize: 14, color: 'var(--ink)' }}>{c.t}</span>
              <span style={{ fontSize: 12, color: 'var(--mute)' }}>{c.when}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ──────────────────────────────────────────────────────────────────────────────
// SEARCH
// ──────────────────────────────────────────────────────────────────────────────
const ScreenSearch = ({ setRoute, allProjects = [], onOpenProject }) => {
  const [q, setQ] = React.useState('');
  const adapted = allProjects.map(adaptProject);
  const matches = q
    ? adapted.filter(p =>
        p.name.toLowerCase().includes(q.toLowerCase()) ||
        (p.desc && p.desc.toLowerCase().includes(q.toLowerCase())) ||
        (p.tag && p.tag.toLowerCase().includes(q.toLowerCase()))
      )
    : [];
  return (
    <div style={contentArea}>
      <div style={{ padding: '40px 48px 40px', maxWidth: 820, margin: '0 auto' }}>
        <h1 className="serif" style={{ fontSize: 28, fontWeight: 500, margin: 0, letterSpacing: '-0.02em', marginBottom: 6 }}>Search</h1>
        <p style={{ fontSize: 13, color: 'var(--mute)', margin: '0 0 22px' }}>
          Across all projects in the firm — your own and your colleagues'.
        </p>
        <div className="search-input" style={{ height: 52, paddingLeft: 18 }}>
          <PIcon name="search" size={18} color="var(--mute)" />
          <input value={q} onChange={e => setQ(e.target.value)} placeholder="Try “GCC fintech”, “TCFD”, “MSME financing”…" autoFocus />
        </div>

        {!q && (
          <div style={{ marginTop: 32, textAlign: 'center', color: 'var(--mute)', fontSize: 13 }}>
            Start typing to search across all projects.
          </div>
        )}

        {q && (
          <>
            <div style={{ fontSize: 12, color: 'var(--mute)', margin: '24px 0 10px' }}>
              {matches.length} projects matching “{q}”
            </div>
            <div style={{ display: 'grid', gap: 10 }}>
              {matches.map(p => {
                const isMember = p.membership !== null;
                const isOwner = p.membership === 'owner';
                return <SearchProjectRow key={p.id} p={p} isMember={isMember} isOwner={isOwner} setRoute={setRoute} onOpenProject={onOpenProject}/>;
              })}
              {matches.length === 0 && (
                <div style={{ padding: 24, borderRadius: 12, background: 'white', border: '1px solid var(--line)', fontSize: 13, color: 'var(--mute)', textAlign: 'center' }}>
                  No projects matched. Try a different keyword.
                </div>
              )}
            </div>
          </>
        )}
      </div>
    </div>
  );
};

const SearchProjectRow = ({ p, isMember, isOwner, setRoute, onOpenProject }) => {
  const [requested, setRequested] = React.useState(p.hasPendingRequest || false);
  const handleRequestJoin = async () => {
    try {
      await PrimusAPI.joinProject(p.id);
      setRequested(true);
    } catch { setRequested(true); }
  };
  return (
    <div style={{
      background: 'white', border: '1px solid var(--line)', borderRadius: 12,
      padding: 14, display: 'flex', alignItems: 'center', gap: 14,
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 9,
        background: isMember ? 'var(--maroon-06)' : 'var(--bg-soft)',
        color: isMember ? 'var(--maroon)' : 'var(--mute)',
        display: 'grid', placeItems: 'center', flexShrink: 0,
      }}>
        <PIcon name="folder" size={17} color={isMember ? 'var(--maroon)' : 'var(--mute)'} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>{p.name}</div>
          {isMember && p.membership && (
            <span className={`role-badge ${p.membership}`}>{p.membership.toUpperCase()}</span>
          )}
          {p.tag && <span className="tag-pill">{p.tag}</span>}
        </div>
        <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 3, display: '-webkit-box', WebkitLineClamp: 1, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{p.desc}</div>
      </div>
      {isMember ? (
        <button onClick={() => { onOpenProject && onOpenProject(p.id); setRoute('project-detail'); }} className="btn-secondary" style={{ height: 34, padding: '0 12px', fontSize: 13 }}>Open</button>
      ) : (
        <button onClick={handleRequestJoin} disabled={requested} style={{
          height: 34, padding: '0 14px', borderRadius: 8,
          background: requested ? 'var(--bg-soft)' : 'var(--maroon)',
          color: requested ? 'var(--mute)' : 'white', border: 'none',
          fontSize: 12, fontFamily: 'inherit', fontWeight: 600,
          cursor: requested ? 'default' : 'pointer',
        }}>{requested ? '✓ Requested' : 'Request to join'}</button>
      )}
    </div>
  );
};

const fileMenuItemStyle = {
  width: '100%', padding: '9px 14px', background: 'transparent', border: 'none',
  cursor: 'pointer', textAlign: 'left', fontSize: 13, fontFamily: 'inherit',
  color: 'var(--ink)', display: 'flex', alignItems: 'center', gap: 8,
  transition: 'background 0.12s',
};

const LibraryFileRow = ({ f, isLast, onDownload, onDelete }) => {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const menuRef = React.useRef(null);
  React.useEffect(() => {
    if (!menuOpen) return;
    const handler = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [menuOpen]);
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '1fr 180px 160px 40px',
      padding: '12px 18px', alignItems: 'center',
      borderBottom: isLast ? 'none' : '1px solid var(--line)',
      cursor: 'pointer', transition: 'background 0.12s',
    }}
    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <FileBadge ext={f.ext} />
        <div>
          <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 500 }}>{f.name}</div>
          <div style={{ fontSize: 11, color: 'var(--mute)' }}>{f.size}</div>
        </div>
      </div>
      <div><span className={`conf ${f.conf}`}>{f.conf}</span></div>
      <div style={{ fontSize: 12, color: 'var(--mute)' }}>{f.modified}</div>
      <div ref={menuRef} style={{ textAlign: 'right', position: 'relative' }}>
        <button onClick={(e) => { e.stopPropagation(); setMenuOpen(o => !o); }} style={{
          width: 28, height: 28, borderRadius: 7, background: 'transparent', border: 'none',
          cursor: 'pointer', color: 'var(--mute)', display: 'grid', placeItems: 'center',
        }}>
          <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.3"/><circle cx="8" cy="8" r="1.3"/><circle cx="13" cy="8" r="1.3"/></svg>
        </button>
        {menuOpen && (
          <div style={{
            position: 'absolute', right: 0, top: '100%', marginTop: 4, width: 140,
            background: 'white', border: '1px solid var(--line-2)', borderRadius: 10,
            boxShadow: '0 8px 24px rgba(26,22,20,0.12)', zIndex: 30, overflow: 'hidden',
          }}>
            {onDownload && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onDownload(); }} style={fileMenuItemStyle}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M8 3v8M4 8l4 4 4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M3 13h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
                Download
              </button>
            )}
            {onDelete && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onDelete(); }} style={{ ...fileMenuItemStyle, color: 'var(--maroon)' }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M3 5h10M6 5V3h4v2M7 8v4M9 8v4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M5 5l.5 8h5l.5-8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Delete
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

const EditProjectModal = ({ open, project, onClose, onSave }) => {
  const [name, setName] = React.useState('');
  const [practice, setPractice] = React.useState('');
  const [desc, setDesc] = React.useState('');
  const [saving, setSaving] = React.useState(false);

  React.useEffect(() => {
    if (open && project) {
      setName(project.name || '');
      setPractice(project.practice || '');
      setDesc(project.description || project.desc || '');
    }
  }, [open, project?.id]);

  if (!open) return null;

  const handleSave = async () => {
    if (!project?.id) return;
    setSaving(true);
    try {
      await PrimusAPI.updateProject(project.id, { name, practice, description: desc });
      if (onSave) onSave({ name, practice, description: desc });
      onClose();
    } catch (ex) {
      console.error('Edit project failed:', ex);
    } finally { setSaving(false); }
  };

  return (
    <ModalShell onClose={onClose} width={520} title="Edit project" subtitle="Update project name, practice or description.">
      <div style={{ padding: '0 24px 24px', display: 'flex', flexDirection: 'column', gap: 18 }}>
        <Field label="Project name">
          <input value={name} onChange={e => setName(e.target.value)} placeholder="Project name" style={fieldInput}/>
        </Field>
        <Field label="Practice">
          <select value={practice} onChange={e => setPractice(e.target.value)} style={fieldInput}>
            {PRACTICES.map(p => <option key={p} value={p}>{p}</option>)}
          </select>
        </Field>
        <Field label="Description" hint="Optional.">
          <textarea value={desc} onChange={e => setDesc(e.target.value)} rows={3}
            style={{ ...fieldInput, height: 'auto', padding: '12px 14px', resize: 'none' }}/>
        </Field>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 4 }}>
          <button className="btn-secondary" onClick={onClose}>Cancel</button>
          <button className="btn-primary" onClick={handleSave} disabled={!name || saving}>
            {saving ? 'Saving…' : 'Save changes'}
          </button>
        </div>
      </div>
    </ModalShell>
  );
};

// ──────────────────────────────────────────────────────────────────────────────
// Profile page — full-page view of the current user's profile
// ──────────────────────────────────────────────────────────────────────────────
const ProfileTagList = ({ items, editing, onChange, placeholder }) => {
  const [input, setInput] = React.useState('');
  const add = () => {
    const v = input.trim();
    if (v && !items.includes(v)) onChange([...items, v]);
    setInput('');
  };
  if (!editing) return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
      {items.length === 0
        ? <span style={{ fontSize: 13, color: 'var(--mute)' }}>—</span>
        : items.map(item => (
          <span key={item} style={{ padding: '3px 10px', borderRadius: 20, background: 'var(--maroon-06)', color: 'var(--maroon)', fontSize: 12, fontWeight: 500 }}>{item}</span>
        ))}
    </div>
  );
  return (
    <div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: items.length ? 6 : 0 }}>
        {items.map(item => (
          <span key={item} style={{ padding: '3px 10px', borderRadius: 20, background: 'var(--maroon-06)', color: 'var(--maroon)', fontSize: 12, fontWeight: 500, display: 'flex', alignItems: 'center', gap: 4 }}>
            {item}
            <button onClick={() => onChange(items.filter(i => i !== item))} style={{ width: 14, height: 14, border: 'none', background: 'none', cursor: 'pointer', color: 'var(--maroon)', fontSize: 14, padding: 0, lineHeight: 1 }}>×</button>
          </span>
        ))}
      </div>
      <div style={{ display: 'flex', gap: 6 }}>
        <input value={input} onChange={e => setInput(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); add(); } }}
          placeholder={placeholder}
          style={{ flex: 1, height: 34, padding: '0 12px', borderRadius: 8, border: '1px solid var(--line-2)', background: 'white', fontSize: 13, fontFamily: 'inherit', color: 'var(--ink)' }}
        />
        <button onClick={add} className="btn-secondary" style={{ height: 34, padding: '0 12px', fontSize: 13 }}>Add</button>
      </div>
    </div>
  );
};

const ProfileInfoCard = ({ title, children }) => (
  <div style={{ background: 'white', border: '1px solid var(--line)', borderRadius: 14, padding: 22, display: 'flex', flexDirection: 'column', gap: 16 }}>
    <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink-2)', textTransform: 'uppercase', letterSpacing: '0.07em' }}>{title}</div>
    {children}
  </div>
);

const ProfileInfoField = ({ label, children }) => (
  <div>
    <div style={{ fontSize: 11, color: 'var(--mute)', fontWeight: 600, letterSpacing: '0.05em', textTransform: 'uppercase', marginBottom: 5 }}>{label}</div>
    {children}
  </div>
);

const ScreenProfile = ({ currentUser, onBack }) => {
  const [profile, setProfile] = React.useState(null);
  const [editing, setEditing] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [fullName, setFullName] = React.useState('');
  const [yoe, setYoe] = React.useState('');
  const [primaryDomain, setPrimaryDomain] = React.useState('');
  const [secondaryDomain, setSecondaryDomain] = React.useState('');
  const [skills, setSkills] = React.useState([]);
  const [tools, setTools] = React.useState([]);
  const [methodologies, setMethodologies] = React.useState([]);
  const [industries, setIndustries] = React.useState([]);
  const [regions, setRegions] = React.useState([]);
  const [languages, setLanguages] = React.useState([]);

  React.useEffect(() => {
    PrimusAPI.getMe().then(data => {
      setProfile(data);
      setFullName(data.full_name || '');
      setYoe(String(data.yoe ?? ''));
      setPrimaryDomain(data.primary_domain || '');
      setSecondaryDomain(data.secondary_domain || '');
      setSkills(data.skills || []);
      setTools(data.tools || []);
      setMethodologies(data.methodologies || []);
      setIndustries(data.industries || []);
      setRegions(data.regions || []);
      setLanguages(data.languages || []);
    }).catch(() => {});
  }, []);

  const handleSave = async () => {
    setSaving(true);
    try {
      const updated = await PrimusAPI.updateMe({
        full_name: fullName,
        yoe: parseInt(yoe) || 0,
        primary_domain: primaryDomain,
        secondary_domain: secondaryDomain,
        skills, tools, methodologies, industries, regions, languages,
      });
      setProfile(updated);
      setEditing(false);
    } catch (ex) { console.error('Save profile failed:', ex); }
    finally { setSaving(false); }
  };

  const cancelEdit = () => {
    if (!profile) return;
    setFullName(profile.full_name || '');
    setYoe(String(profile.yoe ?? ''));
    setPrimaryDomain(profile.primary_domain || '');
    setSecondaryDomain(profile.secondary_domain || '');
    setSkills(profile.skills || []);
    setTools(profile.tools || []);
    setMethodologies(profile.methodologies || []);
    setIndustries(profile.industries || []);
    setRegions(profile.regions || []);
    setLanguages(profile.languages || []);
    setEditing(false);
  };

  if (!profile) return (
    <div style={contentArea}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
        <span style={{ fontSize: 13, color: 'var(--mute)' }}>Loading profile…</span>
      </div>
    </div>
  );

  const initials = profile.full_name
    ? profile.full_name.split(' ').filter(Boolean).map(w => w[0].toUpperCase()).slice(0, 2).join('')
    : '?';
  const designation = profile.designation
    ? profile.designation.split(/[\s_]/).map(w => w[0].toUpperCase() + w.slice(1)).join(' ')
    : '';
  const textInput = (value, setValue, placeholder = '') => ({
    value, onChange: e => setValue(e.target.value), placeholder,
    style: {
      width: '100%', height: 36, padding: '0 12px', borderRadius: 8,
      border: '1px solid var(--line-2)', background: 'white',
      fontSize: 13, fontFamily: 'inherit', color: 'var(--ink)',
    },
  });

  return (
    <div style={contentArea}>
      <div style={{ padding: '32px 48px 48px', maxWidth: 900, margin: '0 auto' }}>
        <button onClick={onBack} style={{ ...crumbBtn, display: 'flex', alignItems: 'center', gap: 6, marginBottom: 22 }}>
          <svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
          Back
        </button>

        {/* Header */}
        <div style={{ background: 'white', border: '1px solid var(--line)', borderRadius: 16, padding: '24px 28px', display: 'flex', alignItems: 'flex-start', gap: 20, marginBottom: 20 }}>
          <div style={{ width: 68, height: 68, borderRadius: 18, flexShrink: 0, background: 'var(--maroon)', color: 'white', display: 'grid', placeItems: 'center', fontSize: 24, fontWeight: 700 }}>{initials}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            {editing
              ? <input {...textInput(fullName, setFullName, 'Full name')} style={{ ...textInput(fullName, setFullName).style, fontSize: 20, fontWeight: 600, marginBottom: 8, height: 40 }}/>
              : <h1 className="serif" style={{ fontSize: 22, fontWeight: 500, margin: '0 0 6px', letterSpacing: '-0.02em' }}>{profile.full_name}</h1>
            }
            <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 8 }}>
              <span style={{ fontSize: 14, color: 'var(--ink-2)' }}>{designation}</span>
              <span style={{ color: 'var(--mute)' }}>·</span>
              <span style={{ fontSize: 13, color: 'var(--mute)' }}>{profile.primus_email}</span>
              <span className={`role-badge`} style={{ background: 'var(--bg-soft)', color: 'var(--ink-2)', border: '1px solid var(--line-2)', borderRadius: 6, padding: '2px 8px', fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.05em' }}>{profile.tier}</span>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
            {editing ? (
              <>
                <button className="btn-secondary" onClick={cancelEdit} style={{ height: 36 }}>Cancel</button>
                <button className="btn-primary" onClick={handleSave} disabled={saving} style={{ height: 36 }}>{saving ? 'Saving…' : 'Save changes'}</button>
              </>
            ) : (
              <button className="btn-secondary" onClick={() => setEditing(true)} style={{ height: 36, display: 'flex', alignItems: 'center', gap: 6 }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M11 2l3 3L5 14H2v-3L11 2z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Edit profile
              </button>
            )}
          </div>
        </div>

        {/* Info grid */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 18 }}>
          <ProfileInfoCard title="Basic info">
            <ProfileInfoField label="Employee code">
              <span style={{ fontSize: 14, color: 'var(--ink)' }}>{profile.emp_code || '—'}</span>
            </ProfileInfoField>
            <ProfileInfoField label="Years of experience">
              {editing
                ? <input type="number" value={yoe} onChange={e => setYoe(e.target.value)} style={{ width: 100, height: 34, padding: '0 10px', borderRadius: 8, border: '1px solid var(--line-2)', background: 'white', fontSize: 13, fontFamily: 'inherit' }}/>
                : <span style={{ fontSize: 14, color: 'var(--ink)' }}>{profile.yoe ?? '—'} yrs</span>
              }
            </ProfileInfoField>
            <ProfileInfoField label="Tier">
              <span style={{ fontSize: 14, color: 'var(--ink)', textTransform: 'capitalize' }}>{profile.tier || '—'}</span>
            </ProfileInfoField>
          </ProfileInfoCard>

          <ProfileInfoCard title="Domain & expertise">
            <ProfileInfoField label="Primary domain">
              {editing
                ? <input {...textInput(primaryDomain, setPrimaryDomain, 'e.g. Financial Services')}/>
                : <span style={{ fontSize: 14, color: 'var(--ink)' }}>{profile.primary_domain || '—'}</span>
              }
            </ProfileInfoField>
            <ProfileInfoField label="Secondary domain">
              {editing
                ? <input {...textInput(secondaryDomain, setSecondaryDomain, 'e.g. Public Policy')}/>
                : <span style={{ fontSize: 14, color: 'var(--ink)' }}>{profile.secondary_domain || '—'}</span>
              }
            </ProfileInfoField>
            <ProfileInfoField label="Skills">
              <ProfileTagList items={skills} editing={editing} onChange={setSkills} placeholder="Add a skill, press Enter"/>
            </ProfileInfoField>
            <ProfileInfoField label="Tools">
              <ProfileTagList items={tools} editing={editing} onChange={setTools} placeholder="Add a tool, press Enter"/>
            </ProfileInfoField>
            <ProfileInfoField label="Methodologies">
              <ProfileTagList items={methodologies} editing={editing} onChange={setMethodologies} placeholder="Add a methodology, press Enter"/>
            </ProfileInfoField>
          </ProfileInfoCard>

          <ProfileInfoCard title="Industry & geography">
            <ProfileInfoField label="Industries">
              <ProfileTagList items={industries} editing={editing} onChange={setIndustries} placeholder="Add an industry, press Enter"/>
            </ProfileInfoField>
            <ProfileInfoField label="Regions">
              <ProfileTagList items={regions} editing={editing} onChange={setRegions} placeholder="Add a region, press Enter"/>
            </ProfileInfoField>
            <ProfileInfoField label="Languages">
              <ProfileTagList items={languages} editing={editing} onChange={setLanguages} placeholder="Add a language, press Enter"/>
            </ProfileInfoField>
          </ProfileInfoCard>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, {
  ScreenProjectDetail, ScreenLibrary, ScreenApplications, ScreenAppDetail, ScreenSearch, ScreenProfile,
  AddSourcesModal, FileBadge, FileRow, LibraryFileRow, EditProjectModal,
  UPLOADED_SEED, extColors, APPS, PRACTICES, adaptLibraryFile, fileMenuItemStyle,
});
