// Variation 3: "Command Center" — Procore-inspired, dense, data-rich
(function(){
const { useState, useContext, createContext } = React;

// ── Theme ────────────────────────────────────────────────────────────────────
const ThemeCtx = createContext(null);

const DARK = {
  outerBg:     '#0f1419',
  headerBg:    '#1a2230',
  headerBorder:'#2a3444',
  panelBg:     '#1a2230',
  panelBorder: '#2a3444',
  rowHover:    '#212b3c',
  rowBorder:   '#212b3c',
  divider:     '#2a3444',
  ink:         '#e5e7eb',
  inkSoft:     '#9ca3af',
  inkFaint:    '#6b7280',
  kpiBg:       '#1a2230',
  barTrack:    '#2a3444',
  searchBg:    '#0f1419',
  searchBorder:'#2a3444',
  navActiveBg: '#2a3444',
  navActiveColor:'#fff',
  navColor:    '#9ca3af',
  btnBorder:   '#2a3444',
  btnColor:    '#9ca3af',
  crumbBg:     '#0f1419',
  crumbBorder: '#2a3444',
  headerTextColor: '#e5e7eb',
};

const LIGHT = {
  outerBg:     '#f6f8fc',
  headerBg:    '#ffffff',
  headerBorder:'#e3e6ea',
  panelBg:     '#ffffff',
  panelBorder: '#e3e6ea',
  rowHover:    '#f1f3f8',
  rowBorder:   '#eef0f2',
  divider:     '#e3e6ea',
  ink:         '#202124',
  inkSoft:     '#5f6368',
  inkFaint:    '#9aa0a6',
  kpiBg:       '#ffffff',
  barTrack:    '#eef0f2',
  searchBg:    '#eaf0f7',
  searchBorder:'transparent',
  navActiveBg: '#e3eaf6',
  navActiveColor:'#1a2c4a',
  navColor:    '#5f6368',
  btnBorder:   '#dadce0',
  btnColor:    '#5f6368',
  crumbBg:     '#ffffff',
  crumbBorder: '#e3e6ea',
  headerTextColor: '#202124',
};

const THEME_KEY = 'ybp_v3_theme';
const loadTheme = () => { try { return localStorage.getItem(THEME_KEY) === 'light' ? 'light' : 'dark'; } catch { return 'dark'; } };

// v3.9.0.50 — מתקן את שרשור ה-theme במסכים שמכילים את V3Shell בעצמם:
// useContext(ThemeCtx) באותן קומפוננטות מחזיר null כי ה-Provider עוד לא קיים.
const useV3Theme = () => {
  const [mode, setMode] = useState(loadTheme);
  React.useEffect(() => {
    const handler = (e) => setMode(e.detail === 'light' ? 'light' : 'dark');
    window.addEventListener('ybp-theme-change', handler);
    return () => window.removeEventListener('ybp-theme-change', handler);
  }, []);
  return mode === 'dark' ? DARK : LIGHT;
};

const V3Shell = ({ children, onNav, onBack, active, crumbs, right, hideNav, projectNav, activeSubView }) => {
  const [mode, setMode] = useState(loadTheme);
  const T = mode === 'dark' ? DARK : LIGHT;
  React.useEffect(() => {
    const handler = (e) => setMode(e.detail === 'light' ? 'light' : 'dark');
    window.addEventListener('ybp-theme-change', handler);
    return () => window.removeEventListener('ybp-theme-change', handler);
  }, []);

  if (typeof AppShell !== 'undefined') {
    return (
      <ThemeCtx.Provider value={T}>
        <AppShell
          active={active}
          onNav={onNav}
          onBack={onBack}
          crumbs={crumbs}
          actions={right}
          projectNav={projectNav}
          activeSubView={activeSubView}
        >
          {children}
        </AppShell>
      </ThemeCtx.Provider>
    );
  }

  // fallback — header ישן (ללא sidebar)
  return (
    <ThemeCtx.Provider value={T}>
      <div style={{ background: T.outerBg, minHeight: '100%', fontFamily: 'Assistant, sans-serif', color: T.ink, direction: 'rtl' }}>
        {crumbs && (
          <div style={{ padding: '8px 20px', fontSize: 12, color: T.inkSoft, borderBottom: `1px solid ${T.crumbBorder}`, background: T.crumbBg, display: 'flex', alignItems: 'center', gap: 6 }}>
            {onBack && (
              <button onClick={onBack} style={{ background: 'transparent', border: 'none', padding: '2px 4px', cursor: 'pointer', color: T.inkSoft, fontFamily: 'inherit' }}>
                <Icon name="chevronR" size={12}/>
              </button>
            )}
            {crumbs.map((c, i) => (
              <React.Fragment key={i}>
                {i > 0 && <Icon name="chevron" size={10} color={T.inkFaint}/>}
                <span style={{ color: i === crumbs.length - 1 ? T.ink : T.inkSoft }}>{c}</span>
              </React.Fragment>
            ))}
            <div style={{ marginRight: 'auto', display: 'flex', gap: 8 }}>{right}</div>
          </div>
        )}
        <div>{children}</div>
      </div>
    </ThemeCtx.Provider>
  );
};

const statusStyle3 = (s) => ({
  active: { bg: 'rgba(59,130,246,0.15)', fg: '#60a5fa' },
  done: { bg: 'rgba(16,185,129,0.15)', fg: '#34d399' },
  attention: { bg: 'rgba(245,158,11,0.15)', fg: '#fbbf24' },
  delay: { bg: 'rgba(239,68,68,0.15)', fg: '#f87171' },
}[s] || {});

const Panel = ({ title, right, children, noPad }) => {
  const T = useContext(ThemeCtx) || DARK;
  return (
    <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 6 }}>
      {title && (
        <div style={{ display: 'flex', alignItems: 'center', padding: '10px 14px', borderBottom: `1px solid ${T.divider}` }}>
          <div style={{ fontSize: 12, fontWeight: 700, color: T.ink, textTransform: 'uppercase', letterSpacing: 0.5 }}>{title}</div>
          <div style={{ marginRight: 'auto' }}>{right}</div>
        </div>
      )}
      <div style={{ padding: noPad ? 0 : 14 }}>{children}</div>
    </div>
  );
};

