// Reusable visuals for sub-pages — UI mocks + animated diagrams + dashboards
// Each visual is themed to the page it appears on.

// CRM kanban / pipeline mock
function CRMPipelineVisual() {
  const stages = [
    { name: "New leads", count: 142, color: "#7A52FF" },
    { name: "Contacted", count: 86, color: "#24A1DE" },
    { name: "Qualified", count: 41, color: "#F118B2" },
    { name: "Funded", count: 17, color: "#2BD974" },
  ];
  const leads = [
    ["Olivia Reyes", "$2,400", "EUR/USD"],
    ["Marcus Chen", "$8,750", "BTC/USD"],
    ["Aria Patel", "$1,250", "Gold"],
    ["Ben Stoll", "$15K", "Indices"],
  ];
  return (
    <div className="crm-mock card" style={{ padding: 18 }}>
      <div className="crm-mock-head">
        <div className="row" style={{ gap: 8 }}>
          <span className="tag"><span className="dot"></span> 4,287 active leads</span>
        </div>
        <span className="mono" style={{ fontSize: 11, color: "var(--text-mute)" }}>PIPELINE / TODAY</span>
      </div>
      <div className="crm-cols">
        {stages.map((s, i) => (
          <div key={s.name} className="crm-col">
            <div className="crm-col-head">
              <span className="crm-dot" style={{ background: s.color }}/>
              <span>{s.name}</span>
              <span className="crm-count">{s.count}</span>
            </div>
            {leads.slice(i, i + 2).concat(leads.slice(0, Math.max(0, 2 - (leads.length - i)))).slice(0, 2).map((l, j) => (
              <div key={j} className="crm-card" style={{ animationDelay: `${(i + j) * 0.15}s` }}>
                <div className="crm-name">{l[0]}</div>
                <div className="crm-meta">
                  <span>{l[1]}</span>
                  <span className="crm-pip">{l[2]}</span>
                </div>
              </div>
            ))}
          </div>
        ))}
      </div>
      <style>{`
        .crm-mock-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
        .crm-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
        .crm-col { background: var(--surface-2); border-radius: 12px; padding: 10px; border: 1px solid var(--line); min-height: 220px; }
        .crm-col-head { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; color: var(--text); margin-bottom: 10px; }
        .crm-col-head span:nth-child(2) { flex: 1; }
        .crm-dot { width: 7px; height: 7px; border-radius: 999px; }
        .crm-count { color: var(--text-mute); font-weight: 500; }
        .crm-card { background: var(--ink-3); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 6px; animation: crm-in .6s ease both; }
        @keyframes crm-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0);} }
        .crm-name { font-size: 11.5px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
        .crm-meta { display: flex; justify-content: space-between; font-size: 10px; color: var(--text-dim); }
        .crm-pip { color: var(--purple-2); font-weight: 600; }
      `}</style>
    </div>
  );
}

