// Primus IQ — New Chat & Projects screens
// Minimalist. Projects has two tabs: "Yours" (member of) and "Discover" (all in org with Join/Invite).

// ──────────────────────────────────────────────────────────────────────────────
// Greeting / New Chat
// ──────────────────────────────────────────────────────────────────────────────
const ScreenNewChat = ({ setRoute, openAddSources, currentUser }) => {
  const [val, setVal] = React.useState('');
  const [focused, setFocused] = React.useState(false);
  const hour = new Date().getHours();
  const greeting = hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening';
  const firstName = currentUser?.full_name?.split(' ')?.[0] || 'there';

  return (
    <div style={contentArea}>
      <div style={{
        position: 'absolute', inset: 0,
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
        padding: '0 48px',
      }}>
        {/* Greeting */}
        <h1 className="serif" style={{
          fontSize: 36, fontWeight: 400, margin: 0, marginBottom: 40,
          letterSpacing: '-0.025em', lineHeight: 1.05,
          textAlign: 'center',
        }}>
          <span style={{ color: 'var(--mute)' }}>{greeting},</span>{' '}
          <span className="wordmark">{firstName}</span>
        </h1>

        {/* Composer */}
        <div style={{ width: 720, maxWidth: '100%' }}>
          <div style={{
            background: 'var(--bg-card)', borderRadius: 18,
            border: `1px solid ${focused ? 'var(--maroon-20)' : 'var(--line-2)'}`,
            boxShadow: focused ? '0 0 0 4px var(--maroon-06), 0 12px 30px rgba(60,30,20,0.06)'
                              : '0 2px 10px rgba(60,30,20,0.04)',
            transition: 'all 0.2s',
            padding: '14px 14px 10px 18px',
          }}>
            <textarea
              value={val}
              onChange={e => setVal(e.target.value)}
              onFocus={() => setFocused(true)}
              onBlur={() => setFocused(false)}
              rows={2}
              placeholder="Ask Primus IQ — drop docs, pick an app, get an answer."
              style={{
                width: '100%', border: 'none', resize: 'none',
                fontFamily: 'inherit', fontSize: 16, color: 'var(--ink)',
                background: 'transparent', lineHeight: 1.5,
                padding: '4px 0',
              }}
            />
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}>
              <button onClick={openAddSources} style={composerIconBtn}>
                <PIcon name="plus" size={16} color="var(--ink-2)" />
              </button>
              <button style={composerChip}>
                <span style={{ width: 6, height: 6, borderRadius: 3, background: 'var(--maroon)' }} />
                Primus IQ
                <PIcon name="chev" size={12} color="var(--mute)" />
              </button>
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 12, color: 'var(--mute)' }}>{val.length} / 8,000</span>
              <button style={{
                width: 36, height: 36, borderRadius: 10,
                background: val ? 'var(--maroon)' : 'var(--bg-soft)',
                color: val ? 'white' : 'var(--mute-2)',
                border: 'none', cursor: val ? '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>

          {/* Quick starts */}
          <div style={{
            display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center',
            marginTop: 22,
          }}>
            {[
              { l: 'Summarize a project', icon: 'folder' },
              { l: 'Draft an RFP response',  icon: 'apps' },
              { l: 'Find an old whitepaper', icon: 'search' },
              { l: 'Open ClimateIQ',         icon: 'apps' },
            ].map(c => (
              <button key={c.l} style={chipBtn}>
                <PIcon name={c.icon} size={14} color="var(--maroon)" />
                {c.l}
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

const composerIconBtn = {
  width: 32, height: 32, borderRadius: 8,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'grid', placeItems: 'center',
  transition: 'all 0.15s',
};
const composerChip = {
  height: 32, padding: '0 10px', borderRadius: 8,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6,
  fontSize: 13, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
};
const chipBtn = {
  padding: '8px 14px', borderRadius: 999,
  background: 'var(--bg-card)', border: '1px solid var(--line)',
  fontSize: 13, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
  cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6,
  transition: 'all 0.15s',
};

// ──────────────────────────────────────────────────────────────────────────────
// Projects listing — Yours + Discover (org-wide directory)
// ──────────────────────────────────────────────────────────────────────────────
const SAMPLE_PROJECTS = [
  { id: 'p1', name: 'GCC Market Entry · Acme',  desc: 'Sector Potential Realization — KSA vs UAE entry sequencing, pricing strategy, talent map.', tag: 'Sector Potential Realization', role: 'OWNER',  files: 24, members: ['N', 'A', 'P'], more: 8,  updated: '24 May' },
  { id: 'p2', name: 'Globex APAC Reorg',         desc: 'Impact Realization — operating model redesign across 6 markets, change roadmap with cost guardrails.', tag: 'Impact Realization',        role: 'MEMBER', files: 38, members: ['N', 'M'],      more: 4,  updated: '22 May' },
  { id: 'p3', name: 'India Public Policy 2026', desc: 'Policy track for FY26 — state-level digital governance benchmarks and procurement reform notes.', tag: 'Public Policy Realization', role: 'OWNER',  files: 12, members: ['N', 'V'],      more: 20, updated: '18 May' },
  { id: 'p4', name: 'TCFD · Portfolio Co.',     desc: 'Climate disclosure rollup across 18 portfolio companies — Scope 1/2 baselines, gap remediation.', tag: 'Economic Potential Realization', role: 'MEMBER', files: 19, members: ['N', 'S'],     more: 5,  updated: '12 May' },
];

const DISCOVER_PROJECTS = [
  { id: 'd1', name: 'Indian MSME Financing',  desc: 'Quarterly research on fintech, NBFC and public scheme penetration in MSME credit.', tag: 'Economic Potential Realization', owner: 'A. Mehta',   members: 9,  files: 47, updated: '23 May' },
  { id: 'd2', name: 'Healthcare Supply Atlas', desc: 'Live corpus on global pharma logistics — 220 papers, 40 interviews, monthly refresh.',  tag: 'Transaction Realization',         owner: 'P. Rao',     members: 32, files: 220, updated: '20 May' },
  { id: 'd3', name: 'Auto OEM EV Roadmap',     desc: 'Buy-side diligence for an EV component supplier — capacity, IP, customer concentration.', tag: 'Sector Potential Realization',    owner: 'V. Kumar',   members: 6,  files: 31, updated: '19 May' },
  { id: 'd4', name: 'PSU Disinvestment Track', desc: 'Cross-firm track of PSU strategic-sale candidates, valuation desks and timelines.',     tag: 'Public Policy Realization',       owner: 'S. Iyer',    members: 14, files: 88, updated: '17 May' },
  { id: 'd5', name: 'GCC Renewables 2026',     desc: 'Annual thought-leadership flagship — 80pp report covering capex, regulation, partnerships.', tag: 'Economic Potential Realization', owner: 'N. Singh',   members: 12, files: 65, updated: '20 May' },
  { id: 'd6', name: 'CSR Effectiveness Index',  desc: 'Multi-state index of CSR spend efficiency — quantitative model + interview corpus.',   tag: 'Impact Realization',              owner: 'R. Banerjee', members: 8, files: 28, updated: '14 May' },
];

const adaptProject = (p) => ({
  id: p.id,
  name: p.name,
  desc: p.description || '',
  tag: p.practice || '',
  role: p.membership ? p.membership.toUpperCase() : null,
  membership: p.membership || null,
  hasPendingRequest: p.has_pending_request || false,
  files: p.artifact_count || 0,
  members: (p.members || []).slice(0, 3).map(m => (m.full_name || '?')[0].toUpperCase()),
  more: Math.max(0, (p.member_count || 0) - 3),
  updated: p.created_at ? new Date(p.created_at).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' }) : '—',
});

const ProjectsListing = ({ setRoute, openCreate, openInvite, projects, onOpenProject }) => {
  const [tab, setTab] = React.useState(0);
  const [q, setQ] = React.useState('');

  const allData = projects ? projects.map(adaptProject) : [];
  const myData = allData.filter(p => p.membership !== null);
  const discData = allData;
  const data = tab === 0 ? myData : discData;
  const filtered = q ? data.filter(p => p.name.toLowerCase().includes(q.toLowerCase()) || p.desc.toLowerCase().includes(q.toLowerCase())) : data;

  return (
    <div style={contentArea}>
      <div style={{ padding: '40px 48px 40px', maxWidth: 1120, margin: '0 auto' }}>
        {/* Header */}
        <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' }}>Projects</h1>
            <p style={{ fontSize: 13, color: 'var(--mute)', margin: '6px 0 0' }}>
              Workspaces with their own files, instructions and chat history.
            </p>
          </div>
          <button className="btn-primary" onClick={openCreate}>
            <PIcon name="plus" size={14} color="white"/> New project
          </button>
        </div>

        {/* Tabs + search */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 18, marginBottom: 22, borderBottom: '1px solid var(--line)' }}>
          {['Your projects', 'Discover'].map((t, i) => (
            <button key={t} onClick={() => setTab(i)} style={{
              padding: '12px 2px', background: 'transparent', border: 'none', cursor: 'pointer',
              fontSize: 14, fontFamily: 'inherit', fontWeight: tab === i ? 600 : 500,
              color: tab === i ? 'var(--ink)' : 'var(--mute)',
              borderBottom: tab === i ? '2px solid var(--maroon)' : '2px solid transparent',
              marginBottom: -1, transition: 'color 0.15s',
            }}>
              {t}
              {i === 1 && <span style={{ marginLeft: 6, fontSize: 11, color: 'var(--mute-2)', fontWeight: 500 }}>· {discData.length} firmwide</span>}
            </button>
          ))}
          <div style={{ flex: 1 }} />
          <div className="search-input" style={{ width: 280, height: 36 }}>
            <PIcon name="search" size={16} color="var(--mute)" />
            <input value={q} onChange={e => setQ(e.target.value)} placeholder={tab === 0 ? 'Filter your projects' : 'Search all projects in the firm'} />
          </div>
        </div>

        {/* Discover info banner */}
        {tab === 1 && (
          <div style={{
            padding: '12px 16px', borderRadius: 10, marginBottom: 18,
            background: 'var(--gold-soft)', border: '1px solid var(--cli-bd)',
            display: 'flex', alignItems: 'center', gap: 10,
            fontSize: 13, color: 'var(--cli-fg)',
          }}>
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
              <circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.4"/>
              <path d="M8 5v3.5M8 11v.01" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
            </svg>
            Discover surfaces every project across Primus Partners. Request to join, or browse public deliverables.
          </div>
        )}

        {/* Grid */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
          {filtered.map(p => tab === 0
            ? <YoursProjectCard key={p.id} p={p} onClick={() => onOpenProject ? onOpenProject(p.id) : setRoute('project-detail')} onInvite={openInvite} />
            : <DiscoverProjectCard key={p.id} p={p} onOpenProject={onOpenProject} />
          )}
        </div>

        {filtered.length === 0 && (
          <div style={{
            padding: 60, borderRadius: 14, background: 'white', border: '1px dashed var(--line-2)',
            textAlign: 'center', fontSize: 14, color: 'var(--mute)',
          }}>
            {q
              ? `No projects match “${q}”.`
              : tab === 0
                ? <span>No projects yet. <button onClick={openCreate} style={{ background: 'none', border: 'none', color: 'var(--maroon)', fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', fontSize: 14 }}>Create your first project.</button></span>
                : 'No firm-wide projects found.'}
          </div>
        )}
      </div>
    </div>
  );
};

const YoursProjectCard = ({ p, onClick, onInvite }) => (
  <div onClick={onClick} style={{
    background: 'white', border: '1px solid var(--line)', borderRadius: 12,
    padding: 16, cursor: 'pointer', transition: 'all 0.18s',
    display: 'flex', flexDirection: 'column', gap: 10,
  }}
  onMouseEnter={e => { e.currentTarget.style.borderColor = 'var(--maroon-20)'; e.currentTarget.style.boxShadow = '0 6px 18px rgba(60,30,20,0.06)'; e.currentTarget.style.transform = 'translateY(-1px)'; }}
  onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--line)'; e.currentTarget.style.boxShadow = 'none'; e.currentTarget.style.transform = 'translateY(0)'; }}
  >
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
        <div style={{
          width: 30, height: 30, borderRadius: 8,
          background: 'var(--maroon-06)', color: 'var(--maroon)',
          display: 'grid', placeItems: 'center', flexShrink: 0,
        }}>
          <PIcon name="folder" size={15} color="var(--maroon)" />
        </div>
        <h3 style={{ fontSize: 14, fontWeight: 600, margin: 0, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.name}</h3>
      </div>
      {p.role && <span className={`role-badge ${p.role === 'OWNER' ? 'owner' : ''}`}>{p.role}</span>}
    </div>

    <p style={{ fontSize: 12, lineHeight: 1.5, color: 'var(--mute)', margin: 0,
                display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{p.desc}</p>

    <div><span className="tag-pill" style={{ maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.tag}</span></div>

    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginTop: 'auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 11, color: 'var(--mute)' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
          <PIcon name="book" size={12} color="var(--mute)" /> {p.files}
        </span>
        <span style={{ color: 'var(--mute-2)' }}>· {p.updated}</span>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <div style={{ display: 'flex' }}>
          {p.members.map((m, i) => (
            <div key={i} className={`avatar ${i === 1 ? 'dark' : i === 2 ? 'gold' : ''}`} style={{ marginLeft: i ? -7 : 0 }}>{m}</div>
          ))}
          {p.more > 0 && (
            <div className="avatar muted" style={{ marginLeft: -7, fontSize: 9 }}>+{p.more}</div>
          )}
        </div>
        {p.role === 'OWNER' && onInvite && (
          <button onClick={(e) => { e.stopPropagation(); onInvite(p); }} title="Invite" style={{
            width: 26, height: 26, borderRadius: 7,
            background: 'transparent', border: '1px solid var(--line-2)',
            cursor: 'pointer', display: 'grid', placeItems: 'center',
            color: 'var(--ink-2)', flexShrink: 0,
          }}>
            <PIcon name="plus" size={11} color="var(--ink-2)" />
          </button>
        )}
      </div>
    </div>
  </div>
);

const DiscoverProjectCard = ({ p, onOpenProject }) => {
  const [requested, setRequested] = React.useState(p.hasPendingRequest || false);
  const isMember = !!p.membership;
  const isOwner = p.membership === 'owner';
  const handleRequestJoin = async (e) => {
    e.stopPropagation();
    try { await PrimusAPI.joinProject(p.id); } catch {}
    setRequested(true);
  };

  return (
    <div style={{
      background: 'white', border: '1px solid var(--line)', borderRadius: 12,
      padding: 16, transition: 'all 0.18s',
      display: 'flex', flexDirection: 'column', gap: 10,
      cursor: isMember ? 'pointer' : 'default',
    }}
    onMouseEnter={e => e.currentTarget.style.borderColor = isMember ? 'var(--maroon-20)' : 'var(--line-2)'}
    onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--line)'}
    onClick={() => isMember && onOpenProject && onOpenProject(p.id)}
    >
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 30, height: 30, borderRadius: 8,
          background: isMember ? 'var(--maroon-06)' : 'var(--bg-soft)',
          color: isMember ? 'var(--maroon)' : 'var(--mute)',
          display: 'grid', placeItems: 'center', flexShrink: 0,
        }}>
          <PIcon name="folder" size={15} color={isMember ? 'var(--maroon)' : 'var(--mute)'} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <h3 style={{ fontSize: 14, fontWeight: 600, margin: 0, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.name}</h3>
          <div style={{ fontSize: 11, color: 'var(--mute)', marginTop: 1 }}>
            {p.files} files · {p.updated}
          </div>
        </div>
        {isMember && <span className={`role-badge ${isOwner ? 'owner' : ''}`}>{p.role}</span>}
      </div>

      <p style={{ fontSize: 12, lineHeight: 1.5, color: 'var(--mute)', margin: 0,
                  display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{p.desc}</p>

      <div><span className="tag-pill" style={{ maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.tag}</span></div>

      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginTop: 'auto' }}>
        <span style={{ fontSize: 11, color: 'var(--mute)', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          {isMember ? 'You have access.' : 'Membership required'}
        </span>
        {!isMember && (
          <button onClick={handleRequestJoin} disabled={requested} style={{
            height: 28, padding: '0 11px', borderRadius: 8,
            background: requested ? 'var(--bg-soft)' : 'var(--maroon)',
            color: requested ? 'var(--mute)' : 'white',
            border: 'none', cursor: requested ? 'default' : 'pointer',
            fontSize: 11.5, fontWeight: 600, fontFamily: 'inherit',
            display: 'inline-flex', alignItems: 'center', gap: 5, flexShrink: 0,
            transition: 'all 0.15s',
          }}>
            {requested ? (
              <>
                <svg width="11" height="11" viewBox="0 0 12 12"><path d="M3 6.5l2 2 4-4.5" stroke="currentColor" fill="none" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Requested
              </>
            ) : (
              <>
                Request to join
                <svg width="10" height="10" viewBox="0 0 12 12"><path d="M3 6h6M6 3l3 3-3 3" stroke="white" fill="none" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
              </>
            )}
          </button>
        )}
        {isMember && (
          <button onClick={(e) => { e.stopPropagation(); onOpenProject && onOpenProject(p.id); }} className="btn-secondary" style={{ height: 28, padding: '0 11px', fontSize: 11.5, flexShrink: 0 }}>
            Open
          </button>
        )}
      </div>
    </div>
  );
};

// ──────────────────────────────────────────────────────────────────────────────
// Invite modal — owner shares membership with colleagues
// ──────────────────────────────────────────────────────────────────────────────
const InviteModal = ({ open, project, onClose, onInviteSent, currentUser }) => {
  const [email, setEmail] = React.useState('');
  const [role, setRole] = React.useState('member');
  const [sending, setSending] = React.useState(false);
  const [sent, setSent] = React.useState(false);
  const [members, setMembers] = React.useState([]);
  const [joinRequests, setJoinRequests] = React.useState([]);
  const [suggestions, setSuggestions] = React.useState([]);
  const [searchTimer, setSearchTimer] = React.useState(null);
  const [showSuggestions, setShowSuggestions] = React.useState(false);

  const refreshTeam = (projectId) => {
    PrimusAPI.listMembers(projectId)
      .then(data => setMembers(data || [])).catch(() => {});
    PrimusAPI.listJoinRequests(projectId)
      .then(data => setJoinRequests(data || [])).catch(() => setJoinRequests([]));
  };

  React.useEffect(() => {
    if (open && project?.id) {
      refreshTeam(project.id);
    } else {
      setMembers([]);
      setJoinRequests([]);
      setEmail('');
      setSuggestions([]);
    }
  }, [open, project?.id]);

  if (!open) return null;

  const handleEmailChange = (e) => {
    const val = e.target.value;
    setEmail(val);
    if (searchTimer) clearTimeout(searchTimer);
    if (val.length >= 2) {
      const timer = setTimeout(async () => {
        try {
          const results = await PrimusAPI.directorySearch(val);
          setSuggestions(results || []);
          setShowSuggestions(true);
        } catch { setSuggestions([]); }
      }, 300);
      setSearchTimer(timer);
    } else {
      setSuggestions([]);
      setShowSuggestions(false);
    }
  };

  const selectSuggestion = (u) => {
    setEmail(u.email);
    setShowSuggestions(false);
    setSuggestions([]);
  };

  const handleSend = async () => {
    if (!email || !project?.id) return;
    setSending(true);
    try {
      const match = suggestions.find(u => u.email === email);
      if (match) {
        await PrimusAPI.inviteMember(project.id, { id: match.id, email: match.email, full_name: match.full_name, in_system: true }, role);
      } else {
        await PrimusAPI.inviteMember(project.id, { email, full_name: email, in_system: false }, role);
      }
      setSent(true);
      setTimeout(() => {
        setSent(false); setEmail('');
        refreshTeam(project.id);
        if (onInviteSent) onInviteSent();
      }, 1500);
    } catch (ex) {
      console.error('Invite failed:', ex);
    } finally { setSending(false); }
  };

  const handleApprove = async (reqId) => {
    try {
      await PrimusAPI.approveJoinRequest(project.id, reqId);
      refreshTeam(project.id);
    } catch (ex) { console.error('Approve failed:', ex); }
  };

  const handleReject = async (reqId) => {
    try {
      await PrimusAPI.rejectJoinRequest(project.id, reqId);
      setJoinRequests(prev => prev.filter(r => r.id !== reqId));
    } catch (ex) { console.error('Reject failed:', ex); }
  };

  const meInitials = currentUser?.full_name
    ? currentUser.full_name.split(' ').filter(Boolean).map(w => w[0].toUpperCase()).slice(0, 2).join('')
    : '?';

  return (
    <ModalShell onClose={onClose} width={680} title="Invite to project" subtitle={(project && project.name) || 'Project'}>
      <div style={{ padding: '0 24px 24px' }}>
        <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-2)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Invite by email</label>
        <div style={{ display: 'flex', gap: 8, marginTop: 8, position: 'relative' }}>
          <div style={{ flex: 1, position: 'relative' }}>
            <input
              value={email}
              onChange={handleEmailChange}
              onBlur={() => setTimeout(() => setShowSuggestions(false), 150)}
              onFocus={() => suggestions.length > 0 && setShowSuggestions(true)}
              placeholder="name@primuspartners.in"
              style={{
                width: '100%', height: 40, padding: '0 14px', borderRadius: 10,
                border: '1px solid var(--line-2)', background: 'white',
                fontSize: 14, fontFamily: 'inherit', color: 'var(--ink)',
              }}
            />
            {showSuggestions && suggestions.length > 0 && (
              <div style={{
                position: 'absolute', top: '100%', left: 0, right: 0, marginTop: 4,
                background: 'white', border: '1px solid var(--line-2)', borderRadius: 10,
                boxShadow: '0 8px 24px rgba(26,22,20,0.12)', zIndex: 50,
                maxHeight: 220, overflowY: 'auto',
              }}>
                {suggestions.map(u => (
                  <div key={u.id || u.email} onMouseDown={() => selectSuggestion(u)} style={{
                    padding: '10px 14px', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 10,
                    transition: 'background 0.1s',
                  }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                  >
                    <div style={{
                      width: 28, height: 28, borderRadius: 14, flexShrink: 0,
                      background: 'var(--maroon-06)', color: 'var(--maroon)',
                      display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 700,
                    }}>
                      {(u.full_name || u.email || '?')[0].toUpperCase()}
                    </div>
                    <div>
                      <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600 }}>{u.full_name || u.email}</div>
                      <div style={{ fontSize: 11, color: 'var(--mute)' }}>{u.email} · {u.designation || ''}</div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
          <select value={role} onChange={e => setRole(e.target.value)} style={{
            height: 40, padding: '0 12px', borderRadius: 10,
            border: '1px solid var(--line-2)', background: 'white',
            fontSize: 13, fontFamily: 'inherit', color: 'var(--ink)',
          }}>
            <option value="viewer">Viewer</option>
            <option value="member">Member</option>
            <option value="editor">Editor</option>
          </select>
          <button className="btn-primary" style={{ height: 40 }} onClick={handleSend} disabled={sending || !email}>
            {sent ? '✓ Sent!' : sending ? 'Sending…' : 'Send invite'}
          </button>
        </div>

        {joinRequests.length > 0 && (
          <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--line)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
              <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-2)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Pending requests</label>
              <span style={{ fontSize: 11, fontWeight: 700, background: 'var(--maroon)', color: 'white', borderRadius: 10, padding: '1px 7px' }}>{joinRequests.length}</span>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 2, maxHeight: 180, overflowY: 'auto' }}>
              {joinRequests.map(req => (
                <div key={req.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0' }}>
                  <div className="avatar" style={{ width: 32, height: 32, fontSize: 12 }}>{(req.requester_name || '?')[0].toUpperCase()}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600 }}>{req.requester_name}</div>
                    <div style={{ fontSize: 11, color: 'var(--mute)' }}>{req.requester_designation || 'Primus Partners'}</div>
                  </div>
                  <button onClick={() => handleApprove(req.id)} style={{
                    height: 30, padding: '0 12px', borderRadius: 7, border: 'none',
                    background: 'var(--maroon)', color: 'white',
                    fontSize: 12, fontFamily: 'inherit', fontWeight: 600, cursor: 'pointer',
                  }}>Approve</button>
                  <button onClick={() => handleReject(req.id)} style={{
                    height: 30, padding: '0 10px', borderRadius: 7,
                    border: '1px solid var(--line-2)', background: 'white',
                    fontSize: 12, fontFamily: 'inherit', color: 'var(--ink-2)', cursor: 'pointer',
                  }}>Reject</button>
                </div>
              ))}
            </div>
          </div>
        )}

        <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--line)' }}>
          <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-2)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>People with access</label>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2, marginTop: 10, maxHeight: 220, overflowY: 'auto' }}>
            {currentUser && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0' }}>
                <div className="avatar" style={{ width: 32, height: 32, fontSize: 12 }}>{meInitials}</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600 }}>{currentUser.full_name} (you)</div>
                  <div style={{ fontSize: 11, color: 'var(--mute)' }}>{currentUser.primus_email}</div>
                </div>
                <span className="role-badge owner">OWNER</span>
              </div>
            )}
            {members.filter(m => m.user_id !== currentUser?.id).map(m => {
              const av = (m.full_name || '?')[0].toUpperCase();
              return (
                <div key={m.user_id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0' }}>
                  <div className="avatar" style={{ width: 32, height: 32, fontSize: 12 }}>{av}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600 }}>{m.full_name}</div>
                    <div style={{ fontSize: 11, color: 'var(--mute)' }}>{m.designation || m.role}</div>
                  </div>
                  <span style={{ fontSize: 12, color: 'var(--mute)', textTransform: 'capitalize' }}>{m.role}</span>
                </div>
              );
            })}
            {members.length === 0 && !currentUser && (
              <div style={{ fontSize: 13, color: 'var(--mute)', padding: '12px 0' }}>Loading members…</div>
            )}
          </div>
        </div>
      </div>
    </ModalShell>
  );
};

// ──────────────────────────────────────────────────────────────────────────────
// Create Project modal — minimalist
// ──────────────────────────────────────────────────────────────────────────────
const CreateProjectModal = ({ open, onClose, onCreate }) => {
  const [name, setName] = React.useState('');
  const [desc, setDesc] = React.useState('');
  const [practice, setPractice] = React.useState('');
  if (!open) return null;
  const practices = [
    'Public Policy Realization',
    'Sector Potential Realization',
    'Impact Realization',
    'Economic Potential Realization',
    'Data & Digital Strategy',
    'Transaction Realization',
  ];
  return (
    <ModalShell onClose={onClose} width={520} title="New project" subtitle="Create a private workspace for files, chat and instructions.">
      <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="e.g. GCC Renewables Capex 2026" style={fieldInput}/>
        </Field>
        <Field label="Practice">
          <select value={practice} onChange={e => setPractice(e.target.value)} style={fieldInput}>
            <option value="">Select a practice</option>
            {practices.map(p => <option key={p} value={p}>{p}</option>)}
          </select>
        </Field>
        <Field label="Description" hint="Optional. Visible to project members.">
          <textarea value={desc} onChange={e => setDesc(e.target.value)} placeholder="What is this project about?" 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={() => { onCreate({ name, desc, practice }); onClose(); }} disabled={!name}>Create project</button>
        </div>
      </div>
    </ModalShell>
  );
};

const Field = ({ label, hint, children }) => (
  <div>
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
      <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--ink-2)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>{label}</label>
      {hint && <span style={{ fontSize: 11, color: 'var(--mute)' }}>{hint}</span>}
    </div>
    {children}
  </div>
);
const fieldInput = {
  width: '100%', height: 40, padding: '0 14px', borderRadius: 10,
  border: '1px solid var(--line-2)', background: 'white',
  fontSize: 14, fontFamily: 'inherit', color: 'var(--ink)',
};

