// MOTIONS PLATFORM — hub sub-platforms + pill sub-nav
// 6 hubs: Motion Queue · Drafting · Brief Bank · Citations · Calendar · Judges
const { useState: useMnH, useMemo: useMnHMemo } = React;
const Tmnh = window.ArbiterTokens;

// ── Shared pill sub-nav ─────────────────────────────────────────────────────
function MnSubNav({ views, active, onChange }) {
  const mn = window.__mn;
  return (
    <div style={{
      display: 'flex', gap: '4px', padding: '6px',
      background: Tmnh.color.bg.secondary,
      border: `1px solid ${Tmnh.color.border.light}`,
      borderRadius: '8px', marginBottom: '16px', flexWrap: 'wrap',
    }}>
      {views.map(v => {
        const isActive = active === v.id;
        return (
          <button key={v.id} onClick={() => onChange(v.id)} style={{
            padding: '6px 12px', fontSize: '11px',
            fontWeight: isActive ? 700 : 500,
            borderRadius: '6px', border: 'none', cursor: 'pointer',
            background: isActive ? mn.plum : 'transparent',
            color: isActive ? '#fff' : Tmnh.color.text.secondary,
            display: 'inline-flex', alignItems: 'center', gap: '6px',
            transition: 'all 0.12s', fontFamily: Tmnh.font.family,
          }}>
            {v.label}
            {v.badge != null && (
              <span style={{
                fontSize: '10px', fontWeight: 700,
                padding: '1px 6px', borderRadius: '8px',
                background: isActive ? 'rgba(255,255,255,0.22)' : Tmnh.color.bg.card,
                color: isActive ? '#fff' : Tmnh.color.text.tertiary,
                fontFamily: Tmnh.font.mono,
              }}>{v.badge}</span>
            )}
          </button>
        );
      })}
    </div>
  );
}
window.MnSubNav = MnSubNav;

// ── QUEUE > My Docket ───────────────────────────────────────────────────────
function MnQueueMyDocket({ data }) {
  const mn = window.__mn;
  const me = 'M. Kirkland';
  const mine = data.motions.filter(m => m.author === me);
  const dueThisWeek = mine.filter(m => {
    if (!m.hearingDate) return false;
    const d = new Date(m.hearingDate);
    const diff = (d - new Date('2026-04-21')) / 86400000;
    return diff >= 0 && diff <= 7;
  });
  const filed = mine.filter(m => ['Filed','Fully Briefed','Under Submission','Awaiting Argument','Opposition Pending'].includes(m.status));
  const won = mine.filter(m => m.status === 'Granted' || m.status === 'Granted in Part');
  const decided = mine.filter(m => ['Granted','Granted in Part','Denied'].includes(m.status));
  const myWin = decided.length ? Math.round((won.length / decided.length) * 100) : 0;

  return (
    <div>
      <div style={mn.stripKpi}>
        <div style={mn.stat}><span style={mn.statLabel}>My active</span><span style={mn.statValue}>{mine.length}</span><span style={{ ...mn.statDelta, color: Tmnh.color.text.tertiary }}>all stages</span></div>
        <div style={mn.stat}><span style={mn.statLabel}>Due ≤ 7 days</span><span style={{ ...mn.statValue, color: mn.crimson }}>{dueThisWeek.length}</span></div>
        <div style={mn.stat}><span style={mn.statLabel}>Filed & pending</span><span style={{ ...mn.statValue, color: mn.plum }}>{filed.length}</span></div>
        <div style={mn.stat}><span style={mn.statLabel}>Decided (YTD)</span><span style={mn.statValue}>{decided.length}</span></div>
        <div style={mn.stat}><span style={mn.statLabel}>My win rate</span><span style={{ ...mn.statValue, color: mn.winColor(myWin) }}>{myWin}%</span><span style={{ ...mn.statDelta, color: Tmnh.color.text.tertiary }}>{won.length} of {decided.length}</span></div>
      </div>

      <div style={mn.card}>
        <div style={mn.cardH}><span>My docket — {me}</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>{mine.length} motions</span></div>
        <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
          <thead><tr>
            <th style={mn.th}>ID</th>
            <th style={mn.th}>Caption</th>
            <th style={mn.th}>Matter</th>
            <th style={mn.th}>Hearing</th>
            <th style={{ ...mn.th, textAlign: 'right' }}>Pages</th>
            <th style={{ ...mn.th, textAlign: 'right' }}>Cites</th>
            <th style={mn.th}>Status</th>
            <th style={mn.th}>Expected outcome</th>
          </tr></thead>
          <tbody>{mine.map(m => {
            const ss = mn.statusColor(m.status);
            return <tr key={m.id}>
              <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700 }}>{m.id}</td>
              <td style={{ ...mn.td, fontWeight: 600, maxWidth: '240px' }}>{m.captionShort}<div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{m.type}</div></td>
              <td style={{ ...mn.td, color: Tmnh.color.text.secondary, fontSize: '11px' }}>{m.matter}</td>
              <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, fontSize: '11px', color: mn.amber }}>{m.hearingDate || '—'}</td>
              <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono }}>{m.pages || '—'}</td>
              <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700 }}>{m.cites}</td>
              <td style={mn.td}><span style={{ ...mn.tag, background: ss.bg, color: ss.color }}>{m.status}</span></td>
              <td style={{ ...mn.td, fontSize: '10px', color: Tmnh.color.text.secondary, fontStyle: 'italic' }}>{m.expectedOutcome}</td>
            </tr>;
          })}</tbody>
        </table></div>
      </div>
    </div>
  );
}
window.MnQueueMyDocket = MnQueueMyDocket;

