// Malbec Live — Home (Personal Assistant)
// Sidebar shell + tabs + assistant surface. Matches screenshot 4.

const { useState: useStateHome, useEffect: useEffectHome } = React;

// Stable icon renderer — returns raw SVG markup from lucide, immune to
// re-renders clobbering each other (unlike the <i data-lucide> + createIcons
// pattern, which only works on freshly-inserted tags).
function LuIcon({ name, size = 14, color = "currentColor", strokeWidth = 2, style = {} }) {
  const html = React.useMemo(() => {
    if (!window.lucide || !window.lucide.icons) return "";
    const k = name.replace(/(^|-)(\w)/g, (_, __, c) => c.toUpperCase());
    const ico = window.lucide.icons[k] || window.lucide.icons[name];
    if (!ico || !Array.isArray(ico)) return "";
    const children = ico.map(([tag, attrs]) => {
      const a = Object.entries(attrs || {}).map(([k, v]) => `${k}="${String(v).replace(/"/g, '&quot;')}"`).join(" ");
      return `<${tag} ${a} />`;
    }).join("");
    return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="${strokeWidth}" stroke-linecap="round" stroke-linejoin="round">${children}</svg>`;
  }, [name, size, color, strokeWidth]);
  return <span style={{ display: "inline-flex", flexShrink: 0, ...style }} dangerouslySetInnerHTML={{ __html: html }} />;
}
window.LuIcon = LuIcon;

// ─────────────────────────────────────────────────────────────
// Left sidebar
// ─────────────────────────────────────────────────────────────

// Workspace catalog — top-level orgs visible in the switcher
const WORKSPACES = [
  {
    id: "live-nation",
    name: "Live Nation",
    plan: "Parent · Enterprise+",
    swatch: "linear-gradient(135deg, #1E1562 0%, #4A3E9E 60%, #7B6CE6 100%)",
  },
  {
    id: "dale-play",
    name: "Dale Play Live",
    plan: "Productora · Enterprise",
    swatch: "linear-gradient(135deg, #A98BE8 0%, #F39AB8 50%, #F2C56D 100%)",
  },
  {
    id: "productora-1",
    name: "Productora 1",
    plan: "Productora · Enterprise",
    swatch: "linear-gradient(135deg, #6F8FE8 0%, #8FB7F2 50%, #C5DDF6 100%)",
  },
  {
    id: "productora-2",
    name: "Productora 2",
    plan: "Productora · Pro",
    swatch: "linear-gradient(135deg, #F2A26D 0%, #F39A8B 50%, #E8867F 100%)",
  },
];
window.WORKSPACES = WORKSPACES;

function WorkspaceSwitcher({ workspace, setWorkspace }) {
  const [open, setOpen] = useStateHome(false);
  const ref = React.useRef(null);
  useEffectHome(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const ws = WORKSPACES.find((w) => w.id === workspace) || WORKSPACES[0];

  return (
    <div ref={ref} style={{ position: "relative", borderBottom: "1px solid var(--live-border)" }}>
      <button
        onClick={() => setOpen((o) => !o)}
        style={{
          display: "flex",
          alignItems: "center",
          gap: 10,
          width: "100%",
          padding: "14px 14px",
          background: open ? "var(--live-sidebar-hover)" : "transparent",
          border: "none",
          cursor: "pointer",
          textAlign: "left",
          fontFamily: "var(--font-sans)",
          transition: "background 140ms ease-out",
        }}
      >
        <div style={{ width: 28, height: 28, borderRadius: 6, background: ws.swatch, flexShrink: 0 }} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: "var(--live-heading)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {ws.name}
          </div>
          <div style={{ fontSize: 11, color: "var(--live-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {ws.plan}
          </div>
        </div>
        <LuIcon name="chevrons-up-down" size={14} color="var(--live-muted)" />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 4px)", left: 8, right: 8, zIndex: 50,
          background: "var(--live-card)",
          border: "1px solid var(--live-border)",
          borderRadius: 10,
          boxShadow: "0 12px 32px rgba(9,14,25,0.14), 0 2px 6px rgba(9,14,25,0.06)",
          padding: 6,
        }}>
          <div style={{ fontSize: 10.5, fontWeight: 600, color: "var(--live-muted)", textTransform: "uppercase", letterSpacing: "0.06em", padding: "8px 10px 6px" }}>
            Workspaces
          </div>
          {WORKSPACES.map((w) => {
            const active = w.id === workspace;
            return (
              <button
                key={w.id}
                onClick={() => { setWorkspace(w.id); setOpen(false); }}
                style={{
                  display: "flex", alignItems: "center", gap: 10,
                  width: "100%", padding: "8px 10px",
                  background: active ? "var(--live-sidebar-active)" : "transparent",
                  border: "none", borderRadius: 6, cursor: "pointer",
                  textAlign: "left", fontFamily: "var(--font-sans)",
                  transition: "background 140ms ease-out",
                }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--live-sidebar-hover)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}
              >
                <div style={{ width: 24, height: 24, borderRadius: 5, background: w.swatch, flexShrink: 0 }} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 600, color: "var(--live-heading)" }}>{w.name}</div>
                  <div style={{ fontSize: 10.5, color: "var(--live-muted)" }}>{w.plan}</div>
                </div>
                {active && <LuIcon name="check" size={13} color="var(--live-primary)" />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}
window.WorkspaceSwitcher = WorkspaceSwitcher;

function HomeSidebar({ route, setRoute, workspace, setWorkspace }) {
  const [expanded, setExpanded] = useStateHome({ Business: true, Operations: false, Ticketing: false, System: false });

  const toggle = (k) => setExpanded((e) => ({ ...e, [k]: !e[k] }));
  const isLN = workspace === "live-nation";

  const NavItem = ({ icon, label, expandable, open, active, onClick, indent }) => (
    <button
      onClick={onClick}
      style={{
        display: "flex",
        alignItems: "center",
        gap: 10,
        width: "100%",
        padding: indent ? "6px 12px 6px 36px" : "7px 12px",
        background: active ? "var(--live-sidebar-active)" : "transparent",
        border: "none",
        borderRadius: 6,
        cursor: "pointer",
        textAlign: "left",
        fontFamily: "var(--font-sans)",
        fontSize: 13,
        fontWeight: active ? 600 : 500,
        color: active ? "var(--live-heading)" : "var(--live-body)",
        transition: "background 140ms ease-out",
      }}
      onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--live-sidebar-hover)"; }}
      onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}
    >
      {icon && <LuIcon name={icon} size={15} color="var(--live-body)" />}
      <span style={{ flex: 1 }}>{label}</span>
      {expandable && (
        <LuIcon name={open ? "chevron-down" : "chevron-right"} size={13} color="var(--live-muted)" />
      )}
    </button>
  );

  return (
    <aside
      style={{
        width: 228,
        background: "var(--live-sidebar-bg)",
        borderRight: "1px solid var(--live-border)",
        display: "flex",
        flexDirection: "column",
        flexShrink: 0,
        height: "100%",
      }}
    >
      {/* Workspace switcher (dropdown) */}
      <WorkspaceSwitcher workspace={workspace} setWorkspace={setWorkspace} />

      {/* Nav */}
      <nav style={{ flex: 1, padding: "14px 10px", overflow: "auto" }}>
        <div
          style={{
            fontSize: 11,
            fontWeight: 600,
            color: "var(--live-muted)",
            padding: "6px 12px 10px",
          }}
        >
          {isLN ? "Live Nation" : "Platform"}
        </div>

        {isLN ? (
          <>
            <NavItem
              icon="building-2"
              label="Productoras"
              active={route === "ln-productoras"}
              onClick={() => setRoute("ln-productoras")}
            />
            <NavItem
              icon="trending-up"
              label="P&L (aggregated)"
              active={route === "ln-pl" || route === "ln-productora-detail"}
              onClick={() => setRoute("ln-pl")}
            />
            <NavItem
              icon="calendar"
              label="Calendar"
              active={route === "ln-calendar"}
              onClick={() => setRoute("ln-calendar")}
            />
            <NavItem
              icon="ticket"
              label="Ticketing"
              active={route === "ln-ticketing"}
              onClick={() => setRoute("ln-ticketing")}
            />
            <NavItem
              icon="settings-2"
              label="System"
              expandable
              open={expanded.System}
              onClick={() => toggle("System")}
            />
          </>
        ) : (
        <>
        <NavItem
          icon="book-open"
          label="Project Hub"
          active={route === "project-hub" || route === "project-detail"}
          onClick={() => setRoute("project-hub")}
        />

        <NavItem
          icon="folder"
          label="Business"
          expandable
          open={expanded.Business}
          onClick={() => toggle("Business")}
        />
        {expanded.Business && (
          <div style={{ display: "flex", flexDirection: "column" }}>
            <NavItem label="P&L" indent active={route === "pl"} onClick={() => setRoute("pl")} />
            <NavItem label="Payments" indent />
            <NavItem label="Billing" indent />
          </div>
        )}

        <NavItem
          icon="compass"
          label="Operations"
          expandable
          open={expanded.Operations}
          onClick={() => toggle("Operations")}
        />
        {expanded.Operations && (
          <div style={{ display: "flex", flexDirection: "column" }}>
            <NavItem
              label="Shows"
              indent
              active={route === "shows"}
              onClick={() => setRoute("shows")}
            />
            <NavItem label="Venues" indent active={route === "venues"} onClick={() => setRoute("venues")} />
            <NavItem label="Calendar" indent active={route === "calendar"} onClick={() => setRoute("calendar")} />
          </div>
        )}
        <NavItem
          icon="ticket"
          label="Ticketing"
          expandable
          open={expanded.Ticketing}
          active={route === "ticketing"}
          onClick={() => { setRoute("ticketing"); toggle("Ticketing"); }}
        />
        <NavItem
          icon="settings-2"
          label="System"
          expandable
          open={expanded.System}
          onClick={() => toggle("System")}
        />
        </>
        )}
      </nav>

      {/* User card */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 10,
          padding: "12px 14px",
          borderTop: "1px solid var(--live-border)",
        }}
      >
        <div
          style={{
            width: 32,
            height: 32,
            borderRadius: 6,
            flexShrink: 0,
            background: "linear-gradient(135deg, #A98BE8 0%, #F39AB8 50%, #F2C56D 100%)",
          }}
        />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div
            style={{
              fontSize: 12.5,
              fontWeight: 600,
              color: "var(--live-heading)",
              whiteSpace: "nowrap",
              overflow: "hidden",
              textOverflow: "ellipsis",
            }}
          >
            shadcn
          </div>
          <div
            style={{
              fontSize: 11,
              color: "var(--live-muted)",
              whiteSpace: "nowrap",
              overflow: "hidden",
              textOverflow: "ellipsis",
            }}
          >
            m@example.com
          </div>
        </div>
        <LuIcon name="chevrons-up-down" size={13} color="var(--live-muted)" />
      </div>
    </aside>
  );
}

// ─────────────────────────────────────────────────────────────
// Top tabs + brand
// ─────────────────────────────────────────────────────────────

function TopTabs({ tab, setTab }) {
  const tabs = ["Home - Personal Assistant", "Business - P&L"];
  return (
    <div
      style={{
        display: "flex",
        alignItems: "flex-end",
        justifyContent: "space-between",
        padding: "0 28px",
        borderBottom: "1px solid var(--live-border)",
        background: "var(--live-bg)",
        height: 54,
      }}
    >
      <div style={{ display: "flex", alignItems: "flex-end", gap: 4, height: "100%" }}>
        {tabs.map((t) => {
          const active = t === tab;
          return (
            <button
              key={t}
              onClick={() => setTab(t)}
              style={{
                appearance: "none",
                background: active ? "var(--live-card)" : "transparent",
                border: "1px solid",
                borderColor: active ? "var(--live-border)" : "transparent",
                borderBottom: active ? "1px solid var(--live-card)" : "1px solid transparent",
                marginBottom: -1,
                borderTopLeftRadius: 8,
                borderTopRightRadius: 8,
                padding: "10px 18px",
                whiteSpace: "nowrap",
                fontSize: 13,
                fontWeight: active ? 600 : 500,
                color: active ? "var(--live-heading)" : "var(--live-muted)",
                cursor: "pointer",
                fontFamily: "var(--font-sans)",
                transition: "color 140ms ease-out, background 140ms ease-out",
              }}
            >
              {t}
            </button>
          );
        })}
      </div>

      {/* Brand lockup top-right */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 8,
          padding: "0 4px 12px",
        }}
      >
        <Grape size={18} color="var(--live-primary)" />
        <div
          style={{
            fontFamily: "var(--font-sans)",
            fontSize: 16,
            letterSpacing: "-0.07em",
            color: "var(--live-heading)",
          }}
        >
          <span style={{ fontWeight: 500 }}>Malbec</span><span style={{ fontStyle: "italic", fontWeight: 300 }}>Live</span>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Assistant surface
// ─────────────────────────────────────────────────────────────

function Banner({ onDismiss }) {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 12,
        background: "var(--live-banner-bg)",
        border: "1px solid var(--live-border)",
        borderRadius: 8,
        padding: "12px 16px",
        marginBottom: 40,
      }}
    >
      <div
        style={{
          flex: 1,
          fontSize: 13,
          color: "var(--live-body)",
        }}
      >
        Use{" "}
        <kbd
          style={{
            display: "inline-block",
            padding: "1px 6px",
            fontFamily: "var(--font-sans)",
            fontSize: 12,
            fontWeight: 500,
            background: "var(--live-card)",
            border: "1px solid var(--live-border)",
            borderRadius: 4,
            color: "var(--live-heading)",
            margin: "0 2px",
          }}
        >
          ⌘
        </kbd>
        {" + "}
        <kbd
          style={{
            display: "inline-block",
            padding: "1px 6px",
            fontFamily: "var(--font-sans)",
            fontSize: 12,
            fontWeight: 500,
            background: "var(--live-card)",
            border: "1px solid var(--live-border)",
            borderRadius: 4,
            color: "var(--live-heading)",
            margin: "0 2px",
          }}
        >
          K
        </kbd>{" "}
        to access the Quick Actions menu and streamline your work.
      </div>
      <button
        onClick={onDismiss}
        aria-label="Dismiss"
        style={{
          appearance: "none",
          background: "transparent",
          border: "none",
          width: 26,
          height: 26,
          borderRadius: 6,
          cursor: "pointer",
          color: "var(--live-muted)",
          display: "grid",
          placeItems: "center",
        }}
        onMouseEnter={(e) => (e.currentTarget.style.background = "var(--live-row-hover)")}
        onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
      >
        <i data-lucide="x" style={{ width: 14, height: 14 }} />
      </button>
    </div>
  );
}

function AssistantInput({ value, setValue, onSubmit }) {
  const [focus, setFocus] = useStateHome(false);
  return (
    <form
      onSubmit={(e) => { e.preventDefault(); onSubmit(); }}
      style={{
        display: "flex",
        alignItems: "center",
        gap: 10,
        width: 520,
        maxWidth: "100%",
      }}
    >
      <div
        style={{
          flex: 1,
          display: "flex",
          alignItems: "center",
          background: "var(--live-card)",
          border: "1px solid var(--live-border)",
          borderRadius: 8,
          padding: "0 14px",
          height: 40,
          boxShadow: focus ? "0 0 0 3px color-mix(in srgb, var(--live-primary) 22%, transparent)" : "none",
          transition: "box-shadow 160ms ease-out",
        }}
      >
        <input
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          onFocus={() => setFocus(true)}
          onBlur={() => setFocus(false)}
          placeholder="What can I help you with?"
          style={{
            flex: 1,
            border: "none",
            outline: "none",
            background: "transparent",
            fontFamily: "var(--font-sans)",
            fontSize: 13,
            color: "var(--live-heading)",
            height: "100%",
          }}
        />
      </div>
      <button
        type="submit"
        aria-label="Send"
        style={{
          width: 40,
          height: 40,
          background: "var(--live-primary)",
          color: "#fff",
          border: "none",
          borderRadius: 8,
          cursor: "pointer",
          display: "grid",
          placeItems: "center",
          boxShadow: "0 1px 3px rgba(9,14,25,0.08)",
          transition: "background 160ms ease-out",
        }}
        onMouseEnter={(e) => (e.currentTarget.style.background = "var(--live-primary-hover)")}
        onMouseLeave={(e) => (e.currentTarget.style.background = "var(--live-primary)")}
      >
        <i data-lucide="chevron-right" style={{ width: 16, height: 16 }} />
      </button>
    </form>
  );
}

function QuickChip({ label, onClick }) {
  return (
    <button
      onClick={onClick}
      style={{
        appearance: "none",
        background: "var(--live-card)",
        border: "1px solid var(--live-border)",
        borderRadius: 999,
        padding: "7px 14px",
        fontSize: 12.5,
        fontWeight: 500,
        color: "var(--live-body)",
        cursor: "pointer",
        fontFamily: "var(--font-sans)",
        whiteSpace: "nowrap",
        transition: "background 140ms ease-out, border-color 140ms ease-out, color 140ms ease-out",
      }}
      onMouseEnter={(e) => {
        e.currentTarget.style.background = "var(--live-row-hover)";
        e.currentTarget.style.borderColor = "var(--live-border-strong)";
      }}
      onMouseLeave={(e) => {
        e.currentTarget.style.background = "var(--live-card)";
        e.currentTarget.style.borderColor = "var(--live-border)";
      }}
    >
      {label}
    </button>
  );
}

function Column({ title, items }) {
  return (
    <div>
      <div
        style={{
          fontSize: 14,
          fontWeight: 600,
          color: "var(--live-heading)",
          marginBottom: 16,
        }}
      >
        {title}
      </div>
      <ul style={{ margin: 0, padding: 0, listStyle: "none" }}>
        {items.map((label, i) => (
          <li key={i}>
            <a
              href="#"
              onClick={(e) => e.preventDefault()}
              style={{
                display: "flex",
                alignItems: "center",
                gap: 10,
                padding: "9px 0",
                fontSize: 13,
                color: "var(--live-muted)",
                textDecoration: "none",
                transition: "color 140ms ease-out",
              }}
              onMouseEnter={(e) => (e.currentTarget.style.color = "var(--live-heading)")}
              onMouseLeave={(e) => (e.currentTarget.style.color = "var(--live-muted)")}
            >
              <span
                style={{
                  width: 5,
                  height: 5,
                  borderRadius: 999,
                  background: "var(--live-bullet)",
                  flexShrink: 0,
                }}
              />
              {label}
            </a>
          </li>
        ))}
      </ul>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// P&L pane (secondary tab — functional stub)
// ─────────────────────────────────────────────────────────────

// ─────────────────────────────────────────────────────────────
// Business · P&L — aggregated statement for the productora.
// Mirrors the project-level Estado de resultados, rolled up across
// every show in the selected period, with Δ vs prior period and a
// 12-month trend.
// ─────────────────────────────────────────────────────────────

// Numbers in thousands (k) of ARS.
// Single source of truth: every show that closed in the trailing 12 months.
// Monthly aggregates, the trend chart, and Top shows are all derived from
// this list so applying an artist filter rolls through every view.
// Per-month sums of (revenue) and (margin) are tuned so monthly totals stay
// consistent across artist filters.
const PL_SHOWS = [
  // April 2025 — revenue $6.20M · margin $1.69M
  { id: "s-2025-04-1", date: "2025-04-05", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1950, margin:  624 },
  { id: "s-2025-04-2", date: "2025-04-12", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue: 1100, margin:  385 },
  { id: "s-2025-04-3", date: "2025-04-19", artist: "Duki",         venue: "Movistar Arena", revenue: 1850, margin:  555 },
  { id: "s-2025-04-4", date: "2025-04-26", artist: "Cazzu",        venue: "Gran Rex",       revenue: 1300, margin:  126 },

  // May 2025 — revenue $7.10M · margin $2.08M
  { id: "s-2025-05-1", date: "2025-05-03", artist: "Lali",         venue: "Movistar Arena", revenue: 2050, margin:  615 },
  { id: "s-2025-05-2", date: "2025-05-10", artist: "Fito Páez",    venue: "Gran Rex",       revenue:  800, margin:  224 },
  { id: "s-2025-05-3", date: "2025-05-17", artist: "Airbag",       venue: "Movistar Arena", revenue: 1500, margin:  420 },
  { id: "s-2025-05-4", date: "2025-05-24", artist: "Cazzu",        venue: "Teatro Colón",   revenue:  950, margin:  201 },
  { id: "s-2025-05-5", date: "2025-05-31", artist: "Duki",         venue: "Vélez",          revenue: 1800, margin:  620 },

  // June 2025 — revenue $8.40M · margin $2.53M
  { id: "s-2025-06-1", date: "2025-06-07", artist: "Bad Bunny",    venue: "Vélez",          revenue: 2500, margin:  775 },
  { id: "s-2025-06-2", date: "2025-06-14", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1900, margin:  608 },
  { id: "s-2025-06-3", date: "2025-06-21", artist: "Lali",         venue: "Vélez",          revenue: 1850, margin:  555 },
  { id: "s-2025-06-4", date: "2025-06-28", artist: "Rels B",       venue: "Movistar Arena", revenue: 1400, margin:  448 },
  { id: "s-2025-06-5", date: "2025-06-15", artist: "Cazzu",        venue: "Teatro Colón",   revenue:  500, margin:  104 },
  { id: "s-2025-06-6", date: "2025-06-22", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue:  250, margin:   40 },

  // July 2025 — revenue $6.90M · margin $1.98M
  { id: "s-2025-07-1", date: "2025-07-05", artist: "Duki",         venue: "Movistar Arena", revenue: 1800, margin:  540 },
  { id: "s-2025-07-2", date: "2025-07-12", artist: "Airbag",       venue: "Movistar Arena", revenue: 1300, margin:  364 },
  { id: "s-2025-07-3", date: "2025-07-19", artist: "Lali",         venue: "Movistar Arena", revenue: 1950, margin:  585 },
  { id: "s-2025-07-4", date: "2025-07-26", artist: "Cazzu",        venue: "Gran Rex",       revenue:  850, margin:  179 },
  { id: "s-2025-07-5", date: "2025-07-30", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1000, margin:  312 },

  // August 2025 — revenue $5.80M · margin $1.53M
  { id: "s-2025-08-1", date: "2025-08-09", artist: "Fito Páez",    venue: "Movistar Arena", revenue: 1400, margin:  390 },
  { id: "s-2025-08-2", date: "2025-08-16", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue: 1100, margin:  385 },
  { id: "s-2025-08-3", date: "2025-08-23", artist: "Cazzu",        venue: "Teatro Colón",   revenue: 1200, margin:  255 },
  { id: "s-2025-08-4", date: "2025-08-30", artist: "Duki",         venue: "Movistar Arena", revenue: 2100, margin:  500 },

  // September 2025 — revenue $7.70M · margin $2.29M
  { id: "s-2025-09-1", date: "2025-09-06", artist: "Lali",         venue: "Vélez",          revenue: 2000, margin:  600 },
  { id: "s-2025-09-2", date: "2025-09-13", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1850, margin:  592 },
  { id: "s-2025-09-3", date: "2025-09-20", artist: "Cazzu",        venue: "Teatro Colón",   revenue:  650, margin:  140 },
  { id: "s-2025-09-4", date: "2025-09-27", artist: "Rels B",       venue: "Movistar Arena", revenue: 1550, margin:  496 },
  { id: "s-2025-09-5", date: "2025-09-14", artist: "Airbag",       venue: "Movistar Arena", revenue: 1050, margin:  294 },
  { id: "s-2025-09-6", date: "2025-09-21", artist: "Nicki Nicole", venue: "Gran Rex",       revenue:  600, margin:  168 },

  // October 2025 — revenue $9.20M · margin $2.84M
  { id: "s-2025-10-1", date: "2025-10-04", artist: "Bad Bunny",    venue: "Vélez",          revenue: 2800, margin:  868 },
  { id: "s-2025-10-2", date: "2025-10-11", artist: "Lali",         venue: "Movistar Arena", revenue: 1850, margin:  555 },
  { id: "s-2025-10-3", date: "2025-10-18", artist: "Bizarrap",     venue: "Vélez",          revenue: 2100, margin:  672 },
  { id: "s-2025-10-4", date: "2025-10-25", artist: "Duki",         venue: "Movistar Arena", revenue: 1300, margin:  390 },
  { id: "s-2025-10-5", date: "2025-10-12", artist: "Cazzu",        venue: "Gran Rex",       revenue:  450, margin:   95 },
  { id: "s-2025-10-6", date: "2025-10-19", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue:  500, margin:  180 },
  { id: "s-2025-10-7", date: "2025-10-26", artist: "Fito Páez",    venue: "Movistar Arena", revenue:  200, margin:   80 },

  // November 2025 — revenue $10.50M · margin $3.13M
  { id: "s-2025-11-1", date: "2025-11-08", artist: "Bad Bunny",    venue: "River",          revenue: 3500, margin: 1050 },
  { id: "s-2025-11-2", date: "2025-11-15", artist: "Lali",         venue: "Vélez",          revenue: 2100, margin:  630 },
  { id: "s-2025-11-3", date: "2025-11-22", artist: "Duki",         venue: "Vélez",          revenue: 1800, margin:  555 },
  { id: "s-2025-11-4", date: "2025-11-29", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1300, margin:  416 },
  { id: "s-2025-11-5", date: "2025-11-09", artist: "Rels B",       venue: "Movistar Arena", revenue: 1100, margin:  352 },
  { id: "s-2025-11-6", date: "2025-11-16", artist: "Cazzu",        venue: "Teatro Colón",   revenue:  300, margin:   58 },
  { id: "s-2025-11-7", date: "2025-11-23", artist: "Nicki Nicole", venue: "Gran Rex",       revenue:  200, margin:   39 },
  { id: "s-2025-11-8", date: "2025-11-30", artist: "Airbag",       venue: "Movistar Arena", revenue:  200, margin:   30 },

  // December 2025 — revenue $12.80M · margin $3.92M
  { id: "s-2025-12-1",  date: "2025-12-06", artist: "Bad Bunny",       venue: "River",          revenue: 4000, margin: 1240 },
  { id: "s-2025-12-2",  date: "2025-12-13", artist: "Lali",            venue: "Vélez",          revenue: 2400, margin:  720 },
  { id: "s-2025-12-3",  date: "2025-12-20", artist: "Bizarrap",        venue: "Vélez",          revenue: 1800, margin:  580 },
  { id: "s-2025-12-4",  date: "2025-12-27", artist: "Duki",            venue: "Movistar Arena", revenue: 1500, margin:  460 },
  { id: "s-2025-12-5",  date: "2025-12-07", artist: "Rels B",          venue: "Movistar Arena", revenue: 1400, margin:  448 },
  { id: "s-2025-12-6",  date: "2025-12-14", artist: "Cazzu",           venue: "Movistar Arena", revenue:  800, margin:  176 },
  { id: "s-2025-12-7",  date: "2025-12-21", artist: "Nicki Nicole",    venue: "Movistar Arena", revenue:  400, margin:  140 },
  { id: "s-2025-12-8",  date: "2025-12-28", artist: "Airbag",          venue: "Vélez",          revenue:  300, margin:   84 },
  { id: "s-2025-12-9",  date: "2025-12-15", artist: "Fito Páez",       venue: "Gran Rex",       revenue:  100, margin:   28 },
  { id: "s-2025-12-10", date: "2025-12-22", artist: "Franco Roadshow", venue: "Movistar Arena", revenue:  100, margin:   44 },

  // January 2026 — revenue $8.40M · margin $2.50M
  { id: "s-2026-01-1", date: "2026-01-10", artist: "Bad Bunny",    venue: "Vélez",          revenue: 2500, margin:  775 },
  { id: "s-2026-01-2", date: "2026-01-17", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1850, margin:  592 },
  { id: "s-2026-01-3", date: "2026-01-24", artist: "Duki",         venue: "Movistar Arena", revenue: 1450, margin:  435 },
  { id: "s-2026-01-4", date: "2026-01-31", artist: "Lali",         venue: "Movistar Arena", revenue: 1900, margin:  570 },
  { id: "s-2026-01-5", date: "2026-01-11", artist: "Rels B",       venue: "Gran Rex",       revenue:  500, margin:  100 },
  { id: "s-2026-01-6", date: "2026-01-18", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue:  200, margin:   28 },

  // February 2026 — revenue $9.86M · margin $2.93M
  { id: "s-2026-02-1", date: "2026-02-07", artist: "Bad Bunny",    venue: "Vélez",          revenue: 2400, margin:  744 },
  { id: "s-2026-02-2", date: "2026-02-14", artist: "Lali",         venue: "Vélez",          revenue: 2050, margin:  615 },
  { id: "s-2026-02-3", date: "2026-02-21", artist: "Duki",         venue: "Movistar Arena", revenue: 1850, margin:  555 },
  { id: "s-2026-02-4", date: "2026-02-28", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1650, margin:  528 },
  { id: "s-2026-02-5", date: "2026-02-08", artist: "Rels B",       venue: "Movistar Arena", revenue: 1200, margin:  384 },
  { id: "s-2026-02-6", date: "2026-02-15", artist: "Cazzu",        venue: "Movistar Arena", revenue:  550, margin:   97 },
  { id: "s-2026-02-7", date: "2026-02-22", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue:  160, margin:    7 },

  // March 2026 — revenue $11.42M · margin $3.54M
  { id: "p1", date: "2026-03-13", artist: "Bad Bunny",    venue: "River",          revenue: 4406, margin: 1366 },
  { id: "p4", date: "2026-03-08", artist: "Duki",         venue: "Vélez",          revenue: 2100, margin:  620 },
  { id: "p2", date: "2026-03-12", artist: "Rels B",       venue: "Movistar Arena", revenue: 1854, margin:  592 },
  { id: "p5", date: "2026-03-21", artist: "Bizarrap",     venue: "Movistar Arena", revenue: 1420, margin:  450 },
  { id: "p3", date: "2026-03-26", artist: "Nicki Nicole", venue: "Teatro Colón",   revenue: 1200, margin:  421 },
  { id: "p6", date: "2026-03-29", artist: "Cazzu",        venue: "Gran Rex",       revenue:  440, margin:   91 },
];

// Variables vs Fijos shares relative to revenue. Sum across both ≈ 0.69 of
// revenue, so margin ≈ 31% — matches the per-show numbers in PL_SHOWS.
const PL_BREAKDOWN_TEMPLATE = {
  ingresos:  [
    { label: "Tickets",                        share: 0.788 },
    { label: "Otros (Sponsors / F&B / Merch)", share: 0.212 },
  ],
  variables: [
    { label: "Sadaic",                share: 0.060 },
    { label: "Alquiler venues",       share: 0.200 },
    { label: "Ingresos Brutos",       share: 0.030 },
    { label: "Comisión ticketera",    share: 0.050 },
    { label: "Producción variable",   share: 0.040 },
    { label: "Marketing variable",    share: 0.021 },
  ],
  fijos:     [
    { label: "Estructura y técnica", share: 0.109 },
    { label: "Servicios",            share: 0.050 },
    { label: "Hospitality",          share: 0.041 },
    { label: "RRHH",                 share: 0.054 },
    { label: "Logística",            share: 0.022 },
    { label: "Seguros",              share: 0.014 },
  ],
};

const PL_MONTH_LABEL_EN = {
  "01": "Jan", "02": "Feb", "03": "Mar", "04": "Apr",
  "05": "May", "06": "Jun", "07": "Jul", "08": "Aug",
  "09": "Sep", "10": "Oct", "11": "Nov", "12": "Dec",
};

// Build the 12 monthly buckets from a (filtered) list of shows.
// Each bucket keeps revenue / variables / fijos / margin in thousands.
function plBuildMonthly(shows) {
  const buckets = new Map();
  for (const s of shows) {
    const ym = s.date.slice(0, 7);
    if (!buckets.has(ym)) buckets.set(ym, { id: ym, shows: 0, revenue: 0, margin: 0 });
    const b = buckets.get(ym);
    b.shows += 1;
    b.revenue += s.revenue;
    b.margin += s.margin;
  }
  // Make sure every month in the trailing window is represented, even if the
  // filter wiped it out. Otherwise the trend chart loses bars.
  const allMonths = Array.from(new Set(PL_SHOWS.map((s) => s.date.slice(0, 7)))).sort();
  return allMonths.map((ym) => {
    const b = buckets.get(ym) || { id: ym, shows: 0, revenue: 0, margin: 0 };
    const costs = b.revenue - b.margin;
    // Hold the variable/fijo split at ~58/42 of total costs to match the
    // breakdown template's variable share (0.401 / 0.69 ≈ 0.58).
    const variables = Math.round(costs * 0.58);
    const fijos = costs - variables;
    const [y, mm] = ym.split("-");
    return { id: ym, label: `${PL_MONTH_LABEL_EN[mm]} ${y}`, shows: b.shows, revenue: b.revenue, margin: b.margin, variables, fijos };
  });
}

// Distinct artists, ordered by total revenue desc — drives the artist filter.
const PL_ARTISTS = (() => {
  const totals = new Map();
  for (const s of PL_SHOWS) totals.set(s.artist, (totals.get(s.artist) || 0) + s.revenue);
  return [...totals.entries()].sort((a, b) => b[1] - a[1]).map(([a]) => a);
})();

// Values stored in thousands of ARS — display as "$11.42M" / "$11.420.000".
function plFmtM(thousands) {
  const m = thousands / 1000;
  const digits = Math.abs(m) >= 100 ? 0 : Math.abs(m) >= 10 ? 1 : 2;
  return "$" + m.toLocaleString("es-AR", { minimumFractionDigits: digits, maximumFractionDigits: digits }) + "M";
}
function plFmtK(thousands) {
  const value = Math.round(thousands * 1000);
  return "$" + value.toLocaleString("es-AR");
}
function plFmtPct(fraction) {
  return (fraction * 100).toLocaleString("es-AR", { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + "%";
}
function plFmtDelta(curr, prev) {
  if (prev == null) return null;
  const diff = curr - prev;
  const pct = prev === 0 ? 0 : diff / prev;
  return { abs: diff, pct, positive: diff >= 0 };
}

function PLPeriodSelect({ value, onChange, options }) {
  const [open, setOpen] = useStateHome(false);
  const ref = React.useRef(null);
  useEffectHome(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);
  const current = options.find((o) => o.id === value) || options[0];
  return (
    <div ref={ref} style={{ position: "relative" }}>
      <button
        onClick={() => setOpen((o) => !o)}
        style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          appearance: "none", background: "var(--live-card)",
          border: "1px solid var(--live-border)", borderRadius: 8,
          padding: "8px 12px", cursor: "pointer",
          fontFamily: "var(--font-sans)", fontSize: 13, fontWeight: 500,
          color: "var(--live-heading)",
        }}
      >
        <LuIcon name="calendar" size={14} color="var(--live-muted)" />
        {current.label}
        <LuIcon name="chevron-down" size={13} color="var(--live-muted)" />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 4px)", left: 0, zIndex: 50,
          minWidth: 200, padding: 6,
          background: "var(--live-card)",
          border: "1px solid var(--live-border)", borderRadius: 10,
          boxShadow: "0 12px 32px rgba(9,14,25,0.14), 0 2px 6px rgba(9,14,25,0.06)",
        }}>
          {options.map((o) => {
            const active = o.id === value;
            return (
              <button
                key={o.id}
                onClick={() => { onChange(o.id); setOpen(false); }}
                style={{
                  display: "flex", alignItems: "center", justifyContent: "space-between",
                  width: "100%", padding: "8px 10px",
                  background: active ? "var(--live-sidebar-active)" : "transparent",
                  border: "none", borderRadius: 6, cursor: "pointer",
                  textAlign: "left", fontFamily: "var(--font-sans)",
                  fontSize: 13, color: "var(--live-heading)",
                }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--live-sidebar-hover)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}
              >
                <span>{o.label}</span>
                {active && <LuIcon name="check" size={13} color="var(--live-primary)" />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

function PLDeltaBadge({ delta, invert }) {
  if (!delta) return null;
  const goodGreen = invert ? !delta.positive : delta.positive;
  const color = goodGreen ? "#1F6B2F" : "#8E2323";
  const bg = goodGreen ? "rgba(91,143,93,0.16)" : "rgba(176,99,99,0.16)";
  const arrow = delta.positive ? "↑" : "↓";
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 4,
      fontSize: 11.5, fontWeight: 600, color, background: bg,
      padding: "2px 8px", borderRadius: 999,
      fontVariantNumeric: "tabular-nums",
    }}>
      {arrow} {plFmtPct(Math.abs(delta.pct))}
    </span>
  );
}

function PLKpi({ icon, label, value, sub, delta, invert, accent }) {
  return (
    <div style={{ padding: "20px 24px", minWidth: 0 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
        <div style={{
          width: 32, height: 32, borderRadius: 999,
          border: "1.25px solid var(--live-border-strong)",
          display: "grid", placeItems: "center",
          color: accent || "var(--live-muted)",
          flexShrink: 0,
        }}>
          <LuIcon name={icon} size={15} />
        </div>
        <div style={{ fontSize: 12.5, color: "var(--live-muted)", fontWeight: 500 }}>{label}</div>
      </div>
      <div style={{
        fontSize: 24, fontWeight: 700, color: "var(--live-heading)",
        letterSpacing: "-0.015em", fontVariantNumeric: "tabular-nums",
      }}>
        {value}
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 8, minHeight: 18 }}>
        <PLDeltaBadge delta={delta} invert={invert} />
        {sub && <span style={{ fontSize: 11.5, color: "var(--live-muted)" }}>{sub}</span>}
      </div>
    </div>
  );
}

function PLTrendChart({ months, activeId, onPick }) {
  const [hover, setHover] = useStateHome(null);
  const max = Math.max(...months.map((m) => m.revenue));
  const W = 760, H = 220;
  const padL = 36, padR = 12, padT = 16, padB = 30;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;
  const step = innerW / months.length;
  const barW = step * 0.62;
  const yFor = (v) => padT + (1 - v / max) * innerH;

  return (
    <div style={{
      background: "var(--live-card)",
      border: "1px solid var(--live-border)",
      borderRadius: 12, padding: "20px 24px",
    }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8, gap: 16, flexWrap: "wrap" }}>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--live-heading)" }}>
            Revenue & Margen — últimos 12 meses
          </div>
          <div style={{ fontSize: 12, color: "var(--live-muted)", marginTop: 2 }}>
            Cada barra = Costos (claro) + Margen (oscuro). Click para cambiar el período activo.
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 14, fontSize: 12, color: "var(--live-muted)" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--live-progress-empty)" }} /> Costos
          </span>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
            <span style={{ width: 10, height: 10, borderRadius: 2, background: "var(--live-primary)" }} /> Margen
          </span>
        </div>
      </div>

      <svg width="100%" viewBox={`0 0 ${W} ${H}`} style={{ display: "block", overflow: "visible" }}>
        {[0.25, 0.5, 0.75, 1].map((g, i) => {
          const y = padT + (1 - g) * innerH;
          return (
            <g key={i}>
              <line x1={padL} y1={y} x2={W - padR} y2={y} stroke="var(--live-border)" strokeDasharray="2 4" />
              <text x={padL - 6} y={y + 3} textAnchor="end" fontSize="10" fill="var(--live-muted)" fontFamily="var(--font-sans)">
                {plFmtM(max * g)}
              </text>
            </g>
          );
        })}

        {months.map((m, i) => {
          const x = padL + step * i + (step - barW) / 2;
          const yMargin = yFor(m.margin);
          const yTop = yFor(m.revenue);
          const isActive = m.id === activeId;
          const isHover = hover === m.id;
          const opacity = isActive ? 1 : isHover ? 0.95 : 0.78;
          return (
            <g key={m.id}
               onMouseEnter={() => setHover(m.id)}
               onMouseLeave={() => setHover(null)}
               onClick={() => onPick(m.id)}
               style={{ cursor: "pointer" }}>
              <rect x={x} y={yTop} width={barW} height={Math.max(0, yMargin - yTop)}
                    fill="var(--live-progress-empty)" opacity={opacity} rx="2" />
              <rect x={x} y={yMargin} width={barW} height={Math.max(0, padT + innerH - yMargin)}
                    fill="var(--live-primary)" opacity={opacity} rx="2" />
              {isActive && (
                <rect x={x - 2} y={yTop - 2} width={barW + 4} height={padT + innerH - yTop + 2}
                      fill="none" stroke="var(--live-primary)" strokeWidth="1.5" rx="3"
                      strokeDasharray="3 3" />
              )}
              <text x={x + barW / 2} y={H - padB + 14} textAnchor="middle" fontSize="10.5"
                    fill={isActive ? "var(--live-heading)" : "var(--live-muted)"}
                    fontWeight={isActive ? 600 : 400}
                    fontFamily="var(--font-sans)">
                {m.label.split(" ")[0]}
              </text>
            </g>
          );
        })}

        {hover && (() => {
          const m = months.find((x) => x.id === hover);
          if (!m) return null;
          const i = months.indexOf(m);
          const cx = padL + step * i + step / 2;
          const cy = yFor(m.revenue) - 8;
          const text = `${m.label} · ${plFmtM(m.revenue)} rev · ${plFmtPct(m.margin / m.revenue)} margen`;
          const w = text.length * 5.5 + 16;
          return (
            <g pointerEvents="none">
              <rect x={cx - w / 2} y={cy - 22} width={w} height={20} rx="4"
                    fill="var(--live-heading)" />
              <text x={cx} y={cy - 8} textAnchor="middle" fontSize="11" fill="#fff"
                    fontFamily="var(--font-sans)">{text}</text>
            </g>
          );
        })()}
      </svg>
    </div>
  );
}

function PLStatement({ active, prior, breakdown }) {
  const [expanded, setExpanded] = useStateHome({ ingresos: false, variables: true, fijos: true });
  const cols = "minmax(260px,1.4fr) 130px 130px 110px 130px";
  const incomeBg = "rgba(91,143,93,0.16)";
  const costBg = "rgba(176,99,99,0.16)";
  const incomeColor = "#1F6B2F";
  const costColor = "#8E2323";

  // Each row's importe = parentValue × (row.share / Σ row.share). This keeps
  // child rows summing to the parent regardless of which artists are filtered.
  const buildRows = (template, parentValue) => {
    if (!template || !parentValue) return [];
    const totalShare = template.reduce((acc, r) => acc + r.share, 0);
    let allocated = 0;
    return template.map((r, i) => {
      const isLast = i === template.length - 1;
      const importe = isLast ? parentValue - allocated : Math.round(parentValue * (r.share / totalShare));
      allocated += importe;
      const share = parentValue ? importe / parentValue : 0;
      return { label: r.label, importe, share };
    });
  };

  const sections = [
    { id: "ingresos",  label: "Ingresos",         tone: "income", parentValue: active.revenue,    priorValue: prior ? prior.revenue : null,    rows: buildRows(breakdown.ingresos,  active.revenue) },
    { id: "variables", label: "Costos Variables", tone: "cost",   parentValue: active.variables,  priorValue: prior ? prior.variables : null,  rows: buildRows(breakdown.variables, active.variables) },
    { id: "fijos",     label: "Costos Fijos",     tone: "cost",   parentValue: active.fijos,      priorValue: prior ? prior.fijos : null,      rows: buildRows(breakdown.fijos,     active.fijos) },
  ];

  return (
    <div>
      <div style={{ fontSize: 16, fontWeight: 600, color: "var(--live-heading)", marginBottom: 12 }}>
        Estado de resultados
      </div>
      <div style={{
        background: "var(--live-card)", border: "1px solid var(--live-border)",
        borderRadius: 10, overflow: "hidden",
      }}>
        <div style={{
          display: "grid", gridTemplateColumns: cols,
          padding: "12px 24px", background: "var(--live-banner-bg)",
          borderBottom: "1px solid var(--live-border)",
          fontSize: 12, fontWeight: 500, color: "var(--live-muted)",
        }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <LuIcon name="info" size={13} /> Concepto
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <LuIcon name="dollar-sign" size={13} /> Importe
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <LuIcon name="percent" size={13} /> % del Revenue
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <LuIcon name="trending-up" size={13} /> Δ vs prev.
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <LuIcon name="hash" size={13} /> Período prev.
          </div>
        </div>

        {sections.map((s) => {
          const open = expanded[s.id];
          const isIncome = s.tone === "income";
          const headerBg = isIncome ? incomeBg : costBg;
          const valueColor = isIncome ? incomeColor : costColor;
          const delta = plFmtDelta(s.parentValue, s.priorValue);
          const share = s.parentValue / active.revenue;
          return (
            <React.Fragment key={s.id}>
              <button
                onClick={() => setExpanded({ ...expanded, [s.id]: !open })}
                style={{
                  appearance: "none", border: "none", textAlign: "left",
                  width: "100%", cursor: "pointer", padding: 0,
                  display: "grid", gridTemplateColumns: cols,
                  background: headerBg,
                  borderTop: "1px solid var(--live-border)",
                  fontFamily: "var(--font-sans)",
                }}
              >
                <div style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 24px" }}>
                  <LuIcon name={open ? "chevron-up" : "chevron-down"} size={14} color="var(--live-body)" />
                  <span style={{ fontSize: 12, color: "var(--live-body)", fontWeight: 500, fontVariantNumeric: "tabular-nums" }}>
                    {s.rows.length}
                  </span>
                  <span style={{ fontSize: 14, fontWeight: 600, color: valueColor }}>{s.label}</span>
                </div>
                <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 14, fontWeight: 600, color: valueColor, fontVariantNumeric: "tabular-nums" }}>
                  {plFmtM(s.parentValue)}
                </div>
                <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 14, fontWeight: 600, color: valueColor, fontVariantNumeric: "tabular-nums" }}>
                  {isIncome ? "100,0%" : plFmtPct(share)}
                </div>
                <div style={{ display: "flex", alignItems: "center", padding: "12px 24px" }}>
                  <PLDeltaBadge delta={delta} invert={!isIncome} />
                </div>
                <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 13, color: "var(--live-muted)", fontVariantNumeric: "tabular-nums" }}>
                  {s.priorValue != null ? plFmtM(s.priorValue) : "—"}
                </div>
              </button>

              {open && s.rows.map((row, ri) => {
                const priorRowValue = s.priorValue != null
                  ? Math.round(s.priorValue * (row.importe / s.parentValue))
                  : null;
                const rowDelta = plFmtDelta(row.importe, priorRowValue);
                return (
                  <div key={ri} style={{
                    display: "grid", gridTemplateColumns: cols,
                    background: "var(--live-card)",
                    borderTop: "1px solid var(--live-border)",
                  }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 24px 12px 38px" }}>
                      <span style={{ display: "inline-grid", placeItems: "center", color: "var(--live-muted)" }}>
                        <LuIcon name="corner-down-right" size={14} />
                      </span>
                      <span style={{ fontSize: 13, color: "var(--live-body)" }}>{row.label}</span>
                    </div>
                    <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 13, color: "var(--live-body)", fontVariantNumeric: "tabular-nums" }}>
                      {plFmtM(row.importe)}
                    </div>
                    <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 13, color: "var(--live-body)", fontVariantNumeric: "tabular-nums" }}>
                      {plFmtPct(row.share)}
                    </div>
                    <div style={{ display: "flex", alignItems: "center", padding: "12px 24px" }}>
                      <PLDeltaBadge delta={rowDelta} invert={!isIncome} />
                    </div>
                    <div style={{ display: "flex", alignItems: "center", padding: "12px 24px", fontSize: 13, color: "var(--live-muted)", fontVariantNumeric: "tabular-nums" }}>
                      {priorRowValue != null ? plFmtM(priorRowValue) : "—"}
                    </div>
                  </div>
                );
              })}
            </React.Fragment>
          );
        })}

        {/* Resultado Neto footer */}
        <div style={{
          display: "grid", gridTemplateColumns: cols,
          background: incomeBg,
          borderTop: "1px solid var(--live-border)",
        }}>
          <div style={{ padding: "14px 24px", fontSize: 14, fontWeight: 600, color: incomeColor }}>
            Resultado Neto
          </div>
          <div style={{ padding: "14px 24px", fontSize: 14, fontWeight: 700, color: incomeColor, fontVariantNumeric: "tabular-nums" }}>
            {plFmtM(active.margin)}
          </div>
          <div style={{ padding: "14px 24px", fontSize: 14, fontWeight: 700, color: incomeColor, fontVariantNumeric: "tabular-nums" }}>
            {plFmtPct(active.margin / active.revenue)}
          </div>
          <div style={{ padding: "14px 24px" }}>
            <PLDeltaBadge delta={plFmtDelta(active.margin, prior ? prior.margin : null)} />
          </div>
          <div style={{ padding: "14px 24px", fontSize: 13, color: "var(--live-muted)", fontVariantNumeric: "tabular-nums" }}>
            {prior ? plFmtM(prior.margin) : "—"}
          </div>
        </div>
      </div>
    </div>
  );
}

function PLTopShows({ shows, onOpenShow }) {
  const cols = "1.4fr 1.2fr 110px 130px 130px 110px 28px";
  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
        <div style={{ fontSize: 16, fontWeight: 600, color: "var(--live-heading)" }}>
          Top shows del período
        </div>
        <div style={{ fontSize: 12, color: "var(--live-muted)" }}>Ordenado por revenue</div>
      </div>
      <div style={{
        background: "var(--live-card)", border: "1px solid var(--live-border)",
        borderRadius: 10, overflow: "hidden",
      }}>
        <div style={{
          display: "grid", gridTemplateColumns: cols,
          padding: "11px 20px", background: "var(--live-banner-bg)",
          borderBottom: "1px solid var(--live-border)",
          fontSize: 11, fontWeight: 600, color: "var(--live-muted)",
          textTransform: "uppercase", letterSpacing: "0.04em",
        }}>
          <div>Show</div>
          <div>Venue</div>
          <div>Fecha</div>
          <div>Revenue</div>
          <div>Margen</div>
          <div>Margen %</div>
          <div />
        </div>
        {shows.map((r, i) => {
          const margPct = r.margin / r.revenue;
          return (
            <div
              key={r.id}
              onClick={() => onOpenShow && onOpenShow(r)}
              style={{
                display: "grid", gridTemplateColumns: cols,
                padding: "12px 20px",
                borderTop: i === 0 ? "none" : "1px solid var(--live-border)",
                alignItems: "center", fontSize: 13,
                cursor: onOpenShow ? "pointer" : "default",
                transition: "background 120ms ease-out",
              }}
              onMouseEnter={(e) => (e.currentTarget.style.background = "var(--live-row-hover)")}
              onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
            >
              <div style={{ fontWeight: 600, color: "var(--live-heading)" }}>{r.artist}</div>
              <div style={{ color: "var(--live-body)" }}>{r.venue}</div>
              <div style={{ color: "var(--live-muted)" }}>{r.date}</div>
              <div style={{ color: "var(--live-body)", fontVariantNumeric: "tabular-nums" }}>{plFmtM(r.revenue)}</div>
              <div style={{ color: "var(--live-body)", fontVariantNumeric: "tabular-nums" }}>{plFmtM(r.margin)}</div>
              <div style={{ fontVariantNumeric: "tabular-nums" }}>
                <span style={{
                  display: "inline-flex", alignItems: "center",
                  fontSize: 11.5, fontWeight: 500,
                  padding: "3px 10px", borderRadius: 999,
                  background: margPct >= 0.30 ? "rgba(91,143,93,0.16)" : "rgba(176,99,99,0.16)",
                  color: margPct >= 0.30 ? "#1F6B2F" : "#8E2323",
                }}>
                  {plFmtPct(margPct)}
                </span>
              </div>
              <div style={{ color: "var(--live-muted)", display: "flex", justifyContent: "flex-end" }}>
                <LuIcon name="chevron-right" size={14} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

const PL_MONTH_ES = {
  "01": "Enero",  "02": "Febrero", "03": "Marzo",     "04": "Abril",
  "05": "Mayo",   "06": "Junio",   "07": "Julio",     "08": "Agosto",
  "09": "Septiembre", "10": "Octubre", "11": "Noviembre", "12": "Diciembre",
};

function PLArtistFilter({ artists, selected, onChange }) {
  const [open, setOpen] = useStateHome(false);
  const [query, setQuery] = useStateHome("");
  const ref = React.useRef(null);
  useEffectHome(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const allOn = selected.length === 0;
  const label = allOn
    ? "Todos los artistas"
    : selected.length === 1
    ? selected[0]
    : `${selected.length} artistas`;

  const toggle = (a) => {
    if (selected.includes(a)) onChange(selected.filter((x) => x !== a));
    else onChange([...selected, a]);
  };
  const clear = () => onChange([]);

  const filtered = artists.filter((a) => a.toLowerCase().includes(query.toLowerCase()));

  return (
    <div ref={ref} style={{ position: "relative" }}>
      <button
        onClick={() => setOpen((o) => !o)}
        style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          appearance: "none",
          background: allOn ? "var(--live-card)" : "var(--live-pill-open-bg)",
          border: "1px solid",
          borderColor: allOn ? "var(--live-border)" : "var(--live-primary)",
          borderRadius: 8,
          padding: "8px 12px", cursor: "pointer",
          fontFamily: "var(--font-sans)", fontSize: 13, fontWeight: 500,
          color: allOn ? "var(--live-heading)" : "var(--live-pill-open-fg)",
        }}
      >
        <LuIcon name="users" size={14} color="var(--live-muted)" />
        {label}
        {!allOn && (
          <span
            role="button"
            onClick={(e) => { e.stopPropagation(); clear(); }}
            style={{
              display: "inline-grid", placeItems: "center",
              width: 16, height: 16, borderRadius: 999,
              background: "rgba(0,0,0,0.08)", color: "var(--live-pill-open-fg)",
              cursor: "pointer",
            }}
            aria-label="Limpiar filtro"
          >
            <LuIcon name="x" size={10} />
          </span>
        )}
        <LuIcon name="chevron-down" size={13} color="var(--live-muted)" />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 4px)", right: 0, zIndex: 50,
          minWidth: 260, padding: 6,
          background: "var(--live-card)",
          border: "1px solid var(--live-border)", borderRadius: 10,
          boxShadow: "0 12px 32px rgba(9,14,25,0.14), 0 2px 6px rgba(9,14,25,0.06)",
        }}>
          <div style={{ padding: "6px 8px 8px" }}>
            <div style={{
              display: "flex", alignItems: "center", gap: 6,
              padding: "6px 10px",
              background: "var(--live-bg)", border: "1px solid var(--live-border)",
              borderRadius: 6,
            }}>
              <LuIcon name="search" size={12} color="var(--live-muted)" />
              <input
                type="text" value={query} onChange={(e) => setQuery(e.target.value)}
                placeholder="Buscar artista…"
                style={{
                  flex: 1, border: "none", outline: "none",
                  background: "transparent", fontFamily: "var(--font-sans)",
                  fontSize: 12.5, color: "var(--live-heading)",
                }}
              />
            </div>
          </div>
          <button
            onClick={clear}
            style={{
              display: "flex", alignItems: "center", justifyContent: "space-between",
              width: "100%", padding: "8px 10px",
              background: allOn ? "var(--live-sidebar-active)" : "transparent",
              border: "none", borderRadius: 6, cursor: "pointer",
              textAlign: "left", fontFamily: "var(--font-sans)",
              fontSize: 13, fontWeight: 500, color: "var(--live-heading)",
            }}
            onMouseEnter={(e) => { if (!allOn) e.currentTarget.style.background = "var(--live-sidebar-hover)"; }}
            onMouseLeave={(e) => { if (!allOn) e.currentTarget.style.background = "transparent"; }}
          >
            <span>Todos los artistas</span>
            {allOn && <LuIcon name="check" size={13} color="var(--live-primary)" />}
          </button>
          <div style={{ height: 1, background: "var(--live-border)", margin: "4px 6px" }} />
          <div style={{ maxHeight: 280, overflow: "auto" }}>
            {filtered.length === 0 && (
              <div style={{ padding: "10px", fontSize: 12, color: "var(--live-muted)", textAlign: "center" }}>
                No coincide ningún artista.
              </div>
            )}
            {filtered.map((a) => {
              const checked = selected.includes(a);
              return (
                <button
                  key={a}
                  onClick={() => toggle(a)}
                  style={{
                    display: "flex", alignItems: "center", gap: 10,
                    width: "100%", padding: "8px 10px",
                    background: "transparent", border: "none", borderRadius: 6,
                    cursor: "pointer", textAlign: "left",
                    fontFamily: "var(--font-sans)", fontSize: 13, color: "var(--live-heading)",
                  }}
                  onMouseEnter={(e) => (e.currentTarget.style.background = "var(--live-sidebar-hover)")}
                  onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
                >
                  <span style={{
                    width: 16, height: 16, borderRadius: 4,
                    border: "1.5px solid",
                    borderColor: checked ? "var(--live-primary)" : "var(--live-border-strong)",
                    background: checked ? "var(--live-primary)" : "transparent",
                    display: "grid", placeItems: "center",
                    color: "#fff", flexShrink: 0,
                  }}>
                    {checked && <LuIcon name="check" size={11} />}
                  </span>
                  <span style={{ flex: 1 }}>{a}</span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

// Period buckets — quarter / YTD pull a range of months from PL_SHOWS.
function plPeriodRange(periodId) {
  if (periodId === "ytd-2026") return { start: "2026-01", end: "2026-12", label: "YTD 2026", granularity: "ytd" };
  if (periodId === "2026-q1")  return { start: "2026-01", end: "2026-03", label: "Q1 2026",  granularity: "quarter" };
  // Single month
  const [y, mm] = periodId.split("-");
  return { start: periodId, end: periodId, label: `${PL_MONTH_ES[mm]} ${y}`, granularity: "month" };
}

function plMatchesPeriod(show, range) {
  const ym = show.date.slice(0, 7);
  return ym >= range.start && ym <= range.end;
}

function plPriorRange(range) {
  if (range.granularity !== "month") return null;
  const [y, mm] = range.start.split("-");
  const idx = parseInt(mm, 10) - 1; // current month index
  if (idx === 0) {
    const py = (parseInt(y, 10) - 1).toString().padStart(4, "0");
    const id = `${py}-12`;
    return { start: id, end: id, label: `Diciembre ${py}` };
  }
  const pmm = idx.toString().padStart(2, "0");
  const id = `${y}-${pmm}`;
  return { start: id, end: id, label: `${PL_MONTH_ES[pmm]} ${y}` };
}

function plAggregate(shows) {
  let revenue = 0, margin = 0;
  for (const s of shows) { revenue += s.revenue; margin += s.margin; }
  const costs = revenue - margin;
  const variables = Math.round(costs * 0.58);
  const fijos = costs - variables;
  return { revenue, margin, variables, fijos, count: shows.length };
}

function PLPane({ onOpenShow }) {
  const [periodId, setPeriodId] = useStateHome("2026-03");
  const [selectedArtists, setSelectedArtists] = useStateHome([]);

  const monthOptions = [...PL_SHOWS]
    .map((s) => s.date.slice(0, 7))
    .filter((v, i, a) => a.indexOf(v) === i)
    .sort()
    .reverse()
    .map((id) => {
      const [y, mm] = id.split("-");
      return { id, label: `${PL_MONTH_ES[mm]} ${y}` };
    });
  const periodOptions = [
    { id: "ytd-2026", label: "YTD 2026" },
    { id: "2026-q1",  label: "Q1 2026" },
    ...monthOptions,
  ];

  // Apply the artist filter once — every downstream computation derives from
  // this filtered list so toggling an artist rolls through KPIs / trend /
  // statement / top shows in lockstep.
  const filteredShows = selectedArtists.length === 0
    ? PL_SHOWS
    : PL_SHOWS.filter((s) => selectedArtists.includes(s.artist));

  const monthly = plBuildMonthly(filteredShows);

  const range = plPeriodRange(periodId);
  const priorR = plPriorRange(range);

  const periodShows = filteredShows.filter((s) => plMatchesPeriod(s, range));
  const priorShows  = priorR ? filteredShows.filter((s) => plMatchesPeriod(s, priorR)) : [];

  const active = plAggregate(periodShows);
  const prior  = priorR ? plAggregate(priorShows) : null;

  const isEmpty = active.revenue === 0;
  const totalCosts = active.variables + active.fijos;
  const priorCosts = prior ? prior.variables + prior.fijos : null;
  const marginRate = isEmpty ? 0 : active.margin / active.revenue;
  const priorMarginRate = prior && prior.revenue ? prior.margin / prior.revenue : null;
  const marginRateDelta = priorMarginRate != null ? {
    abs: marginRate - priorMarginRate,
    pct: priorMarginRate === 0 ? 0 : (marginRate - priorMarginRate) / priorMarginRate,
    positive: marginRate >= priorMarginRate,
  } : null;

  // Active id used to highlight the chart bar — month rows always exist in
  // `monthly`; quarter / YTD selections highlight nothing.
  const activeMonthlyId = range.granularity === "month" ? range.start : null;

  const topShows = [...periodShows].sort((a, b) => b.revenue - a.revenue).slice(0, 8).map((s) => ({
    id: s.id, artist: s.artist, venue: s.venue,
    date: s.date.split("-").reverse().join("/"),
    revenue: s.revenue, margin: s.margin,
  }));

  const summary = selectedArtists.length === 0
    ? `${active.count} shows en ${range.label}`
    : `${active.count} shows · ${selectedArtists.length === 1 ? selectedArtists[0] : selectedArtists.length + " artistas"} · ${range.label}`;

  return (
    <div style={{ padding: "28px 48px 48px", overflow: "auto", height: "100%" }}>
      <div style={{
        display: "flex", alignItems: "flex-end", justifyContent: "space-between",
        marginBottom: 20, gap: 16, flexWrap: "wrap",
      }}>
        <div>
          <h1 style={{
            fontFamily: "var(--font-sans)",
            fontSize: 22, fontWeight: 700,
            letterSpacing: "-0.015em", color: "var(--live-heading)",
            margin: 0, marginBottom: 4,
          }}>
            Business · P&L
          </h1>
          <p style={{ fontSize: 13, color: "var(--live-muted)", margin: 0 }}>
            Estado de resultados agregado de la productora · {summary}.
          </p>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
          <PLPeriodSelect value={periodId} onChange={setPeriodId} options={periodOptions} />
          <PLArtistFilter
            artists={PL_ARTISTS}
            selected={selectedArtists}
            onChange={setSelectedArtists}
          />
          <button style={{
            display: "inline-flex", alignItems: "center", gap: 6,
            appearance: "none", background: "var(--live-card)",
            border: "1px solid var(--live-border)", borderRadius: 8,
            padding: "8px 12px", cursor: "pointer",
            fontFamily: "var(--font-sans)", fontSize: 13, fontWeight: 500,
            color: "var(--live-body)",
          }}>
            <LuIcon name="download" size={13} /> Exportar
          </button>
        </div>
      </div>

      {/* KPI ribbon */}
      <div style={{
        background: "var(--live-banner-bg)",
        border: "1px solid var(--live-border)",
        borderRadius: 12, overflow: "hidden", marginBottom: 24,
      }}>
        <div style={{ height: 3, background: "var(--live-primary)" }} />
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1px 1fr 1px 1fr 1px 1fr" }}>
          <PLKpi
            icon="plus-circle" label="Revenue"
            value={plFmtM(active.revenue)}
            sub={isEmpty
              ? "Sin shows en el período"
              : `${active.count} shows · ${plFmtK(active.revenue / active.count)} prom.`}
            delta={prior ? plFmtDelta(active.revenue, prior.revenue) : null}
            accent="var(--live-primary)"
          />
          <div style={{ background: "var(--live-border)" }} />
          <PLKpi
            icon="minus-circle" label="Costos totales"
            value={plFmtM(totalCosts)}
            sub={isEmpty ? "—" : plFmtPct(totalCosts / active.revenue) + " del Revenue"}
            delta={prior ? plFmtDelta(totalCosts, priorCosts) : null}
            invert
          />
          <div style={{ background: "var(--live-border)" }} />
          <PLKpi
            icon="divide-circle" label="Margen Neto"
            value={plFmtM(active.margin)}
            sub={isEmpty ? "—" : plFmtPct(marginRate) + " del Revenue"}
            delta={prior ? plFmtDelta(active.margin, prior.margin) : null}
            accent="var(--live-primary)"
          />
          <div style={{ background: "var(--live-border)" }} />
          <PLKpi
            icon="percent" label="Margen %"
            value={isEmpty ? "—" : plFmtPct(marginRate)}
            sub={priorMarginRate != null ? "vs " + plFmtPct(priorMarginRate) + " mes ant." : null}
            delta={marginRateDelta}
          />
        </div>
      </div>

      <div style={{ marginBottom: 24 }}>
        <PLTrendChart months={monthly} activeId={activeMonthlyId} onPick={setPeriodId} />
      </div>

      <div style={{ marginBottom: 28 }}>
        <PLStatement active={active} prior={prior} breakdown={PL_BREAKDOWN_TEMPLATE} />
      </div>

      <PLTopShows shows={topShows} onOpenShow={onOpenShow} />
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Home surface
// ─────────────────────────────────────────────────────────────

function AssistantPane({ bannerOpen, setBannerOpen }) {
  const [query, setQuery] = useStateHome("");
  const [status, setStatus] = useStateHome(null);

  const chips = ["This week's shows", "Pending approvals", "P&L summary", "Unpaid invoices", "Ticket sales today"];

  const submit = (prefill) => {
    const q = prefill || query;
    if (!q.trim()) return;
    setQuery(q);
    setStatus(`Routing "${q}" to Malbec Live…`);
    setTimeout(() => setStatus(null), 1800);
  };

  return (
    <div style={{ padding: "20px 48px 48px", overflow: "auto", height: "100%" }}>
      {bannerOpen && <Banner onDismiss={() => setBannerOpen(false)} />}

      {/* Assistant hero — single centered column, all elements aligned to same width */}
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          textAlign: "center",
          paddingTop: bannerOpen ? 64 : 96,
          transition: "padding-top 200ms ease-out",
        }}
      >
        <Grape size={36} color="var(--live-primary)" />
        <h1
          style={{
            fontFamily: "var(--font-sans)",
            fontSize: 24,
            fontWeight: 600,
            color: "var(--live-heading)",
            margin: "20px 0 28px",
            letterSpacing: "-0.015em",
          }}
        >
          Your personal Assistant.
        </h1>

        <AssistantInput value={query} setValue={setQuery} onSubmit={() => submit()} />

        <div
          style={{
            display: "flex",
            flexWrap: "wrap",
            gap: 8,
            justifyContent: "center",
            marginTop: 14,
            width: "100%",
            maxWidth: 570,
          }}
        >
          {chips.map((c) => (
            <QuickChip key={c} label={c} onClick={() => submit(c)} />
          ))}
        </div>

        {status && (
          <div
            style={{
              marginTop: 18,
              fontSize: 12.5,
              color: "var(--live-primary)",
              fontWeight: 500,
            }}
          >
            {status}
          </div>
        )}

        {/* Three columns — same max-width as input/chips for vertical alignment */}
        <div
          style={{
            marginTop: 64,
            width: "100%",
            maxWidth: 700,
            display: "grid",
            gridTemplateColumns: "repeat(3, 1fr)",
            gap: 28,
            textAlign: "left",
          }}
        >
          <Column
            title="Pinned"
            items={["Weekly P&L overview", "Pending payments", "Upcoming shows"]}
          />
          <Column
            title="Recents"
            items={["Costos — Lollapalooza", "Ticket report — Feb 28", "Invoice batch — March"]}
          />
          <Column
            title="Needs attention"
            items={["3 invoices pending", "2 costs over budget", "1 payment overdue"]}
          />
        </div>
      </div>
    </div>
  );
}

function ShowsHeader() {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        padding: "14px 28px",
        borderBottom: "1px solid var(--live-border)",
        background: "var(--live-bg)",
        height: 54,
      }}
    >
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <Grape size={18} color="var(--live-primary)" />
        <div
          style={{
            fontFamily: "var(--font-sans)",
            fontSize: 16,
            letterSpacing: "-0.07em",
            color: "var(--live-heading)",
          }}
        >
          <span style={{ fontWeight: 500 }}>Malbec</span><span style={{ fontStyle: "italic", fontWeight: 300 }}>Live</span>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Workspace tabs — browser-like tabs across the top of the app.
// One tab per open route. Click to activate, X to close. Logo on the right.
// ─────────────────────────────────────────────────────────────

function WorkspaceTabs({ tabs, activeId, onActivate, onClose }) {
  useEffectHome(() => { if (window.lucide) window.lucide.createIcons(); }, [tabs.length, activeId]);
  return (
    <div
      style={{
        display: "flex",
        alignItems: "flex-end",
        justifyContent: "space-between",
        padding: "0 28px",
        borderBottom: "1px solid var(--live-border)",
        background: "var(--live-bg)",
        height: 54,
      }}
    >
      <div style={{
        display: "flex", alignItems: "flex-end",
        gap: 4, height: "100%",
        overflowX: "auto", flex: 1, minWidth: 0,
      }}>
        {tabs.map((t) => {
          const active = t.id === activeId;
          return (
            <div
              key={t.id}
              onClick={() => onActivate(t.id)}
              style={{
                display: "inline-flex",
                alignItems: "center",
                gap: 10,
                background: active ? "var(--live-card)" : "transparent",
                border: "1px solid",
                borderColor: active ? "var(--live-border)" : "transparent",
                borderBottom: active ? "1px solid var(--live-card)" : "1px solid transparent",
                marginBottom: -1,
                borderTopLeftRadius: 8,
                borderTopRightRadius: 8,
                padding: "10px 14px 10px 16px",
                whiteSpace: "nowrap",
                fontSize: 13,
                fontWeight: active ? 600 : 500,
                color: active ? "var(--live-heading)" : "var(--live-muted)",
                cursor: "pointer",
                fontFamily: "var(--font-sans)",
                transition: "color 140ms ease-out, background 140ms ease-out",
                maxWidth: 280,
                overflow: "hidden",
                textOverflow: "ellipsis",
              }}
            >
              <span style={{ overflow: "hidden", textOverflow: "ellipsis" }}>{t.label}</span>
              <button
                onClick={(e) => { e.stopPropagation(); onClose(t.id); }}
                style={{
                  appearance: "none", border: "none", background: "transparent",
                  width: 18, height: 18, borderRadius: 4,
                  display: "grid", placeItems: "center",
                  color: active ? "var(--live-muted)" : "transparent",
                  cursor: "pointer",
                  flexShrink: 0,
                  transition: "background 140ms, color 140ms",
                }}
                onMouseEnter={(e) => {
                  e.currentTarget.style.background = "rgba(0,0,0,0.06)";
                  e.currentTarget.style.color = "var(--live-heading)";
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.background = "transparent";
                  e.currentTarget.style.color = active ? "var(--live-muted)" : "transparent";
                }}
              >
                <i data-lucide="x" style={{ width: 12, height: 12 }} />
              </button>
            </div>
          );
        })}
      </div>

      {/* Brand lockup top-right */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 8,
          padding: "0 4px 14px 16px",
          flexShrink: 0,
        }}
      >
        <Grape size={18} color="var(--live-primary)" />
        <div
          style={{
            fontFamily: "var(--font-sans)",
            fontSize: 16,
            letterSpacing: "-0.07em",
            color: "var(--live-heading)",
          }}
        >
          <span style={{ fontWeight: 500 }}>Malbec</span><span style={{ fontStyle: "italic", fontWeight: 300 }}>Live</span>
        </div>
      </div>
    </div>
  );
}

function Home({ onBackToOnboarding }) {
  const initialRoute = new URLSearchParams(location.search).get("route") || "home";

  // Map a route to a tab definition
  const tabFor = (route, project) => {
    switch (route) {
      case "home":           return { id: "home",          route: "home",          label: "Home - Personal Assistant" };
      case "pl":             return { id: "pl",            route: "pl",            label: "Business - P&L" };
      case "project-hub":    return { id: "project-hub",   route: "project-hub",   label: "Project Hub" };
      case "project-detail": return { id: `project-${(project || {}).id || "detail"}`, route: "project-detail", label: `Project · ${(project || {}).artist || "Detail"}`, project };
      case "shows":          return { id: "shows",         route: "shows",         label: "Shows" };
      case "show-detail":    return { id: "show-detail",   route: "show-detail",   label: "Show · Detail" };
      case "venues":         return { id: "venues",        route: "venues",        label: "Venues" };
      case "calendar":       return { id: "calendar",      route: "calendar",      label: "Calendar" };
      case "ticketing":      return { id: "ticketing",     route: "ticketing",     label: "Ticketing" };
      // Live Nation parent workspace
      case "ln-productoras": return { id: "ln-productoras", route: "ln-productoras", label: "Productoras" };
      case "ln-pl":          return { id: "ln-pl",          route: "ln-pl",          label: "Business · P&L" };
      case "ln-calendar":    return { id: "ln-calendar",    route: "ln-calendar",    label: "Calendar" };
      case "ln-ticketing":   return { id: "ln-ticketing",   route: "ln-ticketing",   label: "Ticketing" };
      case "ln-productora-detail": return { id: `ln-prod-${(project || {}).id || "detail"}`, route: "ln-productora-detail", label: `P&L · ${(project || {}).name || "Productora"}`, project };
      default:               return { id: route,           route,                  label: route };
    }
  };

  const [workspace, setWorkspaceState] = useStateHome("dale-play");

  const initialTab = tabFor(initialRoute);
  const plTab = tabFor("pl");
  const [openTabs, setOpenTabs] = useStateHome(
    initialRoute === "home" ? [initialTab, plTab] : [initialTab]
  );
  const [activeTabId, setActiveTabId] = useStateHome(initialTab.id);

  // Switching workspace replaces all open tabs with that workspace's landing page.
  // Live Nation lands on Productoras; productoras land on Project Hub.
  const setWorkspace = (wsId) => {
    setWorkspaceState(wsId);
    if (wsId === "live-nation") {
      const t = tabFor("ln-productoras");
      setOpenTabs([t]);
      setActiveTabId(t.id);
    } else {
      // Any productora → Project Hub landing
      const t = tabFor("project-hub");
      setOpenTabs([t]);
      setActiveTabId(t.id);
    }
  };
  const [tab, setTab] = useStateHome("Home - Personal Assistant");
  const [bannerOpen, setBannerOpen] = useStateHome(true);
  const [selectedProject, setSelectedProject] = useStateHome(
    initialRoute === "project-detail"
      ? { id: "p1", artist: "Bad Bunny", venue: "River", date: "13/02/2026" }
      : null
  );

  // Open or focus a tab for a given route
  const openRoute = (route, project) => {
    const t = tabFor(route, project);
    setOpenTabs((prev) => {
      if (prev.find((x) => x.id === t.id)) {
        // update project if needed
        return prev.map((x) => (x.id === t.id ? { ...x, ...t } : x));
      }
      return [...prev, t];
    });
    setActiveTabId(t.id);
  };

  // setRoute compatible API for sub-components (sidebar, etc)
  const setRoute = (route, project) => {
    if (route === "project-detail" && project) {
      setSelectedProject(project);
    }
    openRoute(route, project || (route === "project-detail" ? selectedProject : null));
  };

  const closeTab = (id) => {
    setOpenTabs((prev) => {
      const idx = prev.findIndex((x) => x.id === id);
      if (idx === -1) return prev;
      const next = prev.filter((x) => x.id !== id);
      if (next.length === 0) {
        // Always keep at least one tab — fall back to project-hub
        const fallback = tabFor("project-hub");
        setActiveTabId(fallback.id);
        return [fallback];
      }
      if (id === activeTabId) {
        const neighbor = next[Math.min(idx, next.length - 1)];
        setActiveTabId(neighbor.id);
      }
      return next;
    });
  };

  const activeTab = openTabs.find((t) => t.id === activeTabId) || openTabs[0];
  const route = activeTab ? activeTab.route : "project-hub";

  useEffectHome(() => {
    if (window.lucide) window.lucide.createIcons();
  });

  return (
    <div style={{ display: "flex", width: "100%", height: "100%", background: "var(--live-bg)" }}>
      <HomeSidebar route={route} setRoute={(r) => openRoute(r)} workspace={workspace} setWorkspace={setWorkspace} />
      <div style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }}>
        <WorkspaceTabs
          tabs={openTabs}
          activeId={activeTabId}
          onActivate={setActiveTabId}
          onClose={closeTab}
        />
        <div style={{ flex: 1, background: "var(--live-card)", borderLeft: "1px solid var(--live-border)", overflow: "hidden", position: "relative" }}>
          {route === "ln-productoras" ? (
            <LNProductorasPane onOpenProductora={(p) => setWorkspace(p.id)} />
          ) : route === "ln-pl" ? (
            <LNAggregatedPLPane onOpenProductora={(p) => openRoute("ln-productora-detail", p)} />
          ) : route === "ln-productora-detail" ? (
            <LNProductoraDetailPane
              productoraId={(activeTab && activeTab.project && activeTab.project.id) || "dale-play"}
              onBack={() => openRoute("ln-pl")}
              onOpenShow={() => openRoute("show-detail")}
            />
          ) : route === "ln-calendar" ? (
            <LNCalendarPane />
          ) : route === "ln-ticketing" ? (
            <LNTicketingPane />
          ) : route === "show-detail" ? (
            <ShowDetailPane onBack={() => openRoute("shows")} />
          ) : route === "project-hub" || route === "project-detail" ? (
            <ProjectHubPane
              selectedProject={route === "project-detail" ? (activeTab && activeTab.project) || selectedProject : null}
              onOpen={(p) => { setSelectedProject(p); openRoute("project-detail", p); }}
              onBack={() => { openRoute("project-hub"); setSelectedProject(null); }}
            />
          ) : route === "venues" ? (
            <VenuesPane />
          ) : route === "calendar" ? (
            <CalendarPane />
          ) : route === "ticketing" ? (
            <TicketingPane />
          ) : route === "shows" ? (
            <ShowsPane onOpenShow={() => openRoute("show-detail")} />
          ) : route === "home" ? (
            <AssistantPane bannerOpen={bannerOpen} setBannerOpen={setBannerOpen} />
          ) : (
            <PLPane onOpenShow={() => openRoute("show-detail")} />
          )}
          {onBackToOnboarding && route === "home" && (
            <button
              onClick={onBackToOnboarding}
              style={{
                position: "absolute",
                bottom: 18,
                right: 22,
                appearance: "none",
                background: "transparent",
                border: "1px solid var(--live-border)",
                color: "var(--live-muted)",
                fontSize: 11.5,
                fontWeight: 500,
                height: 28,
                padding: "0 12px",
                borderRadius: 999,
                cursor: "pointer",
                fontFamily: "var(--font-sans)",
              }}
            >
              Restart onboarding
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Home });