const V3ProjectsList = ({ onOpenProject, onNewProject, onNav }) => {
  const T = useV3Theme();
  const [statusFilter, setStatusFilter] = useState('all');
  const [pmFilter, setPmFilter] = useState('all');
  // v3.9.0.46 — ארכוב/מחיקת פרויקטים
  const [showArchive, setShowArchive] = useState(false);
  const [menuOpenFor, setMenuOpenFor] = useState(null);
  const [busy, setBusy] = useState(false);
  const [tick, setTick] = useState(0);
  // v3.9.0.48 — שמות מנהלים שכווצו בתצוגה מקובצת
  const [collapsedPMs, setCollapsedPMs] = useState(() => new Set());
  React.useEffect(() => {
    const h = () => setTick(t => t + 1);
    window.addEventListener('ybp-projects-change', h);
    return () => window.removeEventListener('ybp-projects-change', h);
  }, []);
  React.useEffect(() => {
    const close = () => setMenuOpenFor(null);
    window.addEventListener('click', close);
    return () => window.removeEventListener('click', close);
  }, []);
  const me = (window.YBP_AUTH && window.YBP_AUTH.getCurrentUser) ? window.YBP_AUTH.getCurrentUser() : null;
  const isAdmin = _isAdminUser(me);

  // v3.9.0.44 — responsive: מתחת ל-640px הטבלה הופכת לכרטיסים מוערמים
  const vp = window.useViewport ? window.useViewport() : { width: 1200 };
  const isNarrow = (vp.width || 1200) < 640;
  // מיון קבוע: לפי מנהל פרויקט ואז לפי מיקום (כתובת) — חלק ד'
  const allProjects = [...YBP_DATA.projects].sort((a, b) =>
    (a.pm || '').localeCompare(b.pm || '', 'he') ||
    (a.address || '').localeCompare(b.address || '', 'he')
  );
  const pmOptions = [...new Set(allProjects.map(p => p.pm).filter(Boolean))];
  const projects = allProjects.filter(p =>
    (statusFilter === 'all' || p.status === statusFilter) &&
    (pmFilter === 'all' || p.pm === pmFilter)
  );
  // v3.9.0.47 — סינון לפי p.archived top-level (loadProjectsFromSupabase כותב מ-data.archived).
  const visibleProjects = projects.filter(p => {
    const isArchived = !!p.archived;
    return showArchive ? isArchived : !isArchived;
  });
  // KPI מחושב על כלל הפרויקטים (תמונה כוללת), הטבלה משתמשת ב-projects המסונן
  // v3.9.0.46 — totalBudget/totalSpent הוסרו (מספרים מצרפיים חסרי משמעות)
  const active = allProjects.filter(p => p.status === 'active').length;
  const issues = allProjects.reduce((s,p) => s+p.openIssues, 0);

  // v3.9.0.46 — handlers לפעולות פרויקט
  const persistProject = async (proj) => {
    const arr = (window.YBP_DATA && window.YBP_DATA.projects) || [];
    const idx = arr.findIndex(p => p.id === proj.id);
    if (idx !== -1) arr[idx] = proj;
    try {
      const cache = JSON.parse(localStorage.getItem('ybp_user_projects') || '[]');
      const ci = cache.findIndex(p => p.id === proj.id);
      if (ci !== -1) { cache[ci] = proj; localStorage.setItem('ybp_user_projects', JSON.stringify(cache)); }
    } catch {}
    if (window.saveProjectToSupabase) {
      const res = await window.saveProjectToSupabase(proj);
      if (!res.ok) alert('שגיאה בשמירה לענן: ' + (res.error || ''));
    }
  };
  const handleArchive = async (p) => {
    setMenuOpenFor(null); setBusy(true);
    // v3.9.0.47 — archived top-level (לא ב-.data); stripKnown ב-mapProject מעביר ל-jsonb בשמירה,
    // ו-loadProjectsFromSupabase קורא בחזרה ל-top-level. אחרת השמירה הבאה מוחקת.
    const next = { ...p, archived: true };
    await persistProject(next);
    setBusy(false);
    window.dispatchEvent(new CustomEvent('ybp-projects-change'));
  };
  const handleRestore = async (p) => {
    setMenuOpenFor(null); setBusy(true);
    const next = { ...p, archived: false };
    await persistProject(next);
    setBusy(false);
    window.dispatchEvent(new CustomEvent('ybp-projects-change'));
  };
  const handleDelete = async (p) => {
    if (!isAdmin) return;
    const confirm1 = window.prompt(`מחיקה סופית של "${p.name}". הקלד את שם הפרויקט לאישור:`);
    if (confirm1 !== p.name) { setMenuOpenFor(null); return; }
    setMenuOpenFor(null); setBusy(true);
    if (window.deleteProjectFromSupabase) {
      const res = await window.deleteProjectFromSupabase(p.id);
      if (!res.ok) { alert('שגיאה במחיקה: ' + (res.error || '')); setBusy(false); return; }
    }
    const arr = (window.YBP_DATA && window.YBP_DATA.projects) || [];
    const idx = arr.findIndex(x => x.id === p.id);
    if (idx !== -1) arr.splice(idx, 1);
    try {
      const cache = JSON.parse(localStorage.getItem('ybp_user_projects') || '[]');
      localStorage.setItem('ybp_user_projects', JSON.stringify(cache.filter(x => x.id !== p.id)));
      // v92 LWW-fix: track deleted IDs so shadow-write never re-upserts them
      const deleted = JSON.parse(localStorage.getItem('ybp_deleted_project_ids') || '[]');
      if (!deleted.includes(p.id)) { deleted.push(p.id); localStorage.setItem('ybp_deleted_project_ids', JSON.stringify(deleted)); }
    } catch {}
    setBusy(false);
    window.dispatchEvent(new CustomEvent('ybp-projects-change'));
  };
  const handleRename = async (p) => {
    setMenuOpenFor(null);
    const newName = window.prompt('שנה שם פרויקט:', p.name);
    if (!newName || !newName.trim() || newName.trim() === p.name) return;
    setBusy(true);
    const next = { ...p, name: newName.trim() };
    await persistProject(next);
    setBusy(false);
    window.dispatchEvent(new CustomEvent('ybp-projects-change'));
    if (window.toastSuccess) window.toastSuccess('שם הפרויקט עודכן');
  };
  const _menuItem = {
    display:'block', width:'100%', textAlign:'right', padding:'7px 12px', background:'transparent',
    border:'none', cursor:'pointer', fontSize:12, fontFamily:'inherit', color: T.ink, borderRadius:4,
  };

  // v3.9.0.48 — קיבוץ לפי מנהל פרויקט. ברירת מחדל כשאדמין מסתכל על "כל המנהלים".
  // משתמש לא-admin (RLS מחזיר רק את שלו) או בורר מנהל יחיד → תצוגה שטוחה כמו קודם.
  const groupByPM = isAdmin && pmFilter === 'all';
  const togglePM = (pm) => setCollapsedPMs(prev => {
    const next = new Set(prev);
    if (next.has(pm)) next.delete(pm); else next.add(pm);
    return next;
  });
  const pmGroups = groupByPM ? (() => {
    const map = new Map();
    visibleProjects.forEach(p => {
      const key = p.pm || '(ללא מנהל)';
      if (!map.has(key)) map.set(key, []);
      map.get(key).push(p);
    });
    return [...map.entries()]
      .map(([pm, items]) => ({ pm, items }))
      .sort((a, b) => a.pm.localeCompare(b.pm, 'he'));
  })() : null;

  const renderProjectRow = (p) => {
    const ss = statusStyle3(p.status);
    const isArchived = !!p.archived;
    const rowMenu = (
      <div style={{ position: 'absolute', top: 4, insetInlineStart: 4, zIndex: 5 }}>
        <button onClick={(e) => { e.stopPropagation(); setMenuOpenFor(menuOpenFor === p.id ? null : p.id); }}
          title="פעולות"
          style={{ background: 'transparent', border: 'none', cursor: 'pointer',
            color: T.inkFaint, fontSize: 18, padding: '2px 8px', lineHeight: 1, borderRadius: 4 }}>⋯</button>
        {menuOpenFor === p.id && (
          <div onClick={(e) => e.stopPropagation()}
            style={{ position: 'absolute', top: '100%', insetInlineStart: 0, marginTop: 4,
              background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 6,
              minWidth: 180, boxShadow: '0 8px 24px rgba(0,0,0,0.3)', zIndex: 60, padding: 4 }}>
            <button onClick={() => handleRename(p)} disabled={busy} style={_menuItem}>✏️ שנה שם</button>
            {!isArchived
              ? <button onClick={() => handleArchive(p)} disabled={busy} style={_menuItem}>📦 העבר לארכיון</button>
              : <button onClick={() => handleRestore(p)} disabled={busy} style={_menuItem}>↩ שחזר מארכיון</button>}
            {isAdmin && (
              <button onClick={() => handleDelete(p)} disabled={busy}
                style={{ ..._menuItem, color: '#ef4444' }}>🗑 מחק לצמיתות</button>
            )}
          </div>
        )}
      </div>
    );

    if (isNarrow) {
      return (
        <div key={p.id} onClick={() => onOpenProject(p.id)} style={{
          padding: '12px 14px', borderBottom: `1px solid ${T.rowBorder}`,
          cursor: 'pointer', display: 'flex', flexDirection: 'column', gap: 8,
          position: 'relative',
        }}>
          {rowMenu}
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingInlineStart: 28 }}>
            <ProjectPlaceholder kind={p.cover} style={{ width: 36, height: 36, borderRadius: 4, flexShrink: 0 }}/>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ color: T.ink, fontWeight: 700, fontSize: 14, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</div>
              <div style={{ fontSize: 11, color: T.inkFaint }}>{p.client}</div>
            </div>
            <span style={{ background: ss.bg, color: ss.fg, fontSize: 10, fontWeight: 600, padding: '2px 8px', borderRadius: 3 }}>{p.statusLabel}</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <div style={{ flex: 1, height: 5, background: T.barTrack, borderRadius: 2, overflow: 'hidden' }}>
              <div style={{ height: '100%', width: `${p.progress}%`, background: ss.fg }}/>
            </div>
            <span style={{ fontSize: 11, color: T.inkSoft, minWidth: 32, textAlign: 'left' }}>{p.progress}%</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8, fontSize: 11 }}>
            <div>
              <div style={{ color: T.inkFaint, fontSize: 10 }}>תקציב</div>
              <div style={{ color: T.ink }}>{fmtMoney(p.spent)} <span style={{ color: T.inkFaint }}>/ {fmtMoney(p.budget)}</span></div>
            </div>
            <div>
              <div style={{ color: T.inkFaint, fontSize: 10 }}>סיום</div>
              <div style={{ color: p.daysLeft < 14 && p.daysLeft > 0 ? '#f87171' : T.ink }}>
                {p.endDate.slice(5)} {p.daysLeft > 0 && <span style={{ color: T.inkFaint }}>· {p.daysLeft}d</span>}
              </div>
            </div>
            <div>
              <div style={{ color: T.inkFaint, fontSize: 10 }}>בעיות</div>
              <div>
                {p.openIssues > 0
                  ? <span style={{ background: 'rgba(239,68,68,0.15)', color: '#f87171', fontWeight: 700, padding: '1px 7px', borderRadius: 3 }}>{p.openIssues}</span>
                  : <span style={{ color: T.inkFaint }}>0</span>}
              </div>
            </div>
          </div>
        </div>
      );
    }
    return (
      <div key={p.id} onClick={() => onOpenProject(p.id)} style={{
        display: 'grid', gridTemplateColumns: '2.5fr 1fr 1.5fr 1fr 1fr 0.6fr', gap: 10,
        padding: '12px 14px', borderBottom: `1px solid ${T.rowBorder}`, alignItems: 'center',
        cursor: 'pointer', fontSize: 12.5, position: 'relative',
      }}
      onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
      onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
        {rowMenu}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0, paddingInlineStart: 24 }}>
          <ProjectPlaceholder kind={p.cover} style={{ width: 32, height: 32, borderRadius: 4, flexShrink: 0 }}/>
          <div style={{ minWidth: 0 }}>
            <div style={{ color: T.ink, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</div>
            <div style={{ fontSize: 10.5, color: T.inkFaint }}>{p.client}</div>
          </div>
        </div>
        <div><span style={{ display: 'inline-block', background: ss.bg, color: ss.fg, fontSize: 11, fontWeight: 600, padding: '2px 8px', borderRadius: 3 }}>{p.statusLabel}</span></div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ flex: 1, height: 5, background: T.barTrack, borderRadius: 2, overflow: 'hidden' }}>
            <div style={{ height: '100%', width: `${p.progress}%`, background: ss.fg }}/>
          </div>
          <span style={{ fontSize: 11, color: T.inkSoft, minWidth: 28, textAlign: 'left' }}>{p.progress}%</span>
        </div>
        <div>
          <div style={{ color: T.ink }}>{fmtMoney(p.spent)}</div>
          <div style={{ fontSize: 10.5, color: T.inkFaint }}>/ {fmtMoney(p.budget)}</div>
        </div>
        <div>
          <div style={{ color: T.ink }}>{p.endDate.slice(5)}</div>
          <div style={{ fontSize: 10.5, color: p.daysLeft < 14 && p.daysLeft > 0 ? '#f87171' : T.inkFaint }}>
            {p.daysLeft === 0 ? '—' : p.daysLeft + 'd'}
          </div>
        </div>
        <div>
          {p.openIssues > 0 ? <span style={{ background: 'rgba(239,68,68,0.15)', color: '#f87171', fontSize: 11, fontWeight: 700, padding: '2px 7px', borderRadius: 3 }}>{p.openIssues}</span> : <span style={{ color: T.inkFaint }}>0</span>}
        </div>
      </div>
    );
  };

  return (
    <V3Shell active="list" onNav={onNav} crumbs={['פרויקטים', 'כל הפרויקטים']}
      right={<button onClick={onNewProject} style={{ background: '#3b82f6', color: '#fff', border: 'none', padding: '5px 12px', borderRadius: 4, fontSize: 12, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 4 }}><Icon name="plus" size={12}/>חדש</button>}>

      <div style={{ padding: 16, display: 'grid', gridTemplateColumns: isNarrow ? 'repeat(2,1fr)' : 'repeat(3, 1fr)', gap: 12 }}>
        {[
          { label: 'פרויקטים פעילים', value: active, sub: `${allProjects.length} סה״כ`, color: '#3b82f6' },
          { label: 'בעיות פתוחות', value: issues, sub: 'דורש תשומת לב', color: '#ef4444' },
          { label: 'עובדים באתרים', value: allProjects.reduce((s,p)=>s+p.team,0), sub: 'כולל קבלני משנה', color: '#8b5cf6' },
        ].map((k,i) => (
          <div key={i} style={{ background: T.kpiBg, border: `1px solid ${T.panelBorder}`, borderRadius: 6, padding: '12px 14px', borderRight: `2px solid ${k.color}` }}>
            <div style={{ fontSize: 10.5, color: T.inkFaint, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.3 }}>{k.label}</div>
            <div style={{ fontSize: 22, fontWeight: 700, marginTop: 4, letterSpacing: -0.5, color: T.ink }}>{k.value}</div>
            <div style={{ fontSize: 11, color: T.inkFaint }}>{k.sub}</div>
          </div>
        ))}
      </div>

      <div style={{ padding: '0 16px 16px', display: 'grid', gridTemplateColumns: isNarrow ? '1fr' : '2fr 1fr', gap: 12 }}>
        <Panel title={showArchive ? 'פרויקטים בארכיון' : 'פרויקטים'} noPad right={
          <div style={{ display: 'flex', gap: 6 }}>
            <V3DropMenu label={statusFilter === 'all' && pmFilter === 'all' ? 'סינון' : 'סינון •'} T={T} items={[
              { label: 'סטטוס: הכל', onClick: () => setStatusFilter('all') },
              { label: 'סטטוס: פעיל', onClick: () => setStatusFilter('active') },
              { label: 'סטטוס: דורש מעקב', onClick: () => setStatusFilter('attention') },
              { label: 'סטטוס: הושלם', onClick: () => setStatusFilter('done') },
              '-',
              { label: 'מנהל: הכל', onClick: () => setPmFilter('all') },
              ...pmOptions.map(pm => ({ label: 'מנהל: ' + pm, onClick: () => setPmFilter(pm) })),
            ]}/>
            {/* v3.9.0.46 — toggle ארכיון */}
            <button onClick={() => setShowArchive(v => !v)}
              style={{ background: showArchive ? '#3b82f6' : 'transparent', border: `1px solid ${showArchive ? '#3b82f6' : T.btnBorder}`,
                color: showArchive ? '#fff' : T.btnColor, padding: '3px 10px', borderRadius: 3, fontSize: 11, cursor: 'pointer', fontFamily: 'inherit' }}>
              {showArchive ? '↩ פעילים' : '📦 ארכיון'}
            </button>
            <button style={{ background: 'transparent', border: `1px solid ${T.btnBorder}`, color: T.btnColor, padding: '3px 8px', borderRadius: 3, fontSize: 11, cursor: 'pointer', fontFamily: 'inherit' }}>ייצוא</button>
          </div>
        }>
          {/* v3.9.0.44 — desktop: 6-col table; mobile (<640px): stacked cards */}
          {!isNarrow && (
            <div style={{ display: 'grid', gridTemplateColumns: '2.5fr 1fr 1.5fr 1fr 1fr 0.6fr', gap: 10, padding: '8px 14px', borderBottom: `1px solid ${T.divider}`, fontSize: 10.5, color: T.inkFaint, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.4 }}>
              <div>פרויקט</div><div>סטטוס</div><div>התקדמות</div><div>תקציב</div><div>סיום</div><div>בעיות</div>
            </div>
          )}
          {visibleProjects.length === 0 && (
            <div style={{ padding: '32px 16px', textAlign: 'center', color: T.inkFaint, fontSize: 13 }}>
              {showArchive ? 'אין פרויקטים בארכיון' : 'אין פרויקטים פעילים'}
            </div>
          )}
          {/* v3.9.0.48 — admin + "כל המנהלים" → סקשנים מקובצים, כל מנהל בנפרד; אחרת רשימה שטוחה */}
          {groupByPM
            ? pmGroups.map(({ pm, items }) => {
                const collapsed = collapsedPMs.has(pm);
                return (
                  <div key={pm}>
                    <div onClick={() => togglePM(pm)} style={{
                      display: 'flex', alignItems: 'center', gap: 8,
                      padding: '10px 14px', borderBottom: `1px solid ${T.divider}`,
                      background: T.kpiBg, cursor: 'pointer', userSelect: 'none',
                    }}>
                      <span style={{ fontSize: 10, color: T.inkFaint, display: 'inline-block', width: 12, textAlign: 'center' }}>
                        {collapsed ? '◀' : '▼'}
                      </span>
                      <span style={{ fontSize: 12.5, fontWeight: 700, color: T.ink }}>{pm}</span>
                      <span style={{ fontSize: 11, color: T.inkFaint }}>· {items.length}</span>
                    </div>
                    {!collapsed && items.map(p => renderProjectRow(p))}
                  </div>
                );
              })
            : visibleProjects.map(p => renderProjectRow(p))
          }
        </Panel>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <Panel title="התראות">
            {(function() {
              const alerts = [];
              projects.forEach(p => {
                if (p.status === 'delay') alerts.push({ level: 'critical', text: `${p.name} — פרויקט בעיכוב` });
                else if (p.openIssues > 0) alerts.push({ level: 'warning', text: `${p.name} — ${p.openIssues} ממצאים פתוחים` });
                else if (p.daysLeft > 0 && p.daysLeft <= 14 && p.status !== 'completed') alerts.push({ level: 'warning', text: `${p.name} — ${p.daysLeft} ימים לסיום` });
              });
              if (alerts.length === 0) {
                return <div style={{ padding: '12px 0', fontSize: 12, color: T.inkFaint, textAlign: 'center' }}>אין התראות פעילות</div>;
              }
              return alerts.slice(0, 6).map((a, i) => {
                const c = a.level === 'critical' ? '#f87171' : a.level === 'warning' ? '#fbbf24' : '#60a5fa';
                return (
                  <div key={i} style={{ padding: '8px 0', borderTop: i > 0 ? `1px solid ${T.divider}` : 'none', display: 'flex', gap: 10 }}>
                    <div style={{ width: 6, height: 6, borderRadius: 3, background: c, marginTop: 6, flexShrink: 0 }}/>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12, color: T.ink, lineHeight: 1.4 }}>{a.text}</div>
                    </div>
                  </div>
                );
              });
            })()}
          </Panel>
          <Panel title="ניצול תקציב">
            <div style={{ height: 120, display: 'flex', alignItems: 'flex-end', gap: 6 }}>
              {projects.map((p,i) => {
                const h = p.budget > 0 ? (p.spent / p.budget) * 100 : 0;
                const c = p.status === 'delay' ? '#f87171' : p.status === 'attention' ? '#fbbf24' : p.status === 'done' ? '#34d399' : '#60a5fa';
                return (
                  <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
                    <div style={{ height: `${h}%`, width: '100%', background: c, borderRadius: '2px 2px 0 0', minHeight: 4 }}/>
                    <div style={{ fontSize: 9, color: T.inkFaint, writingMode: 'vertical-rl', transform: 'rotate(180deg)' }}>P{i+1}</div>
                  </div>
                );
              })}
            </div>
          </Panel>
        </div>
      </div>
    </V3Shell>
  );
};