// ── QUEUE > By Matter ───────────────────────────────────────────────────────
function MnQueueByMatter({ data }) {
  const mn = window.__mn;
  const groups = useMnHMemo(() => {
    const g = {};
    data.motions.forEach(m => {
      if (!g[m.matter]) g[m.matter] = { matter: m.matter, court: m.court, judge: m.judge, motions: [], active: 0, decided: 0, won: 0 };
      g[m.matter].motions.push(m);
      if (['Granted','Granted in Part','Denied','Moot','Withdrawn'].includes(m.status)) {
        g[m.matter].decided++;
        if (m.status === 'Granted' || m.status === 'Granted in Part') g[m.matter].won++;
      } else {
        g[m.matter].active++;
      }
    });
    return Object.values(g).sort((a,b) => b.motions.length - a.motions.length);
  }, [data]);

  return (
    <div style={mn.cardGrid(420)}>
      {groups.map(g => (
        <div key={g.matter} style={mn.card}>
          <div style={mn.cardH}>
            <div>
              <div style={{ fontSize: '13px', fontWeight: 700, color: Tmnh.color.text.primary }}>{g.matter}</div>
              <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, fontWeight: 500, marginTop: '2px' }}>{g.court} · {g.judge}</div>
            </div>
            <span style={{ ...mn.tag, background: mn.plumBg, color: mn.plum }}>{g.motions.length} motion{g.motions.length === 1 ? '' : 's'}</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(90px, 100%), 1fr))', gap: '8px', padding: '12px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontSize: '18px', fontWeight: 700, color: mn.plum, fontFamily: Tmnh.font.mono }}>{g.active}</div>
              <div style={{ fontSize: '9px', fontWeight: 600, color: Tmnh.color.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Active</div>
            </div>
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontSize: '18px', fontWeight: 700, color: mn.emerald, fontFamily: Tmnh.font.mono }}>{g.won}</div>
              <div style={{ fontSize: '9px', fontWeight: 600, color: Tmnh.color.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Won</div>
            </div>
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontSize: '18px', fontWeight: 700, color: Tmnh.color.text.primary, fontFamily: Tmnh.font.mono }}>{g.decided}</div>
              <div style={{ fontSize: '9px', fontWeight: 600, color: Tmnh.color.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Decided</div>
            </div>
          </div>
          <div>
            {g.motions.slice(0, 6).map(m => {
              const ss = mn.statusColor(m.status);
              return (
                <div key={m.id} style={{ display: 'flex', alignItems: 'center', gap: '10px', padding: '8px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
                  <span style={{ fontFamily: Tmnh.font.mono, fontSize: '11px', color: mn.plum, fontWeight: 700, minWidth: '52px' }}>{m.id}</span>
                  <span style={{ fontSize: '11px', color: Tmnh.color.text.primary, flex: 1, fontWeight: 500 }}>{m.captionShort}</span>
                  <span style={{ ...mn.tag, background: ss.bg, color: ss.color, fontSize: '9px' }}>{m.status}</span>
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}
window.MnQueueByMatter = MnQueueByMatter;

// ── QUEUE > By Type ─────────────────────────────────────────────────────────
function MnQueueByType({ data }) {
  const mn = window.__mn;
  const groups = useMnHMemo(() => {
    const g = {};
    data.motions.forEach(m => {
      const key = m.kind || 'Motion';
      if (!g[key]) g[key] = { kind: key, total: 0, active: 0, won: 0, decided: 0, pages: 0, cites: 0 };
      g[key].total++;
      g[key].pages += (m.pages || 0);
      g[key].cites += (m.cites || 0);
      if (['Granted','Granted in Part','Denied','Moot','Withdrawn'].includes(m.status)) {
        g[key].decided++;
        if (m.status === 'Granted') g[key].won++;
        else if (m.status === 'Granted in Part') g[key].won += 0.5;
      } else g[key].active++;
    });
    return Object.values(g).sort((a,b) => b.total - a.total);
  }, [data]);

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>Motion types — performance by kind</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>{groups.length} categories</span></div>
      <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
        <thead><tr>
          <th style={mn.th}>Kind</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Total</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Active</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Decided</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Avg pages</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Avg cites</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Win rate</th>
          <th style={mn.th}>Distribution</th>
        </tr></thead>
        <tbody>{groups.map(g => {
          const win = g.decided ? Math.round((g.won / g.decided) * 100) : null;
          const avgP = g.total ? Math.round(g.pages / g.total) : 0;
          const avgC = g.total ? Math.round(g.cites / g.total) : 0;
          return <tr key={g.kind}>
            <td style={{ ...mn.td, fontWeight: 700 }}>{g.kind}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, fontWeight: 700 }}>{g.total}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: mn.plum }}>{g.active}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono }}>{g.decided}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: Tmnh.color.text.secondary }}>{avgP || '—'}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: Tmnh.color.text.secondary }}>{avgC}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, fontWeight: 700, color: win == null ? Tmnh.color.text.tertiary : mn.winColor(win) }}>{win == null ? '—' : `${win}%`}</td>
            <td style={{ ...mn.td, minWidth: '180px' }}>
              <div style={{ display: 'flex', height: '6px', borderRadius: '3px', overflow: 'hidden', background: Tmnh.color.bg.secondary }}>
                <div style={{ width: `${(g.active / g.total) * 100}%`, background: mn.plum }} />
                <div style={{ width: `${(g.won / g.total) * 100}%`, background: mn.emerald }} />
                <div style={{ width: `${((g.decided - g.won) / g.total) * 100}%`, background: mn.crimson }} />
              </div>
            </td>
          </tr>;
        })}</tbody>
      </table></div>
    </div>
  );
}
window.MnQueueByType = MnQueueByType;