// Client Area screenshot mock
function ClientAreaVisual() {
  return (
    <div className="ca-mock card" style={{ padding: 0, overflow: "hidden" }}>
      <div className="ca-topbar">
        <div className="row" style={{ gap: 8 }}>
          <Logo height={18}/>
        </div>
        <div className="ca-tabs">
          <span className="ca-tab active">Dashboard</span>
          <span className="ca-tab">Accounts</span>
          <span className="ca-tab">Deposits</span>
          <span className="ca-tab">Documents</span>
        </div>
        <div className="ca-avatar">OR</div>
      </div>
      <div className="ca-body">
        <div className="ca-balance">
          <div>
            <div className="ca-bal-label">Total equity</div>
            <div className="ca-bal-v">$ 24,830<span className="ca-bal-cents">.42</span></div>
            <div className="ca-bal-delta">+ $814 today (+3.4%)</div>
          </div>
          <div className="ca-spark">
            <svg viewBox="0 0 200 60" preserveAspectRatio="none" width="100%" height="100%">
              <defs>
                <linearGradient id="caspark" x1="0" x2="0" y1="0" y2="1">
                  <stop offset="0" stopColor="#2BD974" stopOpacity="0.5"/>
                  <stop offset="1" stopColor="#2BD974" stopOpacity="0"/>
                </linearGradient>
              </defs>
              <path d="M0 40 L20 36 L40 38 L60 30 L80 32 L100 22 L120 18 L140 24 L160 14 L180 10 L200 12 L200 60 L0 60 Z" fill="url(#caspark)"/>
              <path d="M0 40 L20 36 L40 38 L60 30 L80 32 L100 22 L120 18 L140 24 L160 14 L180 10 L200 12" stroke="#2BD974" fill="none" strokeWidth="1.5"/>
            </svg>
          </div>
        </div>
        <div className="ca-grid">
          <div className="ca-cell"><div className="ca-cell-l">Live account #4291</div><div className="ca-cell-v">$ 18,402</div><div className="ca-cell-s">Standard MT5</div></div>
          <div className="ca-cell"><div className="ca-cell-l">Demo #8814</div><div className="ca-cell-v">$ 100,000</div><div className="ca-cell-s">Practice</div></div>
          <div className="ca-cell"><div className="ca-cell-l">Crypto wallet</div><div className="ca-cell-v">$ 6,428</div><div className="ca-cell-s">USDT/BTC</div></div>
        </div>
        <div className="ca-actions">
          <button className="ca-btn primary">Deposit</button>
          <button className="ca-btn">Withdraw</button>
          <button className="ca-btn">Transfer</button>
          <button className="ca-btn">New account</button>
        </div>
      </div>
      <style>{`
        .ca-topbar { display: flex; align-items: center; gap: 14px; padding: 14px 18px; border-bottom: 1px solid var(--line); background: var(--ink-2); }
        .ca-tabs { display: flex; gap: 14px; flex: 1; justify-content: center; }
        .ca-tab { font-size: 12px; color: var(--text-dim); padding-bottom: 4px; border-bottom: 2px solid transparent; }
        .ca-tab.active { color: var(--text); border-color: var(--purple-2); }
        .ca-avatar { width: 28px; height: 28px; border-radius: 999px; background: linear-gradient(135deg, var(--purple-2), var(--pink)); color: #fff; display: grid; place-items: center; font-size: 10px; font-weight: 700; }
        .ca-body { padding: 22px; }
        .ca-balance { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: end; padding-bottom: 18px; border-bottom: 1px solid var(--line); margin-bottom: 18px; }
        .ca-bal-label { font-size: 11px; color: var(--text-dim); letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 6px; }
        .ca-bal-v { font-family: var(--font-display); font-size: 38px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
        .ca-bal-cents { color: var(--text-dim); font-weight: 500; }
        .ca-bal-delta { font-size: 12px; color: #2BD974; margin-top: 4px; }
        .ca-spark { height: 60px; }
        .ca-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 16px; }
        .ca-cell { padding: 12px; background: var(--surface-2); border-radius: 10px; border: 1px solid var(--line); }
        .ca-cell-l { font-size: 10.5px; color: var(--text-dim); margin-bottom: 6px; }
        .ca-cell-v { font-size: 17px; font-weight: 600; color: var(--text); letter-spacing: -0.01em; }
        .ca-cell-s { font-size: 10px; color: var(--text-mute); margin-top: 2px; }
        .ca-actions { display: flex; gap: 8px; flex-wrap: wrap; }
        .ca-btn { font-size: 12.5px; padding: 9px 14px; border-radius: 8px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text); }
        .ca-btn.primary { background: linear-gradient(180deg, var(--purple-2), var(--purple)); border-color: transparent; color: #fff; }
      `}</style>
    </div>
  );
}

// Payments — methods + recovery flow
function PaymentsVisual() {
  const methods = [
    { n: "Cards", v: "$4.2M", c: "#7A52FF" },
    { n: "Crypto", v: "$2.8M", c: "#FFB000" },
    { n: "Bank", v: "$1.6M", c: "#24A1DE" },
    { n: "APMs", v: "$870K", c: "#F118B2" },
  ];
  return (
    <div className="card" style={{ padding: 22 }}>
      <div className="row between" style={{ marginBottom: 16 }}>
        <span className="tag"><span className="dot"/> $9.4M last 30d</span>
        <span className="mono" style={{ fontSize: 11, color: "var(--text-mute)" }}>PAYMENTS / VOLUME</span>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 14 }}>
        {methods.map((m) => (
          <div key={m.n} style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 12, padding: "12px 14px" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
              <span style={{ width: 8, height: 8, borderRadius: 999, background: m.c }}/>
              <span style={{ fontSize: 12, fontWeight: 600 }}>{m.n}</span>
            </div>
            <div style={{ fontSize: 20, fontWeight: 700, letterSpacing: "-0.01em" }}>{m.v}</div>
            <div style={{ height: 4, background: "var(--ink-3)", borderRadius: 999, marginTop: 8, overflow: "hidden" }}>
              <div style={{ height: "100%", background: m.c, width: m.n === "Cards" ? "78%" : m.n === "Crypto" ? "55%" : m.n === "Bank" ? "32%" : "18%" }}/>
            </div>
          </div>
        ))}
      </div>
      <div style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 12, padding: "12px 14px" }}>
        <div className="row between" style={{ marginBottom: 8 }}>
          <span style={{ fontSize: 11.5, fontWeight: 600 }}>Decline recovery</span>
          <span className="mono" style={{ fontSize: 10.5, color: "var(--green)" }}>+ 23% recovered</span>
        </div>
        <div style={{ display: "flex", gap: 6, alignItems: "center", fontSize: 10.5, color: "var(--text-dim)" }}>
          <span style={{ background: "rgba(255,122,69,0.18)", color: "#FF7A45", padding: "3px 7px", borderRadius: 6 }}>Decline</span>
          <span>→</span>
          <span style={{ background: "rgba(122,82,255,0.18)", color: "#7A52FF", padding: "3px 7px", borderRadius: 6 }}>Smart retry</span>
          <span>→</span>
          <span style={{ background: "rgba(43,217,116,0.18)", color: "#2BD974", padding: "3px 7px", borderRadius: 6 }}>Captured</span>
        </div>
      </div>
    </div>
  );
}