// ── Dropdown menu for V3 ────────────────────────────────────────────────────
const V3DropMenu = ({ label, icon, bg, items, T }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef();
  React.useEffect(() => {
    if (!open) return;
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);
  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={() => setOpen(o => !o)} style={{
        background: open ? (bg || '#3b82f6') : 'transparent',
        border: `1px solid ${open ? 'transparent' : (T ? T.btnBorder : '#444')}`,
        color: open ? '#fff' : (T ? T.btnColor : '#fff'),
        padding: '3px 10px', borderRadius: 3, fontSize: 11, cursor: 'pointer',
        fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 4,
        transition: 'all .15s',
      }}>
        {icon && <span>{icon}</span>}
        {label}
        <span style={{ fontSize: 8, opacity: 0.7 }}>{open ? '▲' : '▼'}</span>
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', right: 0, zIndex: 9999,
          background: '#1e2d42', borderRadius: 6, boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
          border: '1px solid rgba(255,255,255,0.1)', minWidth: 150, overflow: 'hidden',
        }}>
          {items.map((item, i) => item === '-' ? (
            <div key={i} style={{ height: 1, background: 'rgba(255,255,255,0.08)', margin: '3px 0' }} />
          ) : (
            <button key={i} onClick={() => { item.onClick && item.onClick(); setOpen(false); }} style={{
              display: 'flex', alignItems: 'center', gap: 8, width: '100%',
              padding: '8px 12px', background: 'none', border: 'none',
              fontSize: 12, color: 'rgba(255,255,255,0.85)', cursor: 'pointer',
              fontFamily: 'inherit', textAlign: 'right', transition: 'background .1s',
            }}
            onMouseEnter={e => e.currentTarget.style.background = 'rgba(255,255,255,0.08)'}
            onMouseLeave={e => e.currentTarget.style.background = 'none'}
            >
              {item.icon && <span style={{ fontSize: 14, width: 18, textAlign: 'center' }}>{item.icon}</span>}
              {item.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

const V3ProjectDetail = ({ projectId, onBack, onOpenClient, onNewMeeting, onNewDaily, onOpenTasks, onOpenMeetings, onOpenBudget, onOpenGantt, onOpenBooklet, onOpenReports, onOpenSiteDoc, onOpenQuotes, onOpenPayments, onOpenTenders, onOpenProtocols, onOpenProjContacts, onNav }) => {
  const T = useV3Theme();
  const [subView, setSubView] = useState('overview');
  // v3.9.0.44 — סכומי תקציב אמיתיים מ-BudgetStore (החליפו את project.spent/budget הסטטיים).
  // v3.9.0.47 — טען גם contingency כדי שהכרטיס יציג עלות בפועל **כולל** בלתי צפוי.
  const [budgetTotals, setBudgetTotals] = useState({ estimate: 0, actual: 0, offer: 0, contingency: 0 });
  React.useEffect(() => {
    if (!projectId || !window.BudgetStore) return;
    let cancelled = false;
    (async () => {
      try {
        const { lines, meta } = await window.BudgetStore.getForProject(projectId);
        if (cancelled) return;
        const tot = (lines || []).reduce((a, r) => ({
          estimate: a.estimate + (Number(r.estimate) || 0),
          actual:   a.actual   + (Number(r.actual)   || 0),
          offer:    a.offer    + (Number(r.offer)    || 0),
        }), { estimate: 0, actual: 0, offer: 0 });
        tot.contingency = Number((meta && meta.contingency)) || 0;
        setBudgetTotals(tot);
      } catch (e) { console.warn('[V3ProjectDetail] budget load:', e); }
    })();
    return () => { cancelled = true; };
  }, [projectId]);
  const project = projectId ? (YBP_DATA.projects.find(p => p.id === projectId) || null) : null;
  const detail = YBP_DATA.projectDetail;
  if (!project) {
    return (
      <V3Shell active="list" onNav={onNav} onBack={onBack} crumbs={['פרויקטים']}>
        <div style={{ padding: 60, textAlign: 'center', color: '#9ca3af', fontSize: 15 }}>טוען פרויקטים...</div>
      </V3Shell>
    );
  }
  const ss = statusStyle3(project.status);

  // projectNav החדש — רשימה שטוחה אחת (v3.9.0.50)
  const projectNavData = {
    projectName: project.name,
    items: [
      { icon: 'home',         label: 'סקירה',        subView: 'overview',     onClick: () => setSubView('overview') },
      { icon: 'book',         label: 'חוברת פרויקט', subView: 'booklet',      onClick: onOpenBooklet },
      { icon: 'check_square', label: 'משימות',       subView: 'tasks',        onClick: onOpenTasks },
      { icon: 'clipboard',    label: 'דוחות',        subView: 'reports',      onClick: onOpenReports },
      { icon: 'bar_chart',    label: 'גאנט',         subView: 'gantt',        onClick: onOpenGantt },
      { icon: 'calendar',     label: 'פגישות',       subView: 'meetings',     onClick: onOpenMeetings },
      { icon: 'users',        label: 'אנשי קשר',     subView: 'contacts',     onClick: onOpenProjContacts },
      // Finance items — visible רק אם canSeeFinance
      ...(window.YBP_CAN_SEE_FINANCE ? [
        { icon: 'file_text', label: 'הצעות מחיר', subView: 'quotes',   onClick: onOpenQuotes },
        { icon: 'cloud',     label: 'תשלומים',    subView: 'payments', onClick: onOpenPayments },
        { icon: 'grid',      label: 'תקציב',      subView: 'budget',   onClick: onOpenBudget },
      ] : []),
    ],
    // מוקפא — לא מוצג, נשמר לשימוש עתידי. אל תמחק.
    _frozen: {
      finance: [
        { icon: '📑', label: 'הצעות מחיר', subView: 'quotes',    onClick: onOpenQuotes },
        { icon: '💸', label: 'תשלומים',    subView: 'payments',  onClick: onOpenPayments },
        { icon: '📊', label: 'תקציב',      subView: 'budget',    onClick: onOpenBudget },
      ],
      tenders:   [{ icon: '📬', label: 'מכרזים',     subView: 'tenders',   onClick: onOpenTenders }],
      docs:      [{ icon: '📁', label: 'מסמכים',     subView: 'docs',      onClick: () => setSubView('docs') }],
      team:      [{ icon: '👷', label: 'צוות וקבלנים', subView: 'team',    onClick: () => setSubView('team') }],
    },
  };

  return (
    <V3Shell active="list" onNav={onNav} onBack={onBack} crumbs={['פרויקטים', project.type, project.name]}
      projectNav={projectNavData}
      activeSubView={subView}
      right={
        <>
          <button onClick={onOpenClient} style={{ background: 'transparent', border: `1px solid ${T.btnBorder}`, color: T.btnColor, padding: '3px 10px', borderRadius: 3, fontSize: 11, cursor: 'pointer', fontFamily: 'inherit' }}>לקוח</button>
          <button onClick={onNewMeeting} style={{ background: '#3b82f6', color: '#fff', border: 'none', padding: '3px 12px', borderRadius: 3, fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' }}>+ עדכון</button>
        </>
      }>

      {/* KPI Banner strip */}
      <div style={{ padding: '16px 16px 0', background: T.panelBg, borderBottom: `1px solid ${T.panelBorder}` }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
          <ProjectPlaceholder kind={project.cover} style={{ width: 52, height: 52, borderRadius: 6, flexShrink: 0 }} label={project.type.toUpperCase()}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 2 }}>
              <span style={{ background: ss.bg, color: ss.fg, fontSize: 11, fontWeight: 700, padding: '2px 8px', borderRadius: 3 }}>{project.statusLabel}</span>
              <span style={{ fontSize: 11, color: T.inkFaint }}>ID: {project.id.toUpperCase()}</span>
            </div>
            <div style={{ fontSize: 18, fontWeight: 700, color: T.ink }}>{project.name}</div>
            <div style={{ fontSize: 12, color: T.inkSoft }}>{project.client} • {project.address}</div>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6,1fr)', gap: 0, borderTop: `1px solid ${T.divider}` }}>
          {[
            { l: 'התקדמות', v: `${project.progress}%`, click: onOpenGantt },
            // v3.9.0.47 — "עלות בפועל" **כולל בלתי צפוי** (תואם actualWithContingency במסך התקציב).
            // TODO(payments): כשייבנה מסך התשלומים — לחשב מנתוני תשלומים בפועל.
            { l: 'עלות בפועל', v: fmtMoney(budgetTotals.actual * (1 + (budgetTotals.contingency || 0) / 100)), click: onOpenBudget },
            { l: 'נוצל',       v: `${budgetTotals.estimate > 0 ? Math.round(budgetTotals.actual / budgetTotals.estimate * 100) : 0}%` },
            { l: 'ימים',    v: project.daysLeft },
            { l: 'צוות',    v: project.team,  click: onOpenTasks },
            { l: 'בעיות',   v: project.openIssues },
          ].map(({l,v,click},i) => (
            <div key={i} onClick={click} style={{
              padding: '10px 14px', cursor: click ? 'pointer' : 'default',
              borderLeft: i > 0 ? `1px solid ${T.divider}` : 'none',
            }}
            onMouseEnter={e => click && (e.currentTarget.style.background = T.rowHover)}
            onMouseLeave={e => click && (e.currentTarget.style.background = 'transparent')}
            >
              <div style={{ fontSize: 10, color: T.inkFaint, textTransform: 'uppercase', letterSpacing: 0.4 }}>{l}</div>
              <div style={{ fontSize: 18, fontWeight: 700, color: T.ink, marginTop: 2 }}>{v}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Sub-view content */}
      <div style={{ padding: 16 }}>
        {subView === 'overview' && <V3OverviewView project={project} detail={detail} T={T} ss={ss} onOpenTasks={onOpenTasks} onOpenReports={onOpenReports} onOpenBooklet={onOpenBooklet} projectId={projectId}/>}
        {subView === 'tasks'    && <V3TasksView    detail={detail} T={T} onOpenTasks={onOpenTasks} projectId={projectId}/>}
        {subView === 'updates'  && <V3UpdatesView  projectId={projectId} T={T}
           onOpenReports={onOpenReports} onOpenTasks={onOpenTasks} onOpenBooklet={onOpenBooklet}/>}
        {subView === 'docs'     && <V3DocsView     projectId={projectId} T={T}/>}
        {subView === 'team'     && <V3TeamView     projectId={projectId} T={T}/>}
      </div>
    </V3Shell>
  );
};

// ── V3 Sub-views ──────────────────────────────────────────────────────────────

const V3OverviewView = ({ project, detail, T, ss, onOpenTasks, onOpenReports, onOpenBooklet, projectId }) => {
  const bookletData = React.useMemo(() => {
    try {
      const raw = localStorage.getItem('ybp_booklet_' + projectId);
      if (!raw) return { total: 17, done: 0 };
      const saved = JSON.parse(raw);
      const done = Object.values(saved).filter(v => v.completed).length;
      return { total: 17, done };
    } catch { return { total: 17, done: 0 }; }
  }, [projectId]);
  const bookletPct = Math.round(bookletData.done / bookletData.total * 100);

  // משימות פתוחות אמיתיות מ-SyncStore (במקום detail.tasks הסטטי הריק)
  const [ovStore, setOvStore] = React.useState(() => (typeof SyncStore !== 'undefined' ? SyncStore.get() : { tasks: [] }));
  React.useEffect(() => {
    if (typeof SyncStore === 'undefined') return;
    return SyncStore.subscribe(setOvStore);
  }, []);
  const openTasks = (ovStore.tasks || []).filter(t => t.projectId === projectId && t.status !== 'done');

  // עדכונים אחרונים מ-ActivityStore (5 פריטים) — מחליף את detail.updates הריק
  const [recentFeed, setRecentFeed] = React.useState([]);
  React.useEffect(() => {
    if (!projectId || !window.ActivityStore) return;
    window.ActivityStore.getProjectFeed(projectId)
      .then(f => setRecentFeed((f?.recentActivity || []).slice(0, 5)))
      .catch(() => setRecentFeed([]));
  }, [projectId]);

  return (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
    <div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr', gap: 12 }}>
    <Panel title="שלבים וציר זמן">
      {project.phases.map((ph, i) => {
        const c = ph.status === 'done' ? '#34d399' : ph.status === 'active' ? '#60a5fa' : '#4b5563';
        return (
          <div key={i} style={{ padding: '8px 0', borderTop: i > 0 ? `1px solid ${T.divider}` : 'none' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
              <div style={{ width: 6, height: 6, borderRadius: 3, background: c, flexShrink: 0 }}/>
              <span style={{ fontSize: 12.5, color: T.ink, flex: 1 }}>{ph.name}</span>
              <span style={{ fontSize: 11, color: T.inkSoft }}>{ph.progress}%</span>
            </div>
            <div style={{ height: 3, background: T.barTrack, borderRadius: 2, overflow: 'hidden', marginRight: 16 }}>
              <div style={{ height: '100%', width: `${ph.progress}%`, background: c }}/>
            </div>
          </div>
        );
      })}
    </Panel>

    <Panel title="משימות פתוחות" right={<span style={{ fontSize: 11, color: T.inkSoft }}>{openTasks.length} פתוחות</span>}>
      {openTasks.length === 0 && (
        <div style={{ padding: '14px 0', fontSize: 12, color: T.inkFaint, textAlign: 'center' }}>אין משימות פתוחות</div>
      )}
      {openTasks.slice(0, 6).map((t, i) => {
        const pc = t.severity === 'high' ? '#f87171' : t.severity === 'medium' ? '#fbbf24' : '#60a5fa';
        return (
          <div key={t.id} onClick={() => onOpenTasks && onOpenTasks()} style={{
            padding: '8px 4px', borderTop: i > 0 ? `1px solid ${T.divider}` : 'none',
            display: 'flex', gap: 10, alignItems: 'flex-start', cursor: 'pointer', borderRadius: 4, margin: '0 -4px',
          }}
          onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
          onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
            <div style={{ width: 2, alignSelf: 'stretch', background: pc, borderRadius: 1, flexShrink: 0 }}/>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, color: T.ink, lineHeight: 1.3 }}>{t.title}</div>
              <div style={{ fontSize: 10.5, color: T.inkFaint, marginTop: 2 }}>{t.assignee || '—'}{t.due ? ' • ' + t.due.slice(5) : ''}</div>
            </div>
          </div>
        );
      })}
    </Panel>

    <Panel title="עדכונים אחרונים">
      {recentFeed.length === 0 ? (
        <div style={{ padding: '12px 4px', fontSize: 12, color: T.inkSoft, textAlign: 'center' }}>אין עדכונים להצגה</div>
      ) : recentFeed.map((u, i) => {
        const c = u.severity === 'high' ? '#f87171' : u.severity === 'medium' ? '#fbbf24' : '#60a5fa';
        return (
          <div key={u.id} onClick={() => onOpenReports && onOpenReports()} style={{
            padding: '8px 4px', borderTop: i > 0 ? `1px solid ${T.divider}` : 'none',
            cursor: 'pointer', borderRadius: 4, margin: '0 -4px',
          }}
          onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
          onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 3 }}>
              <span style={{ width: 4, height: 4, borderRadius: 2, background: c, flexShrink: 0 }}/>
              <span style={{ fontSize: 11, color: T.inkSoft, flex: 1 }}>{u.subtitle || ''}</span>
              <span style={{ fontSize: 10.5, color: T.inkFaint }}>{u.date ? new Date(u.date).toLocaleDateString('he-IL') : ''}</span>
            </div>
            <div style={{ fontSize: 12, color: T.ink, lineHeight: 1.4 }}>{u.title}</div>
          </div>
        );
      })}
    </Panel>
  </div>

  {/* כרטיס חוברת פרויקט */}
  {onOpenBooklet && (
    <div onClick={onOpenBooklet} style={{
      background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8,
      padding: '16px 20px', cursor: 'pointer', transition: 'all 0.15s',
      display: 'flex', alignItems: 'center', gap: 16,
    }}
    onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
    onMouseLeave={e => e.currentTarget.style.background = T.panelBg}>
      {/* Progress ring */}
      <div style={{ position: 'relative', width: 52, height: 52, flexShrink: 0 }}>
        <svg width="52" height="52" style={{ transform: 'rotate(-90deg)' }}>
          <circle cx="26" cy="26" r="20" fill="none" stroke={T.barTrack} strokeWidth="5"/>
          <circle cx="26" cy="26" r="20" fill="none" stroke="#60a5fa" strokeWidth="5"
            strokeDasharray={`${2 * Math.PI * 20}`}
            strokeDashoffset={`${2 * Math.PI * 20 * (1 - bookletPct / 100)}`}
            strokeLinecap="round"/>
        </svg>
        <div style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 11, fontWeight: 800, color: T.ink,
        }}>{bookletPct}%</div>
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 14, fontWeight: 700, color: T.ink, marginBottom: 3 }}>📋 חוברת פרויקט</div>
        <div style={{ fontSize: 12, color: T.inkSoft, marginBottom: 6 }}>
          {bookletData.done} מתוך {bookletData.total} משימות הושלמו
        </div>
        <div style={{ height: 4, background: T.barTrack, borderRadius: 2, overflow: 'hidden' }}>
          <div style={{ height: '100%', width: `${bookletPct}%`, background: '#60a5fa', borderRadius: 2, transition: 'width 0.4s' }}/>
        </div>
      </div>
      <div style={{ fontSize: 18, color: T.inkFaint }}>›</div>
    </div>
  )}
  </div>
  );
};