// ── DRAFTING > Checklists ───────────────────────────────────────────────────
function MnDraftChecklists({ data }) {
  const mn = window.__mn;
  const CHECKS = [
    { id: 'caption',  label: 'Caption & case number correct' },
    { id: 'toc',      label: 'Table of Contents / Authorities' },
    { id: 'cites',    label: 'Citations Shepardized (≤ 30 days)' },
    { id: 'exhibits', label: 'Exhibits indexed & attached' },
    { id: 'length',   label: 'Within page / word limit' },
    { id: 'proof',    label: 'Partner proofread + redline' },
    { id: 'signature',label: 'Signature block & bar admissions' },
    { id: 'cos',      label: 'Certificate of Service' },
    { id: 'ecf',      label: 'ECF filing package ready' },
  ];
  const drafts = data.drafts || [];
  const rand = (id, i) => ((id.charCodeAt(id.length - 1) + i * 7) % 10);
  const status = (id, i) => {
    const r = rand(id, i);
    if (r < 6) return 'done';
    if (r < 8) return 'progress';
    return 'todo';
  };
  const sym = { done: 'ok', progress: '◐', todo: '○' };
  const clr = { done: mn.emerald, progress: mn.amber, todo: Tmnh.color.text.tertiary };

  return (
    <div style={mn.cardGrid(420)}>
      {drafts.map(d => {
        const done = CHECKS.filter((_, i) => status(d.motionId || d.id, i) === 'done').length;
        const pct = Math.round((done / CHECKS.length) * 100);
        return (
          <div key={d.motionId || d.id} style={mn.card}>
            <div style={mn.cardH}>
              <div>
                <div style={{ fontSize: '13px', fontWeight: 700 }}>{d.caption || d.title}</div>
                <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{d.motionId} · {d.author} · {d.lastEdit || '—'}</div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                <div style={{ width: '60px', height: '4px', background: Tmnh.color.bg.secondary, borderRadius: '2px', overflow: 'hidden' }}>
                  <div style={{ width: `${pct}%`, height: '100%', background: pct >= 80 ? mn.emerald : pct >= 50 ? mn.amber : mn.crimson }} />
                </div>
                <span style={{ fontSize: '11px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: pct >= 80 ? mn.emerald : Tmnh.color.text.primary }}>{done}/{CHECKS.length}</span>
              </div>
            </div>
            <div>
              {CHECKS.map((c, i) => {
                const s = status(d.motionId || d.id, i);
                return (
                  <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: '10px', padding: '7px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
                    <span style={{ width: '16px', fontSize: '13px', color: clr[s], fontWeight: 700, textAlign: 'center' }}>{sym[s]}</span>
                    <span style={{ fontSize: '11px', color: s === 'done' ? Tmnh.color.text.tertiary : Tmnh.color.text.primary, textDecoration: s === 'done' ? 'line-through' : 'none', flex: 1 }}>{c.label}</span>
                    {s === 'progress' && <span style={{ ...mn.tag, background: mn.amberBg, color: mn.amber, fontSize: '9px' }}>In progress</span>}
                    {s === 'todo' && <span style={{ ...mn.tag, background: Tmnh.color.bg.secondary, color: Tmnh.color.text.tertiary, fontSize: '9px' }}>Todo</span>}
                  </div>
                );
              })}
            </div>
          </div>
        );
      })}
    </div>
  );
}
window.MnDraftChecklists = MnDraftChecklists;

// ── DRAFTING > Collaborators ────────────────────────────────────────────────
function MnDraftCollaborators({ data }) {
  const mn = window.__mn;
  const drafts = data.drafts || [];
  const roles = ['Author', 'Senior Reviewer', 'Partner Approver', 'Cite-Checker'];
  const reviewers = [
    { name: 'L. Torres',    role: 'Senior Reviewer' },
    { name: 'J. Park',      role: 'Cite-Checker'    },
    { name: 'R. Vasquez',   role: 'Senior Reviewer' },
    { name: 'A. Petrov',    role: 'Cite-Checker'    },
    { name: 'S. Chen',      role: 'Partner Approver'},
    { name: 'M. Kirkland',  role: 'Partner Approver'},
  ];
  const stateFor = (id, role) => {
    const r = (id.charCodeAt(id.length - 1) + role.length) % 10;
    if (r < 4) return { s: 'Approved',  bg: mn.emeraldBg, c: mn.emerald };
    if (r < 7) return { s: 'In review', bg: mn.amberBg,   c: mn.amber   };
    if (r < 9) return { s: 'Requested', bg: mn.plumBg,    c: mn.plum    };
    return      { s: 'Blocked',   bg: mn.crimsonBg, c: mn.crimson };
  };

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>Draft collaborators — review pipeline</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>{drafts.length} active drafts</span></div>
      <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
        <thead><tr>
          <th style={mn.th}>Draft</th>
          <th style={mn.th}>Author</th>
          {roles.slice(1).map(r => <th key={r} style={mn.th}>{r}</th>)}
          <th style={mn.th}>Last activity</th>
        </tr></thead>
        <tbody>{drafts.map(d => {
          const id = d.motionId || d.id;
          return <tr key={id}>
            <td style={{ ...mn.td, maxWidth: '260px' }}>
              <div style={{ fontWeight: 700 }}>{d.caption || d.title}</div>
              <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px', fontFamily: Tmnh.font.mono }}>{id}</div>
            </td>
            <td style={{ ...mn.td, fontSize: '11px' }}>{d.author}<div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary }}>Author</div></td>
            {roles.slice(1).map((r, i) => {
              const rv = reviewers.filter(x => x.role === r)[i % 2] || reviewers[i];
              const st = stateFor(id, r);
              return <td key={r} style={{ ...mn.td, fontSize: '11px' }}>
                <div style={{ fontWeight: 500 }}>{rv.name}</div>
                <span style={{ ...mn.tag, background: st.bg, color: st.c, marginTop: '3px', fontSize: '9px' }}>{st.s}</span>
              </td>;
            })}
            <td style={{ ...mn.td, fontSize: '10px', color: Tmnh.color.text.tertiary, fontFamily: Tmnh.font.mono }}>{d.lastEdit || '2026-04-20'}</td>
          </tr>;
        })}</tbody>
      </table></div>
    </div>
  );
}
window.MnDraftCollaborators = MnDraftCollaborators;