// KYC pipeline
function KYCVisual() {
  const steps = [
    { l: "Submitted", v: "1,284", c: "#7A52FF" },
    { l: "Auto-verified", v: "1,019", c: "#2BD974" },
    { l: "Manual review", v: "211", c: "#FFB000" },
    { l: "Rejected", v: "54", c: "#FF7A45" },
  ];
  return (
    <div className="card" style={{ padding: 22 }}>
      <div className="row between" style={{ marginBottom: 14 }}>
        <span className="tag"><span className="dot"/> KYC pipeline</span>
        <span className="mono" style={{ fontSize: 11, color: "var(--text-mute)" }}>LAST 7 DAYS</span>
      </div>
      <div style={{ display: "grid", gap: 6 }}>
        {steps.map((s) => (
          <div key={s.l} style={{ display: "grid", gridTemplateColumns: "120px 1fr 60px", gap: 10, alignItems: "center" }}>
            <span style={{ fontSize: 12, color: "var(--text-dim)" }}>{s.l}</span>
            <div style={{ height: 22, background: "var(--ink-3)", borderRadius: 6, overflow: "hidden" }}>
              <div style={{ height: "100%", background: s.c, width: `${(parseInt(s.v.replace(",", "")) / 1284) * 100}%`, opacity: 0.85 }}/>
            </div>
            <span className="mono" style={{ fontSize: 12, fontWeight: 600 }}>{s.v}</span>
          </div>
        ))}
      </div>
      <div style={{ marginTop: 16, display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 8 }}>
        {[
          { l: "Sumsub", s: "Connected", c: "#2BD974" },
          { l: "Onfido", s: "Connected", c: "#2BD974" },
          { l: "Veriff", s: "Optional", c: "#7A52FF" },
        ].map((p) => (
          <div key={p.l} style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, padding: 10, textAlign: "center" }}>
            <div style={{ fontSize: 12, fontWeight: 600 }}>{p.l}</div>
            <div style={{ fontSize: 10.5, color: p.c, marginTop: 4 }}>● {p.s}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// Trading platform / chart visual
function TradingVisual() {
  return (
    <div className="card" style={{ padding: 0, overflow: "hidden" }}>
      <div style={{ display: "flex", padding: "12px 16px", borderBottom: "1px solid var(--line)", gap: 14, alignItems: "center" }}>
        <span className="mono" style={{ fontSize: 13, fontWeight: 700 }}>EUR/USD</span>
        <span style={{ fontSize: 13, color: "#2BD974", fontWeight: 600 }}>1.08642</span>
        <span style={{ fontSize: 11, color: "var(--text-dim)" }}>+0.0023 (+0.21%)</span>
        <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--text-mute)" }}>1H · MT5</span>
      </div>
      <div style={{ padding: 16, height: 240, position: "relative" }}>
        <svg viewBox="0 0 400 200" width="100%" height="100%" preserveAspectRatio="none">
          <defs>
            <linearGradient id="tv-grad" x1="0" x2="0" y1="0" y2="1">
              <stop offset="0" stopColor="var(--purple-2)" stopOpacity="0.3"/>
              <stop offset="1" stopColor="var(--purple-2)" stopOpacity="0"/>
            </linearGradient>
          </defs>
          <g stroke="var(--line)" strokeDasharray="2 4">
            <line x1="0" y1="50" x2="400" y2="50"/>
            <line x1="0" y1="100" x2="400" y2="100"/>
            <line x1="0" y1="150" x2="400" y2="150"/>
          </g>
          {Array.from({ length: 30 }).map((_, i) => {
            const x = 10 + i * 13;
            const high = 30 + Math.sin(i * 0.7) * 25 + Math.random() * 8;
            const low = high + 14 + Math.random() * 12;
            const open = high + Math.random() * (low - high - 4);
            const close = high + Math.random() * (low - high - 4);
            const up = close < open;
            return (
              <g key={i}>
                <line x1={x} y1={high} x2={x} y2={low} stroke={up ? "#2BD974" : "#FF6B6B"} strokeWidth="1"/>
                <rect x={x - 3} y={Math.min(open, close)} width="6" height={Math.abs(close - open) || 1} fill={up ? "#2BD974" : "#FF6B6B"}/>
              </g>
            );
          })}
          <path d="M0 120 Q 50 110, 100 100 T 200 80 T 300 70 T 400 60 L 400 200 L 0 200 Z" fill="url(#tv-grad)" opacity="0.5"/>
        </svg>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", borderTop: "1px solid var(--line)" }}>
        {[
          { l: "Spread", v: "0.6 pip" },
          { l: "Volume", v: "1.2M lots" },
          { l: "Latency", v: "12 ms" },
          { l: "Open trades", v: "3,421" },
        ].map((s) => (
          <div key={s.l} style={{ padding: 12, borderRight: "1px solid var(--line)", textAlign: "center" }}>
            <div style={{ fontSize: 10.5, color: "var(--text-mute)", letterSpacing: "0.06em", textTransform: "uppercase" }}>{s.l}</div>
            <div className="mono" style={{ fontSize: 13, fontWeight: 600, marginTop: 4 }}>{s.v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// Mobile trader phone mock
function MobileTraderVisual() {
  return (
    <div style={{ display: "flex", justifyContent: "center", padding: 20 }}>
      <div className="phone-mock" style={{ width: 280, height: 560, borderRadius: 36, background: "var(--ink)", border: "8px solid #1a1a2e", boxShadow: "0 30px 80px -20px rgba(0,0,0,0.5)", overflow: "hidden", position: "relative" }}>
        <div style={{ height: 28, background: "var(--ink-2)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, color: "var(--text)" }}>9:41</div>
        <div style={{ padding: 16 }}>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 16 }}>
            <div>
              <div style={{ fontSize: 11, color: "var(--text-dim)" }}>Equity</div>
              <div style={{ fontSize: 24, fontWeight: 700, letterSpacing: "-0.02em" }}>$ 24,830</div>
            </div>
            <div style={{ width: 32, height: 32, borderRadius: 999, background: "linear-gradient(135deg, var(--purple-2), var(--pink))" }}/>
          </div>
          <div style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 14, padding: 12, marginBottom: 12 }}>
            <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
              <span style={{ fontSize: 12, fontWeight: 600 }}>EUR/USD</span>
              <span style={{ fontSize: 12, color: "#2BD974" }}>+0.21%</span>
            </div>
            <svg viewBox="0 0 200 50" width="100%" height="40">
              <path d="M0 30 Q 30 25, 60 22 T 120 15 T 200 8" stroke="#2BD974" fill="none" strokeWidth="1.5"/>
            </svg>
            <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
              <button style={{ flex: 1, padding: 8, borderRadius: 8, background: "rgba(43,217,116,0.18)", color: "#2BD974", border: 0, fontSize: 11, fontWeight: 600 }}>Buy 1.0864</button>
              <button style={{ flex: 1, padding: 8, borderRadius: 8, background: "rgba(255,107,107,0.18)", color: "#FF6B6B", border: 0, fontSize: 11, fontWeight: 600 }}>Sell 1.0862</button>
            </div>
          </div>
          {["BTC/USD", "Gold", "AAPL"].map((s, i) => (
            <div key={s} style={{ display: "flex", justifyContent: "space-between", padding: 10, borderBottom: "1px solid var(--line)" }}>
              <span style={{ fontSize: 12, fontWeight: 500 }}>{s}</span>
              <span style={{ fontSize: 12, color: i % 2 ? "#FF6B6B" : "#2BD974" }}>{i % 2 ? "−0.42%" : "+1.18%"}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// BI dashboards visual
function BIDashboardVisual() {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div className="row between" style={{ marginBottom: 12 }}>
        <span className="tag"><span className="dot"/> Live BI</span>
        <span className="mono" style={{ fontSize: 11, color: "var(--text-mute)" }}>OPS / DASHBOARD</span>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8, marginBottom: 12 }}>
        {[
          { l: "FTDs", v: "287", d: "+18%" },
          { l: "Avg deposit", v: "$2.4K", d: "+5%" },
          { l: "Conversion", v: "11.4%", d: "+2.1%" },
          { l: "Retention", v: "68%", d: "+4%" },
        ].map((m) => (
          <div key={m.l} style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, padding: 10 }}>
            <div style={{ fontSize: 10, color: "var(--text-mute)", letterSpacing: "0.06em" }}>{m.l.toUpperCase()}</div>
            <div style={{ fontSize: 18, fontWeight: 700, marginTop: 4, letterSpacing: "-0.01em" }}>{m.v}</div>
            <div style={{ fontSize: 10, color: "#2BD974", marginTop: 2 }}>{m.d}</div>
          </div>
        ))}
      </div>
      <div style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 12, padding: 14 }}>
        <div className="row between" style={{ marginBottom: 8, fontSize: 11 }}>
          <span style={{ fontWeight: 600 }}>Funnel performance</span>
          <span className="mono" style={{ color: "var(--text-mute)" }}>30D</span>
        </div>
        <svg viewBox="0 0 400 110" width="100%" height="110">
          <g>
            {Array.from({ length: 30 }).map((_, i) => (
              <rect key={i} x={i * 13} y={110 - (50 + Math.sin(i * 0.5) * 20 + Math.random() * 18)} width="9" height={50 + Math.sin(i * 0.5) * 20 + Math.random() * 18} fill="var(--purple-2)" opacity={0.4 + (i / 60)} rx="2"/>
            ))}
          </g>
        </svg>
      </div>
    </div>
  );
}

// IB tree visual
function IBTreeVisual() {
  return (
    <div className="card" style={{ padding: 22 }}>
      <div className="row between" style={{ marginBottom: 18 }}>
        <span className="tag"><span className="dot"/> IB network</span>
        <span className="mono" style={{ fontSize: 11, color: "var(--text-mute)" }}>312 PARTNERS · 4 LEVELS</span>
      </div>
      <svg viewBox="0 0 400 220" width="100%" height="220">
        <g>
          {/* Edges */}
          <g stroke="var(--line-2)" fill="none" strokeWidth="1">
            <path d="M200 30 L100 90"/>
            <path d="M200 30 L200 90"/>
            <path d="M200 30 L300 90"/>
            <path d="M100 110 L60 170"/>
            <path d="M100 110 L140 170"/>
            <path d="M200 110 L200 170"/>
            <path d="M300 110 L260 170"/>
            <path d="M300 110 L340 170"/>
          </g>
          {/* Nodes */}
          <g>
            <Node x={200} y={30} label="Master IB" big/>
            <Node x={100} y={100} label="L2 · A"/>
            <Node x={200} y={100} label="L2 · B"/>
            <Node x={300} y={100} label="L2 · C"/>
            <Node x={60} y={180} label="C-127" small/>
            <Node x={140} y={180} label="C-291" small/>
            <Node x={200} y={180} label="C-308" small/>
            <Node x={260} y={180} label="C-412" small/>
            <Node x={340} y={180} label="C-518" small/>
          </g>
        </g>
      </svg>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 8, marginTop: 4 }}>
        {[
          { l: "Commission", v: "$48,210" },
          { l: "Active sub-IBs", v: "127" },
          { l: "Volume routed", v: "$8.2M" },
        ].map((s) => (
          <div key={s.l} style={{ background: "var(--surface-2)", border: "1px solid var(--line)", borderRadius: 10, padding: 10, textAlign: "center" }}>
            <div style={{ fontSize: 10.5, color: "var(--text-mute)" }}>{s.l}</div>
            <div className="mono" style={{ fontSize: 14, fontWeight: 600, marginTop: 4 }}>{s.v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function Node({ x, y, label, big, small }) {
  const r = big ? 18 : small ? 10 : 14;
  return (
    <g>
      <circle cx={x} cy={y} r={r} fill={big ? "var(--purple-2)" : "var(--ink-3)"} stroke={big ? "var(--purple-2)" : "var(--line-2)"} strokeWidth="1.5"/>
      {!small && <text x={x} y={y + r + 12} fontSize="9" fill="var(--text-dim)" textAnchor="middle">{label}</text>}
      {small && <text x={x} y={y + 3} fontSize="7.5" fill="var(--text-dim)" textAnchor="middle">{label}</text>}
    </g>
  );
}

window.CRMPipelineVisual = CRMPipelineVisual;
window.ClientAreaVisual = ClientAreaVisual;
window.PaymentsVisual = PaymentsVisual;
window.KYCVisual = KYCVisual;
window.TradingVisual = TradingVisual;
window.MobileTraderVisual = MobileTraderVisual;
window.BIDashboardVisual = BIDashboardVisual;
window.IBTreeVisual = IBTreeVisual;