// ──────────────────────────────────────────────────────────────────────────────
// Shared modal shell — used across Create/Invite/AddSources/Tagging
// ──────────────────────────────────────────────────────────────────────────────
const ModalShell = ({ onClose, width = 520, title, subtitle, children, padded = true, headerBorder = true }) => (
  <div onClick={onClose} style={{
    position: 'absolute', inset: 0, zIndex: 50,
    background: 'rgba(26, 22, 20, 0.32)', backdropFilter: 'blur(4px)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    animation: 'fadein 0.18s ease-out',
  }}>
    <div onClick={e => e.stopPropagation()} style={{
      width, maxHeight: '90%', overflow: 'auto',
      background: 'var(--bg-card)', borderRadius: 16,
      boxShadow: '0 30px 80px rgba(26,22,20,0.25), 0 0 0 1px var(--line)',
      animation: 'rise 0.22s ease-out',
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{
        padding: '20px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',
        borderBottom: headerBorder ? '1px solid var(--line)' : 'none',
      }}>
        <div>
          <h2 className="serif" style={{ fontSize: 18, fontWeight: 500, margin: 0, letterSpacing: '-0.01em' }}>{title}</h2>
          {subtitle && <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 4 }}>{subtitle}</div>}
        </div>
        <button onClick={onClose} style={{
          width: 30, height: 30, borderRadius: 8, background: 'transparent', border: 'none',
          cursor: 'pointer', display: 'grid', placeItems: 'center', color: 'var(--mute)',
        }}
        onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
        onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
        >
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
        </button>
      </div>
      {padded ? children : children}
    </div>
  </div>
);

const contentArea = {
  flex: 1, height: '100%', background: 'var(--bg)',
  position: 'relative', overflow: 'auto',
};

Object.assign(window, {
  ScreenNewChat, ProjectsListing, YoursProjectCard, DiscoverProjectCard,
  CreateProjectModal, InviteModal, ModalShell, Field, fieldInput,
  contentArea, SAMPLE_PROJECTS, DISCOVER_PROJECTS, adaptProject,
});