// ── BRIEF BANK > By Category ────────────────────────────────────────────────
function MnBbByCategory({ data }) {
  const mn = window.__mn;
  const parseWin = (s) => {
    const mt = /(\d+)\s+of\s+(\d+)/.exec(s || '');
    if (!mt) return { w: 0, t: 0 };
    return { w: +mt[1], t: +mt[2] };
  };
  const groups = useMnHMemo(() => {
    const g = {};
    data.briefBank.forEach(b => {
      if (!g[b.category]) g[b.category] = { category: b.category, briefs: [], w: 0, t: 0, pages: 0, cites: 0 };
      const p = parseWin(b.winRate);
      g[b.category].briefs.push(b);
      g[b.category].w += p.w; g[b.category].t += p.t;
      g[b.category].pages += b.pages; g[b.category].cites += b.cites;
    });
    return Object.values(g).sort((a,b) => b.briefs.length - a.briefs.length);
  }, [data]);

  return (
    <div style={mn.cardGrid(420)}>
      {groups.map(g => {
        const winPct = g.t ? Math.round((g.w / g.t) * 100) : 0;
        return (
          <div key={g.category} style={mn.card}>
            <div style={mn.cardH}>
              <div>
                <div style={{ fontSize: '13px', fontWeight: 700 }}>{g.category}</div>
                <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{g.briefs.length} brief{g.briefs.length === 1 ? '' : 's'} · {g.w}/{g.t} prior wins</div>
              </div>
              <span style={{ ...mn.tag, background: mn.winColor(winPct) + '22', color: mn.winColor(winPct), fontWeight: 700 }}>{winPct}%</span>
            </div>
            <div>
              {g.briefs.map(b => (
                <div key={b.id} style={{ display: 'flex', alignItems: 'center', gap: '10px', padding: '8px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
                  <span style={{ fontFamily: Tmnh.font.mono, fontSize: '10px', color: mn.plum, fontWeight: 700, minWidth: '48px' }}>{b.id}</span>
                  <div style={{ flex: 1, fontSize: '11px' }}>
                    <div style={{ fontWeight: 600 }}>{b.title}</div>
                    <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '1px' }}>{b.author} · {b.pages} pg · {b.cites} cites</div>
                  </div>
                  <span style={{ fontSize: '10px', color: Tmnh.color.text.secondary, fontStyle: 'italic' }}>{b.winRate}</span>
                </div>
              ))}
            </div>
          </div>
        );
      })}
    </div>
  );
}
window.MnBbByCategory = MnBbByCategory;

// ── BRIEF BANK > High-Win ───────────────────────────────────────────────────
function MnBbHighWin({ data }) {
  const mn = window.__mn;
  const parseWin = (s) => {
    const mt = /(\d+)\s+of\s+(\d+)/.exec(s || '');
    if (!mt) return { w: 0, t: 1, pct: 0 };
    return { w: +mt[1], t: +mt[2], pct: +mt[2] ? (+mt[1] / +mt[2]) * 100 : 0 };
  };
  const ranked = useMnHMemo(() => data.briefBank.map(b => ({ ...b, _win: parseWin(b.winRate) })).sort((a,b) => b._win.pct - a._win.pct || b._win.t - a._win.t), [data]);

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>High win-rate briefs — leaderboard</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>ranked by prior wins</span></div>
      <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
        <thead><tr>
          <th style={{ ...mn.th, width: '40px' }}>#</th>
          <th style={mn.th}>Brief</th>
          <th style={mn.th}>Category</th>
          <th style={mn.th}>Author</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Pages</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Cites</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Wins</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Win rate</th>
          <th style={mn.th}>Rating</th>
        </tr></thead>
        <tbody>{ranked.map((b, i) => {
          const pct = Math.round(b._win.pct);
          const stars = Math.max(1, Math.round(pct / 20));
          return <tr key={b.id}>
            <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700, textAlign: 'center' }}>{i + 1}</td>
            <td style={{ ...mn.td, maxWidth: '280px' }}>
              <div style={{ fontWeight: 600 }}>{b.title}</div>
              <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '1px' }}>{b.id} · {b.type}</div>
            </td>
            <td style={{ ...mn.td, fontSize: '11px', color: Tmnh.color.text.secondary }}>{b.category}</td>
            <td style={{ ...mn.td, fontSize: '11px' }}>{b.author}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono }}>{b.pages}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700 }}>{b.cites}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono }}>{b._win.w}/{b._win.t}</td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, fontWeight: 700, color: mn.winColor(pct) }}>{pct}%</td>
            <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, fontSize: '13px', color: mn.plum, letterSpacing: '1px' }}>{'●'.repeat(stars)}{'○'.repeat(5 - stars)}</td>
          </tr>;
        })}</tbody>
      </table></div>
    </div>
  );
}
window.MnBbHighWin = MnBbHighWin;

