// ════════════════════════════════════════════════════════════════════════
// PropMystro · Dashboard — faithful port of the final Apps Script Mission
// Control (three layouts behind a live toggle: Mission Control / Grid / Inbox,
// persisted to localStorage). Adapted to read the commercial app's Supabase
// data: compliance + rent roll are live now; finance/arrears/tax/maintenance/
// inspections/bank signals populate as those modules (M2–M7) come online.
// Self-contained styles using the cool-paper Heritage tokens. → window.PMDashboardFull
// ════════════════════════════════════════════════════════════════════════
(function () {
  const { useState } = React;
  const PM_DASH_LAYOUT_KEY = 'pm-dash-layout';
  const CERTLBL = { gas_safety: 'Gas Safety', eicr: 'Electrical (EICR)', epc: 'EPC', deposit_protection: 'Deposit protection', right_to_rent: 'Right to Rent', hmo_licence: 'HMO licence', insurance: 'Insurance', hmo_inspection: 'HMO inspection' };
  const REQUIRED = ['gas_safety', 'eicr', 'epc'];
  const money = (n) => '£' + Math.round(Number(n || 0)).toLocaleString('en-GB');
  const fdate = (d) => d ? new Date(d).toLocaleDateString('en-GB', { day: 'numeric', month: 'short' }) : '—';
  const addr1 = (a) => (a || '').split(',')[0];
  const pill = (s) => (s === 'overdue' || s === 'critical') ? 'crit' : (s === 'missing' || s === 'warn') ? 'warn' : 'mono';

  // ── one roll-up the three layouts read ─────────────────────────────────
  function buildData(props, certs, extra) {
    props = props || []; certs = certs || []; extra = extra || {};
    const tickets = extra.tickets || [], bankRows = extra.bankRows || [], payments = extra.payments || [], expenses = extra.expenses || [], tenancies = extra.tenancies || [], tenants = extra.tenants || [];
    const byProp = {};
    certs.forEach(c => { (byProp[c.property_id] = byProp[c.property_id] || []).push(c); });
    const compliance = [];
    props.forEach(p => {
      REQUIRED.forEach(type => {
        const list = (byProp[p.id] || []).filter(c => c.type === type && c.expiry_date).sort((a, b) => new Date(b.expiry_date) - new Date(a.expiry_date));
        const cert = list[0];
        if (!cert) { compliance.push({ property: p, type, status: 'missing', days: null }); return; }
        const days = Math.ceil((new Date(cert.expiry_date) - new Date()) / 864e5);
        if (days < 0) compliance.push({ property: p, type, status: 'overdue', days });
        else if (days < 30) compliance.push({ property: p, type, status: 'critical', days });
        else if (days < 90) compliance.push({ property: p, type, status: 'warn', days });
      });
    });
    const order = { overdue: 0, missing: 1, critical: 2, warn: 3 };
    compliance.sort((a, b) => (order[a.status] - order[b.status]) || ((a.days == null ? 9999 : a.days) - (b.days == null ? 9999 : b.days)));
    const complianceCrit = compliance.filter(c => ['overdue', 'missing', 'critical'].includes(c.status));
    const propById = {}; props.forEach(p => { propById[p.id] = p; });
    const tenantById = {}; tenants.forEach(t => { tenantById[t.id] = t; });

    // ── finance: collected/expenses 12mo, net, arrears per active tenancy ──
    const yearAgo = new Date(Date.now() - 365 * 864e5).toISOString().slice(0, 10);
    const collected = payments.filter(x => (x.date || '') >= yearAgo).reduce((s, x) => s + Number(x.amount || 0), 0);
    const expenseTotal = expenses.filter(x => (x.date || '') >= yearAgo).reduce((s, x) => s + Number(x.amount || 0), 0);
    const monthsElapsed = (start) => { if (!start) return 0; const s = new Date(start), n = new Date(); let m = (n.getFullYear() - s.getFullYear()) * 12 + (n.getMonth() - s.getMonth()); if (n.getDate() >= s.getDate()) m += 1; return Math.max(0, m); };
    const arrears = [];
    let expectedAll = 0, receivedAll = 0;
    tenancies.filter(t => t.status === 'active').forEach(ty => {
      const expected = Number(ty.rent_pcm || 0) * monthsElapsed(ty.start_date);
      const received = payments.filter(x => x.tenancy_id === ty.id).reduce((s, x) => s + Number(x.amount || 0), 0);
      expectedAll += expected; receivedAll += received;
      const owed = expected - received;
      if (owed > 1) arrears.push({ tenancy: ty, property: propById[ty.property_id], lead: tenantById[ty.lead_tenant_id], owed });
    });
    arrears.sort((a, b) => b.owed - a.owed);
    const arrearsTotal = arrears.reduce((s, a) => s + a.owed, 0);
    const collectionRate = expectedAll > 0 ? Math.min(100, Math.round(receivedAll / expectedAll * 100)) : 100;

    // ── maintenance: open + escalated damp/mould (Awaab clock) ──
    const openTickets = tickets.filter(t => t.status !== 'resolved');
    const escalated = openTickets.filter(t => t.category === 'damp_mould');
    const maintAlerts = openTickets.filter(t => t.category === 'damp_mould' || t.priority === 'critical' || t.priority === 'high')
      .map(t => { let days = null; if (t.category === 'damp_mould' && t.raised_at) { const dl = new Date(t.raised_at); dl.setDate(dl.getDate() + 14); days = Math.ceil((dl - new Date()) / 864e5); } return { ticket: t, property: propById[t.property_id], days, escalated: t.category === 'damp_mould' }; })
      .sort((a, b) => (a.escalated !== b.escalated) ? (a.escalated ? -1 : 1) : ((a.days == null ? 999 : a.days) - (b.days == null ? 999 : b.days)));

    const bankInbox = bankRows.filter(r => r.status === 'unmatched');

    const monthlyRent = props.reduce((s, p) => s + Number(p.rent || 0), 0);
    const tenantedCount = props.filter(p => Number(p.rent || 0) > 0).length;
    const finance = { monthlyRent, tenantedCount, collectionRate, net: collected - expenseTotal, collected, expenseTotal, arrearsTotal };
    const criticalCount = complianceCrit.length + escalated.length + arrears.filter(a => a.owed >= Number(a.tenancy.rent_pcm || 0)).length;
    return {
      compliance, complianceCrit, finance,
      arrears, arrearsCrit: arrears.filter(a => a.owed >= Number(a.tenancy.rent_pcm || 0)),
      taxAlerts: [], taxQueries: [], tickets: openTickets, escalated, maintAlerts,
      inspections: [], inspOverdue: [], inspPending: [], bankInbox, activity: [],
      criticalCount, propCount: props.length,
    };
  }

  function Section({ title, count, onAll, children }) {
    return <div className="pm-dash-sec">
      <div className="pm-dash-sec-head">
        <h3 className="pmd-h3">{title}{count != null && <span className="pm-dash-count">{count}</span>}</h3>
        {onAll && <button className="pmd-link" onClick={onAll}>View all →</button>}
      </div>
      <div className="pm-dash-sec-body">{children}</div>
    </div>;
  }

  // ── LAYOUT A · MISSION CONTROL ─────────────────────────────────────────
  function Mission({ d, go, onOpen }) {
    const f = d.finance;
    return <React.Fragment>
      <div className="pm-dash-kpis">
        <button className="pm-dash-kpi" onClick={() => go('properties')}>
          <span className="pm-stat-l">MONTHLY RENT ROLL</span><strong>{money(f.monthlyRent)}</strong>
          <span className="pm-dash-kpi-sub">{f.tenantedCount} tenanted · {f.collectionRate}% collected</span>
        </button>
        <button className="pm-dash-kpi" onClick={() => go('expenses')}>
          <span className="pm-stat-l">NET POSITION (12MO)</span><strong className={f.net >= 0 ? 'pm-pos' : 'pm-neg'}>{money(f.net)}</strong>
          <span className="pm-dash-kpi-sub">{money(f.collected)} in · {money(f.expenseTotal)} out</span>
        </button>
        <button className={'pm-dash-kpi' + (d.arrears.length ? ' warn' : '')} onClick={() => go('ledger')}>
          <span className="pm-stat-l">RENT ARREARS</span><strong>{money(f.arrearsTotal)}</strong>
          <span className="pm-dash-kpi-sub">{d.arrears.length} {d.arrears.length === 1 ? 'tenancy' : 'tenancies'} behind</span>
        </button>
        <button className={'pm-dash-kpi' + (d.criticalCount ? ' crit' : ' ok')} onClick={() => go('alerts')}>
          <span className="pm-stat-l">NEEDS ATTENTION</span><strong>{d.criticalCount}</strong>
          <span className="pm-dash-kpi-sub">{d.criticalCount ? 'critical items today' : 'all clear'}</span>
        </button>
      </div>

      {d.criticalCount > 0 && <div className="pm-dash-band">
        <span className="pm-dot pm-crit"></span><strong>Act today:</strong>
        {d.escalated.slice(0, 2).map((t, i) => <button key={'e' + i} className="pm-dash-band-chip" onClick={() => go('maintenance')}>🦠 {t.title.length > 26 ? t.title.slice(0, 24) + '…' : t.title}</button>)}
        {d.complianceCrit.slice(0, 3).map((c, i) => <button key={i} className="pm-dash-band-chip" onClick={() => onOpen(c.property)}>
          {CERTLBL[c.type].split(' ')[0]} · {addr1(c.property.address)} {c.status === 'overdue' ? Math.abs(c.days) + 'd over' : c.status === 'missing' ? 'missing' : c.days + 'd'}
        </button>)}
      </div>}

      <div className="pm-dash-cols">
        <div className="pm-dash-col">
          <Section title="Compliance" count={d.compliance.length} onAll={() => go('compliance')}>
            {d.compliance.length === 0 && <div className="pm-dash-empty">Every required certificate is in date. ✓</div>}
            {d.compliance.slice(0, 6).map((c, i) => <button key={i} className="pm-dash-row" onClick={() => onOpen(c.property)}>
              <span className={'pm-dot pm-' + pill(c.status)}></span>
              <span className="pm-dash-row-main">{CERTLBL[c.type]}<span className="pmd-muted"> · {addr1(c.property.address)}</span></span>
              <span className="pmd-mono pm-dash-row-meta">{c.status === 'missing' ? 'missing' : c.status === 'overdue' ? Math.abs(c.days) + 'd over' : c.days + 'd'}</span>
            </button>)}
          </Section>
          <Section title="Rent & arrears" count={d.arrears.length} onAll={() => go('ledger')}>
            {d.arrears.length === 0 && <div className="pm-dash-empty">Every tenancy is paid up. ✓</div>}
            {d.arrears.slice(0, 5).map((a, i) => <button key={i} className="pm-dash-row" onClick={() => a.property && onOpen(a.property)}>
              <span className={'pm-dot pm-' + (a.owed >= Number(a.tenancy.rent_pcm || 0) ? 'crit' : 'warn')}></span>
              <span className="pm-dash-row-main">{a.lead ? a.lead.full_name : 'Tenant'}<span className="pmd-muted"> · {a.property ? addr1(a.property.address) : '—'}</span></span>
              <span className="pmd-mono pm-dash-row-meta">{money(a.owed)}</span>
            </button>)}
            {d.bankInbox.length > 0 && <button className="pm-dash-row" onClick={() => go('bank')}>
              <span className="pm-dot pm-warn"></span>
              <span className="pm-dash-row-main">Bank inbox<span className="pmd-muted"> · unmatched statement lines</span></span>
              <span className="pmd-mono pm-dash-row-meta">{d.bankInbox.length}</span>
            </button>}
          </Section>
        </div>
        <div className="pm-dash-col">
          <Section title="Maintenance" count={d.tickets.length} onAll={() => go('maintenance')}>
            {d.maintAlerts.length === 0 && <div className="pm-dash-empty">{d.tickets.length ? d.tickets.length + ' open · nothing urgent. ✓' : 'No open tickets. ✓'}</div>}
            {d.maintAlerts.slice(0, 5).map((m, i) => <button key={i} className="pm-dash-row" onClick={() => go('maintenance')}>
              <span className={'pm-dot pm-' + (m.escalated ? 'crit' : 'warn')}></span>
              <span className="pm-dash-row-main">{m.ticket.title.length > 34 ? m.ticket.title.slice(0, 32) + '…' : m.ticket.title}<span className="pmd-muted"> · {m.property ? addr1(m.property.address) : '—'}</span></span>
              <span className="pmd-mono pm-dash-row-meta">{m.escalated && m.days != null ? (m.days < 0 ? Math.abs(m.days) + 'd over' : m.days + 'd left') : m.ticket.priority}</span>
            </button>)}
          </Section>
          <Section title="Tax" count={d.taxAlerts.length}>
            <div className="pm-dash-empty">MTD &amp; SA105 signals appear once Tax is enabled. ✓</div>
          </Section>
        </div>
      </div>
    </React.Fragment>;
  }

  // ── LAYOUT B · GRID ────────────────────────────────────────────────────
  function Grid({ d, go }) {
    const f = d.finance;
    const card = (title, accent, body, target) => <button className={'pm-dash-card' + (accent ? ' pm-dash-card-' + accent : '')} onClick={() => go(target || 'properties')}>
      <div className="pm-dash-card-head"><h3 className="pmd-h3">{title}</h3><span className="pm-dash-card-go">→</span></div>{body}
    </button>;
    return <div className="pm-dash-grid">
      {card('Finance', f.net >= 0 ? 'ok' : 'crit', <React.Fragment>
        <div className="pm-dash-card-big">{money(f.net)}<span className="pm-dash-card-unit"> net</span></div>
        <div className="pm-dash-card-stats">
          <div><span className="pm-stat-l">RENT/MO</span><strong>{money(f.monthlyRent)}</strong></div>
          <div><span className="pm-stat-l">TENANTED</span><strong>{f.tenantedCount}</strong></div>
          <div><span className="pm-stat-l">PROPS</span><strong>{d.propCount}</strong></div>
        </div>
      </React.Fragment>, 'ledger')}
      {card('Compliance', d.complianceCrit.length ? 'crit' : 'ok', <React.Fragment>
        <div className="pm-dash-card-big">{d.complianceCrit.length}<span className="pm-dash-card-unit"> critical</span></div>
        <div className="pm-dash-card-line">{d.compliance.length} total flags across {d.propCount} properties</div>
        {d.compliance.slice(0, 3).map((c, i) => <div key={i} className="pm-dash-mini"><span className={'pm-dot pm-' + pill(c.status)}></span>{CERTLBL[c.type].split(' ')[0]} · {addr1(c.property.address)}</div>)}
      </React.Fragment>, 'compliance')}
      {card('Rent & arrears', d.arrears.length ? 'warn' : 'ok', <React.Fragment>
        <div className="pm-dash-card-big">{money(f.arrearsTotal)}<span className="pm-dash-card-unit"> owed</span></div>
        <div className="pm-dash-card-line">{d.arrears.length ? d.arrears.length + ' tenanc' + (d.arrears.length === 1 ? 'y' : 'ies') + ' behind · ' + f.collectionRate + '% collected' : 'Every tenancy paid up · ' + f.collectionRate + '% collected'}</div>
        {d.arrears.slice(0, 3).map((a, i) => <div key={i} className="pm-dash-mini"><span className="pm-dot pm-warn"></span>{a.lead ? a.lead.full_name : 'Tenant'} · {money(a.owed)}</div>)}
      </React.Fragment>, 'ledger')}
      {card('Tax', 'ok', <React.Fragment>
        <div className="pm-dash-card-big">0<span className="pm-dash-card-unit"> due</span></div>
        <div className="pm-dash-card-line">MTD quarterly &amp; SA105 — coming soon</div>
      </React.Fragment>, 'tax')}
      {card('Maintenance', d.escalated.length ? 'crit' : 'ok', <React.Fragment>
        <div className="pm-dash-card-big">{d.tickets.length}<span className="pm-dash-card-unit"> open</span></div>
        <div className="pm-dash-card-line">{d.escalated.length ? d.escalated.length + ' escalated — damp & mould clock running' : 'No escalations'}</div>
        {d.maintAlerts.slice(0, 3).map((m, i) => <div key={i} className="pm-dash-mini"><span className={'pm-dot pm-' + (m.escalated ? 'crit' : 'warn')}></span>{m.ticket.title.length > 30 ? m.ticket.title.slice(0, 28) + '…' : m.ticket.title}</div>)}
      </React.Fragment>, 'maintenance')}
      {card('Bank', d.bankInbox.length ? 'warn' : 'ok', <React.Fragment>
        <div className="pm-dash-card-big">{d.bankInbox.length}<span className="pm-dash-card-unit"> unmatched</span></div>
        <div className="pm-dash-card-line">{d.bankInbox.length ? 'Statement lines waiting in the inbox' : 'Bank inbox clear'}</div>
      </React.Fragment>, 'bank')}
      {card('Inspections', 'ok', <React.Fragment>
        <div className="pm-dash-card-big">0<span className="pm-dash-card-unit"> due</span></div>
        <div className="pm-dash-card-line">Routine inspections — HMO 3-monthly, others 6-monthly</div>
      </React.Fragment>, 'inspections')}
    </div>;
  }

  // ── LAYOUT C · INBOX ───────────────────────────────────────────────────
  function Inbox({ d, go, onOpen }) {
    const items = [];
    d.compliance.forEach(c => {
      const tier = ['overdue', 'missing', 'critical'].includes(c.status) ? 0 : (c.days != null && c.days < 60 ? 1 : 2);
      items.push({ tier, icon: '◉', label: CERTLBL[c.type] + (c.status === 'missing' ? ' missing' : c.status === 'overdue' ? ' ' + Math.abs(c.days) + 'd overdue' : ' expires in ' + c.days + 'd'), where: addr1(c.property.address), go: () => onOpen(c.property), sort: c.days == null ? -1 : c.days });
    });
    d.maintAlerts.forEach(m => {
      items.push({ tier: m.escalated ? 0 : 1, icon: '⚒', label: m.ticket.title + (m.escalated && m.days != null ? (m.days < 0 ? ' · ' + Math.abs(m.days) + 'd over' : ' · ' + m.days + 'd left') : ''), where: m.property ? addr1(m.property.address) : '', go: () => go('maintenance'), sort: m.days == null ? 50 : m.days });
    });
    d.bankInbox.length > 0 && items.push({ tier: 1, icon: '⇄', label: d.bankInbox.length + ' unmatched bank line' + (d.bankInbox.length === 1 ? '' : 's'), where: 'Bank reconciliation', go: () => go('bank'), sort: 5 });
    d.arrears.forEach(a => {
      items.push({ tier: a.owed >= Number(a.tenancy.rent_pcm || 0) ? 0 : 1, icon: '£', label: (a.lead ? a.lead.full_name : 'Tenant') + ' · ' + money(a.owed) + ' arrears', where: a.property ? addr1(a.property.address) : '', go: () => go('ledger'), sort: 3 });
    });
    const tiers = [
      { t: 0, label: 'Critical — act today', cls: 'crit' },
      { t: 1, label: 'This week', cls: 'warn' },
      { t: 2, label: 'Upcoming', cls: 'mono' },
    ];
    const byTier = (t) => items.filter(it => it.tier === t).sort((a, b) => a.sort - b.sort);
    return <div className="pm-dash-inbox">
      {items.length === 0 && <div className="pm-dash-empty" style={{ textAlign: 'center', padding: 40 }}><div style={{ fontSize: 30 }}>✓</div><strong>Inbox zero</strong><div className="pmd-sub">Nothing needs your attention right now.</div></div>}
      {tiers.map(tier => { const list = byTier(tier.t); if (!list.length) return null; return <div key={tier.t} className="pm-inbox-tier">
        <div className="pm-inbox-tier-head"><span className={'pm-dot pm-' + tier.cls}></span>{tier.label}<span className="pm-dash-count">{list.length}</span></div>
        {list.map((it, i) => <button key={i} className="pm-inbox-item" onClick={it.go}>
          <span className="pm-inbox-icon">{it.icon}</span>
          <span className="pm-inbox-label">{it.label}</span>
          {it.where && <span className="pmd-mono pmd-muted pm-inbox-where">{it.where}</span>}
          <span className="pm-inbox-go">→</span>
        </button>)}
      </div>; })}
    </div>;
  }

  // ── ROOT ───────────────────────────────────────────────────────────────
  function Dashboard({ account, props, certs, extra, go, onOpen }) {
    const [layout, setLayout] = useState(() => { try { return localStorage.getItem(PM_DASH_LAYOUT_KEY) || 'mission'; } catch { return 'mission'; } });
    const pick = (l) => { setLayout(l); try { localStorage.setItem(PM_DASH_LAYOUT_KEY, l); } catch {} };
    const d = buildData(props, certs, extra);
    const hour = new Date().getHours();
    const greet = hour < 12 ? 'Good morning' : hour < 18 ? 'Good afternoon' : 'Good evening';
    const loading = props === null || certs === null;

    return <div className="pm-dash">
      <Styles />
      <div className="pmd-head">
        <div>
          <h1 className="pmd-h2">{greet}</h1>
          <p className="pmd-sub">Here's where {account.name} stands today — {new Date().toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' })}.</p>
        </div>
        <div className="pm-seg">
          <button className={'pm-seg-btn' + (layout === 'mission' ? ' on' : '')} onClick={() => pick('mission')}>Mission Control</button>
          <button className={'pm-seg-btn' + (layout === 'grid' ? ' on' : '')} onClick={() => pick('grid')}>Grid</button>
          <button className={'pm-seg-btn' + (layout === 'inbox' ? ' on' : '')} onClick={() => pick('inbox')}>Inbox</button>
        </div>
      </div>
      {loading ? <div style={{ padding: 40, textAlign: 'center' }}><span className="spin dark" /></div>
        : layout === 'mission' ? <Mission d={d} go={go} onOpen={onOpen} />
        : layout === 'grid' ? <Grid d={d} go={go} />
        : <Inbox d={d} go={go} onOpen={onOpen} />}
    </div>;
  }

  function Styles() {
    return <style>{`
    .pm-dash .pmd-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 4px; }
    .pmd-h2 { font-size: 26px; font-weight: 700; letter-spacing: -0.01em; }
    .pmd-h3 { font-size: 15px; font-weight: 700; }
    .pmd-sub { color: var(--ink-faint); margin: 4px 0 0; font-size: 14px; }
    .pmd-muted { color: var(--ink-faint); } .pmd-mono { font-family: 'JetBrains Mono', monospace; }
    .pmd-link { background: none; border: 0; color: var(--brand-deep); font-weight: 600; font-size: 12.5px; cursor: pointer; padding: 0; }
    .pm-dash .pm-seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; padding: 3px; gap: 2px; }
    .pm-dash .pm-seg-btn { background: transparent; border: 0; padding: 6px 14px; border-radius: 6px; font-size: 13px; font-weight: 600; color: var(--ink-soft); cursor: pointer; white-space: nowrap; }
    .pm-dash .pm-seg-btn.on { background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
    .pm-stat-l { font-family: 'JetBrains Mono', monospace; font-size: 9.5px; color: var(--ink-faint); letter-spacing: 0.05em; }
    .pm-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
    .pm-dot.pm-crit { background: var(--red); } .pm-dot.pm-warn { background: var(--amber); } .pm-dot.pm-ok { background: var(--ok); } .pm-dot.pm-mono { background: var(--ink-faint); }
    .pm-pos { color: var(--ok); } .pm-neg { color: var(--red); }
    .pm-dash-count { font-family: 'JetBrains Mono', monospace; font-size: 11px; background: var(--surface-2); color: var(--ink-soft); border-radius: 10px; padding: 1px 7px; margin-left: 6px; font-weight: 500; }

    .pm-dash-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 18px 0; }
    .pm-dash-kpi { text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; display: flex; flex-direction: column; gap: 3px; cursor: pointer; transition: border-color .12s, box-shadow .12s; }
    .pm-dash-kpi:hover { border-color: var(--ink-faint); box-shadow: var(--shadow); }
    .pm-dash-kpi strong { font-size: 26px; line-height: 1.1; font-weight: 700; }
    .pm-dash-kpi-sub { font-size: 11.5px; color: var(--ink-faint); }
    .pm-dash-kpi.crit { background: var(--red-soft); border-color: rgba(184,57,42,0.25); }
    .pm-dash-kpi.warn { background: var(--amber-soft); border-color: rgba(201,138,31,0.25); }
    .pm-dash-kpi.ok strong { color: var(--ok); }

    .pm-dash-band { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; background: var(--red-soft); border: 1px solid rgba(184,57,42,0.2); border-radius: var(--radius); padding: 10px 14px; margin-bottom: 16px; font-size: 13px; }
    .pm-dash-band-chip { background: var(--surface); border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px; font-size: 12px; cursor: pointer; }
    .pm-dash-band-chip:hover { border-color: var(--red); color: var(--red); }

    .pm-dash-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
    .pm-dash-col { display: flex; flex-direction: column; gap: 16px; }
    .pm-dash-sec { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
    .pm-dash-sec-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
    .pm-dash-sec-body { display: flex; flex-direction: column; gap: 1px; }
    .pm-dash-row { display: flex; align-items: center; gap: 9px; padding: 7px 6px; background: transparent; border: 0; border-radius: 7px; text-align: left; cursor: pointer; width: 100%; }
    .pm-dash-row:hover { background: var(--surface-2); }
    .pm-dash-row-main { flex: 1; font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .pm-dash-row-meta { font-size: 11px; color: var(--ink-faint); white-space: nowrap; }
    .pm-dash-empty { font-size: 13px; color: var(--ink-faint); padding: 6px; }

    .pm-dash-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 18px; }
    .pm-dash-card { text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; cursor: pointer; display: flex; flex-direction: column; gap: 8px; transition: border-color .12s, box-shadow .12s; min-height: 150px; }
    .pm-dash-card:hover { border-color: var(--ink-faint); box-shadow: var(--shadow); }
    .pm-dash-card-crit { border-top: 3px solid var(--red); } .pm-dash-card-warn { border-top: 3px solid var(--amber); } .pm-dash-card-ok { border-top: 3px solid var(--ok); }
    .pm-dash-card-head { display: flex; justify-content: space-between; align-items: center; }
    .pm-dash-card-go { color: var(--ink-faint); font-size: 16px; }
    .pm-dash-card-big { font-size: 30px; font-weight: 700; line-height: 1; }
    .pm-dash-card-unit { font-size: 13px; font-weight: 400; color: var(--ink-faint); }
    .pm-dash-card-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
    .pm-dash-card-stats strong { display: block; font-size: 13px; }
    .pm-dash-card-line { font-size: 11.5px; color: var(--ink-faint); }
    .pm-dash-mini { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    .pm-dash-inbox { margin-top: 18px; display: flex; flex-direction: column; gap: 20px; max-width: 880px; }
    .pm-inbox-tier-head { display: flex; align-items: center; gap: 8px; font-family: 'JetBrains Mono', monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft); margin-bottom: 8px; }
    .pm-inbox-item { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 11px 14px; margin-bottom: 6px; cursor: pointer; transition: border-color .12s; }
    .pm-inbox-item:hover { border-color: var(--ink-faint); }
    .pm-inbox-icon { width: 26px; height: 26px; border-radius: 7px; background: var(--surface-2); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; flex-shrink: 0; }
    .pm-inbox-label { flex: 1; font-size: 13.5px; min-width: 0; }
    .pm-inbox-where { white-space: nowrap; }
    .pm-inbox-go { color: var(--ink-faint); }

    @media (max-width: 980px) {
      .pm-dash-kpis { grid-template-columns: 1fr 1fr; }
      .pm-dash-cols { grid-template-columns: 1fr; }
      .pm-dash-grid { grid-template-columns: 1fr 1fr; }
    }
    @media (max-width: 640px) {
      .pm-dash-kpis, .pm-dash-grid { grid-template-columns: 1fr; }
      .pm-dash .pmd-head { flex-direction: column; }
    }
    `}</style>;
  }

  window.PMDashboardFull = Dashboard;
})();