const V3TasksView = ({ T, onOpenTasks, projectId }) => {
  const [view, setView] = useState('kanban'); // 'kanban' | 'list'
  const [showAddModal, setShowAddModal] = useState(false);
  const [store, setStore] = useState(() => (typeof SyncStore !== 'undefined' ? SyncStore.get() : { tasks: [] }));
  React.useEffect(() => {
    if (typeof SyncStore === 'undefined') return;
    return SyncStore.subscribe(setStore);
  }, []);

  // משימות אמיתיות מ-SyncStore, מסוננות לפרויקט הנוכחי
  const tasks = (store.tasks || []).filter(t => t.projectId === projectId && t.status !== 'archived');

  // מיפוי חומרה (severity) → תווית + צבע. SyncStore שומר 'high'/'medium'/'low'
  const sevMap = {
    high:   { label: 'גבוהה',   color: '#f87171' },
    medium: { label: 'בינונית', color: '#fbbf24' },
    low:    { label: 'נמוכה',   color: '#60a5fa' },
  };

  const cols = [
    { k: 'open',        label: 'לביצוע', color: '#9ca3af' },
    { k: 'in-progress', label: 'בביצוע', color: '#3b82f6' },
    { k: 'review',      label: 'בבדיקה', color: '#f59e0b' },
    { k: 'done',        label: 'הושלם',  color: '#10b981' },
  ];
  const knownStatuses = new Set(cols.map(c => c.k));
  // סטטוס לא מוכר → משויך ל'לביצוע' כדי שאף משימה לא תיעלם מה-Kanban
  const normStatus = (s) => (knownStatuses.has(s) ? s : 'open');

  const tabBtn = (active) => ({
    flex: 1, padding: '8px 14px', borderRadius: 6, fontSize: 13, fontWeight: 600,
    fontFamily: 'inherit', cursor: 'pointer',
    background: active ? T.panelBg : 'transparent',
    color: active ? T.ink : T.inkSoft,
    border: active ? `1px solid ${T.panelBorder}` : '1px solid transparent',
    boxShadow: active ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
  });

  return (
    <div>
      {/* Sub-tabs + Add button row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
        <div style={{ display: 'flex', background: T.rowHover, borderRadius: 7, padding: 3, gap: 2, flex: '0 0 auto' }}>
          <button onClick={() => setView('kanban')} style={tabBtn(view === 'kanban')}>📋 Kanban</button>
          <button onClick={() => setView('list')} style={tabBtn(view === 'list')}>📃 רשימה</button>
        </div>
        {onOpenTasks && (
          <button onClick={onOpenTasks} style={{
            background: 'transparent', border: 'none', color: T.inkSoft,
            fontSize: 12, cursor: 'pointer', fontFamily: 'inherit', textDecoration: 'underline',
          }}>מסך מלא ↗</button>
        )}
        <button onClick={() => setShowAddModal(true)} style={{
          marginRight: 'auto',
          background: '#1a2c4a', color: '#fff', border: 'none',
          padding: '8px 14px', borderRadius: 6, fontSize: 13, fontWeight: 600,
          cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, fontFamily: 'inherit',
        }}>
          + הוסף משימה
        </button>
      </div>

      {showAddModal && typeof AddTaskModal !== 'undefined' && (
        <AddTaskModal projectId={projectId} onClose={() => setShowAddModal(false)}/>
      )}

      {/* Empty state — אין משימות בכלל לפרויקט */}
      {tasks.length === 0 && (
        <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, padding: 40, textAlign: 'center' }}>
          <div style={{ fontSize: 32, marginBottom: 8 }}>✅</div>
          <div style={{ fontSize: 14, color: T.inkSoft, marginBottom: 4 }}>אין עדיין משימות בפרויקט זה</div>
          <div style={{ fontSize: 12, color: T.inkFaint }}>לחץ "הוסף משימה" כדי ליצור משימה ראשונה</div>
        </div>
      )}

      {/* View: Kanban */}
      {tasks.length > 0 && view === 'kanban' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 10 }}>
          {cols.map(col => {
            const items = tasks.filter(t => normStatus(t.status) === col.k);
            return (
              <div key={col.k} style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, padding: 10, minHeight: 300 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 10 }}>
                  <span style={{ width: 7, height: 7, borderRadius: 4, background: col.color }}/>
                  <span style={{ fontSize: 12, fontWeight: 700, color: T.ink }}>{col.label}</span>
                  <span style={{ fontSize: 11, color: T.inkFaint }}>{items.length}</span>
                </div>
                {items.map(t => {
                  const sv = sevMap[t.severity] || sevMap.medium;
                  return (
                    <div key={t.id} onClick={() => setView('list')} style={{
                      background: T.rowHover, borderRadius: 6, padding: 10, marginBottom: 6,
                      cursor: 'pointer', border: `1px solid ${T.panelBorder}`,
                    }}
                    onMouseEnter={e => e.currentTarget.style.opacity = '0.8'}
                    onMouseLeave={e => e.currentTarget.style.opacity = '1'}>
                      <div style={{ fontSize: 11, fontWeight: 500, color: T.ink, lineHeight: 1.3, marginBottom: 6 }}>{t.title}</div>
                      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                        <span style={{ fontSize: 10, color: sv.color, fontWeight: 600 }}>{sv.label}</span>
                        <span style={{ fontSize: 10, color: T.inkFaint }}>{t.due ? t.due.slice(5) : ''}</span>
                      </div>
                    </div>
                  );
                })}
                {items.length === 0 && (
                  <div style={{ fontSize: 11, color: T.inkFaint, textAlign: 'center', padding: '12px 0' }}>—</div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {/* View: List — רשימה מלאה משובצת בתוך ה-Tab (TaskCard) */}
      {tasks.length > 0 && view === 'list' && (
        <div>
          {typeof TaskCard !== 'undefined' ? (
            tasks.map(t => <TaskCard key={t.id} task={t} store={store}/>)
          ) : (
            <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, padding: 32, textAlign: 'center' }}>
              <div style={{ fontSize: 14, color: T.inkSoft, marginBottom: 12 }}>הרשימה המפורטת נפתחת במסך נפרד</div>
              <button onClick={() => onOpenTasks && onOpenTasks()} style={{
                background: '#1a2c4a', color: '#fff', border: 'none',
                padding: '10px 18px', borderRadius: 6, fontSize: 13, fontWeight: 600,
                cursor: 'pointer', fontFamily: 'inherit',
              }}>פתח רשימה מפורטת ←</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const V3UpdatesView = ({ projectId, T, onOpenReports, onOpenTasks, onOpenBooklet }) => {
  const [feed, setFeed] = React.useState(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    if (!projectId) { setLoading(false); return; }
    setLoading(true);
    (window.ActivityStore?.getProjectFeed(projectId) || Promise.resolve(null))
      .then(f => { setFeed(f); setLoading(false); })
      .catch(() => { setFeed(null); setLoading(false); });
  }, [projectId]);

  const routeFn = (route) => {
    if (route === 'tasks')   return onOpenTasks;
    if (route === 'reports') return onOpenReports;
    if (route === 'booklet') return onOpenBooklet;
    return null;
  };

  if (loading) return <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft, fontSize: 13 }}>טוען עדכונים…</div>;
  if (!feed) return <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft }}>שגיאה בטעינת עדכונים</div>;

  const { statusStrip: s, needsAttention, recentActivity } = feed;
  const isEmpty = (!needsAttention?.length) && (!recentActivity?.length);
  if (isEmpty) return (
    <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft }}>
      <div style={{ fontSize: 32, marginBottom: 10 }}>📊</div>
      <div style={{ fontSize: 14, fontWeight: 600, color: T.ink }}>אין פעילות להצגה</div>
    </div>
  );

  const stripCard = (label, value, color) => (
    <div style={{ flex: '1 1 0', minWidth: 100, background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, padding: '10px 12px' }}>
      <div style={{ fontSize: 11, color: T.inkSoft, marginBottom: 4 }}>{label}</div>
      <div style={{ fontSize: 18, fontWeight: 700, color: color || T.ink }}>{value}</div>
    </div>
  );

  const sevBg = (sev) => sev === 'high' ? 'rgba(239,68,68,0.08)' : sev === 'medium' ? 'rgba(245,158,11,0.08)' : 'transparent';
  const sevDot = (sev) => sev === 'high' ? '#f87171' : sev === 'medium' ? '#fbbf24' : sev === 'low' ? '#9ca3af' : '#60a5fa';

  const renderRow = (item, i, list) => (
    <div key={item.id} onClick={() => { const fn = routeFn(item.route); fn && fn(); }} style={{
      display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 14px',
      borderBottom: i < list.length - 1 ? `1px solid ${T.divider}` : 'none',
      background: sevBg(item.severity), cursor: 'pointer',
    }}
    onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
    onMouseLeave={e => e.currentTarget.style.background = sevBg(item.severity)}>
      <span style={{ width: 6, height: 6, borderRadius: 3, background: sevDot(item.severity), marginTop: 6, flexShrink: 0 }}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: T.ink }}>{item.title}</div>
        {item.subtitle && <div style={{ fontSize: 11, color: T.inkSoft, marginTop: 2 }}>{item.subtitle}</div>}
      </div>
      {item.date && <div style={{ fontSize: 11, color: T.inkFaint, flexShrink: 0 }}>{new Date(item.date).toLocaleDateString('he-IL')}</div>}
    </div>
  );

  return (
    <div style={{ maxWidth: 900, margin: '0 auto', display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* Status strip */}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        {stripCard('משימות פתוחות', s.tasksOpen)}
        {stripCard('בביצוע', s.tasksInProgress)}
        {stripCard('הושלמו', s.tasksDone, '#10b981')}
        {stripCard('באיחור', s.tasksOverdue, s.tasksOverdue > 0 ? '#ef4444' : T.ink)}
        {stripCard('חוברת', `${s.bookletDone}/${s.bookletTotal}`)}
        {stripCard("ריג'קטים ממתינים", s.rejectsPending, s.rejectsPending > 0 ? '#f59e0b' : T.ink)}
      </div>

      {/* Needs attention */}
      {needsAttention?.length > 0 && (
        <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, overflow: 'hidden' }}>
          <div style={{ padding: '12px 14px', borderBottom: `1px solid ${T.divider}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ fontSize: 13, fontWeight: 700, color: T.ink }}>⚠ דורש טיפול</span>
            <span style={{ fontSize: 11, color: T.inkSoft, background: T.rowHover, padding: '2px 8px', borderRadius: 10 }}>{needsAttention.length}</span>
          </div>
          {needsAttention.map((item, i) => renderRow(item, i, needsAttention))}
        </div>
      )}

      {/* Recent activity */}
      {recentActivity?.length > 0 && (
        <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, overflow: 'hidden' }}>
          <div style={{ padding: '12px 14px', borderBottom: `1px solid ${T.divider}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ fontSize: 13, fontWeight: 700, color: T.ink }}>📋 פעילות אחרונה</span>
            <span style={{ fontSize: 11, color: T.inkSoft, background: T.rowHover, padding: '2px 8px', borderRadius: 10 }}>{recentActivity.length}</span>
          </div>
          {recentActivity.map((item, i) => renderRow(item, i, recentActivity))}
        </div>
      )}
    </div>
  );
};