// ── BRIEF BANK > Recent ─────────────────────────────────────────────────────
function MnBbRecent({ data }) {
  const mn = window.__mn;
  const recent = useMnHMemo(() => [...data.briefBank].sort((a,b) => (b.lastUpdated || '').localeCompare(a.lastUpdated || '')), [data]);

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>Recently added / updated</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>sorted by last update</span></div>
      <div>{recent.map(b => (
        <div key={b.id} style={{ display: 'grid', gridTemplateColumns: 'minmax(70px, 80px) minmax(200px, 2fr) minmax(120px, 160px) minmax(90px, 120px) minmax(80px, 100px)', gap: 'clamp(8px, 0.8vw, 16px)', alignItems: 'center', padding: '12px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
          <span style={{ fontSize: '11px', fontFamily: Tmnh.font.mono, color: mn.amber, fontWeight: 700 }}>{b.lastUpdated}</span>
          <div>
            <div style={{ fontSize: '12px', fontWeight: 600 }}>{b.title}</div>
            <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{b.id} · {b.type} · {b.pages} pg · {b.cites} cites</div>
            <div style={{ marginTop: '4px', display: 'flex', flexWrap: 'wrap', gap: '4px' }}>
              {(b.tags || []).slice(0, 4).map(t => <span key={t} style={{ ...mn.tag, background: mn.plumBg, color: mn.plum, fontSize: '9px' }}>{t}</span>)}
            </div>
          </div>
          <span style={{ fontSize: '11px', color: Tmnh.color.text.secondary }}>{b.category}</span>
          <span style={{ fontSize: '11px', color: Tmnh.color.text.secondary }}>{b.author}</span>
          <span style={{ fontSize: '11px', color: Tmnh.color.text.secondary, fontStyle: 'italic' }}>{b.winRate}</span>
        </div>
      ))}</div>
    </div>
  );
}
window.MnBbRecent = MnBbRecent;

// ── CITATIONS > Shepardize ──────────────────────────────────────────────────
function MnCitShepardize({ data }) {
  const mn = window.__mn;
  const today = new Date('2026-04-21');
  const cits = useMnHMemo(() => data.citations.map(c => {
    const v = c.lastVerified ? Math.round((today - new Date(c.lastVerified)) / 86400000) : 999;
    let risk = 'ok';
    if (c.treatment === 'caution' || c.flagNote) risk = 'caution';
    if (c.treatment === 'negative' || c.treatment === 'superseded' || c.treatment === 'overruled') risk = 'negative';
    if (v > 30 && risk === 'ok') risk = 'stale';
    return { ...c, daysSinceVerify: v, risk };
  }).sort((a,b) => {
    const rank = { negative: 0, caution: 1, stale: 2, ok: 3 };
    return rank[a.risk] - rank[b.risk];
  }), [data]);

  const counts = cits.reduce((a,c) => { a[c.risk] = (a[c.risk] || 0) + 1; return a; }, {});
  const riskStyle = { negative: { bg: mn.crimsonBg, c: mn.crimson, label: 'Negative' }, caution: { bg: mn.amberBg, c: mn.amber, label: 'Caution' }, stale: { bg: mn.slateBg, c: mn.slate, label: 'Stale (>30d)' }, ok: { bg: mn.emeraldBg, c: mn.emerald, label: 'Clean' } };

  return (
    <div>
      <div style={mn.stripAuto(200)}>
        {['negative','caution','stale','ok'].map(k => (
          <div key={k} style={mn.stat}>
            <span style={mn.statLabel}>{riskStyle[k].label}</span>
            <span style={{ ...mn.statValue, color: riskStyle[k].c }}>{counts[k] || 0}</span>
          </div>
        ))}
      </div>

      <div style={mn.card}>
        <div style={mn.cardH}><span>Citation treatment — triage</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>sorted: negative → caution → stale → clean</span></div>
        <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
          <thead><tr>
            <th style={mn.th}>Risk</th>
            <th style={mn.th}>Short</th>
            <th style={mn.th}>Citation</th>
            <th style={mn.th}>Motions</th>
            <th style={{ ...mn.th, textAlign: 'right' }}>Firm uses</th>
            <th style={{ ...mn.th, textAlign: 'right' }}>Verified</th>
            <th style={mn.th}>Flag</th>
            <th style={{ ...mn.th, textAlign: 'right' }}>Action</th>
          </tr></thead>
          <tbody>{cits.map(c => {
            const rs = riskStyle[c.risk];
            return <tr key={c.id}>
              <td style={mn.td}><span style={{ ...mn.tag, background: rs.bg, color: rs.c }}>{rs.label}</span></td>
              <td style={{ ...mn.td, fontWeight: 700 }}>{c.short}</td>
              <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, fontSize: '10px', color: Tmnh.color.text.secondary }}>{c.cite}</td>
              <td style={{ ...mn.td, fontSize: '10px', fontFamily: Tmnh.font.mono, color: mn.plum }}>{(c.motionIds || []).join(', ') || '—'}</td>
              <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700 }}>{c.firmUsage}</td>
              <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, fontSize: '10px', color: c.daysSinceVerify > 30 ? mn.amber : Tmnh.color.text.tertiary }}>{c.daysSinceVerify}d ago</td>
              <td style={{ ...mn.td, fontSize: '10px', color: Tmnh.color.text.secondary, fontStyle: 'italic', maxWidth: '220px' }}>{c.flagNote || (c.risk === 'stale' ? 'Re-verify on Westlaw' : '—')}</td>
              <td style={{ ...mn.td, textAlign: 'right' }}>
                <button style={{ ...mn.btnGhost, fontSize: '10px' }}>{c.risk === 'ok' ? 'Re-check' : 'Review →'}</button>
              </td>
            </tr>;
          })}</tbody>
        </table></div>
      </div>
    </div>
  );
}
window.MnCitShepardize = MnCitShepardize;

// ── CITATIONS > Firm Core ───────────────────────────────────────────────────
function MnCitFirmCore({ data }) {
  const mn = window.__mn;
  const top = useMnHMemo(() => [...data.citations].sort((a,b) => b.firmUsage - a.firmUsage).slice(0, 20), [data]);
  const max = top[0]?.firmUsage || 1;

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>Firm core citations — most-used authorities</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>top 20 firmwide</span></div>
      <div style={{ padding: '8px 0' }}>{top.map((c, i) => (
        <div key={c.id} style={{ display: 'grid', gridTemplateColumns: 'minmax(36px, 40px) minmax(160px, 220px) minmax(180px, 2fr) minmax(90px, 120px) minmax(52px, 60px)', gap: 'clamp(8px, 0.6vw + 4px, 14px)', alignItems: 'center', padding: '8px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
          <span style={{ fontSize: '13px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: i < 3 ? mn.plum : Tmnh.color.text.tertiary }}>#{i + 1}</span>
          <span style={{ fontSize: '12px', fontWeight: 700 }}>{c.short}</span>
          <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
            <div style={{ flex: 1, height: '8px', background: Tmnh.color.bg.secondary, borderRadius: '4px', overflow: 'hidden' }}>
              <div style={{ width: `${(c.firmUsage / max) * 100}%`, height: '100%', background: mn.plum, borderRadius: '4px' }} />
            </div>
            <span style={{ fontSize: '10px', fontFamily: Tmnh.font.mono, color: Tmnh.color.text.tertiary }}>{c.cite}</span>
          </div>
          <span style={{ ...mn.tag, background: c.treatment === 'positive' ? mn.emeraldBg : c.treatment === 'caution' ? mn.amberBg : mn.crimsonBg, color: c.treatment === 'positive' ? mn.emerald : c.treatment === 'caution' ? mn.amber : mn.crimson, textTransform: 'capitalize' }}>{c.treatment}</span>
          <span style={{ fontSize: '14px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: mn.plum, textAlign: 'right' }}>{c.firmUsage}</span>
        </div>
      ))}</div>
    </div>
  );
}
window.MnCitFirmCore = MnCitFirmCore;

// ── CITATIONS > Conflicts ───────────────────────────────────────────────────
function MnCitConflicts({ data }) {
  const mn = window.__mn;
  const flagged = data.citations.filter(c => c.treatment !== 'positive' || c.flagNote);

  return (
    <div>
      <div style={{ padding: '12px 16px', background: mn.crimsonBg, border: `1px solid ${mn.crimson}30`, borderRadius: '8px', marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
        <span style={{ fontSize: '18px', color: mn.crimson }}><Icons.Alert size={11}/></span>
        <div>
          <div style={{ fontSize: '13px', fontWeight: 700, color: mn.crimson }}>{flagged.length} citation{flagged.length === 1 ? '' : 's'} flagged for review</div>
          <div style={{ fontSize: '11px', color: Tmnh.color.text.secondary, marginTop: '2px' }}>Negative treatment, abrogation, or partner-supplied caution notes — resolve before filing.</div>
        </div>
      </div>

      <div style={{ display: 'grid', gap: '10px' }}>
        {flagged.map(c => (
          <div key={c.id} style={{ ...mn.card, marginBottom: 0, borderLeft: `3px solid ${c.treatment === 'caution' ? mn.amber : mn.crimson}` }}>
            <div style={{ padding: '12px 16px', display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(260px, 100%), 1fr))', gap: '16px', alignItems: 'start' }}>
              <div>
                <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '4px' }}>
                  <span style={{ fontSize: '13px', fontWeight: 700 }}>{c.short}</span>
                  <span style={{ ...mn.tag, background: c.treatment === 'caution' ? mn.amberBg : mn.crimsonBg, color: c.treatment === 'caution' ? mn.amber : mn.crimson, textTransform: 'capitalize' }}>{c.treatment}</span>
                </div>
                <div style={{ fontSize: '11px', color: Tmnh.color.text.secondary, fontFamily: Tmnh.font.mono, marginBottom: '8px' }}>{c.cite}</div>
                {c.flagNote && (
                  <div style={{ fontSize: '11px', color: Tmnh.color.text.primary, padding: '8px 10px', background: Tmnh.color.bg.secondary, borderRadius: '4px', borderLeft: `2px solid ${mn.amber}` }}>
                    <strong style={{ color: mn.amber, marginRight: '6px' }}>Flag:</strong>{c.flagNote}
                  </div>
                )}
                <div style={{ display: 'flex', gap: '6px', marginTop: '8px' }}>
                  <button style={mn.btnSecondary}>Open in Westlaw</button>
                  <button style={mn.btnGhost}>Find replacement →</button>
                  <button style={mn.btnGhost}>Mark resolved</button>
                </div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>In motions</div>
                <div style={{ fontSize: '11px', fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700, marginTop: '2px' }}>{(c.motionIds || []).join(', ') || '—'}</div>
                <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', marginTop: '10px' }}>Firm-wide uses</div>
                <div style={{ fontSize: '16px', fontFamily: Tmnh.font.mono, color: mn.plum, fontWeight: 700, marginTop: '2px' }}>{c.firmUsage}</div>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
window.MnCitConflicts = MnCitConflicts;

// ── CALENDAR > Due Soon ─────────────────────────────────────────────────────
function MnCalDueSoon({ data }) {
  const mn = window.__mn;
  const today = new Date('2026-04-21');
  const windowed = useMnHMemo(() => (data.calendar || []).map(e => ({ ...e, _days: Math.round((new Date(e.date) - today) / 86400000) })).filter(e => e._days >= 0 && e._days <= 30).sort((a,b) => a._days - b._days), [data]);
  const buckets = { '≤ 7 days': [], '8–14 days': [], '15–30 days': [] };
  windowed.forEach(e => {
    if (e._days <= 7) buckets['≤ 7 days'].push(e);
    else if (e._days <= 14) buckets['8–14 days'].push(e);
    else buckets['15–30 days'].push(e);
  });
  const bucketColor = { '≤ 7 days': mn.crimson, '8–14 days': mn.amber, '15–30 days': mn.plum };

  return (
    <div style={{ ...mn.cardGrid(280), gap: 'clamp(8px, 0.6vw + 6px, 14px)' }}>
      {Object.entries(buckets).map(([label, events]) => (
        <div key={label} style={mn.card}>
          <div style={{ ...mn.cardH, borderLeft: `3px solid ${bucketColor[label]}` }}>
            <span style={{ color: bucketColor[label], fontWeight: 700 }}>{label}</span>
            <span style={{ fontSize: '14px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: bucketColor[label] }}>{events.length}</span>
          </div>
          <div>{events.length === 0 ? (
            <div role="status" style={{ padding: '24px 16px', textAlign: 'center', fontSize: '11px', color: Tmnh.color.text.tertiary, fontStyle: 'italic' }}>No events in window</div>
          ) : events.map(e => (
            <div key={e.motionId + e.date} style={{ padding: '10px 16px', borderBottom: `1px solid ${Tmnh.color.border.light}` }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '3px' }}>
                <span style={{ fontSize: '10px', fontFamily: Tmnh.font.mono, color: bucketColor[label], fontWeight: 700 }}>{e.date}</span>
                <span style={{ ...mn.tag, background: Tmnh.color.bg.secondary, color: Tmnh.color.text.secondary, fontSize: '9px' }}>{e.type}</span>
                {e.urgency === 'critical' && <span style={{ ...mn.tag, background: mn.crimsonBg, color: mn.crimson, fontSize: '9px' }}>critical</span>}
              </div>
              <div style={{ fontSize: '11px', fontWeight: 600 }}>{e.caption}</div>
              <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{e.matter} · <span style={{ fontFamily: Tmnh.font.mono, color: mn.plum }}>{e.motionId}</span></div>
            </div>
          ))}</div>
        </div>
      ))}
    </div>
  );
}
window.MnCalDueSoon = MnCalDueSoon;

// ── CALENDAR > Hearings ─────────────────────────────────────────────────────
function MnCalHearings({ data }) {
  const mn = window.__mn;
  const hearings = useMnHMemo(() => (data.calendar || []).filter(e => ['Hearing','Evidentiary','Oral Arg','Argument'].includes(e.type)).sort((a,b) => a.date.localeCompare(b.date)), [data]);

  return (
    <div style={mn.card}>
      <div style={mn.cardH}><span>Hearings & oral arguments — chronological</span><span style={{ fontSize: '11px', color: Tmnh.color.text.tertiary, fontWeight: 500 }}>{hearings.length} scheduled</span></div>
      <div style={mn.tableWrap}><table style={{ ...mn.tableFixed, minWidth: '900px' }}>
        <thead><tr>
          <th style={mn.th}>Date</th>
          <th style={mn.th}>Type</th>
          <th style={mn.th}>Motion</th>
          <th style={mn.th}>Matter</th>
          <th style={mn.th}>Urgency</th>
          <th style={{ ...mn.th, textAlign: 'right' }}>Days out</th>
        </tr></thead>
        <tbody>{hearings.map(e => {
          const days = Math.round((new Date(e.date) - new Date('2026-04-21')) / 86400000);
          return <tr key={e.motionId + e.date}>
            <td style={{ ...mn.td, fontFamily: Tmnh.font.mono, fontWeight: 700, color: mn.plum }}>{e.date}</td>
            <td style={mn.td}><span style={{ ...mn.tag, background: Tmnh.color.bg.secondary, color: Tmnh.color.text.secondary }}>{e.type}</span></td>
            <td style={{ ...mn.td, maxWidth: '260px' }}>
              <div style={{ fontWeight: 600 }}>{e.caption}</div>
              <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px', fontFamily: Tmnh.font.mono }}>{e.motionId}</div>
            </td>
            <td style={{ ...mn.td, fontSize: '11px', color: Tmnh.color.text.secondary }}>{e.matter}</td>
            <td style={mn.td}>
              {e.urgency === 'critical' && <span style={{ ...mn.tag, background: mn.crimsonBg, color: mn.crimson }}>Critical</span>}
              {e.urgency === 'high'     && <span style={{ ...mn.tag, background: mn.amberBg, color: mn.amber }}>High</span>}
              {(!e.urgency || e.urgency === 'normal') && <span style={{ ...mn.tag, background: Tmnh.color.bg.secondary, color: Tmnh.color.text.tertiary }}>Normal</span>}
            </td>
            <td style={{ ...mn.td, textAlign: 'right', fontFamily: Tmnh.font.mono, fontWeight: 700, color: days <= 7 ? mn.crimson : days <= 14 ? mn.amber : Tmnh.color.text.primary }}>{days < 0 ? 'past' : `+${days}d`}</td>
          </tr>;
        })}</tbody>
      </table></div>
    </div>
  );
}
window.MnCalHearings = MnCalHearings;

// ── JUDGES > Tendency Analysis ──────────────────────────────────────────────
function MnJdgTendency({ data }) {
  const mn = window.__mn;
  const ranked = useMnHMemo(() => [...data.judges].sort((a,b) => b.grantRate - a.grantRate), [data]);

  const barRow = (label, pct, color) => (
    <div style={{ display: 'grid', gridTemplateColumns: 'minmax(80px, 110px) minmax(60px, 1fr) 40px', gap: '8px', alignItems: 'center', marginBottom: '4px' }}>
      <span style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' }}>{label}</span>
      <div style={{ height: '6px', background: Tmnh.color.bg.secondary, borderRadius: '3px', overflow: 'hidden' }}>
        <div style={{ width: `${pct}%`, height: '100%', background: color, borderRadius: '3px' }} />
      </div>
      <span style={{ fontSize: '10px', fontFamily: Tmnh.font.mono, fontWeight: 700, color, textAlign: 'right' }}>{pct}%</span>
    </div>
  );

  return (
    <div style={mn.cardGrid(420)}>
      {ranked.map(j => {
        const tc = mn.tendencyColor(j.grantRate);
        return (
          <div key={j.id} style={mn.card}>
            <div style={mn.cardH}>
              <div>
                <div style={{ fontSize: '13px', fontWeight: 700 }}>{j.name}</div>
                <div style={{ fontSize: '10px', color: Tmnh.color.text.tertiary, marginTop: '2px' }}>{j.court} · {j.tenure} · {j.opinionsAnalyzed} opinions analyzed</div>
              </div>
              <span style={{ ...mn.tag, background: tc + '22', color: tc, fontWeight: 700 }}>{j.tendency}</span>
            </div>
            <div style={{ padding: '12px 16px' }}>
              {barRow('Overall',  j.grantRate,             mn.tendencyColor(j.grantRate))}
              {barRow('MSJ',      j.msjGrantRate,          mn.tendencyColor(j.msjGrantRate))}
              {barRow('Daubert',  j.daubertGrantRate,      mn.tendencyColor(j.daubertGrantRate))}
              {barRow('Discovery',j.discoveryMotionGrant,  mn.tendencyColor(j.discoveryMotionGrant))}
              <div style={{ display: 'flex', gap: '12px', marginTop: '12px', paddingTop: '10px', borderTop: `1px solid ${Tmnh.color.border.light}` }}>
                <div><div style={{ fontSize: '9px', color: Tmnh.color.text.tertiary, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Avg days to ruling</div><div style={{ fontSize: '14px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: Tmnh.color.text.primary }}>{j.avgDaysToRuling}</div></div>
                <div><div style={{ fontSize: '9px', color: Tmnh.color.text.tertiary, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Our win rate</div><div style={{ fontSize: '14px', fontFamily: Tmnh.font.mono, fontWeight: 700, color: mn.winColor(j.firmWinRate) }}>{j.firmWinRate}%</div></div>
              </div>
              {j.notableNotes && <div style={{ marginTop: '10px', fontSize: '11px', color: Tmnh.color.text.secondary, fontStyle: 'italic', padding: '8px 10px', background: Tmnh.color.bg.secondary, borderRadius: '4px' }}>{j.notableNotes}</div>}
            </div>
          </div>
        );
      })}
    </div>
  );
}
window.MnJdgTendency = MnJdgTendency;

// ═══════════════════════════════════════════════════════════════════════════
// HUB WRAPPERS
// ═══════════════════════════════════════════════════════════════════════════

function MnQueueHub({ data }) {
  const [sub, setSub] = useMnH('all');
  const views = [
    { id: 'all',      label: 'All motions',  badge: data.motions.length },
    { id: 'mine',     label: 'My docket' },
    { id: 'bymatter', label: 'By matter' },
    { id: 'bytype',   label: 'By type' },
    { id: 'rulings',  label: 'Rulings',      badge: (data.rulings || []).length },
    { id: 'activity', label: 'Activity',     badge: (data.activity || []).length },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'all'      && <MotionsQueue data={data} />}
      {sub === 'mine'     && <MnQueueMyDocket data={data} />}
      {sub === 'bymatter' && <MnQueueByMatter data={data} />}
      {sub === 'bytype'   && <MnQueueByType data={data} />}
      {sub === 'rulings'  && <MotionsRulings data={data} />}
      {sub === 'activity' && <MotionsActivity data={data} />}
    </div>
  );
}
window.MnQueueHub = MnQueueHub;

function MnDraftingHub({ data }) {
  const [sub, setSub] = useMnH('workspaces');
  const views = [
    { id: 'workspaces',    label: 'Workspaces',    badge: (data.drafts || []).length },
    { id: 'templates',     label: 'Templates',     badge: (data.templates || []).length },
    { id: 'checklists',    label: 'Checklists' },
    { id: 'collaborators', label: 'Collaborators' },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'workspaces'    && <MotionsDrafting data={data} />}
      {sub === 'templates'     && <MotionsTemplates data={data} />}
      {sub === 'checklists'    && <MnDraftChecklists data={data} />}
      {sub === 'collaborators' && <MnDraftCollaborators data={data} />}
    </div>
  );
}
window.MnDraftingHub = MnDraftingHub;

function MnBriefBankHub({ data }) {
  const [sub, setSub] = useMnH('library');
  const views = [
    { id: 'library',    label: 'Library',     badge: data.briefBank.length },
    { id: 'category',   label: 'By category' },
    { id: 'highwin',    label: 'High win-rate' },
    { id: 'recent',     label: 'Recent' },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'library'  && <MotionsBriefBank data={data} />}
      {sub === 'category' && <MnBbByCategory data={data} />}
      {sub === 'highwin'  && <MnBbHighWin data={data} />}
      {sub === 'recent'   && <MnBbRecent data={data} />}
    </div>
  );
}
window.MnBriefBankHub = MnBriefBankHub;

function MnCitationsHub({ data }) {
  const [sub, setSub] = useMnH('tracker');
  const flagged = data.citations.filter(c => c.treatment !== 'positive' || c.flagNote).length;
  const views = [
    { id: 'tracker',     label: 'Tracker',     badge: data.citations.length },
    { id: 'shepardize',  label: 'Shepardize' },
    { id: 'firmcore',    label: 'Firm core' },
    { id: 'conflicts',   label: 'Conflicts',   badge: flagged },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'tracker'    && <MotionsCitations data={data} />}
      {sub === 'shepardize' && <MnCitShepardize data={data} />}
      {sub === 'firmcore'   && <MnCitFirmCore data={data} />}
      {sub === 'conflicts'  && <MnCitConflicts data={data} />}
    </div>
  );
}
window.MnCitationsHub = MnCitationsHub;

function MnCalendarHub({ data }) {
  const [sub, setSub] = useMnH('timeline');
  const views = [
    { id: 'timeline',  label: 'Timeline',        badge: (data.calendar || []).length },
    { id: 'duesoon',   label: 'Due soon' },
    { id: 'hearings',  label: 'Hearings' },
    { id: 'oralarg',   label: 'Oral arguments',  badge: (data.oralArgs || []).length },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'timeline' && <MotionsCalendar data={data} />}
      {sub === 'duesoon'  && <MnCalDueSoon data={data} />}
      {sub === 'hearings' && <MnCalHearings data={data} />}
      {sub === 'oralarg'  && <MotionsOralArgs data={data} />}
    </div>
  );
}
window.MnCalendarHub = MnCalendarHub;

function MnJudgesHub({ data }) {
  const [sub, setSub] = useMnH('directory');
  const views = [
    { id: 'directory',  label: 'Directory',         badge: data.judges.length },
    { id: 'tendency',   label: 'Tendency' },
    { id: 'opposing',   label: 'Opposing counsel',  badge: (data.opposingCounsel || []).length },
    { id: 'analytics',  label: 'Win-rate analytics' },
  ];
  return (
    <div>
      <MnSubNav views={views} active={sub} onChange={setSub} />
      {sub === 'directory' && <MotionsJudges data={data} />}
      {sub === 'tendency'  && <MnJdgTendency data={data} />}
      {sub === 'opposing'  && <MotionsOpposingCounsel data={data} />}
      {sub === 'analytics' && <MotionsAnalytics data={data} />}
    </div>
  );
}
window.MnJudgesHub = MnJudgesHub;