const V3DocsView = ({ projectId, T }) => (
  <div style={{ maxWidth: 900, margin: '0 auto' }}>
    {window.DriveFolderEmbed
      ? <window.DriveFolderEmbed projectId={projectId}/>
      : <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft }}>טוען…</div>}
  </div>
);

// ── PM management helpers (v3.9.0.43) ─────────────────────────────────────────
const _pmKeyOf = (email) => (email || '').split('@')[0].toLowerCase();
const _ADMIN_EMAILS = ['nathan@ybprojects.com','yuval@ybprojects.com','barak@ybprojects.com'];
const _isAdminUser = (u) => !!u && (u.role === 'admin' || _ADMIN_EMAILS.includes((u.email || '').toLowerCase()));

const ProjectManagersPanel = ({ project, profiles, setProject, T }) => {
  const [busy, setBusy]       = React.useState(false);
  const [adding, setAdding]   = React.useState(false);
  const [pickKey, setPickKey] = React.useState('');
  const [changing, setChanging] = React.useState(false);
  const [newMainKey, setNewMainKey] = React.useState('');

  const me        = (window.YBP_AUTH && window.YBP_AUTH.getCurrentUser) ? window.YBP_AUTH.getCurrentUser() : null;
  const myKey     = me ? _pmKeyOf(me.email) : '';
  const isAdmin   = _isAdminUser(me);
  const mainKey   = (project?.pmKey || project?.data?.pmKey || '').toLowerCase();
  const mainName  = project?.pm || project?.data?.pm || '';
  const isMainPm  = !!mainKey && mainKey === myKey;
  const canManage = isAdmin || isMainPm;

  const pmsList   = Array.isArray(project?.pms) && project.pms.length ? project.pms
                  : Array.isArray(project?.data?.pms) && project.data.pms.length ? project.data.pms
                  : (mainKey ? [mainKey] : []);
  const extras    = pmsList.filter(k => k && k.toLowerCase() !== mainKey);

  const profileByKey = (k) => profiles.find(p => _pmKeyOf(p.email) === (k || '').toLowerCase()) || null;
  const nameOf       = (k) => profileByKey(k)?.full_name || profileByKey(k)?.email || k;

  // mainKey first, then extras alphabetically; selectable list excludes already-included
  const availableForAdd = profiles.filter(p => !pmsList.includes(_pmKeyOf(p.email)));

  const persist = async (nextPmKey, nextPm, nextPms) => {
    const merged = {
      ...project,
      pm:    nextPm,
      pmKey: nextPmKey,
      pms:   nextPms,
    };
    setBusy(true);
    try {
      // 1) UI state
      setProject(merged);
      // 2) YBP_DATA
      const arr = (window.YBP_DATA && window.YBP_DATA.projects) || [];
      const idx = arr.findIndex(p => p.id === merged.id);
      if (idx !== -1) arr[idx] = merged;
      // 3) localStorage cache
      try {
        const cache = JSON.parse(localStorage.getItem('ybp_user_projects') || '[]');
        const ci = cache.findIndex(p => p.id === merged.id);
        if (ci !== -1) { cache[ci] = merged; localStorage.setItem('ybp_user_projects', JSON.stringify(cache)); }
      } catch {}
      // 4) Supabase
      if (window.saveProjectToSupabase) {
        const res = await window.saveProjectToSupabase(merged);
        if (!res.ok) {
          alert('שגיאה בשמירה לענן: ' + (res.error || 'unknown'));
        }
      }
    } finally { setBusy(false); }
  };

  const handleChangeMain = async () => {
    if (!newMainKey) return;
    const p = profileByKey(newMainKey);
    if (!p) return;
    const nextPms = Array.from(new Set([newMainKey, ...pmsList.filter(k => k !== mainKey)]));
    await persist(newMainKey, p.full_name || p.email, nextPms);
    setChanging(false); setNewMainKey('');
  };

  const handleAdd = async () => {
    if (!pickKey) return;
    if (pmsList.includes(pickKey)) { setAdding(false); setPickKey(''); return; }
    const nextPms = [...pmsList, pickKey];
    await persist(mainKey, mainName, nextPms);
    setAdding(false); setPickKey('');
  };

  const handleRemove = async (key) => {
    if (key === mainKey) { alert('אסור להסיר את המנהל האחראי'); return; }
    if (!confirm(`להסיר את ${nameOf(key)} מהפרויקט?`)) return;
    const nextPms = pmsList.filter(k => k !== key);
    await persist(mainKey, mainName, nextPms);
  };

  const btn = {
    padding: '5px 12px', borderRadius: 6, fontSize: 11, fontWeight: 700,
    cursor: 'pointer', fontFamily: 'inherit', border: `1px solid ${T.panelBorder}`,
    background: T.rowHover, color: T.ink,
  };
  const btnPrimary = { ...btn, background: '#1a2c4a', color: '#fff', border: '1px solid #1a2c4a' };

  return (
    <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, overflow: 'hidden', marginBottom: 12 }}>
      <div style={{ padding: '12px 18px', borderBottom: `1px solid ${T.divider}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}>
        <span style={{ fontSize: 13, fontWeight: 700, color: T.ink }}>🧭 מנהלי הפרויקט</span>
        {canManage && (
          <div style={{ display: 'flex', gap: 6 }}>
            <button disabled={busy} onClick={() => { setChanging(v => !v); setAdding(false); }} style={btn}>
              ↔ החלף אחראי
            </button>
            <button disabled={busy} onClick={() => { setAdding(v => !v); setChanging(false); }} style={btn}>
              + הוסף מנהל
            </button>
          </div>
        )}
      </div>

      {/* Main PM */}
      <div style={{ padding: '12px 18px', borderBottom: extras.length ? `1px solid ${T.divider}` : 'none', display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 12, alignItems: 'center' }}>
        <Avatar name={mainName || '?'} size={36}/>
        <div>
          <div style={{ fontSize: 13, fontWeight: 700, color: T.ink }}>{mainName || nameOf(mainKey) || '(לא מוגדר)'}</div>
          <div style={{ fontSize: 11, color: T.inkSoft }}>
            <span style={{ background: '#fef3c7', color: '#92400e', padding: '1px 8px', borderRadius: 10, fontWeight: 700 }}>אחראי</span>
            {mainKey && <span style={{ marginRight: 6 }}>· {mainKey}</span>}
          </div>
        </div>
        <div/>
      </div>

      {/* Extras */}
      {extras.map((k, i) => (
        <div key={k} style={{
          padding: '10px 18px', display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 12, alignItems: 'center',
          borderBottom: i < extras.length - 1 ? `1px solid ${T.divider}` : 'none',
        }}>
          <Avatar name={nameOf(k)} size={32}/>
          <div>
            <div style={{ fontSize: 12, fontWeight: 600, color: T.ink }}>{nameOf(k)}</div>
            <div style={{ fontSize: 10, color: T.inkSoft }}>גישה נוספת · {k}</div>
          </div>
          {canManage && (
            <button onClick={() => handleRemove(k)} disabled={busy} title="הסר" style={{
              background: 'transparent', border: 'none', cursor: 'pointer',
              color: '#ef4444', fontSize: 13, padding: 4,
            }}>🗑 הסר</button>
          )}
        </div>
      ))}

      {/* Change-main picker */}
      {changing && canManage && (
        <div style={{ padding: '12px 18px', borderTop: `1px solid ${T.divider}`, background: T.rowHover, display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
          <select value={newMainKey} onChange={e => setNewMainKey(e.target.value)} style={{
            padding: '6px 10px', borderRadius: 6, border: `1px solid ${T.panelBorder}`,
            fontSize: 12, fontFamily: 'inherit', background: T.panelBg, color: T.ink, minWidth: 200,
          }}>
            <option value="">— בחר מנהל חדש —</option>
            {profiles.filter(p => _pmKeyOf(p.email) !== mainKey).map(p => (
              <option key={p.id} value={_pmKeyOf(p.email)}>{p.full_name || p.email} · {p.email}</option>
            ))}
          </select>
          <button disabled={!newMainKey || busy} onClick={handleChangeMain} style={btnPrimary}>שמור</button>
          <button onClick={() => { setChanging(false); setNewMainKey(''); }} style={btn}>ביטול</button>
          {/* TODO(drive): החלפת אחראי לא מעבירה את תיקיית הדרייב (נוצרה תחת ה-PM המקורי). העברת תיקייה — נושא נפרד. */}
        </div>
      )}

      {/* Add-extra picker */}
      {adding && canManage && (
        <div style={{ padding: '12px 18px', borderTop: `1px solid ${T.divider}`, background: T.rowHover, display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
          <select value={pickKey} onChange={e => setPickKey(e.target.value)} style={{
            padding: '6px 10px', borderRadius: 6, border: `1px solid ${T.panelBorder}`,
            fontSize: 12, fontFamily: 'inherit', background: T.panelBg, color: T.ink, minWidth: 200,
          }}>
            <option value="">— בחר מנהל להוספה —</option>
            {availableForAdd.map(p => (
              <option key={p.id} value={_pmKeyOf(p.email)}>{p.full_name || p.email} · {p.email}</option>
            ))}
          </select>
          <button disabled={!pickKey || busy} onClick={handleAdd} style={btnPrimary}>הוסף</button>
          <button onClick={() => { setAdding(false); setPickKey(''); }} style={btn}>ביטול</button>
        </div>
      )}

      {!canManage && (
        <div style={{ padding: '8px 18px', fontSize: 10, color: T.inkSoft, background: T.rowHover, borderTop: `1px solid ${T.divider}` }}>
          רק admin או המנהל האחראי יכולים לשנות מנהלים.
        </div>
      )}
    </div>
  );
};

const V3TeamView = ({ projectId, T }) => {
  const [contacts, setContacts] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [profiles, setProfiles] = React.useState([]);
  const [project, setProject] = React.useState(
    () => (window.YBP_DATA && window.YBP_DATA.projects || []).find(p => p.id === projectId) || null
  );

  React.useEffect(() => {
    if (!projectId) { setLoading(false); return; }
    setLoading(true);
    (window.ContactsStore?.listForProject(projectId) || Promise.resolve([]))
      .then(list => { setContacts(list || []); setLoading(false); })
      .catch(() => { setContacts([]); setLoading(false); });
  }, [projectId]);

  // v3.9.0.44 — טען PM list מטבלת contacts (role='ניהול פרויקט') במקום מ-profiles.
  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        if (!window.ContactsStore || !window.ContactsStore.listProjectManagers) return;
        const rows = await window.ContactsStore.listProjectManagers();
        if (!cancelled) setProfiles(rows || []);
      } catch (e) { console.warn('[V3TeamView] listProjectManagers failed:', e); }
    })();
    return () => { cancelled = true; };
  }, []);

  // Sync local project state when YBP_DATA changes (e.g. after refresh)
  React.useEffect(() => {
    const fresh = (window.YBP_DATA && window.YBP_DATA.projects || []).find(p => p.id === projectId);
    if (fresh) setProject(fresh);
  }, [projectId]);

  const contactsPanel = (
    loading ? (
      <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft, fontSize: 13 }}>
        טוען אנשי קשר...
      </div>
    ) : contacts.length === 0 ? (
      <div style={{ padding: 40, textAlign: 'center', color: T.inkSoft, background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8 }}>
        <div style={{ fontSize: 32, marginBottom: 10 }}>👥</div>
        <div style={{ fontSize: 14, fontWeight: 600, color: T.ink, marginBottom: 6 }}>אין אנשי קשר משויכים</div>
        <div style={{ fontSize: 12, color: T.inkSoft }}>שייך אנשי קשר לפרויקט דרך מסך CRM</div>
      </div>
    ) : (
      <div style={{ background: T.panelBg, border: `1px solid ${T.panelBorder}`, borderRadius: 8, overflow: 'hidden' }}>
        <div style={{ padding: '12px 18px', borderBottom: `1px solid ${T.divider}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span style={{ fontSize: 13, fontWeight: 700, color: T.ink }}>👥 צוות וקבלנים</span>
          <span style={{ fontSize: 11, color: T.inkSoft, background: T.rowHover, padding: '2px 8px', borderRadius: 10 }}>{contacts.length} איש</span>
        </div>
        {contacts.map((c, i) => {
          const phone = c.phone || c.office_phone || '';
          const email = c.email || c.office_email || '';
          return (
            <div key={c.id || i} style={{
              display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 12,
              padding: '12px 18px', alignItems: 'center',
              borderBottom: i < contacts.length - 1 ? `1px solid ${T.divider}` : 'none',
            }}
            onMouseEnter={e => e.currentTarget.style.background = T.rowHover}
            onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <Avatar name={c.name} size={36}/>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: T.ink }}>{c.name}</div>
                <div style={{ fontSize: 11, color: T.inkSoft }}>{c.role}{c.company ? ` · ${c.company}` : ''}</div>
                {phone && <div style={{ fontSize: 11, color: T.inkSoft, marginTop: 2 }}>{phone}</div>}
              </div>
              <div style={{ display: 'flex', gap: 6 }}>
                {phone && (
                  <a href={`tel:${phone}`} style={{ width: 30, height: 30, borderRadius: 7, border: `1px solid ${T.panelBorder}`, background: T.rowHover, display: 'flex', alignItems: 'center', justifyContent: 'center', textDecoration: 'none', fontSize: 13 }} title="התקשר">📞</a>
                )}
                {email && (
                  <a href={`mailto:${email}`} style={{ width: 30, height: 30, borderRadius: 7, border: `1px solid ${T.panelBorder}`, background: T.rowHover, display: 'flex', alignItems: 'center', justifyContent: 'center', textDecoration: 'none', fontSize: 13 }} title="מייל">✉️</a>
                )}
              </div>
            </div>
          );
        })}
      </div>
    )
  );

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <ProjectManagersPanel project={project} profiles={profiles} setProject={setProject} T={T}/>
      {contactsPanel}
    </div>
  );
};

const V3ClientView = ({ projectId, onBack }) => {
  const project = YBP_DATA.projects.find(p => p.id === projectId) || YBP_DATA.projects[0];
  return (
    <div style={{ background: '#0f1419', minHeight: '100%', fontFamily: 'Assistant, sans-serif', color: '#e5e7eb', direction: 'rtl' }}>
      <header style={{ background: '#1a2230', borderBottom: '1px solid #2a3444', padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 12 }}>
        <button onClick={onBack} style={{ background: 'transparent', border: 'none', color: '#9ca3af', cursor: 'pointer', padding: 6 }}><Icon name="chevronR" size={14}/></button>
        <img src="assets/ybp-logo-new.png" alt="YBP" style={{ height: 26, display: 'block', objectFit: 'contain' }}/>
        <div style={{ fontSize: 12, color: '#9ca3af' }}>פורטל לקוח • {project.client}</div>
        <div style={{ marginRight: 'auto', fontSize: 11, color: '#6b7280' }}>Live • עודכן לפני 2 שעות</div>
      </header>
      <div style={{ padding: 20, maxWidth: 1100, margin: '0 auto' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 16 }}>
          <div>
            <div style={{ fontSize: 11, color: '#60a5fa', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>LIVE STATUS</div>
            <h1 style={{ fontSize: 32, fontWeight: 700, color: '#fff', marginTop: 6, letterSpacing: -0.8 }}>{project.name}</h1>
            <div style={{ fontSize: 13, color: '#9ca3af', marginTop: 4 }}>{project.address}</div>
            <ProjectPlaceholder kind={project.cover} style={{ height: 260, marginTop: 18, borderRadius: 6 }} label="LIVE SITE VIEW"/>
          </div>
          <div>
            <div style={{ background: '#1a2230', border: '1px solid #2a3444', borderRadius: 6, padding: 24, textAlign: 'center' }}>
              <div style={{ fontSize: 80, fontWeight: 700, color: '#60a5fa', letterSpacing: -3, lineHeight: 1 }}>{project.progress}<span style={{ fontSize: 36 }}>%</span></div>
              <div style={{ fontSize: 13, color: '#9ca3af', marginTop: 4 }}>הושלם מהפרויקט</div>
              <div style={{ marginTop: 16, paddingTop: 16, borderTop: '1px solid #2a3444', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, textAlign: 'right' }}>
                <div><div style={{ fontSize: 10, color: '#6b7280', textTransform: 'uppercase' }}>ימים שנותרו</div><div style={{ fontSize: 22, fontWeight: 700, color: '#fff' }}>{project.daysLeft}</div></div>
                <div><div style={{ fontSize: 10, color: '#6b7280', textTransform: 'uppercase' }}>סיום</div><div style={{ fontSize: 15, fontWeight: 700, color: '#fff', marginTop: 4 }}>{project.endDate}</div></div>
              </div>
            </div>
            <div style={{ marginTop: 12, background: '#1a2230', border: '1px solid #2a3444', borderRadius: 6, padding: 16 }}>
              <div style={{ fontSize: 11, color: '#9ca3af', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.4, marginBottom: 10 }}>שלבי פרויקט</div>
              {project.phases.map((ph, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 0' }}>
                  <div style={{ width: 20, height: 20, borderRadius: 10,
                    background: ph.status === 'done' ? '#34d399' : ph.status === 'active' ? '#1a2230' : '#2a3444',
                    border: ph.status === 'active' ? '2px solid #60a5fa' : 'none',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 10, fontWeight: 700, color: '#fff' }}>
                    {ph.status === 'done' ? <Icon name="check" size={11} color="#0f1419" strokeWidth={3}/> : i + 1}
                  </div>
                  <div style={{ flex: 1, fontSize: 12.5, color: '#e5e7eb' }}>{ph.name}</div>
                  <div style={{ fontSize: 11, color: ph.status === 'done' ? '#34d399' : ph.status === 'active' ? '#60a5fa' : '#6b7280' }}>
                    {ph.status === 'done' ? '✓' : ph.status === 'active' ? ph.progress + '%' : '—'}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Budget section for client */}
        {(() => {
          const [showDetail, setShowDetail] = React.useState(false);
          const spent = project.spent, budget = project.budget;
          const pct = budget > 0 ? Math.round((spent/budget)*100) : 0;
          return (
            <div style={{ marginTop: 16, background: '#1a2230', border: '1px solid #2a3444', borderRadius: 6, padding: 20 }}>
              <div style={{ fontSize: 11, color: '#9ca3af', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.4, marginBottom: 14 }}>סיכום תקציב</div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 12, marginBottom: 14, textAlign: 'center' }}>
                {[
                  { label: 'אומדן תקציב', value: budget, color: '#60a5fa' },
                  { label: 'הצעות מחיר', value: spent, color: '#fbbf24' },
                  { label: 'עלות בפועל', value: budget-spent, color: budget-spent < 0 ? '#f87171' : '#34d399' },
                ].map(({label,value,color}) => (
                  <div key={label}>
                    <div style={{ fontSize: 10, color: '#6b7280', marginBottom: 4 }}>{label}</div>
                    <div style={{ fontSize: 18, fontWeight: 700, color }}>{value.toLocaleString('he-IL')} ₪</div>
                  </div>
                ))}
              </div>
              <div style={{ height: 6, background: '#2a3444', borderRadius: 3, overflow: 'hidden', marginBottom: 10 }}>
                <div style={{ height: '100%', width: `${Math.min(100,pct)}%`, background: pct > 100 ? '#f87171' : '#60a5fa', borderRadius: 3 }}/>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <span style={{ fontSize: 11, color: '#6b7280' }}>{pct}% נוצל</span>
                <button onClick={() => setShowDetail(v => !v)} style={{
                  background: 'transparent', border: '1px solid #2a3444', color: '#9ca3af',
                  padding: '5px 12px', borderRadius: 4, fontSize: 11, cursor: 'pointer', fontFamily: 'inherit',
                }}>{showDetail ? '▲ הסתר פירוט' : '▼ פירוט תקציב'}</button>
              </div>
              {showDetail && (
                <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid #2a3444' }}>
                  {(() => {
                    try {
                      const d = JSON.parse(localStorage.getItem('ybp_budget_' + projectId));
                      if (!d) return <div style={{ fontSize: 12, color: '#6b7280', textAlign: 'center', padding: 12 }}>פירוט יעודכן בקרוב</div>;
                      return d.sections.map(s => {
                        const tot = s.items.reduce((a,it) => ({ e: a.e+(Number(it.estimate)||0), o: a.o+(Number(it.offer)||0), ac: a.ac+(Number(it.actual)||0) }), {e:0,o:0,ac:0});
                        if (!tot.e && !tot.o && !tot.ac) return null;
                        return (
                          <div key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0', borderBottom: '1px solid #1f2937', fontSize: 12 }}>
                            <span>{s.icon}</span>
                            <span style={{ flex: 1, color: '#e5e7eb' }}>{s.name}</span>
                            {tot.e > 0 && <span style={{ color: '#6b7280' }}>א׳ {tot.e.toLocaleString('he-IL')}</span>}
                            {tot.o > 0 && <span style={{ color: '#60a5fa' }}>הצ׳ {tot.o.toLocaleString('he-IL')}</span>}
                            {tot.ac > 0 && <span style={{ color: '#34d399', fontWeight: 700 }}>פ׳ {tot.ac.toLocaleString('he-IL')}</span>}
                          </div>
                        );
                      });
                    } catch(e) { return <div style={{ fontSize: 12, color: '#6b7280' }}>לא זמין</div>; }
                  })()}
                </div>
              )}
            </div>
          );
        })()}
      </div>
    </div>
  );
};

Object.assign(window, { V3ProjectsList, V3ProjectDetail, V3ClientView });
})();
